
From: Royce Lv <lvroyce@linux.vnet.ibm.com> Change media operation should not remove device and just change the source, so fix the implementation from detach then attach to updateDeviceFlags. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/model/vmstorages.py | 116 ++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py index 1597d49..7c5ab85 100644 --- a/src/kimchi/model/vmstorages.py +++ b/src/kimchi/model/vmstorages.py @@ -41,31 +41,58 @@ DEV_TYPE_SRC_ATTR_MAP = {'file': 'file', 'block': 'dev'} +def _get_storage_xml(params): + src_type = params.get('src_type') + disk = E.disk(type=src_type, device=params.get('type')) + disk.append(E.driver(name='qemu', type='raw')) + # Working with url paths + if src_type == 'network': + output = urlparse.urlparse(params.get('path')) + host = E.host(name=output.hostname, port= + output.port or socket.getservbyname(output.scheme)) + source = E.source(protocol=output.scheme, name=output.path) + source.append(host) + disk.append(source) + else: + # Fixing source attribute + source = E.source() + source.set(DEV_TYPE_SRC_ATTR_MAP[src_type], params.get('path')) + disk.append(source) + + disk.append(E.target(dev=params.get('dev'), bus='ide')) + return ET.tostring(disk) + + +def _check_cdrom_path(path): + if check_url_path(path): + src_type = 'network' + # Check if path is a valid local path + elif os.path.exists(path): + if os.path.isfile(path): + src_type = 'file' + else: + # Check if path is a valid cdrom drive + with open('/proc/sys/dev/cdrom/info') as cdinfo: + content = cdinfo.read() + + cds = re.findall("drive name:\t\t(.*)", content) + if not cds: + raise InvalidParameter("KCHCDROM0003E", {'value': path}) + + drives = [os.path.join('/dev', p) for p in cds[0].split('\t')] + if path not in drives: + raise InvalidParameter("KCHCDROM0003E", {'value': path}) + + src_type = 'block' + else: + raise InvalidParameter("KCHCDROM0003E", {'value': path}) + return src_type + + class VMStoragesModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] - def _get_storage_xml(self, params): - src_type = params.get('src_type') - disk = E.disk(type=src_type, device=params.get('type')) - disk.append(E.driver(name='qemu', type='raw')) - # Working with url paths - if src_type == 'network': - output = urlparse.urlparse(params.get('path')) - host = E.host(name=output.hostname, port= - output.port or socket.getservbyname(output.scheme)) - source = E.source(protocol=output.scheme, name=output.path) - source.append(host) - disk.append(source) - else: - # Fixing source attribute - source = E.source() - source.set(DEV_TYPE_SRC_ATTR_MAP[src_type], params.get('path')) - disk.append(source) - - disk.append(E.target(dev=params.get('dev'), bus='ide')) - return ET.tostring(disk) - def create(self, vm_name, params): dom = VMModel.get_vm(vm_name, self.conn) if DOM_STATE_MAP[dom.info()[0]] != 'shutoff': @@ -84,33 +111,12 @@ class VMStoragesModel(object): # Path will never be blank due to API.json verification. # There is no need to cover this case here. path = params['path'] + params['src_type'] = _check_cdrom_path(path) # Check if path is an url - if check_url_path(path): - params['src_type'] = 'network' - # Check if path is a valid local path - elif os.path.exists(path): - if os.path.isfile(path): - params['src_type'] = 'file' - else: - # Check if path is a valid cdrom drive - with open('/proc/sys/dev/cdrom/info') as cdinfo: - content = cdinfo.read() - - cds = re.findall("drive name:\t\t(.*)", content) - if not cds: - raise InvalidParameter("KCHCDROM0003E", {'value': path}) - - drives = [os.path.join('/dev', p) for p in cds[0].split('\t')] - if path not in drives: - raise InvalidParameter("KCHCDROM0003E", {'value': path}) - - params['src_type'] = 'block' - else: - raise InvalidParameter("KCHCDROM0003E", {'value': path}) # Add device to VM - dev_xml = self._get_storage_xml(params) + dev_xml = _get_storage_xml(params) try: conn = self.conn.get() dom = conn.lookupByName(vm_name) @@ -199,23 +205,17 @@ class VMStorageModel(object): raise OperationFailed("KCHCDROM0010E", {'error': e.message}) def update(self, vm_name, dev_name, params): + if params.get('path'): + params['src_type'] = _check_cdrom_path(params['path']) + dom = VMModel.get_vm(vm_name, self.conn) - if DOM_STATE_MAP[dom.info()[0]] != 'shutoff': - raise InvalidOperation('KCHCDROM0011E') - info = self.lookup(vm_name, dev_name) - backup_params = info.copy() + dev_info = self.lookup(vm_name, dev_name) + dev_info.update(params) + xml = _get_storage_xml(dev_info) - info.update(params) - kargs = {'conn': self.conn} - stgModel = VMStoragesModel(**kargs) try: - self.delete(vm_name, dev_name) - return stgModel.create(vm_name, info) + dom.updateDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT) except Exception as e: - try: - stgModel.create(vm_name, backup_params) - except: - pass - raise OperationFailed("KCHCDROM0009E", {'error': e.message}) + return dev_name -- 1.8.1.2