mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-25 09:12:38 +02:00
pre-commit: clean up Python flake8 excludes with black (#9793)
This commit is contained in:
parent
0d9c5065de
commit
57309314a1
@ -83,17 +83,6 @@ repos:
|
||||
hooks:
|
||||
- id: flake8
|
||||
args: [--config, .github/linters/.flake8]
|
||||
exclude: >
|
||||
(?x)
|
||||
^agent/bindir/cloud-setup-agent\.in$|
|
||||
^client/bindir/cloud-update-xenserver-licenses\.in$|
|
||||
^cloud-cli/bindir/cloud-tool$|
|
||||
^python/bindir/cloud-grab-dependent-library-versions$|
|
||||
^python/bindir/cloud-setup-baremetal$|
|
||||
^scripts/vm/hypervisor/xenserver/storagePlugin$|
|
||||
^scripts/vm/hypervisor/xenserver/vmopspremium$|
|
||||
^setup/bindir/cloud-setup-encryption\.in$|
|
||||
^venv/.*$
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.45.0
|
||||
hooks:
|
||||
|
||||
@ -35,7 +35,7 @@ for pythonpath in (
|
||||
|
||||
from cloudutils.cloudException import CloudRuntimeException, CloudInternalException
|
||||
from cloudutils.utilities import initLoging, bash
|
||||
from cloudutils.configFileOps import configFileOps
|
||||
from cloudutils.configFileOps import configFileOps
|
||||
from cloudutils.globalEnv import globalEnv
|
||||
from cloudutils.networkConfig import networkConfig
|
||||
from cloudutils.syscfg import sysConfigFactory
|
||||
@ -43,35 +43,41 @@ from cloudutils.serviceConfig import configureLibvirtConfig, configure_libvirt_t
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
def getUserInputs():
|
||||
print("Welcome to the CloudStack Agent Setup:")
|
||||
|
||||
cfo = configFileOps("@AGENTSYSCONFDIR@/agent.properties")
|
||||
oldMgt = cfo.getEntry("host")
|
||||
|
||||
mgtSvr = input("Please input the Management Server Hostname/IP-Address:[%s]"%oldMgt)
|
||||
mgtSvr = input(
|
||||
"Please input the Management Server Hostname/IP-Address:[%s]" % oldMgt
|
||||
)
|
||||
if mgtSvr == "":
|
||||
mgtSvr = oldMgt
|
||||
try:
|
||||
socket.getaddrinfo(mgtSvr, 443)
|
||||
except:
|
||||
print("Failed to resolve %s. Please input a valid hostname or IP-Address."%mgtSvr)
|
||||
print(
|
||||
"Failed to resolve %s. Please input a valid hostname or IP-Address."
|
||||
% mgtSvr
|
||||
)
|
||||
exit(1)
|
||||
|
||||
oldToken = cfo.getEntry("zone")
|
||||
zoneToken = input("Please input the Zone Id:[%s]"%oldToken)
|
||||
zoneToken = input("Please input the Zone Id:[%s]" % oldToken)
|
||||
|
||||
if zoneToken == "":
|
||||
zoneToken = oldToken
|
||||
|
||||
oldPod = cfo.getEntry("pod")
|
||||
podId = input("Please input the Pod Id:[%s]"%oldPod)
|
||||
podId = input("Please input the Pod Id:[%s]" % oldPod)
|
||||
|
||||
if podId == "":
|
||||
podId = oldToken
|
||||
podId = oldToken
|
||||
|
||||
oldCluster = cfo.getEntry("cluster")
|
||||
clusterId = input("Please input the Cluster Id:[%s]"%oldCluster)
|
||||
clusterId = input("Please input the Cluster Id:[%s]" % oldCluster)
|
||||
if clusterId == "":
|
||||
clusterId = oldCluster
|
||||
|
||||
@ -79,18 +85,20 @@ def getUserInputs():
|
||||
if oldHypervisor == "":
|
||||
oldHypervisor = "kvm"
|
||||
|
||||
hypervisor = input("Please input the Hypervisor type kvm/lxc:[%s]"%oldHypervisor)
|
||||
hypervisor = input("Please input the Hypervisor type kvm/lxc:[%s]" % oldHypervisor)
|
||||
if hypervisor == "":
|
||||
hypervisor = oldHypervisor
|
||||
|
||||
try:
|
||||
defaultNic = networkConfig.getDefaultNetwork()
|
||||
except:
|
||||
print("Failed to get default route. Please configure your network to have a default route")
|
||||
print(
|
||||
"Failed to get default route. Please configure your network to have a default route"
|
||||
)
|
||||
exit(1)
|
||||
|
||||
defNic = defaultNic.name
|
||||
network = input("Please choose which network used to create VM:[%s]"%defNic)
|
||||
network = input("Please choose which network used to create VM:[%s]" % defNic)
|
||||
if network == "":
|
||||
if defNic == "":
|
||||
print("You need to specify one of Nic or bridge on your system")
|
||||
@ -100,7 +108,8 @@ def getUserInputs():
|
||||
|
||||
return [mgtSvr, zoneToken, network, podId, clusterId, hypervisor]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
initLoging("@AGENTLOGDIR@/setup.log")
|
||||
glbEnv = globalEnv()
|
||||
|
||||
@ -108,13 +117,23 @@ if __name__ == '__main__':
|
||||
glbEnv.agentMode = "Agent"
|
||||
parser = OptionParser()
|
||||
parser.add_option("-a", action="store_true", dest="auto", help="auto mode")
|
||||
parser.add_option("-m", "--host", dest="mgt", help="Management server hostname or IP-Address")
|
||||
parser.add_option(
|
||||
"-m", "--host", dest="mgt", help="Management server hostname or IP-Address"
|
||||
)
|
||||
parser.add_option("-z", "--zone", dest="zone", help="zone id")
|
||||
parser.add_option("-p", "--pod", dest="pod", help="pod id")
|
||||
parser.add_option("-c", "--cluster", dest="cluster", help="cluster id")
|
||||
parser.add_option("-t", "--hypervisor", default="kvm", dest="hypervisor", help="hypervisor type")
|
||||
parser.add_option(
|
||||
"-t", "--hypervisor", default="kvm", dest="hypervisor", help="hypervisor type"
|
||||
)
|
||||
parser.add_option("-g", "--guid", dest="guid", help="guid")
|
||||
parser.add_option("-s", action="store_true", default=False, dest="secure", help="Secure and enable TLS for libvirtd")
|
||||
parser.add_option(
|
||||
"-s",
|
||||
action="store_true",
|
||||
default=False,
|
||||
dest="secure",
|
||||
help="Secure and enable TLS for libvirtd",
|
||||
)
|
||||
parser.add_option("--pubNic", dest="pubNic", help="Public traffic interface")
|
||||
parser.add_option("--prvNic", dest="prvNic", help="Private traffic interface")
|
||||
parser.add_option("--guestNic", dest="guestNic", help="Guest traffic interface")
|
||||
@ -140,15 +159,15 @@ if __name__ == '__main__':
|
||||
glbEnv.pod = userInputs[3]
|
||||
glbEnv.cluster = userInputs[4]
|
||||
glbEnv.hypervisor = userInputs[5]
|
||||
#generate UUID
|
||||
# generate UUID
|
||||
glbEnv.uuid = old_config.getEntry("guid")
|
||||
if glbEnv.uuid == "":
|
||||
glbEnv.uuid = bash("uuidgen").getStdout()
|
||||
else:
|
||||
for para, value in list(options.__dict__.items()):
|
||||
if value is None:
|
||||
print("Missing operand:%s"%para)
|
||||
print("Try %s --help for more information"%sys.argv[0])
|
||||
print("Missing operand:%s" % para)
|
||||
print("Try %s --help for more information" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
glbEnv.uuid = options.guid
|
||||
@ -168,7 +187,7 @@ if __name__ == '__main__':
|
||||
try:
|
||||
syscfg.config()
|
||||
print("CloudStack Agent setup is done!")
|
||||
except (CloudRuntimeException,CloudInternalException) as e:
|
||||
except (CloudRuntimeException, CloudInternalException) as e:
|
||||
print(e)
|
||||
print("Try to restore your system:")
|
||||
try:
|
||||
|
||||
@ -34,16 +34,19 @@ from threading import Thread
|
||||
# ---- 2) waf configured PYTHONDIR
|
||||
# ---- 3) System Python path
|
||||
for pythonpath in (
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
||||
):
|
||||
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(
|
||||
os.path.dirname(__file__), os.path.pardir, os.path.pardir, "python", "lib"
|
||||
),
|
||||
):
|
||||
if os.path.isdir(pythonpath):
|
||||
sys.path.insert(0, pythonpath)
|
||||
# ---- End snippet of code ----
|
||||
from cloud_utils import check_call, CalledProcessError, read_properties
|
||||
|
||||
cfg = "@MSCONF@/db.properties"
|
||||
|
||||
#---------------------- option parsing and command line checks ------------------------
|
||||
# ---------------------- option parsing and command line checks ------------------------
|
||||
|
||||
|
||||
usage = """%prog <license file> <-a | host names / IP addresses...>
|
||||
@ -51,132 +54,171 @@ usage = """%prog <license file> <-a | host names / IP addresses...>
|
||||
This command deploys the license file specified in the command line into a specific XenServer host or all XenServer hosts known to the management server."""
|
||||
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-a", "--all", action="store_true", dest="all", default=False,
|
||||
help="deploy to all known hosts rather that a single host")
|
||||
parser.add_option(
|
||||
"-a",
|
||||
"--all",
|
||||
action="store_true",
|
||||
dest="all",
|
||||
default=False,
|
||||
help="deploy to all known hosts rather that a single host",
|
||||
)
|
||||
|
||||
#------------------ functions --------------------
|
||||
# ------------------ functions --------------------
|
||||
|
||||
def e(msg): parser.error(msg)
|
||||
|
||||
def getknownhosts(host,username,password):
|
||||
conn = mysql.connector.connect(host=host, user=username, password=password)
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT h.private_ip_address,d.value FROM cloud.host h inner join cloud.host_details d on (h.id = d.host_id) where d.name = 'username' and setup = 1")
|
||||
usernames = dict(cur.fetchall())
|
||||
cur.execute("SELECT h.private_ip_address,d.value FROM cloud.host h inner join cloud.host_details d on (h.id = d.host_id) where d.name = 'password' and setup = 1")
|
||||
passwords = dict(cur.fetchall())
|
||||
creds = dict( [ [x,(usernames[x],passwords[x])] for x in list(usernames.keys()) ] )
|
||||
cur.close()
|
||||
conn.close()
|
||||
return creds
|
||||
def e(msg):
|
||||
parser.error(msg)
|
||||
|
||||
|
||||
def getknownhosts(host, username, password):
|
||||
conn = mysql.connector.connect(host=host, user=username, password=password)
|
||||
cur = conn.cursor()
|
||||
cur.execute(
|
||||
"SELECT h.private_ip_address,d.value FROM cloud.host h inner join cloud.host_details d on (h.id = d.host_id) where d.name = 'username' and setup = 1"
|
||||
)
|
||||
usernames = dict(cur.fetchall())
|
||||
cur.execute(
|
||||
"SELECT h.private_ip_address,d.value FROM cloud.host h inner join cloud.host_details d on (h.id = d.host_id) where d.name = 'password' and setup = 1"
|
||||
)
|
||||
passwords = dict(cur.fetchall())
|
||||
creds = dict([[x, (usernames[x], passwords[x])] for x in list(usernames.keys())])
|
||||
cur.close()
|
||||
conn.close()
|
||||
return creds
|
||||
|
||||
|
||||
def splitlast(string, splitter):
|
||||
splitted = string.split(splitter)
|
||||
first, last = splitter.join(splitted[:-1]), splitted[-1]
|
||||
return first, last
|
||||
|
||||
def splitlast(string,splitter):
|
||||
splitted = string.split(splitter)
|
||||
first,last = splitter.join(splitted[:-1]),splitted[-1]
|
||||
return first,last
|
||||
|
||||
def parseuserpwfromhosts(hosts):
|
||||
creds = {}
|
||||
for host in hosts:
|
||||
user = "root"
|
||||
password = ""
|
||||
if "@" in host:
|
||||
user,host = splitlast(host,"@")
|
||||
if ":" in user:
|
||||
user,password = splitlast(user,":")
|
||||
creds[host] = (user,password)
|
||||
return creds
|
||||
creds = {}
|
||||
for host in hosts:
|
||||
user = "root"
|
||||
password = ""
|
||||
if "@" in host:
|
||||
user, host = splitlast(host, "@")
|
||||
if ":" in user:
|
||||
user, password = splitlast(user, ":")
|
||||
creds[host] = (user, password)
|
||||
return creds
|
||||
|
||||
|
||||
class XenServerConfigurator(Thread):
|
||||
|
||||
def __init__(self,host,user,password,keyfiledata):
|
||||
Thread.__init__(self)
|
||||
self.host = host
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.keyfiledata = keyfiledata
|
||||
self.retval = None # means all's good
|
||||
self.stdout = ""
|
||||
self.stderr = ""
|
||||
self.state = 'initialized'
|
||||
def __init__(self, host, user, password, keyfiledata):
|
||||
Thread.__init__(self)
|
||||
self.host = host
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.keyfiledata = keyfiledata
|
||||
self.retval = None # means all's good
|
||||
self.stdout = ""
|
||||
self.stderr = ""
|
||||
self.state = "initialized"
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self.state = 'running'
|
||||
c = paramiko.SSHClient()
|
||||
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
c.connect(self.host,username=self.user,password=self.password)
|
||||
sftp = c.open_sftp()
|
||||
sftp.chdir("/tmp")
|
||||
f = sftp.open("xen-license","w")
|
||||
f.write(self.keyfiledata)
|
||||
f.close()
|
||||
sftp.close()
|
||||
stdin,stdout,stderr = c.exec_command("xe host-license-add license-file=/tmp/xen-license")
|
||||
c.exec_command("false")
|
||||
self.stdout = stdout.read(-1)
|
||||
self.stderr = stderr.read(-1)
|
||||
self.retval = stdin.channel.recv_exit_status()
|
||||
c.close()
|
||||
if self.retval != 0: self.state = 'failed'
|
||||
else: self.state = 'finished'
|
||||
def run(self):
|
||||
try:
|
||||
self.state = "running"
|
||||
c = paramiko.SSHClient()
|
||||
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
c.connect(self.host, username=self.user, password=self.password)
|
||||
sftp = c.open_sftp()
|
||||
sftp.chdir("/tmp")
|
||||
f = sftp.open("xen-license", "w")
|
||||
f.write(self.keyfiledata)
|
||||
f.close()
|
||||
sftp.close()
|
||||
stdin, stdout, stderr = c.exec_command(
|
||||
"xe host-license-add license-file=/tmp/xen-license"
|
||||
)
|
||||
c.exec_command("false")
|
||||
self.stdout = stdout.read(-1)
|
||||
self.stderr = stderr.read(-1)
|
||||
self.retval = stdin.channel.recv_exit_status()
|
||||
c.close()
|
||||
if self.retval != 0:
|
||||
self.state = "failed"
|
||||
else:
|
||||
self.state = "finished"
|
||||
|
||||
except Exception as e:
|
||||
self.state = 'failed'
|
||||
self.retval = e
|
||||
#raise
|
||||
except Exception as e:
|
||||
self.state = "failed"
|
||||
self.retval = e
|
||||
# raise
|
||||
|
||||
def __str__(self):
|
||||
if self.state == 'failed':
|
||||
return "<%s XenServerConfigurator on %s@%s: %s>"%(self.state,self.user,self.host,str(self.retval))
|
||||
else:
|
||||
return "<%s XenServerConfigurator on %s@%s>"%(self.state,self.user,self.host)
|
||||
def __str__(self):
|
||||
if self.state == "failed":
|
||||
return "<%s XenServerConfigurator on %s@%s: %s>" % (
|
||||
self.state,
|
||||
self.user,
|
||||
self.host,
|
||||
str(self.retval),
|
||||
)
|
||||
else:
|
||||
return "<%s XenServerConfigurator on %s@%s>" % (
|
||||
self.state,
|
||||
self.user,
|
||||
self.host,
|
||||
)
|
||||
|
||||
#------------- actual code --------------------
|
||||
|
||||
# ------------- actual code --------------------
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
try:
|
||||
licensefile,args = args[0],args[1:]
|
||||
except IndexError: e("The first argument must be the license file to use")
|
||||
licensefile, args = args[0], args[1:]
|
||||
except IndexError:
|
||||
e("The first argument must be the license file to use")
|
||||
|
||||
if options.all:
|
||||
if len(args) != 0: e("IP addresses cannot be specified if -a is specified")
|
||||
config = read_properties(cfg)
|
||||
creds = getknownhosts(config["db.cloud.host"],config["db.cloud.username"],config["db.cloud.password"])
|
||||
hosts = list(creds.keys())
|
||||
if len(args) != 0:
|
||||
e("IP addresses cannot be specified if -a is specified")
|
||||
config = read_properties(cfg)
|
||||
creds = getknownhosts(
|
||||
config["db.cloud.host"],
|
||||
config["db.cloud.username"],
|
||||
config["db.cloud.password"],
|
||||
)
|
||||
hosts = list(creds.keys())
|
||||
else:
|
||||
if not args: e("You must specify at least one IP address, or -a")
|
||||
hosts = args
|
||||
creds = parseuserpwfromhosts(hosts)
|
||||
if not args:
|
||||
e("You must specify at least one IP address, or -a")
|
||||
hosts = args
|
||||
creds = parseuserpwfromhosts(hosts)
|
||||
|
||||
try:
|
||||
keyfiledata = file(licensefile).read(-1)
|
||||
keyfiledata = file(licensefile).read(-1)
|
||||
except OSError as e:
|
||||
sys.stderr.write("The file %s cannot be opened"%licensefile)
|
||||
sys.exit(1)
|
||||
sys.stderr.write("The file %s cannot be opened" % licensefile)
|
||||
sys.exit(1)
|
||||
|
||||
configurators = []
|
||||
for host,(user,password) in list(creds.items()):
|
||||
configurators.append ( XenServerConfigurator(host,user,password,keyfiledata ) )
|
||||
for host, (user, password) in list(creds.items()):
|
||||
configurators.append(XenServerConfigurator(host, user, password, keyfiledata))
|
||||
|
||||
|
||||
for c in configurators: c.start()
|
||||
|
||||
for c in configurators:
|
||||
print(c.host + "...", end=' ')
|
||||
c.join()
|
||||
if c.state == 'failed':
|
||||
if c.retval:
|
||||
msg = "failed with return code %s: %s%s"%(c.retval,c.stdout,c.stderr)
|
||||
msg = msg.strip()
|
||||
print(msg)
|
||||
else: print("failed: %s"%c.retval)
|
||||
else:
|
||||
print("done")
|
||||
c.start()
|
||||
|
||||
successes = len( [ a for a in configurators if not a.state == 'failed' ] )
|
||||
failures = len( [ a for a in configurators if a.state == 'failed' ] )
|
||||
for c in configurators:
|
||||
print(c.host + "...", end=" ")
|
||||
c.join()
|
||||
if c.state == "failed":
|
||||
if c.retval:
|
||||
msg = "failed with return code %s: %s%s" % (c.retval, c.stdout, c.stderr)
|
||||
msg = msg.strip()
|
||||
print(msg)
|
||||
else:
|
||||
print("failed: %s" % c.retval)
|
||||
else:
|
||||
print("done")
|
||||
|
||||
print("%3s successes"%successes)
|
||||
print("%3s failures"%failures)
|
||||
successes = len([a for a in configurators if not a.state == "failed"])
|
||||
failures = len([a for a in configurators if a.state == "failed"])
|
||||
|
||||
print("%3s successes" % successes)
|
||||
print("%3s failures" % failures)
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
# 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
|
||||
@ -25,4 +25,5 @@ sys.path.append(os.path.dirname(os.path.dirname(__file__)))
|
||||
import cloudtool
|
||||
|
||||
ret = cloudtool.main()
|
||||
if ret: sys.exit(ret)
|
||||
if ret:
|
||||
sys.exit(ret)
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
# 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
|
||||
@ -18,64 +18,99 @@
|
||||
|
||||
import subprocess
|
||||
|
||||
depLibraries = ['bzip2', 'gzip', 'unzip', 'openssh-clients', 'nfs-utils', 'wget', 'ws-commons-util', 'commons-dbcp',
|
||||
'commons-collections', 'commons-httpclient', 'jpackage-utils', 'mysql-connector-python3', 'python-paramiko', 'ipmitool', 'commons-httpclient', 'commons-collections',
|
||||
'commons-pool', 'commons-dbcp', 'jakarta-commons-logging', 'java-*-openjdk']
|
||||
depLibraries = [
|
||||
"bzip2",
|
||||
"gzip",
|
||||
"unzip",
|
||||
"openssh-clients",
|
||||
"nfs-utils",
|
||||
"wget",
|
||||
"ws-commons-util",
|
||||
"commons-dbcp",
|
||||
"commons-collections",
|
||||
"commons-httpclient",
|
||||
"jpackage-utils",
|
||||
"mysql-connector-python3",
|
||||
"python-paramiko",
|
||||
"ipmitool",
|
||||
"commons-httpclient",
|
||||
"commons-collections",
|
||||
"commons-pool",
|
||||
"commons-dbcp",
|
||||
"jakarta-commons-logging",
|
||||
"java-*-openjdk",
|
||||
]
|
||||
|
||||
|
||||
def runCmd(cmds):
|
||||
process = subprocess.Popen(' '.join(cmds), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
process = subprocess.Popen(
|
||||
" ".join(cmds), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
stdout, stderr = process.communicate()
|
||||
if process.returncode != 0:
|
||||
raise Exception(stderr.decode('utf-8'))
|
||||
return stdout.decode('utf-8')
|
||||
raise Exception(stderr.decode("utf-8"))
|
||||
return stdout.decode("utf-8")
|
||||
|
||||
|
||||
def getDependentLibraryInfo():
|
||||
def getVersion(res, pkgname):
|
||||
start = False
|
||||
for l in res.split('\n'):
|
||||
for l in res.split("\n"):
|
||||
if "Installed Packages" in l:
|
||||
start = True
|
||||
continue
|
||||
if not start: continue
|
||||
|
||||
(key, value) = l.split(':', 2)
|
||||
if not start:
|
||||
continue
|
||||
|
||||
(key, value) = l.split(":", 2)
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
if key == 'Name' and "*" not in pkgname and pkgname not in value:
|
||||
print("Required package name %s doesn't equal to package %s installed"%(pkgname, value))
|
||||
return 'UNKNOWN'
|
||||
if 'Version' in key: return value
|
||||
if 'Description' in key: return 'UNKNOWN' # we hit the end
|
||||
return 'UNKNOWN'
|
||||
if key == "Name" and "*" not in pkgname and pkgname not in value:
|
||||
print(
|
||||
"Required package name %s doesn't equal to package %s installed"
|
||||
% (pkgname, value)
|
||||
)
|
||||
return "UNKNOWN"
|
||||
if "Version" in key:
|
||||
return value
|
||||
if "Description" in key:
|
||||
return "UNKNOWN" # we hit the end
|
||||
return "UNKNOWN"
|
||||
|
||||
libraryMap = {}
|
||||
for l in depLibraries:
|
||||
cmd = ['yum', 'info', '"%s"'%l]
|
||||
cmd = ["yum", "info", '"%s"' % l]
|
||||
try:
|
||||
result = runCmd(cmd)
|
||||
version = getVersion(result, l)
|
||||
libraryMap[l] = version
|
||||
except Exception as e:
|
||||
print("When finding %s, encounters %s"%(l, e))
|
||||
print("When finding %s, encounters %s" % (l, e))
|
||||
continue
|
||||
return libraryMap
|
||||
|
||||
|
||||
def arrangeOutPut(libraryMap):
|
||||
msg = ['\n\n\nBelow is the checking list of library version that CloudStack depends on:']
|
||||
msg = [
|
||||
"\n\n\nBelow is the checking list of library version that CloudStack depends on:"
|
||||
]
|
||||
for l in depLibraries:
|
||||
if l in libraryMap:
|
||||
entry = "%-40s: %s"%(l, libraryMap[l])
|
||||
entry = "%-40s: %s" % (l, libraryMap[l])
|
||||
else:
|
||||
entry = "%-40s: %s"%(l, 'UNKNOWN')
|
||||
entry = "%-40s: %s" % (l, "UNKNOWN")
|
||||
msg.append(entry)
|
||||
print('\n'.join(msg))
|
||||
|
||||
if __name__ == '__main__':
|
||||
pythonDepLibraries = ['python', 'python3']
|
||||
relver = runCmd(['rpm', '-q', 'centos-release'])
|
||||
if relver.startswith('centos-release-') and int(relver[len('centos-release-')]) >= 8:
|
||||
pythonDepLibraries = ['python2', 'python36']
|
||||
print("\n".join(msg))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pythonDepLibraries = ["python", "python3"]
|
||||
relver = runCmd(["rpm", "-q", "centos-release"])
|
||||
if (
|
||||
relver.startswith("centos-release-")
|
||||
and int(relver[len("centos-release-")]) >= 8
|
||||
):
|
||||
pythonDepLibraries = ["python2", "python36"]
|
||||
depLibraries = pythonDepLibraries + depLibraries
|
||||
|
||||
arrangeOutPut(getDependentLibraryInfo())
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
# 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
|
||||
@ -23,11 +23,15 @@ import traceback
|
||||
from os.path import exists, join
|
||||
from signal import alarm, signal, SIGALRM, SIGKILL
|
||||
|
||||
|
||||
class CloudRuntimeException(Exception):
|
||||
def __init__(self, errMsg):
|
||||
self.errMsg = errMsg
|
||||
|
||||
def __str__(self):
|
||||
return self.errMsg
|
||||
|
||||
|
||||
def formatExceptionInfo(maxTBlevel=5):
|
||||
cla, exc, trbk = sys.exc_info()
|
||||
excTb = traceback.format_tb(trbk, maxTBlevel)
|
||||
@ -36,10 +40,11 @@ def formatExceptionInfo(maxTBlevel=5):
|
||||
msg += tb
|
||||
return msg
|
||||
|
||||
|
||||
class bash:
|
||||
def __init__(self, args, timeout=600):
|
||||
self.args = args
|
||||
logging.debug("execute:%s"%args)
|
||||
logging.debug("execute:%s" % args)
|
||||
self.timeout = timeout
|
||||
self.process = None
|
||||
self.success = False
|
||||
@ -48,6 +53,7 @@ class bash:
|
||||
def run(self):
|
||||
class Alarm(Exception):
|
||||
pass
|
||||
|
||||
def alarm_handler(signum, frame):
|
||||
raise Alarm
|
||||
|
||||
@ -63,21 +69,21 @@ class bash:
|
||||
alarm(0)
|
||||
except Alarm:
|
||||
os.kill(self.process.pid, SIGKILL)
|
||||
raise CloudRuntimeException("Timeout during command execution")
|
||||
raise CloudRuntimeException("Timeout during command execution")
|
||||
|
||||
self.success = self.process.returncode == 0
|
||||
except:
|
||||
raise CloudRuntimeException(formatExceptionInfo())
|
||||
raise CloudRuntimeException(formatExceptionInfo())
|
||||
|
||||
# if not self.success:
|
||||
# raise CloudRuntimeException(self.getStderr())
|
||||
# if not self.success:
|
||||
# raise CloudRuntimeException(self.getStderr())
|
||||
|
||||
def isSuccess(self):
|
||||
return self.success
|
||||
|
||||
|
||||
def getStdout(self):
|
||||
return self.stdout.strip("\n")
|
||||
|
||||
|
||||
def getLines(self):
|
||||
return self.stdout.split("\n")
|
||||
|
||||
@ -88,130 +94,150 @@ class bash:
|
||||
def initLoging(logFile=None):
|
||||
try:
|
||||
if logFile is None:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(filename=logFile, level=logging.DEBUG)
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(filename=logFile, level=logging.DEBUG)
|
||||
except:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
def writeProgressBar(msg, result=None):
|
||||
|
||||
def writeProgressBar(msg, result=None):
|
||||
if msg is not None:
|
||||
output = "%-80s"%msg
|
||||
output = "%-80s" % msg
|
||||
elif result is True:
|
||||
output = "[ \033[92m%-2s\033[0m ]\n"%"OK"
|
||||
output = "[ \033[92m%-2s\033[0m ]\n" % "OK"
|
||||
elif result is False:
|
||||
output = "[ \033[91m%-6s\033[0m ]\n"%"FAILED"
|
||||
output = "[ \033[91m%-6s\033[0m ]\n" % "FAILED"
|
||||
sys.stdout.write(output)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
|
||||
def printError(msg):
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.write("\n")
|
||||
sys.stderr.flush()
|
||||
|
||||
|
||||
def printMsg(msg):
|
||||
sys.stdout.write(msg+"\n")
|
||||
sys.stdout.write(msg + "\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def checkRpm(pkgName):
|
||||
chkPkg = bash("rpm -q %s"%pkgName)
|
||||
writeProgressBar("Checking %s"%pkgName, None)
|
||||
chkPkg = bash("rpm -q %s" % pkgName)
|
||||
writeProgressBar("Checking %s" % pkgName, None)
|
||||
if not chkPkg.isSuccess():
|
||||
writeProgressBar(None, False)
|
||||
printError("%s is not found, please make sure it is installed. You may try 'yum install %s'\n"%(pkgName, pkgName))
|
||||
printError(
|
||||
"%s is not found, please make sure it is installed. You may try 'yum install %s'\n"
|
||||
% (pkgName, pkgName)
|
||||
)
|
||||
return False
|
||||
else:
|
||||
writeProgressBar(None, True)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def checkEnv():
|
||||
writeProgressBar("Checking is root")
|
||||
ret = bash("whoami")
|
||||
if ret.getStdout() != "root":
|
||||
writeProgressBar(None, False)
|
||||
printError("This script must run as root")
|
||||
return False
|
||||
else:
|
||||
writeProgressBar(None, True)
|
||||
|
||||
pkgList = ['tftp-server', 'syslinux', 'xinetd', 'chkconfig', 'dhcp']
|
||||
for pkg in pkgList:
|
||||
if not checkRpm(pkg):
|
||||
return False
|
||||
return True
|
||||
writeProgressBar("Checking is root")
|
||||
ret = bash("whoami")
|
||||
if ret.getStdout() != "root":
|
||||
writeProgressBar(None, False)
|
||||
printError("This script must run as root")
|
||||
return False
|
||||
else:
|
||||
writeProgressBar(None, True)
|
||||
|
||||
pkgList = ["tftp-server", "syslinux", "xinetd", "chkconfig", "dhcp"]
|
||||
for pkg in pkgList:
|
||||
if not checkRpm(pkg):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def exitIfFail(ret):
|
||||
if not ret: sys.exit(1)
|
||||
|
||||
if not ret:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def bashWithResult(cmd):
|
||||
writeProgressBar("Executing '%s'"%cmd)
|
||||
writeProgressBar("Executing '%s'" % cmd)
|
||||
ret = bash(cmd)
|
||||
if not ret.isSuccess():
|
||||
writeProgressBar(None, False)
|
||||
writeProgressBar(ret.getStderr() + '\n')
|
||||
writeProgressBar(ret.getStderr() + "\n")
|
||||
return False
|
||||
else:
|
||||
writeProgressBar(None, True)
|
||||
return True
|
||||
|
||||
def configurePxeStuff():
|
||||
stuff = ['tftp', 'xinetd', 'dhcpd']
|
||||
cmds = ['chkconfig --level 345 %s on' % i for i in stuff]
|
||||
cmds.append('/etc/init.d/xinetd restart')
|
||||
|
||||
|
||||
|
||||
def configurePxeStuff():
|
||||
stuff = ["tftp", "xinetd", "dhcpd"]
|
||||
cmds = ["chkconfig --level 345 %s on" % i for i in stuff]
|
||||
cmds.append("/etc/init.d/xinetd restart")
|
||||
|
||||
for cmd in cmds:
|
||||
if not bashWithResult(cmd): return False
|
||||
|
||||
chkIptable = bash('chkconfig --list iptables')
|
||||
if 'on' in chkIptable.getStdout():
|
||||
if not bashWithResult(cmd):
|
||||
return False
|
||||
|
||||
chkIptable = bash("chkconfig --list iptables")
|
||||
if "on" in chkIptable.getStdout():
|
||||
printMsg("Detected iptables is running, need to open tftp port 69")
|
||||
if not bashWithResult('iptables -I INPUT 1 -p udp --dport 69 -j ACCEPT'): return False
|
||||
if not bashWithResult('/etc/init.d/iptables save'): return False
|
||||
|
||||
return True
|
||||
|
||||
if not bashWithResult("iptables -I INPUT 1 -p udp --dport 69 -j ACCEPT"):
|
||||
return False
|
||||
if not bashWithResult("/etc/init.d/iptables save"):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def getTftpRootDir(tftpRootDirList):
|
||||
tftpRoot = bash("cat /etc/xinetd.d/tftp | grep server_args")
|
||||
if not tftpRoot.isSuccess():
|
||||
printError("Cannot get tftp root directory from /etc/xinetd.d/tftp, here may be something wrong with your tftp-server, try reinstall it\n")
|
||||
printError(
|
||||
"Cannot get tftp root directory from /etc/xinetd.d/tftp, here may be something wrong with your tftp-server, try reinstall it\n"
|
||||
)
|
||||
return False
|
||||
tftpRootDir = tftpRoot.getStdout()
|
||||
index = tftpRootDir.find("/")
|
||||
if index == -1:
|
||||
printError("Wrong server_arg in /etc/xinetd.d/tftp (%s)"%tftpRootDir)
|
||||
printError("Wrong server_arg in /etc/xinetd.d/tftp (%s)" % tftpRootDir)
|
||||
return False
|
||||
tftpRootDir = tftpRootDir[index:]
|
||||
tftpRootDirList.append(tftpRootDir)
|
||||
return True
|
||||
|
||||
|
||||
def preparePING(tftpRootDir):
|
||||
pingFiles = ['boot.msg', 'initrd.gz', 'kernel', 'pxelinux.0']
|
||||
pingFiles = ["boot.msg", "initrd.gz", "kernel", "pxelinux.0"]
|
||||
pingDir = "/usr/share/PING"
|
||||
|
||||
|
||||
for f in pingFiles:
|
||||
path = join(pingDir, f)
|
||||
if not exists(path):
|
||||
printError("Cannot find %s, please make sure PING-3.01 is installed"%path)
|
||||
printError("Cannot find %s, please make sure PING-3.01 is installed" % path)
|
||||
return False
|
||||
if not bashWithResult("cp -f %s %s"%(path, tftpRootDir)): return False
|
||||
|
||||
if not bashWithResult("mkdir -p %s/pxelinux.cfg"%tftpRootDir): return False
|
||||
|
||||
if not bashWithResult("cp -f %s %s" % (path, tftpRootDir)):
|
||||
return False
|
||||
|
||||
if not bashWithResult("mkdir -p %s/pxelinux.cfg" % tftpRootDir):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
initLoging("/tmp/cloud-setup-baremetal.log")
|
||||
tftpRootDirList = []
|
||||
|
||||
|
||||
exitIfFail(checkEnv())
|
||||
exitIfFail(configurePxeStuff())
|
||||
exitIfFail(getTftpRootDir(tftpRootDirList))
|
||||
|
||||
|
||||
tftpRootDir = tftpRootDirList[0].strip()
|
||||
exitIfFail(preparePING(tftpRootDir))
|
||||
printMsg("")
|
||||
printMsg("Setup BareMetal PXE server successfully")
|
||||
printMsg("TFTP root directory is: %s\n"%tftpRootDir)
|
||||
printMsg("TFTP root directory is: %s\n" % tftpRootDir)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
# 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
|
||||
@ -18,11 +18,14 @@
|
||||
|
||||
# Version @VERSION@
|
||||
#
|
||||
# A plugin for executing script needed by vmops cloud
|
||||
# A plugin for executing script needed by vmops cloud
|
||||
|
||||
import os, sys, time
|
||||
import XenAPIPlugin
|
||||
sys.path.extend(["/opt/xensource/sm/", "/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"])
|
||||
|
||||
sys.path.extend(
|
||||
["/opt/xensource/sm/", "/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]
|
||||
)
|
||||
import util
|
||||
import base64
|
||||
import socket
|
||||
@ -37,15 +40,18 @@ import logging
|
||||
|
||||
lib.setup_logging("/var/log/cloud/storageplugin.log")
|
||||
|
||||
|
||||
def echo(fn):
|
||||
def wrapped(*v, **k):
|
||||
name = fn.__name__
|
||||
logging.debug("#### xen plugin enter %s ####" % name )
|
||||
logging.debug("#### xen plugin enter %s ####" % name)
|
||||
res = fn(*v, **k)
|
||||
logging.debug("#### xen plugin exit %s ####" % name )
|
||||
logging.debug("#### xen plugin exit %s ####" % name)
|
||||
return res
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
@echo
|
||||
def downloadTemplateFromUrl(session, args):
|
||||
destPath = args["destPath"]
|
||||
@ -59,17 +65,23 @@ def downloadTemplateFromUrl(session, args):
|
||||
except:
|
||||
logging.debug("exception: " + str(sys.exc_info()))
|
||||
return ""
|
||||
|
||||
|
||||
|
||||
@echo
|
||||
def getTemplateSize(session, args):
|
||||
srcUrl = args["srcUrl"]
|
||||
try:
|
||||
template = urllib2.urlopen(srcUrl)
|
||||
headers = template.info()
|
||||
return str(headers["content-length"])
|
||||
except:
|
||||
return ""
|
||||
srcUrl = args["srcUrl"]
|
||||
try:
|
||||
template = urllib2.urlopen(srcUrl)
|
||||
headers = template.info()
|
||||
return str(headers["content-length"])
|
||||
except:
|
||||
return ""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
XenAPIPlugin.dispatch({"downloadTemplateFromUrl": downloadTemplateFromUrl
|
||||
,"getTemplateSize": getTemplateSize
|
||||
})
|
||||
XenAPIPlugin.dispatch(
|
||||
{
|
||||
"downloadTemplateFromUrl": downloadTemplateFromUrl,
|
||||
"getTemplateSize": getTemplateSize,
|
||||
}
|
||||
)
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
# 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
|
||||
@ -18,10 +18,11 @@
|
||||
|
||||
# Version @VERSION@
|
||||
#
|
||||
# A plugin for executing script needed by vmops cloud
|
||||
# A plugin for executing script needed by vmops cloud
|
||||
|
||||
import os, sys, time
|
||||
import XenAPIPlugin
|
||||
|
||||
if os.path.exists("/opt/xensource/sm"):
|
||||
sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"])
|
||||
if os.path.exists("/usr/lib/xcp/sm"):
|
||||
@ -33,119 +34,147 @@ import logging
|
||||
|
||||
lib.setup_logging("/var/log/cloud/cloud.log")
|
||||
|
||||
|
||||
def echo(fn):
|
||||
def wrapped(*v, **k):
|
||||
name = fn.__name__
|
||||
logging.debug("#### CLOUD enter %s ####" % name )
|
||||
logging.debug("#### CLOUD enter %s ####" % name)
|
||||
res = fn(*v, **k)
|
||||
logging.debug("#### CLOUD exit %s ####" % name )
|
||||
logging.debug("#### CLOUD exit %s ####" % name)
|
||||
return res
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
@echo
|
||||
def forceShutdownVM(session, args):
|
||||
domId = args['domId']
|
||||
domId = args["domId"]
|
||||
try:
|
||||
cmd = ["/opt/xensource/debug/xenops", "destroy_domain", "-domid", domId]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt = '10#failed'
|
||||
txt = "10#failed"
|
||||
return txt
|
||||
|
||||
|
||||
@echo
|
||||
def create_privatetemplate_from_snapshot(session, args):
|
||||
templatePath = args['templatePath']
|
||||
snapshotPath = args['snapshotPath']
|
||||
tmpltLocalDir = args['tmpltLocalDir']
|
||||
templatePath = args["templatePath"]
|
||||
snapshotPath = args["snapshotPath"]
|
||||
tmpltLocalDir = args["tmpltLocalDir"]
|
||||
try:
|
||||
cmd = ["bash", "/opt/cloud/bin/create_privatetemplate_from_snapshot.sh",snapshotPath, templatePath, tmpltLocalDir]
|
||||
cmd = [
|
||||
"bash",
|
||||
"/opt/cloud/bin/create_privatetemplate_from_snapshot.sh",
|
||||
snapshotPath,
|
||||
templatePath,
|
||||
tmpltLocalDir,
|
||||
]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt = '10#failed'
|
||||
txt = "10#failed"
|
||||
return txt
|
||||
|
||||
|
||||
@echo
|
||||
def upgrade_snapshot(session, args):
|
||||
templatePath = args['templatePath']
|
||||
snapshotPath = args['snapshotPath']
|
||||
templatePath = args["templatePath"]
|
||||
snapshotPath = args["snapshotPath"]
|
||||
try:
|
||||
cmd = ["bash", "/opt/cloud/bin/upgrate_snapshot.sh",snapshotPath, templatePath]
|
||||
cmd = ["bash", "/opt/cloud/bin/upgrate_snapshot.sh", snapshotPath, templatePath]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt = '10#failed'
|
||||
txt = "10#failed"
|
||||
return txt
|
||||
|
||||
|
||||
@echo
|
||||
def copy_vhd_to_secondarystorage(session, args):
|
||||
mountpoint = args['mountpoint']
|
||||
vdiuuid = args['vdiuuid']
|
||||
sruuid = args['sruuid']
|
||||
mountpoint = args["mountpoint"]
|
||||
vdiuuid = args["vdiuuid"]
|
||||
sruuid = args["sruuid"]
|
||||
try:
|
||||
cmd = ["bash", "/opt/cloud/bin/copy_vhd_to_secondarystorage.sh", mountpoint, vdiuuid, sruuid]
|
||||
cmd = [
|
||||
"bash",
|
||||
"/opt/cloud/bin/copy_vhd_to_secondarystorage.sh",
|
||||
mountpoint,
|
||||
vdiuuid,
|
||||
sruuid,
|
||||
]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt = '10#failed'
|
||||
txt = "10#failed"
|
||||
return txt
|
||||
|
||||
|
||||
@echo
|
||||
def copy_vhd_from_secondarystorage(session, args):
|
||||
mountpoint = args['mountpoint']
|
||||
sruuid = args['sruuid']
|
||||
namelabel = args['namelabel']
|
||||
mountpoint = args["mountpoint"]
|
||||
sruuid = args["sruuid"]
|
||||
namelabel = args["namelabel"]
|
||||
try:
|
||||
cmd = ["bash", "/opt/cloud/bin/copy_vhd_from_secondarystorage.sh", mountpoint, sruuid, namelabel]
|
||||
cmd = [
|
||||
"bash",
|
||||
"/opt/cloud/bin/copy_vhd_from_secondarystorage.sh",
|
||||
mountpoint,
|
||||
sruuid,
|
||||
namelabel,
|
||||
]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt = '10#failed'
|
||||
txt = "10#failed"
|
||||
return txt
|
||||
|
||||
|
||||
@echo
|
||||
def remove_corrupt_vdi(session, args):
|
||||
vdifile = args['vdifile']
|
||||
vdifile = args["vdifile"]
|
||||
try:
|
||||
cmd = ['rm', '-f', vdifile]
|
||||
cmd = ["rm", "-f", vdifile]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt = '10#failed'
|
||||
txt = "10#failed"
|
||||
return txt
|
||||
|
||||
|
||||
@echo
|
||||
def setup_heartbeat_sr(session, args):
|
||||
host = args['host']
|
||||
sr = args['sr']
|
||||
host = args["host"]
|
||||
sr = args["sr"]
|
||||
try:
|
||||
cmd = ["bash", "/opt/cloud/bin/setup_heartbeat_sr.sh", host, sr]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt = ''
|
||||
txt = ""
|
||||
return txt
|
||||
|
||||
|
||||
@echo
|
||||
def setup_heartbeat_file(session, args):
|
||||
host = args['host']
|
||||
sr = args['sr']
|
||||
add = args['add']
|
||||
host = args["host"]
|
||||
sr = args["sr"]
|
||||
add = args["add"]
|
||||
try:
|
||||
cmd = ["bash", "/opt/cloud/bin/setup_heartbeat_file.sh", host, sr, add]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt = ''
|
||||
txt = ""
|
||||
return txt
|
||||
|
||||
|
||||
|
||||
@echo
|
||||
def heartbeat(session, args):
|
||||
host = args['host']
|
||||
timeout = args['timeout']
|
||||
interval = args['interval']
|
||||
try:
|
||||
cmd = ["/bin/bash", "/opt/cloud/bin/launch_hb.sh", host, timeout, interval]
|
||||
txt = util.pread2(cmd)
|
||||
host = args["host"]
|
||||
timeout = args["timeout"]
|
||||
interval = args["interval"]
|
||||
try:
|
||||
cmd = ["/bin/bash", "/opt/cloud/bin/launch_hb.sh", host, timeout, interval]
|
||||
txt = util.pread2(cmd)
|
||||
except:
|
||||
txt='fail'
|
||||
txt = "fail"
|
||||
return txt
|
||||
|
||||
|
||||
@echo
|
||||
def asmonitor(session, args):
|
||||
try:
|
||||
@ -153,7 +182,21 @@ def asmonitor(session, args):
|
||||
result = perfmod.get_vm_group_perfmon(args)
|
||||
return result
|
||||
except:
|
||||
return 'fail'
|
||||
return "fail"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
XenAPIPlugin.dispatch({"forceShutdownVM":forceShutdownVM, "upgrade_snapshot":upgrade_snapshot, "create_privatetemplate_from_snapshot":create_privatetemplate_from_snapshot, "copy_vhd_to_secondarystorage":copy_vhd_to_secondarystorage, "copy_vhd_from_secondarystorage":copy_vhd_from_secondarystorage, "setup_heartbeat_sr":setup_heartbeat_sr, "setup_heartbeat_file":setup_heartbeat_file, "heartbeat": heartbeat, "asmonitor": asmonitor, "remove_corrupt_vdi": remove_corrupt_vdi})
|
||||
XenAPIPlugin.dispatch(
|
||||
{
|
||||
"forceShutdownVM": forceShutdownVM,
|
||||
"upgrade_snapshot": upgrade_snapshot,
|
||||
"create_privatetemplate_from_snapshot": create_privatetemplate_from_snapshot,
|
||||
"copy_vhd_to_secondarystorage": copy_vhd_to_secondarystorage,
|
||||
"copy_vhd_from_secondarystorage": copy_vhd_from_secondarystorage,
|
||||
"setup_heartbeat_sr": setup_heartbeat_sr,
|
||||
"setup_heartbeat_file": setup_heartbeat_file,
|
||||
"heartbeat": heartbeat,
|
||||
"asmonitor": asmonitor,
|
||||
"remove_corrupt_vdi": remove_corrupt_vdi,
|
||||
}
|
||||
)
|
||||
|
||||
@ -31,25 +31,33 @@ import shutil
|
||||
|
||||
# squelch mysqldb spurious warnings
|
||||
import warnings
|
||||
warnings.simplefilter('ignore')
|
||||
|
||||
warnings.simplefilter("ignore")
|
||||
# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
|
||||
# ---- We do this so cloud_utils can be looked up in the following order:
|
||||
# ---- 1) Sources directory
|
||||
# ---- 2) waf configured PYTHONDIR
|
||||
# ---- 3) System Python path
|
||||
for pythonpath in (
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
||||
):
|
||||
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(
|
||||
os.path.dirname(__file__), os.path.pardir, os.path.pardir, "python", "lib"
|
||||
),
|
||||
):
|
||||
if os.path.isdir(pythonpath):
|
||||
sys.path.insert(0, pythonpath)
|
||||
# ---- End snippet of code ----
|
||||
|
||||
|
||||
def runCmd(cmds):
|
||||
process = subprocess.Popen(' '.join(cmds), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
process = subprocess.Popen(
|
||||
" ".join(cmds), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
stdout, stderr = process.communicate()
|
||||
if process.returncode != 0:
|
||||
raise Exception(stderr)
|
||||
return stdout.decode('utf-8')
|
||||
return stdout.decode("utf-8")
|
||||
|
||||
|
||||
class DBDeployer(object):
|
||||
parser = None
|
||||
@ -62,15 +70,15 @@ class DBDeployer(object):
|
||||
dbConfPath = r"@MSCONF@"
|
||||
dbDotProperties = {}
|
||||
dbDotPropertiesIndex = 0
|
||||
encryptionKeyFile = '@MSCONF@/key'
|
||||
encryptionJarPath = '@COMMONLIBDIR@/lib/cloudstack-utils.jar'
|
||||
encryptionKeyFile = "@MSCONF@/key"
|
||||
encryptionJarPath = "@COMMONLIBDIR@/lib/cloudstack-utils.jar"
|
||||
success = False
|
||||
magicString = 'This_is_a_magic_string_i_think_no_one_will_duplicate'
|
||||
magicString = "This_is_a_magic_string_i_think_no_one_will_duplicate"
|
||||
|
||||
def preRun(self):
|
||||
def backUpDbDotProperties():
|
||||
dbpPath = os.path.join(self.dbConfPath, 'db.properties')
|
||||
copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
|
||||
dbpPath = os.path.join(self.dbConfPath, "db.properties")
|
||||
copyPath = os.path.join(self.dbConfPath, "db.properties.origin")
|
||||
|
||||
if os.path.isfile(dbpPath):
|
||||
shutil.copy2(dbpPath, copyPath)
|
||||
@ -79,8 +87,8 @@ class DBDeployer(object):
|
||||
|
||||
def postRun(self):
|
||||
def cleanOrRecoverDbDotProperties():
|
||||
dbpPath = os.path.join(self.dbConfPath, 'db.properties')
|
||||
copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
|
||||
dbpPath = os.path.join(self.dbConfPath, "db.properties")
|
||||
copyPath = os.path.join(self.dbConfPath, "db.properties.origin")
|
||||
if os.path.isfile(copyPath):
|
||||
if not self.success:
|
||||
shutil.copy2(copyPath, dbpPath)
|
||||
@ -88,21 +96,20 @@ class DBDeployer(object):
|
||||
|
||||
cleanOrRecoverDbDotProperties()
|
||||
|
||||
|
||||
def info(self, msg, result=None):
|
||||
output = ""
|
||||
if msg is not None:
|
||||
output = "%-80s"%msg
|
||||
output = "%-80s" % msg
|
||||
|
||||
if result is True:
|
||||
output += "[ \033[92m%-2s\033[0m ]\n"%"OK"
|
||||
output += "[ \033[92m%-2s\033[0m ]\n" % "OK"
|
||||
elif result is False:
|
||||
output += "[ \033[91m%-6s\033[0m ]\n"%"FAILED"
|
||||
output += "[ \033[91m%-6s\033[0m ]\n" % "FAILED"
|
||||
sys.stdout.write(output)
|
||||
sys.stdout.flush()
|
||||
|
||||
def debug(self, msg):
|
||||
msg = "DEBUG:%s"%msg
|
||||
msg = "DEBUG:%s" % msg
|
||||
sys.stdout.write(msg)
|
||||
sys.stdout.flush()
|
||||
|
||||
@ -122,7 +129,8 @@ class DBDeployer(object):
|
||||
|
||||
def errorAndExit(self, msg):
|
||||
self.postRun()
|
||||
err = '''\n\nWe apologize for below error:
|
||||
err = (
|
||||
"""\n\nWe apologize for below error:
|
||||
***************************************************************
|
||||
%s
|
||||
***************************************************************
|
||||
@ -131,36 +139,48 @@ Please run:
|
||||
cloud-setup-encryption -h
|
||||
|
||||
for full help
|
||||
''' % msg
|
||||
"""
|
||||
% msg
|
||||
)
|
||||
sys.stderr.write(err)
|
||||
sys.stderr.flush()
|
||||
sys.exit(1)
|
||||
|
||||
def prepareDBFiles(self):
|
||||
def prepareDBDotProperties():
|
||||
dbpPath = os.path.join(self.dbConfPath, 'db.properties')
|
||||
dbpPath = os.path.join(self.dbConfPath, "db.properties")
|
||||
dbproperties = file(dbpPath).read().splitlines()
|
||||
newdbp = []
|
||||
emptyLine = 0
|
||||
for line in dbproperties:
|
||||
passed = False
|
||||
line = line.strip()
|
||||
if line.startswith("#"): key = line; value = ''; passed = True
|
||||
if line == '' or line == '\n': key = self.magicString + str(emptyLine); value = ''; emptyLine += 1; passed = True
|
||||
if line.startswith("#"):
|
||||
key = line
|
||||
value = ""
|
||||
passed = True
|
||||
if line == "" or line == "\n":
|
||||
key = self.magicString + str(emptyLine)
|
||||
value = ""
|
||||
emptyLine += 1
|
||||
passed = True
|
||||
|
||||
try:
|
||||
if not passed:
|
||||
(key, value) = line.split('=', 1)
|
||||
(key, value) = line.split("=", 1)
|
||||
except Exception as e:
|
||||
err = '''Wrong format in %s (%s):
|
||||
err = """Wrong format in %s (%s):
|
||||
Besides comments beginning "#" and empty line, all key-value pairs must be in formula of
|
||||
key=value
|
||||
for example:
|
||||
db.cloud.username = cloud
|
||||
''' % (dbpPath, line)
|
||||
""" % (
|
||||
dbpPath,
|
||||
line,
|
||||
)
|
||||
self.errorAndExit(err)
|
||||
self.putDbProperty(key, value)
|
||||
self.info("Preparing %s"%dbpPath, True)
|
||||
self.info("Preparing %s" % dbpPath, True)
|
||||
|
||||
prepareDBDotProperties()
|
||||
|
||||
@ -172,41 +192,69 @@ for example:
|
||||
if key.startswith("#"):
|
||||
entries.insert(index, key)
|
||||
elif key.startswith(self.magicString):
|
||||
entries.insert(index, '')
|
||||
entries.insert(index, "")
|
||||
else:
|
||||
entries.insert(index, "%s=%s"%(key, value))
|
||||
file(os.path.join(self.dbConfPath, 'db.properties'), 'w').write('\n'.join(entries))
|
||||
entries.insert(index, "%s=%s" % (key, value))
|
||||
file(os.path.join(self.dbConfPath, "db.properties"), "w").write(
|
||||
"\n".join(entries)
|
||||
)
|
||||
|
||||
self.info("Finalizing setup ...", None)
|
||||
finalizeDbProperties()
|
||||
self.info(None, True)
|
||||
self.success = True # At here, we have done successfully and nothing more after this flag is set
|
||||
self.success = True # At here, we have done successfully and nothing more after this flag is set
|
||||
|
||||
def processEncryptionStuff(self):
|
||||
def encrypt(value):
|
||||
cmd = ['java','-classpath','"' + self.encryptionJarPath + '"','com.cloud.utils.crypt.EncryptionCLI','-i','"' + value + '"', '-p', '"' + self.mgmtsecretkey + '"']
|
||||
return runCmd(cmd).strip('\n')
|
||||
cmd = [
|
||||
"java",
|
||||
"-classpath",
|
||||
'"' + self.encryptionJarPath + '"',
|
||||
"com.cloud.utils.crypt.EncryptionCLI",
|
||||
"-i",
|
||||
'"' + value + '"',
|
||||
"-p",
|
||||
'"' + self.mgmtsecretkey + '"',
|
||||
]
|
||||
return runCmd(cmd).strip("\n")
|
||||
|
||||
def saveMgmtServerSecretKey():
|
||||
if self.encryptiontype == 'file':
|
||||
file(self.encryptionKeyFile, 'w').write(self.mgmtsecretkey)
|
||||
if self.encryptiontype == "file":
|
||||
file(self.encryptionKeyFile, "w").write(self.mgmtsecretkey)
|
||||
|
||||
def formatEncryptResult(value):
|
||||
return 'ENC(%s)'%value
|
||||
return "ENC(%s)" % value
|
||||
|
||||
def encryptDBSecretKey():
|
||||
self.putDbProperty('db.cloud.encrypt.secret', formatEncryptResult(encrypt(self.dbsecretkey)))
|
||||
self.putDbProperty(
|
||||
"db.cloud.encrypt.secret",
|
||||
formatEncryptResult(encrypt(self.dbsecretkey)),
|
||||
)
|
||||
|
||||
def encryptDBPassword():
|
||||
dbPassword = self.getDbProperty('db.cloud.password')
|
||||
if dbPassword == '': return # Don't encrypt empty password
|
||||
if dbPassword == None: self.errorAndExit('Cannot find db.cloud.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
|
||||
self.putDbProperty('db.cloud.password', formatEncryptResult(encrypt(dbPassword)))
|
||||
dbPassword = self.getDbProperty("db.cloud.password")
|
||||
if dbPassword == "":
|
||||
return # Don't encrypt empty password
|
||||
if dbPassword == None:
|
||||
self.errorAndExit(
|
||||
"Cannot find db.cloud.password in %s"
|
||||
% os.path.join(self.dbConfPath, "db.properties")
|
||||
)
|
||||
self.putDbProperty(
|
||||
"db.cloud.password", formatEncryptResult(encrypt(dbPassword))
|
||||
)
|
||||
|
||||
usagePassword = self.getDbProperty('db.usage.password')
|
||||
if usagePassword == '': return # Don't encrypt empty password
|
||||
if usagePassword == None: self.errorAndExit('Cannot find db.usage.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
|
||||
self.putDbProperty('db.usage.password', formatEncryptResult(encrypt(usagePassword)))
|
||||
usagePassword = self.getDbProperty("db.usage.password")
|
||||
if usagePassword == "":
|
||||
return # Don't encrypt empty password
|
||||
if usagePassword == None:
|
||||
self.errorAndExit(
|
||||
"Cannot find db.usage.password in %s"
|
||||
% os.path.join(self.dbConfPath, "db.properties")
|
||||
)
|
||||
self.putDbProperty(
|
||||
"db.usage.password", formatEncryptResult(encrypt(usagePassword))
|
||||
)
|
||||
|
||||
self.info("Processing encryption ...", None)
|
||||
self.putDbProperty("db.cloud.encryption.type", self.encryptiontype)
|
||||
@ -222,26 +270,55 @@ for example:
|
||||
self.dbsecretkey = self.options.dbsecretkey
|
||||
self.isDebug = self.options.debug
|
||||
|
||||
|
||||
def validateParameters():
|
||||
if self.encryptiontype != 'file' and self.encryptiontype != 'web':
|
||||
self.errorAndExit('Wrong encryption type %s, --encrypt-type can only be "file" or "web'%self.encryptiontype)
|
||||
if self.encryptiontype != "file" and self.encryptiontype != "web":
|
||||
self.errorAndExit(
|
||||
'Wrong encryption type %s, --encrypt-type can only be "file" or "web'
|
||||
% self.encryptiontype
|
||||
)
|
||||
|
||||
#---------------------- option parsing and command line checks ------------------------
|
||||
# ---------------------- option parsing and command line checks ------------------------
|
||||
usage = """%prog [-e ENCRYPTIONTYPE] [-m MGMTSECRETKEY] [-k DBSECRETKEY] [--debug]
|
||||
|
||||
This command sets up the CloudStack Encryption.
|
||||
|
||||
"""
|
||||
self.parser = OptionParser(usage=usage)
|
||||
self.parser.add_option("-v", "--debug", action="store_true", dest="debug", default=False,
|
||||
help="If enabled, print the commands it will run as they run")
|
||||
self.parser.add_option("-e", "--encrypt-type", action="store", type="string", dest="encryptiontype", default="file",
|
||||
help="Encryption method used for db password encryption. Valid values are file, web. Default is file.")
|
||||
self.parser.add_option("-m", "--managementserver-secretkey", action="store", type="string", dest="mgmtsecretkey", default="password",
|
||||
help="Secret key used to encrypt confidential parameters in db.properties. A string, default is password")
|
||||
self.parser.add_option("-k", "--database-secretkey", action="store", type="string", dest="dbsecretkey", default="password",
|
||||
help="Secret key used to encrypt sensitive database values. A string, default is password")
|
||||
self.parser.add_option(
|
||||
"-v",
|
||||
"--debug",
|
||||
action="store_true",
|
||||
dest="debug",
|
||||
default=False,
|
||||
help="If enabled, print the commands it will run as they run",
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-e",
|
||||
"--encrypt-type",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="encryptiontype",
|
||||
default="file",
|
||||
help="Encryption method used for db password encryption. Valid values are file, web. Default is file.",
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-m",
|
||||
"--managementserver-secretkey",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="mgmtsecretkey",
|
||||
default="password",
|
||||
help="Secret key used to encrypt confidential parameters in db.properties. A string, default is password",
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-k",
|
||||
"--database-secretkey",
|
||||
action="store",
|
||||
type="string",
|
||||
dest="dbsecretkey",
|
||||
default="password",
|
||||
help="Secret key used to encrypt sensitive database values. A string, default is password",
|
||||
)
|
||||
|
||||
(self.options, self.args) = self.parser.parse_args()
|
||||
parseOtherOptions()
|
||||
@ -257,10 +334,11 @@ for example:
|
||||
finally:
|
||||
self.postRun()
|
||||
|
||||
print('')
|
||||
print("")
|
||||
print("CloudStack has successfully setup Encryption")
|
||||
print('')
|
||||
print("")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
o = DBDeployer()
|
||||
o.run()
|
||||
o = DBDeployer()
|
||||
o.run()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user