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 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)
Example #3
0
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
Example #4
0
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)