Esempio n. 1
0
    def start(self, job_id):
        """Start virtual machine. 
        Async command.
        
        TO-DO : read config from extended database
        
        :param job_id: unique id of the async job
        """
        self.logger.info('Start vm : %s' % self._id)

        if self.get_state() == 'Running':
            raise ClskObjectError('Virtual machine is already running.')

        VirtualMachine.start(self, job_id)

        # get virtual machine extended device from db if they are configured
        info = self.info(cache=False)
        # get vm id
        vm_id = info['id']

        try:
            vm = self.db_manager.get_vm(vm_id)
            if vm:
                devices = vm['devices']
                self.append_device(devices)
        except (QueryError, TransactionError) as ex:
            raise ClskObjectError(ex)
Esempio n. 2
0
    def list_tenants(self):
        '''List all tenants 
        tenant syntax: <cloudsatck_id>.<domain_path>.<account>
        Ex. clsk42.ROOT/CSI/DC.test1
        '''
        params = {'command':'listAccounts',
                  'listall':'true'}

        tenants_list = []
        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['listaccountsresponse']
            if len(res) > 0:
                accounts = res['account']
                for account in accounts:
                    domain_path = self.get_domain_path(account['domainid'])
                    #domain = account['domain']
                    #if domain != 'ROOT':
                    #    domain = "ROOT/%s" % domain
                        
                    tenant = "%s.%s.%s" % (self.clsk_instance.name, 
                                           domain_path, 
                                           account['name'])
                    tenants_list.append(tenant)
            else:
                return []
        except KeyError as ex:
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            raise ClskObjectError(ex)
        
        return tenants_list       
Esempio n. 3
0
    def list_volumes(self):
        '''List storage pool volumes.'''
        params = {'command':'listVolumes',
                  'listall':'true',
                  'zoneid':self._data['zoneid'],
                 }      

        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['listvolumesresponse']
            if len(res) > 0:
                data = res['volume']
            else:
                return []
        except KeyError as ex:
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            raise ClskObjectError(ex)     
        
        volumes = []
        for item in data:
            # create Volume instance
            volume = VolumeExt(self.clsk_instance, data=item)
            volumes.append(volume)
        
        return volumes 
Esempio n. 4
0
    def list_virtual_machines(self):
        '''List all virtual machines.'''
        params = {
            'command': 'listVirtualMachines',
            'listall': True,
            'networkid': self._id,
        }

        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['listvirtualmachinesresponse']
            if len(res) > 0:
                data = res['virtualmachine']
            else:
                return []
        except KeyError as ex:
            self.logger.error('Error parsing json data: %s' % ex)
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            self.logger.error(ex)
            raise ClskObjectError(ex)

        vms = []
        for item in data:
            # create Account instance
            vm = VirtualMachineExt(self.clsk_instance, data=item)
            vms.append(vm)
        return vms
Esempio n. 5
0
    def list_routers(self):
        '''List all routers'''
        params = {'command':'listRouters',
                  'listAll':'true'
                 }

        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['listroutersresponse']
            if len(res) > 0:
                data = res['router']
            else:
                return []
        except KeyError as ex :
            self.logger.error('Error parsing json data: %s' % ex)
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            self.logger.error(ex)
            raise ClskObjectError(ex)
        
        vms = []
        for item in data:
            # create Account instance
            vm = VirtualRouterExt(self.clsk_instance, data=item)
            vms.append(vm)
        return vms
Esempio n. 6
0
    def change_graphics_password(self, password):
        """"Append additionale devices not supported from cloudstack using
        low level api like libvirt or vpshere api.
        
        :param devices: litst with additional devices : 
                            spice_graphics, vlc_graphics, 
                            video_cirrus, video_qxl,
                            virtio_serial, usb_redirect, sound_card,        
        """
        self.logger.info('Change password to vm : %s' % self._id)

        info = self.info(cache=True)
        if self.get_state() != 'Running':
            raise ClskObjectError('Virtual machine is not running.')

        # get hypervisor name
        hostname = info['hostname']
        # get vm internal name
        vm_internal_name = info['instancename']
        # get vm id
        vm_id = info['id']
        # get vm hypervisor
        hypervisor = info['hypervisor']

        # KVM hypervisor
        if hypervisor == 'KVM':
            '''TO-DO : gestire meglio le operazioni: se una delle due fallisce
            l'altra potrebbe andare a termine senza rendersene conto'''

            # change password of libvirt domain
            try:
                # get connection to qemu server
                qemu_conn = self.clsk_instance.get_hypervisor_conn(
                    'qemu', hostname)
                # create instance of VirtDomain
                virt_domain = VirtDomain(qemu_conn, name=vm_internal_name)
                # change graphics password
                virt_domain.change_graphics_password(password)
                # delete vm manager instance
                del virt_domain
                # release libvirt connection
                self.clsk_instance.release_hypervisor_conn(
                    'qemu', hostname, qemu_conn)
            except (ApiManagerError, VirtDomainError) as ex:
                self.logger.error('Error changing libvirt domain password')
                raise ClskObjectError(ex)

            # save password on db
            try:
                self.db_manager.update_graphic_password(vm_id, 'test')
            except (QueryError, TransactionError) as ex:
                self.logger.error('Error saving libvirt domain password to db')
                raise ClskObjectError(ex)

        # other hypervisor
        else:
            self.logger.debug(
                'Hypervisor %s doesn\'t support graphic device change password'
                % (hypervisor))
Esempio n. 7
0
 def create_private_network(self, name, displaytext, 
                                  networkoffering_id, zone_id,
                                  domain_id=None, domain=None, account=None,
                                  networkdomain=None, 
                                  physicalnetworkid=None):
     '''Create private network.
     
     
     '''       
     params = {'command':'createNetwork',
               'name':name,
               'displaytext':displaytext,
               'networkofferingid':networkoffering_id,
               'zoneid':zone_id,
               'acltype':'Account',
              }
     
     if domain:
         params['domainid'] = self.get_domain_id(domain)
     elif domain_id:
         params['domainid'] = domain_id
     if account:
         params['account'] = account
     if physicalnetworkid:
         params['physicalnetworkid'] = physicalnetworkid
     if networkdomain:
         params['networkdomain'] = networkdomain            
     
     try:
         self._api_client.set_timeout(120)
         response = self._api_client.send_api_request(params)
         res = json.loads(response)['createnetworkresponse']
         if len(res) > 0:
             data = res['network']
         else:
             return None
         
         # create network
         net = NetworkExt(self.clsk_instance, data=data)
         self.logger.debug('Private cloudstack network was created: %s' % name)
         return net   
     except KeyError as ex :
         self.logger.error('Error parsing json data: %s' % ex)
         raise ClskObjectError('Error parsing json data: %s' % ex)
     except ApiError as ex:
         self.logger.error(ex)
         raise ClskObjectError(ex)
Esempio n. 8
0
    def list_networks(self, zone_id=None, domain=None, domain_id=None,
                            account=None, net_id=None):
        '''List network.
        
        :param zone_id: [optional] id of the zone
        :param domain_id: [optional] id of the domain        
        :param domain: [optional] name of the domain
        :param account: [optional] name of the account
        :param net_id: [optional] id of the network
        '''
        params = {'command':'listNetworks',
                  'listall':'true'}

        if zone_id:
            params['zoneid'] = zone_id
        if domain_id:
            params['domainid'] = domain_id
        if domain:
            params['domainid'] = self.get_domain_id(domain)
        if account:
            params['account'] = account
        if net_id:
            params['id'] = net_id

        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['listnetworksresponse']
            if len(res) > 0:
                data = res['network']
            else:
                return []
        except KeyError as ex :
            self.logger.error('Error parsing json data: %s' % ex)
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            self.logger.error(ex)
            raise ClskObjectError(ex)
        
        networks = []
        for item in data:
            # create Account instance
            network = NetworkExt(self.clsk_instance, data=item)
            networks.append(network)
        
        return networks    
Esempio n. 9
0
    def list_volumes(self, zone_id=None, domain=None, domain_id=None,
                           account=None, vol_id=None):
        '''List volumes.

        :param zone_id: [optional] id of the zone
        :param domain_id: [optional] id of the domain
        :param domain: [optional] name of the domain
        :param account: [optional] name of the account
        :param vole_id: [optional] id of the volume        
        '''
        params = {'command':'listVolumes',
                  'listall':'true'}

        if zone_id:
            params['zoneid'] = zone_id  
        if domain:
            params['domainid'] = self.get_domain_id(domain)
        if domain_id:
            params['domainid'] = domain_id
        if account:
            params['account'] = account
        if vol_id:
            params['id'] = vol_id

        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['listvolumesresponse']
            if len(res) > 0:
                data = res['volume']
            else:
                return []
        except KeyError as ex:
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            raise ClskObjectError(ex)

        volumes = []
        for item in data:
            # create Network instance
            volume = VolumeExt(self.clsk_instance, data=item)
            volumes.append(volume)
        
        return volumes 
Esempio n. 10
0
    def config(self):
        """Describe virtual machine configuration."""
        self.logger.info('Get configuration for vm : %s' % self._id)

        info = self.info(cache=True)
        if self.get_state() != 'Running':
            raise ClskObjectError('Virtual machine is not running.')

        # get hypervisor name
        hostname = info['hostname']
        # get vm internal name
        vm_internal_name = info['instancename']
        # get vm hypervisor
        hypervisor = info['hypervisor']

        # KVM hypervisor
        if hypervisor == 'KVM':
            try:
                # get connection to qemu server
                qemu_conn = self.clsk_instance.get_hypervisor_conn(
                    'qemu', hostname)
                # create instance of VirtDomain
                virt_domain = VirtDomain(qemu_conn, name=vm_internal_name)
                # get domain info
                info = virt_domain.info()
                # delete vm manager instance
                del virt_domain
                # release libvirt connection
                self.clsk_instance.release_hypervisor_conn(
                    'qemu', hostname, qemu_conn)

                return info
            except (ApiManagerError, VirtDomainError) as ex:
                self.logger.error('Error reading libvirt domain configuration')
                raise ClskObjectError(ex)
        # other hypervisor
        else:
            return None
Esempio n. 11
0
    def get_storagepool_info(self):
        '''List all storage pools.'''
        params = {'command': 'listStoragePools', 'name': self._data['storage']}

        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['liststoragepoolsresponse']
            if len(res) > 0:
                data = res['storagepool'][0]
                pool_info = {
                    'type': data['type'],
                    'state': data['state'],
                    'path': data['path'],
                    'ipaddress': data['ipaddress']
                }

                return pool_info
            else:
                return None
        except KeyError as ex:
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            raise ClskObjectError(ex)
Esempio n. 12
0
 def list_storagepools(self, zoneid=None, name=None):
     '''List all storage pools.'''
     params = {'command':'listStoragePools'}
     
     if zoneid:
         params['zoneid'] = zoneid
     if name:
         params['name'] = name            
     
     try:
         response = self._api_client.send_api_request(params)
         res = json.loads(response)['liststoragepoolsresponse']['storagepool']
         data = res
     except KeyError as ex:
         raise ClskObjectError('Error parsing json data: %s' % ex)
     except ApiError as ex:
         raise ClskObjectError(ex)
     
     storagepools = []
     for item in data:
         # create StoragePool instance
         storagepool = StoragePoolExt(self.clsk_instance, data=item)
         storagepools.append(storagepool)
     return storagepools    
Esempio n. 13
0
    def list_virtual_machines(self, domain=None, account=None, vm_id=None):
        '''List all virtual machines.'''
        params = {'command':'listVirtualMachines',
                  'listall':'true',
                 }

        if domain:
            try:
                params['domainid'] = self.get_domain_id(domain)
            except ApiError as ex:
                raise ClskObjectError(ex)
        if account:
            params['account'] = account
        if vm_id:
            params['id'] = vm_id            
        
        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['listvirtualmachinesresponse']
            if len(res) > 0:
                data = res['virtualmachine']
            else:
                return []
        except KeyError as ex :
            self.logger.error('Error parsing json data: %s' % ex)
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            self.logger.error(ex)
            raise ClskObjectError(ex)
        
        vms = []
        for item in data:
            # create Account instance
            vm = VirtualMachineExt(self.clsk_instance, data=item)
            vms.append(vm)
        return vms
Esempio n. 14
0
    def stop(self, job_id):
        """Stop virtual machine.
        Async command.
        
        read config from extended database
        
        TO-DO : read config from extended database
        
        :param job_id: unique id of the async job        
        """
        self.logger.info('Stop vm : %s' % self._id)

        if self.get_state() != 'Running':
            raise ClskObjectError('Virtual machine is not running.')

        VirtualMachine.stop(self, job_id)
Esempio n. 15
0
    def destroy(self, job_id):
        """Destroy virtual machine.
        Async command."""
        self.logger.info('Destroy vm : %s' % self._id)

        VirtualMachine.destroy(self, job_id)

        # remove virtual machine extended device from db if they are configured
        info = self.info(cache=True)
        # get vm id
        vm_id = info['id']

        try:
            vm = self.db_manager.get_vm(vm_id)
            if vm:
                self.db_manager.delete_vm(vm_id)
        except (QueryError, TransactionError) as ex:
            raise ClskObjectError(ex)
Esempio n. 16
0
    def update(self, job_id, devices):
        """Update virtual machine. 
        Async command.
        
        TO-DO : read config from extended database
        
        :param job_id: unique id of the async job
        """
        self.logger.info('Update vm : %s' % self._id)

        # get virtual machine extended device from db if they are configured
        info = self.info(cache=True)
        # get vm id
        vm_id = info['id']

        try:
            vm = self.db_manager.get_vm(vm_id)
            if vm:
                # remove old config
                self.db_manager.delete_vm(vm_id)
                # append new devices
                self.append_device(devices)
        except (QueryError, TransactionError) as ex:
            raise ClskObjectError(ex)
Esempio n. 17
0
    def list_volume(self):
        """List virtual machine volume.
        TODO: extend to other hypervisor
        """
        # get qemu disk info
        #disks = self.config()['devices']['disk']

        # get cloudstack volume info
        params = {
            'command': 'listVolumes',
            'listall': 'true',
            'virtualmachineid': self._id
        }

        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)['listvolumesresponse']
            if len(res) > 0:
                vols = res['volume']
                volumes = []
                for vol in vols:
                    # create VolumeExt object
                    volume_obj = VolumeExt(self.clsk_instance, data=vol)

                    # get volume type
                    vol_type = vol['type']

                    # create base
                    volume = {
                        'id': vol['id'],
                        'name': vol['name'],
                        'offering': get_attrib(vol, 'diskofferingdisplaytext',
                                               ''),
                        'size': vol['size'],
                        'storage': vol['storage'],
                        'type': vol_type,
                        'deviceid': vol['deviceid'],
                        'attached': get_attrib(vol, 'attached', '')
                    }
                    """
                    # set extended info to ROOT volume
                    if self._data['hypervisor'] == 'KVM' and vol_type == 'ROOT':
                        volume['source'] = {}
                        
                        # get storage pool connection info
                        pool_info = volume_obj.get_storagepool_info()
                        volume['source']['type'] = pool_info['type']
                        volume['source']['path'] = pool_info['path']
                        volume['source']['ipaddress'] = pool_info['ipaddress']
                        
                        # find qemu root disk
                        for disk in disks:
                            if (disk['alias']['name'] == 'ide0-0-0' and
                                disk['target']['dev'] == 'hda' or
                                disk['alias']['name'] == 'virtio-disk0' and
                                disk['target']['dev'] == 'vda'):
                                volume['source']['file'] = disk['source']['file'].split('/')[-1]                   
                    """

                    # append volume
                    volumes.append(volume)
                return volumes

            else:
                return []

        except KeyError as ex:
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            raise ClskObjectError(ex)
Esempio n. 18
0
    def create_vm(self, job_id, name, displayname, serviceofferingid, 
                        templateid, zoneid, domain, account, hypervisor, 
                        networkids, devices=None, hostid=None, 
                        diskofferingid=None, size=None, keyboard='it'):
        """Create virtual machine.
        Async command.

        TO-DO : extend to support vmware virtual machine

        :param job_id: unique id of the async job
        :param name: host name for the virtual machine
        :param displayname: an optional user generated name for the 
                            virtual machine
        :param serviceofferingid: the ID of the service offering for the 
                                  virtual machine
        :param templateid: the: ID of the template for the virtual machine
        :param zoneid: availability zone for the virtual machine
        :param domain: an optional domain for the virtual machine. If the 
                       account parameter is used, domain must also be used.        
        :param account: an optional account for the virtual machine. 
                        Must be used with domainId.
        :param projectid: Deploy vm for the project        
        :param diskofferingid: the ID of the disk offering for the virtual 
                               machine. If the template is of ISO format, the 
                               diskOfferingId is for the root disk volume. 
                               Otherwise this parameter is used to indicate the 
                               offering for the data disk volume. If the 
                               templateId parameter passed is from a Template 
                               object, the diskOfferingId refers to a DATA Disk 
                               Volume created. If the templateId parameter 
                               passed is from an ISO object, the diskOfferingId 
                               refers to a ROOT Disk Volume created.
        :param hostid: destination Host ID to deploy the VM to - parameter 
                       available for root admin only
        :param hypervisor: the hypervisor on which to deploy the virtual machine
        :param networkids: list of network ids used by virtual machine. 
                           Can't be specified with ipToNetworkList parameter        
        :param keyboard: an optional keyboard device type for the virtual 
                         machine. valid value can be one of de,de-ch,es,fi,fr,
                         fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us
        :param keypair: name of the ssh key pair used to login to the 
                        virtual machine
        :param size: the arbitrary size for the DATADISK volume. Mutually 
                     exclusive with diskOfferingId
        :param startvm: true if network offering supports specifying ip ranges; 
                        defaulted to true if not specified
        :param devices: dict with additional devices : {'spice_graphics':''}
                        spice_graphics, vnc_graphics, rdp_graphics, 
                        video_cirrus, video_qxl,
                        virtio_serial, usb_redirect,
                        sound_card_ac97, sound_card_es1370, 
                        sound_card_sb16, sound_card_ich6
        """
        self.logger.info('Create new extended virtual machine - START')
        
        # get domain id
        domainid = self.get_domain_id(domain)
        
        # create vm with cloudstack api
        params = {'command':'deployVirtualMachine',
                  'name':name,
                  'displayname':displayname,
                  'serviceofferingid':serviceofferingid,
                  'templateid':templateid,
                  'zoneid':zoneid,
                  'domainid':domainid,
                  'account':account,
                  'hypervisor':hypervisor,
                  'networkids':networkids,
                  'keyboard':keyboard,
                  'startvm':'true',
                 }
        
        # the ID of the disk offering for the virtual machine. If the template 
        # is of ISO format, the diskOfferingId is for the root disk volume. 
        # Otherwise this parameter is used to indicate the offering for 
        # the data disk volume
        if diskofferingid != None:
            params['diskofferingid'] = diskofferingid
        # the arbitrary size for the DATADISK volume. Mutually exclusive with 
        # diskOfferingId
        if size != None:
            params['size'] = size
        # destination Host ID to deploy the VM to
        if hostid != None:
            params['hostid'] = hostid
        
        try:
            response = self._api_client.send_api_request(params)
            res = json.loads(response)

            clsk_job_id = res['deployvirtualmachineresponse']['jobid']
            data = self._api_client.query_async_job(job_id, clsk_job_id)['virtualmachine']

            # create virtualmachine object
            vm = VirtualMachineExt(self.clsk_instance, data=data)
            self.logger.debug('Default cloudstack virtual machine was created: %s' % name)
        except KeyError as ex :
            self.logger.error('Error parsing json data: %s' % ex)
            raise ClskObjectError('Error parsing json data: %s' % ex)
        except ApiError as ex:
            self.logger.error(ex)
            raise ClskObjectError(ex)
        
        # append devices
        vm.append_device(devices)
        
        self.logger.info('Create new extended virtual machine - STOP')
        return vm
Esempio n. 19
0
 def create_external_network(self, name, displaytext, 
                                   networkoffering_id, zone_id,
                                   gateway, netmask, startip, endip, vlan, 
                                   domain_id=None, domain=None, account=None,
                                   networkdomain=None, shared=False,
                                   physicalnetworkid=None):
     '''Create diretc network for the account
     
     :param shared: True set network shared for all account in the domain.
                    False set network isolated to account. 
     :param gateway: 10.102.221.129
     :param netmask: 255.255.255.240
     :param startip: 10.102.221.130
     :param endip: 10.102.221.142
     :param vlan: 329
     '''
     params = {'command':'createNetwork',
               'name':name,
               'displaytext':displaytext,
               'networkofferingid':networkoffering_id,
               'zoneid':zone_id,
               'gateway':gateway,
               'netmask':netmask,
               'startip':startip,
               'endip':endip,
               'vlan':vlan,
              }
     
     # set shared status of the network
     if shared:
         params['acltype'] = 'Domain'
     else:
         params['acltype'] = 'Account'
         
     if domain:
         params['domainid'] = self.get_domain_id(domain)
     elif domain_id:
         params['domainid'] = domain_id
     if account:
         params['account'] = account
     if physicalnetworkid:
         params['physicalnetworkid'] = physicalnetworkid
     if networkdomain:
         params['networkdomain'] = networkdomain
     
     try:
         self._api_client.set_timeout(120)
         response = self._api_client.send_api_request(params)
         res = json.loads(response)['createnetworkresponse']
         if len(res) > 0:
             data = res['network']
         else:
             return None
         
         # create network
         net = NetworkExt(self.clsk_instance, data=data)
         self.logger.debug('Hybrid cloudstack network was created: %s' % name)
         return net            
     except KeyError as ex :
         self.logger.error('Error parsing json data: %s' % ex)
         raise ClskObjectError('Error parsing json data: %s' % ex)
     except ApiError as ex:
         self.logger.error(ex)
         raise ClskObjectError(ex)
Esempio n. 20
0
    def append_device(self, devices):
        """"Append additionale devices not supported from cloudstack using
        low level api like libvirt or vpshere api.
        
        :param devices: litst with additional devices : 
                            spice_graphics, vlc_graphics, 
                            video_cirrus, video_qxl,
                            virtio_serial, usb_redirect, sound_card,        
        """
        self.logger.info('Append device to vm : %s' % self._id)

        info = self.info(cache=True)
        if self.get_state() != 'Running':
            raise ClskObjectError('Virtual machine is not running.')

        # get hypervisor name
        hostname = info['hostname']
        # get vm internal name
        vm_internal_name = info['instancename']
        # get vm id
        vm_id = info['id']
        # get vm hypervisor
        hypervisor = info['hypervisor']

        # KVM hypervisor
        if hypervisor == 'KVM':
            '''TO-DO : gestire meglio le operazioni: se una delle due fallisce
            l'altra potrebbe andare a termine senza rendersene conto'''

            # append device to libvirt domain
            try:
                # get connection to qemu server
                qemu_conn = self.clsk_instance.get_hypervisor_conn(
                    'qemu', hostname)
                # create instance of VirtDomain
                virt_domain = VirtDomain(qemu_conn, name=vm_internal_name)
                # append extra devices
                domain2 = virt_domain.append_device(devices.keys())
                # delete vm manager instance
                del virt_domain
                # release libvirt connection
                self.clsk_instance.release_hypervisor_conn(
                    'qemu', hostname, qemu_conn)
            except (ApiManagerError, VirtDomainError) as ex:
                self.logger.error('Error appending devices to libvirt domain')
                raise ClskObjectError(ex)

            # save virtual machine devices configuration on db
            try:
                # add new virtual machine reference into db and append device
                # if it doesn't exists
                if not self.db_manager.get_vm(vm_id):
                    self.db_manager.add_vm(vm_id, devices)
            except (QueryError, TransactionError) as ex:
                self.logger.error(
                    'Error saving libvirt domain extended configuration to db')
                raise ClskObjectError(ex)

        # other hypervisor
        else:
            self.logger.debug('Hypervisor %s doesn\'t support append devices' %
                              (hypervisor))