def _make_disks(self): for drive in self.boot_caps.drives: path = self._abspath(drive.disk.file) size = None if drive.disk.size is not None: size = float(drive.disk.size) / 1024 # FIXME: This is awkward; the image should be able to express # whether the disk is expected to be there or not independently # of its classification, especially for user disks # FIXME: We ignore the target for the mapping in m.target if (drive.disk.use == ImageParser.Disk.USE_SYSTEM and not os.path.exists(path)): raise ImageInstallerException(_("System disk %s does not exist") % path) device = VirtualDisk.DEVICE_DISK if drive.disk.format == ImageParser.Disk.FORMAT_ISO: device = VirtualDisk.DEVICE_CDROM disk = VirtualDisk(conn=self.conn, path=path, size=size, device=device, format=drive.disk.format) disk.target = drive.target self.install_devices.append(disk)
def _get_original_devices_info(self): clonelist = [] retdisks = [] for disk in self._guest.get_devices("disk"): if self._do_we_clone_device(disk): clonelist.append(disk) continue # Set up virtual disk to encapsulate all relevant path info for disk in clonelist: validate = not self.preserve_dest_disks try: if (disk.path and validate and not VirtualDisk.path_exists(self._hyper_conn, disk.path)): raise ValueError(_("Disk '%s' does not exist.") % disk.path) device = VirtualDisk.DEVICE_DISK if not disk.path: # Tell VirtualDisk we are a cdrom to allow empty media device = VirtualDisk.DEVICE_CDROM d = VirtualDisk(disk.path, conn=self._hyper_conn, device=device, driverType=disk.driver_type, validate=validate) d.target = disk.target except Exception, e: logging.debug("", exc_info=True) raise ValueError(_("Could not determine original disk " "information: %s" % str(e))) retdisks.append(d)
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 generate_clone_disk_path(origpath, design, newname=None): origname = design.original_guest newname = newname or design.clone_name path = origpath suffix = "" # Try to split the suffix off the existing disk name. Ex. # foobar.img -> foobar-clone.img # # If the suffix is greater than 7 characters, assume it isn't # a file extension and is part of the disk name, at which point # just stick '-clone' on the end. if origpath.count(".") and len(origpath.rsplit(".", 1)[1]) <= 7: path, suffix = origpath.rsplit(".", 1) suffix = "." + suffix dirname = os.path.dirname(path) basename = os.path.basename(path) clonebase = basename + "-clone" if origname and basename == origname: clonebase = newname clonebase = os.path.join(dirname, clonebase) return _util.generate_name( clonebase, lambda p: VirtualDisk.path_exists(design.original_conn, p), suffix, lib_collision=False)
def _make_disks(self): for m in self.boot_caps.drives: p = self._abspath(m.disk.file) s = None if m.disk.size is not None: s = float(m.disk.size)/1024 # FIXME: This is awkward; the image should be able to express # whether the disk is expected to be there or not independently # of its classification, especially for user disks # FIXME: We ignore the target for the mapping in m.target if (m.disk.use == ImageParser.Disk.USE_SYSTEM and not os.path.exists(p)): raise ImageInstallerException(_("System disk %s does not exist") % p) device = VirtualDisk.DEVICE_DISK if m.disk.format == ImageParser.Disk.FORMAT_ISO: device = VirtualDisk.DEVICE_CDROM d = VirtualDisk(p, s, device = device, type = VirtualDisk.TYPE_FILE) d.target = m.target self.install_devices.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 _prepare_kernel_and_initrd(self, guest, meter): disk = None # If installing off a local path, map it through to a virtual CD/disk if (self.location is not None and self._location_is_path and not os.path.isdir(self.location)): device = VirtualDisk.DEVICE_DISK if guest._lookup_osdict_key('pv_cdrom_install'): device = VirtualDisk.DEVICE_CDROM disk = VirtualDisk(conn=guest.conn, device=device, path=self.location, readOnly=True, transient=True) if self._install_bootconfig.kernel: return disk # Need to fetch the kernel & initrd from a remote site, or # out of a loopback mounted disk image/device ignore, os_type, os_variant, media = OSDistro.acquireKernel( guest, self.location, meter, self.scratchdir, self.os_type) (kernelfn, initrdfn, args) = media if guest.get_os_autodetect(): if os_type: logging.debug("Auto detected OS type as: %s" % os_type) guest.os_type = os_type if (os_variant and guest.os_type == os_type): logging.debug("Auto detected OS variant as: %s" % os_variant) guest.os_variant = os_variant self._install_bootconfig.kernel = kernelfn self._install_bootconfig.initrd = initrdfn self._install_bootconfig.kernel_args = args self._tmpfiles.append(kernelfn) if initrdfn: self._tmpfiles.append(initrdfn) if self._initrd_injections: self._perform_initrd_injections() return disk
def _prepare_cdrom(self, guest, meter): if not self._location_is_path: # Xen needs a boot.iso if its a http://, ftp://, or nfs: url (store_ignore, os_type_ignore, os_variant_ignore, media) = \ OSDistro.acquireBootDisk(guest, self.location, meter, self.scratchdir) cdrom = media self._tmpfiles.append(cdrom) else: cdrom = self.location disk = VirtualDisk(path=cdrom, conn=guest.conn, device=VirtualDisk.DEVICE_CDROM, readOnly=True, transient=True) self.install_devices.append(disk)
def generate_clone_disk_path(origpath, design): basename = origpath suffix = "" # Try to split the suffix off the existing disk name. Ex. # foobar.img -> foobar-clone.img # # If the suffix is greater than 7 characters, assume it isn't # a file extension and is part of the disk name, at which point # just stick '-clone' on the end. if basename.count(".") and len(basename.rsplit(".", 1)[1]) <= 7: basename, suffix = basename.rsplit(".", 1) suffix = "." + suffix return _util.generate_name(basename + "-clone", lambda p: VirtualDisk.path_exists(design.original_conn, p), suffix, lib_collision=False)
def set_clone_devices(self, devpath): # Devices here is a string path. Every call to set_clone_devices # Adds the path (if valid) to the internal _clone_devices list disklist = [] is_list, pathlist = _listify(devpath) # Check path is valid for path in pathlist: try: device = VirtualDisk.DEVICE_DISK if not path: device = VirtualDisk.DEVICE_CDROM disk = VirtualDisk(path, size=.0000001, conn=self._hyper_conn, device=device) disklist.append(disk) except Exception, e: raise ValueError(_("Could not use path '%s' for cloning: %s") % (path, str(e)))
def set_location(self, val): """ Valid values for location: 1) it can be a local file (ex. boot.iso), directory (ex. distro tree) or physical device (ex. cdrom media) 2) tuple of the form (poolname, volname) pointing to a file or device which will set location as that path 3) http, ftp, or nfs path for an install tree """ is_tuple = False validated = True self._location_is_path = True is_local = (not self.conn or not _util.is_uri_remote(self.conn.getURI())) # Basic validation if type(val) is not str and (type(val) is not tuple and len(val) != 2): raise ValueError(_("Invalid 'location' type %s." % type(val))) if type(val) is tuple and len(val) == 2: logging.debug("DistroInstaller location is a (poolname, volname)" " tuple") if not self.conn: raise ValueError( _("'conn' must be specified if 'location' is" " a storage tuple.")) is_tuple = True elif _is_url(val, is_local): val = _sanitize_url(val) self._location_is_path = False logging.debug("DistroInstaller location is a network source.") elif os.path.exists(os.path.abspath(val)) and is_local: val = os.path.abspath(val) logging.debug("DistroInstaller location is a local " "file/path: %s" % val) else: # Didn't determine anything about the location validated = False if self._location_is_path or (validated == False and self.conn and _util.is_storage_capable(self.conn)): # If user passed a storage tuple, OR # We couldn't determine the location type and a storage capable # connection was passed: # Pass the parameters off to VirtualDisk to validate, and pull # out the path stuple = (is_tuple and val) or None path = (not is_tuple and val) or None try: d = VirtualDisk(path=path, device=VirtualDisk.DEVICE_CDROM, transient=True, readOnly=True, conn=self.conn, volName=stuple) val = d.path except Exception, e: logging.debug(str(e)) raise ValueError( _("Checking installer location failed: " "Could not find media '%s'." % str(val)))
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