def _do_we_clone_device(self, xml, i): base_path = "/domain/devices/disk[%d]" % i source = _util.get_xml_path( xml, "%s/source/@dev | %s/source/@file" % (base_path, base_path)) target = _util.get_xml_path(xml, base_path + "/target/@dev") ro = _util.get_xml_path(xml, "count(%s/readonly)" % base_path) share = _util.get_xml_path(xml, "count(%s/shareable)" % base_path) if not target: raise ValueError("XML has no 'dev' attribute in disk target") if target in self.skip_target: return (None, None) if target in self.force_target: return (source, target) # No media path if not source and self.CLONE_POLICY_NO_EMPTYMEDIA in self.clone_policy: return (None, None) # Readonly disks if ro and self.CLONE_POLICY_NO_READONLY in self.clone_policy: return (None, None) # Shareable disks if share and self.CLONE_POLICY_NO_SHAREABLE in self.clone_policy: return (None, None) return (source, target)
def _do_we_clone_device(self, xml, i): base_path = "/domain/devices/disk[%d]" % i source = _util.get_xml_path(xml, "%s/source/@dev | %s/source/@file" % (base_path, base_path)) target = _util.get_xml_path(xml, base_path + "/target/@dev") ro = _util.get_xml_path(xml, "count(%s/readonly)" % base_path) share = _util.get_xml_path(xml, "count(%s/shareable)" % base_path) if not target: raise ValueError("XML has no 'dev' attribute in disk target") if target in self.skip_target: return (None, None) if target in self.force_target: return (source, target) # No media path if not source and self.CLONE_POLICY_NO_EMPTYMEDIA in self.clone_policy: return (None, None) # Readonly disks if ro and self.CLONE_POLICY_NO_READONLY in self.clone_policy: return (None, None) # Shareable disks if share and self.CLONE_POLICY_NO_SHAREABLE in self.clone_policy: return (None, None) return (source, target)
def _upload_file(conn, meter, destpool, src): # Build stream object stream = conn.newStream(0) def safe_send(data): while True: ret = stream.send(data) if ret == 0 or ret == len(data): break data = data[ret:] # Build placeholder volume size = os.path.getsize(src) basename = os.path.basename(src) poolpath = _util.get_xml_path(destpool.XMLDesc(0), "/pool/target/path") name = Storage.StorageVolume.find_free_name(basename, pool_object=destpool) if name != basename: logging.debug("Generated non-colliding volume name %s", name) disk = VirtualDisk(conn=conn, path=os.path.join(poolpath, name), sizebytes=size, sparse=True) disk.setup_dev(meter=meter) vol = disk.vol_object if not vol: raise RuntimeError(_("Failed to lookup scratch media volume")) try: # Register upload offset = 0 length = size flags = 0 stream.upload(vol, offset, length, flags) # Open source file fileobj = file(src, "r") # Start transfer total = 0 meter.start(size=size, text=_("Transferring %s") % os.path.basename(src)) while True: # blocksize = (1024 ** 2) blocksize = 1024 data = fileobj.read(blocksize) if not data: break safe_send(data) total += len(data) meter.update(total) # Cleanup stream.finish() meter.end(size) except: if vol: vol.delete(0) raise return vol
def get_volume_for_pool(pool_object=None, pool_name=None, conn=None): """ Returns volume class associated with passed pool_object/name """ pool_object = StorageVolume.lookup_pool_by_name(pool_object=pool_object, pool_name=pool_name, conn=conn) return StoragePool.get_volume_for_pool(_util.get_xml_path(pool_object.XMLDesc(0), "/pool/@type"))
def __init__(self, name, input_vol): if not isinstance(input_vol, libvirt.virStorageVol): raise ValueError(_("input_vol must be a virStorageVol")) pool = input_vol.storagePoolLookupByVolume() # Populate some basic info xml = input_vol.XMLDesc(0) typ = input_vol.info()[0] cap = int(_util.get_xml_path(xml, "/volume/capacity")) alc = int(_util.get_xml_path(xml, "/volume/allocation")) fmt = _util.get_xml_path(xml, "/volume/target/format/@type") StorageVolume.__init__(self, name=name, pool=pool, pool_name=pool.name(), allocation=alc, capacity=cap) self.input_vol = input_vol self._file_type = typ self._format = fmt
def _countMACaddr(vms, searchmac): if not searchmac: return def count_cb(ctx): c = 0 for mac in ctx.xpathEval("/domain/devices/interface/mac"): macaddr = mac.xpathEval("attribute::address")[0].content if macaddr and _util.compareMAC(searchmac, macaddr) == 0: c += 1 return c count = 0 for vm in vms: xml = vm.XMLDesc(0) count += _util.get_xml_path(xml, func=count_cb) return count
def _get_original_devices_info(self, xml): disks = [] lst = [] count = _util.get_xml_path(xml, "count(/domain/devices/disk)") for i in range(1, int(count + 1)): # Check if the disk needs cloning (path, target) = self._do_we_clone_device(xml, i) if target == None: continue lst.append((path, target)) # Set up virtual disk to encapsulate all relevant path info for path, target in lst: d = None validate = not self.preserve_dest_disks try: if (path and validate and not VirtualDisk.path_exists(self._hyper_conn, path)): raise ValueError(_("Disk '%s' does not exist.") % path) device = VirtualDisk.DEVICE_DISK if not path: # Tell VirtualDisk we are a cdrom to allow empty media device = VirtualDisk.DEVICE_CDROM d = VirtualDisk(path, conn=self._hyper_conn, device=device, validate=validate) d.target = target except Exception, e: _util.log_exception(e) raise ValueError( _("Could not determine original disk " "information: %s" % str(e))) disks.append(d)
def _get_original_devices_info(self, xml): disks = [] lst = [] count = _util.get_xml_path(xml, "count(/domain/devices/disk)") for i in range(1, int(count + 1)): # Check if the disk needs cloning (path, target) = self._do_we_clone_device(xml, i) if target == None: continue lst.append((path, target)) # Set up virtual disk to encapsulate all relevant path info for path, target in lst: d = None validate = not self.preserve_dest_disks try: if (path and validate and not VirtualDisk.path_exists(self._hyper_conn, path)): raise ValueError(_("Disk '%s' does not exist.") % path) device = VirtualDisk.DEVICE_DISK if not path: # Tell VirtualDisk we are a cdrom to allow empty media device = VirtualDisk.DEVICE_CDROM d = VirtualDisk(path, conn=self._hyper_conn, device=device, validate=validate) d.target = target except Exception, e: _util.log_exception(e) raise ValueError(_("Could not determine original disk " "information: %s" % str(e))) disks.append(d)
def set_original_xml(self, val): if type(val) is not str: raise ValueError(_("Original xml must be a string.")) self._original_xml = val self._original_guest = _util.get_xml_path(self.original_xml, "/domain/name")
def _upload_file(conn, meter, destpool, src): # Build stream object stream = conn.newStream(0) def safe_send(data): while True: ret = stream.send(data) if ret == 0 or ret == len(data): break data = data[ret:] # Build placeholder volume size = os.path.getsize(src) basename = os.path.basename(src) poolpath = _util.get_xml_path(destpool.XMLDesc(0), "/pool/target/path") name = Storage.StorageVolume.find_free_name(basename, pool_object=destpool) if name != basename: logging.debug("Generated non-colliding volume name %s" % name) disk = VirtualDisk(conn=conn, path=os.path.join(poolpath, name), sizebytes=size, sparse=True) disk.setup_dev(meter=meter) vol = disk.vol_object if not vol: raise RuntimeError(_("Failed to lookup scratch media volume")) try: # Register upload offset = 0 length = size flags = 0 stream.upload(vol, offset, length, flags) # Open source file fileobj = file(src, "r") # Start transfer total = 0 meter.start(size=size, text=_("Transferring %s") % os.path.basename(src)) while True: #blocksize = (1024 ** 2) blocksize = 1024 data = fileobj.read(blocksize) if not data: break safe_send(data) total += len(data) meter.update(total) # Cleanup stream.finish() meter.end(size) except: if vol: vol.delete(0) raise return vol