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 VolumeAttributes(properties.Owner): generation = properties.Integer(required=False, minval=0, maxval=sc.MAX_GENERATION) description = properties.String(required=False) def __init__(self, params): self.generation = params.get("generation") self.description = params.get("description") # TODO use properties.Enum when it supports optional enum self.type = params.get("type") # TODO use properties.Enum when it supports optional enum self.legality = params.get("legality") self._validate() def _validate(self): if self._is_empty(): raise ValueError("No attributes to update") self._validate_type() self._validate_legality() def _is_empty(self): return (self.description is None and self.generation is None and self.legality is None and self.type is None) def _validate_type(self): if self.type is not None: if self.type != sc.type2name(sc.SHARED_VOL): raise ValueError("Volume type not supported %s" % self.type) def _validate_legality(self): if self.legality is not None: if self.legality not in [sc.LEGAL_VOL, sc.ILLEGAL_VOL]: raise ValueError("Legality not supported %s" % self.legality) def __repr__(self): values = [ "%s=%r" % (key, value) for key, value in vars(self).items() if value is not None ] return "<VolumeAttributes %s at 0x%x>" % (", ".join(values), id(self))
class Cls(properties.Owner): value = properties.Integer(required=True) def __init__(self, value=None): self.value = value
class Cls(properties.Owner): value = properties.Integer(maxval=100)
class Cls(properties.Owner): value = properties.Integer(minval=0)
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)