mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01: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:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
args: [--config, .github/linters/.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
|
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||||
rev: v0.45.0
|
rev: v0.45.0
|
||||||
hooks:
|
hooks:
|
||||||
|
|||||||
@ -43,19 +43,25 @@ from cloudutils.serviceConfig import configureLibvirtConfig, configure_libvirt_t
|
|||||||
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
|
|
||||||
def getUserInputs():
|
def getUserInputs():
|
||||||
print("Welcome to the CloudStack Agent Setup:")
|
print("Welcome to the CloudStack Agent Setup:")
|
||||||
|
|
||||||
cfo = configFileOps("@AGENTSYSCONFDIR@/agent.properties")
|
cfo = configFileOps("@AGENTSYSCONFDIR@/agent.properties")
|
||||||
oldMgt = cfo.getEntry("host")
|
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 == "":
|
if mgtSvr == "":
|
||||||
mgtSvr = oldMgt
|
mgtSvr = oldMgt
|
||||||
try:
|
try:
|
||||||
socket.getaddrinfo(mgtSvr, 443)
|
socket.getaddrinfo(mgtSvr, 443)
|
||||||
except:
|
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)
|
exit(1)
|
||||||
|
|
||||||
oldToken = cfo.getEntry("zone")
|
oldToken = cfo.getEntry("zone")
|
||||||
@ -86,7 +92,9 @@ def getUserInputs():
|
|||||||
try:
|
try:
|
||||||
defaultNic = networkConfig.getDefaultNetwork()
|
defaultNic = networkConfig.getDefaultNetwork()
|
||||||
except:
|
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)
|
exit(1)
|
||||||
|
|
||||||
defNic = defaultNic.name
|
defNic = defaultNic.name
|
||||||
@ -100,7 +108,8 @@ def getUserInputs():
|
|||||||
|
|
||||||
return [mgtSvr, zoneToken, network, podId, clusterId, hypervisor]
|
return [mgtSvr, zoneToken, network, podId, clusterId, hypervisor]
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
initLoging("@AGENTLOGDIR@/setup.log")
|
initLoging("@AGENTLOGDIR@/setup.log")
|
||||||
glbEnv = globalEnv()
|
glbEnv = globalEnv()
|
||||||
|
|
||||||
@ -108,13 +117,23 @@ if __name__ == '__main__':
|
|||||||
glbEnv.agentMode = "Agent"
|
glbEnv.agentMode = "Agent"
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
parser.add_option("-a", action="store_true", dest="auto", help="auto mode")
|
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("-z", "--zone", dest="zone", help="zone id")
|
||||||
parser.add_option("-p", "--pod", dest="pod", help="pod id")
|
parser.add_option("-p", "--pod", dest="pod", help="pod id")
|
||||||
parser.add_option("-c", "--cluster", dest="cluster", help="cluster 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("-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("--pubNic", dest="pubNic", help="Public traffic interface")
|
||||||
parser.add_option("--prvNic", dest="prvNic", help="Private traffic interface")
|
parser.add_option("--prvNic", dest="prvNic", help="Private traffic interface")
|
||||||
parser.add_option("--guestNic", dest="guestNic", help="Guest traffic interface")
|
parser.add_option("--guestNic", dest="guestNic", help="Guest traffic interface")
|
||||||
|
|||||||
@ -35,9 +35,12 @@ from threading import Thread
|
|||||||
# ---- 3) System Python path
|
# ---- 3) System Python path
|
||||||
for pythonpath in (
|
for pythonpath in (
|
||||||
"@PYTHONDIR@",
|
"@PYTHONDIR@",
|
||||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
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)
|
if os.path.isdir(pythonpath):
|
||||||
|
sys.path.insert(0, pythonpath)
|
||||||
# ---- End snippet of code ----
|
# ---- End snippet of code ----
|
||||||
from cloud_utils import check_call, CalledProcessError, read_properties
|
from cloud_utils import check_call, CalledProcessError, read_properties
|
||||||
|
|
||||||
@ -51,30 +54,45 @@ 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."""
|
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 = OptionParser(usage=usage)
|
||||||
parser.add_option("-a", "--all", action="store_true", dest="all", default=False,
|
parser.add_option(
|
||||||
help="deploy to all known hosts rather that a single host")
|
"-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 e(msg):
|
||||||
|
parser.error(msg)
|
||||||
|
|
||||||
|
|
||||||
def getknownhosts(host, username, password):
|
def getknownhosts(host, username, password):
|
||||||
conn = mysql.connector.connect(host=host, user=username, password=password)
|
conn = mysql.connector.connect(host=host, user=username, password=password)
|
||||||
cur = conn.cursor()
|
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")
|
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())
|
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")
|
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())
|
passwords = dict(cur.fetchall())
|
||||||
creds = dict([[x, (usernames[x], passwords[x])] for x in list(usernames.keys())])
|
creds = dict([[x, (usernames[x], passwords[x])] for x in list(usernames.keys())])
|
||||||
cur.close()
|
cur.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
return creds
|
return creds
|
||||||
|
|
||||||
|
|
||||||
def splitlast(string, splitter):
|
def splitlast(string, splitter):
|
||||||
splitted = string.split(splitter)
|
splitted = string.split(splitter)
|
||||||
first, last = splitter.join(splitted[:-1]), splitted[-1]
|
first, last = splitter.join(splitted[:-1]), splitted[-1]
|
||||||
return first, last
|
return first, last
|
||||||
|
|
||||||
|
|
||||||
def parseuserpwfromhosts(hosts):
|
def parseuserpwfromhosts(hosts):
|
||||||
creds = {}
|
creds = {}
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
@ -87,6 +105,7 @@ def parseuserpwfromhosts(hosts):
|
|||||||
creds[host] = (user, password)
|
creds[host] = (user, password)
|
||||||
return creds
|
return creds
|
||||||
|
|
||||||
|
|
||||||
class XenServerConfigurator(Thread):
|
class XenServerConfigurator(Thread):
|
||||||
|
|
||||||
def __init__(self, host, user, password, keyfiledata):
|
def __init__(self, host, user, password, keyfiledata):
|
||||||
@ -98,11 +117,11 @@ class XenServerConfigurator(Thread):
|
|||||||
self.retval = None # means all's good
|
self.retval = None # means all's good
|
||||||
self.stdout = ""
|
self.stdout = ""
|
||||||
self.stderr = ""
|
self.stderr = ""
|
||||||
self.state = 'initialized'
|
self.state = "initialized"
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
self.state = 'running'
|
self.state = "running"
|
||||||
c = paramiko.SSHClient()
|
c = paramiko.SSHClient()
|
||||||
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
c.connect(self.host, username=self.user, password=self.password)
|
c.connect(self.host, username=self.user, password=self.password)
|
||||||
@ -112,25 +131,39 @@ class XenServerConfigurator(Thread):
|
|||||||
f.write(self.keyfiledata)
|
f.write(self.keyfiledata)
|
||||||
f.close()
|
f.close()
|
||||||
sftp.close()
|
sftp.close()
|
||||||
stdin,stdout,stderr = c.exec_command("xe host-license-add license-file=/tmp/xen-license")
|
stdin, stdout, stderr = c.exec_command(
|
||||||
|
"xe host-license-add license-file=/tmp/xen-license"
|
||||||
|
)
|
||||||
c.exec_command("false")
|
c.exec_command("false")
|
||||||
self.stdout = stdout.read(-1)
|
self.stdout = stdout.read(-1)
|
||||||
self.stderr = stderr.read(-1)
|
self.stderr = stderr.read(-1)
|
||||||
self.retval = stdin.channel.recv_exit_status()
|
self.retval = stdin.channel.recv_exit_status()
|
||||||
c.close()
|
c.close()
|
||||||
if self.retval != 0: self.state = 'failed'
|
if self.retval != 0:
|
||||||
else: self.state = 'finished'
|
self.state = "failed"
|
||||||
|
else:
|
||||||
|
self.state = "finished"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.state = 'failed'
|
self.state = "failed"
|
||||||
self.retval = e
|
self.retval = e
|
||||||
# raise
|
# raise
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.state == 'failed':
|
if self.state == "failed":
|
||||||
return "<%s XenServerConfigurator on %s@%s: %s>"%(self.state,self.user,self.host,str(self.retval))
|
return "<%s XenServerConfigurator on %s@%s: %s>" % (
|
||||||
|
self.state,
|
||||||
|
self.user,
|
||||||
|
self.host,
|
||||||
|
str(self.retval),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return "<%s XenServerConfigurator on %s@%s>"%(self.state,self.user,self.host)
|
return "<%s XenServerConfigurator on %s@%s>" % (
|
||||||
|
self.state,
|
||||||
|
self.user,
|
||||||
|
self.host,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ------------- actual code --------------------
|
# ------------- actual code --------------------
|
||||||
|
|
||||||
@ -138,15 +171,22 @@ class XenServerConfigurator(Thread):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
licensefile, args = args[0], args[1:]
|
licensefile, args = args[0], args[1:]
|
||||||
except IndexError: e("The first argument must be the license file to use")
|
except IndexError:
|
||||||
|
e("The first argument must be the license file to use")
|
||||||
|
|
||||||
if options.all:
|
if options.all:
|
||||||
if len(args) != 0: e("IP addresses cannot be specified if -a is specified")
|
if len(args) != 0:
|
||||||
|
e("IP addresses cannot be specified if -a is specified")
|
||||||
config = read_properties(cfg)
|
config = read_properties(cfg)
|
||||||
creds = getknownhosts(config["db.cloud.host"],config["db.cloud.username"],config["db.cloud.password"])
|
creds = getknownhosts(
|
||||||
|
config["db.cloud.host"],
|
||||||
|
config["db.cloud.username"],
|
||||||
|
config["db.cloud.password"],
|
||||||
|
)
|
||||||
hosts = list(creds.keys())
|
hosts = list(creds.keys())
|
||||||
else:
|
else:
|
||||||
if not args: e("You must specify at least one IP address, or -a")
|
if not args:
|
||||||
|
e("You must specify at least one IP address, or -a")
|
||||||
hosts = args
|
hosts = args
|
||||||
creds = parseuserpwfromhosts(hosts)
|
creds = parseuserpwfromhosts(hosts)
|
||||||
|
|
||||||
@ -161,22 +201,24 @@ for host,(user,password) in list(creds.items()):
|
|||||||
configurators.append(XenServerConfigurator(host, user, password, keyfiledata))
|
configurators.append(XenServerConfigurator(host, user, password, keyfiledata))
|
||||||
|
|
||||||
|
|
||||||
for c in configurators: c.start()
|
for c in configurators:
|
||||||
|
c.start()
|
||||||
|
|
||||||
for c in configurators:
|
for c in configurators:
|
||||||
print(c.host + "...", end=' ')
|
print(c.host + "...", end=" ")
|
||||||
c.join()
|
c.join()
|
||||||
if c.state == 'failed':
|
if c.state == "failed":
|
||||||
if c.retval:
|
if c.retval:
|
||||||
msg = "failed with return code %s: %s%s" % (c.retval, c.stdout, c.stderr)
|
msg = "failed with return code %s: %s%s" % (c.retval, c.stdout, c.stderr)
|
||||||
msg = msg.strip()
|
msg = msg.strip()
|
||||||
print(msg)
|
print(msg)
|
||||||
else: print("failed: %s"%c.retval)
|
else:
|
||||||
|
print("failed: %s" % c.retval)
|
||||||
else:
|
else:
|
||||||
print("done")
|
print("done")
|
||||||
|
|
||||||
successes = len( [ a for a in configurators if not a.state == 'failed' ] )
|
successes = len([a for a in configurators if not a.state == "failed"])
|
||||||
failures = len( [ a for a in configurators if a.state == 'failed' ] )
|
failures = len([a for a in configurators if a.state == "failed"])
|
||||||
|
|
||||||
print("%3s successes" % successes)
|
print("%3s successes" % successes)
|
||||||
print("%3s failures" % failures)
|
print("%3s failures" % failures)
|
||||||
|
|||||||
@ -25,4 +25,5 @@ sys.path.append(os.path.dirname(os.path.dirname(__file__)))
|
|||||||
import cloudtool
|
import cloudtool
|
||||||
|
|
||||||
ret = cloudtool.main()
|
ret = cloudtool.main()
|
||||||
if ret: sys.exit(ret)
|
if ret:
|
||||||
|
sys.exit(ret)
|
||||||
|
|||||||
@ -18,40 +18,68 @@
|
|||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
depLibraries = ['bzip2', 'gzip', 'unzip', 'openssh-clients', 'nfs-utils', 'wget', 'ws-commons-util', 'commons-dbcp',
|
depLibraries = [
|
||||||
'commons-collections', 'commons-httpclient', 'jpackage-utils', 'mysql-connector-python3', 'python-paramiko', 'ipmitool', 'commons-httpclient', 'commons-collections',
|
"bzip2",
|
||||||
'commons-pool', 'commons-dbcp', 'jakarta-commons-logging', 'java-*-openjdk']
|
"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):
|
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()
|
stdout, stderr = process.communicate()
|
||||||
if process.returncode != 0:
|
if process.returncode != 0:
|
||||||
raise Exception(stderr.decode('utf-8'))
|
raise Exception(stderr.decode("utf-8"))
|
||||||
return stdout.decode('utf-8')
|
return stdout.decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
def getDependentLibraryInfo():
|
def getDependentLibraryInfo():
|
||||||
def getVersion(res, pkgname):
|
def getVersion(res, pkgname):
|
||||||
start = False
|
start = False
|
||||||
for l in res.split('\n'):
|
for l in res.split("\n"):
|
||||||
if "Installed Packages" in l:
|
if "Installed Packages" in l:
|
||||||
start = True
|
start = True
|
||||||
continue
|
continue
|
||||||
if not start: continue
|
if not start:
|
||||||
|
continue
|
||||||
|
|
||||||
(key, value) = l.split(':', 2)
|
(key, value) = l.split(":", 2)
|
||||||
key = key.strip()
|
key = key.strip()
|
||||||
value = value.strip()
|
value = value.strip()
|
||||||
if key == 'Name' and "*" not in pkgname and pkgname not in value:
|
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))
|
print(
|
||||||
return 'UNKNOWN'
|
"Required package name %s doesn't equal to package %s installed"
|
||||||
if 'Version' in key: return value
|
% (pkgname, value)
|
||||||
if 'Description' in key: return 'UNKNOWN' # we hit the end
|
)
|
||||||
return 'UNKNOWN'
|
return "UNKNOWN"
|
||||||
|
if "Version" in key:
|
||||||
|
return value
|
||||||
|
if "Description" in key:
|
||||||
|
return "UNKNOWN" # we hit the end
|
||||||
|
return "UNKNOWN"
|
||||||
|
|
||||||
libraryMap = {}
|
libraryMap = {}
|
||||||
for l in depLibraries:
|
for l in depLibraries:
|
||||||
cmd = ['yum', 'info', '"%s"'%l]
|
cmd = ["yum", "info", '"%s"' % l]
|
||||||
try:
|
try:
|
||||||
result = runCmd(cmd)
|
result = runCmd(cmd)
|
||||||
version = getVersion(result, l)
|
version = getVersion(result, l)
|
||||||
@ -61,21 +89,28 @@ def getDependentLibraryInfo():
|
|||||||
continue
|
continue
|
||||||
return libraryMap
|
return libraryMap
|
||||||
|
|
||||||
|
|
||||||
def arrangeOutPut(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:
|
for l in depLibraries:
|
||||||
if l in libraryMap:
|
if l in libraryMap:
|
||||||
entry = "%-40s: %s" % (l, libraryMap[l])
|
entry = "%-40s: %s" % (l, libraryMap[l])
|
||||||
else:
|
else:
|
||||||
entry = "%-40s: %s"%(l, 'UNKNOWN')
|
entry = "%-40s: %s" % (l, "UNKNOWN")
|
||||||
msg.append(entry)
|
msg.append(entry)
|
||||||
print('\n'.join(msg))
|
print("\n".join(msg))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
pythonDepLibraries = ['python', 'python3']
|
if __name__ == "__main__":
|
||||||
relver = runCmd(['rpm', '-q', 'centos-release'])
|
pythonDepLibraries = ["python", "python3"]
|
||||||
if relver.startswith('centos-release-') and int(relver[len('centos-release-')]) >= 8:
|
relver = runCmd(["rpm", "-q", "centos-release"])
|
||||||
pythonDepLibraries = ['python2', 'python36']
|
if (
|
||||||
|
relver.startswith("centos-release-")
|
||||||
|
and int(relver[len("centos-release-")]) >= 8
|
||||||
|
):
|
||||||
|
pythonDepLibraries = ["python2", "python36"]
|
||||||
depLibraries = pythonDepLibraries + depLibraries
|
depLibraries = pythonDepLibraries + depLibraries
|
||||||
|
|
||||||
arrangeOutPut(getDependentLibraryInfo())
|
arrangeOutPut(getDependentLibraryInfo())
|
||||||
|
|||||||
@ -23,11 +23,15 @@ import traceback
|
|||||||
from os.path import exists, join
|
from os.path import exists, join
|
||||||
from signal import alarm, signal, SIGALRM, SIGKILL
|
from signal import alarm, signal, SIGALRM, SIGKILL
|
||||||
|
|
||||||
|
|
||||||
class CloudRuntimeException(Exception):
|
class CloudRuntimeException(Exception):
|
||||||
def __init__(self, errMsg):
|
def __init__(self, errMsg):
|
||||||
self.errMsg = errMsg
|
self.errMsg = errMsg
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.errMsg
|
return self.errMsg
|
||||||
|
|
||||||
|
|
||||||
def formatExceptionInfo(maxTBlevel=5):
|
def formatExceptionInfo(maxTBlevel=5):
|
||||||
cla, exc, trbk = sys.exc_info()
|
cla, exc, trbk = sys.exc_info()
|
||||||
excTb = traceback.format_tb(trbk, maxTBlevel)
|
excTb = traceback.format_tb(trbk, maxTBlevel)
|
||||||
@ -36,6 +40,7 @@ def formatExceptionInfo(maxTBlevel=5):
|
|||||||
msg += tb
|
msg += tb
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
class bash:
|
class bash:
|
||||||
def __init__(self, args, timeout=600):
|
def __init__(self, args, timeout=600):
|
||||||
self.args = args
|
self.args = args
|
||||||
@ -48,6 +53,7 @@ class bash:
|
|||||||
def run(self):
|
def run(self):
|
||||||
class Alarm(Exception):
|
class Alarm(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def alarm_handler(signum, frame):
|
def alarm_handler(signum, frame):
|
||||||
raise Alarm
|
raise Alarm
|
||||||
|
|
||||||
@ -94,6 +100,7 @@ def initLoging(logFile=None):
|
|||||||
except:
|
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:
|
if msg is not None:
|
||||||
output = "%-80s" % msg
|
output = "%-80s" % msg
|
||||||
@ -104,26 +111,33 @@ def writeProgressBar(msg, result=None):
|
|||||||
sys.stdout.write(output)
|
sys.stdout.write(output)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
def printError(msg):
|
def printError(msg):
|
||||||
sys.stderr.write(msg)
|
sys.stderr.write(msg)
|
||||||
sys.stderr.write("\n")
|
sys.stderr.write("\n")
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
|
||||||
def printMsg(msg):
|
def printMsg(msg):
|
||||||
sys.stdout.write(msg + "\n")
|
sys.stdout.write(msg + "\n")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
def checkRpm(pkgName):
|
def checkRpm(pkgName):
|
||||||
chkPkg = bash("rpm -q %s" % pkgName)
|
chkPkg = bash("rpm -q %s" % pkgName)
|
||||||
writeProgressBar("Checking %s" % pkgName, None)
|
writeProgressBar("Checking %s" % pkgName, None)
|
||||||
if not chkPkg.isSuccess():
|
if not chkPkg.isSuccess():
|
||||||
writeProgressBar(None, False)
|
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
|
return False
|
||||||
else:
|
else:
|
||||||
writeProgressBar(None, True)
|
writeProgressBar(None, True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def checkEnv():
|
def checkEnv():
|
||||||
writeProgressBar("Checking is root")
|
writeProgressBar("Checking is root")
|
||||||
ret = bash("whoami")
|
ret = bash("whoami")
|
||||||
@ -134,46 +148,56 @@ def checkEnv():
|
|||||||
else:
|
else:
|
||||||
writeProgressBar(None, True)
|
writeProgressBar(None, True)
|
||||||
|
|
||||||
pkgList = ['tftp-server', 'syslinux', 'xinetd', 'chkconfig', 'dhcp']
|
pkgList = ["tftp-server", "syslinux", "xinetd", "chkconfig", "dhcp"]
|
||||||
for pkg in pkgList:
|
for pkg in pkgList:
|
||||||
if not checkRpm(pkg):
|
if not checkRpm(pkg):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def exitIfFail(ret):
|
def exitIfFail(ret):
|
||||||
if not ret: sys.exit(1)
|
if not ret:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def bashWithResult(cmd):
|
def bashWithResult(cmd):
|
||||||
writeProgressBar("Executing '%s'" % cmd)
|
writeProgressBar("Executing '%s'" % cmd)
|
||||||
ret = bash(cmd)
|
ret = bash(cmd)
|
||||||
if not ret.isSuccess():
|
if not ret.isSuccess():
|
||||||
writeProgressBar(None, False)
|
writeProgressBar(None, False)
|
||||||
writeProgressBar(ret.getStderr() + '\n')
|
writeProgressBar(ret.getStderr() + "\n")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
writeProgressBar(None, True)
|
writeProgressBar(None, True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def configurePxeStuff():
|
def configurePxeStuff():
|
||||||
stuff = ['tftp', 'xinetd', 'dhcpd']
|
stuff = ["tftp", "xinetd", "dhcpd"]
|
||||||
cmds = ['chkconfig --level 345 %s on' % i for i in stuff]
|
cmds = ["chkconfig --level 345 %s on" % i for i in stuff]
|
||||||
cmds.append('/etc/init.d/xinetd restart')
|
cmds.append("/etc/init.d/xinetd restart")
|
||||||
|
|
||||||
for cmd in cmds:
|
for cmd in cmds:
|
||||||
if not bashWithResult(cmd): return False
|
if not bashWithResult(cmd):
|
||||||
|
return False
|
||||||
|
|
||||||
chkIptable = bash('chkconfig --list iptables')
|
chkIptable = bash("chkconfig --list iptables")
|
||||||
if 'on' in chkIptable.getStdout():
|
if "on" in chkIptable.getStdout():
|
||||||
printMsg("Detected iptables is running, need to open tftp port 69")
|
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("iptables -I INPUT 1 -p udp --dport 69 -j ACCEPT"):
|
||||||
if not bashWithResult('/etc/init.d/iptables save'): return False
|
return False
|
||||||
|
if not bashWithResult("/etc/init.d/iptables save"):
|
||||||
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def getTftpRootDir(tftpRootDirList):
|
def getTftpRootDir(tftpRootDirList):
|
||||||
tftpRoot = bash("cat /etc/xinetd.d/tftp | grep server_args")
|
tftpRoot = bash("cat /etc/xinetd.d/tftp | grep server_args")
|
||||||
if not tftpRoot.isSuccess():
|
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
|
return False
|
||||||
tftpRootDir = tftpRoot.getStdout()
|
tftpRootDir = tftpRoot.getStdout()
|
||||||
index = tftpRootDir.find("/")
|
index = tftpRootDir.find("/")
|
||||||
@ -184,8 +208,9 @@ def getTftpRootDir(tftpRootDirList):
|
|||||||
tftpRootDirList.append(tftpRootDir)
|
tftpRootDirList.append(tftpRootDir)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def preparePING(tftpRootDir):
|
def preparePING(tftpRootDir):
|
||||||
pingFiles = ['boot.msg', 'initrd.gz', 'kernel', 'pxelinux.0']
|
pingFiles = ["boot.msg", "initrd.gz", "kernel", "pxelinux.0"]
|
||||||
pingDir = "/usr/share/PING"
|
pingDir = "/usr/share/PING"
|
||||||
|
|
||||||
for f in pingFiles:
|
for f in pingFiles:
|
||||||
@ -193,9 +218,11 @@ def preparePING(tftpRootDir):
|
|||||||
if not exists(path):
|
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
|
return False
|
||||||
if not bashWithResult("cp -f %s %s"%(path, 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
|
if not bashWithResult("mkdir -p %s/pxelinux.cfg" % tftpRootDir):
|
||||||
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -214,4 +241,3 @@ if __name__ == "__main__":
|
|||||||
printMsg("Setup BareMetal PXE server successfully")
|
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)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,10 @@
|
|||||||
|
|
||||||
import os, sys, time
|
import os, sys, time
|
||||||
import XenAPIPlugin
|
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 util
|
||||||
import base64
|
import base64
|
||||||
import socket
|
import socket
|
||||||
@ -37,6 +40,7 @@ import logging
|
|||||||
|
|
||||||
lib.setup_logging("/var/log/cloud/storageplugin.log")
|
lib.setup_logging("/var/log/cloud/storageplugin.log")
|
||||||
|
|
||||||
|
|
||||||
def echo(fn):
|
def echo(fn):
|
||||||
def wrapped(*v, **k):
|
def wrapped(*v, **k):
|
||||||
name = fn.__name__
|
name = fn.__name__
|
||||||
@ -44,8 +48,10 @@ def echo(fn):
|
|||||||
res = fn(*v, **k)
|
res = fn(*v, **k)
|
||||||
logging.debug("#### xen plugin exit %s ####" % name)
|
logging.debug("#### xen plugin exit %s ####" % name)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def downloadTemplateFromUrl(session, args):
|
def downloadTemplateFromUrl(session, args):
|
||||||
destPath = args["destPath"]
|
destPath = args["destPath"]
|
||||||
@ -60,6 +66,7 @@ def downloadTemplateFromUrl(session, args):
|
|||||||
logging.debug("exception: " + str(sys.exc_info()))
|
logging.debug("exception: " + str(sys.exc_info()))
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def getTemplateSize(session, args):
|
def getTemplateSize(session, args):
|
||||||
srcUrl = args["srcUrl"]
|
srcUrl = args["srcUrl"]
|
||||||
@ -69,7 +76,12 @@ def getTemplateSize(session, args):
|
|||||||
return str(headers["content-length"])
|
return str(headers["content-length"])
|
||||||
except:
|
except:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
XenAPIPlugin.dispatch({"downloadTemplateFromUrl": downloadTemplateFromUrl
|
XenAPIPlugin.dispatch(
|
||||||
,"getTemplateSize": getTemplateSize
|
{
|
||||||
})
|
"downloadTemplateFromUrl": downloadTemplateFromUrl,
|
||||||
|
"getTemplateSize": getTemplateSize,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
import os, sys, time
|
import os, sys, time
|
||||||
import XenAPIPlugin
|
import XenAPIPlugin
|
||||||
|
|
||||||
if os.path.exists("/opt/xensource/sm"):
|
if os.path.exists("/opt/xensource/sm"):
|
||||||
sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"])
|
sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"])
|
||||||
if os.path.exists("/usr/lib/xcp/sm"):
|
if os.path.exists("/usr/lib/xcp/sm"):
|
||||||
@ -33,6 +34,7 @@ import logging
|
|||||||
|
|
||||||
lib.setup_logging("/var/log/cloud/cloud.log")
|
lib.setup_logging("/var/log/cloud/cloud.log")
|
||||||
|
|
||||||
|
|
||||||
def echo(fn):
|
def echo(fn):
|
||||||
def wrapped(*v, **k):
|
def wrapped(*v, **k):
|
||||||
name = fn.__name__
|
name = fn.__name__
|
||||||
@ -40,112 +42,139 @@ def echo(fn):
|
|||||||
res = fn(*v, **k)
|
res = fn(*v, **k)
|
||||||
logging.debug("#### CLOUD exit %s ####" % name)
|
logging.debug("#### CLOUD exit %s ####" % name)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def forceShutdownVM(session, args):
|
def forceShutdownVM(session, args):
|
||||||
domId = args['domId']
|
domId = args["domId"]
|
||||||
try:
|
try:
|
||||||
cmd = ["/opt/xensource/debug/xenops", "destroy_domain", "-domid", domId]
|
cmd = ["/opt/xensource/debug/xenops", "destroy_domain", "-domid", domId]
|
||||||
txt = util.pread2(cmd)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt = '10#failed'
|
txt = "10#failed"
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def create_privatetemplate_from_snapshot(session, args):
|
def create_privatetemplate_from_snapshot(session, args):
|
||||||
templatePath = args['templatePath']
|
templatePath = args["templatePath"]
|
||||||
snapshotPath = args['snapshotPath']
|
snapshotPath = args["snapshotPath"]
|
||||||
tmpltLocalDir = args['tmpltLocalDir']
|
tmpltLocalDir = args["tmpltLocalDir"]
|
||||||
try:
|
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)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt = '10#failed'
|
txt = "10#failed"
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def upgrade_snapshot(session, args):
|
def upgrade_snapshot(session, args):
|
||||||
templatePath = args['templatePath']
|
templatePath = args["templatePath"]
|
||||||
snapshotPath = args['snapshotPath']
|
snapshotPath = args["snapshotPath"]
|
||||||
try:
|
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)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt = '10#failed'
|
txt = "10#failed"
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def copy_vhd_to_secondarystorage(session, args):
|
def copy_vhd_to_secondarystorage(session, args):
|
||||||
mountpoint = args['mountpoint']
|
mountpoint = args["mountpoint"]
|
||||||
vdiuuid = args['vdiuuid']
|
vdiuuid = args["vdiuuid"]
|
||||||
sruuid = args['sruuid']
|
sruuid = args["sruuid"]
|
||||||
try:
|
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)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt = '10#failed'
|
txt = "10#failed"
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def copy_vhd_from_secondarystorage(session, args):
|
def copy_vhd_from_secondarystorage(session, args):
|
||||||
mountpoint = args['mountpoint']
|
mountpoint = args["mountpoint"]
|
||||||
sruuid = args['sruuid']
|
sruuid = args["sruuid"]
|
||||||
namelabel = args['namelabel']
|
namelabel = args["namelabel"]
|
||||||
try:
|
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)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt = '10#failed'
|
txt = "10#failed"
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def remove_corrupt_vdi(session, args):
|
def remove_corrupt_vdi(session, args):
|
||||||
vdifile = args['vdifile']
|
vdifile = args["vdifile"]
|
||||||
try:
|
try:
|
||||||
cmd = ['rm', '-f', vdifile]
|
cmd = ["rm", "-f", vdifile]
|
||||||
txt = util.pread2(cmd)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt = '10#failed'
|
txt = "10#failed"
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def setup_heartbeat_sr(session, args):
|
def setup_heartbeat_sr(session, args):
|
||||||
host = args['host']
|
host = args["host"]
|
||||||
sr = args['sr']
|
sr = args["sr"]
|
||||||
try:
|
try:
|
||||||
cmd = ["bash", "/opt/cloud/bin/setup_heartbeat_sr.sh", host, sr]
|
cmd = ["bash", "/opt/cloud/bin/setup_heartbeat_sr.sh", host, sr]
|
||||||
txt = util.pread2(cmd)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt = ''
|
txt = ""
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def setup_heartbeat_file(session, args):
|
def setup_heartbeat_file(session, args):
|
||||||
host = args['host']
|
host = args["host"]
|
||||||
sr = args['sr']
|
sr = args["sr"]
|
||||||
add = args['add']
|
add = args["add"]
|
||||||
try:
|
try:
|
||||||
cmd = ["bash", "/opt/cloud/bin/setup_heartbeat_file.sh", host, sr, add]
|
cmd = ["bash", "/opt/cloud/bin/setup_heartbeat_file.sh", host, sr, add]
|
||||||
txt = util.pread2(cmd)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt = ''
|
txt = ""
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def heartbeat(session, args):
|
def heartbeat(session, args):
|
||||||
host = args['host']
|
host = args["host"]
|
||||||
timeout = args['timeout']
|
timeout = args["timeout"]
|
||||||
interval = args['interval']
|
interval = args["interval"]
|
||||||
try:
|
try:
|
||||||
cmd = ["/bin/bash", "/opt/cloud/bin/launch_hb.sh", host, timeout, interval]
|
cmd = ["/bin/bash", "/opt/cloud/bin/launch_hb.sh", host, timeout, interval]
|
||||||
txt = util.pread2(cmd)
|
txt = util.pread2(cmd)
|
||||||
except:
|
except:
|
||||||
txt='fail'
|
txt = "fail"
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
@echo
|
@echo
|
||||||
def asmonitor(session, args):
|
def asmonitor(session, args):
|
||||||
try:
|
try:
|
||||||
@ -153,7 +182,21 @@ def asmonitor(session, args):
|
|||||||
result = perfmod.get_vm_group_perfmon(args)
|
result = perfmod.get_vm_group_perfmon(args)
|
||||||
return result
|
return result
|
||||||
except:
|
except:
|
||||||
return 'fail'
|
return "fail"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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,7 +31,8 @@ import shutil
|
|||||||
|
|
||||||
# squelch mysqldb spurious warnings
|
# squelch mysqldb spurious warnings
|
||||||
import 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 ----
|
# ---- 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:
|
# ---- We do this so cloud_utils can be looked up in the following order:
|
||||||
# ---- 1) Sources directory
|
# ---- 1) Sources directory
|
||||||
@ -39,17 +40,24 @@ warnings.simplefilter('ignore')
|
|||||||
# ---- 3) System Python path
|
# ---- 3) System Python path
|
||||||
for pythonpath in (
|
for pythonpath in (
|
||||||
"@PYTHONDIR@",
|
"@PYTHONDIR@",
|
||||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
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)
|
if os.path.isdir(pythonpath):
|
||||||
|
sys.path.insert(0, pythonpath)
|
||||||
# ---- End snippet of code ----
|
# ---- End snippet of code ----
|
||||||
|
|
||||||
|
|
||||||
def runCmd(cmds):
|
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()
|
stdout, stderr = process.communicate()
|
||||||
if process.returncode != 0:
|
if process.returncode != 0:
|
||||||
raise Exception(stderr)
|
raise Exception(stderr)
|
||||||
return stdout.decode('utf-8')
|
return stdout.decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
class DBDeployer(object):
|
class DBDeployer(object):
|
||||||
parser = None
|
parser = None
|
||||||
@ -62,15 +70,15 @@ class DBDeployer(object):
|
|||||||
dbConfPath = r"@MSCONF@"
|
dbConfPath = r"@MSCONF@"
|
||||||
dbDotProperties = {}
|
dbDotProperties = {}
|
||||||
dbDotPropertiesIndex = 0
|
dbDotPropertiesIndex = 0
|
||||||
encryptionKeyFile = '@MSCONF@/key'
|
encryptionKeyFile = "@MSCONF@/key"
|
||||||
encryptionJarPath = '@COMMONLIBDIR@/lib/cloudstack-utils.jar'
|
encryptionJarPath = "@COMMONLIBDIR@/lib/cloudstack-utils.jar"
|
||||||
success = False
|
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 preRun(self):
|
||||||
def backUpDbDotProperties():
|
def backUpDbDotProperties():
|
||||||
dbpPath = os.path.join(self.dbConfPath, 'db.properties')
|
dbpPath = os.path.join(self.dbConfPath, "db.properties")
|
||||||
copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
|
copyPath = os.path.join(self.dbConfPath, "db.properties.origin")
|
||||||
|
|
||||||
if os.path.isfile(dbpPath):
|
if os.path.isfile(dbpPath):
|
||||||
shutil.copy2(dbpPath, copyPath)
|
shutil.copy2(dbpPath, copyPath)
|
||||||
@ -79,8 +87,8 @@ class DBDeployer(object):
|
|||||||
|
|
||||||
def postRun(self):
|
def postRun(self):
|
||||||
def cleanOrRecoverDbDotProperties():
|
def cleanOrRecoverDbDotProperties():
|
||||||
dbpPath = os.path.join(self.dbConfPath, 'db.properties')
|
dbpPath = os.path.join(self.dbConfPath, "db.properties")
|
||||||
copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
|
copyPath = os.path.join(self.dbConfPath, "db.properties.origin")
|
||||||
if os.path.isfile(copyPath):
|
if os.path.isfile(copyPath):
|
||||||
if not self.success:
|
if not self.success:
|
||||||
shutil.copy2(copyPath, dbpPath)
|
shutil.copy2(copyPath, dbpPath)
|
||||||
@ -88,7 +96,6 @@ class DBDeployer(object):
|
|||||||
|
|
||||||
cleanOrRecoverDbDotProperties()
|
cleanOrRecoverDbDotProperties()
|
||||||
|
|
||||||
|
|
||||||
def info(self, msg, result=None):
|
def info(self, msg, result=None):
|
||||||
output = ""
|
output = ""
|
||||||
if msg is not None:
|
if msg is not None:
|
||||||
@ -122,7 +129,8 @@ class DBDeployer(object):
|
|||||||
|
|
||||||
def errorAndExit(self, msg):
|
def errorAndExit(self, msg):
|
||||||
self.postRun()
|
self.postRun()
|
||||||
err = '''\n\nWe apologize for below error:
|
err = (
|
||||||
|
"""\n\nWe apologize for below error:
|
||||||
***************************************************************
|
***************************************************************
|
||||||
%s
|
%s
|
||||||
***************************************************************
|
***************************************************************
|
||||||
@ -131,33 +139,45 @@ Please run:
|
|||||||
cloud-setup-encryption -h
|
cloud-setup-encryption -h
|
||||||
|
|
||||||
for full help
|
for full help
|
||||||
''' % msg
|
"""
|
||||||
|
% msg
|
||||||
|
)
|
||||||
sys.stderr.write(err)
|
sys.stderr.write(err)
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def prepareDBFiles(self):
|
def prepareDBFiles(self):
|
||||||
def prepareDBDotProperties():
|
def prepareDBDotProperties():
|
||||||
dbpPath = os.path.join(self.dbConfPath, 'db.properties')
|
dbpPath = os.path.join(self.dbConfPath, "db.properties")
|
||||||
dbproperties = file(dbpPath).read().splitlines()
|
dbproperties = file(dbpPath).read().splitlines()
|
||||||
newdbp = []
|
newdbp = []
|
||||||
emptyLine = 0
|
emptyLine = 0
|
||||||
for line in dbproperties:
|
for line in dbproperties:
|
||||||
passed = False
|
passed = False
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if line.startswith("#"): key = line; value = ''; passed = True
|
if line.startswith("#"):
|
||||||
if line == '' or line == '\n': key = self.magicString + str(emptyLine); value = ''; emptyLine += 1; passed = True
|
key = line
|
||||||
|
value = ""
|
||||||
|
passed = True
|
||||||
|
if line == "" or line == "\n":
|
||||||
|
key = self.magicString + str(emptyLine)
|
||||||
|
value = ""
|
||||||
|
emptyLine += 1
|
||||||
|
passed = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not passed:
|
if not passed:
|
||||||
(key, value) = line.split('=', 1)
|
(key, value) = line.split("=", 1)
|
||||||
except Exception as e:
|
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
|
Besides comments beginning "#" and empty line, all key-value pairs must be in formula of
|
||||||
key=value
|
key=value
|
||||||
for example:
|
for example:
|
||||||
db.cloud.username = cloud
|
db.cloud.username = cloud
|
||||||
''' % (dbpPath, line)
|
""" % (
|
||||||
|
dbpPath,
|
||||||
|
line,
|
||||||
|
)
|
||||||
self.errorAndExit(err)
|
self.errorAndExit(err)
|
||||||
self.putDbProperty(key, value)
|
self.putDbProperty(key, value)
|
||||||
self.info("Preparing %s" % dbpPath, True)
|
self.info("Preparing %s" % dbpPath, True)
|
||||||
@ -172,10 +192,12 @@ for example:
|
|||||||
if key.startswith("#"):
|
if key.startswith("#"):
|
||||||
entries.insert(index, key)
|
entries.insert(index, key)
|
||||||
elif key.startswith(self.magicString):
|
elif key.startswith(self.magicString):
|
||||||
entries.insert(index, '')
|
entries.insert(index, "")
|
||||||
else:
|
else:
|
||||||
entries.insert(index, "%s=%s" % (key, value))
|
entries.insert(index, "%s=%s" % (key, value))
|
||||||
file(os.path.join(self.dbConfPath, 'db.properties'), 'w').write('\n'.join(entries))
|
file(os.path.join(self.dbConfPath, "db.properties"), "w").write(
|
||||||
|
"\n".join(entries)
|
||||||
|
)
|
||||||
|
|
||||||
self.info("Finalizing setup ...", None)
|
self.info("Finalizing setup ...", None)
|
||||||
finalizeDbProperties()
|
finalizeDbProperties()
|
||||||
@ -184,29 +206,55 @@ for example:
|
|||||||
|
|
||||||
def processEncryptionStuff(self):
|
def processEncryptionStuff(self):
|
||||||
def encrypt(value):
|
def encrypt(value):
|
||||||
cmd = ['java','-classpath','"' + self.encryptionJarPath + '"','com.cloud.utils.crypt.EncryptionCLI','-i','"' + value + '"', '-p', '"' + self.mgmtsecretkey + '"']
|
cmd = [
|
||||||
return runCmd(cmd).strip('\n')
|
"java",
|
||||||
|
"-classpath",
|
||||||
|
'"' + self.encryptionJarPath + '"',
|
||||||
|
"com.cloud.utils.crypt.EncryptionCLI",
|
||||||
|
"-i",
|
||||||
|
'"' + value + '"',
|
||||||
|
"-p",
|
||||||
|
'"' + self.mgmtsecretkey + '"',
|
||||||
|
]
|
||||||
|
return runCmd(cmd).strip("\n")
|
||||||
|
|
||||||
def saveMgmtServerSecretKey():
|
def saveMgmtServerSecretKey():
|
||||||
if self.encryptiontype == 'file':
|
if self.encryptiontype == "file":
|
||||||
file(self.encryptionKeyFile, 'w').write(self.mgmtsecretkey)
|
file(self.encryptionKeyFile, "w").write(self.mgmtsecretkey)
|
||||||
|
|
||||||
def formatEncryptResult(value):
|
def formatEncryptResult(value):
|
||||||
return 'ENC(%s)'%value
|
return "ENC(%s)" % value
|
||||||
|
|
||||||
def encryptDBSecretKey():
|
def encryptDBSecretKey():
|
||||||
self.putDbProperty('db.cloud.encrypt.secret', formatEncryptResult(encrypt(self.dbsecretkey)))
|
self.putDbProperty(
|
||||||
|
"db.cloud.encrypt.secret",
|
||||||
|
formatEncryptResult(encrypt(self.dbsecretkey)),
|
||||||
|
)
|
||||||
|
|
||||||
def encryptDBPassword():
|
def encryptDBPassword():
|
||||||
dbPassword = self.getDbProperty('db.cloud.password')
|
dbPassword = self.getDbProperty("db.cloud.password")
|
||||||
if dbPassword == '': return # Don't encrypt empty password
|
if dbPassword == "":
|
||||||
if dbPassword == None: self.errorAndExit('Cannot find db.cloud.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
|
return # Don't encrypt empty password
|
||||||
self.putDbProperty('db.cloud.password', formatEncryptResult(encrypt(dbPassword)))
|
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')
|
usagePassword = self.getDbProperty("db.usage.password")
|
||||||
if usagePassword == '': return # Don't encrypt empty password
|
if usagePassword == "":
|
||||||
if usagePassword == None: self.errorAndExit('Cannot find db.usage.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
|
return # Don't encrypt empty password
|
||||||
self.putDbProperty('db.usage.password', formatEncryptResult(encrypt(usagePassword)))
|
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.info("Processing encryption ...", None)
|
||||||
self.putDbProperty("db.cloud.encryption.type", self.encryptiontype)
|
self.putDbProperty("db.cloud.encryption.type", self.encryptiontype)
|
||||||
@ -222,10 +270,12 @@ for example:
|
|||||||
self.dbsecretkey = self.options.dbsecretkey
|
self.dbsecretkey = self.options.dbsecretkey
|
||||||
self.isDebug = self.options.debug
|
self.isDebug = self.options.debug
|
||||||
|
|
||||||
|
|
||||||
def validateParameters():
|
def validateParameters():
|
||||||
if self.encryptiontype != 'file' and self.encryptiontype != 'web':
|
if self.encryptiontype != "file" and self.encryptiontype != "web":
|
||||||
self.errorAndExit('Wrong encryption type %s, --encrypt-type can only be "file" or "web'%self.encryptiontype)
|
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]
|
usage = """%prog [-e ENCRYPTIONTYPE] [-m MGMTSECRETKEY] [-k DBSECRETKEY] [--debug]
|
||||||
@ -234,14 +284,41 @@ for example:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
self.parser = OptionParser(usage=usage)
|
self.parser = OptionParser(usage=usage)
|
||||||
self.parser.add_option("-v", "--debug", action="store_true", dest="debug", default=False,
|
self.parser.add_option(
|
||||||
help="If enabled, print the commands it will run as they run")
|
"-v",
|
||||||
self.parser.add_option("-e", "--encrypt-type", action="store", type="string", dest="encryptiontype", default="file",
|
"--debug",
|
||||||
help="Encryption method used for db password encryption. Valid values are file, web. Default is file.")
|
action="store_true",
|
||||||
self.parser.add_option("-m", "--managementserver-secretkey", action="store", type="string", dest="mgmtsecretkey", default="password",
|
dest="debug",
|
||||||
help="Secret key used to encrypt confidential parameters in db.properties. A string, default is password")
|
default=False,
|
||||||
self.parser.add_option("-k", "--database-secretkey", action="store", type="string", dest="dbsecretkey", default="password",
|
help="If enabled, print the commands it will run as they run",
|
||||||
help="Secret key used to encrypt sensitive database values. A string, default is password")
|
)
|
||||||
|
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()
|
(self.options, self.args) = self.parser.parse_args()
|
||||||
parseOtherOptions()
|
parseOtherOptions()
|
||||||
@ -257,9 +334,10 @@ for example:
|
|||||||
finally:
|
finally:
|
||||||
self.postRun()
|
self.postRun()
|
||||||
|
|
||||||
print('')
|
print("")
|
||||||
print("CloudStack has successfully setup Encryption")
|
print("CloudStack has successfully setup Encryption")
|
||||||
print('')
|
print("")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
o = DBDeployer()
|
o = DBDeployer()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user