mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Adding new marvincli changes(draft)
This commit is contained in:
parent
412791e09f
commit
6c4978c40c
@ -20,6 +20,7 @@ import os
|
||||
from optparse import OptionParser
|
||||
import cmd
|
||||
import random
|
||||
from collections import OrderedDict
|
||||
from marvin.marvinInit import MarvinInit
|
||||
from marvin.deployDataCenter import DeployDataCenters
|
||||
from marvin.cloudstackException import GetDetailExceptionInfo
|
||||
@ -31,73 +32,6 @@ from marvin.codes import (SUCCESS,
|
||||
from marvin.tcExecuteEngine import TestCaseExecuteEngine
|
||||
|
||||
|
||||
class MarvinCliHelp(object):
|
||||
|
||||
@classmethod
|
||||
def do_printhelp(cls):
|
||||
print "\n1. for building marvin from spec file and installing."
|
||||
cls.help_build_and_install()
|
||||
print "\n2. for syncing apis and installing marvin."
|
||||
cls.help_sync_and_install()
|
||||
print "\n3. for deploying a datacenter"
|
||||
cls.help_deploydc()
|
||||
print "\n4. for running test cases"
|
||||
cls.help_runtest()
|
||||
print "\n5. for deploying a datacenter (and) running tests"
|
||||
cls.help_deploydc_and_runtest()
|
||||
print "\n6. for generating apis from spec file"
|
||||
cls.help_generateapis_from_apispecfile()
|
||||
print "\n7. for generating apis from end point"
|
||||
cls.help_generateapis_from_endpoint()
|
||||
print "\n8. for printing marvincli version"
|
||||
cls.help_printversion()
|
||||
|
||||
@classmethod
|
||||
def print_msg(cls, msg):
|
||||
print ShellColor.BOLD + ShellColor.RED + msg + ShellColor.END
|
||||
|
||||
@classmethod
|
||||
def help_printversion(cls):
|
||||
cls.print_msg("marvincli -v or --version")
|
||||
|
||||
@classmethod
|
||||
def help_deploydc(cls):
|
||||
cls.print_msg(
|
||||
"marvincli [deploydc] \n\t[config-file=<marvin-config-file EX: advanced.cfg file>]")
|
||||
|
||||
@classmethod
|
||||
def help_deploydc_and_runtest(cls, deploy=False):
|
||||
msg = "marvincli [deploydc_and_runtest] \n\t[config-file=<path_to_marvin_cfg> \n\ttc-path=<test suite or test suite folder path>" \
|
||||
"\n\tzone=<name of the zone> \n\thyp-type=<hypervisor_type> " \
|
||||
"\n\trequired_hardware=<true\\false>]"
|
||||
cls.print_msg(msg)
|
||||
|
||||
@classmethod
|
||||
def help_generateapis_from_apispecfile(cls):
|
||||
cls.print_msg(
|
||||
"marvincli [generateapis_from_apispecfile] \n\t[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tapi-spec-file=<api spec file EX: /etc/cloud/cli/commands.xml>]")
|
||||
|
||||
@classmethod
|
||||
def help_generateapis_from_endpoint(cls):
|
||||
cls.print_msg(
|
||||
"marvincli [generateapis_from_endpoint] \n\t[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tend-point=<CS Endpoint ip EX: localhost>]")
|
||||
|
||||
@classmethod
|
||||
def help_runtest(cls):
|
||||
cls.print_msg(
|
||||
"marvincli [runtest] \n\t[config-file=<path_to_marvin_config> \n\ttc-path=test/integration/smoke \n\trequired_hardware=<true\\false> \n\tzone=<name of zone> \n\thyp-type=<xenserver\\kvm\\vmware> etc]")
|
||||
|
||||
@classmethod
|
||||
def help_sync_and_install(cls):
|
||||
cls.print_msg(
|
||||
"marvincli [sync_and_install] \n\t[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tend-point=<CS installed host ip EX: localhost>]")
|
||||
|
||||
@classmethod
|
||||
def help_build_and_install(cls):
|
||||
cls.print_msg(
|
||||
"marvincli [build_and_install] \n\t[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tapi-sync-file<api spec file generated by cs EX: /etc/cloud/cli/commands.xml>]")
|
||||
|
||||
|
||||
class VerifyAndExit(object):
|
||||
|
||||
def __init__(self, msg):
|
||||
@ -110,26 +44,113 @@ class VerifyAndExit(object):
|
||||
if original_func(*args, **kwargs) == FAILED:
|
||||
exit_check = True
|
||||
except Exception as e:
|
||||
print "---", e
|
||||
print "===Exception.Please Check:===", e
|
||||
exit_check = True
|
||||
finally:
|
||||
if exit_check:
|
||||
print "==== %s ====" % self.msg
|
||||
MarvinCliHelp.do_printhelp()
|
||||
MarvinCliHelp.print_cmds_help()
|
||||
sys.exit(1)
|
||||
return new_function
|
||||
|
||||
|
||||
class MarvinCliCommands(object):
|
||||
cmds_info = {'deploydc': {'options': ['config-file'], 'help': 'config-file=<marvin-config-file EX: advanced.cfg file>'},
|
||||
'deploydc_and_runtest': {'options': ['config-file', 'tc-path', 'zone', 'hyp-type', 'required_hardware'], 'help': ''},
|
||||
'generateapis_from_endpoint': {'options': '', 'help': '[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tend-point=<CS Endpoint ip EX: localhost>]'},
|
||||
'generateapis_from_apispecfile': {'options': '', 'help': '[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tapi-spec-file=<api spec file EX: /etc/cloud/cli/commands.xml>]'},
|
||||
'runtest': {'options': '', 'help': '[config-file=<path_to_marvin_config> \n\ttc-path=test/integration/smoke \n\trequired_hardware=<true\\false> \n\tzone=<name of zone> \n\thyp-type=<xenserver\\kvm\\vmware> etc]'},
|
||||
'sync_and_install': {'options': ['sync_and_install'], 'help': '[marvincli sync_and_install cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tend-point=<CS installed host ip EX: localhost>]'},
|
||||
'build_and_install': {'options': ['build_and_install'], 'help': '[marvincli build_and_install cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tapi-sync-file<api spec file generated by cs EX: /etc/cloud/cli/commands.xml>]'},
|
||||
'version': {'options': '', 'help': ''}
|
||||
}
|
||||
cmds_info = OrderedDict({
|
||||
'deploydc':
|
||||
{
|
||||
'summary': 'for deploying a datacenter',
|
||||
'options': ['*config-file'],
|
||||
'help': 'marvincli deploydc config-file=<marvin-config-file EX: setup/dev/advanced.cfg file>',
|
||||
'desc': 'deploys a data center using the config file provided'
|
||||
},
|
||||
'deploydc_and_runtest':
|
||||
{
|
||||
'summary': 'for deploying a datacenter (and) running tests, either test suite (or) directory of test suites',
|
||||
'options': ['*config-file', '*tc-path', 'zone', 'hyp-type', 'required_hardware'],
|
||||
'help': 'marvincli deploydc_and_runtest config-file=<path_to_marvin_cfg EX: setup/dev/advanced.cfg>'
|
||||
'tc-path=<test suite or test suite folder path EX: test/integration/smoke/>'
|
||||
'zone=<name of the zone> hyp-type=<hypervisor_type EX: xen,kvm,vmware etc> required_hardware=<true\\false>',
|
||||
'desc': 'deploys a data center using the config file provided, and runs test cases using the test suite or directory of test suites provided. '
|
||||
'If zone to run against is not provided, then default zone mentioned in config file is provided '
|
||||
'If hyp-type information is not provided, first hypervisor from config file is taken. '
|
||||
'If required_hardware option is not provided, then it is set to false'
|
||||
},
|
||||
'generateapis_from_endpoint':
|
||||
{
|
||||
'summary': 'for generating apis from cs end point',
|
||||
'options': ['*cs-folder-path', 'end-point'],
|
||||
'help': 'marvincli generateapis_from_endpoint cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/>'
|
||||
'end-point=<CS Endpoint ip EX: localhost>',
|
||||
'desc': 'generates cloudstackAPI directory with CS apis information from cloudstack endpoint. '
|
||||
'If end-point information is not provided, localhost is considered as default'
|
||||
|
||||
},
|
||||
'generateapis_from_apispecfile':
|
||||
{
|
||||
'summary': 'for generating apis from api spec file',
|
||||
'options': ['*cs-folder-path', 'api-spec-file'],
|
||||
'help': 'marvincli generateapis_from_apispecfile cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/>'
|
||||
'api-spec-file=<api spec file EX: /etc/cloud/cli/commands.xml>',
|
||||
'desc': 'generates cloudstackAPI directory with CS apis information from cloudstack api spec file. '
|
||||
'If spec file information is not provided, /etc/cloud/cli/commands.xml is considered as default'
|
||||
},
|
||||
'runtest':
|
||||
{
|
||||
'summary': 'for running test cases, either test suite (or) directory of test suites',
|
||||
'options': ['*config-file', '*tc-path', 'required_hardware', 'zone', 'hyp-type'],
|
||||
'help': 'marvincli runtest config-file=<path_to_marvin_config> tc-path=test/integration/smoke'
|
||||
'required_hardware=<true\\false> zone=<name of zone> hyp-type=<xenserver\\kvm\\vmware> etc',
|
||||
'desc': 'runs marvin integration tests against CS using config file, test suite path or directory of test suites are provided as input for running tests',
|
||||
},
|
||||
'sync_and_install':
|
||||
{
|
||||
'summary': 'for syncing apis and installing marvin using cs endpoint',
|
||||
'options': ['*cs-folder-path', 'end-point'],
|
||||
'help': 'marvincli sync_and_install cs-folder-path = <cloudstack code root dir EX: /root/cs-4.5/cloudstack/>'
|
||||
'end-point = <CS installed host ip EX: localhost>',
|
||||
'desc': 'generates cloudstackAPI directory with CS apis information from cloudstack end-point (and) installs new marvin.'
|
||||
'If end-point information is not provided, localhost is considered as default'
|
||||
},
|
||||
'build_and_install':
|
||||
{
|
||||
'summary': 'for building and installing marvin using spec file',
|
||||
'options': ['*cs-folder-path', 'api-sync-file'],
|
||||
'help': 'marvincli build_and_install cs-folder-path = <cloudstack code root dir EX: /root/cs-4.5/cloudstack/>'
|
||||
'api-sync-file = <api spec file generated by cs EX: /etc/cloud/cli/commands.xml>',
|
||||
'desc': 'generates cloudstackAPI directory with CS apis information from cloudstack api-spec-file (and) installs new marvin.'
|
||||
'If api spec file information is not provided, /etc/cloud/cli/commands.xml is considered as default'
|
||||
},
|
||||
'version':
|
||||
{
|
||||
'summary': 'for printing marvincli version',
|
||||
'options': ['-v (or) --version'],
|
||||
'help': 'marvincli -v (or) marvincli --version',
|
||||
'desc': 'prints the version of marvincli'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
class MarvinCliHelp(object):
|
||||
|
||||
@classmethod
|
||||
def print_cmds_help(cls):
|
||||
msg = ''
|
||||
for cmd_name, cmd_txt in MarvinCliCommands.cmds_info.items():
|
||||
msg = msg + \
|
||||
'\n----------------------------------------------------\n'
|
||||
cmd_info = ShellColor.BOLD + ShellColor.RED + \
|
||||
'cmd_name:%s' % str(cmd_name) + ShellColor.END
|
||||
for key, value in cmd_txt.iteritems():
|
||||
cmd_info = cmd_info + '\n' + \
|
||||
str(key) + ' : ' + str(value).strip('\n')
|
||||
msg = msg + cmd_info
|
||||
# return ShellColor.BOLD + ShellColor.RED + msg + ShellColor.END
|
||||
return msg
|
||||
|
||||
@classmethod
|
||||
def print_msg(cls, msg):
|
||||
if msg:
|
||||
return ShellColor.BOLD + ShellColor.RED + msg + ShellColor.END
|
||||
|
||||
|
||||
class ShellColor(object):
|
||||
@ -163,7 +184,8 @@ class MarvinCli(cmd.Cmd, object):
|
||||
self.__csFolder = "."
|
||||
cmd.Cmd.__init__(self)
|
||||
|
||||
@VerifyAndExit("Invalid input options, please check")
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def parse_input_deploy(self, inputs=None):
|
||||
'''
|
||||
Parses,reads the options and verifies for the config file
|
||||
@ -181,7 +203,8 @@ class MarvinCli(cmd.Cmd, object):
|
||||
return SUCCESS
|
||||
return FAILED
|
||||
|
||||
@VerifyAndExit("Invalid input options, please check")
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def parse_input_runtcs(self, inputs):
|
||||
'''
|
||||
Parses,reads the options and verifies for the config file
|
||||
@ -193,7 +216,6 @@ class MarvinCli(cmd.Cmd, object):
|
||||
(key, value) = item.split('=')
|
||||
out_dict[key] = value
|
||||
self.__configFile = out_dict.get('config-file', None)
|
||||
self.__deployFlag = out_dict.get('deploy', False)
|
||||
self.__zone = out_dict.get("zone", None)
|
||||
self.__hypervisorType = out_dict.get("hyp-type", None)
|
||||
self.__tcPath = out_dict.get("tc-path",)
|
||||
@ -225,13 +247,13 @@ class MarvinCli(cmd.Cmd, object):
|
||||
return FAILED
|
||||
except Exception as e:
|
||||
print "====Exception Occurred under start_marvin: %s ====" % \
|
||||
GetDetailExceptionInfo(e)
|
||||
GetDetailExceptionInfo(e)
|
||||
return FAILED
|
||||
|
||||
def run_test_suites(self):
|
||||
print "\n==== Started Running Test Cases ===="
|
||||
xunit_out_path = "/tmp/marvin_xunit_out" + \
|
||||
str(random.randrange(1, 10000)) + ".xml"
|
||||
str(random.randrange(1, 10000)) + ".xml"
|
||||
marvin_tc_run_cmd = "nosetests-2.7 -s --with-marvin --marvin-config=%s --with-xunit --xunit-file=%s %s -a tags=advanced, required_hardware=%s --zone=%s --hypervisor=%s"
|
||||
if os.path.isfile(self.__tcPath):
|
||||
marvin_tc_run_cmd = marvin_tc_run_cmd % (self.__configFile,
|
||||
@ -252,16 +274,32 @@ class MarvinCli(cmd.Cmd, object):
|
||||
'''
|
||||
print "\n==== Running Test Cases Successful ===="
|
||||
|
||||
def do_deploy(self, args):
|
||||
self.__deployFlag = True
|
||||
self.parse_input_deploy(inputs=args)
|
||||
self.start_marvin()
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def do_deploydc(self, args):
|
||||
try:
|
||||
self.__deployFlag = True
|
||||
self.parse_input_deploy(inputs=args)
|
||||
self.start_marvin()
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "==== deploy cmd failed :%s ==== " % str(e)
|
||||
return FAILED
|
||||
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def do_deploydc_and_runtest(self, args):
|
||||
self.do_deploy(inputs=args)
|
||||
self.parse_input_runtcs()
|
||||
self.run_test_suites()
|
||||
try:
|
||||
self.do_deploy(inputs=args)
|
||||
self.parse_input_runtcs()
|
||||
self.run_test_suites()
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "==== deploydc cmd failed:%s ==== " % str(e)
|
||||
return FAILED
|
||||
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def do_generateapis_from_apispecfile(self, args):
|
||||
api_spec_file = "/etc/cloud/cli/commands.xml"
|
||||
cs_api_folder = "."
|
||||
@ -281,11 +319,11 @@ class MarvinCli(cmd.Cmd, object):
|
||||
if api_spec_file:
|
||||
try:
|
||||
cg.generateCodeFromXML(api_spec_file)
|
||||
return
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "==== Generating apis from api spec file failed: %s ====" % str(e.message())
|
||||
sys.exit(1)
|
||||
sys.exit(1)
|
||||
return FAILED
|
||||
return FAILED
|
||||
|
||||
def create_marvin_api_folder(self, cs_folder_path='.'):
|
||||
cs_api_folder = cs_folder_path + "/tools/marvin/marvin/cloudstackAPI"
|
||||
@ -295,6 +333,8 @@ class MarvinCli(cmd.Cmd, object):
|
||||
os.makedirs(cs_api_folder)
|
||||
return cs_api_folder
|
||||
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def do_generateapis_from_endpoint(self, args):
|
||||
endpoint_url = 'http://%s:8096/client/api?command=listApis&\
|
||||
response=json'
|
||||
@ -312,36 +352,54 @@ response=json'
|
||||
try:
|
||||
endpoint_url = endpoint_url % str(cs_end_point)
|
||||
cg.generateCodeFromJSON(endpoint_url)
|
||||
return
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "==== Generating apis from end point failed: %s ====" % str(e.message())
|
||||
sys.exit(1)
|
||||
sys.exit(1)
|
||||
return FAILED
|
||||
return FAILED
|
||||
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def do_runtest(self, args):
|
||||
self.parse_input_runtcs(args)
|
||||
self.start_marvin()
|
||||
self.run_test_suites()
|
||||
try:
|
||||
self.parse_input_runtcs(args)
|
||||
self.start_marvin()
|
||||
self.run_test_suites()
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "==== run test failed: %s ====" % str(e.message())
|
||||
return FAILED
|
||||
|
||||
def install_marvin(self):
|
||||
if self.__csFolder:
|
||||
marvin_setup_file_path = self.__csFolder + "/tools/marvin/setup.py"
|
||||
# step2: Build and install the Marvin
|
||||
try:
|
||||
os.system("python %s install" % str(marvin_setup_file_path))
|
||||
print "==== Marvin Installed Successfully ===="
|
||||
except Exception as e:
|
||||
print "==== Marvin Installation Failed ===="
|
||||
print "==== Marvin Installed Successfully ===="
|
||||
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def do_build_and_install(self, args):
|
||||
# step1: Generate the apis from spec file first
|
||||
self.do_generateapis_from_apispecfile(args)
|
||||
self.install_marvin()
|
||||
try:
|
||||
self.do_generateapis_from_apispecfile(args)
|
||||
self.install_marvin()
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "==== build from end point and install marvin failed: %s ====" % str(e)
|
||||
return FAILED
|
||||
|
||||
@VerifyAndExit(
|
||||
"cmd failed, may be invalid input options, please check help")
|
||||
def do_sync_and_install(self, args):
|
||||
# step1: Generate the apis from spec file first
|
||||
self.do_generateapis_from_endpoint(args)
|
||||
self.install_marvin()
|
||||
try:
|
||||
self.do_generateapis_from_endpoint(args)
|
||||
self.install_marvin()
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "==== sync from spec file and install marvin failed: %s ====" % str(e)
|
||||
return FAILED
|
||||
|
||||
|
||||
class MarvinCliParser(OptionParser):
|
||||
@ -349,9 +407,14 @@ class MarvinCliParser(OptionParser):
|
||||
def format_help(self, formatter=None):
|
||||
if formatter is None:
|
||||
formatter = self.formatter
|
||||
print MarvinCliHelp.print_msg("Usage: marvincli [cmd] [options].See, the below cmds for more information \n\n")
|
||||
print MarvinCliHelp.do_printhelp()
|
||||
return "\n===========================================================================\n"
|
||||
result = []
|
||||
if self.usage:
|
||||
result.append(MarvinCliHelp.print_msg("\nUsage: marvincli [cmd] [options]. See, the below cmds for more information."
|
||||
"(*) signifies mandatory fields \n\n"))
|
||||
self.description = MarvinCliHelp.print_cmds_help()
|
||||
if self.description:
|
||||
result.append(self.format_description(formatter) + "\n")
|
||||
return "".join(result)
|
||||
|
||||
|
||||
def main():
|
||||
@ -364,12 +427,14 @@ def main():
|
||||
MarvinCliHelp.help_printversion()
|
||||
sys.exit(0)
|
||||
if len(sys.argv) > 1:
|
||||
if sys.argv[1].lower() in ["deploydc", "deploydc_and_runtest", "generateapis_from_endpoint",
|
||||
"generateapis_from_apispecfile", "runtest", "sync_and_install", "build_and_install"]:
|
||||
MarvinCli().onecmd(' '.join(args))
|
||||
else:
|
||||
if sys.argv[1].lower() not in MarvinCliCommands.cmds_info.keys():
|
||||
print "\n==== Invalid Command ===="
|
||||
sys.exit(1)
|
||||
args = ' '.join(args)
|
||||
if '-h' in args or '--help' in args:
|
||||
print MarvinCliCommands.cmds_info[sys.argv[0]]
|
||||
else:
|
||||
MarvinCli().onecmd(args)
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -111,10 +111,12 @@ class MarvinInit:
|
||||
if not self.__hypervisorType:
|
||||
if self.__parsedConfig and self.__parsedConfig.zones is not None:
|
||||
for zone in self.__parsedConfig.zones:
|
||||
for pod in zone.pods and pod is not None:
|
||||
for cluster in pod.clusters and cluster is not None:
|
||||
self.__hypervisorType = cluster.hypervisor
|
||||
break
|
||||
for pod in zone.pods:
|
||||
if pod is not None:
|
||||
for cluster in pod.clusters:
|
||||
if cluster is not None and cluster.hypervisor is not None:
|
||||
self.__hypervisorType = cluster.hypervisor
|
||||
break
|
||||
if not self.__zoneForTests:
|
||||
if self.__parsedConfig and self.__parsedConfig.zones is not None:
|
||||
for zone in self.__parsedConfig.zones:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user