Esempio n. 1
0
    def test_image_glance_direct_import(self):
        """Test 'glance-direct' import functionalities

        Create image, stage image data, import image and verify
        that import succeeded.
        """
        self._require_import_method('glance-direct')

        image_id = self._stage_and_check()
        # import image from staging to backend
        resp = self.client.image_import(image_id, method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.client, image_id)

        if not self.versions_client.has_version('2.12'):
            # API is not new enough to support image/tasks API
            LOG.info('Glance does not support v2.12, so I am unable to '
                     'validate the image/tasks API.')
            return

        # Make sure we can access the task and that some of the key
        # fields look legit.
        tasks = self.client.show_image_tasks(image_id)
        self.assertEqual(1, len(tasks['tasks']))
        task = tasks['tasks'][0]
        self.assertEqual('success', task['status'])
        self.assertEqual(resp.response['x-openstack-request-id'],
                         task['request_id'])
        self.assertEqual('glance-direct',
                         task['input']['import_req']['method']['name'])
Esempio n. 2
0
 def test_wait_for_image_imported_to_stores(self):
     self.client.show_image.return_value = ({'status': 'active',
                                             'stores': 'fake_store'})
     start_time = int(time.time())
     waiters.wait_for_image_imported_to_stores(
         self.client, 'fake_image_id', 'fake_store')
     end_time = int(time.time())
     # Ensure waiter returns before build_timeout
     self.assertLess((end_time - start_time), 10)
Esempio n. 3
0
    def test_glance_direct_import_image_to_specific_stores(self):
        """Test image is imported in all available stores

        Create image, import image to specified store(s) using glance-direct
        import method and verify that import succeeded.
        """
        image, stores = self._create_and_stage_image()
        self.client.image_import(image['id'],
                                 method='glance-direct',
                                 stores=stores)

        waiters.wait_for_image_imported_to_stores(self.client, image['id'],
                                                  (','.join(stores)))
Esempio n. 4
0
    def test_glance_direct_import_image_to_all_stores(self):
        """Test image is imported in all available stores

        Create image, import image to all available stores using glance-direct
        import method and verify that import succeeded.
        """
        image, stores = self._create_and_stage_image(all_stores=True)

        self.client.image_import(image['id'],
                                 method='glance-direct',
                                 all_stores=True)

        waiters.wait_for_image_imported_to_stores(self.client, image['id'],
                                                  stores)
Esempio n. 5
0
    def test_remote_import(self):
        """Test image import against a different worker than stage.

        This creates and stages an image against the primary API worker,
        but then calls import on a secondary worker (if available) to
        test that distributed image import works (i.e. proxies the import
        request to the proper worker).
        """
        self._require_import_method('glance-direct')

        if not CONF.image.alternate_image_endpoint:
            raise self.skipException('No image_remote service to test '
                                     'against')

        image_id = self._stage_and_check()
        # import image from staging to backend, but on the alternate worker
        self.os_primary.image_client_remote.image_import(
            image_id, method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.client, image_id)
Esempio n. 6
0
    def test_image_web_download_import(self):
        """Test 'web-download' import functionalities

        Create image, import image and verify that import
        succeeded.
        """
        self._require_import_method('web-download')

        image = self._create_image()
        # Now try to get image details
        body = self.client.show_image(image['id'])
        self.assertEqual(image['id'], body['id'])
        self.assertEqual('queued', body['status'])
        # import image from web to backend
        image_uri = CONF.image.http_image
        self.client.image_import(image['id'],
                                 method='web-download',
                                 image_uri=image_uri)
        waiters.wait_for_image_imported_to_stores(self.client, image['id'])
Esempio n. 7
0
    def test_image_web_download_import(self):
        """Test 'web-download' import functionalities

        Create image, import image and verify that import
        succeeded.
        """
        if 'web-download' not in self.available_import_methods:
            raise self.skipException('Server does not support '
                                     'web-download import method')
        image = self._create_image()
        # Now try to get image details
        body = self.client.show_image(image['id'])
        self.assertEqual(image['id'], body['id'])
        self.assertEqual('queued', body['status'])
        # import image from web to backend
        image_uri = CONF.image.http_image
        self.client.image_import(image['id'],
                                 method='web-download',
                                 image_uri=image_uri)
        waiters.wait_for_image_imported_to_stores(self.client, image['id'])
Esempio n. 8
0
    def test_image_glance_direct_import(self):
        """Test 'glance-direct' import functionalities

        Create image, stage image data, import image and verify
        that import succeeded.
        """
        if 'glance-direct' not in self.available_import_methods:
            raise self.skipException('Server does not support '
                                     'glance-direct import method')
        image = self._create_image()
        # Stage image data
        file_content = data_utils.random_bytes()
        image_file = io.BytesIO(file_content)
        self.client.stage_image_file(image['id'], image_file)
        # Check image status is 'uploading'
        body = self.client.show_image(image['id'])
        self.assertEqual(image['id'], body['id'])
        self.assertEqual('uploading', body['status'])
        # import image from staging to backend
        self.client.image_import(image['id'], method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.client, image['id'])
Esempio n. 9
0
    def test_image_stage_quota(self):
        if not CONF.image_feature_enabled.import_image:
            skip_msg = ("%s skipped as image import is not available" %
                        __name__)
            raise self.skipException(skip_msg)

        self.check_quotas_enabled()

        # Create a staging quota of 1MiB, allow 10MiB of active
        # images, and a total of ten images.
        self._update_limit('image_stage_total', 1)
        self._update_limit('image_size_total', 10)
        self._update_limit('image_count_total', 10)
        self._update_limit('image_count_uploading', 10)

        file_content = data_utils.random_bytes(1 * units.Mi)

        # Create and stage a 1MiB image.
        image1 = self.create_image(name='first',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.image_client.stage_image_file(image1['id'],
                                           io.BytesIO(file_content))

        # Create and stage a second 1MiB image. This succeeds, but
        # after completion, we are over quota.
        image2 = self.create_image(name='second',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.image_client.stage_image_file(image2['id'],
                                           io.BytesIO(file_content))

        # Create and attempt to stage a third 1MiB image. This should fail to
        # stage (but not create) because we are over quota.
        image3 = self.create_image(name='third',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.stage_image_file, image3['id'],
                          io.BytesIO(file_content))

        # Make sure that even though we are over our stage quota, we
        # can still create and upload an image the regular way.
        image_upload = self.create_image(name='uploaded',
                                         container_format='bare',
                                         disk_format='raw',
                                         visibility='private')
        self.image_client.store_image_file(image_upload['id'],
                                           io.BytesIO(file_content))

        # Increase our stage quota to two MiB.
        self._update_limit('image_stage_total', 2)

        # Now the upload of the already-created image is allowed, but
        # after completion, we are over quota again.
        self.image_client.stage_image_file(image3['id'],
                                           io.BytesIO(file_content))

        # Create and attempt to stage a fourth 1MiB image. This should
        # fail to stage (but not create) because we are over quota.
        image4 = self.create_image(name='fourth',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.stage_image_file, image4['id'],
                          io.BytesIO(file_content))

        # Finish our import of image1 to make space in our stage quota.
        self.image_client.image_import(image1['id'], method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.image_client,
                                                  image1['id'])

        # Now the upload of the already-created image is allowed.
        self.image_client.stage_image_file(image4['id'],
                                           io.BytesIO(file_content))

        # Delete all the images we created before the next test runs,
        # so that it starts with full quota.
        self._cleanup_images()
Esempio n. 10
0
    def test_image_count_uploading_quota(self):
        if not CONF.image_feature_enabled.import_image:
            skip_msg = ("%s skipped as image import is not available" %
                        __name__)
            raise self.skipException(skip_msg)

        self.check_quotas_enabled()

        # Set a quota on the number of images we can have in uploading state.
        self._update_limit('image_stage_total', 10)
        self._update_limit('image_size_total', 10)
        self._update_limit('image_count_total', 10)
        self._update_limit('image_count_uploading', 1)

        file_content = data_utils.random_bytes(1 * units.Mi)

        # Create and stage an image
        image1 = self.create_image(name='first',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.image_client.stage_image_file(image1['id'],
                                           io.BytesIO(file_content))

        # Check that we can not stage another
        image2 = self.create_image(name='second',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.stage_image_file, image2['id'],
                          io.BytesIO(file_content))

        # ... nor upload directly
        image3 = self.create_image(name='third',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.store_image_file, image3['id'],
                          io.BytesIO(file_content))

        # Update our quota to make room
        self._update_limit('image_count_uploading', 2)

        # Now our upload should work
        self.image_client.store_image_file(image3['id'],
                                           io.BytesIO(file_content))

        # ...and because that is no longer in uploading state, we should be
        # able to stage our second image from above.
        self.image_client.stage_image_file(image2['id'],
                                           io.BytesIO(file_content))

        # Finish our import of image2
        self.image_client.image_import(image2['id'], method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.image_client,
                                                  image2['id'])

        # Set our quota back to one
        self._update_limit('image_count_uploading', 1)

        # Since image1 is still staged, we should not be able to upload
        # an image.
        image4 = self.create_image(name='fourth',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.store_image_file, image4['id'],
                          io.BytesIO(file_content))

        # Finish our import of image1 to make space in our uploading quota.
        self.image_client.image_import(image1['id'], method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.image_client,
                                                  image1['id'])

        # Make sure that freed up the one upload quota to complete our upload
        self.image_client.store_image_file(image4['id'],
                                           io.BytesIO(file_content))

        # Delete all the images we created before the next test runs,
        # so that it starts with full quota.
        self._cleanup_images()