def _set_cinder_quotas(self, tenant_id): storage_client = clients.volume_client(self.cloud) return self._set_quotas(storage_client, tenant_id, gigabytes=-1, snapshots=-1, volumes=-1)
def run(self, cfg, migration): cloud = cfg.clouds[getattr(migration, self.location)] network_client = clients.network_client(cloud) compute_client = clients.compute_client(cloud) storage_client = clients.volume_client(cloud) try: if self.net_quota is None: clients.retry(network_client.delete_quota, self.admin_tenant_id) else: clients.retry( network_client.update_quota, self.admin_tenant_id, { 'quota': { 'network': self.net_quota['network'], 'subnet': self.net_quota['subnet'], 'port': self.net_quota['port'], } }) except neutron_exceptions.NotFound: pass if self.compute_quota: clients.retry(compute_client.quotas.update, self.admin_tenant_id, **self.compute_quota) if self.storage_quota: clients.retry(storage_client.quotas.update, self.obj_tenant_id, **self.storage_quota)
def discover_one(self, uuid): volume_client = clients.volume_client(self.cloud) try: volume = self.load_from_cloud( self.retry(volume_client.volumes.get, uuid, expected_exceptions=[cinder_exceptions.NotFound])) with model.Session() as session: session.store(volume) return volume except cinder_exceptions.NotFound: raise discover.NotFound()
def discover_all(self): volumes = [] volume_client = clients.volume_client(self.cloud) for raw_volume in self.retry(volume_client.volumes.list, search_opts={'all_tenants': True}, returns_iterable=True): try: volumes.append(self.load_from_cloud(raw_volume)) except model.ValidationError as e: LOG.warning('Invalid volume %s in cloud %s: %s', raw_volume.id, self.cloud.name, e) with model.Session() as session: for volume in volumes: session.store(volume)
def migrate(self, source_obj, *args, **kwargs): cinder_client = clients.volume_client( self.src_cloud, _scope(source_obj.tenant.object_id.id)) raw_volume = clients.retry(cinder_client.volumes.get, source_obj.object_id.id) if raw_volume.attachments: nova_client = clients.compute_client(self.src_cloud) assert len(raw_volume.attachments) == 1 detached_vm_id = raw_volume.attachments[0]['server_id'] shutoff_vm(nova_client, detached_vm_id) self._detach_volume(self.src_cloud, source_obj, detached_vm_id, abort_migration=True) self.detached_vm_id = detached_vm_id return dict(attached_vm_id=self.detached_vm_id)
def restore_internal_state(self, internal_state): tenant_id = internal_state['tenant_id'] volume_id = internal_state['volume_id'] self.created_object = None if tenant_id is not None and volume_id is not None: volume_client = clients.volume_client(self.dst_cloud, _scope(tenant_id)) try: self.created_object = clients.retry( volume_client.volumes.get, volume_id, expected_exceptions=[cinder_exceptions.NotFound]) except cinder_exceptions.NotFound: LOG.warning( 'Failed to find volume with id %s when restoring ' 'task state', volume_id)
def discover_all(self): volume_client = clients.volume_client(self.cloud) raw_volumes = self.retry(volume_client.volumes.list, search_opts={'all_tenants': True}, returns_iterable=True) attachments = [] for raw_volume in raw_volumes: for raw_attachment in raw_volume.attachments: try: attachment = self.load_from_cloud(raw_attachment) attachments.append(attachment) except model.ValidationError as e: LOG.warning('Invalid attachment %s in cloud %s: %s', raw_attachment['id'], self.cloud.name, e) with model.Session() as session: for attachment in attachments: session.store(attachment)
def _detach_volume(self, cloud, volume, vm_id, abort_migration=False): volume_id = volume.object_id.id nova_client = clients.compute_client(cloud) cinder_client = clients.volume_client( cloud, _scope(volume.tenant.object_id.id)) if _object_is_deleted(cinder_client, 'volumes', volume_id, cinder_exceptions.NotFound): return if _object_status_is(cinder_client, 'volumes', volume_id, 'in-use'): nova_client.volumes.delete_server_volume(vm_id, volume_id) try: clients.wait_for(_object_status_is, cinder_client, 'volumes', volume_id, 'available') except clients.Timeout: if abort_migration: raise base.AbortMigration( 'Volume %s in cloud %s couldn\'t attach', volume_id, cloud.name)
def _attach_volume(self, cloud, volume, vm_id): volume_id = volume.object_id.id nova_client = clients.compute_client(cloud) cinder_client = clients.volume_client( cloud, _scope(volume.tenant.object_id.id)) if _object_status_is(cinder_client, 'volumes', volume_id, 'available'): nova_client.volumes.create_server_volume(vm_id, volume_id, '/dev/vdb') try: clients.wait_for(_object_status_is, cinder_client, 'volumes', volume_id, 'in-use') except clients.Timeout: raise base.AbortMigration( 'Volume %s in cloud %s couldn\'t attach', volume_id, cloud.name) else: raise base.AbortMigration( 'Volume %s in cloud %s is not available for attachment', volume_id, cloud.name)
def _delete_volume(self, vol): tenant_id = getattr(vol, 'os-vol-tenant-attr:tenant_id') volume_client = clients.volume_client(self.dst_cloud, _scope(tenant_id)) try: volume = clients.retry( volume_client.volumes.get, vol.id, expected_exceptions=[cinder_exceptions.NotFound]) if volume.status not in ('available', 'in-use', 'error', 'error_restoring'): clients.retry(volume_client.volumes.reset_state, volume, 'error', expected_exceptions=[cinder_exceptions.NotFound]) clients.retry(volume_client.volumes.delete, volume, expected_exceptions=[cinder_exceptions.NotFound]) except cinder_exceptions.NotFound: LOG.warning('Can not delete cinder volume: already deleted')
def migrate(self, source_obj, *args, **kwargs): dst_tenant_id = _get_object_tenant_id(self.dst_cloud, source_obj) volume_client = clients.volume_client(self.dst_cloud, _scope(dst_tenant_id)) ovr_source_obj = self.override(source_obj) zone = ovr_source_obj.availability_zone vol = clients.retry(volume_client.volumes.create, size=ovr_source_obj.size, display_name=ovr_source_obj.name, display_description=ovr_source_obj.description, volume_type=ovr_source_obj.volume_type, availability_zone=zone, metadata=ovr_source_obj.metadata) try: self.created_object = clients.wait_for(_object_status_is, volume_client, 'volumes', vol.id, 'available') except clients.Timeout: self._delete_volume(vol) raise base.AbortMigration('Volume didn\'t become active') result = self.load_from_cloud(storage.Volume, self.dst_cloud, self.created_object) return dict(dst_object=result)
def volume_client(self, scope=None): # pylint: disable=no-member return clients.volume_client(self.credential, scope or self.scope)