class BackupConfig(properties.Owner): backup_id = properties.String(required=True) from_checkpoint_id = properties.String(required='') to_checkpoint_id = properties.String(default='') def __init__(self, backup_config): self.backup_id = backup_config.get("backup_id") self.from_checkpoint_id = backup_config.get("from_checkpoint_id") self.to_checkpoint_id = backup_config.get("to_checkpoint_id") self.disks = [DiskConfig(d) for d in backup_config.get("disks", ())]
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 CheckpointConfig(properties.Owner): id = properties.UUID(required=True) xml = properties.String(required=True) def __init__(self, checkpoint_config): self.id = checkpoint_config.get("id") self.xml = checkpoint_config.get("xml")
class ScratchDiskConfig(properties.Owner): path = properties.String(required=True) type = properties.Enum(required=True, values=[DISK_TYPE.FILE, DISK_TYPE.BLOCK]) def __init__(self, **kw): self.path = kw.get("path") self.type = kw.get("type")
class ScratchDiskConfig(properties.Owner): path = properties.String(required=True) type = properties.Enum(required=True, values=[DISK_TYPE.FILE, DISK_TYPE.BLOCK]) sd_id = properties.UUID(required=False) img_id = properties.UUID(required=False) vol_id = properties.UUID(required=False) def __init__(self, **kw): self.path = kw.get("path") self.type = kw.get("type") self.sd_id = kw.get("sd_id") self.img_id = kw.get("img_id") self.vol_id = kw.get("vol_id")
class CheckpointConfig(properties.Owner): id = properties.UUID(required=True) xml = properties.String() def __init__(self, checkpoint_config): self.id = checkpoint_config.get("id") self.xml = checkpoint_config.get("xml") if "config" in checkpoint_config: self.config = BackupConfig(checkpoint_config["config"]) else: self.config = None if self.config is None and self.xml is None: raise exception.CheckpointError( reason="Cannot redefine checkpoint without " "checkpoint XML or backup config", checkpoint_id=self.id)
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 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.String(required=True) def __init__(self, value=None): self.value = value
class Cls(properties.Owner): value = properties.String()
class CopyDataExternalEndpoint(properties.Owner): """ CopyDataExternalEndpoint represents endpoints for volumes not managed by vdsm, such as Managed Block Storage volumes. """ url = properties.String(required=True) generation = properties.Integer(required=False, minval=0, maxval=sc.MAX_GENERATION) format = properties.String(required=True) sparse = properties.Boolean(required=False) create = properties.Boolean(required=False) is_zero = properties.Boolean(required=True) def __init__(self, params, host_id, job_id): self.lease = validators.Lease(params.get('lease')) self.url = params.get('url') self.generation = params.get('generation') self.format = params.get('format') self.sparse = params.get('sparse', False) self.create = params.get('create', True) self.is_zero = params.get('is_zero', False) self.host_id = host_id self.job_id = job_id @property def locks(self): return [ sd.ExternalLease(self.host_id, self.lease.sd_id, self.lease.lease_id), ] @property def path(self): return self.url def is_invalid_vm_conf_disk(self): return False @property def qemu_format(self): return self.format @property def backing_path(self): return None @property def qcow2_compat(self): return "1.1" @property def backing_qemu_format(self): return None @property def recommends_unordered_writes(self): return self.format == "raw" and not self.sparse @property def requires_create(self): return self.create @property def zero_initialized(self): return self.is_zero @contextmanager def volume_operation(self): dom = sdCache.produce_manifest(self.lease.sd_id) metadata = dom.get_lvb(self.lease.lease_id) log.info("Current lease %s metadata: %r", self.lease.sd_id, metadata) self._validate_metadata(metadata) try: yield except Exception: self._update_metadata(dom, metadata, sc.JOB_STATUS_FAILED) raise self._update_metadata(dom, metadata, sc.JOB_STATUS_SUCCEEDED) @contextmanager def prepare(self): yield def _validate_metadata(self, metadata): if metadata.get("type") != "JOB": raise se.UnsupportedOperation("Metadata type is not support", expected="JOB", actual=metadata.get("type")) if metadata.get("job_id") != self.job_id: raise se.UnsupportedOperation( "job_id on lease doesn't match passed job_id", expected=self.job_id, actual=metadata.get("job_id")) if metadata.get("job_status") != sc.JOB_STATUS_PENDING: raise se.JobStatusMismatch(sc.JOB_STATUS_PENDING, metadata.get("job_status")) if metadata.get("generation") != self.generation: raise se.GenerationMismatch(self.generation, metadata.get("generation")) def _update_metadata(self, dom, metadata, job_status): updated_metadata = metadata.copy() updated_metadata["modified"] = int(time.time()) updated_metadata["host_hardware_id"] = host.uuid() updated_metadata["job_status"] = job_status if job_status == sc.JOB_STATUS_SUCCEEDED: updated_metadata["generation"] = su.next_generation( metadata["generation"]) log.info("Updated lease %s metadata: %r", self.lease.sd_id, updated_metadata) dom.set_lvb(self.lease.lease_id, updated_metadata)