def run(**kwargs): """Calls all the functions needed to upload new template to RHEVM. This is called either by template_upload_all script, or by main function. Args: **kwargs: Kwargs generated from cfme_data['template_upload']['template_upload_rhevm']. """ ovaname = get_ova_name(kwargs.get('image_url')) mgmt_sys = cfme_data['management_systems'][kwargs.get('provider')] rhevurl = mgmt_sys['hostname'] rhevm_credentials = mgmt_sys['credentials'] username = credentials[rhevm_credentials]['username'] password = credentials[rhevm_credentials]['password'] ssh_rhevm_creds = mgmt_sys['hosts'][0]['credentials'] sshname = credentials[ssh_rhevm_creds]['username'] sshpass = credentials[ssh_rhevm_creds]['password'] rhevip = mgmt_sys['ipaddress'] apiurl = 'https://%s:443/api' % rhevurl ssh_client = make_ssh_client(rhevip, sshname, sshpass) api = API(url=apiurl, username=username, password=password, insecure=True, persistent_auth=False) template_name = kwargs.get('template_name', None) if template_name is None: template_name = cfme_data['basic_info']['appliance_template'] kwargs = update_params_api(api, **kwargs) check_kwargs(**kwargs) if api.templates.get(template_name) is not None: print "RHEVM: Found finished template with this name." print "RHEVM: The script will now end." else: print "RHEVM: Downloading .ova file..." download_ova(ssh_client, kwargs.get('image_url')) try: print "RHEVM: Templatizing .ova file..." template_from_ova(api, username, password, rhevip, kwargs.get('edomain'), ovaname, ssh_client) print "RHEVM: Importing new template..." import_template(api, kwargs.get('edomain'), kwargs.get('sdomain'), kwargs.get('cluster')) print "RHEVM: Making a temporary VM from new template..." make_vm_from_template(api, kwargs.get('cluster')) print "RHEVM: Adding disk to created VM..." add_disk_to_vm(api, kwargs.get('sdomain'), kwargs.get('disk_size'), kwargs.get('disk_format'), kwargs.get('disk_interface')) print "RHEVM: Templatizing VM..." templatize_vm(api, template_name, kwargs.get('cluster')) finally: cleanup(api, kwargs.get('edomain'), ssh_client, ovaname) ssh_client.close() api.disconnect() print "RHEVM: Done."
def conn(url, user, password): api = API(url=url, username=user, password=password, insecure=True) try: value = api.test() except: raise Exception("error connecting to the oVirt API") return api
def _initialize_api(hostname, username, password, ca, insecure): """ Initialize the oVirt RESTful API """ url = 'https://{hostname}/ovirt-engine/api'.format( hostname=hostname, ) api = API(url=url, username=username, password=password, ca_file=ca, validate_cert_chain=not insecure) pi = api.get_product_info() if pi is not None: vrm = '%s.%s.%s' % ( pi.get_version().get_major(), pi.get_version().get_minor(), pi.get_version().get_revision() ) logging.debug("API Vendor(%s)\tAPI Version(%s)" % ( pi.get_vendor(), vrm) ) else: api.test(throw_exception=True) return api
def conn(url, user, password): api = API(url=url, username=user, password=password, insecure=True) try: value = api.test() except: print "error connecting to the oVirt API" sys.exit(1) return api
def get_connection(location): api = API( url="https://" + locations.get(location, "host"), username=locations.get(location, "username"), password=locations.get(location, "password"), ca_file=locations.get(location, "certificate") ) print "Connected to %s successfully!" % api.get_product_info().name return api
def main(): URL='https://<ovirt-host>:443/api' USERNAME='******' PASSWORD='******' api = API(url=URL, username=USERNAME, password=PASSWORD,insecure=True) vm_list=api.vms.list() for vm in vm_list: print vm.name api.disconnect()
def main(): url='https://vm-rhevm01.infoplus-ot.ris:443/api' username='******' password=getpass.getpass("Supply password for user %s: " % username) api = API(url=url, username=username, password=password,insecure=True) vm_list=api.vms.list() for vm in vm_list: print vm.name api.disconnect()
def main(): URL = 'https://192.168.1.112:443/api' USERNAME = '******' PASSWORD = '******' api = API(url=URL, username=USERNAME, password=PASSWORD, insecure=True) vm = api.vms.get(name="ubuntu14.04") print vm.name #vm_list = api.vms.list() #for vm in vm_list: # print vm.name api.disconnect()
def start_vm(vm_name, host_ip): try: api = API(url="https://engine167.eayun.com", username="******", password="******", ca_file="ca.crt") vm = api.vms.get(name=vm_name) try: vm.start(action=params.Action(vm=params.VM(host=params.Host(address=host_ip)))) print "Started '%s'." % vm.get_name() except Exception as ex: print "Unable to start '%s': %s" % (vm.get_name(), ex) api.disconnect() except Exception as ex: print "Unexpected error: %s" % ex
def run(**kwargs): ovaname = get_ova_name(kwargs.get('image_url')) mgmt_sys = cfme_data['management_systems'][kwargs.get('provider')] rhevurl = mgmt_sys['hostname'] rhevm_credentials = mgmt_sys['credentials'] username = credentials[rhevm_credentials]['username'] password = credentials[rhevm_credentials]['password'] ssh_rhevm_creds = mgmt_sys['hosts'][0]['credentials'] sshname = credentials[ssh_rhevm_creds]['username'] sshpass = credentials[ssh_rhevm_creds]['password'] rhevip = mgmt_sys['ipaddress'] apiurl = 'https://%s:443/api' % rhevurl ssh_client = make_ssh_client(rhevip, sshname, sshpass) api = API(url=apiurl, username=username, password=password, insecure=True, persistent_auth=False) template_name = kwargs.get('template_name', None) if template_name is None: template_name = cfme_data['basic_info']['cfme_template_name'] if api.templates.get(template_name) is not None: print "RHEVM: Found finished template with this name." print "RHEVM: The script will now end." else: print "RHEVM: Downloading .ova file..." download_ova(ssh_client, kwargs.get('image_url')) print "RHEVM: Templatizing .ova file..." template_from_ova(api, username, password, rhevip, kwargs.get('edomain'), ovaname, ssh_client) print "RHEVM: Importing new template..." import_template(api, kwargs.get('edomain'), kwargs.get('sdomain'), kwargs.get('cluster')) print "RHEVM: Making a temporary VM from new template..." make_vm_from_template(api, kwargs.get('cluster')) print "RHEVM: Adding disk to created VM..." add_disk_to_vm(api, kwargs.get('sdomain'), kwargs.get('disk_size'), kwargs.get('disk_format'), kwargs.get('disk_interface')) print "RHEVM: Templatizing VM..." templatize_vm(api, template_name, kwargs.get('cluster')) print "RHEVM: Cleaning up..." cleanup(api, kwargs.get('edomain')) ssh_client.close() api.disconnect() print "RHEVM: Done."
def on_pass(self, button): self.api = API(url='https://127.0.0.1/api', username='******', password=self.w_password.edit_text.encode("ascii", "ignore"), insecure=True) if not self.api.vms.get(name=self.vm_name) == None: self.widget.set_popup_text("Vm named '%s' exists, please remove or rename it and try again" % self.vm_name) self.widget.open_pop_up() return divider = urwid.Divider("-") self.w_mgmt_profile = VnicProfileSelector(self.api, True, self.vnic_profile_changed_mgmt) self.w_int_profile = VnicProfileSelector(self.api, True, self.vnic_profile_changed_int) self.w_int_profile.set_ip_info(False) self.w_ext_profile = VnicProfileSelector(self.api, False, None) self.w_vm_pass = urwid.Edit(u"vm root password: "******"*") self.w_keystone_pass = urwid.Edit(u"keystone admin password: "******"*") self.widget.original_widget = urwid.Pile([ urwid.Text(u"Deploying neutron appliance under datacenter 'Default'"), divider, urwid.Text("Choose profile for management network:"), self.w_mgmt_profile, divider, urwid.Text("Choose profile for internal network:"), self.w_int_profile, divider, urwid.Text("Choose profile for external network:"), self.w_ext_profile, divider, self.w_vm_pass, self.w_keystone_pass, divider, urwid.Button(u"OK", on_press=self.begin_deploy) ])
def _init_api(self): self.log.debug("Doing blocking acquire() on global RHEVM API connection lock") self.api_connections_lock.acquire() self.log.debug("Got global RHEVM API connection lock") url = self.api_details['url'] username = self.api_details['username'] password = self.api_details['password'] self.api = API(url=url, username=username, password=password)
def process(api_url, username, password, cert_file=None): api = API(url=api_url, username=username, password=password, cert_file=cert_file, insecure=(not cert_file)) print('Connected to %s' % api_url) problematic_vms = list(iter_problematic_vms(api)) api.disconnect() if problematic_vms: print(build_search_criteria(problematic_vms, get_single_vm_criteria_by_name)) print(build_search_criteria(problematic_vms, get_single_vm_criteria_by_id)) else: print('All MAC addresses are in range')
def __init__(self, module): self.module = module user = module.params.get('user') password = module.params.get('password') server = module.params.get('server') port = module.params.get('port') insecure_api = module.params.get('insecure_api') url = "https://%s:%s" % (server, port) try: api = API(url=url, username=user, password=password, insecure=str(insecure_api)) api.test() self.conn = api except: raise Exception("Failed to connect to RHEV-M.")
def start_vms(vmObj): logging.info('Thread to start %s', vmObj.name) try: vmObj.start() #time.sleep(5) except Exception as e: logging.debug('Exception caught on VM ( %s) start:\n%s' % (vmObj.name, str(e))) failedVms.append(vmObj.name) if __name__ == "__main__": try: api = API(url=APIURL, username=APIUSER, password=APIPASS, ca_file=CAFILE) print 'Connected to oVIRT API %s Successfully' % APIURL logging.info ( 'Successfully Connected to %s' % APIURL) try: print ' \n I am logging in %s \n' % LOGFILENAME vmsList = api.vms.list() for i in vmsList: print i.name if i.status.state != 'up': logging.warning('%s is not up, trying to start it' % i.name) threadMe = Thread(target=start_vms, args=[i]) threadMe.start() threads.append(threadMe) except Exception as e: logging.debug('Error:\n%s' % str(e)) logging.warning ('No of VMs to start : %s' % len(threads)) print 'No of VMs to start: %s' % len(threads) for th in threads: logging.info ('Waiting for %s to join' % th) th.join (30) if not th.isAlive(): logging.info ('Thread : %s terminated' % (th.getName())) else: logging.debug( 'Thread : %s is still alive, you may check this task..' % (th)) logging.debug (' Below Vms failed to start with an exception:%s' % (failedVms)); api.disconnect() except Exception as ex: logging.debug('Unexpected error: %s' % ex)
def stop_vm(vm_name): try: api = API(url="https://engine167.eayun.com", username="******", password="******", ca_file="ca.crt") vm = api.vms.get(name=vm_name) try: vm.stop() print "Stoped '%s'." % vm.get_name() except Exception as ex: print "Unable to stop '%s': %s" % (vm.get_name(), ex) api.disconnect() except Exception as ex: print "Unexpected error: %s" % ex
def __init__(self, hostname, username, password, **kwargs): # generate URL from hostname if 'port' in kwargs: url = 'https://%s:%s/api' % (hostname, kwargs['port']) else: url = 'https://%s/api' % hostname self.api = API(url=url, username=username, password=password, insecure=True)
def __init__(self, hostname='localhost', username='******', password='******'): """ Initialize RHEVMSystem """ # sanitize hostname if not hostname.startswith('https://'): hostname = 'https://%s' % hostname if not hostname.endswith('/api'): hostname = '%s/api' % hostname self.api = API(url=hostname, username=username, password=password, insecure=True)
def conn(url, username, password, ca_file): """ define connection RHEV-M api""" try: api = API(url=url, username=username, password=password, ca_file=ca_file) return api except Exception as ex: print "Unexpected error: %s" % ex
def connect(): url = 'http://localhost:8080/ovirt-engine/api' username = '******' password = '******' print 'Connecting to', url, 'as', username api = API(url=url, username=username, password=password) print 'Connected' return api
def connect(self, args): try: self._api = API(args.url, args.username, args.password, insecure=True) except Exception, e: print "Failed to connect to: %s" % args.url print e sys.exit(1)
def rhevm_create_api(url, username, password): """Creates rhevm api endpoint. Args: url: URL to rhevm provider username: username used to log in into rhevm password: password used to log in into rhevm """ apiurl = 'https://%s:443/api' % url return API(url=apiurl, username=username, password=password, insecure=True, persistent_auth=False)
def connect(self): """Connect to oVirt/RHEV API""" try: self.api = API(url=self.url, username=self.user, password=self.password, insecure='True') return self.api except RequestError as err: print("Error: {} Reason: {}".format(err.status, err.reason)) exit(1)
def login(self, username, password): global api try: api = API(url=self.baseUrl, username=username, password=password, filter=True) except RequestError as reqErr: return False, "Login error" except ConnectionError as conErr: return False, "Bad URL" return True, ''
def __entrypoint(self): try: url = 'https://rhevserver.com' api = API(url=url, username=self._username, password=self._password, ca_file='ca.crt') return api except Exception as ex: print('Error: %s' % ex)
def _get_connection(self): #open a connection to the rest api connection = None try: connection = API(url='http://localhost:8080', username='******', password='******') except BaseException as ex: #letting the external proxy know there was an error print >> sys.stderr, ex return None return connection
def _get_connection(self): #open a connection to the rest api connection = None try: connection = API(url='http://host:port', username='******', password='') except BaseException as ex: #letting the external proxy know there was an error print >> sys.stderr, ex return None return connection
def initAPI(): global controller logging.debug("Initiating the API object") URL = API_OBJECT_PATH % (controller.CONF["HOST_FQDN"], controller.CONF["HTTPS_PORT"]) USERNAME = '******' try: controller.CONF["API_OBJECT"] = API( url=URL, username=USERNAME, password=controller.CONF['AUTH_PASS']) except: logging.error(traceback.format_exc()) raise Exception(ERROR_CREATE_API_OBJECT)
def connect(): api_url = "https://manager/ovirt-engine/api" api_user = "******" api_password = "******" api_ca = "/path/to/my.cer" try: api = API(url=api_url, username=api_user, password=api_password, ca_file=api_ca) return api except Exception as e: sys.exit("api connection failed: %s" % e)
def __init__(self, url, cluster_name, ca_file, username=None, password=None, kerberos=None, verbose=0, **kwargs): super(RHEVM, self).__init__() self.url = url self.username = username self.password = password self.cluster = cluster_name self.ca_file = ca_file self.kerberos = kerberos self.verbose = verbose self.debug = verbose > 1 if self.kerberos: if self.verbose: show("Using Kerberos authentication") self.api = API(url=self.url, kerberos=True, ca_file=self.ca_file, filter=True, debug=self.debug) else: if self.verbose: show("Using username and password: %s" % self.username) self.api = API(url=self.url, username=self.username, password=self.password, ca_file=self.ca_file, debug=self.debug)
def start_vm(vm_name, host_ip): try: api = API(url="https://engine167.eayun.com", username="******", password="******", ca_file="ca.crt") vm = api.vms.get(name=vm_name) try: vm.start( action = params.Action( vm = params.VM( host = params.Host(address = host_ip) ) ) ) print "Started '%s'." % vm.get_name() except Exception as ex: print "Unable to start '%s': %s" % (vm.get_name(), ex) api.disconnect() except Exception as ex: print "Unexpected error: %s" % ex
def get_engine_api(): api = None eac_data = ta_info_xml.get_engine_api_conf() if eac_data == {}: return try: # print eac_data['url'], eac_data['username'], eac_data['password'], eac_data['ca_file'] api = API(url=eac_data['url'], username=eac_data['username'], password=eac_data['password'], ca_file=eac_data['ca_file']) except Exception as e: pass return api
def login(self, url, username, password, ca_file): global api try: api = API(url=url, username=username, password=password, ca_file=ca_file) except RequestError as reqErr: return False, "Login error" except ConnectionError as conErr: return False, "Bad URL" except NoCertificatesError as certErr: return False, "SSL error. Use 'http(s)://'" except Exception as e: return False, str(e) return True, ''
def ovirt_create_storage(module): name = module.params['name'] datacenter = module.params['datacenter'] host = module.params['host'] path = module.params['path'] type = module.params['type'] storage_type = module.params['storage_type'] storage_url = module.params['storage_url'] username = module.params['username'] password = module.params['password'] url = module.params['url'] try: api = API(url=url, username=username, password=password, insecure=True, session_timeout=60) except Exception as ex: module.fail_json(msg='could not connect to ovirt api') isoParams = params.StorageDomain( name=name, data_center=api.datacenters.get(datacenter), type_=storage_type, host=api.hosts.get(host), storage=params.Storage( type_=type, address=storage_url, path=path, )) if api.datacenters.get(datacenter).storagedomains.get(name): module.exit_json(changed=False) if module.check_mode: module.exit_json(changed=True) try: sd = api.storagedomains.add(isoParams) api.datacenters.get(datacenter).storagedomains.add( api.storagedomains.get(name)) except Exception as ex: module.fail_json(msg='Adding storage domain failed' + str(ex)) module.exit_json(changed=True)
def waitfor_api(module): username = module.params['username'] password = module.params['password'] url = module.params['url'] max_tries = module.params['max_tries'] time_out = module.params['time_out'] while max_tries>0: try: api = API(url=url,username=username,password=password,insecure=True,timeout=0) module.exit_json(changed=False) except Exception as ex: sleep(time_out) max_tries -= 1 module.fail_json(msg='ovirt api timed out')
def main(argv=None): # setup connection engine_api = API(url=engine_url, username="******", password=password, insecure=True) print "Starting smoke testing" rhevh = approve(engine_api, node_name) print "Host approved" create_nfs_storage(engine_api, rhevh, 'data') print "Data storage created" create_nfs_storage(engine_api, rhevh, 'export') print "Export storage created" subprocess.check_call( ["rhevm-image-uploader", "--insecure", "-u", "admin@internal", "-p", password, "-e", "export", "upload", testvm]) print "Uploaded VMs" test_vm = import_vm(engine_api, testvm) print "Vm imported" start = datetime.datetime.now() test_vm.start() while test_vm.status.state != 'up': if (datetime.datetime.now() - start).seconds > 600: print "\033[1m Error: \033[0m start fail" raise RuntimeError("Cant start imported VM") time.sleep(5) test_vm = test_vm.update() print "All success" return 0
def connect_engine( self ): '''Connect ovirt-engine, default connect local ovirt-engine api = API(url="https://128.224.165.209:443/api", \ username="******", \ password="******", \ ca_file="/etc/pki/ovirt-engine/ca.pem") ''' try: self.api = API(url=self.ovirt_dict['URL'], username=self.ovirt_dict['USERINFOS'][0][0], password=self.ovirt_dict['USERINFOS'][0][1], ca_file=self.ovirt_dict['CA_FILE']) print 'Connect ovirt-engine successfully' self.ovirt_dict['CONNECTION'] = True except Exception as e: print 'Connect ovirt-engine failed:\n%s' % (str(e)) self.ovirt_dict['CONNECTION'] = False return False
def apilogin(url, username, password, insecure=True, persistent_auth=True, session_timeout=36000): api = None try: api = API(url=url, username=username, password=password, insecure=insecure, persistent_auth=persistent_auth, session_timeout=session_timeout) except: print "Error while logging in with supplied credentials, please check and try again" sys.exit(1) return api
def discover(URL, USERNAME, PASSWORD): from ovirtsdk.api import API from ovirtsdk.xml import params api = API(url=URL, username=USERNAME, password=PASSWORD, insecure=True) vm_list = api.vms.list() number_of_vms = len(vm_list) counter = 1 result = '{\n\t"data":[\n' for vm in vm_list: if counter < number_of_vms: result += '\t\t{ "{#VMNAME}":"%s%s%s" },\n' % (vm_prefix, vm.name, vm_suffix) else: result += '\t\t{ "{#VMNAME}":"%s%s%s" }\n' % (vm_prefix, vm.name, vm_suffix) counter += 1 result += '\t]\n}' create_dict(api, vm_list) return result
def apilogin(url, username, password, insecure=True, persistent_auth=True, session_timeout=36000): """ @param url: URL for RHEV-M / Ovirt @param username: username to use @param password: password for username @param insecure: if True, do not validate SSL cert @param persistent_auth: Use persistent authentication @param session_timeout: Session timeout for non-persistent authentication @return: """ api = None try: api = API(url=url, username=username, password=password, insecure=insecure, persistent_auth=persistent_auth, session_timeout=session_timeout) except: print("Error while logging in with supplied credentials, please check and try again") sys.exit(1) return api
def api(self, dc): """ Create an oVirt API instance for a requested datacenter :param dc: datacenter :type dc: str :rtype: ovirtsdk.api.API """ kwargs = { 'password': self.config.get(dc, OVIRT_PASSWORD), 'url': self.config.get(dc, OVIRT_URL), 'username': self.config.get(dc, OVIRT_USERNAME), } if self.config.has_option(dc, OVIRT_CA): kwargs['ca_file'] = self.config.get(dc, OVIRT_CA) if self.config.has_option(dc, OVIRT_API_INSECURE): kwargs['insecure'] = bool(self.config.get(dc, OVIRT_API_INSECURE)) return API(**kwargs)
def connect(ovirt_api_url, ovirt_username, ovirt_password, cinder_username, cinder_password, cinder_project, cinder_auth_url, ceph_conf_file, ceph_client, ceph_pool): VERSION = params.Version(major='4', minor='0') ovirt_api = API(url=ovirt_api_url, username=ovirt_username, password=ovirt_password, insecure=True) cinder_api = client.Client(cinder_username, cinder_password, cinder_project, cinder_auth_url, service_type="volume") ceph_api = rados.Rados(conffile=ceph_conf_file, name="client.{}".format(ceph_client)) ceph_api.connect() ceph_api_ioctx = ceph_api.open_ioctx(ceph_pool) return ovirt_api, cinder_api, ceph_api, ceph_api_ioctx
def ovirt_get_vms(self, url, user, passw, ssl_insecure): ''' using sdk to attack ovirt api and getting all the vms to be classfied ''' api = API(url=url, username=user, password=passw, insecure=ssl_insecure) logging.info('nodes found:') for vm in api.vms.list(): vnode = {} name = vm.get_name() group = self.classify_vm(name) vnode[group] = {} guestinfo = vm.get_guest_info() if guestinfo is not None and guestinfo.get_ips() is not None: for element in guestinfo.get_ips().get_ip(): ip = element.get_address() else: ip = [''] logging.info(vnode) vnode[group]['nodes'] = '{}-{}'.format(name, ip[0]) self.vnodes.append(vnode)
from ovirtsdk.api import API from ovirtsdk.xml import params VERSION = params.Version(major='3', minor='5') URL = 'https://rhevm.example.com/ovirt-engine/api' CA = '/etc/pki/ovirt-engine/ca.pem' USERNAME = '******' PASSWORD = '******' HOST_NAME = 'rhevh1' PM_ADDRESS = '192.168.101.11' try: api = API(url=URL, username=USERNAME, password=PASSWORD, ca_file=CA) print "Connected to %s successfully!" % api.get_product_info().name except Exception as err: print "Connection failed: %s" % err try: host = api.hosts.get(HOST_NAME) pm = host.get_power_management() pm.set_type('ilo') pm.set_enabled(True) pm.set_address(PM_ADDRESS) pm.set_username('root') pm.set_password('Secret') host.update()
disks['datadg_002'] = disk disk = {} disk['size'] = '6' disks['recodg_001'] = disk disks['recodg_002'] = disk disk = {} disk['size'] = '4' disks['systemdg_001'] = disk disks['systemdg_002'] = disk disks['systemdg_003'] = disk disks['systemdg_004'] = disk disk = None apiurl = "https://" + ovirt_host + "/api" api = API(url=apiurl, username='******', password='******', insecure=True) for disk in disks: print "Creating disk '%s' with size '%sGB'" % (disk, disks[disk]['size']) api.vms.get(guest_name).disks.add( params.Disk(storage_domains=params.StorageDomains( storage_domain=[api.storagedomains.get(datastore)]), size=int(disks[disk]['size']) * 1024 * 1024 * 1024, status=None, interface='virtio', format='raw', sparse=False, bootable=False, shareable=True, alias=guest_name + '_' + disk))
def ovirtConnect(url, username, password): """Connect to hostname oVirt server using user/password""" api = API(url=url, username=username, password=password, insecure=True) return api
class RHEVMSystem(MgmtSystemAPIBase): """ Client to RHEVM API This class piggy backs off ovirtsdk. Benefits of ovirtsdk: - Don't need intimite knowledge w/ RHEVM api itself. Detriments of ovirtsdk: - Response to most quaries are returned as an object rather than a string. This makes it harder to do simple stuff like getting the status of a vm. - Because of this, it makes listing VMs based on **kwargs impossible since ovirtsdk relies on re class to find matches. I.E. List out VM with this name (positive case) Ideal: self.api.vms.list(name='test_vm') Underneath the hood: - ovirtsdk fetches list of all vms [ovirtsdk.infrastructure.brokers.VM object, ...] - ovirtsdk then tries to filter the result using re. - tries to look for 'name' attr in ovirtsdk.infrastructure.brokers.VM object - found name attribute, in this case, the type of the value of the attribute is string. - match() succeed in comparing the value to 'test_vm' I.E. List out VM with that's powered on (negative case) Ideal: self.api.vms.list(status='up') Underneath the hood: - '^same step as above except^' - found status attribute, in this case, the type of the value of the attribute is ovirtsdk.xml.params.Status - match() failed because class is compared to string 'up' This problem should be attributed to how RHEVM api was designed rather than how ovirtsdk handles RHEVM api responses. - Obj. are not updated after action calls. - I.E. vm = api.vms.get(name='test_vm') vm.status.get_state() # returns 'down' vm.start() # wait a few mins vm.status.get_state() # returns 'down'; wtf? vm = api.vms.get(name='test_vm') vm.status.get_state() # returns 'up' """ def __init__(self, hostname='localhost', username='******', password='******'): """ Initialize RHEVMSystem """ # sanitize hostname if not hostname.startswith('https://'): hostname = 'https://%s' % hostname if not hostname.endswith('/api'): hostname = '%s/api' % hostname self.api = API(url=hostname, username=username, password=password, insecure=True) def _get_vm(self, vm_name=None): """ RHEVMSystem implementation in _get_vm. """ if vm_name is None: raise Exception('Could not find a VM named %s.' % vm_name) else: vm = self.api.vms.get(name=vm_name) if vm is None: raise Exception('Could not find a VM named %s.' % vm_name) return vm def start_vm(self, vm_name=None): """ RHEVMSystem implementation of start_vm. """ vm = self._get_vm(vm_name) if vm.status.get_state() == 'up': raise Exception('Could not start %s because it\'s already running.' % vm_name) else: ack = vm.start() if ack.get_status().get_state() == 'complete': return True return False def stop_vm(self, vm_name): """ RHEVMSystem implementation of stop_vm. """ vm = self._get_vm(vm_name) if vm.status.get_state() == 'down': raise Exception('Could not stop %s because it\'s not running.' % vm_name) else: ack = vm.stop() if ack.get_status().get_state() == 'complete': return True return False def delete_vm(self, vm_name): """ RHEVMSystem implementation of delete_vm. """ vm = self._get_vm(vm_name) if vm.status.get_state() == 'up': raise Exception('Could not delete %s because it\'s still running.' % vm_name) else: ack = vm.delete() if ack.get_status().get_state() == '': return True return False def create_vm(self, vm_name): """ RHEVMSystem implementation of create_vm. """ #Unfortunately, there are not enough smurf slaves in the village to build this functionality yet. pass def restart_vm(self, vm_name): """ RHEVMSystem implementation of restart_vm. """ if not self.stop_vm(vm_name): return False else: return self.start_vm(vm_name) def list_vm(self, **kwargs): """ RHEVMSystem implementation of list_vm. """ # list vm based on kwargs can be buggy # i.e. you can't return a list of powered on vm # but you can return a vm w/ a matched name vm_list = self.api.vms.list(**kwargs) return [vm.name for vm in vm_list] def info(self): """ RHEVMSystem implementation of info. """ # and we got nothing! pass def disconnect(self): """ RHEVMSystem implementation of disconnect. """ self.api.disconnect() def vm_status(self, vm_name=None): """ RHEVMSystem implementation of vm_status. """ state = self._get_vm(vm_name).get_status().get_state() print "vm " + vm_name + " status is " + state return state def is_vm_running(self, vm_name): """ RHEVMSystem implementation of is_vm_running. """ state = self.vm_status(vm_name) return "up" == state def is_vm_stopped(self, vm_name): """ RHEVMSystem implementation of is_vm_stopped. """ state = self.vm_status(vm_name) return "down" == state def is_vm_suspended(self, vm_name): """ RHEVMSystem implementation of is_vm_suspended. """ state = self.vm_status(vm_name) return "suspended" == state def suspend_vm(self, vm_name): """ RHEVMSystem implementation of suspend_vm. """ vm = self._get_vm(vm_name) if vm.status.get_state() == 'down': raise Exception('Could not suspend %s because it\'s not running.' % vm_name) else: ack = vm.suspend() return ack.get_status().get_state() == 'complete'
try: #force off #vmObj.stop() #graceful shutdown - http://website-humblec.rhcloud.com/ovirt-shutdownstop-start-virtual-machines-vms-ovirt-dc-automatically-using-python-sdk/#comment-253 vmObj.shutdown() #time.sleep(5) except Exception as e: logging.debug('Exception caught on VM ( %s) stop:\n%s' % (vmObj.name, str(e))) failedVms.append(vmObj.name) if __name__ == "__main__": try: api = API(url=APIURL, username=APIUSER, password=APIPASS, ca_file=CAFILE) print 'Connected to RHEVM API %s Successfully' % APIURL logging.info('Successfully Connected to %s' % APIURL) try: print ' \n I am logging in %s \n' % LOGFILENAME vmsList = api.vms.list() for i in vmsList: print i.name if i.status.state != 'down': logging.warning('%s is not down, trying to stop it' % i.name) threadMe = Thread(target=start_vms, args=[i]) threadMe.start() threads.append(threadMe) except Exception as e:
class TabNeutron(Tab): def __init__(self, main_loop): self.main_loop = main_loop self.name = u"Neutron Deploy" self.vm_name = "NeutronAppliance" self.widget = SimplePopupLauncher(self.get_pass()) def get_pass(self): self.w_password = urwid.Edit(u"Please enter admin@internal password to procceed: ", mask="*") return urwid.Columns([ ('weight', 4, self.w_password), ('weight', 1, urwid.Button(u"GO", on_press=self.on_pass)) ]) def on_pass(self, button): self.api = API(url='https://127.0.0.1/api', username='******', password=self.w_password.edit_text.encode("ascii", "ignore"), insecure=True) if not self.api.vms.get(name=self.vm_name) == None: self.widget.set_popup_text("Vm named '%s' exists, please remove or rename it and try again" % self.vm_name) self.widget.open_pop_up() return divider = urwid.Divider("-") self.w_mgmt_profile = VnicProfileSelector(self.api, True, self.vnic_profile_changed_mgmt) self.w_int_profile = VnicProfileSelector(self.api, True, self.vnic_profile_changed_int) self.w_int_profile.set_ip_info(False) self.w_ext_profile = VnicProfileSelector(self.api, False, None) self.w_vm_pass = urwid.Edit(u"vm root password: "******"*") self.w_keystone_pass = urwid.Edit(u"keystone admin password: "******"*") self.widget.original_widget = urwid.Pile([ urwid.Text(u"Deploying neutron appliance under datacenter 'Default'"), divider, urwid.Text("Choose profile for management network:"), self.w_mgmt_profile, divider, urwid.Text("Choose profile for internal network:"), self.w_int_profile, divider, urwid.Text("Choose profile for external network:"), self.w_ext_profile, divider, self.w_vm_pass, self.w_keystone_pass, divider, urwid.Button(u"OK", on_press=self.begin_deploy) ]) def vnic_profile_changed_mgmt(self, button, selected): if selected: if self.w_mgmt_profile.get_vnic_profile_id_by_name(button.get_label()) == self.w_int_profile.get_vnic_profile_id(): self.w_int_profile.set_ip_info(False) else: self.w_int_profile.set_ip_info(True) def vnic_profile_changed_int(self, button, selected): if selected: if self.w_mgmt_profile.get_vnic_profile_id() == self.w_int_profile.get_vnic_profile_id_by_name(button.get_label()): self.w_int_profile.set_ip_info(False) else: self.w_int_profile.set_ip_info(True) def begin_deploy(self, button): conf_widget = self.widget.original_widget self.output = urwid.Text("") widget = urwid.BoxAdapter(urwid.Frame( header=urwid.Text("Setup output:"), body=urwid.Filler(self.output, valign="bottom"), footer=urwid.Button("percentage"), focus_part="header"), 20) widget.set_focus("footer") self.widget.original_widget = widget self.log(u"Detecting ip conflicts...") conflict = True conflict_ip = self.w_mgmt_profile.w_ip.edit_text if os.system("arping %s -w 10" % conflict_ip): conflict = False elif not self.mgmt_int_same(): conflict_ip = self.w_int_profile.w_ip.edit_text if os.system("arping %s -w 10" % conflict_ip): conflict = False if conflict: self.widget.set_popup_text("IP address %s is already used, please configure a unused IP address." % conflict_ip) self.widget.open_pop_up() self.widget.original_widget = conf_widget return self.log(u"Begin neutron appliance deploy") self.add_vm() self.add_external_provider() self.configure_uiplugin() self.configure_httpd() self.log(u"Neutron appliance deploy finished, please REFRESH your webadmin page") self.api.disconnect() def log(self, text): self.output.set_text(self.output.text + text + "\n") self.main_loop.draw_screen() def mgmt_int_same(self): return self.w_mgmt_profile.get_vnic_profile_id() == self.w_int_profile.get_vnic_profile_id() def add_vm(self): mgmt_int_same = self.mgmt_int_same() template_name = "Neutron_Appliance_Template" nics = [] nics.append(params.NIC( name="eth0", boot_protocol="STATIC", on_boot=True, network=params.Network( ip=params.IP( address=self.w_mgmt_profile.w_ip.edit_text, netmask=self.w_mgmt_profile.w_netmask.edit_text, gateway=self.w_mgmt_profile.w_gateway.edit_text, ) ) )) if not mgmt_int_same: nics.append(params.NIC( name="eth2", boot_protocol="STATIC", on_boot=True, network=params.Network( ip=params.IP( address=self.w_int_profile.w_ip.edit_text, netmask=self.w_int_profile.w_netmask.edit_text, gateway=self.w_int_profile.w_gateway.edit_text, ) ) )) nics.append(params.NIC( name="eth1", boot_protocol="NONE", on_boot=True, )) vm=params.VM( name=self.vm_name, cluster=self.api.clusters.get(name="Default"), template=self.api.templates.get(name=template_name), ) self.log(u"Adding neutron vm") self.api.vms.add(vm) self.log(u"Neutron vm added successflly") self.api.vms.get(self.vm_name).nics.add(params.NIC( name='eth0', vnic_profile=params.VnicProfile(id=self.w_mgmt_profile.get_vnic_profile_id()), interface='virtio' )) self.log("NIC 'eth0' added to neutron vm as management network") self.api.vms.get(self.vm_name).nics.add(params.NIC( name='eth1', vnic_profile=params.VnicProfile(id=self.w_ext_profile.get_vnic_profile_id()), interface='virtio' )) self.log("NIC 'eth1' added to neutron vm as external network") if not mgmt_int_same: self.api.vms.get(self.vm_name).nics.add(params.NIC( name='eth2', vnic_profile=params.VnicProfile(id=self.w_int_profile.get_vnic_profile_id()), interface='virtio' )) self.log("NIC 'eth2' added to neutron vm as internal network") cloud_init_content = """runcmd: - sed -i 's/ServerAlias 127.0.0.1/ServerAlias %s/' /etc/httpd/conf.d/15-horizon_vhost.conf - sed -i 's/local_ip =127.0.0.1/local_ip = %s/' /etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini - sed -i 's/#CSRF_COOKIE_SECURE/CSRF_COOKIE_SECURE/' /etc/openstack-dashboard/local_settings - sed -i 's/#SESSION_COOKIE_SECURE/SESSION_COOKIE_SECURE/' /etc/openstack-dashboard/local_settings - service httpd restart - mysql neutron --execute="delete from ml2_gre_endpoints where ip_address='127.0.0.1'" - service neutron-openvswitch-agent restart - chkconfig cloud-init off - source /root/keystonerc_admin - keystone user-password-update --pass %s admin - sed -i '/^export OS_PASSWORD/c\export OS_PASSWORD=%s' /root/keystonerc_admin""" % ( self.w_mgmt_profile.w_ip.edit_text, self.w_mgmt_profile.w_ip.edit_text if mgmt_int_same else self.w_int_profile.w_ip.edit_text, self.w_keystone_pass.edit_text, self.w_keystone_pass.edit_text, ) initialization=params.Initialization( cloud_init=params.CloudInit( host=params.Host(address="localhost"), regenerate_ssh_keys=True, users=params.Users( user=[params.User(user_name="root", password=self.w_vm_pass.edit_text)] ), network_configuration=params.NetworkConfiguration( nics=params.Nics(nic=nics) ), files=params.Files( file=[params.File(name="/tmp/setup", type_="PLAINTEXT", content=cloud_init_content,)] ) ) ) self.log("Wait for vm to be created...") created = False while not created: time.sleep(10) if "down" == self.api.vms.get(name=self.vm_name).status.state: created = True self.log("Starting vm...") vm = self.api.vms.get(name=self.vm_name) vm.start( action=params.Action( use_cloud_init=True, vm=params.VM( initialization=initialization ) ) ) def add_external_provider(self): external_provider_name = "neutron-appliance" if not self.api.openstacknetworkproviders.get(name=external_provider_name) == None: self.log("Removing existing external provider: %s ..." % external_provider_name) self.api.openstacknetworkproviders.get(name=external_provider_name).delete() self.log(u"Adding external provider...") agent_configuration = params.AgentConfiguration( network_mappings='vmnet:br-tun', broker_type='rabbit_mq', address=self.w_mgmt_profile.w_ip.edit_text, port=5672, username='******', password='******', ) self.api.openstacknetworkproviders.add(params.OpenStackNetworkProvider( name=external_provider_name, description='auto created by eayunos', url='http://%s:9696' % self.w_mgmt_profile.w_ip.edit_text, requires_authentication=True, username='******', password=self.w_password.edit_text.encode("ascii", "ignore"), authentication_url='http://%s:5000/v2.0/' % self.w_mgmt_profile.w_ip.edit_text, tenant_name='admin', plugin_type='OPEN_VSWITCH', agent_configuration=agent_configuration, )) self.log(u"External provider added successfully") def configure_uiplugin(self): os.system("ln -nsf /usr/share/neutron-uiplugin/neutron-resources /usr/share/ovirt-engine/ui-plugins/neutron-resources") os.system("ln -nsf /usr/share/neutron-uiplugin/neutron.json /usr/share/ovirt-engine/ui-plugins/neutron.json") self.log("Neutron uiplugin configured") def configure_httpd(self): content = """ProxyPass "/dashboard" "http://{IP}/dashboard" ProxyPassReverse "/dashboard" "http://{IP}/dashboard" ProxyPass "/static" "http://{IP}/static" ProxyPassReverse "/static" "http://{IP}/static" """.replace("{IP}", self.w_mgmt_profile.w_ip.edit_text) with open("/etc/httpd/conf.d/z-neutron.conf", "w") as f: f.write(content) self.log("Restarting httpd service") os.system("service httpd restart") self.log("Httpd reverse proxy configured")
#!/usr/bin/python from ovirtsdk.api import API from ovirtsdk.xml import params import time import sys USERNAME = '******' PASSWORD = '******' URL = 'https://localhost/api' api = API(URL, username=USERNAME, password=PASSWORD, insecure=True) student_vms = api.vms.list(query="*") avail = api.storagedomains.get( name="Sys_11").get_available() / 1024 / 1024 / 1024 for j in student_vms: if j.name == "Win7-teacher1": pass else: try: print j.name console_user = j.sessions.list()[0] if (console_user.get_console_user() != True) and (avail <= 20): j.stop() except: pass
class RHEVMHelper(object): api_connections_lock = BoundedSemaphore() def __init__(self, url, username, password): self.log = logging.getLogger('%s.%s' % (__name__, self.__class__.__name__)) # The SDK allows only a single active connection object to be created, regardless of whether # or not multiple RHEVM servers are being accessed. For now we need to have a global lock, # create a connection object before each batch of API interactions and then disconnect it. self.api_details = { 'url':url, 'username':username, 'password':password } # TODO: When this limitation in the ovirt SDK is removed, get rid of these def _init_api(self): self.log.debug("Doing blocking acquire() on global RHEVM API connection lock") self.api_connections_lock.acquire() self.log.debug("Got global RHEVM API connection lock") url = self.api_details['url'] username = self.api_details['username'] password = self.api_details['password'] self.api = API(url=url, username=username, password=password, insecure=True) def _disconnect_api(self): try: self.log.debug("Attempting API disconnect") if hasattr(self, 'api') and self.api is not None: self.api.disconnect() else: self.log.debug("API connection was not initialized. Will not attempt to disconnect.") finally: # Must always do this self.log.debug("Releasing global RHEVM API connection lock") self.api_connections_lock.release() # These are the only two genuinley public methods # What we create is a VM template def import_template(self, image_filename, nfs_host, nfs_path, nfs_dir, cluster, ovf_name = None, ovf_desc = None): if not ovf_desc: self.ovf_desc = "Imported by Image Factory" else: self.ovf_desc = ovf_desc self.log.debug("Preparing for RHEVM template import of image file (%s)" % (image_filename)) # API lock protected action try: self._init_api() self.init_vm_import(image_filename, nfs_host, nfs_path, nfs_dir, cluster) finally: self._disconnect_api() self.ovf_name = ovf_name self.log.debug("Staging files") self.stage_files() self.log.debug("Moving files to final export domain location") self.move_files() self.ovf_pkg.delete() self.log.debug("Executing import") # API lock protected action try: self._init_api() self.execute_import() finally: self._disconnect_api() return str(self.ovf_pkg.tpl_uuid) def delete_template(self, template_uuid): template = self.api.templates.get(id=template_uuid) if template: template.delete() return True else: return False # Begin Nuts and Bolts # We don't want to run seteuid() in our main process as it will globally change the UID/GID for everything # OTOH, we need to be root to access our image files and temp files # We use stdin and Popen's preexec_fn via the helper functions below to deal with this def become_nfs_user(self): os.setegid(NFSGID) os.seteuid(NFSUID) def copy_as_nfs_user(self, sourcefile, destfile): self.log.debug("Copying (%s) to (%s) as nfsuser" % (sourcefile, destfile)) f = open(sourcefile,"r") (stdout, stderr, retcode) = subprocess_check_output([ 'dd', 'of=%s' % (destfile), 'bs=4k' ], stdin=f, preexec_fn=self.become_nfs_user) f.close() def copy_dir_as_nfs_user(self, sourcefile, destfile): self.log.debug("Copying directory (%s) to (%s) as nfsuser" % (sourcefile, destfile)) (stdout, stderr, retcode) = subprocess_check_output([ 'cp', '-r', '%s' % (sourcefile), '%s' % (destfile)], preexec_fn=self.become_nfs_user) def move_as_nfs_user(self, sourcefile, destfile): self.log.debug("Moving (%s) to (%s) as nfsuser" % (sourcefile, destfile)) (stdout, stderr, retcode) = subprocess_check_output([ 'mv', '%s' % (sourcefile), '%s' % (destfile)], preexec_fn=self.become_nfs_user) def mkdir_as_nfs_user(self, directory): self.log.debug("Making directory (%s) as nfsuser" % (directory)) (stdout, stderr, retcode) = subprocess_check_output([ 'mkdir', '%s' % (directory)], preexec_fn=self.become_nfs_user) def rm_rf_as_nfs_user(self, directory): self.log.debug("Recursive remove of dir (%s) as nfsuser" % (directory)) (stdout, stderr, retcode) = subprocess_check_output([ 'rm', '-rf', '%s' % (directory)], preexec_fn=self.become_nfs_user) def get_storage_domain(self, nfs_host, nfs_path): # Find the storage domain that matches the nfs details given sds = self.api.storagedomains.list() for sd in sds: if sd.get_type() == "export": self.log.debug("Export domain: (%s)" % (sd.get_name())) stor = sd.get_storage() if (stor.get_address() == nfs_host) and (stor.get_path() == nfs_path): self.log.debug("This is the right domain (%s)" % (sd.get_id())) return sd return None def get_pool_id(self, sd_uuid): # Get datacenter for a given storage domain UUID # This is the UUID that becomes the "StoragePoolID" in our OVF XML # TODO: The storagedomain object has a get_data_center() method that doesn't seem to work # Find out why dcs = self.api.datacenters.list() for dc in dcs: self.log.debug("Looking for our storage domain (%s) in data center (%s)" % (sd_uuid, dc.get_id())) sd = dc.storagedomains.get(id=sd_uuid) if sd: self.log.debug("This is the right datacenter (%s)" % (dc.get_id())) return dc return None def get_cluster_by_dc(self, poolid): # If we have been passed "_any_" as the cluster name, we pick the first cluster that # matches our datacenter/pool ID clusters = self.api.clusters.list() for cluster in clusters: dc_id = None if cluster.get_data_center(): dc_id = cluster.get_data_center().get_id() self.log.debug("Checking cluster (%s) with name (%s) with data center (%s)" % (cluster.get_id(), cluster.get_name(), dc_id)) if dc_id == poolid: return cluster self.log.debug("Cannot find cluster for dc (%s)" % (poolid)) return None def get_cluster_by_name(self, name): # If we have been passed a specific cluster name, we need to find that specific cluster clusters = self.api.clusters.list() for cluster in clusters: self.log.debug("Checking cluster (%s) with name (%s)" % (cluster.get_id(), cluster.get_name())) if cluster.get_name() == name: return cluster self.log.debug("Cannot find cluster named (%s)" % (name)) return None def init_vm_import(self, image_filename, nfs_host, nfs_path, nfs_dir, cluster): # Prepare for the import of a VM self.image_filename = image_filename self.nfs_host = nfs_host self.nfs_path = nfs_path self.nfs_dir = nfs_dir # Sets some values used when creating XML and meta files self.storage_domain_object = self.get_storage_domain(nfs_host, nfs_path) if self.storage_domain_object: self.storage_domain = self.storage_domain_object.get_id() else: raise Exception("Cannot find storage domain matching NFS details given") self.dc_object = self.get_pool_id(self.storage_domain) if self.dc_object: # Our StoragePoolID is the UUID of the DC containing our storage domain self.pool_id=self.dc_object.get_id() else: raise Exception("Cannot find datacenter for our storage domain") if cluster == '_any_': self.cluster_object = self.get_cluster_by_dc(self.pool_id) else: self.cluster_object = self.get_cluster_by_name(cluster) if self.cluster_object: self.cluster = self.cluster_object.get_id() else: raise Exception("Cannot find cluster (%s)" % (cluster)) def stage_files(self): # Called after init to copy files to staging location # This is the base dir of the export domain self.export_domain_dir = self.nfs_dir + "/" + self.storage_domain if not os.path.isdir(self.export_domain_dir): raise Exception("Cannot find expected export domain directory (%s) at local mount point (%s)" % (self.nfs_dir, self.storage_domain)) self.ovf_pkg = RHEVOVFPackage(disk=self.image_filename, ovf_name=self.ovf_name, ovf_desc=self.ovf_desc) self.ovf_pkg.sync() def move_files(self): self.final_image_dir = "%s/images/%s" % (self.export_domain_dir, str(self.ovf_pkg.img_uuid)) self.final_ovf_dir = "%s/master/vms/%s" % (self.export_domain_dir, str(self.ovf_pkg.tpl_uuid)) self.copy_dir_as_nfs_user(self.ovf_pkg.image_dir, self.final_image_dir) self.copy_dir_as_nfs_user(self.ovf_pkg.ovf_dir, self.final_ovf_dir) def remove_export_template(self): self.rm_rf_as_nfs_user(self.final_image_dir) self.rm_rf_as_nfs_user(self.final_ovf_dir) def execute_import(self): # We import to the master storage domain of the datacenter of which our export domain is a member # Got it? action = params.Action() sds = self.dc_object.storagedomains.list() for sd in sds: if sd.get_master(): action.storage_domain=sd if not action.storage_domain: raise Exception("Could not find master storage domain for datacenter ID (%s)" % (self.dc_object.get_id())) action.cluster = self.cluster_object # At this point our freshly copied in files are discoverable via the tpl_uuid in our export domain template = self.storage_domain_object.templates.get(id=str(self.ovf_pkg.tpl_uuid)) if template: template.import_template(action=action) real_template = self.api.templates.get(id=str(self.ovf_pkg.tpl_uuid)) # Wait 5 minutes for an import to finish self.log.debug("Waiting for template import to complete") for i in range(30): self.log.debug("Waited %d - state (%s)" % (i*10, real_template.get_status().get_state())) if real_template.get_status().get_state() != 'locked': break real_template = real_template.update() sleep(10) self.log.debug("Deleting export domain files") self.remove_export_template() final_state = real_template.get_status().get_state() if final_state == 'ok': self.log.debug("Template import completed successfully") return elif final_state == 'locked': raise Exception("Timed out waiting for template import to finish") else: raise Exception("Template import ended in unknown state (%s)" % (final_state))
class RHEVMSystem(MgmtSystemAPIBase): """ Client to RHEVM API This class piggy backs off ovirtsdk. Benefits of ovirtsdk: - Don't need intimite knowledge w/ RHEVM api itself. Detriments of ovirtsdk: - Response to most quaries are returned as an object rather than a string. This makes it harder to do simple stuff like getting the status of a vm. - Because of this, it makes listing VMs based on **kwargs impossible since ovirtsdk relies on re class to find matches. E.G. List out VM with this name (positive case) Ideal: self.api.vms.list(name='test_vm') Underneath the hood: - ovirtsdk fetches list of all vms [ovirtsdk.infrastructure.brokers.VM object, ...] - ovirtsdk then tries to filter the result using re. - tries to look for 'name' attr in ovirtsdk.infrastructure.brokers.VM object - found name attribute, in this case, the type of the value of the attribute is string. - match() succeed in comparing the value to 'test_vm' E.G. List out VM with that's powered on (negative case) Ideal: self.api.vms.list(status='up') Underneath the hood: - '^same step as above except^' - found status attribute, in this case, the type of the value of the attribute is ovirtsdk.xml.params.Status - match() failed because class is compared to string 'up' This problem should be attributed to how RHEVM api was designed rather than how ovirtsdk handles RHEVM api responses. - Obj. are not updated after action calls. - E.G. vm = api.vms.get(name='test_vm') vm.status.get_state() # returns 'down' vm.start() # wait a few mins vm.status.get_state() # returns 'down'; wtf? vm = api.vms.get(name='test_vm') vm.status.get_state() # returns 'up' """ _stats_available = { 'num_vm': lambda self: len(self.list_vm()), 'num_host': lambda self: len(self.list_host()), 'num_cluster': lambda self: len(self.list_cluster()), 'num_template': lambda self: len(self.list_template()), 'num_datastore': lambda self: len(self.list_datastore()), } def __init__(self, hostname, username, password, **kwargs): # generate URL from hostname if 'port' in kwargs: url = 'https://%s:%s/api' % (hostname, kwargs['port']) else: url = 'https://%s/api' % hostname self.api = API(url=url, username=username, password=password, insecure=True) def _get_vm(self, vm_name=None): if vm_name is None: raise Exception('Could not find a VM named %s.' % vm_name) else: vm = self.api.vms.get(name=vm_name) if vm is None: raise Exception('Could not find a VM named %s.' % vm_name) return vm def get_ip_address(self, vm_name): vm = self._get_vm(vm_name) return vm.get_guest_info().get_ips().get_ip()[0].get_address() def does_vm_exist(self, name): try: self._get_vm(name) return True except Exception: return False def start_vm(self, vm_name=None): vm = self._get_vm(vm_name) if vm.status.get_state() == 'up': return True else: ack = vm.start() if ack.get_status().get_state() == 'complete': return True return False def stop_vm(self, vm_name): vm = self._get_vm(vm_name) if vm.status.get_state() == 'down': return True else: ack = vm.stop() if ack.get_status().get_state() == 'complete': return True return False def delete_vm(self, vm_name): vm = self._get_vm(vm_name) if vm.status.get_state() == 'up': self.stop_vm(vm_name) ack = vm.delete() if ack == '': return True else: return False def create_vm(self, vm_name): raise NotImplementedError('This function has not yet been implemented.') # Heres the code but don't have a need and no time to test it to get it right # including for inclusion later # # def create_vm(self, vm_name, *args, **kwargs): # MB = 1024 * 1024 # try: # self.api.vms.add( # params.VM( # name=vm_name, # memory=kwargs['memory_in_mb'] * MB, # cluster=self.api.clusters.get(kwargs['cluster_name']), # template=self.api.templates.get('Blank'))) # print 'VM created' # self.api.vms.get(vm_name).nics.add(params.NIC(name='eth0', # network=params.Network(name='ovirtmgmt'), interface='virtio')) # print 'NIC added to VM' # self.api.vms.get(vm_name).disks.add(params.Disk( # storage_domains=params.StorageDomains( # storage_domain=[self.api.storagedomains.get(kwargs['storage_domain'])], # size=512 * MB, # status=None, # interface='virtio', # format='cow', # sparse=True, # bootable=True))) # print 'Disk added to VM' # print 'Waiting for VM to reach Down status' # while self.api.vms.get(vm_name).status.state != 'down': # time.sleep(1) # except Exception as e: # print 'Failed to create VM with disk and NIC\n%s' % str(e) def restart_vm(self, vm_name): if not self.stop_vm(vm_name): return False else: return self.start_vm(vm_name) def list_vm(self, **kwargs): # list vm based on kwargs can be buggy # i.e. you can't return a list of powered on vm # but you can return a vm w/ a matched name vm_list = self.api.vms.list(**kwargs) return [vm.name for vm in vm_list] def list_host(self, **kwargs): host_list = self.api.hosts.list(**kwargs) return [host.name for host in host_list] def list_datastore(self, **kwargs): datastore_list = self.api.storagedomains.list(**kwargs) return [ds.name for ds in datastore_list if ds.get_status() is None] def list_cluster(self, **kwargs): cluster_list = self.api.clusters.list(**kwargs) return [cluster.name for cluster in cluster_list] def list_template(self, **kwargs): ''' CFME ignores the 'Blank' template, so we do too ''' template_list = self.api.templates.list(**kwargs) return [template.name for template in template_list if template.name != "Blank"] def list_flavor(self): raise NotImplementedError('This function is not supported on this platform.') def info(self): # and we got nothing! pass def disconnect(self): self.api.disconnect() def vm_status(self, vm_name=None): state = self._get_vm(vm_name).get_status().get_state() return state def is_vm_running(self, vm_name): state = self.vm_status(vm_name) return "up" == state def is_vm_stopped(self, vm_name): state = self.vm_status(vm_name) return "down" == state def is_vm_suspended(self, vm_name): state = self.vm_status(vm_name) return "suspended" == state def suspend_vm(self, vm_name): vm = self._get_vm(vm_name) if vm.status.get_state() == 'down': raise Exception('Could not suspend %s because it\'s not running.' % vm_name) else: ack = vm.suspend() return ack.get_status().get_state() == 'complete' def clone_vm(self, source_name, vm_name): raise NotImplementedError('This function has not yet been implemented.') def deploy_template(self, template, *args, **kwargs): self.api.vms.add(params.VM( name=kwargs['vm_name'], cluster=self.api.clusters.get(kwargs['cluster_name']), template=self.api.templates.get(template))) while self.api.vms.get(kwargs['vm_name']).status.state != 'down': time.sleep(5) self.start_vm(kwargs['vm_name']) while not self.is_vm_running(kwargs['vm_name']): time.sleep(5) return kwargs['vm_name']
class RHEVMHelper(object): api_connections_lock = BoundedSemaphore() def __init__(self, url, username, password): self.log = logging.getLogger('%s.%s' % (__name__, self.__class__.__name__)) # The SDK allows only a single active connection object to be created, regardless of whether # or not multiple RHEVM servers are being accessed. For now we need to have a global lock, # create a connection object before each batch of API interactions and then disconnect it. self.api_details = { 'url':url, 'username':username, 'password':password } # TODO: When this limitation in the ovirt SDK is removed, get rid of these def _init_api(self): self.log.debug("Doing blocking acquire() on global RHEVM API connection lock") self.api_connections_lock.acquire() self.log.debug("Got global RHEVM API connection lock") url = self.api_details['url'] username = self.api_details['username'] password = self.api_details['password'] self.api = API(url=url, username=username, password=password) def _disconnect_api(self): self.api.disconnect() self.log.debug("Releasing global RHEVM API connection lock") self.api_connections_lock.release() # These are the only two genuinley public methods # What we create is a VM template def import_template(self, image_filename, nfs_host, nfs_path, nfs_dir, cluster, ovf_name = None, ovf_desc = None): if not ovf_desc: self.ovf_desc = "Imported by Image Factory" else: self.ovf_desc = ovf_desc self.log.debug("Preparing for RHEVM template import of image file (%s)" % (image_filename)) # API lock protected action try: self._init_api() self.init_vm_import(image_filename, nfs_host, nfs_path, nfs_dir, cluster) finally: self._disconnect_api() if not ovf_name: self.ovf_name=str(self.tpl_uuid) else: self.ovf_name = ovf_name self.log.debug("Staging files") self.stage_files() self.log.debug("Moving files to final export domain location") self.move_files() self.log.debug("Executing import") # API lock protected action try: self._init_api() self.execute_import() finally: self._disconnect_api() return str(self.tpl_uuid) def delete_template(self, template_uuid): template = self.api.templates.get(id=template_uuid) if template: template.delete() return True else: return False # Begin Nuts and Bolts # We don't want to run seteuid() in our main process as it will globally change the UID/GID for everything # OTOH, we need to be root to access our image files and temp files # We use stdin and Popen's preexec_fn via the helper functions below to deal with this def become_nfs_user(self): os.setegid(NFSGID) os.seteuid(NFSUID) def copy_as_nfs_user(self, sourcefile, destfile): self.log.debug("Copying (%s) to (%s) as nfsuser" % (sourcefile, destfile)) f = open(sourcefile,"r") (stdout, stderr, retcode) = subprocess_check_output([ 'dd', 'of=%s' % (destfile), 'bs=4k' ], stdin=f, preexec_fn=self.become_nfs_user) f.close() def move_as_nfs_user(self, sourcefile, destfile): self.log.debug("Moving (%s) to (%s) as nfsuser" % (sourcefile, destfile)) (stdout, stderr, retcode) = subprocess_check_output([ 'mv', '%s' % (sourcefile), '%s' % (destfile)], preexec_fn=self.become_nfs_user) def mkdir_as_nfs_user(self, directory): self.log.debug("Making directory (%s) as nfsuser" % (directory)) (stdout, stderr, retcode) = subprocess_check_output([ 'mkdir', '%s' % (directory)], preexec_fn=self.become_nfs_user) def rm_rf_as_nfs_user(self, directory): self.log.debug("Recursive remove of dir (%s) as nfsuser" % (directory)) (stdout, stderr, retcode) = subprocess_check_output([ 'rm', '-rf', '%s' % (directory)], preexec_fn=self.become_nfs_user) def get_storage_domain(self, nfs_host, nfs_path): # Find the storage domain that matches the nfs details given sds = self.api.storagedomains.list() for sd in sds: if sd.get_type() == "export": self.log.debug("Export domain: (%s)" % (sd.get_name())) stor = sd.get_storage() if (stor.get_address() == nfs_host) and (stor.get_path() == nfs_path): self.log.debug("This is the right domain (%s)" % (sd.get_id())) return sd return None def get_pool_id(self, sd_uuid): # Get datacenter for a given storage domain UUID # This is the UUID that becomes the "StoragePoolID" in our OVF XML # TODO: The storagedomain object has a get_data_center() method that doesn't seem to work # Find out why dcs = self.api.datacenters.list() for dc in dcs: self.log.debug("Looking for our storage domain (%s) in data center (%s)" % (sd_uuid, dc.get_id())) sd = dc.storagedomains.get(id=sd_uuid) if sd: self.log.debug("This is the right datacenter (%s)" % (dc.get_id())) return dc return None def get_cluster_by_dc(self, poolid): # If we have been passed "_any_" as the cluster name, we pick the first cluster that # matches our datacenter/pool ID clusters = self.api.clusters.list() for cluster in clusters: dc_id = None if cluster.get_data_center(): dc_id = cluster.get_data_center().get_id() self.log.debug("Checking cluster (%s) with name (%s) with data center (%s)" % (cluster.get_id(), cluster.get_name(), dc_id)) if dc_id == poolid: return cluster self.log.debug("Cannot find cluster for dc (%s)" % (poolid)) return None def get_cluster_by_name(self, name): # If we have been passed a specific cluster name, we need to find that specific cluster clusters = self.api.clusters.list() for cluster in clusters: self.log.debug("Checking cluster (%s) with name (%s)" % (cluster.get_id(), cluster.get_name())) if cluster.get_name() == name: return cluster self.log.debug("Cannot find cluster named (%s)" % (name)) return None def check_qcow_size(self, filename): # Detect if an image is in qcow format # If it is, return the size of the underlying disk image # If it isn't, return none # For interested parties, this is the QCOW header struct in C # struct qcow_header { # uint32_t magic; # uint32_t version; # uint64_t backing_file_offset; # uint32_t backing_file_size; # uint32_t cluster_bits; # uint64_t size; /* in bytes */ # uint32_t crypt_method; # uint32_t l1_size; # uint64_t l1_table_offset; # uint64_t refcount_table_offset; # uint32_t refcount_table_clusters; # uint32_t nb_snapshots; # uint64_t snapshots_offset; # }; # And in Python struct format string-ese qcow_struct=">IIQIIQIIQQIIQ" # > means big-endian qcow_magic = 0x514649FB # 'Q' 'F' 'I' 0xFB f = open(filename,"r") pack = f.read(struct.calcsize(qcow_struct)) f.close() unpack = struct.unpack(qcow_struct, pack) if unpack[0] == qcow_magic: return unpack[5] else: return None def init_vm_import(self, image_filename, nfs_host, nfs_path, nfs_dir, cluster): # Prepare for the import of a VM self.image_filename = image_filename self.nfs_host = nfs_host self.nfs_path = nfs_path self.nfs_dir = nfs_dir # Sets some values used when creating XML and meta files self.storage_domain_object = self.get_storage_domain(nfs_host, nfs_path) if self.storage_domain_object: self.storage_domain = self.storage_domain_object.get_id() else: raise Exception("Cannot find storage domain matching NFS details given") self.dc_object = self.get_pool_id(self.storage_domain) if self.dc_object: # Our StoragePoolID is the UUID of the DC containing our storage domain self.pool_id=self.dc_object.get_id() else: raise Exception("Cannot find datacenter for our storage domain") if cluster == '_any_': self.cluster_object = self.get_cluster_by_dc(self.pool_id) else: self.cluster_object = self.get_cluster_by_name(cluster) if self.cluster_object: self.cluster = self.cluster_object.get_id() else: raise Exception("Cannot find cluster (%s)" % (cluster)) # Volume size is the qcow_size if the image is qcow # or the raw disk image size if not self.qcow_size = self.check_qcow_size(image_filename) if self.qcow_size: self.vol_size=self.qcow_size else: statb = os.stat(image_filename) self.vol_size = statb[stat.ST_SIZE] # We need these three unique identifiers when generating XML and the meta file self.img_uuid = uuid.uuid4() self.vol_uuid = uuid.uuid4() self.tpl_uuid = uuid.uuid4() # Set this once to use in both the OVF XML and the meta file self.raw_create_time = time.time() self.create_time = time.gmtime(self.raw_create_time) def stage_files(self): # Called after init to copy files to staging location # This is the base dir of the export domain self.export_domain_dir = self.nfs_dir + "/" + self.storage_domain if not os.path.isdir(self.export_domain_dir): raise Exception("Cannot find expected export domain directory (%s) at local mount point (%s)" % (self.nfs_dir, self.storage_domain)) # Make distinct tempdir for OVF stuff self.ovftmpdir=self.export_domain_dir + "/" + "imgfac." + str(self.tpl_uuid) self.mkdir_as_nfs_user(self.ovftmpdir) # Add the OVF file self.ovfdest = self.ovftmpdir + "/" + str(self.tpl_uuid) + ".ovf" ovf_file_object = NamedTemporaryFile() et = self.generate_ovf_xml() et.write(ovf_file_object) ovf_file_object.flush() self.copy_as_nfs_user(ovf_file_object.name, self.ovfdest) ovf_file_object.close() # Make our own temporary subdir for the image file itself self.imgtmpdir=self.export_domain_dir + "/" + "imgfac." + str(self.img_uuid) self.mkdir_as_nfs_user(self.imgtmpdir) # Add the meta file for the image self.imgdest = self.imgtmpdir + "/" + str(self.vol_uuid) self.imgmetadest = self.imgdest + ".meta" meta_file_object = NamedTemporaryFile() meta_file_object.write(self.generate_meta_file()) meta_file_object.flush() self.copy_as_nfs_user(meta_file_object.name, self.imgmetadest) meta_file_object.close() # Copy the big image file last self.copy_as_nfs_user(self.image_filename, self.imgdest) def move_files(self): self.final_image_dir = "%s/images/%s" % (self.export_domain_dir, str(self.img_uuid)) self.final_ovf_dir = "%s/master/vms/%s" % (self.export_domain_dir, str(self.tpl_uuid)) self.move_as_nfs_user(self.imgtmpdir, self.final_image_dir) self.move_as_nfs_user(self.ovftmpdir, self.final_ovf_dir) def remove_export_template(self): self.rm_rf_as_nfs_user(self.final_image_dir) self.rm_rf_as_nfs_user(self.final_ovf_dir) def execute_import(self): # We import to the master storage domain of the datacenter of which our export domain is a member # Got it? action = params.Action() sds = self.dc_object.storagedomains.list() for sd in sds: if sd.get_master(): action.storage_domain=sd if not action.storage_domain: raise Exception("Could not find master storage domain for datacenter ID (%s)" % (self.dc_object.get_id())) action.cluster = self.cluster_object # At this point our freshly copied in files are discoverable via the tpl_uuid in our export domain template = self.storage_domain_object.templates.get(id=str(self.tpl_uuid)) if template: template.import_template(action=action) real_template = self.api.templates.get(id=str(self.tpl_uuid)) # Wait 5 minutes for an import to finish self.log.debug("Waiting for template import to complete") for i in range(30): self.log.debug("Waited %d - state (%s)" % (i*10, real_template.get_status().get_state())) if real_template.get_status().get_state() != 'locked': break real_template = real_template.update() sleep(10) self.log.debug("Deleting export domain files") self.remove_export_template() final_state = real_template.get_status().get_state() if final_state == 'ok': self.log.debug("Template import completed successfully") return elif final_state == 'locked': raise Exception("Timed out waiting for template import to finish") else: raise Exception("Template import ended in unknown state (%s)" % (final_state)) def generate_meta_file(self): metafile="" metafile += "DOMAIN=" + self.storage_domain + "\n" # saved template has VOLTYPE=SHARED metafile += "VOLTYPE=LEAF\n" metafile += "CTIME=" + str(int(self.raw_create_time)) + "\n" # saved template has FORMAT=COW if self.qcow_size: metafile += "FORMAT=COW\n" else: metafile += "FORMAT=RAW\n" metafile += "IMAGE=" + str(self.img_uuid) + "\n" metafile += "DISKTYPE=1\n" metafile += "PUUID=00000000-0000-0000-0000-000000000000\n" metafile += "LEGALITY=LEGAL\n" metafile += "MTIME=" + str(int(self.raw_create_time)) + "\n" metafile += "POOL_UUID=" + self.pool_id + "\n" # assuming 1KB alignment metafile += "SIZE=" + str(self.vol_size/512) + "\n" metafile += "TYPE=SPARSE\n" metafile += "DESCRIPTION=Uploaded by Image Factory\n" metafile += "EOF\n" return metafile def generate_ovf_xml(self): etroot = ElementTree.Element('ovf:Envelope') etroot.set('xmlns:ovf', "http://schemas.dmtf.org/ovf/envelope/1/") etroot.set('xmlns:rasd', "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData") etroot.set('xmlns:vssd', "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData") etroot.set('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance") etroot.set('ovf:version', "0.9") etref = ElementTree.Element('References') etfile = ElementTree.Element('File') etfile.set('ovf:href', str(self.img_uuid)+'/'+str(self.vol_uuid)) etfile.set('ovf:id', str(self.vol_uuid)) etfile.set('ovf:size', str(self.vol_size)) # TODO: Bulk this up a bit etfile.set('ovf:description', self.ovf_name) etref.append(etfile) etroot.append(etref) etsec = ElementTree.Element('Section') etsec.set('xsi:type', "ovf:NetworkSection_Type") ete = ElementTree.Element('Info') ete.text = "List of Networks" etsec.append(ete) # dummy section, even though we have Ethernet defined below etroot.append(etsec) etsec = ElementTree.Element('Section') etsec.set('xsi:type', "ovf:DiskSection_Type") etdisk = ElementTree.Element('Disk') etdisk.set('ovf:diskId', str(self.vol_uuid)) vol_size_str = str((self.vol_size + (1024*1024*1024) - 1) / (1024*1024*1024)) etdisk.set('ovf:size', vol_size_str) etdisk.set('ovf:vm_snapshot_id', '00000000-0000-0000-0000-000000000000') etdisk.set('ovf:actual_size', vol_size_str) etdisk.set('ovf:format', 'http://www.vmware.com/specifications/vmdk.html#sparse') etdisk.set('ovf:parentRef', '') # XXX ovf:vm_snapshot_id etdisk.set('ovf:fileRef', str(self.img_uuid)+'/'+str(self.vol_uuid)) # XXX ovf:format ("usually url to the specification") if self.qcow_size: etdisk.set('ovf:volume-type', "Sparse") etdisk.set('ovf:volume-format', "COW") else: etdisk.set('ovf:volume-type', "Preallocated") etdisk.set('ovf:volume-format', "RAW") etdisk.set('ovf:disk-interface', "VirtIO") etdisk.set('ovf:disk-type', "System") etdisk.set('ovf:boot', "true") etdisk.set('ovf:wipe-after-delete', "false") etsec.append(etdisk) etroot.append(etsec) etcon = ElementTree.Element('Content') etcon.set('xsi:type', "ovf:VirtualSystem_Type") etcon.set('ovf:id', "out") ete = ElementTree.Element('Name') ete.text = self.ovf_name etcon.append(ete) ete = ElementTree.Element('TemplateId') ete.text = str(self.tpl_uuid) etcon.append(ete) # spec also has 'TemplateName' ete = ElementTree.Element('Description') ete.text = self.ovf_desc etcon.append(ete) ete = ElementTree.Element('Domain') # AD domain, not in use right now # ete.text = etcon.append(ete) ete = ElementTree.Element('CreationDate') ete.text = time.strftime("%Y/%m/%d %H:%M:%S", self.create_time) etcon.append(ete) ete = ElementTree.Element('TimeZone') # ete.text = etcon.append(ete) ete = ElementTree.Element('IsAutoSuspend') ete.text = "false" etcon.append(ete) ete = ElementTree.Element('VmType') ete.text = "1" etcon.append(ete) ete = ElementTree.Element('default_display_type') # vnc = 0, gxl = 1 ete.text = "0" etcon.append(ete) ete = ElementTree.Element('default_boot_sequence') # C=0, DC=1, N=2, CDN=3, CND=4, DCN=5, DNC=6, NCD=7, # NDC=8, CD=9, D=10, CN=11, DN=12, NC=13, ND=14 # (C - HardDisk, D - CDROM, N - Network) ete.text = "1" etcon.append(ete) etsec = ElementTree.Element('Section') etsec.set('xsi:type', "ovf:OperatingSystemSection_Type") etsec.set('ovf:id', str(self.tpl_uuid)) etsec.set('ovf:required', "false") ete = ElementTree.Element('Info') ete.text = "Guest OS" etsec.append(ete) ete = ElementTree.Element('Description') # This is rigid, must be "Other", "OtherLinux", "RHEL6", or such ete.text = "OtherLinux" etsec.append(ete) etcon.append(etsec) etsec = ElementTree.Element('Section') etsec.set('xsi:type', "ovf:VirtualHardwareSection_Type") ete = ElementTree.Element('Info') ete.text = "1 CPU, 512 Memory" etsec.append(ete) etsys = ElementTree.Element('System') # This is probably wrong, needs actual type. ete = ElementTree.Element('vssd:VirtualSystemType') ete.text = "RHEVM 4.6.0.163" etsys.append(ete) etsec.append(etsys) etitem = ElementTree.Element('Item') ete = ElementTree.Element('rasd:Caption') ete.text = "1 virtual CPU" etitem.append(ete) ete = ElementTree.Element('rasd:Description') ete.text = "Number of virtual CPU" etitem.append(ete) ete = ElementTree.Element('rasd:InstanceId') ete.text = "1" etitem.append(ete) ete = ElementTree.Element('rasd:ResourceType') ete.text = "3" etitem.append(ete) ete = ElementTree.Element('rasd:num_of_sockets') ete.text = "1" etitem.append(ete) ete = ElementTree.Element('rasd:cpu_per_socket') ete.text = "1" etitem.append(ete) etsec.append(etitem) etitem = ElementTree.Element('Item') ete = ElementTree.Element('rasd:Caption') ete.text = "512 MB of memory" etitem.append(ete) ete = ElementTree.Element('rasd:Description') ete.text = "Memory Size" etitem.append(ete) ete = ElementTree.Element('rasd:InstanceId') ete.text = "2" etitem.append(ete) ete = ElementTree.Element('rasd:ResourceType') ete.text = "4" etitem.append(ete) ete = ElementTree.Element('rasd:AllocationUnits') ete.text = "MegaBytes" etitem.append(ete) ete = ElementTree.Element('rasd:VirtualQuantity') ete.text = "512" etitem.append(ete) etsec.append(etitem) etitem = ElementTree.Element('Item') ete = ElementTree.Element('rasd:Caption') ete.text = "Drive 1" etitem.append(ete) ete = ElementTree.Element('rasd:InstanceId') ete.text = str(self.vol_uuid) etitem.append(ete) ete = ElementTree.Element('rasd:ResourceType') ete.text = "17" etitem.append(ete) ete = ElementTree.Element('rasd:HostResource') ete.text = str(self.img_uuid)+'/'+str(self.vol_uuid) etitem.append(ete) ete = ElementTree.Element('rasd:Parent') ete.text = "00000000-0000-0000-0000-000000000000" etitem.append(ete) ete = ElementTree.Element('rasd:Template') ete.text = "00000000-0000-0000-0000-000000000000" etitem.append(ete) ete = ElementTree.Element('rasd:ApplicationList') # List of installed applications, separated by comma etitem.append(ete) # This corresponds to ID of volgroup in host where snapshot was taken. # Obviously we have nothing like it. ete = ElementTree.Element('rasd:StorageId') # "Storage Domain Id" ete.text = "00000000-0000-0000-0000-000000000000" etitem.append(ete) ete = ElementTree.Element('rasd:StoragePoolId') ete.text = self.pool_id etitem.append(ete) ete = ElementTree.Element('rasd:CreationDate') ete.text = time.strftime("%Y/%m/%d %H:%M:%S", self.create_time) etitem.append(ete) ete = ElementTree.Element('rasd:LastModified') ete.text = time.strftime("%Y/%m/%d %H:%M:%S", self.create_time) etitem.append(ete) etsec.append(etitem) etitem = ElementTree.Element('Item') ete = ElementTree.Element('rasd:Caption') ete.text = "Ethernet 0 rhevm" etitem.append(ete) ete = ElementTree.Element('rasd:InstanceId') ete.text = "3" etitem.append(ete) ete = ElementTree.Element('rasd:ResourceType') ete.text = "10" etitem.append(ete) ete = ElementTree.Element('rasd:ResourceSubType') # e1000 = 2, pv = 3 ete.text = "3" etitem.append(ete) ete = ElementTree.Element('rasd:Connection') ete.text = "rhevm" etitem.append(ete) ete = ElementTree.Element('rasd:Name') ete.text = "eth0" etitem.append(ete) # also allowed is "MACAddress" ete = ElementTree.Element('rasd:speed') ete.text = "1000" etitem.append(ete) etsec.append(etitem) etitem = ElementTree.Element('Item') ete = ElementTree.Element('rasd:Caption') ete.text = "Graphics" etitem.append(ete) ete = ElementTree.Element('rasd:InstanceId') # doc says "6", reality is "5" ete.text = "5" etitem.append(ete) ete = ElementTree.Element('rasd:ResourceType') ete.text = "20" etitem.append(ete) ete = ElementTree.Element('rasd:VirtualQuantity') ete.text = "1" etitem.append(ete) etsec.append(etitem) etcon.append(etsec) etroot.append(etcon) et = ElementTree.ElementTree(etroot) return et
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', filename=LOGFILENAME, filemode='w') def start_vms(vmObj): logging.info('Thread to start %s', vmObj.name) try: vmObj.start() #time.sleep(5) except Exception as e: logging.debug('Exception caught on VM ( %s) start:\n%s' % (vmObj.name, str(e))) failedVms.append(vmObj.name) if __name__ == "__main__": try: api = API(url=APIURL, username=APIUSER, password=APIPASS, ca_file=CAFILE) print 'Connected to RHEVM API %s Successfully' % APIURL logging.info ( 'Successfully Connected to %s' % APIURL) try: print ' \n I am logging in %s \n' % LOGFILENAME vmsList = api.vms.list() for i in vmsList: print i.name if i.status.state != 'up': logging.warning('%s is not up, trying to start it' % i.name) threadMe = Thread(target=start_vms, args=[i]) threadMe.start() threads.append(threadMe) except Exception as e: logging.debug('Error:\n%s' % str(e))
class ovirt_test( object ): """An instance represents ovirt test. """ def __init__ ( self, test_dict = {} ): '''Constructor for ovirt_test. self.ovirt_dict = {} self.ovirt_dict['URL'] = url self.ovirt_dict['VERSION'] = params.Version(major='3', minor='0') self.ovirt_dict['CA_FILE'] = "/etc/pki/ovirt-engine/ca.pem" self.ovirt_dict['USERINFO'] = {} self.ovirt_dict['USERINFO']['NAME'] = 'admin@internal' self.ovirt_dict['USERINFO']['PASSWORD'] = '******' self.ovirt_dict['DATACENTERS'] = [(name,type,cluster,storage,network),(name,...), ...] network = [(name,type),(name, ...), ...] storage = [(name,type,addr,path),(name, ...), ...] cluster = [(name,type,hosts,vms,volumes),(name, ...), ...] hosts = [(name,address),(name, ...), ...] volumes = [(name,type),(name, ...), ...] vms = [(name,type,ostype,display,nics,disks),(name, ...), ...] nics = [(name,type,network),(name, ...), ...] disks = [(name,type,size,storage),(name, ...), ...] ''' global iCLUSTERS global iSTORAGES global iHOSTS iCLUSTERS = 2 iSTORAGES = 3 iHOSTS = 2 self.ovirt_dict = {} self.ovirt_dict['URL'] = test_dict['URL'] self.ovirt_dict['VERSION'] = test_dict['VERSION'] self.ovirt_dict['CA_FILE'] = test_dict['CA_FILE'] self.ovirt_dict['USERINFOS'] = [] self.ovirt_dict['USERINFOS'].append(test_dict['USERINFOS'][0]) self.ovirt_dict['CONNECTION'] = False self.ovirt_dict['DATACENTERS'] = [] self.ovirt_dict['CLUSTERS'] = [] self.ovirt_dict['HOSTS'] = [] self.ovirt_dict['STORAGES'] = [] self.ovirt_dict['VMS'] = [] self.ovirt_dict['NICS'] = [] self.ovirt_dict['DISKS'] = [] def connect_engine( self ): '''Connect ovirt-engine, default connect local ovirt-engine api = API(url="https://128.224.165.209:443/api", \ username="******", \ password="******", \ ca_file="/etc/pki/ovirt-engine/ca.pem") ''' try: self.api = API(url=self.ovirt_dict['URL'], username=self.ovirt_dict['USERINFOS'][0][0], password=self.ovirt_dict['USERINFOS'][0][1], ca_file=self.ovirt_dict['CA_FILE']) print 'Connect ovirt-engine successfully' self.ovirt_dict['CONNECTION'] = True except Exception as e: print 'Connect ovirt-engine failed:\n%s' % (str(e)) self.ovirt_dict['CONNECTION'] = False return False def disconnect( self ): '''Disconnect ovirt-engine''' try: if self.api.disconnect() == None: print 'Disconnect ovirt-engine successfully' self.ovirt_dict['CONNECTION'] = False except Exception as e: print 'Disconnect ovirt-engine failed:\n%s' % (str(e)) self.ovirt_dict['CONNECTION'] = 1 return False def check_item( self, group , item_name, Other = 'None' ): '''Check the item(item_name) exist in group''' try: index = 0 length = len(group) for index in range(0,length): if group[index][0] == item_name: if Other != 'None' and group[index][1] == Other: return index return index if index + 1 >= length: return None except Exception as e: print 'Check %s failed:\n%s' % (item_name,str(e)) return None def add_user( self, UserInfo = ('admin@internal','admin') ): '''add a new user''' try: self.ovirt_dict['USERINFOS'].append(UserInfo) except Exception as e: print 'Add new user failed:\n%s' % (str(e)) return False def change_user( self, UserInfo = ('admin@internal','admin') ): '''change username and password''' try: length = len(self.ovirt_dict['USERINFOS']) for i in range(0,length): if self.ovirt_dict['USERINFOS'][i][0] == UserInfo[0]: tempUser = self.ovirt_dict['USERINFOS'][i] self.ovirt_dict['USERINFOS'].remove(tempUser) self.ovirt_dict['USERINFOS'].insert(i,UserInfo) Found = 1 break else: Found = 0 if Found == 0: print 'Change user information failed' return False except Exception as e: print 'Change user information failed:\n%s' % (str(e)) return False def printInstanceInfo( self ): ''''change username and password''' print self.ovirt_dict def print_summary(self, summary): lenth = len(summary) print ' \n' + '#'*10 + ' ' + summary + ' ' + '#'*(40-lenth) + ' \n'
if config.rhevmconfig["host"] == "": print "No RHEV-M hostname was specified." error() elif config.rhevmconfig["user"] == "": print "No user name was specified." error() elif config.rhevmconfig["passwd"] == "": print "Enter password for user %s:" % (config.rhevmconfig['user']) config.rhevmconfig['passwd'] = getpass() # Connect to RHEV-M if config.vmconfig["quiet"] == False: print "Connecting to RHEV-M %s..." % (config.rhevmconfig['host']) api = API(url=config.rhevmconfig["host"], username=config.rhevmconfig["user"], password=config.rhevmconfig["passwd"], insecure=True) if config.vmconfig["quiet"] == False: print "Connection established" print "" if config.vmname != "": vm = vm(config.vmname, config.vmconfig, api) if command == "start": vm.start() elif command == "stop": vm.stop() elif command == "console": vm.console(config.rhevmconfig) elif command == "migrate": vm.migrate()
p.add_option("-t", "--vm-template", action="store", type="string", dest="vm_template", help="provide template name. eg: -a create -n vm01 -t tpl01 -c cluster01") p.add_option("-p", "--vm-password", action="store", type="string", dest="vm_password", help="-a init -p password_of_vm -i vm_nic_info") p.add_option("-i", "--vm-nic-info", action="store", type="string", dest="vm_nic_info", help='nic info: "name_of_nic, ip_address, net_mask, gateway". ' 'eg: -a init -n vm01 -p 123456 -i "eth0, 10.0.100.101, 255.255.255.0, 10.0.100.1"') p.add_option("-L", "--vm-list", action="store", type="string", dest="vm_list", help='a list of vms. eg: -a stop-list -L "vm01, vm02, vm03"') p.set_defaults(action='list', vm_cluster='C01', vm_template='tpl-m1') opt, args = p.parse_args() oe_conn = None try: oe_conn = API(url=OE_URL, username=OE_USERNAME, password=OE_PASSWORD, ca_file=OE_CA_FILE) if opt.action == 'list': vm_list(oe_conn) elif opt.action == 'start': vm_start(oe_conn, opt.vm_name) elif opt.action == 'stop': vm_stop(oe_conn, opt.vm_name) elif opt.action == 'delete': vm_delete(oe_conn, opt.vm_name) elif opt.action == 'create': vm_create_from_tpl(oe_conn, opt.vm_name, opt.vm_template, opt.vm_cluster) elif opt.action == 'init': vm_run_once(oe_conn, opt.vm_name, opt.vm_password, opt.vm_nic_info) elif opt.action == 'start-list': for vm in opt.vm_list.replace(' ', '').split(','): print('[I] try to start vm: {0}'.format(vm))
6. from time import sleep 7. 8. 9. VERSION = params.Version(major='3', minor='0') 10. ##change to fit your host 11. URL = input(' enter ip address, example: 'https://192.168.1.1:8443/api') 12. USERNAME = input('Enter username, example: [email protected] ') 13. PASSWORD = input('Enter your password) 14. 15. DC_NAME = input('Enter name of your datacenter') 16. CLUSTER_NAME = input('cluster name') 17. HOST_NAME = input('input host name') 18. STORAGE_NAME = input('input storage name') 19. VM_NAME = input('enter VM name') 20. 21. api = API(url=URL, username=USERNAME, password=PASSWORD)30 22. try: 23. if api.hosts.add(params.Host(name=HOST_NAME, address=HOST_ADDRESS, cluster=api.clusters.get(CLUSTER_NAME), root_password=ROOT_PASSWORD)): 24. 25. print 'Host was installed successfully' 26. print 'Waiting for host to reach the Up status' 27. while api.hosts.get(HOST_NAME).status.state != 'up': 28. sleep(1) 29. print "Host is up" 30. except Exception as e: 31. print 'Failed to install Host:\n%s' % str(e) 32. 33. 34. def connectToHost(host,host_user,host_pw): 35. apiurl="https://"+host+"/api" #change for your host 36. #insecure -> skips SSL check
def __init__(self, *args, **kw): _API.__init__(self, *args, **kw) self.vms = VMs(self.id)