def test_create_backup(self): # Prioritize glance v2 over v1 for deleting/waiting for image status. if CONF.image_feature_enabled.api_v2: glance_admin_client = self.os_admin.image_client_v2 elif CONF.image_feature_enabled.api_v1: glance_admin_client = self.os_admin.image_client else: raise lib_exc.InvalidConfiguration( 'Either api_v1 or api_v2 must be True in ' '[image-feature-enabled].') backup_name = data_utils.rand_name(self.__class__.__name__ + '-Backup') self.rbac_utils.switch_role(self, toggle_rbac_role=True) resp = self.servers_client.create_backup(self.server_id, backup_type='daily', rotation=1, name=backup_name).response # Prior to microversion 2.45, image ID must be parsed from location # header. With microversion 2.45+, image_id is returned. if api_version_utils.compare_version_header_to_response( "OpenStack-API-Version", "2.45", resp, "lt"): image_id = resp['image_id'] else: image_id = data_utils.parse_image_id(resp['location']) # Use admin credentials to wait since waiting involves show, which is # a different policy. self.addCleanup(test_utils.call_and_ignore_notfound_exc, glance_admin_client.delete_image, image_id) waiters.wait_for_image_status(glance_admin_client, image_id, 'active')
def test_wait_for_image_status(self): self.client.show_image.return_value = ({'status': 'active'}) start_time = int(time.time()) waiters.wait_for_image_status(self.client, 'fake_image_id', 'active') end_time = int(time.time()) # Ensure waiter returns before build_timeout self.assertTrue((end_time - start_time) < 10)
def test_wait_for_image_status(self): self.client.show_image.return_value = ({'status': 'active'}) start_time = int(time.time()) waiters.wait_for_image_status(self.client, 'fake_image_id', 'active') end_time = int(time.time()) # Ensure waiter returns before build_timeout self.assertLess((end_time - start_time), 10)
def test_create_volume_from_image_with_decreasing_size(self): # Create image image_name = data_utils.rand_name(self.__class__.__name__ + "-image") image = self.images_client.create_image( name=image_name, container_format=CONF.image.container_formats[0], disk_format=CONF.image.disk_formats[0], visibility='private', min_disk=CONF.volume.volume_size + 1) self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.images_client.delete_image, image['id']) # Upload image with 1KB data image_file = six.BytesIO(data_utils.random_bytes()) self.images_client.store_image_file(image['id'], image_file) waiters.wait_for_image_status(self.images_client, image['id'], 'active') # Note(jeremyZ): To shorten the test time (uploading a big size image # is time-consuming), here just consider the scenario that volume size # is smaller than the min_disk of image. self.assertRaises(lib_exc.BadRequest, self.volumes_client.create_volume, size=CONF.volume.volume_size, imageRef=image['id'])
def _create_image(): params = { 'name': data_utils.rand_name(cls.__name__ + '-image'), 'container_format': 'bare', 'disk_format': 'raw' } if CONF.image_feature_enabled.api_v1: params.update({'is_public': False}) params = { 'headers': common_image.image_meta_to_headers(**params) } else: params.update({'visibility': 'private'}) body = cls.glance_client.create_image(**params) body = body['image'] if 'image' in body else body image_id = body['id'] cls.images.append(image_id) # Wait 1 second between creation and upload to ensure a delta # between created_at and updated_at. time.sleep(1) image_file = six.BytesIO((b'*' * 1024)) if CONF.image_feature_enabled.api_v1: cls.glance_client.update_image(image_id, data=image_file) else: cls.glance_client.store_image_file(image_id, data=image_file) waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE') body = cls.client.show_image(image_id)['image'] return body
def test_create_delete_image(self): # Create a new image name = data_utils.rand_name('image') meta = {'image_type': 'test'} body = self.client.create_image(self.server_id, name=name, metadata=meta) image_id = data_utils.parse_image_id(body.response['location']) waiters.wait_for_image_status(self.client, image_id, 'ACTIVE') # Verify the image was created correctly image = self.client.show_image(image_id)['image'] self.assertEqual(name, image['name']) self.assertEqual('test', image['metadata']['image_type']) original_image = self.client.show_image(self.image_ref)['image'] # Verify minRAM is the same as the original image self.assertEqual(image['minRam'], original_image['minRam']) # Verify minDisk is the same as the original image or the flavor size flavor_disk_size = self._get_default_flavor_disk_size(self.flavor_ref) self.assertIn(str(image['minDisk']), (str(original_image['minDisk']), str(flavor_disk_size))) # Verify the image was deleted correctly self.client.delete_image(image_id) self.client.wait_for_resource_deletion(image_id)
def resource_setup(cls): super(ImagesMetadataTestJSON, cls).resource_setup() cls.image_id = None params = { 'name': data_utils.rand_name('image'), 'container_format': 'bare', 'disk_format': 'raw' } if CONF.image_feature_enabled.api_v1: params.update({'is_public': False}) params = {'headers': common_image.image_meta_to_headers(**params)} else: params.update({'visibility': 'private'}) body = cls.glance_client.create_image(**params) body = body['image'] if 'image' in body else body cls.image_id = body['id'] cls.images.append(cls.image_id) image_file = six.BytesIO((b'*' * 1024)) if CONF.image_feature_enabled.api_v1: cls.glance_client.update_image(cls.image_id, data=image_file) else: cls.glance_client.store_image_file(cls.image_id, data=image_file) waiters.wait_for_image_status(cls.client, cls.image_id, 'ACTIVE')
def test_create_delete_image(self): # Create a new image name = data_utils.rand_name('image') meta = {'image_type': 'test'} body = self.client.create_image(self.server_id, name=name, metadata=meta) image_id = data_utils.parse_image_id(body.response['location']) waiters.wait_for_image_status(self.client, image_id, 'ACTIVE') # Verify the image was created correctly image = self.client.show_image(image_id) self.assertEqual(name, image['name']) self.assertEqual('test', image['metadata']['image_type']) original_image = self.client.show_image(self.image_ref) # Verify minRAM is the same as the original image self.assertEqual(image['minRam'], original_image['minRam']) # Verify minDisk is the same as the original image or the flavor size flavor_disk_size = self._get_default_flavor_disk_size(self.flavor_ref) self.assertIn(str(image['minDisk']), (str(original_image['minDisk']), str(flavor_disk_size))) # Verify the image was deleted correctly self.client.delete_image(image_id) self.client.wait_for_resource_deletion(image_id)
def test_create_delete_image(self): # Create a new image name = data_utils.rand_name("image") meta = {"image_type": "test"} body = self.client.create_image(self.server_id, name, meta) image_id = data_utils.parse_image_id(body.response["location"]) waiters.wait_for_image_status(self.client, image_id, "ACTIVE") # Verify the image was created correctly image = self.client.show_image(image_id) self.assertEqual(name, image["name"]) self.assertEqual("test", image["metadata"]["image_type"]) original_image = self.client.show_image(self.image_ref) # Verify minRAM is the same as the original image self.assertEqual(image["minRam"], original_image["minRam"]) # Verify minDisk is the same as the original image or the flavor size flavor_disk_size = self._get_default_flavor_disk_size(self.flavor_ref) self.assertIn(str(image["minDisk"]), (str(original_image["minDisk"]), str(flavor_disk_size))) # Verify the image was deleted correctly self.client.delete_image(image_id) self.client.wait_for_resource_deletion(image_id)
def _create_image(): params = { 'name': data_utils.rand_name(cls.__name__ + '-image'), 'container_format': 'bare', 'disk_format': 'raw' } if CONF.image_feature_enabled.api_v1: params.update({'is_public': False}) params = {'headers': common_image.image_meta_to_headers(**params)} else: params.update({'visibility': 'private'}) body = cls.glance_client.create_image(**params) body = body['image'] if 'image' in body else body image_id = body['id'] cls.addClassResourceCleanup( test_utils.call_and_ignore_notfound_exc, cls.compute_images_client.delete_image, image_id) # Wait 1 second between creation and upload to ensure a delta # between created_at and updated_at. time.sleep(1) image_file = six.BytesIO((b'*' * 1024)) if CONF.image_feature_enabled.api_v1: cls.glance_client.update_image(image_id, data=image_file) else: cls.glance_client.store_image_file(image_id, data=image_file) waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE') body = cls.client.show_image(image_id)['image'] return body
def _create_image(): params = { 'name': data_utils.rand_name('image'), 'container_format': 'bare', 'disk_format': 'raw' } if CONF.image_feature_enabled.api_v1: params.update({'is_public': False}) params = {'headers': common_image.image_meta_to_headers(**params)} else: params.update({'visibility': 'private'}) body = cls.glance_client.create_image(**params) body = body['image'] if 'image' in body else body image_id = body['id'] cls.images.append(image_id) # Wait 1 second between creation and upload to ensure a delta # between created_at and updated_at. time.sleep(1) image_file = six.StringIO(('*' * 1024)) if CONF.image_feature_enabled.api_v1: cls.glance_client.update_image(image_id, data=image_file) else: cls.glance_client.store_image_file(image_id, data=image_file) waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE') body = cls.client.show_image(image_id)['image'] return body
def _create_image(): params = { "name": data_utils.rand_name(cls.__name__ + "-image"), "container_format": "bare", "disk_format": "raw", } if CONF.image_feature_enabled.api_v1: params.update({"is_public": False}) params = {"headers": common_image.image_meta_to_headers(**params)} else: params.update({"visibility": "private"}) body = cls.glance_client.create_image(**params) body = body["image"] if "image" in body else body image_id = body["id"] cls.images.append(image_id) # Wait 1 second between creation and upload to ensure a delta # between created_at and updated_at. time.sleep(1) image_file = six.BytesIO((b"*" * 1024)) if CONF.image_feature_enabled.api_v1: cls.glance_client.update_image(image_id, data=image_file) else: cls.glance_client.store_image_file(image_id, data=image_file) waiters.wait_for_image_status(cls.client, image_id, "ACTIVE") body = cls.client.show_image(image_id)["image"] return body
def test_register_http_image(self): container_format, disk_format = get_container_and_disk_format() image = self.create_image(name='New Http Image', container_format=container_format, disk_format=disk_format, is_public=False, copy_from=CONF.image.http_image) self.assertEqual('New Http Image', image.get('name')) self.assertFalse(image.get('is_public')) waiters.wait_for_image_status(self.client, image['id'], 'active') self.client.show_image(image['id'])
def test_volume_upload(self): # NOTE(gfidente): the volume uploaded in Glance comes from setUpClass, # it is shared with the other tests. After it is uploaded in Glance, # there is no way to delete it from Cinder, so we delete it from Glance # using the Glance image_client and from Cinder via tearDownClass. image_name = data_utils.rand_name(self.__class__.__name__ + "-Image") body = self.client.upload_volume(self.volume["id"], image_name=image_name, disk_format=CONF.volume.disk_format)[ "os-volume_upload_image" ] image_id = body["image_id"] self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.image_client.delete_image, image_id) waiters.wait_for_image_status(self.image_client, image_id, "active") waiters.wait_for_volume_status(self.client, self.volume["id"], "available")
def test_volume_upload(self): # NOTE(gfidente): the volume uploaded in Glance comes from setUpClass, # it is shared with the other tests. After it is uploaded in Glance, # there is no way to delete it from Cinder, so we delete it from Glance # using the Glance image_client and from Cinder via tearDownClass. image_name = data_utils.rand_name('Image') body = self.client.upload_volume( self.volume['id'], image_name=image_name, disk_format=CONF.volume.disk_format)['os-volume_upload_image'] image_id = body["image_id"] self.addCleanup(self._cleanup_image, image_id) waiters.wait_for_image_status(self.image_client, image_id, 'active') waiters.wait_for_volume_status(self.client, self.volume['id'], 'available')
def resource_setup(cls): super(ImagesMetadataTestJSON, cls).resource_setup() cls.image_id = None name = data_utils.rand_name('image') body = cls.glance_client.create_image(name=name, container_format='bare', disk_format='raw', is_public=False)['image'] cls.image_id = body['id'] cls.images.append(cls.image_id) image_file = six.StringIO(('*' * 1024)) cls.glance_client.update_image(cls.image_id, data=image_file) waiters.wait_for_image_status(cls.client, cls.image_id, 'ACTIVE')
def upload_volume(self, volume): image_name = data_utils.rand_name(self.__class__.__name__ + '-Image') body = self.volumes_client.upload_volume( volume['id'], image_name=image_name, disk_format=CONF.volume.disk_format)['os-volume_upload_image'] image_id = body['image_id'] self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.compute_images_client.delete_image, image_id) waiters.wait_for_image_status(self.compute_images_client, image_id, 'ACTIVE') waiters.wait_for_volume_resource_status(self.volumes_client, self.volume['id'], 'available') return image_id
def _create_image(): name = data_utils.rand_name('image') body = cls.glance_client.create_image(name=name, container_format='bare', disk_format='raw', is_public=False) image_id = body['id'] cls.images.append(image_id) # Wait 1 second between creation and upload to ensure a delta # between created_at and updated_at. time.sleep(1) image_file = six.StringIO(('*' * 1024)) cls.glance_client.update_image(image_id, data=image_file) waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE') body = cls.client.show_image(image_id) return body
def test_volume_upload_public(self): # This also enforces "volume_extension:volume_actions:upload_image". image_name = data_utils.rand_name(self.__class__.__name__ + '-Image') with self.override_role(): body = self.volumes_client.upload_volume( self.volume['id'], image_name=image_name, visibility="public", disk_format=CONF.volume.disk_format)['os-volume_upload_image'] image_id = body["image_id"] self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.image_client.delete_image, image_id) waiters.wait_for_image_status(self.image_client, image_id, 'active') waiters.wait_for_volume_resource_status(self.volumes_client, self.volume['id'], 'available')
def _create_image(): name = data_utils.rand_name('image') body = cls.glance_client.create_image(name=name, container_format='bare', disk_format='raw', is_public=False)['image'] image_id = body['id'] cls.images.append(image_id) # Wait 1 second between creation and upload to ensure a delta # between created_at and updated_at. time.sleep(1) image_file = six.StringIO(('*' * 1024)) cls.glance_client.update_image(image_id, data=image_file) waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE') body = cls.client.show_image(image_id)['image'] return body
def create_server_snapshot(self, server, name=None): # Glance client _image_client = self.image_client # Compute client _images_client = self.compute_images_client if name is None: name = data_utils.rand_name(self.__class__.__name__ + 'snapshot') LOG.debug("Creating a snapshot image for server: {}" .format(server['name'])) image = _images_client.create_image(server['id'], name=name) image_id = image.response['location'].split('images/')[1] waiters.wait_for_image_status(_image_client, image_id, 'active') self.addCleanup(_image_client.wait_for_resource_deletion, image_id) self.addCleanup(test_utils.call_and_ignore_notfound_exc, _image_client.delete_image, image_id) if CONF.image_feature_enabled.api_v1: # In glance v1 the additional properties are stored in the headers. resp = _image_client.check_image(image_id) snapshot_image = common_image.get_image_meta_from_headers(resp) image_props = snapshot_image.get('properties', {}) else: # In glance v2 the additional properties are flattened. snapshot_image = _image_client.show_image(image_id) image_props = snapshot_image bdm = image_props.get('block_device_mapping') if bdm: bdm = json.loads(bdm) if bdm and 'snapshot_id' in bdm[0]: snapshot_id = bdm[0]['snapshot_id'] self.addCleanup( self.snapshots_client.wait_for_resource_deletion, snapshot_id) self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.snapshots_client.delete_snapshot, snapshot_id) waiters.wait_for_volume_resource_status(self.snapshots_client, snapshot_id, 'available') image_name = snapshot_image['name'] self.assertEqual(name, image_name) LOG.debug("Created snapshot image {} for server {}" .format(image_name, server['name'])) return snapshot_image
def create_image_from_server(cls, server_id, **kwargs): """Wrapper utility that returns an image created from the server.""" name = kwargs.pop('name', data_utils.rand_name(cls.__name__ + "-image")) wait_until = kwargs.pop('wait_until', None) wait_for_server = kwargs.pop('wait_for_server', True) image = cls.compute_images_client.create_image(server_id, name=name, **kwargs) if api_version_utils.compare_version_header_to_response( "OpenStack-API-Version", "compute 2.45", image.response, "lt"): image_id = image['image_id'] else: image_id = data_utils.parse_image_id(image.response['location']) cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc, cls.compute_images_client.delete_image, image_id) if wait_until is not None: try: waiters.wait_for_image_status(cls.compute_images_client, image_id, wait_until) except lib_exc.NotFound: if wait_until.upper() == 'ACTIVE': # If the image is not found after create_image returned # that means the snapshot failed in nova-compute and nova # deleted the image. There should be a compute fault # recorded with the server in that case, so get the server # and dump some details. server = ( cls.servers_client.show_server(server_id)['server']) if 'fault' in server: raise exceptions.SnapshotNotFoundException( server['fault'], image_id=image_id) else: raise exceptions.SnapshotNotFoundException( image_id=image_id) else: raise image = cls.compute_images_client.show_image(image_id)['image'] if wait_until.upper() == 'ACTIVE': if wait_for_server: waiters.wait_for_server_status(cls.servers_client, server_id, 'ACTIVE') return image
def test_volume_upload_image(self): # TODO(felipemonteiro): The ``upload_volume`` endpoint also enforces # "volume:copy_volume_to_image". image_name = data_utils.rand_name(self.__class__.__name__ + '-Image') with self.override_role(): body = self.volumes_client.upload_volume( self.volume['id'], image_name=image_name, visibility="private", disk_format=CONF.volume.disk_format)['os-volume_upload_image'] image_id = body["image_id"] self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.image_client.delete_image, image_id) waiters.wait_for_image_status(self.image_client, image_id, 'active') waiters.wait_for_volume_resource_status(self.volumes_client, self.volume['id'], 'available')
def test_volume_upload(self): # TODO(felipemonteiro): The ``upload_volume`` endpoint also enforces # "volume:copy_volume_to_image" but is not currently contained in # Cinder's policy.json. image_name = data_utils.rand_name(self.__class__.__name__ + '-Image') self.rbac_utils.switch_role(self, toggle_rbac_role=True) body = self.volumes_client.upload_volume( self.volume['id'], image_name=image_name, visibility="private", disk_format=CONF.volume.disk_format)['os-volume_upload_image'] image_id = body["image_id"] self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.image_client.delete_image, image_id) waiters.wait_for_image_status(self.image_client, image_id, 'active') waiters.wait_for_volume_resource_status(self.os_admin.volumes_client, self.volume['id'], 'available')
def create_image_from_server(cls, server_id, **kwargs): """Wrapper utility that returns an image created from the server.""" name = data_utils.rand_name(cls.__name__ + "-image") if "name" in kwargs: name = kwargs.pop("name") image = cls.images_client.create_image(server_id, name=name) image_id = data_utils.parse_image_id(image.response["location"]) cls.images.append(image_id) if "wait_until" in kwargs: waiters.wait_for_image_status(cls.images_client, image_id, kwargs["wait_until"]) image = cls.images_client.show_image(image_id) if kwargs["wait_until"] == "ACTIVE": if kwargs.get("wait_for_server", True): waiters.wait_for_server_status(cls.servers_client, server_id, "ACTIVE") return image
def create_image(self): # Create image image_name = data_utils.rand_name(self.__class__.__name__ + "-image") image = self.images_client.create_image( name=image_name, container_format=CONF.image.container_formats[0], disk_format=CONF.image.disk_formats[0], visibility='private', min_disk=CONF.volume.volume_size + 1) self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.images_client.delete_image, image['id']) # Upload image with 1KB data image_file = six.BytesIO(data_utils.random_bytes()) self.images_client.store_image_file(image['id'], image_file) waiters.wait_for_image_status(self.images_client, image['id'], 'active') return image
def test_volume_upload(self): # NOTE(gfidente): the volume uploaded in Glance comes from setUpClass, # it is shared with the other tests. After it is uploaded in Glance, # there is no way to delete it from Cinder, so we delete it from Glance # using the Glance images_client and from Cinder via tearDownClass. image_name = data_utils.rand_name(self.__class__.__name__ + '-Image') body = self.volumes_client.upload_volume( self.volume['id'], image_name=image_name, disk_format=CONF.volume.disk_format)['os-volume_upload_image'] image_id = body["image_id"] self.addCleanup(test_utils.call_and_ignore_notfound_exc, self.images_client.delete_image, image_id) waiters.wait_for_image_status(self.images_client, image_id, 'active') waiters.wait_for_volume_resource_status(self.volumes_client, self.volume['id'], 'available') image_info = self.images_client.show_image(image_id) self.assertEqual(image_name, image_info['name']) self.assertEqual(CONF.volume.disk_format, image_info['disk_format'])
def create_image_with_data(cls, **kwargs): # we do this as a class method so we can use the # addClassResourceCleanup functionality of tempest.test.BaseTestCase images_client = cls.os_primary.image_client_v2 if 'min_disk' not in kwargs: kwargs['min_disk'] = 1 response = images_client.create_image(**kwargs) image_id = response['id'] cls.addClassResourceCleanup(images_client.wait_for_resource_deletion, image_id) cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc, images_client.delete_image, image_id) # upload "data" to image image_file = io.BytesIO(data_utils.random_bytes(size=1024)) images_client.store_image_file(image_id, image_file) waiters.wait_for_image_status(images_client, image_id, 'active') image = images_client.show_image(image_id) return image
def create_image_from_server(cls, server_id, **kwargs): """Wrapper utility that returns an image created from the server.""" name = data_utils.rand_name(cls.__name__ + "-image") if 'name' in kwargs: name = kwargs.pop('name') image = cls.compute_images_client.create_image(server_id, name=name) image_id = data_utils.parse_image_id(image.response['location']) cls.images.append(image_id) if 'wait_until' in kwargs: waiters.wait_for_image_status(cls.compute_images_client, image_id, kwargs['wait_until']) image = cls.compute_images_client.show_image(image_id)['image'] if kwargs['wait_until'] == 'ACTIVE': if kwargs.get('wait_for_server', True): waiters.wait_for_server_status(cls.servers_client, server_id, 'ACTIVE') return image
def create_image_from_server(cls, server_id, **kwargs): """Wrapper utility that returns an image created from the server.""" name = data_utils.rand_name(cls.__name__ + "-image") if 'name' in kwargs: name = kwargs.pop('name') image = cls.images_client.create_image(server_id, name) image_id = data_utils.parse_image_id(image.response['location']) cls.images.append(image_id) if 'wait_until' in kwargs: waiters.wait_for_image_status(cls.images_client, image_id, kwargs['wait_until']) image = cls.images_client.show_image(image_id) if kwargs['wait_until'] == 'ACTIVE': if kwargs.get('wait_for_server', True): waiters.wait_for_server_status(cls.servers_client, server_id, 'ACTIVE') return image
def create_image_from_server(cls, server_id, **kwargs): """Wrapper utility that returns an image created from the server.""" name = kwargs.pop('name', data_utils.rand_name(cls.__name__ + "-image")) wait_until = kwargs.pop('wait_until', None) wait_for_server = kwargs.pop('wait_for_server', True) image = cls.compute_images_client.create_image(server_id, name=name, **kwargs) image_id = data_utils.parse_image_id(image.response['location']) cls.images.append(image_id) if wait_until is not None: try: waiters.wait_for_image_status(cls.compute_images_client, image_id, wait_until) except lib_exc.NotFound: if wait_until.upper() == 'ACTIVE': # If the image is not found after create_image returned # that means the snapshot failed in nova-compute and nova # deleted the image. There should be a compute fault # recorded with the server in that case, so get the server # and dump some details. server = ( cls.servers_client.show_server(server_id)['server']) if 'fault' in server: raise exceptions.SnapshotNotFoundException( server['fault'], image_id=image_id) else: raise exceptions.SnapshotNotFoundException( image_id=image_id) else: raise image = cls.compute_images_client.show_image(image_id)['image'] if wait_until.upper() == 'ACTIVE': if wait_for_server: waiters.wait_for_server_status(cls.servers_client, server_id, 'ACTIVE') return image
def resource_setup(cls): super(ImagesMetadataTestJSON, cls).resource_setup() cls.image_id = None name = data_utils.rand_name('image') if CONF.image_feature_enabled.api_v1: kwargs = dict(is_public=False) else: kwargs = dict(visibility='private') body = cls.glance_client.create_image(name=name, container_format='bare', disk_format='raw', **kwargs) body = body['image'] if 'image' in body else body cls.image_id = body['id'] cls.images.append(cls.image_id) image_file = six.StringIO(('*' * 1024)) if CONF.image_feature_enabled.api_v1: cls.glance_client.update_image(cls.image_id, data=image_file) else: cls.glance_client.store_image_file(cls.image_id, data=image_file) waiters.wait_for_image_status(cls.client, cls.image_id, 'ACTIVE')
def create_image_from_server(cls, server_id, **kwargs): """Wrapper utility that returns an image created from the server.""" name = data_utils.rand_name(cls.__name__ + "-image") if 'name' in kwargs: name = kwargs.pop('name') image = cls.compute_images_client.create_image(server_id, name=name) image_id = data_utils.parse_image_id(image.response['location']) cls.images.append(image_id) if 'wait_until' in kwargs: try: waiters.wait_for_image_status(cls.compute_images_client, image_id, kwargs['wait_until']) except lib_exc.NotFound: if kwargs['wait_until'].upper() == 'ACTIVE': # If the image is not found after create_image returned # that means the snapshot failed in nova-compute and nova # deleted the image. There should be a compute fault # recorded with the server in that case, so get the server # and dump some details. server = ( cls.servers_client.show_server(server_id)['server']) if 'fault' in server: raise exceptions.SnapshotNotFoundException( server['fault'], image_id=image_id) else: raise exceptions.SnapshotNotFoundException( image_id=image_id) else: raise image = cls.compute_images_client.show_image(image_id)['image'] if kwargs['wait_until'] == 'ACTIVE': if kwargs.get('wait_for_server', True): waiters.wait_for_server_status(cls.servers_client, server_id, 'ACTIVE') return image
def _create_image(): name = data_utils.rand_name('image') if CONF.image_feature_enabled.api_v1: kwargs = dict(is_public=False) else: kwargs = dict(visibility='private') body = cls.glance_client.create_image(name=name, container_format='bare', disk_format='raw', **kwargs) body = body['image'] if 'image' in body else body image_id = body['id'] cls.images.append(image_id) # Wait 1 second between creation and upload to ensure a delta # between created_at and updated_at. time.sleep(1) image_file = six.StringIO(('*' * 1024)) if CONF.image_feature_enabled.api_v1: cls.glance_client.update_image(image_id, data=image_file) else: cls.glance_client.store_image_file(image_id, data=image_file) waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE') body = cls.client.show_image(image_id)['image'] return body
def test_create_backup(self): # Positive test:create backup successfully and rotate backups correctly # create the first and the second backup # Check if glance v1 is available to determine which client to use. We # prefer glance v1 for the compute API tests since the compute image # API proxy was written for glance v1. if CONF.image_feature_enabled.api_v1: glance_client = self.os_primary.image_client elif CONF.image_feature_enabled.api_v2: glance_client = self.os_primary.image_client_v2 else: raise lib_exc.InvalidConfiguration( 'Either api_v1 or api_v2 must be True in ' '[image-feature-enabled].') backup1 = data_utils.rand_name('backup-1') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup1).response oldest_backup_exist = True # the oldest one should be deleted automatically in this test def _clean_oldest_backup(oldest_backup): if oldest_backup_exist: try: glance_client.delete_image(oldest_backup) except lib_exc.NotFound: pass else: LOG.warning( "Deletion of oldest backup %s should not have " "been successful as it should have been " "deleted during rotation.", oldest_backup) image1_id = data_utils.parse_image_id(resp['location']) self.addCleanup(_clean_oldest_backup, image1_id) waiters.wait_for_image_status(glance_client, image1_id, 'active') backup2 = data_utils.rand_name('backup-2') waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup2).response image2_id = data_utils.parse_image_id(resp['location']) self.addCleanup(glance_client.delete_image, image2_id) waiters.wait_for_image_status(glance_client, image2_id, 'active') # verify they have been created properties = { 'image_type': 'backup', 'backup_type': "daily", 'instance_uuid': self.server_id, } params = { 'status': 'active', 'sort_key': 'created_at', 'sort_dir': 'asc' } if CONF.image_feature_enabled.api_v1: for key, value in properties.items(): params['property-%s' % key] = value image_list = glance_client.list_images(detail=True, **params)['images'] else: # Additional properties are flattened in glance v2. params.update(properties) image_list = glance_client.list_images(params)['images'] self.assertEqual(2, len(image_list)) self.assertEqual((backup1, backup2), (image_list[0]['name'], image_list[1]['name'])) # create the third one, due to the rotation is 2, # the first one will be deleted backup3 = data_utils.rand_name('backup-3') waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup3).response image3_id = data_utils.parse_image_id(resp['location']) self.addCleanup(glance_client.delete_image, image3_id) # the first back up should be deleted waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') glance_client.wait_for_resource_deletion(image1_id) oldest_backup_exist = False if CONF.image_feature_enabled.api_v1: image_list = glance_client.list_images(detail=True, **params)['images'] else: image_list = glance_client.list_images(params)['images'] self.assertEqual( 2, len(image_list), 'Unexpected number of images for ' 'v2:test_create_backup; was the oldest backup not ' 'yet deleted? Image list: %s' % [image['name'] for image in image_list]) self.assertEqual((backup2, backup3), (image_list[0]['name'], image_list[1]['name']))
def test_create_backup(self): # Positive test:create backup successfully and rotate backups correctly # create the first and the second backup backup1 = data_utils.rand_name('backup-1') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup1).response oldest_backup_exist = True # the oldest one should be deleted automatically in this test def _clean_oldest_backup(oldest_backup): if oldest_backup_exist: try: self.os.image_client.delete_image(oldest_backup) except lib_exc.NotFound: pass else: LOG.warning("Deletion of oldest backup %s should not have " "been successful as it should have been " "deleted during rotation." % oldest_backup) image1_id = data_utils.parse_image_id(resp['location']) self.addCleanup(_clean_oldest_backup, image1_id) waiters.wait_for_image_status(self.os.image_client, image1_id, 'active') backup2 = data_utils.rand_name('backup-2') waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup2).response image2_id = data_utils.parse_image_id(resp['location']) self.addCleanup(self.os.image_client.delete_image, image2_id) waiters.wait_for_image_status(self.os.image_client, image2_id, 'active') # verify they have been created properties = { 'image_type': 'backup', 'backup_type': "daily", 'instance_uuid': self.server_id, } image_list = self.os.image_client.list_images(detail=True, properties=properties, status='active', sort_key='created_at', sort_dir='asc')['images'] self.assertEqual(2, len(image_list)) self.assertEqual((backup1, backup2), (image_list[0]['name'], image_list[1]['name'])) # create the third one, due to the rotation is 2, # the first one will be deleted backup3 = data_utils.rand_name('backup-3') waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup3).response image3_id = data_utils.parse_image_id(resp['location']) self.addCleanup(self.os.image_client.delete_image, image3_id) # the first back up should be deleted waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') self.os.image_client.wait_for_resource_deletion(image1_id) oldest_backup_exist = False image_list = self.os.image_client.list_images(detail=True, properties=properties, status='active', sort_key='created_at', sort_dir='asc')['images'] self.assertEqual( 2, len(image_list), 'Unexpected number of images for ' 'v2:test_create_backup; was the oldest backup not ' 'yet deleted? Image list: %s' % [image['name'] for image in image_list]) self.assertEqual((backup2, backup3), (image_list[0]['name'], image_list[1]['name']))
def test_create_backup(self): # Positive test:create backup successfully and rotate backups correctly # create the first and the second backup backup1 = data_utils.rand_name('backup-1') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup1).response oldest_backup_exist = True # the oldest one should be deleted automatically in this test def _clean_oldest_backup(oldest_backup): if oldest_backup_exist: try: self.os.image_client.delete_image(oldest_backup) except lib_exc.NotFound: pass else: LOG.warning("Deletion of oldest backup %s should not have " "been successful as it should have been " "deleted during rotation." % oldest_backup) image1_id = data_utils.parse_image_id(resp['location']) self.addCleanup(_clean_oldest_backup, image1_id) waiters.wait_for_image_status(self.os.image_client, image1_id, 'active') backup2 = data_utils.rand_name('backup-2') waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup2).response image2_id = data_utils.parse_image_id(resp['location']) self.addCleanup(self.os.image_client.delete_image, image2_id) waiters.wait_for_image_status(self.os.image_client, image2_id, 'active') # verify they have been created properties = { 'image_type': 'backup', 'backup_type': "daily", 'instance_uuid': self.server_id, } image_list = self.os.image_client.list_images( detail=True, properties=properties, status='active', sort_key='created_at', sort_dir='asc')['images'] self.assertEqual(2, len(image_list)) self.assertEqual((backup1, backup2), (image_list[0]['name'], image_list[1]['name'])) # create the third one, due to the rotation is 2, # the first one will be deleted backup3 = data_utils.rand_name('backup-3') waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup3).response image3_id = data_utils.parse_image_id(resp['location']) self.addCleanup(self.os.image_client.delete_image, image3_id) # the first back up should be deleted waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') self.os.image_client.wait_for_resource_deletion(image1_id) oldest_backup_exist = False image_list = self.os.image_client.list_images( detail=True, properties=properties, status='active', sort_key='created_at', sort_dir='asc')['images'] self.assertEqual(2, len(image_list), 'Unexpected number of images for ' 'v2:test_create_backup; was the oldest backup not ' 'yet deleted? Image list: %s' % [image['name'] for image in image_list]) self.assertEqual((backup2, backup3), (image_list[0]['name'], image_list[1]['name']))
def wait_for_image_status(self, image_id, status): """Waits for an image to reach a given status.""" waiters.wait_for_image_status(self, image_id, status)
def test_create_backup(self): # Positive test:create backup successfully and rotate backups correctly # create the first and the second backup # Check if glance v1 is available to determine which client to use. We # prefer glance v1 for the compute API tests since the compute image # API proxy was written for glance v1. if CONF.image_feature_enabled.api_v1: glance_client = self.os.image_client elif CONF.image_feature_enabled.api_v2: glance_client = self.os.image_client_v2 else: raise lib_exc.InvalidConfiguration("Either api_v1 or api_v2 must be True in " "[image-feature-enabled].") backup1 = data_utils.rand_name("backup-1") resp = self.client.create_backup(self.server_id, backup_type="daily", rotation=2, name=backup1).response oldest_backup_exist = True # the oldest one should be deleted automatically in this test def _clean_oldest_backup(oldest_backup): if oldest_backup_exist: try: glance_client.delete_image(oldest_backup) except lib_exc.NotFound: pass else: LOG.warning( "Deletion of oldest backup %s should not have " "been successful as it should have been " "deleted during rotation." % oldest_backup ) image1_id = data_utils.parse_image_id(resp["location"]) self.addCleanup(_clean_oldest_backup, image1_id) waiters.wait_for_image_status(glance_client, image1_id, "active") backup2 = data_utils.rand_name("backup-2") waiters.wait_for_server_status(self.client, self.server_id, "ACTIVE") resp = self.client.create_backup(self.server_id, backup_type="daily", rotation=2, name=backup2).response image2_id = data_utils.parse_image_id(resp["location"]) self.addCleanup(glance_client.delete_image, image2_id) waiters.wait_for_image_status(glance_client, image2_id, "active") # verify they have been created properties = {"image_type": "backup", "backup_type": "daily", "instance_uuid": self.server_id} params = {"status": "active", "sort_key": "created_at", "sort_dir": "asc"} if CONF.image_feature_enabled.api_v1: for key, value in properties.items(): params["property-%s" % key] = value image_list = glance_client.list_images(detail=True, **params)["images"] else: # Additional properties are flattened in glance v2. params.update(properties) image_list = glance_client.list_images(params)["images"] self.assertEqual(2, len(image_list)) self.assertEqual((backup1, backup2), (image_list[0]["name"], image_list[1]["name"])) # create the third one, due to the rotation is 2, # the first one will be deleted backup3 = data_utils.rand_name("backup-3") waiters.wait_for_server_status(self.client, self.server_id, "ACTIVE") resp = self.client.create_backup(self.server_id, backup_type="daily", rotation=2, name=backup3).response image3_id = data_utils.parse_image_id(resp["location"]) self.addCleanup(glance_client.delete_image, image3_id) # the first back up should be deleted waiters.wait_for_server_status(self.client, self.server_id, "ACTIVE") glance_client.wait_for_resource_deletion(image1_id) oldest_backup_exist = False if CONF.image_feature_enabled.api_v1: image_list = glance_client.list_images(detail=True, **params)["images"] else: image_list = glance_client.list_images(params)["images"] self.assertEqual( 2, len(image_list), "Unexpected number of images for " "v2:test_create_backup; was the oldest backup not " "yet deleted? Image list: %s" % [image["name"] for image in image_list], ) self.assertEqual((backup2, backup3), (image_list[0]["name"], image_list[1]["name"]))
def resource_setup(cls): super(UserIsolationSetup, cls).resource_setup() # Prepare an array to store information fileinfo = {} if os.path.exists(file_path): LOG.info("/!\\ deleting previous file /!\\") os.remove(file_path) # Create a server LOG.info("setting up server...") name = data_utils.rand_name("VM_Setup") server = cls.create_test_server(name=name, wait_until="ACTIVE") cls.server = cls.client.show_server(server["id"])["server"] fileinfo["server"] = cls.server LOG.info("VM_Setup created and active") # Create an image name = data_utils.rand_name("image") body = cls.compute_images_client.create_image(cls.server["id"], name=name) image_id = data_utils.parse_image_id(body.response["location"]) waiters.wait_for_image_status(cls.compute_images_client, image_id, "ACTIVE") cls.image = cls.compute_images_client.show_image(image_id)["image"] fileinfo["image"] = cls.image LOG.info("image created and active") # Create a keypair cls.keypairname = data_utils.rand_name("keypair") cls.keypairs_client.create_keypair(name=cls.keypairname) fileinfo["keypairname"] = cls.keypairname LOG.info("keypair created") # Create a security group name = data_utils.rand_name("security") description = data_utils.rand_name("description") cls.security_group = cls.security_client.create_security_group(name=name, description=description)[ "security_group" ] fileinfo["security_group"] = cls.security_group LOG.info("security group created") # Create a security group rule cls.rule = cls.rule_client.create_security_group_rule( parent_group_id=cls.security_group["id"], ip_protocol="tcp", from_port=22, to_port=22 )["security_group_rule"] fileinfo["rule"] = cls.rule LOG.info("security rule created") # Create two volumes name = data_utils.rand_name("volume1") cls.metadata = {"vol_metadata": data_utils.rand_name("vol_metadata")} cls.volume1 = cls.volumes_client.create_volume(size=1, display_name=name, metadata=cls.metadata)["volume"] name = data_utils.rand_name("volume2") cls.volume2 = cls.volumes_client.create_volume(size=1, display_name=name)["volume"] waiters.wait_for_volume_status(cls.volumes_client, cls.volume1["id"], "available") waiters.wait_for_volume_status(cls.volumes_client, cls.volume2["id"], "available") fileinfo["volume1"] = cls.volume1 fileinfo["metadata"] = cls.metadata fileinfo["volume2"] = cls.volume2 LOG.info("volumes created") # Create a snapshot from volume1 name = data_utils.rand_name("snapshot") cls.snapshot = cls.snapshots_client.create_snapshot(volume_id=cls.volume1["id"], display_name=name)["snapshot"] waiters.wait_for_snapshot_status(cls.snapshots_client, cls.snapshot["id"], "available") fileinfo["snapshot"] = cls.snapshot LOG.info("snapshot created") # Attach volume2 to the server cls.attachment = cls.servers_client.attach_volume(cls.server["id"], volumeId=cls.volume2["id"])[ "volumeAttachment" ] waiters.wait_for_volume_status(cls.volumes_client, cls.volume2["id"], "in-use") fileinfo["attachment"] = cls.attachment LOG.info("volume attached to server") # Save array information to file f = open(file_path, "w") json.dump(fileinfo, f) f.close() LOG.info("file created with ids, waiting...")
def test_create_backup(self): # Positive test:create backup successfully and rotate backups correctly # create the first and the second backup # Check if glance v1 is available to determine which client to use. We # prefer glance v1 for the compute API tests since the compute image # API proxy was written for glance v1. if CONF.image_feature_enabled.api_v1: glance_client = self.os_primary.image_client elif CONF.image_feature_enabled.api_v2: glance_client = self.os_primary.image_client_v2 else: raise lib_exc.InvalidConfiguration( 'Either api_v1 or api_v2 must be True in ' '[image-feature-enabled].') backup1 = data_utils.rand_name('backup-1') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup1) oldest_backup_exist = True # the oldest one should be deleted automatically in this test def _clean_oldest_backup(oldest_backup): if oldest_backup_exist: try: glance_client.delete_image(oldest_backup) except lib_exc.NotFound: pass else: LOG.warning("Deletion of oldest backup %s should not have " "been successful as it should have been " "deleted during rotation.", oldest_backup) if api_version_utils.compare_version_header_to_response( "OpenStack-API-Version", "compute 2.45", resp.response, "lt"): image1_id = resp['image_id'] else: image1_id = data_utils.parse_image_id(resp.response['location']) self.addCleanup(_clean_oldest_backup, image1_id) waiters.wait_for_image_status(glance_client, image1_id, 'active') backup2 = data_utils.rand_name('backup-2') waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup2) if api_version_utils.compare_version_header_to_response( "OpenStack-API-Version", "compute 2.45", resp.response, "lt"): image2_id = resp['image_id'] else: image2_id = data_utils.parse_image_id(resp.response['location']) self.addCleanup(glance_client.delete_image, image2_id) waiters.wait_for_image_status(glance_client, image2_id, 'active') # verify they have been created properties = { 'image_type': 'backup', 'backup_type': "daily", 'instance_uuid': self.server_id, } params = { 'status': 'active', 'sort_key': 'created_at', 'sort_dir': 'asc' } if CONF.image_feature_enabled.api_v1: for key, value in properties.items(): params['property-%s' % key] = value image_list = glance_client.list_images( detail=True, **params)['images'] else: # Additional properties are flattened in glance v2. params.update(properties) image_list = glance_client.list_images(params)['images'] self.assertEqual(2, len(image_list)) self.assertEqual((backup1, backup2), (image_list[0]['name'], image_list[1]['name'])) # create the third one, due to the rotation is 2, # the first one will be deleted backup3 = data_utils.rand_name('backup-3') waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') resp = self.client.create_backup(self.server_id, backup_type='daily', rotation=2, name=backup3) if api_version_utils.compare_version_header_to_response( "OpenStack-API-Version", "compute 2.45", resp.response, "lt"): image3_id = resp['image_id'] else: image3_id = data_utils.parse_image_id(resp.response['location']) self.addCleanup(glance_client.delete_image, image3_id) # the first back up should be deleted waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE') glance_client.wait_for_resource_deletion(image1_id) oldest_backup_exist = False if CONF.image_feature_enabled.api_v1: image_list = glance_client.list_images( detail=True, **params)['images'] else: image_list = glance_client.list_images(params)['images'] self.assertEqual(2, len(image_list), 'Unexpected number of images for ' 'v2:test_create_backup; was the oldest backup not ' 'yet deleted? Image list: %s' % [image['name'] for image in image_list]) self.assertEqual((backup2, backup3), (image_list[0]['name'], image_list[1]['name']))
def create_image_from_server(cls, server_id, **kwargs): """Wrapper utility that returns an image created from the server. If compute microversion >= 2.36, the returned image response will be from the image service API rather than the compute image proxy API. """ name = kwargs.pop('name', data_utils.rand_name(cls.__name__ + "-image")) wait_until = kwargs.pop('wait_until', None) wait_for_server = kwargs.pop('wait_for_server', True) image = cls.compute_images_client.create_image(server_id, name=name, **kwargs) if api_version_utils.compare_version_header_to_response( "OpenStack-API-Version", "compute 2.45", image.response, "lt"): image_id = image['image_id'] else: image_id = data_utils.parse_image_id(image.response['location']) # The compute image proxy APIs were deprecated in 2.35 so # use the images client directly if the API microversion being # used is >=2.36. if not cls.is_requested_microversion_compatible('2.35'): client = cls.images_client else: client = cls.compute_images_client cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc, client.delete_image, image_id) if wait_until is not None: try: wait_until = wait_until.upper() if not cls.is_requested_microversion_compatible('2.35'): wait_until = wait_until.lower() waiters.wait_for_image_status(client, image_id, wait_until) except lib_exc.NotFound: if wait_until.upper() == 'ACTIVE': # If the image is not found after create_image returned # that means the snapshot failed in nova-compute and nova # deleted the image. There should be a compute fault # recorded with the server in that case, so get the server # and dump some details. server = ( cls.servers_client.show_server(server_id)['server']) if 'fault' in server: raise exceptions.SnapshotNotFoundException( server['fault'], image_id=image_id) else: raise exceptions.SnapshotNotFoundException( image_id=image_id) else: raise image = client.show_image(image_id) # Compute image client returns response wrapped in 'image' element # which is not the case with Glance image client. if 'image' in image: image = image['image'] if wait_until.upper() == 'ACTIVE': if wait_for_server: waiters.wait_for_server_status(cls.servers_client, server_id, 'ACTIVE') return image