This action will force synchronization from Gao Xing/CloudStack, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
# Licensed to the Apache Software Foundation (ASF) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The ASF licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.from utilities import writeProgressBar, bashfrom cloudException import CloudRuntimeException, CloudInternalException, formatExceptionInfoimport loggingfrom networkConfig import networkConfigimport refrom configFileOps import configFileOpsimport osimport shutilclass serviceCfgBase(object):def __init__(self, syscfg):self.status = Noneself.serviceName = ""self.cfoHandlers = []self.syscfg = syscfgself.netMgrRunning = Falsedef configration(self):writeProgressBar("Configure " + self.serviceName + " ...", None)result = Falsetry:result = self.config()if result is None:result = Falseself.status = resultwriteProgressBar(None, result)return resultexcept CloudRuntimeException, e:self.status = resultwriteProgressBar(None, result)logging.debug(e.getDetails())raise eexcept CloudInternalException, e:self.status = resultwriteProgressBar(None, result)raise eexcept:logging.debug(formatExceptionInfo())if self.syscfg.env.mode == "Server":raise CloudRuntimeException("Configure %s failed, Please check the /var/log/cloudstack/setupManagement.log for detail"%self.serviceName)else:raise CloudRuntimeException("Configure %s failed, Please check the /var/log/cloudstack/setupAgent.log for detail"%self.serviceName)def backup(self):if self.status is None:return TruewriteProgressBar("Restore " + self.serviceName + " ...", None)result = Falsetry:for cfo in self.cfoHandlers:cfo.backup()result = self.restore()except (CloudRuntimeException, CloudInternalException), e:logging.debug(e)writeProgressBar(None, result)def config(self):return Truedef restore(self):return Trueclass networkConfigBase:def __init__(self, syscfg):self.netcfg = networkConfig()self.serviceName = "Network"self.brName = Noneself.dev = Noneself.syscfg = syscfgdef isPreConfiged(self):preCfged = Falsefor br in self.syscfg.env.nics:if not self.netcfg.isNetworkDev(br):logging.debug("%s is not a network device, is it down?"%br)return Falseif self.syscfg.env.bridgeType == "openvswitch" and not self.netcfg.isOvsBridge(br):raise CloudInternalException("%s is not an openvswitch bridge" % br)if self.syscfg.env.bridgeType == "native" and not self.netcfg.isBridge(br) and not self.netcfg.isNetworkDev(br):# traffic label doesn't have to be a bridge, we'll create bridges on itraise CloudInternalException("%s is not a bridge and not a net device" % br)preCfged = Truereturn preCfgeddef cfgNetwork(self, dev=None, brName=None):if dev is None:device = self.netcfg.getDefaultNetwork()else:device = self.netcfg.getDevInfo(dev)if device.type == "dev":if brName is None:brName = "cloudbr0"self.writeToCfgFile(brName, device)elif device.type == "brport":brName = self.netcfg.getBridge(dev)brDevice = self.netcfg.getDevInfo(brName)self.writeToCfgFile(brDevice.name, device)elif device.type == "bridge":#Fixme, assuming the outgoing physcial device is on port 1enslavedDev = self.netcfg.getEnslavedDev(device.name, 1)if enslavedDev is None:raise CloudInternalException("Failed to get enslaved devices on bridge:%s"%device.name)brDevice = devicedevice = self.netcfg.getDevInfo(enslavedDev)brName = brDevice.nameself.writeToCfgFile(brName, device)self.brName = brNameself.dev = device.namedef writeToCfgFile(self):passclass networkConfigUbuntu(serviceCfgBase, networkConfigBase):def __init__(self, syscfg):super(networkConfigUbuntu, self).__init__(syscfg)networkConfigBase.__init__(self, syscfg)self.netCfgFile = "/etc/network/interfaces"def getNetworkMethod(self, line):if line.find("static") != -1:return "static"elif line.find("dhcp") != -1:return "dhcp"else:logging.debug("Failed to find the network method from:%s"%line)raise CloudInternalException("Failed to find the network method from /etc/network/interfaces")def addBridge(self, br, dev):bash("ifdown %s"%dev.name)for line in file(self.netCfgFile).readlines():match = re.match("^ *iface %s.*"%dev.name, line)if match is not None:dev.method = self.getNetworkMethod(match.group(0))cfo = configFileOps(self.netCfgFile, self)if self.syscfg.env.bridgeType == "openvswitch":bridgeCfg = "\n".join(("","iface {device} inet manual"," ovs_type OVSPort"," ovs_bridge {bridge}","","auto {bridge}","allow-ovs {bridge}","iface {bridge} inet {device_method}"," ovs_type OVSBridge"," ovs_ports {device}","")).format(bridge=br, device=dev.name, device_method=dev.method)cfo.replace_line("^ *auto %s.*" % dev.name,"allow-{bridge} {device}".format(bridge=br, device=dev.name))elif self.syscfg.env.bridgeType == "native":bridgeCfg = "\niface %s inet manual\n\auto %s\n\iface %s inet %s\n\bridge_ports %s\n"%(dev.name, br, br, dev.method, dev.name)else:raise CloudInternalException("Unknown network.bridge.type %s" % self.syscfg.env.bridgeType)cfo.replace_line("^ *iface %s.*"%dev.name, bridgeCfg)def addDev(self, br, dev):logging.debug("Haven't implement yet")def addBridgeAndDev(self, br, dev):logging.debug("Haven't implement yet")def writeToCfgFile(self, br, dev):cfg = file(self.netCfgFile).read()ifaceDev = re.search("^ *iface %s.*"%dev.name, cfg, re.MULTILINE)ifaceBr = re.search("^ *iface %s.*"%br, cfg, re.MULTILINE)if ifaceDev is not None and ifaceBr is not None:logging.debug("%s:%s already configured"%(br, dev.name))return Trueelif ifaceDev is not None and ifaceBr is None:#reconfig bridgeself.addBridge(br, dev)elif ifaceDev is None and ifaceBr is not None:#reconfig devraise CloudInternalException("Missing device configuration, Need to add your network configuration into /etc/network/interfaces at first")else:raise CloudInternalException("Missing bridge/device network configuration, need to add your network configuration into /etc/network/interfaces at first")def config(self):try:if super(networkConfigUbuntu, self).isPreConfiged():return Trueself.netMgrRunning = self.syscfg.svo.isServiceRunning("network-manager")super(networkConfigUbuntu, self).cfgNetwork()if self.netMgrRunning:self.syscfg.svo.stopService("network-manager")self.syscfg.svo.disableService("network-manager")ifup_op = bash("ifup %s"%self.brName)if not ifup_op.isSuccess():raise CloudInternalException("Can't start network:%s %s" % (self.brName, ifup_op.getErrMsg()))self.syscfg.env.nics.append(self.brName)self.syscfg.env.nics.append(self.brName)self.syscfg.env.nics.append(self.brName)return Trueexcept:raisedef restore(self):try:if self.netMgrRunning:self.syscfg.svo.enableService("network-manager")self.syscfg.svo.startService("network-manager")bash("/etc/init.d/networking stop")bash("/etc/init.d/networking start")return Trueexcept:logging.debug(formatExceptionInfo())return Falseclass networkConfigRedhat(serviceCfgBase, networkConfigBase):def __init__(self, syscfg):super(networkConfigRedhat, self).__init__(syscfg)networkConfigBase.__init__(self, syscfg)def writeToCfgFile(self, brName, dev):self.devCfgFile = "/etc/sysconfig/network-scripts/ifcfg-%s" % dev.nameself.brCfgFile = "/etc/sysconfig/network-scripts/ifcfg-%s" % brNameisDevExist = os.path.exists(self.devCfgFile)isBrExist = os.path.exists(self.brCfgFile)if isDevExist and isBrExist:logging.debug("%s:%s already configured"%(brName, dev.name))return Trueelif isDevExist and not isBrExist:#reconfig bridgeself.addBridge(brName, dev)elif not isDevExist and isBrExist:#reconfig devraise CloudInternalException("Missing device configuration, Need to add your network configuration into /etc/sysconfig/network-scripts at first")else:raise CloudInternalException("Missing bridge/device network configuration, need to add your network configuration into /etc/sysconfig/network-scripts at first")def addBridge(self, brName, dev):bash("ifdown %s" % dev.name)if not os.path.exists(self.brCfgFile):shutil.copy(self.devCfgFile, self.brCfgFile)#config device file at first: disable nm, set onboot=yes if notcfo = configFileOps(self.devCfgFile, self)cfo.addEntry("NM_CONTROLLED", "no")cfo.addEntry("ONBOOT", "yes")if self.syscfg.env.bridgeType == "openvswitch":if cfo.getEntry("IPADDR"):cfo.rmEntry("IPADDR", cfo.getEntry("IPADDR"))cfo.addEntry("DEVICETYPE", "ovs")cfo.addEntry("TYPE", "OVSPort")cfo.addEntry("OVS_BRIDGE", brName)elif self.syscfg.env.bridgeType == "native":cfo.addEntry("BRIDGE", brName)else:raise CloudInternalException("Unknown network.bridge.type %s" % self.syscfg.env.bridgeType)cfo.save()cfo = configFileOps(self.brCfgFile, self)cfo.addEntry("NM_CONTROLLED", "no")cfo.addEntry("ONBOOT", "yes")cfo.addEntry("DEVICE", brName)if self.syscfg.env.bridgeType == "openvswitch":if cfo.getEntry("HWADDR"):cfo.rmEntry("HWADDR", cfo.getEntry("HWADDR"))if cfo.getEntry("UUID"):cfo.rmEntry("UUID", cfo.getEntry("UUID"))cfo.addEntry("STP", "yes")cfo.addEntry("DEVICETYPE", "ovs")cfo.addEntry("TYPE", "OVSBridge")elif self.syscfg.env.bridgeType == "native":cfo.addEntry("TYPE", "Bridge")else:raise CloudInternalException("Unknown network.bridge.type %s" % self.syscfg.env.bridgeType)cfo.save()def config(self):try:if super(networkConfigRedhat, self).isPreConfiged():return Truesuper(networkConfigRedhat, self).cfgNetwork()self.netMgrRunning = self.syscfg.svo.isServiceRunning("NetworkManager")if self.netMgrRunning:self.syscfg.svo.stopService("NetworkManager")self.syscfg.svo.disableService("NetworkManager")cfo = configFileOps("/etc/sysconfig/network", self)cfo.addEntry("NOZEROCONF", "yes")cfo.save()if not bash("service network restart").isSuccess():raise CloudInternalException("Can't restart network")self.syscfg.env.nics.append(self.brName)self.syscfg.env.nics.append(self.brName)self.syscfg.env.nics.append(self.brName)return Trueexcept:raisedef restore(self):try:if self.netMgrRunning:self.syscfg.svo.enableService("NetworkManager")self.syscfg.svo.startService("NetworkManager")bash("service network restart")return Trueexcept:logging.debug(formatExceptionInfo())return Falseclass cgroupConfig(serviceCfgBase):def __init__(self, syscfg):super(cgroupConfig, self).__init__(syscfg)self.serviceName = "Cgroup"def config(self):try:cfo = configFileOps("/etc/cgconfig.conf", self)addConfig = "group virt {\n\cpu {\n\cpu.shares = 9216;\n\}\n\}\n"cfo.add_lines(addConfig)self.syscfg.svo.stopService("cgconfig", True)self.syscfg.svo.enableService("cgconfig",forcestart=True)cfo = configFileOps("/etc/cgrules.conf", self)cfgline = "root:/usr/sbin/libvirtd cpu virt/\n"cfo.add_lines(cfgline)self.syscfg.svo.stopService("cgred", True)if not self.syscfg.svo.enableService("cgred"):return Falsereturn Trueexcept:raisedef restore(self):try:self.syscfg.svo.stopService("cgconfig")self.syscfg.svo.enableService("cgconfig",forcestart=True)self.syscfg.svo.stopService("cgred")self.syscfg.svo.enableService("cgred")return Trueexcept:logging.debug(formatExceptionInfo())return Falseclass nfsConfig(serviceCfgBase):def __init__(self, syscfg):super(nfsConfig, self).__init__(syscfg)self.serviceName = "Nfs"def config(self):try:if not os.path.exists("/etc/nfsmount.conf"):return Truecfo = configFileOps("/etc/nfsmount.conf")cfo.addEntry("Ac", "False")cfo.addEntry("actimeo", "0")cfo.save()self.syscfg.svo.enableService("rpcbind")self.syscfg.svo.stopService("rpcbind")self.syscfg.svo.startService("rpcbind")self.syscfg.svo.enableService("nfs")self.syscfg.svo.stopService("nfs")self.syscfg.svo.startService("nfs")return Trueexcept:logging.debug(formatExceptionInfo())return Falseclass securityPolicyConfigUbuntu(serviceCfgBase):def __init__(self, syscfg):super(securityPolicyConfigUbuntu, self).__init__(syscfg)self.serviceName = "Apparmor"def config(self):try:cmd = bash("service apparmor status")if not cmd.isSuccess() or cmd.getStdout() == "":self.spRunning = Falsereturn Trueif not bash("apparmor_status |grep libvirt").isSuccess():return Truebash("ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/")bash("ln -s /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper /etc/apparmor.d/disable/")bash("apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd")bash("apparmor_parser -R /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper")return Trueexcept:raise CloudRuntimeException("Failed to configure apparmor, please see the /var/log/cloudstack/setupAgent.log for detail, \or you can manually disable it before starting myCloud")def restore(self):try:self.syscfg.svo.enableService("apparmor")self.syscfg.svo.startService("apparmor")return Trueexcept:logging.debug(formatExceptionInfo())return Falseclass securityPolicyConfigRedhat(serviceCfgBase):def __init__(self, syscfg):super(securityPolicyConfigRedhat, self).__init__(syscfg)self.serviceName = "SElinux"def config(self):selinuxEnabled = Trueif not bash("selinuxenabled").isSuccess():selinuxEnabled = Falseif selinuxEnabled:try:bash("setenforce 0")cfo = configFileOps("/etc/selinux/config", self)cfo.replace_line("SELINUX=", "SELINUX=permissive")return Trueexcept:raise CloudRuntimeException("Failed to configure selinux, please see the /var/log/cloudstack/setupAgent.log for detail, \or you can manually disable it before starting myCloud")else:return Truedef restore(self):try:bash("setenforce 1")return Trueexcept:logging.debug(formatExceptionInfo())return Falseclass libvirtConfigRedhat(serviceCfgBase):def __init__(self, syscfg):super(libvirtConfigRedhat, self).__init__(syscfg)self.serviceName = "Libvirt"def config(self):try:cfo = configFileOps("/etc/libvirt/libvirtd.conf", self)cfo.addEntry("listen_tcp", "1")cfo.addEntry("tcp_port", "\"16509\"")cfo.addEntry("auth_tcp", "\"none\"")cfo.addEntry("listen_tls", "0")cfo.save()cfo = configFileOps("/etc/sysconfig/libvirtd", self)cfo.addEntry("export CGROUP_DAEMON", "'cpu:/virt'")cfo.addEntry("LIBVIRTD_ARGS", "-l")cfo.save()filename = "/etc/libvirt/qemu.conf"cfo = configFileOps(filename, self)cfo.addEntry("cgroup_controllers", "[\"cpu\"]")cfo.addEntry("security_driver", "\"none\"")cfo.addEntry("user", "\"root\"")cfo.addEntry("group", "\"root\"")cfo.addEntry("vnc_listen", "\"0.0.0.0\"")cfo.save()self.syscfg.svo.stopService("libvirtd")if not self.syscfg.svo.startService("libvirtd"):return Falsereturn Trueexcept:raisedef restore(self):passclass libvirtConfigUbuntu(serviceCfgBase):def __init__(self, syscfg):super(libvirtConfigUbuntu, self).__init__(syscfg)self.serviceName = "Libvirt"def setupLiveMigration(self):cfo = configFileOps("/etc/libvirt/libvirtd.conf", self)cfo.addEntry("listen_tcp", "1")cfo.addEntry("tcp_port", "\"16509\"");cfo.addEntry("auth_tcp", "\"none\"");cfo.addEntry("listen_tls", "0")cfo.save()if os.path.exists("/etc/init/libvirt-bin.conf"):cfo = configFileOps("/etc/init/libvirt-bin.conf", self)cfo.replace_line("exec /usr/sbin/libvirtd","exec /usr/sbin/libvirtd -d -l")else:cfo = configFileOps("/etc/default/libvirt-bin", self)cfo.replace_or_add_line("libvirtd_opts=","libvirtd_opts='-l -d'")def config(self):try:self.setupLiveMigration()filename = "/etc/libvirt/qemu.conf"cfo = configFileOps(filename, self)cfo.addEntry("security_driver", "\"none\"")cfo.addEntry("user", "\"root\"")cfo.addEntry("group", "\"root\"")cfo.save()self.syscfg.svo.stopService("libvirt-bin")self.syscfg.svo.enableService("libvirt-bin")return Trueexcept:raisedef restore(self):try:self.syscfg.svo.stopService("libvirt-bin")self.syscfg.svo.startService("libvirt-bin")return Trueexcept:logging.debug(formatExceptionInfo())return Falseclass firewallConfigUbuntu(serviceCfgBase):def __init__(self, syscfg):super(firewallConfigUbuntu, self).__init__(syscfg)self.serviceName = "Firewall"def config(self):try:ports = "22 1798 16509".split()for p in ports:bash("ufw allow %s"%p)bash("ufw allow proto tcp from any to any port 5900:6100")bash("ufw allow proto tcp from any to any port 49152:49216")self.syscfg.svo.stopService("ufw")self.syscfg.svo.startService("ufw")return Trueexcept:raisedef restore(self):return Trueclass firewallConfigBase(serviceCfgBase):def __init__(self, syscfg):super(firewallConfigBase, self).__init__(syscfg)self.serviceName = "Firewall"self.rules = []def allowPort(self, port):status = Falsetry:status = bash("iptables-save|grep INPUT|grep -w %s"%port).isSuccess()except:passif not status:redo = Falseresult = Truetry:result = bash("iptables -I INPUT -p tcp -m tcp --dport %s -j ACCEPT"%port).isSuccess()except:redo = Trueif not result or redo:bash("sleep 30")bash("iptables -I INPUT -p tcp -m tcp --dport %s -j ACCEPT"%port)def config(self):try:for port in self.ports:self.allowPort(port)for rule in self.rules:bash("iptables " + rule)bash("iptables-save > /etc/sysconfig/iptables")self.syscfg.svo.stopService("iptables")self.syscfg.svo.startService("iptables")return Trueexcept:raisedef restore(self):return Trueclass firewallConfigAgent(firewallConfigBase):def __init__(self, syscfg):super(firewallConfigAgent, self).__init__(syscfg)self.ports = "22 16509 5900:6100 49152:49216".split()if syscfg.env.distribution.getVersion() == "CentOS":self.rules = ["-D FORWARD -j RH-Firewall-1-INPUT"]else:self.rules = ["-D FORWARD -j REJECT --reject-with icmp-host-prohibited"]class cloudAgentConfig(serviceCfgBase):def __init__(self, syscfg):super(cloudAgentConfig, self).__init__(syscfg)if syscfg.env.agentMode == "Agent":self.serviceName = "cloudAgent"elif syscfg.env.agentMode == "myCloud":self.serviceName = "myCloud"elif syscfg.env.agentMode == "Console":self.serviceName = "Console Proxy"def configMyCloud(self):try:cfo = configFileOps("/etc/cloudstack/agent/agent.properties", self)cfo.addEntry("host", self.syscfg.env.mgtSvr)cfo.addEntry("zone", self.syscfg.env.zone)cfo.addEntry("port", "443")cfo.addEntry("private.network.device", self.syscfg.env.nics[0])cfo.addEntry("public.network.device", self.syscfg.env.nics[1])cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])if cfo.getEntry("local.storage.uuid") == "":cfo.addEntry("local.storage.uuid", str(bash("uuidgen").getStdout()))cfo.addEntry("guid", str(self.syscfg.env.uuid))cfo.addEntry("mount.path", "/mnt")cfo.addEntry("resource", "com.cloud.storage.resource.LocalSecondaryStorageResource|com.cloud.agent.resource.computing.CloudZonesComputingResource")cfo.save()#self.syscfg.svo.stopService("cloud-agent")#self.syscfg.svo.enableService("cloud-agent")return Trueexcept:raisedef configAgent(self):try:cfo = configFileOps("/etc/cloudstack/agent/agent.properties", self)cfo.addEntry("host", self.syscfg.env.mgtSvr)cfo.addEntry("zone", self.syscfg.env.zone)cfo.addEntry("pod", self.syscfg.env.pod)cfo.addEntry("cluster", self.syscfg.env.cluster)cfo.addEntry("hypervisor.type", self.syscfg.env.hypervisor)cfo.addEntry("port", "8250")cfo.addEntry("private.network.device", self.syscfg.env.nics[0])cfo.addEntry("public.network.device", self.syscfg.env.nics[1])cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])cfo.addEntry("guid", str(self.syscfg.env.uuid))if cfo.getEntry("local.storage.uuid") == "":cfo.addEntry("local.storage.uuid", str(bash("uuidgen").getStdout()))cfo.addEntry("resource", "com.cloud.hypervisor.kvm.resource.LibvirtComputingResource")cfo.save()self.syscfg.svo.stopService("cloudstack-agent")bash("sleep 30")self.syscfg.svo.enableService("cloudstack-agent")return Trueexcept:raisedef configConsole(self):try:cfo = configFileOps("/etc/cloudstack/agent/agent.properties", self)cfo.addEntry("host", self.syscfg.env.mgtSvr)cfo.addEntry("zone", self.syscfg.env.zone)cfo.addEntry("pod", self.syscfg.env.pod)cfo.addEntry("cluster", self.syscfg.env.cluster)cfo.addEntry("port", "8250")cfo.addEntry("private.network.device", self.syscfg.env.nics[0])cfo.addEntry("public.network.device", self.syscfg.env.nics[1])cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])cfo.addEntry("guid", str(self.syscfg.env.uuid))cfo.addEntry("resource", "com.cloud.agent.resource.computing.consoleProxyResource")cfo.save()self.syscfg.svo.stopService("cloudstack-agent")self.syscfg.svo.enableService("cloudstack-agent")return Trueexcept:raisedef config(self):if self.syscfg.env.agentMode == "Agent":return self.configAgent()elif self.syscfg.env.agentMode == "myCloud":return self.configMyCloud()elif self.syscfg.env.agentMode == "console":return self.configConsole()def restore(self):return Trueclass sudoersConfig(serviceCfgBase):def __init__(self, syscfg):super(sudoersConfig, self).__init__(syscfg)self.serviceName = "sudoers"def config(self):try:cfo = configFileOps("/etc/sudoers", self)cfo.addEntry("cloud ALL ", "NOPASSWD : /bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount, /usr/bin/keytool")cfo.rmEntry("Defaults", "requiretty", " ")cfo.save()return Trueexcept:raisedef restore(self):return Trueclass firewallConfigServer(firewallConfigBase):def __init__(self, syscfg):super(firewallConfigServer, self).__init__(syscfg)#9090 is used for cluster management serverif self.syscfg.env.svrMode == "myCloud":self.ports = "443 8080 8250 8443 9090".split()else:self.ports = "8080 7080 8250 9090".split()class ubuntuFirewallConfigServer(firewallConfigServer):def allowPort(self, port):status = Falsetry:status = bash("iptables-save|grep INPUT|grep -w %s"%port).isSuccess()except:passif not status:bash("ufw allow %s/tcp"%port)def config(self):try:for port in self.ports:self.allowPort(port)return Trueexcept:raise
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。