コード例 #1
0
ファイル: vmstorages.py プロジェクト: SkyWei/kimchi
    def update(self, vm_name, dev_name, params):
        old_disk_ref_cnt = None
        new_disk_ref_cnt = None

        dom = VMModel.get_vm(vm_name, self.conn)

        dev_info = self.lookup(vm_name, dev_name)
        if dev_info['type'] != 'cdrom':
            raise InvalidOperation("KCHVMSTOR0006E")

        params['path'] = check_remote_disk_path(params.get('path', ''),
                                                self.caps.qemu_stream_dns)

        old_disk_path = dev_info['path']
        new_disk_path = params['path']
        if new_disk_path != old_disk_path:
            # An empty path means a CD-ROM was empty or ejected:
            if old_disk_path is not '':
                old_disk_ref_cnt = get_disk_ref_cnt(
                    self.objstore, self.conn, old_disk_path)
            if new_disk_path is not '':
                new_disk_ref_cnt = get_disk_ref_cnt(
                    self.objstore, self.conn, new_disk_path)

        dev_info.update(params)
        dev, xml = get_disk_xml(dev_info)

        try:
            dom.updateDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0009E", {'error': e.message})

        try:
            if old_disk_ref_cnt is not None and \
               old_disk_ref_cnt > 0:
                set_disk_ref_cnt(self.objstore, old_disk_path,
                                 old_disk_ref_cnt - 1)
            if new_disk_ref_cnt is not None:
                set_disk_ref_cnt(self.objstore, new_disk_path,
                                 new_disk_ref_cnt + 1)
        except Exception as e:
            kimchi_log.error("Unable to update dev ref_cnt on update due to"
                             " %s:" % e.message)
        return dev
コード例 #2
0
    def update(self, vm_name, dev_name, params):
        old_disk_ref_cnt = None
        new_disk_ref_cnt = None

        dom = VMModel.get_vm(vm_name, self.conn)

        dev_info = self.lookup(vm_name, dev_name)
        if dev_info['type'] != 'cdrom':
            raise InvalidOperation("KCHVMSTOR0006E")

        params['path'] = check_remote_disk_path(params.get('path', ''),
                                                self.caps.qemu_stream_dns)

        old_disk_path = dev_info['path']
        new_disk_path = params['path']
        if new_disk_path != old_disk_path:
            # An empty path means a CD-ROM was empty or ejected:
            if old_disk_path is not '':
                old_disk_ref_cnt = get_disk_ref_cnt(self.objstore, self.conn,
                                                    old_disk_path)
            if new_disk_path is not '':
                new_disk_ref_cnt = get_disk_ref_cnt(self.objstore, self.conn,
                                                    new_disk_path)

        dev_info.update(params)
        dev, xml = get_disk_xml(dev_info)

        try:
            dom.updateDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0009E", {'error': e.message})

        try:
            if old_disk_ref_cnt is not None and \
               old_disk_ref_cnt > 0:
                set_disk_ref_cnt(self.objstore, old_disk_path,
                                 old_disk_ref_cnt - 1)
            if new_disk_ref_cnt is not None:
                set_disk_ref_cnt(self.objstore, new_disk_path,
                                 new_disk_ref_cnt + 1)
        except Exception as e:
            kimchi_log.error("Unable to update dev ref_cnt on update due to"
                             " %s:" % e.message)
        return dev
コード例 #3
0
ファイル: vmstorages.py プロジェクト: clnperez/kimchi
    def delete(self, vm_name, dev_name):
        conn = self.conn.get()

        try:
            bus_type = self.lookup(vm_name, dev_name)['bus']
            dom = conn.lookupByName(vm_name)
        except NotFoundError:
            raise

        if (bus_type not in HOTPLUG_TYPE and
                DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
            raise InvalidOperation('KCHVMSTOR0011E')

        try:
            disk = get_device_node(dom, dev_name)
            path = get_vm_disk_info(dom, dev_name)['path']
            if path is None or len(path) < 1:
                path = self.lookup(vm_name, dev_name)['path']
            # This has to be done before it's detached. If it wasn't
            #   in the obj store, its ref count would have been updated
            #   by get_disk_ref_cnt()
            if path is not None:
                ref_cnt = get_disk_ref_cnt(self.objstore, self.conn, path)
            else:
                kimchi_log.error("Unable to decrement volume ref_cnt on"
                                 " delete because no path could be found.")
            dom.detachDeviceFlags(etree.tostring(disk),
                                  get_vm_config_flag(dom, 'all'))
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0010E", {'error': e.message})

        if ref_cnt is not None and ref_cnt > 0:
            set_disk_ref_cnt(self.objstore, path, ref_cnt - 1)
        else:
            kimchi_log.error("Unable to decrement %s:%s ref_cnt on delete."
                             % (vm_name, dev_name))
コード例 #4
0
    def delete(self, vm_name, dev_name):
        conn = self.conn.get()

        try:
            bus_type = self.lookup(vm_name, dev_name)['bus']
            dom = conn.lookupByName(vm_name)
        except NotFoundError:
            raise

        if (bus_type not in HOTPLUG_TYPE
                and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
            raise InvalidOperation('KCHVMSTOR0011E')

        try:
            disk = get_device_node(dom, dev_name)
            path = get_vm_disk_info(dom, dev_name)['path']
            if path is None or len(path) < 1:
                path = self.lookup(vm_name, dev_name)['path']
            # This has to be done before it's detached. If it wasn't
            #   in the obj store, its ref count would have been updated
            #   by get_disk_ref_cnt()
            if path is not None:
                ref_cnt = get_disk_ref_cnt(self.objstore, self.conn, path)
            else:
                kimchi_log.error("Unable to decrement volume ref_cnt on"
                                 " delete because no path could be found.")
            dom.detachDeviceFlags(etree.tostring(disk),
                                  get_vm_config_flag(dom, 'all'))
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0010E", {'error': e.message})

        if ref_cnt is not None and ref_cnt > 0:
            set_disk_ref_cnt(self.objstore, path, ref_cnt - 1)
        else:
            kimchi_log.error("Unable to decrement %s:%s ref_cnt on delete." %
                             (vm_name, dev_name))
コード例 #5
0
ファイル: vmstorages.py プロジェクト: clnperez/kimchi
    def create(self, vm_name, params):
        vol_model = None
        # Path will never be blank due to API.json verification.
        # There is no need to cover this case here.
        if not ('vol' in params) ^ ('path' in params):
            raise InvalidParameter("KCHVMSTOR0017E")

        dom = VMModel.get_vm(vm_name, self.conn)
        params['bus'] = _get_device_bus(params['type'], dom,
                                        self.caps.metadata_support)
        params['format'] = 'raw'

        dev_list = [dev for dev, bus in get_vm_disks(dom).iteritems()
                    if bus == params['bus']]
        dev_list.sort()
        if len(dev_list) == 0:
            params['index'] = 0
        else:
            char = dev_list.pop()[2]
            params['index'] = string.ascii_lowercase.index(char) + 1

        if (params['bus'] not in HOTPLUG_TYPE
                and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
            raise InvalidOperation('KCHVMSTOR0011E')

        if params.get('vol'):
            try:
                pool = params['pool']
                vol_model = StorageVolumeModel(conn=self.conn,
                                               objstore=self.objstore)
                vol_info = vol_model.lookup(pool, params['vol'])
            except KeyError:
                raise InvalidParameter("KCHVMSTOR0012E")
            except Exception as e:
                raise InvalidParameter("KCHVMSTOR0015E", {'error': e})
            if vol_info['ref_cnt'] != 0:
                raise InvalidParameter("KCHVMSTOR0016E")

            valid_format = {
                "disk": ["raw", "bochs", "qcow", "qcow2", "qed", "vmdk"],
                "cdrom": "iso"}

            if vol_info['type'] == 'file':
                if (params['type'] == 'disk' and
                        vol_info['format'] in valid_format[params['type']]):
                    params['format'] = vol_info['format']
                else:
                    raise InvalidParameter("KCHVMSTOR0018E",
                                           {"format": vol_info['format'],
                                            "type": params['type']})

            params['path'] = vol_info['path']
            params['disk'] = vol_info['type']

        params.update(self._get_available_bus_address(params['bus'], vm_name))

        # Add device to VM
        dev, xml = get_disk_xml(params)
        try:
            conn = self.conn.get()
            dom = conn.lookupByName(vm_name)
            dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})

        # Don't put a try-block here. Let the exception be raised. If we
        #   allow disks ref_cnts to be out of sync, data corruption could
        #   occour if a disk is added to two guests unknowingly.
        if params.get('vol'):
            set_disk_ref_cnt(self.objstore, params['path'],
                             vol_info['ref_cnt'] + 1)

        return dev
コード例 #6
0
    def create(self, vm_name, params):
        vol_model = None
        # Path will never be blank due to API.json verification.
        # There is no need to cover this case here.
        if not ('vol' in params) ^ ('path' in params):
            raise InvalidParameter("KCHVMSTOR0017E")

        dom = VMModel.get_vm(vm_name, self.conn)
        params['bus'] = _get_device_bus(params['type'], dom,
                                        self.caps.metadata_support)
        params['format'] = 'raw'

        dev_list = [
            dev for dev, bus in get_vm_disks(dom).iteritems()
            if bus == params['bus']
        ]
        dev_list.sort()
        if len(dev_list) == 0:
            params['index'] = 0
        else:
            char = dev_list.pop()[2]
            params['index'] = string.ascii_lowercase.index(char) + 1

        if (params['bus'] not in HOTPLUG_TYPE
                and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
            raise InvalidOperation('KCHVMSTOR0011E')

        if params.get('vol'):
            try:
                pool = params['pool']
                vol_model = StorageVolumeModel(conn=self.conn,
                                               objstore=self.objstore)
                vol_info = vol_model.lookup(pool, params['vol'])
            except KeyError:
                raise InvalidParameter("KCHVMSTOR0012E")
            except Exception as e:
                raise InvalidParameter("KCHVMSTOR0015E", {'error': e})
            if vol_info['ref_cnt'] != 0:
                raise InvalidParameter("KCHVMSTOR0016E")

            valid_format = {
                "disk": ["raw", "bochs", "qcow", "qcow2", "qed", "vmdk"],
                "cdrom": "iso"
            }

            if vol_info['type'] == 'file':
                if (params['type'] == 'disk' and vol_info['format']
                        in valid_format[params['type']]):
                    params['format'] = vol_info['format']
                else:
                    raise InvalidParameter("KCHVMSTOR0018E", {
                        "format": vol_info['format'],
                        "type": params['type']
                    })

            params['path'] = vol_info['path']
            params['disk'] = vol_info['type']

        params.update(self._get_available_bus_address(params['bus'], vm_name))
        params['path'] = check_remote_disk_path(params['path'],
                                                self.caps.qemu_stream_dns)

        # Add device to VM
        dev, xml = get_disk_xml(params)
        try:
            conn = self.conn.get()
            dom = conn.lookupByName(vm_name)
            dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})

        # Don't put a try-block here. Let the exception be raised. If we
        #   allow disks ref_cnts to be out of sync, data corruption could
        #   occour if a disk is added to two guests unknowingly.
        if params.get('vol'):
            set_disk_ref_cnt(self.objstore, params['path'],
                             vol_info['ref_cnt'] + 1)

        return dev