
On 05/05/2014 05:35 PM, Aline Manera wrote:
On 04/28/2014 07:20 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
Vmstorages will refer to storagevolume functions to get storage volume format and reference count, Meanwhile storage volume will refer to vm storages to see if a path is refered by a vm to prevent a disk be used by multiple vm. To prevent circular reference, abstract vm disk list and lookup function to a single module.
Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/model/storagevolumes.py | 9 +++--- src/kimchi/model/vmstorages.py | 55 +++++------------------------------- src/kimchi/vmdisks.py | 58 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 52 deletions(-) create mode 100644 src/kimchi/vmdisks.py
diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py index 8a568eb..9a56a63 100644 --- a/src/kimchi/model/storagevolumes.py +++ b/src/kimchi/model/storagevolumes.py @@ -28,8 +28,8 @@ from kimchi.exception import MissingParameter, NotFoundError, OperationFailed from kimchi.isoinfo import IsoImage from kimchi.model.storagepools import StoragePoolModel from kimchi.utils import kimchi_log -from kimchi.model.vms import VMsModel -from kimchi.model.vmstorages import VMStoragesModel, VMStorageModel +from kimchi.model.vms import VMsModel, VMModel +from kimchi.vmdisks import get_vm_disk, get_vm_disk_list
VOLUME_TYPE_MAP = {0: 'file', @@ -134,9 +134,10 @@ class StorageVolumeModel(object): # try to find this volume in exsisted vm vms = VMsModel.get_vms(self.conn) for vm in vms: - storages = VMStoragesModel(**args).get_list(vm) + dom = VMModel.get_vm(vm, self.conn) + storages = get_vm_disk_list(dom) for disk in storages: - d_info = VMStorageModel(**args).lookup(vm, disk) + d_info = get_vm_disk(dom, disk) if path == d_info['path']: ref_cnt = ref_cnt + 1 session.store('storagevolume', vol_id, diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py index b265e6a..c04d511 100644 --- a/src/kimchi/model/vmstorages.py +++ b/src/kimchi/model/vmstorages.py @@ -33,22 +33,12 @@ from kimchi.exception import OperationFailed from kimchi.model.vms import DOM_STATE_MAP, VMModel from kimchi.utils import check_url_path from kimchi.osinfo import lookup +from kimchi.vmdisks import get_device_xml, get_vm_disk, get_vm_disk_list +from kimchi.vmdisks import DEV_TYPE_SRC_ATTR_MAP
-DEV_TYPE_SRC_ATTR_MAP = {'file': 'file', - 'block': 'dev'} HOTPLUG_TYPE = ['scsi', 'virtio']
-def _get_device_xml(dom, dev_name): - # Get VM xml and then devices xml - xml = dom.XMLDesc(0) - devices = objectify.fromstring(xml).devices - disk = devices.xpath("./disk/target[@dev='%s']/.." % dev_name) - if not disk: - return None - return disk[0] - - def _get_device_bus(dev_type, dom): try: version, distro = VMModel.vm_get_os_metadata(dom) @@ -114,6 +104,7 @@ def _check_cdrom_path(path): class VMStoragesModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] + self.objstore = kargs['objstore']
def _get_available_bus_address(self, bus_type, vm_name): if bus_type not in ['ide']: @@ -125,7 +116,7 @@ class VMStoragesModel(object): valid_id = [('0', '0'), ('0', '1'), ('1', '0'), ('1', '1')] controller_id = '0' for dev_name in disks: - disk = _get_device_xml(dom, dev_name) + disk = get_device_xml(dom, dev_name) if disk.target.attrib['bus'] == 'ide': controller_id = disk.address.attrib['controller'] bus_id = disk.address.attrib['bus'] @@ -156,7 +147,6 @@ class VMStoragesModel(object): # There is no need to cover this case here. path = params['path'] params['src_type'] = _check_cdrom_path(path) - params.setdefault( 'bus', _get_device_bus(params['type'], dom)) if (params['bus'] not in HOTPLUG_TYPE @@ -187,13 +177,7 @@ class VMStoragesModel(object):
def get_list(self, vm_name): dom = VMModel.get_vm(vm_name, self.conn) - xml = dom.XMLDesc(0) - devices = objectify.fromstring(xml).devices - storages = [disk.target.attrib['dev'] - for disk in devices.xpath("./disk[@device='disk']")] - storages += [disk.target.attrib['dev'] - for disk in devices.xpath("./disk[@device='cdrom']")] - return storages + return get_vm_disk_list(dom)
class VMStorageModel(object): @@ -203,32 +187,7 @@ class VMStorageModel(object): def lookup(self, vm_name, dev_name): # Retrieve disk xml and format return dict dom = VMModel.get_vm(vm_name, self.conn) - disk = _get_device_xml(dom, dev_name) - if disk is None: - raise NotFoundError("KCHVMSTOR0007E", {'dev_name': dev_name, - 'vm_name': vm_name}) - path = "" - dev_bus = 'ide' - try: - source = disk.source - if source is not None: - src_type = disk.attrib['type'] - if src_type == 'network': - host = source.host - path = (source.attrib['protocol'] + '://' + - host.attrib['name'] + ':' + - host.attrib['port'] + source.attrib['name']) - else: - path = source.attrib[DEV_TYPE_SRC_ATTR_MAP[src_type]] - # Retrieve storage bus type - dev_bus = disk.target.attrib['bus'] - except: - pass - dev_type = disk.attrib['device'] - return {'dev': dev_name, - 'type': dev_type, - 'path': path, - 'bus': dev_bus} + return get_vm_disk(dom, dev_name)
def delete(self, vm_name, dev_name): # Get storage device xml @@ -246,7 +205,7 @@ class VMStorageModel(object): try: conn = self.conn.get() dom = conn.lookupByName(vm_name) - disk = _get_device_xml(dom, dev_name) + disk = get_device_xml(dom, dev_name) dom.detachDeviceFlags(etree.tostring(disk), libvirt.VIR_DOMAIN_AFFECT_CURRENT) except Exception as e: diff --git a/src/kimchi/vmdisks.py b/src/kimchi/vmdisks.py new file mode 100644 index 0000000..73269ee --- /dev/null +++ b/src/kimchi/vmdisks.py
Missing the license header
I will add it before applying.
@@ -0,0 +1,58 @@ +from lxml import objectify + +from kimchi.exception import NotFoundError + +DEV_TYPE_SRC_ATTR_MAP = {'file': 'file', + 'block': 'dev'} + + +def get_device_xml(dom, dev_name): + # Get VM xml and then devices xml + xml = dom.XMLDesc(0) + devices = objectify.fromstring(xml).devices + disk = devices.xpath("./disk/target[@dev='%s']/.." % dev_name) + if not disk: + return None + return disk[0] + + +def get_vm_disk(dom, dev_name): + # Retrieve disk xml and format return dict + disk = get_device_xml(dom, dev_name) + if disk is None: + raise NotFoundError( + "KCHVMSTOR0007E", + {'dev_name': dev_name, 'vm_name': dom.name()}) + path = "" + dev_bus = 'ide' + try: + source = disk.source + if source is not None: + src_type = disk.attrib['type'] + if src_type == 'network': + host = source.host + path = (source.attrib['protocol'] + '://' + + host.attrib['name'] + ':' + + host.attrib['port'] + source.attrib['name']) + else: + path = source.attrib[DEV_TYPE_SRC_ATTR_MAP[src_type]] + # Retrieve storage bus type + dev_bus = disk.target.attrib['bus'] + except: + pass + dev_type = disk.attrib['device'] + return {'dev': dev_name, + 'type': dev_type, + 'path': path, + 'format': disk.driver.attrib['type'], + 'bus': dev_bus} + + +def get_vm_disk_list(dom): + xml = dom.XMLDesc(0) + devices = objectify.fromstring(xml).devices + storages = [disk.target.attrib['dev'] + for disk in devices.xpath("./disk[@device='disk']")] + storages += [disk.target.attrib['dev'] + for disk in devices.xpath("./disk[@device='cdrom']")] + return storages
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel