class VolumeInfo(properties.Owner): """ VolumeInfo should be used for performing operations on any volume in a chain except shared volume. A volume is prepared in read-write mode. While performing operations, the volume is not set as illegal. """ sd_id = properties.UUID(required=True) img_id = properties.UUID(required=True) vol_id = properties.UUID(required=True) generation = properties.Integer(required=False, minval=0, maxval=sc.MAX_GENERATION) def __init__(self, params, host_id): self.sd_id = params.get('sd_id') self.img_id = params.get('img_id') self.vol_id = params.get('vol_id') self.generation = params.get('generation') self._host_id = host_id self._vol = None @property def locks(self): img_ns = rm.getNamespace(sc.IMAGE_NAMESPACE, self.sd_id) ret = [ rm.ResourceManagerLock(sc.STORAGE, self.sd_id, rm.SHARED), rm.ResourceManagerLock(img_ns, self.img_id, rm.EXCLUSIVE) ] dom = sdCache.produce_manifest(self.sd_id) if dom.hasVolumeLeases(): ret.append( volume.VolumeLease(self._host_id, self.sd_id, self.img_id, self.vol_id)) return ret @property def path(self): return self.volume.getVolumePath() @property def volume(self): if self._vol is None: dom = sdCache.produce_manifest(self.sd_id) self._vol = dom.produceVolume(self.img_id, self.vol_id) return self._vol def volume_operation(self): return self.volume.operation(requested_gen=self.generation, set_illegal=False) @contextmanager def prepare(self): self.volume.prepare(rw=True, justme=False) try: yield finally: self.volume.teardown(self.sd_id, self.vol_id, justme=False)
class Lease(properties.Owner): """ External sanlock lease. """ sd_id = properties.UUID(required=True) lease_id = properties.UUID(required=True) def __init__(self, params): self.sd_id = params.get("sd_id") self.lease_id = params.get("lease_id")
class StorageDomainReduceParams(properties.Owner): sd_id = properties.UUID(required=True) guid = properties.String(required=True) def __init__(self, params): self.sd_id = params.get('sd_id') self.guid = params.get('guid')
class CopyDataDivEndpoint(properties.Owner): sd_id = properties.UUID(required=True) img_id = properties.UUID(required=True) vol_id = properties.UUID(required=True) def __init__(self, params): self.sd_id = params.get('sd_id') self.img_id = params.get('img_id') self.vol_id = params.get('vol_id') self._vol = None @property def path(self): return self._vol.getVolumePath() @property def qemu_format(self): # TODO: Use Image._detect_format to handle broken VM md images. return sc.fmt2str(self._vol.getFormat()) @property def backing_path(self): parent_vol = self._vol.getParentVolume() if not parent_vol: return None return volume.getBackingVolumePath(self.img_id, parent_vol.volUUID) @property def backing_qemu_format(self): parent_vol = self._vol.getParentVolume() if not parent_vol: return None return sc.fmt2str(parent_vol.getFormat()) @contextmanager def prepare(self, writable=False): dom = sdCache.produce_manifest(self.sd_id) self._vol = dom.produceVolume(self.img_id, self.vol_id) self._vol.prepare(rw=writable, justme=True) try: yield finally: self._vol.teardown(self.sd_id, self.vol_id, justme=True)
class SealImageInfo(properties.Owner): sd_id = properties.UUID(required=True) img_id = properties.UUID(required=True) vol_id = properties.UUID(required=True) def __init__(self, params, sp_id, irs): self.sd_id = params.get('sd_id') self.img_id = params.get('img_id') self.vol_id = params.get('vol_id') self._sp_id = sp_id self._irs = irs self._path = None @property def path(self): return self._path def prepare(self): res = self._irs.prepareImage(self.sd_id, self._sp_id, self.img_id, self.vol_id, allowIllegal=True) if res['status']['code']: raise ImagePreparingError("Cannot prepare image %s: %s" % (self, res['status']['message'])) self._path = res['path'] def teardown(self): res = self._irs.teardownImage(self.sd_id, self._sp_id, self.img_id) if res['status']['code']: raise ImageTearingDownError("Cannot tear down image %s: %s" % (self, res['status']['message'])) def __repr__(self): return ("<%s sd_id=%s img_id=%s vol_id=%s at 0x%s>" % (self.__class__.__name__, self.sd_id, self.img_id, self.vol_id, id(self)))
class StorageDomainDeviceMoveParams(properties.Owner): sd_id = properties.UUID(required=True) src_guid = properties.String(required=True) def __init__(self, params): self.sd_id = params.get('sd_id') self.src_guid = params.get('src_guid') dst_guids = params.get('dst_guids') or [] # TODO: using properties.List for dst_guids when it is available self.dst_guids = frozenset(dst_guids) if type(dst_guids) is not list: raise ValueError("dst_guids is not a list") for item in dst_guids: if not isinstance(item, six.string_types): raise ValueError("dst_guids item %s isn't a string" % item) if len(self.dst_guids) != len(dst_guids): raise ValueError("dst_guids contains duplicate values") if self.src_guid in self.dst_guids: raise ValueError("src_guid is in dst_guids")
class Cls(properties.Owner): value = properties.UUID(required=True)
class Cls(properties.Owner): value = properties.UUID(default="00000000-0000-0000-0000-000000000000")
class CopyDataDivEndpoint(properties.Owner): sd_id = properties.UUID(required=True) img_id = properties.UUID(required=True) vol_id = properties.UUID(required=True) generation = properties.Integer(required=False, minval=0, maxval=sc.MAX_GENERATION) def __init__(self, params, host_id, writable): self.sd_id = params.get('sd_id') self.img_id = params.get('img_id') self.vol_id = params.get('vol_id') self.generation = params.get('generation') self._host_id = host_id self._writable = writable self._vol = None @property def locks(self): img_ns = rm.getNamespace(sc.IMAGE_NAMESPACE, self.sd_id) mode = rm.EXCLUSIVE if self._writable else rm.SHARED ret = [ rm.ResourceManagerLock(sc.STORAGE, self.sd_id, rm.SHARED), rm.ResourceManagerLock(img_ns, self.img_id, mode) ] if self._writable: dom = sdCache.produce_manifest(self.sd_id) if dom.hasVolumeLeases(): ret.append( volume.VolumeLease(self._host_id, self.sd_id, self.img_id, self.vol_id)) return ret @property def path(self): return self.volume.getVolumePath() def is_invalid_vm_conf_disk(self): return workarounds.invalid_vm_conf_disk(self.volume) @property def qemu_format(self): return sc.fmt2str(self.volume.getFormat()) @property def backing_path(self): parent_vol = self.volume.getParentVolume() if not parent_vol: return None return volume.getBackingVolumePath(self.img_id, parent_vol.volUUID) @property def qcow2_compat(self): dom = sdCache.produce_manifest(self.sd_id) return dom.qcow2_compat() @property def backing_qemu_format(self): parent_vol = self.volume.getParentVolume() if not parent_vol: return None return sc.fmt2str(parent_vol.getFormat()) @property def volume(self): if self._vol is None: dom = sdCache.produce_manifest(self.sd_id) self._vol = dom.produceVolume(self.img_id, self.vol_id) return self._vol def volume_operation(self): return self.volume.operation(self.generation) @contextmanager def prepare(self): self.volume.prepare(rw=self._writable, justme=False) try: yield finally: self.volume.teardown(self.sd_id, self.vol_id, justme=False)