def vm_reaper(): """ Iterates through each task in the db which has not yet been cleaned and runs the reaper This function iterates through each task. If the task is either failed or passed, ie, the task has completed, then the VM is cleaned up and then the docker container. If both of these operations occur, then the cleanup is set to True. """ tasks = tapi.task().get(cleanup=False)['objects'] for task in tasks: if task['result'] in ["failed", "passed", "invalid"]: vm_cleanup = False docker_cleanup = False if task['provider'] == "Sprout" and task['vm_name'] == "Sprout": vm_cleanup = True else: if task['provider'] and task['vm_name']: logger.info('Cleaning up {} on {}'.format( task['vm_name'], task['provider'])) if task['vm_name'] == "None": vm_cleanup = True else: appliance = Appliance(task['provider'], task['vm_name']) try: if appliance.does_vm_exist(): logger.info("Destroying {}".format( appliance.vm_name)) appliance.destroy() vm_cleanup = True except Exception: logger.info('Exception occured cleaning up') containers = dockerbot.dc.containers(all=True) for container in containers: if task['tid'] in container['Names'][0]: logger.info('Cleaning up docker container {}'.format( container['Id'])) dockerbot.dc.remove_container(container['Id'], force=True) docker_cleanup = True break else: docker_cleanup = True if docker_cleanup and vm_cleanup: tapi.task(task['tid']).put({'cleanup': True})
def vm_reaper(): """ Iterates through each task in the db which has not yet been cleaned and runs the reaper This function iterates through each task. If the task is either failed or passed, ie, the task has completed, then the VM is cleaned up and then the docker container. If both of these operations occur, then the cleanup is set to True. """ tasks = tapi.task().get(cleanup=False)['objects'] for task in tasks: if task['result'] in ["failed", "passed", "invalid"]: vm_cleanup = False docker_cleanup = False if task['provider'] == "Sprout" and task['vm_name'] == "Sprout": vm_cleanup = True else: if task['provider'] and task['vm_name']: logger.info('Cleaning up {} on {}'.format(task['vm_name'], task['provider'])) if task['vm_name'] == "None": vm_cleanup = True else: appliance = Appliance(task['provider'], task['vm_name']) try: if appliance.does_vm_exist(): logger.info("Destroying {}".format(appliance.vm_name)) appliance.destroy() vm_cleanup = True except Exception: logger.info('Exception occured cleaning up') containers = dockerbot.dc.containers(all=True) for container in containers: if task['tid'] in container['Names'][0]: logger.info('Cleaning up docker container {}'.format(container['Id'])) dockerbot.dc.remove_container(container['Id'], force=True) docker_cleanup = True break else: docker_cleanup = True if docker_cleanup and vm_cleanup: tapi.task(task['tid']).put({'cleanup': True})
def compliance_vm(request, provider_key, provider_crud): try: ip_addr = re.findall(r'[0-9]+(?:\.[0-9]+){3}', store.base_url)[0] appl_name = provider_crud.get_mgmt_system().get_vm_name_from_ip(ip_addr) appliance = Appliance(provider_key, appl_name) logger.info( "The tested appliance ({}) is already on this provider ({}) so reusing it.".format( appl_name, provider_key)) appliance.configure_fleecing() vm = Vm(appl_name, provider_crud) except VmNotFoundViaIP: logger.info("Provisioning a new appliance on provider {}.".format(provider_key)) appliance = provision_appliance( vm_name_prefix=PREFIX + "host_", version=str(version.current_version()), provider_name=provider_key) request.addfinalizer(lambda: diaper(appliance.destroy)) appliance.configure(setup_fleece=True) vm = Vm(appliance.vm_name, provider_crud) # Do the final touches with appliance.ipapp(browser_steal=True) as appl: appl.set_session_timeout(86400) provider_crud.refresh_provider_relationships() vm.wait_to_appear() vm.load_details() wait_for_ssa_enabled() yield vm
def call_appliance(provider_name, vm_name, action, *args): # Given a provider class, find the named method and call it with # *args. This could possibly be generalized for other CLI tools. appliance = Appliance(provider_name, vm_name) try: call = getattr(appliance, action) except AttributeError: raise Exception('Action "%s" not found' % action) if isinstance(getattr(type(appliance), action), property): return call else: return call(*args)
def get_appliance(provider): '''Fixture to provision appliance to the provider being tested if necessary''' global appliance_list, main_provider appliance_vm_prefix = "long-test_ssa-appl_" if provider.key not in appliance_list: try: # see if the current appliance is on the needed provider ip_addr = urlparse(store.base_url).hostname appl_name = provider.mgmt.get_vm_name_from_ip(ip_addr) logger.info( "re-using already provisioned appliance on {}...".format( provider.key)) main_provider = provider.key appliance = Appliance(provider.key, appl_name) appliance.configure_fleecing() appliance_list[provider.key] = appliance except Exception as e: logger.exception(e) # provision appliance and configure ver_to_prov = str(version.current_version()) logger.info("provisioning {} appliance on {}...".format( ver_to_prov, provider.key)) appliance = None try: appliance = provision_appliance( vm_name_prefix=appliance_vm_prefix, version=ver_to_prov, provider_name=provider.key) logger.info("appliance IP address: " + str(appliance.address)) appliance.configure(setup_fleece=True) except Exception as e: logger.exception(e) if appliance is not None: appliance.destroy() raise CFMEException( 'Appliance encountered error during initial setup: {}'. format(str(e))) appliance_list[provider.key] = appliance return appliance_list[provider.key]
def compliance_vm(request, provider): try: ip_addr = urlparse(store.base_url).hostname appl_name = provider.mgmt.get_vm_name_from_ip(ip_addr) appliance = Appliance(provider.key, appl_name) logger.info( "The tested appliance ({}) is already on this provider ({}) so reusing it." .format(appl_name, provider.key)) try: appliance.configure_fleecing() except (EOFError, ApplianceException) as e: # If something was happening, restart and wait for the UI to reappear to prevent errors appliance.ipapp.reboot() pytest.skip( "Error during appliance configuration. Skipping:\n{}: {}". format(type(e).__name__, str(e))) vm = Vm(appl_name, provider) except VmNotFoundViaIP: logger.info("Provisioning a new appliance on provider {}.".format( provider.key)) appliance = provision_appliance(vm_name_prefix=PREFIX + "host_", version=str(version.current_version()), provider_name=provider.key) request.addfinalizer(lambda: diaper(appliance.destroy)) try: appliance.configure(setup_fleece=True) except (EOFError, ApplianceException) as e: # Add known exceptions as needed. pytest.skip( "Error during appliance configuration. Skipping:\n{}: {}". format(type(e).__name__, str(e))) vm = Vm(appliance.vm_name, provider) if provider.type in {"rhevm"}: request.addfinalizer(appliance.remove_rhev_direct_lun_disk) # Do the final touches with appliance.ipapp(browser_steal=True) as appl: appl.set_session_timeout(86400) provider.refresh_provider_relationships() vm.wait_to_appear() vm.load_details() wait_for_ssa_enabled() yield vm
def compliance_vm(request, provider): try: ip_addr = urlparse(store.base_url).hostname appl_name = provider.mgmt.get_vm_name_from_ip(ip_addr) appliance = Appliance(provider.key, appl_name) logger.info( "The tested appliance (%s) is already on this provider (%s) so reusing it.", appl_name, provider.key) try: appliance.configure_fleecing() except (EOFError, ApplianceException) as e: # If something was happening, restart and wait for the UI to reappear to prevent errors appliance.ipapp.reboot() pytest.skip( "Error during appliance configuration. Skipping:\n{}: {}".format( type(e).__name__, str(e))) vm = VM.factory(appl_name, provider) except exceptions.VMNotFoundViaIP: logger.info("Provisioning a new appliance on provider %s.", provider.key) appliance = provision_appliance( vm_name_prefix=PREFIX + "host_", version=str(version.current_version()), provider_name=provider.key) request.addfinalizer(lambda: diaper(appliance.destroy)) try: appliance.configure(setup_fleece=True) except (EOFError, ApplianceException) as e: # Add known exceptions as needed. pytest.skip( "Error during appliance configuration. Skipping:\n{}: {}".format( type(e).__name__, str(e))) vm = VM.factory(appliance.vm_name, provider) if provider.type in {"rhevm"}: request.addfinalizer(appliance.remove_rhev_direct_lun_disk) # Do the final touches with appliance.ipapp(browser_steal=True) as appl: appl.set_session_timeout(86400) provider.refresh_provider_relationships() vm.wait_to_appear() vm.load_details() wait_for_ssa_enabled() yield vm
def get_appliance(provider_crud): '''Fixture to provision appliance to the provider being tested if necessary''' global appliance_list, main_provider appliance_vm_prefix = "test_vm_analysis" if provider_crud.key not in appliance_list: try: # see if the current appliance is on the needed provider ip_addr = re.findall(r'[0-9]+(?:\.[0-9]+){3}', conf.env['base_url'])[0] appl_name = provider_crud.get_mgmt_system().get_vm_name_from_ip(ip_addr) logger.info("re-using already provisioned appliance on {}...".format(provider_crud.key)) main_provider = provider_crud.key appliance = Appliance(provider_crud.key, appl_name) appliance.configure_fleecing() appliance_list[provider_crud.key] = appliance except Exception as e: logger.error("Exception: %s" % str(e)) # provision appliance and configure ver_to_prov = str(version.current_version()) logger.info("provisioning {} appliance on {}...".format(ver_to_prov, provider_crud.key)) appliance = None try: appliance = provision_appliance( vm_name_prefix=appliance_vm_prefix, version=ver_to_prov, provider_name=provider_crud.key) logger.info("appliance IP address: " + str(appliance.address)) appliance.configure(setup_fleece=True) except Exception as e: logger.error("Exception: %s" % str(e)) if appliance is not None: appliance.destroy() raise CFMEException( 'Appliance encountered error during initial setup: {}'.format(str(e))) appliance_list[provider_crud.key] = appliance return appliance_list[provider_crud.key]
def get_appliance(provider): '''Fixture to provision appliance to the provider being tested if necessary''' global appliance_list, main_provider appliance_vm_prefix = "long-test_ssa-appl_" if provider.key not in appliance_list: try: # see if the current appliance is on the needed provider ip_addr = urlparse(store.base_url).hostname appl_name = provider.mgmt.get_vm_name_from_ip(ip_addr) logger.info("re-using already provisioned appliance on {}...".format(provider.key)) main_provider = provider.key appliance = Appliance(provider.key, appl_name) appliance.configure_fleecing() appliance_list[provider.key] = appliance except Exception as e: logger.exception(e) # provision appliance and configure ver_to_prov = str(version.current_version()) logger.info("provisioning {} appliance on {}...".format(ver_to_prov, provider.key)) appliance = None try: appliance = provision_appliance( vm_name_prefix=appliance_vm_prefix, version=ver_to_prov, provider_name=provider.key) logger.info("appliance IP address: " + str(appliance.address)) appliance.configure(setup_fleece=True) except Exception as e: logger.exception(e) if appliance is not None: appliance.destroy() raise CFMEException( 'Appliance encountered error during initial setup: {}'.format(str(e))) appliance_list[provider.key] = appliance return appliance_list[provider.key]
def main(): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) # required options (heh) parser.add_argument('--provider', help='provider key in cfme_data') parser.add_argument('--template', help='the name of the template to clone') parser.add_argument('--vm_name', help='the name of the VM to create') # generic options parser.add_argument('--destroy', dest='destroy', action='store_true', help='Destroy the destination VM') parser.add_argument('--configure', default=False, action='store_true', help='configure the VM after provisioning') parser.add_argument('--no-cleanup', default=True, action='store_false', dest='cleanup', help="don't clean up the vm on clone failure") parser.add_argument('--log', dest='loglevel', default='WARNING', help='Set the log level') parser.add_argument('--outfile', dest='outfile', help='Write provisioning details to the named file', default='') # sub options organized for provider types rhev_parser = parser.add_argument_group('rhev') rhev_parser.add_argument('--cluster', default=None, help='the name of the VM on which to act') rhev_parser.add_argument('--place_policy_host', default=None, help='the host for the vm to start on') rhev_parser.add_argument('--place_policy_aff', default=None, help='the affinity of the vm on a host') cloud_parser = parser.add_argument_group('cloud') cloud_parser.add_argument('--flavor', default=None, help='ec2/rhos flavor') openstack_parser = parser.add_argument_group('openstack') openstack_parser.add_argument('--floating-ip-pool', default=None, help='openstack floating ip pool to use') args = parser.parse_args() # get_mgmt validates, since it will explode without an existing key or type provider = get_mgmt(args.provider) provider_dict = cfme_data['management_systems'][args.provider] provider_type = provider_dict['type'] # Used by the cloud provs flavors = cfme_data['appliance_provisioning']['default_flavors'].get(provider_type, []) logger.info('Connecting to {}'.format(args.provider)) if args.destroy: # TODO: destroy should be its own script # but it's easy enough to just hijack the parser here # This returns True if destroy fails to give POSIXy exit codes (0 is good, False is 0, etc) return not destroy_vm(provider, args.vm_name) deploy_args = { 'vm_name': args.vm_name, 'template': args.template, } # Try to snag defaults from cfme_data here for each provider type if provider_type == 'rhevm': cluster = provider_dict.get('default_cluster', args.cluster) if cluster is None: raise Exception('--cluster is required for rhev instances and default is not set') deploy_args['cluster'] = cluster if args.place_policy_host and args.place_policy_aff: deploy_args['placement_policy_host'] = args.place_policy_host deploy_args['placement_policy_affinity'] = args.rhev_place_policy_aff elif provider_type == 'ec2': # ec2 doesn't have an api to list available flavors, so the first flavor is the default try: flavor = args.flavor or flavors[0] except IndexError: raise Exception('--flavor is required for EC2 instances and default is not set') deploy_args['instance_type'] = flavor elif provider_type == 'openstack': # filter openstack flavors based on what's available available_flavors = provider.list_flavor() flavors = filter(lambda f: f in available_flavors, flavors) try: flavor = args.flavor or flavors[0] except IndexError: raise Exception('--flavor is required for RHOS instances and ' 'default is not set or unavailable on provider') # flavour? Thanks, psav... deploy_args['flavour_name'] = flavor if 'network' in provider_dict: # support rhos4 network names deploy_args['network_name'] = provider_dict['network'] provider_pools = [p.name for p in provider.api.floating_ip_pools.list()] try: # TODO: If there are multiple pools, have a provider default in cfme_data floating_ip_pool = args.floating_ip_pool or provider_pools[0] except IndexError: raise Exception('No floating IP pools available on provider') if floating_ip_pool is not None: deploy_args['floating_ip_pool'] = floating_ip_pool elif provider_type == "virtualcenter": if "allowed_datastores" in provider_dict: deploy_args["allowed_datastores"] = provider_dict["allowed_datastores"] elif provider_type == 'scvmm': deploy_args["host_group"] = provider_dict["provisioning"]['host_group'] # Do it! try: logger.info('Cloning {} to {} on {}'.format(args.template, args.vm_name, args.provider)) provider.deploy_template(**deploy_args) except Exception as e: logger.exception(e) logger.error('Clone failed') if args.cleanup: logger.info('attempting to destroy {}'.format(args.vm_name)) destroy_vm(provider, args.vm_name) return 12 if provider.is_vm_running(args.vm_name): logger.info("VM {} is running".format(args.vm_name)) else: logger.error("VM is not running") return 10 ip, time_taken = wait_for(provider.get_ip_address, [args.vm_name], num_sec=1200, fail_condition=None) logger.info('IP Address returned is {}'.format(ip)) if args.configure: logger.info('Configuring appliance, this can take a while.') app = Appliance(args.provider, args.vm_name) app.configure() if args.outfile: with open(args.outfile, 'w') as outfile: outfile.write("appliance_ip_address={}\n".format(ip)) # In addition to the outfile, drop the ip address on stdout for easy parsing print(ip)
def main(): parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) # required options (heh) parser.add_argument('--provider', help='provider key in cfme_data') parser.add_argument('--template', help='the name of the template to clone') parser.add_argument('--vm_name', help='the name of the VM to create') # generic options parser.add_argument('--destroy', dest='destroy', action='store_true', help='Destroy the destination VM') parser.add_argument('--configure', default=False, action='store_true', help='configure the VM after provisioning') parser.add_argument('--no-cleanup', default=True, action='store_false', dest='cleanup', help="don't clean up the vm on clone failure") parser.add_argument('--log', dest='loglevel', default='WARNING', help='Set the log level') parser.add_argument('--outfile', dest='outfile', help='Write provisioning details to the named file', default='') # sub options organized for provider types rhev_parser = parser.add_argument_group('rhev') rhev_parser.add_argument('--cluster', default=None, help='the name of the VM on which to act') rhev_parser.add_argument('--place_policy_host', default=None, help='the host for the vm to start on') rhev_parser.add_argument('--place_policy_aff', default=None, help='the affinity of the vm on a host') cloud_parser = parser.add_argument_group('cloud') cloud_parser.add_argument('--flavor', default=None, help='ec2/rhos flavor') openstack_parser = parser.add_argument_group('openstack') openstack_parser.add_argument('--floating-ip-pool', default=None, help='openstack floating ip pool to use') args = parser.parse_args() # get_mgmt validates, since it will explode without an existing key or type provider = get_mgmt(args.provider) provider_dict = cfme_data['management_systems'][args.provider] provider_type = provider_dict['type'] # Used by the cloud provs flavors = cfme_data['appliance_provisioning']['default_flavors'].get( provider_type, []) logger.info('Connecting to {}'.format(args.provider)) if args.destroy: # TODO: destroy should be its own script # but it's easy enough to just hijack the parser here # This returns True if destroy fails to give POSIXy exit codes (0 is good, False is 0, etc) return not destroy_vm(provider, args.vm_name) deploy_args = { 'vm_name': args.vm_name, 'template': args.template, } # Try to snag defaults from cfme_data here for each provider type if provider_type == 'rhevm': cluster = provider_dict.get('default_cluster', args.cluster) if cluster is None: raise Exception( '--cluster is required for rhev instances and default is not set' ) deploy_args['cluster'] = cluster if args.place_policy_host and args.place_policy_aff: deploy_args['placement_policy_host'] = args.place_policy_host deploy_args[ 'placement_policy_affinity'] = args.rhev_place_policy_aff elif provider_type == 'ec2': # ec2 doesn't have an api to list available flavors, so the first flavor is the default try: flavor = args.flavor or flavors[0] except IndexError: raise Exception( '--flavor is required for EC2 instances and default is not set' ) deploy_args['instance_type'] = flavor elif provider_type == 'openstack': # filter openstack flavors based on what's available available_flavors = provider.list_flavor() flavors = filter(lambda f: f in available_flavors, flavors) try: flavor = args.flavor or flavors[0] except IndexError: raise Exception('--flavor is required for RHOS instances and ' 'default is not set or unavailable on provider') # flavour? Thanks, psav... deploy_args['flavour_name'] = flavor if 'network' in provider_dict: # support rhos4 network names deploy_args['network_name'] = provider_dict['network'] provider_pools = [ p.name for p in provider.api.floating_ip_pools.list() ] try: # TODO: If there are multiple pools, have a provider default in cfme_data floating_ip_pool = args.floating_ip_pool or provider_pools[0] except IndexError: raise Exception('No floating IP pools available on provider') if floating_ip_pool is not None: deploy_args['floating_ip_pool'] = floating_ip_pool elif provider_type == "virtualcenter": if "allowed_datastores" in provider_dict: deploy_args["allowed_datastores"] = provider_dict[ "allowed_datastores"] elif provider_type == 'scvmm': deploy_args["host_group"] = provider_dict["provisioning"]['host_group'] # Do it! try: logger.info('Cloning {} to {} on {}'.format(args.template, args.vm_name, args.provider)) provider.deploy_template(**deploy_args) except Exception as e: logger.exception(e) logger.error('Clone failed') if args.cleanup: logger.info('attempting to destroy {}'.format(args.vm_name)) destroy_vm(provider, args.vm_name) return 12 if provider.is_vm_running(args.vm_name): logger.info("VM {} is running".format(args.vm_name)) else: logger.error("VM is not running") return 10 ip, time_taken = wait_for(provider.get_ip_address, [args.vm_name], num_sec=1200, fail_condition=None) logger.info('IP Address returned is {}'.format(ip)) if args.configure: logger.info('Configuring appliance, this can take a while.') app = Appliance(args.provider, args.vm_name) app.configure() if args.outfile: with open(args.outfile, 'w') as outfile: outfile.write("appliance_ip_address={}\n".format(ip)) # In addition to the outfile, drop the ip address on stdout for easy parsing print(ip)
def main(**kwargs): # get_mgmt validates, since it will explode without an existing key or type if kwargs.get('deploy', None): kwargs['configure'] = True kwargs['outfile'] = 'appliance_ip_address_1' provider_data = utils.conf.provider_data providers = provider_data['management_systems'] provider_dict = provider_data['management_systems'][kwargs['provider']] credentials =\ {'username': provider_dict['username'], 'password': provider_dict['password'], 'tenant': provider_dict['template_upload'].get('tenant_admin', 'admin'), 'auth_url': provider_dict.get('auth_url', None), } provider = get_mgmt(kwargs['provider'], providers=providers, credentials=credentials) flavors = provider_dict['template_upload'].get('flavors', ['m1.medium']) provider_type = provider_data['management_systems'][kwargs['provider']]['type'] deploy_args = { 'vm_name': kwargs['vm_name'], 'template': kwargs['template'], } else: provider = get_mgmt(kwargs['provider']) provider_dict = cfme_data['management_systems'][kwargs['provider']] provider_type = provider_dict['type'] flavors = cfme_data['appliance_provisioning']['default_flavors'].get(provider_type, []) deploy_args = { 'vm_name': kwargs['vm_name'], 'template': kwargs['template'], } logger.info('Connecting to {}'.format(kwargs['provider'])) if kwargs.get('destroy', None): # TODO: destroy should be its own script # but it's easy enough to just hijack the parser here # This returns True if destroy fails to give POSIXy exit codes (0 is good, False is 0, etc) return not destroy_vm(provider, deploy_args['vm_name']) # Try to snag defaults from cfme_data here for each provider type if provider_type == 'rhevm': cluster = provider_dict.get('default_cluster', kwargs.get('cluster', None)) if cluster is None: raise Exception('--cluster is required for rhev instances and default is not set') deploy_args['cluster'] = cluster if kwargs.get('place_policy_host', None) and kwargs.get('place_policy_aff', None): deploy_args['placement_policy_host'] = kwargs['place_policy_host'] deploy_args['placement_policy_affinity'] = kwargs['place_policy_aff'] elif provider_type == 'ec2': # ec2 doesn't have an api to list available flavors, so the first flavor is the default try: flavor = kwargs.get('flavor', None) or flavors[0] except IndexError: raise Exception('--flavor is required for EC2 instances and default is not set') deploy_args['instance_type'] = flavor elif provider_type == 'openstack': # filter openstack flavors based on what's available available_flavors = provider.list_flavor() flavors = filter(lambda f: f in available_flavors, flavors) try: flavor = kwargs.get('flavor', None) or flavors[0] except IndexError: raise Exception('--flavor is required for RHOS instances and ' 'default is not set or unavailable on provider') # flavour? Thanks, psav... deploy_args['flavour_name'] = flavor if 'network' in provider_dict: # support rhos4 network names deploy_args['network_name'] = provider_dict['network'] provider_pools = [p.name for p in provider.api.floating_ip_pools.list()] try: # TODO: If there are multiple pools, have a provider default in cfme_data floating_ip_pool = kwargs.get('floating_ip_pool', None) or provider_pools[0] except IndexError: raise Exception('No floating IP pools available on provider') if floating_ip_pool is not None: deploy_args['floating_ip_pool'] = floating_ip_pool elif provider_type == "virtualcenter": if "allowed_datastores" in provider_dict: deploy_args["allowed_datastores"] = provider_dict["allowed_datastores"] elif provider_type == 'scvmm': deploy_args["host_group"] = provider_dict["provisioning"]['host_group'] elif provider_type == 'gce': deploy_args['ssh_key'] = '{user_name}:{public_key}'.format( user_name=cred['ssh']['ssh-user'], public_key=cred['ssh']['public_key']) # Do it! try: logger.info('Cloning {} to {} on {}'.format(deploy_args['template'], deploy_args['vm_name'], kwargs['provider'])) provider.deploy_template(**deploy_args) except Exception as e: logger.exception(e) logger.error('Clone failed') if kwargs.get('cleanup', None): logger.info('attempting to destroy {}'.format(deploy_args['vm_name'])) destroy_vm(provider, deploy_args['vm_name']) return 12 if provider.is_vm_running(deploy_args['vm_name']): logger.info("VM {} is running".format(deploy_args['vm_name'])) else: logger.error("VM is not running") return 10 try: ip, time_taken = wait_for(provider.get_ip_address, [deploy_args['vm_name']], num_sec=1200, fail_condition=None) logger.info('IP Address returned is {}'.format(ip)) except Exception as e: logger.exception(e) logger.error('IP address not returned') return 10 try: if kwargs.get('configure', None): logger.info('Configuring appliance, this can take a while.') if kwargs.get('deploy', None): app = IPAppliance(address=ip) else: app = Appliance(kwargs['provider'], deploy_args['vm_name']) if provider_type == 'gce': with app as ipapp: ipapp.configure_gce() else: app.configure() logger.info('Successfully Configured the appliance.') except Exception as e: logger.exception(e) logger.error('Appliance Configuration Failed') if not kwargs.get('deploy', None): app = Appliance(kwargs['provider'], deploy_args['vm_name']) ssh_client = app.ssh_client() status, output = ssh_client.run_command('find /root/anaconda-post.log') if status == 0: ssh_client.get_file('/root/anaconda-post.log', log_path.join('anaconda-post.log').strpath) ssh_client.close() return 10 if kwargs.get('outfile', None) or kwargs.get('deploy', None): with open(kwargs['outfile'], 'w') as outfile: outfile.write("appliance_ip_address={}\n".format(ip)) # In addition to the outfile, drop the ip address on stdout for easy parsing print(ip)
def main(**kwargs): # get_mgmt validates, since it will explode without an existing key or type if kwargs.get('deploy', None): kwargs['configure'] = True provider_data = utils.conf.provider_data providers = provider_data['management_systems'] provider_dict = provider_data['management_systems'][kwargs['provider']] credentials =\ {'username': provider_dict['username'], 'password': provider_dict['password'], 'tenant': provider_dict['template_upload'].get('tenant_admin', None), 'auth_url': provider_dict.get('auth_url', None), } provider = get_mgmt(kwargs['provider'], providers=providers, credentials=credentials) flavors = provider_dict['template_upload'].get('flavors', []) provider_type = provider_data['management_systems'][kwargs['provider']]['type'] deploy_args = { 'vm_name': kwargs['vm_name'], 'template': kwargs['template'], } else: provider = get_mgmt(kwargs['provider']) provider_dict = cfme_data['management_systems'][kwargs['provider']] provider_type = provider_dict['type'] flavors = cfme_data['appliance_provisioning']['default_flavors'].get(provider_type, []) deploy_args = { 'vm_name': kwargs['vm_name'], 'template': kwargs['template'], } logger.info('Connecting to {}'.format(kwargs['provider'])) if kwargs.get('destroy', None): # TODO: destroy should be its own script # but it's easy enough to just hijack the parser here # This returns True if destroy fails to give POSIXy exit codes (0 is good, False is 0, etc) return not destroy_vm(provider, deploy_args['vm_name']) # Try to snag defaults from cfme_data here for each provider type if provider_type == 'rhevm': cluster = provider_dict.get('default_cluster', kwargs.get('cluster', None)) if cluster is None: raise Exception('--cluster is required for rhev instances and default is not set') deploy_args['cluster'] = cluster if kwargs.get('place_policy_host', None) and kwargs.get('place_policy_aff', None): deploy_args['placement_policy_host'] = kwargs['place_policy_host'] deploy_args['placement_policy_affinity'] = kwargs['place_policy_aff'] elif provider_type == 'ec2': # ec2 doesn't have an api to list available flavors, so the first flavor is the default try: flavor = kwargs.get('flavor', None) or flavors[0] except IndexError: raise Exception('--flavor is required for EC2 instances and default is not set') deploy_args['instance_type'] = flavor elif provider_type == 'openstack': # filter openstack flavors based on what's available available_flavors = provider.list_flavor() flavors = filter(lambda f: f in available_flavors, flavors) try: flavor = kwargs.get('flavor', None) or flavors[0] except IndexError: raise Exception('--flavor is required for RHOS instances and ' 'default is not set or unavailable on provider') # flavour? Thanks, psav... deploy_args['flavour_name'] = flavor if 'network' in provider_dict: # support rhos4 network names deploy_args['network_name'] = provider_dict['network'] provider_pools = [p.name for p in provider.api.floating_ip_pools.list()] try: # TODO: If there are multiple pools, have a provider default in cfme_data floating_ip_pool = kwargs.get('floating_ip_pool', None) or provider_pools[0] except IndexError: raise Exception('No floating IP pools available on provider') if floating_ip_pool is not None: deploy_args['floating_ip_pool'] = floating_ip_pool elif provider_type == "virtualcenter": if "allowed_datastores" in provider_dict: deploy_args["allowed_datastores"] = provider_dict["allowed_datastores"] elif provider_type == 'scvmm': deploy_args["host_group"] = provider_dict["provisioning"]['host_group'] # Do it! try: logger.info('Cloning {} to {} on {}'.format(deploy_args['template'], deploy_args['vm_name'], kwargs['provider'])) provider.deploy_template(**deploy_args) except Exception as e: logger.exception(e) logger.error('Clone failed') if kwargs.get('cleanup', None): logger.info('attempting to destroy {}'.format(deploy_args['vm_name'])) destroy_vm(provider, deploy_args['vm_name']) return 12 if provider.is_vm_running(deploy_args['vm_name']): logger.info("VM {} is running".format(deploy_args['vm_name'])) else: logger.error("VM is not running") return 10 ip, time_taken = wait_for(provider.get_ip_address, [deploy_args['vm_name']], num_sec=1200, fail_condition=None) logger.info('IP Address returned is {}'.format(ip)) if kwargs.get('configure', None): logger.info('Configuring appliance, this can take a while.') app = Appliance(kwargs['provider'], deploy_args['vm_name']) app.configure() if kwargs.get('outfile', None): with open(kwargs['outfile'], 'w') as outfile: outfile.write("appliance_ip_address={}\n".format(ip)) # In addition to the outfile, drop the ip address on stdout for easy parsing print(ip)