mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 01:32:18 +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:
|
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:
|
||||||
|
|||||||
@ -35,7 +35,7 @@ for pythonpath in (
|
|||||||
|
|
||||||
from cloudutils.cloudException import CloudRuntimeException, CloudInternalException
|
from cloudutils.cloudException import CloudRuntimeException, CloudInternalException
|
||||||
from cloudutils.utilities import initLoging, bash
|
from cloudutils.utilities import initLoging, bash
|
||||||
from cloudutils.configFileOps import configFileOps
|
from cloudutils.configFileOps import configFileOps
|
||||||
from cloudutils.globalEnv import globalEnv
|
from cloudutils.globalEnv import globalEnv
|
||||||
from cloudutils.networkConfig import networkConfig
|
from cloudutils.networkConfig import networkConfig
|
||||||
from cloudutils.syscfg import sysConfigFactory
|
from cloudutils.syscfg import sysConfigFactory
|
||||||
@ -43,35 +43,41 @@ 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")
|
||||||
zoneToken = input("Please input the Zone Id:[%s]"%oldToken)
|
zoneToken = input("Please input the Zone Id:[%s]" % oldToken)
|
||||||
|
|
||||||
if zoneToken == "":
|
if zoneToken == "":
|
||||||
zoneToken = oldToken
|
zoneToken = oldToken
|
||||||
|
|
||||||
oldPod = cfo.getEntry("pod")
|
oldPod = cfo.getEntry("pod")
|
||||||
podId = input("Please input the Pod Id:[%s]"%oldPod)
|
podId = input("Please input the Pod Id:[%s]" % oldPod)
|
||||||
|
|
||||||
if podId == "":
|
if podId == "":
|
||||||
podId = oldToken
|
podId = oldToken
|
||||||
|
|
||||||
oldCluster = cfo.getEntry("cluster")
|
oldCluster = cfo.getEntry("cluster")
|
||||||
clusterId = input("Please input the Cluster Id:[%s]"%oldCluster)
|
clusterId = input("Please input the Cluster Id:[%s]" % oldCluster)
|
||||||
if clusterId == "":
|
if clusterId == "":
|
||||||
clusterId = oldCluster
|
clusterId = oldCluster
|
||||||
|
|
||||||
@ -79,18 +85,20 @@ def getUserInputs():
|
|||||||
if oldHypervisor == "":
|
if oldHypervisor == "":
|
||||||
oldHypervisor = "kvm"
|
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 == "":
|
if hypervisor == "":
|
||||||
hypervisor = oldHypervisor
|
hypervisor = oldHypervisor
|
||||||
|
|
||||||
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
|
||||||
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 network == "":
|
||||||
if defNic == "":
|
if defNic == "":
|
||||||
print("You need to specify one of Nic or bridge on your system")
|
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]
|
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")
|
||||||
@ -140,15 +159,15 @@ if __name__ == '__main__':
|
|||||||
glbEnv.pod = userInputs[3]
|
glbEnv.pod = userInputs[3]
|
||||||
glbEnv.cluster = userInputs[4]
|
glbEnv.cluster = userInputs[4]
|
||||||
glbEnv.hypervisor = userInputs[5]
|
glbEnv.hypervisor = userInputs[5]
|
||||||
#generate UUID
|
# generate UUID
|
||||||
glbEnv.uuid = old_config.getEntry("guid")
|
glbEnv.uuid = old_config.getEntry("guid")
|
||||||
if glbEnv.uuid == "":
|
if glbEnv.uuid == "":
|
||||||
glbEnv.uuid = bash("uuidgen").getStdout()
|
glbEnv.uuid = bash("uuidgen").getStdout()
|
||||||
else:
|
else:
|
||||||
for para, value in list(options.__dict__.items()):
|
for para, value in list(options.__dict__.items()):
|
||||||
if value is None:
|
if value is None:
|
||||||
print("Missing operand:%s"%para)
|
print("Missing operand:%s" % para)
|
||||||
print("Try %s --help for more information"%sys.argv[0])
|
print("Try %s --help for more information" % sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
glbEnv.uuid = options.guid
|
glbEnv.uuid = options.guid
|
||||||
@ -168,7 +187,7 @@ if __name__ == '__main__':
|
|||||||
try:
|
try:
|
||||||
syscfg.config()
|
syscfg.config()
|
||||||
print("CloudStack Agent setup is done!")
|
print("CloudStack Agent setup is done!")
|
||||||
except (CloudRuntimeException,CloudInternalException) as e:
|
except (CloudRuntimeException, CloudInternalException) as e:
|
||||||
print(e)
|
print(e)
|
||||||
print("Try to restore your system:")
|
print("Try to restore your system:")
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -34,16 +34,19 @@ from threading import Thread
|
|||||||
# ---- 2) waf configured PYTHONDIR
|
# ---- 2) waf configured PYTHONDIR
|
||||||
# ---- 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
|
||||||
|
|
||||||
cfg = "@MSCONF@/db.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...>
|
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."""
|
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 getknownhosts(host,username,password):
|
def e(msg):
|
||||||
conn = mysql.connector.connect(host=host, user=username, password=password)
|
parser.error(msg)
|
||||||
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())
|
def getknownhosts(host, username, password):
|
||||||
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")
|
conn = mysql.connector.connect(host=host, user=username, password=password)
|
||||||
passwords = dict(cur.fetchall())
|
cur = conn.cursor()
|
||||||
creds = dict( [ [x,(usernames[x],passwords[x])] for x in list(usernames.keys()) ] )
|
cur.execute(
|
||||||
cur.close()
|
"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"
|
||||||
conn.close()
|
)
|
||||||
return creds
|
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):
|
def parseuserpwfromhosts(hosts):
|
||||||
creds = {}
|
creds = {}
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
user = "root"
|
user = "root"
|
||||||
password = ""
|
password = ""
|
||||||
if "@" in host:
|
if "@" in host:
|
||||||
user,host = splitlast(host,"@")
|
user, host = splitlast(host, "@")
|
||||||
if ":" in user:
|
if ":" in user:
|
||||||
user,password = splitlast(user,":")
|
user, password = splitlast(user, ":")
|
||||||
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):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
self.host = host
|
self.host = host
|
||||||
self.user = user
|
self.user = user
|
||||||
self.password = password
|
self.password = password
|
||||||
self.keyfiledata = keyfiledata
|
self.keyfiledata = keyfiledata
|
||||||
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)
|
||||||
sftp = c.open_sftp()
|
sftp = c.open_sftp()
|
||||||
sftp.chdir("/tmp")
|
sftp.chdir("/tmp")
|
||||||
f = sftp.open("xen-license","w")
|
f = sftp.open("xen-license", "w")
|
||||||
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(
|
||||||
c.exec_command("false")
|
"xe host-license-add license-file=/tmp/xen-license"
|
||||||
self.stdout = stdout.read(-1)
|
)
|
||||||
self.stderr = stderr.read(-1)
|
c.exec_command("false")
|
||||||
self.retval = stdin.channel.recv_exit_status()
|
self.stdout = stdout.read(-1)
|
||||||
c.close()
|
self.stderr = stderr.read(-1)
|
||||||
if self.retval != 0: self.state = 'failed'
|
self.retval = stdin.channel.recv_exit_status()
|
||||||
else: self.state = 'finished'
|
c.close()
|
||||||
|
if self.retval != 0:
|
||||||
|
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>" % (
|
||||||
else:
|
self.state,
|
||||||
return "<%s XenServerConfigurator on %s@%s>"%(self.state,self.user,self.host)
|
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()
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
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:
|
||||||
config = read_properties(cfg)
|
e("IP addresses cannot be specified if -a is specified")
|
||||||
creds = getknownhosts(config["db.cloud.host"],config["db.cloud.username"],config["db.cloud.password"])
|
config = read_properties(cfg)
|
||||||
hosts = list(creds.keys())
|
creds = getknownhosts(
|
||||||
|
config["db.cloud.host"],
|
||||||
|
config["db.cloud.username"],
|
||||||
|
config["db.cloud.password"],
|
||||||
|
)
|
||||||
|
hosts = list(creds.keys())
|
||||||
else:
|
else:
|
||||||
if not args: e("You must specify at least one IP address, or -a")
|
if not args:
|
||||||
hosts = args
|
e("You must specify at least one IP address, or -a")
|
||||||
creds = parseuserpwfromhosts(hosts)
|
hosts = args
|
||||||
|
creds = parseuserpwfromhosts(hosts)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
keyfiledata = file(licensefile).read(-1)
|
keyfiledata = file(licensefile).read(-1)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
sys.stderr.write("The file %s cannot be opened"%licensefile)
|
sys.stderr.write("The file %s cannot be opened" % licensefile)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
configurators = []
|
configurators = []
|
||||||
for host,(user,password) in list(creds.items()):
|
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:
|
for c in configurators:
|
||||||
print(c.host + "...", end=' ')
|
c.start()
|
||||||
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")
|
|
||||||
|
|
||||||
successes = len( [ a for a in configurators if not a.state == 'failed' ] )
|
for c in configurators:
|
||||||
failures = len( [ a for a in configurators if a.state == 'failed' ] )
|
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)
|
successes = len([a for a in configurators if not a.state == "failed"])
|
||||||
print("%3s failures"%failures)
|
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
|
# to you under the Apache License, Version 2.0 (the
|
||||||
# "License"); you may not use this file except in compliance
|
# "License"); you may not use this file except in compliance
|
||||||
# with the License. You may obtain a copy of the License at
|
# with the License. You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing,
|
# Unless required by applicable law or agreed to in writing,
|
||||||
# software distributed under the License is distributed on an
|
# software distributed under the License is distributed on an
|
||||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
# "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
|
import cloudtool
|
||||||
|
|
||||||
ret = cloudtool.main()
|
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
|
# to you under the Apache License, Version 2.0 (the
|
||||||
# "License"); you may not use this file except in compliance
|
# "License"); you may not use this file except in compliance
|
||||||
# with the License. You may obtain a copy of the License at
|
# with the License. You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing,
|
# Unless required by applicable law or agreed to in writing,
|
||||||
# software distributed under the License is distributed on an
|
# software distributed under the License is distributed on an
|
||||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
@ -18,64 +18,99 @@
|
|||||||
|
|
||||||
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)
|
||||||
libraryMap[l] = version
|
libraryMap[l] = version
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("When finding %s, encounters %s"%(l, e))
|
print("When finding %s, encounters %s" % (l, e))
|
||||||
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())
|
||||||
|
|||||||
@ -6,9 +6,9 @@
|
|||||||
# to you under the Apache License, Version 2.0 (the
|
# to you under the Apache License, Version 2.0 (the
|
||||||
# "License"); you may not use this file except in compliance
|
# "License"); you may not use this file except in compliance
|
||||||
# with the License. You may obtain a copy of the License at
|
# with the License. You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing,
|
# Unless required by applicable law or agreed to in writing,
|
||||||
# software distributed under the License is distributed on an
|
# software distributed under the License is distributed on an
|
||||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
@ -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,10 +40,11 @@ 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
|
||||||
logging.debug("execute:%s"%args)
|
logging.debug("execute:%s" % args)
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.process = None
|
self.process = None
|
||||||
self.success = False
|
self.success = False
|
||||||
@ -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
|
||||||
|
|
||||||
@ -63,21 +69,21 @@ class bash:
|
|||||||
alarm(0)
|
alarm(0)
|
||||||
except Alarm:
|
except Alarm:
|
||||||
os.kill(self.process.pid, SIGKILL)
|
os.kill(self.process.pid, SIGKILL)
|
||||||
raise CloudRuntimeException("Timeout during command execution")
|
raise CloudRuntimeException("Timeout during command execution")
|
||||||
|
|
||||||
self.success = self.process.returncode == 0
|
self.success = self.process.returncode == 0
|
||||||
except:
|
except:
|
||||||
raise CloudRuntimeException(formatExceptionInfo())
|
raise CloudRuntimeException(formatExceptionInfo())
|
||||||
|
|
||||||
# if not self.success:
|
# if not self.success:
|
||||||
# raise CloudRuntimeException(self.getStderr())
|
# raise CloudRuntimeException(self.getStderr())
|
||||||
|
|
||||||
def isSuccess(self):
|
def isSuccess(self):
|
||||||
return self.success
|
return self.success
|
||||||
|
|
||||||
def getStdout(self):
|
def getStdout(self):
|
||||||
return self.stdout.strip("\n")
|
return self.stdout.strip("\n")
|
||||||
|
|
||||||
def getLines(self):
|
def getLines(self):
|
||||||
return self.stdout.split("\n")
|
return self.stdout.split("\n")
|
||||||
|
|
||||||
@ -88,130 +94,150 @@ class bash:
|
|||||||
def initLoging(logFile=None):
|
def initLoging(logFile=None):
|
||||||
try:
|
try:
|
||||||
if logFile is None:
|
if logFile is None:
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
else:
|
else:
|
||||||
logging.basicConfig(filename=logFile, level=logging.DEBUG)
|
logging.basicConfig(filename=logFile, level=logging.DEBUG)
|
||||||
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
|
||||||
elif result is True:
|
elif result is True:
|
||||||
output = "[ \033[92m%-2s\033[0m ]\n"%"OK"
|
output = "[ \033[92m%-2s\033[0m ]\n" % "OK"
|
||||||
elif result is False:
|
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.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")
|
||||||
if ret.getStdout() != "root":
|
if ret.getStdout() != "root":
|
||||||
writeProgressBar(None, False)
|
writeProgressBar(None, False)
|
||||||
printError("This script must run as root")
|
printError("This script must run as root")
|
||||||
return False
|
return False
|
||||||
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():
|
|
||||||
stuff = ['tftp', 'xinetd', 'dhcpd']
|
def configurePxeStuff():
|
||||||
cmds = ['chkconfig --level 345 %s on' % i for i in stuff]
|
stuff = ["tftp", "xinetd", "dhcpd"]
|
||||||
cmds.append('/etc/init.d/xinetd restart')
|
cmds = ["chkconfig --level 345 %s on" % i for i in stuff]
|
||||||
|
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')
|
|
||||||
if 'on' in chkIptable.getStdout():
|
chkIptable = bash("chkconfig --list iptables")
|
||||||
|
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 True
|
return False
|
||||||
|
|
||||||
|
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("/")
|
||||||
if index == -1:
|
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
|
return False
|
||||||
tftpRootDir = tftpRootDir[index:]
|
tftpRootDir = tftpRootDir[index:]
|
||||||
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:
|
||||||
path = join(pingDir, f)
|
path = join(pingDir, f)
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
initLoging("/tmp/cloud-setup-baremetal.log")
|
initLoging("/tmp/cloud-setup-baremetal.log")
|
||||||
tftpRootDirList = []
|
tftpRootDirList = []
|
||||||
|
|
||||||
exitIfFail(checkEnv())
|
exitIfFail(checkEnv())
|
||||||
exitIfFail(configurePxeStuff())
|
exitIfFail(configurePxeStuff())
|
||||||
exitIfFail(getTftpRootDir(tftpRootDirList))
|
exitIfFail(getTftpRootDir(tftpRootDirList))
|
||||||
|
|
||||||
tftpRootDir = tftpRootDirList[0].strip()
|
tftpRootDir = tftpRootDirList[0].strip()
|
||||||
exitIfFail(preparePING(tftpRootDir))
|
exitIfFail(preparePING(tftpRootDir))
|
||||||
printMsg("")
|
printMsg("")
|
||||||
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)
|
||||||
|
|
||||||
|
|||||||
@ -6,9 +6,9 @@
|
|||||||
# to you under the Apache License, Version 2.0 (the
|
# to you under the Apache License, Version 2.0 (the
|
||||||
# "License"); you may not use this file except in compliance
|
# "License"); you may not use this file except in compliance
|
||||||
# with the License. You may obtain a copy of the License at
|
# with the License. You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing,
|
# Unless required by applicable law or agreed to in writing,
|
||||||
# software distributed under the License is distributed on an
|
# software distributed under the License is distributed on an
|
||||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
@ -18,11 +18,14 @@
|
|||||||
|
|
||||||
# Version @VERSION@
|
# 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 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,15 +40,18 @@ 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__
|
||||||
logging.debug("#### xen plugin enter %s ####" % name )
|
logging.debug("#### xen plugin enter %s ####" % name)
|
||||||
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"]
|
||||||
@ -59,17 +65,23 @@ def downloadTemplateFromUrl(session, args):
|
|||||||
except:
|
except:
|
||||||
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"]
|
||||||
try:
|
try:
|
||||||
template = urllib2.urlopen(srcUrl)
|
template = urllib2.urlopen(srcUrl)
|
||||||
headers = template.info()
|
headers = template.info()
|
||||||
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,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@ -6,9 +6,9 @@
|
|||||||
# to you under the Apache License, Version 2.0 (the
|
# to you under the Apache License, Version 2.0 (the
|
||||||
# "License"); you may not use this file except in compliance
|
# "License"); you may not use this file except in compliance
|
||||||
# with the License. You may obtain a copy of the License at
|
# with the License. You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing,
|
# Unless required by applicable law or agreed to in writing,
|
||||||
# software distributed under the License is distributed on an
|
# software distributed under the License is distributed on an
|
||||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
@ -18,10 +18,11 @@
|
|||||||
|
|
||||||
# Version @VERSION@
|
# 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 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,119 +34,147 @@ 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__
|
||||||
logging.debug("#### CLOUD enter %s ####" % name )
|
logging.debug("#### CLOUD enter %s ####" % name)
|
||||||
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,25 +31,33 @@ 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
|
||||||
# ---- 2) waf configured PYTHONDIR
|
# ---- 2) waf configured PYTHONDIR
|
||||||
# ---- 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,21 +96,20 @@ 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:
|
||||||
output = "%-80s"%msg
|
output = "%-80s" % msg
|
||||||
|
|
||||||
if result is True:
|
if result is True:
|
||||||
output += "[ \033[92m%-2s\033[0m ]\n"%"OK"
|
output += "[ \033[92m%-2s\033[0m ]\n" % "OK"
|
||||||
elif result is False:
|
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.write(output)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
def debug(self, msg):
|
def debug(self, msg):
|
||||||
msg = "DEBUG:%s"%msg
|
msg = "DEBUG:%s" % msg
|
||||||
sys.stdout.write(msg)
|
sys.stdout.write(msg)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
@ -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,36 +139,48 @@ 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)
|
||||||
|
|
||||||
prepareDBDotProperties()
|
prepareDBDotProperties()
|
||||||
|
|
||||||
@ -172,41 +192,69 @@ 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()
|
||||||
self.info(None, True)
|
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 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,26 +270,55 @@ 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]
|
||||||
|
|
||||||
This command sets up the CloudStack Encryption.
|
This command sets up the CloudStack Encryption.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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,10 +334,11 @@ 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()
|
||||||
o.run()
|
o.run()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user