Example #1
0
    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')
Example #2
0
 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)
Example #3
0
 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)
Example #4
0
    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)
Example #10
0
    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 _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
Example #14
0
 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'])
Example #15
0
 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")
Example #17
0
 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')
Example #18
0
    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')
Example #19
0
    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')
Example #20
0
 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')
Example #21
0
    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
Example #25
0
    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
Example #26
0
    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
Example #27
0
    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')
Example #29
0
    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')
Example #30
0
    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
Example #31
0
    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 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
Example #33
0
    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
Example #35
0
    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
Example #36
0
    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
Example #37
0
    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
Example #38
0
    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')
Example #39
0
    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')
Example #40
0
    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
Example #42
0
    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']))
Example #43
0
    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']))
Example #44
0
    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']))
Example #45
0
 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)
Example #46
0
 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)
Example #47
0
    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...")
Example #49
0
    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']))
Example #50
0
    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
Example #51
0
    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