class RavelloPowerAdapter(): def __init__(self, user, password, application_name, vm_name): self.client = RavelloClient() self.client.login(user, password) self.application_name = application_name self.vm_name = vm_name def _get_application_id(self): for app in self.client.get_applications(): if app['name'] == self.application_name: return app['id'] return None def _get_vm_id(self): app_id = self._get_application_id() for vm in self.client.get_vms(app_id): if vm['name'] == self.vm_name: return vm['id'] return None def get_vm_state(self): return self.client.get_vm_state(self._get_application_id(), self._get_vm_id()) def power_on_vm(self): vm_state = self.get_vm_state() if vm_state in ['STARTED', 'STARTING']: return elif vm_state == 'STOPPED': self.client.start_vm(self._get_application_id(), self._get_vm_id()) else: raise Exception("Error when powering on the VM. Cannot handle " "VM state: '%s'" % vm_state) def power_off_vm(self): vm_state = self.get_vm_state() if vm_state in ['STOPPED', 'STOPPING']: return if vm_state == 'STARTED': self.client.poweroff_vm(self._get_application_id(), self._get_vm_id()) else: raise Exception("Error when powering off the VM. Cannot handle " "VM state: '%s'" % vm_state)
class RavelloBmc(bmc.Bmc): """Ravello IPMI virtual BMC.""" def get_vm(self, application, name): """Get a VM by name.""" vms = application.get(self._aspect, {}).get('vms', []) for vm in vms: if vm['name'] == name: return vm msg = 'vm not found: {0}'.format(name) logging.error(msg) raise ValueError(msg) def connect(self): """Connect to the Ravello API server with the given credentials.""" try: self._client = RavelloClient() #self._client.login(self._username, self._password) self._client = RavelloClient(eph_token=self._password) c = self._client self._app = c.get_application_by_name(self._app_name, aspect=self._aspect) self._vm = self.get_vm(self._app, self._vm_name) return True except Exception as e: msg = "Exception while connecting to API server:" + str(e) logging.error(msg) print(msg) return False def __init__(self, authdata, port, address, aspect, username, password, app_name, vm_name): """Ravello virtual BMC constructor.""" self._client = None super(RavelloBmc, self).__init__(authdata, address=address, port=port) self._aspect = aspect self._username = username self._password = password self._app_name = app_name self._vm_name = vm_name def disconnect(self): """Disconnect from the Ravello API server.""" if not self._client: return self._client.logout() self._client.close() def __del__(self): """Ravello virtual BMC destructor.""" self.disconnect() # Disable default BMC server implementations def cold_reset(self): """Cold reset reset the BMC so it's not implemented.""" raise NotImplementedError def get_boot_device(self): """Get the boot device of a Ravello VM.""" try: # query the vm again to have an updated device c = self._client self._app = c.get_application_by_name(self._app_name, aspect=self._aspect) self._vm = self.get_vm(self._app, self._vm_name) if self._vm['bootOrder'][0] == "DISK": return 0x08 elif self._vm['bootOrder'][0] == "CDROM": return 0x04 except Exception as e: logging.error(self._vm_name + ' get_boot_device:' + str(e)) return 0xce return 0x04 def get_system_boot_options(self, request, session): logging.info(self._vm_name + " get boot options") if request['data'][0] == 5: # boot flags try: bootdevice = self.get_boot_device() logging.info(self._vm_name + ' bootdevice = ' + bootdevice) except NotImplementedError: session.send_ipmi_response(data=[1, 5, 0, 0, 0, 0, 0]) if (type(bootdevice) != int and bootdevice in ipmicommand.boot_devices): bootdevice = ipmicommand.boot_devices[bootdevice] paramdata = [1, 5, 0b10000000, bootdevice, 0, 0, 0] return session.send_ipmi_response(data=paramdata) else: session.send_ipmi_response(code=0x80) def set_boot_device(self, bootdevice): try: # query the vm again to have an updated device c = self._client self._app = c.get_application_by_name(self._app_name) appid = self._app['id'] for vm in self._app['design']['vms']: change = False if vm['name'] == self._vm_name: logging.info(self._vm_name + " Boot device requested: " + str(bootdevice)) if bootdevice == "network": vm['bootOrder'] = ["CDROM", "DISK"] change = True elif bootdevice == "hd": vm['bootOrder'] = ["DISK", "CDROM"] change = True if change == True: #pprint (self._app) logging.info("Updating app " + self._app_name + " vm " + self._vm_name + " with boot device " + str(bootdevice)) ap = self._client.update_application(self._app) if ap['published']: logging.info("Updating app " + str(appid)) self._client.publish_application_updates(appid) except Exception as e: logging.error(self._vm_name + ' set_boot_device:' + str(e)) return 0xce def set_kg(self, kg): """Desactivated IPMI call.""" raise NotImplementedError def set_system_boot_options(self, request, session): logging.info("set boot options vm:" + self._vm_name) if request['data'][0] in (0, 3, 4): logging.info("Ignored RAW option " + str(request['data']) + " for: " + self._vm_name + "... Smile and wave.") # for now, just smile and nod at boot flag bit clearing # implementing it is a burden and implementing it does more to # confuse users than serve a useful purpose session.send_ipmi_response(code=0x00) elif request['data'][0] == 5: bootdevice = (request['data'][2] >> 2) & 0b1111 logging.info("Got set boot device for " + self._vm_name + " to " + str(request['data'][2])) try: bootdevice = ipmicommand.boot_devices[bootdevice] logging.info("Setting boot device for " + self._vm_name + " to " + bootdevice) except KeyError: session.send_ipmi_response(code=0xcc) return self.set_boot_device(bootdevice) session.send_ipmi_response() else: raise NotImplementedError def power_reset(self): """Reset a VM.""" # Shmulik wrote "Currently, limited to: "chassis power on/off/status" raise NotImplementedError # Implement power state BMC features def get_power_state(self): """Get the power state of a Ravello VM.""" try: # query the vm again to have an updated status c = self._client self._app = c.get_application_by_name(self._app_name, aspect=self._aspect) self._vm = self.get_vm(self._app, self._vm_name) if self._vm['state'] == 'STARTED' or self._vm[ 'state'] == 'STARTING' or self._vm['state'] == 'STOPPING': logging.info('returning power state ON for vm ' + self._vm_name) return "on" else: logging.info('returning power state OFF for vm ' + self._vm_name) return "off" except Exception as e: logging.error(self._vm_name + ' get_power_state:' + str(e)) return 0xce return "off" def power_off(self): """Cut the power without waiting for clean shutdown.""" logging.info("Power OFF called for VM " + self._vm_name + " with state: " + self._vm['state']) # query the vm again to have an updated status c = self._client self._app = c.get_application_by_name(self._app_name, aspect=self._aspect) self._vm = self.get_vm(self._app, self._vm_name) if self._vm['state'] == 'STARTED': try: #self._client.poweroff_vm(self._app, self._vm) self._client.stop_vm(self._app, self._vm) except Exception as e: logging.error(self._vm_name + ' power_off:' + str(e)) return 0xce elif self._vm['state'] == 'STOPPING' or self._vm['state'] == 'STARTING': return 0xc0 else: return 0xce def power_on(self): """Start a vm.""" logging.info("Power ON called for VM " + self._vm_name + " with state: " + self._vm['state']) # query the vm again to have an updated status c = self._client self._app = c.get_application_by_name(self._app_name, aspect=self._aspect) self._vm = self.get_vm(self._app, self._vm_name) if self._vm['state'] == 'STOPPED': try: self._client.start_vm(self._app, self._vm) except Exception as e: logging.error(self._vm_name + ' power_on:' + str(e)) return 0xce elif self._vm['state'] == 'STOPPING' or self._vm['state'] == 'STARTING': return 0xc0 else: return 0xce def power_shutdown(self): """Gently power off while waiting for clean shutdown.""" logging.info("Power SHUTDOWN called for VM " + self._vm_name + " with state: " + self._vm['state']) # query the vm again to have an updated status c = self._client self._app = c.get_application_by_name(self._app_name, aspect=self._aspect) self._vm = self.get_vm(self._app, self._vm_name) if self._vm['state'] == 'STARTED': try: self._client.stop_vm(self._app, self._vm) except Exception as e: logging.error(self._vm_name + ' power_shutdown:' + str(e)) return 0xce elif self._vm['state'] == 'STOPPING' or self._vm['state'] == 'STARTING': return 0xc0 else: return 0xce
tplimportdisks = env.get_template('import_disks.j2') import_disks = tplimportdisks.render(images=import_images, project_name=bpname, osp_auth_url=auth_url, osp_username=auth_user, osp_password=auth_password, osp_project=osp_project, ibm_api_key=ibm_api_key, ibm_bucket_name=ibm_bucket_name, ibm_endpoint=ibm_endpoint, ibm_auth_endpoint=ibm_auth_endpoint, ibm_resource_id=ibm_resource_id) print("INFO: Generated %s" % (output_dir + "/playbook_import_disks.yaml")) fp = open(output_dir + "/playbook_import_disks.yaml", "w") fp.write(import_disks) fp.close() print("INFO: Generated %s" % (output_dir + "/playbook_import_disks.hosts")) fp = open(output_dir + "/playbook_import_disks.hosts", "w") fp.write("[export]\n%s" % exporterhost) fp.write("\n[import]\n%s\n" % importhost) fp.close() if vm["state"] == 'STOPPED': client.start_vm(app, vm) while vm["state"] != "STARTED": print("Waiting till VM is started") vm = client.get_vm(app_id, vm_id, 'deployment') time.sleep(30)