Add support for image deactivate and reactivate

https://wiki.openstack.org/wiki/Glance-deactivate-image
Adding the api support for these commands.
Deactivate and reactivate image action is done by admin tenant.

- Added admin folder to image tests
- Added support for admin image classes for v1 and v2
- Added config deactivate_image , this feature is not running on
  icehouse
- Added a testcase for image deactivate.

Depends-On: Ia1d3d811bd57d3de16d397cfab341e8d0f17cb69
Change-Id: I7880f0e2646ce8660e035ebaa19a60f5bf271b64
This commit is contained in:
bkopilov 2015-05-15 23:46:25 +03:00
parent 941c56c543
commit 81aaae7fc2
7 changed files with 95 additions and 0 deletions

View File

@ -647,6 +647,10 @@
# Is the v1 image API enabled (boolean value)
#api_v1 = true
# Is the deactivate-image feature enabled. The feature has been
# integrated since Kilo. (boolean value)
#deactivate_image = false
[input-scenario]

View File

View File

View File

@ -0,0 +1,55 @@
# Copyright 2015 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from six import moves
from tempest_lib.common.utils import data_utils
import testtools
from tempest.api.image import base
from tempest import config
from tempest import test
CONF = config.CONF
class BasicAdminOperationsImagesTest(base.BaseV2ImageAdminTest):
"""
Here we test admin operations of images
"""
@testtools.skipUnless(CONF.image_feature_enabled.deactivate_image,
'deactivate-image is not available.')
@test.idempotent_id('951ebe01-969f-4ea9-9898-8a3f1f442ab0')
def test_admin_deactivate_reactivate_image(self):
# Create image by non-admin tenant
image_name = data_utils.rand_name('image')
body = self.client.create_image(name=image_name,
container_format='bare',
disk_format='raw',
visibility='private')
image_id = body['id']
self.addCleanup(self.client.delete_image, image_id)
# upload an image file
image_file = moves.cStringIO(data_utils.random_bytes())
self.client.store_image(image_id, image_file)
# deactivate image
self.admin_client.deactivate_image(image_id)
body = self.client.show_image(image_id)
self.assertEqual("deactivated", body['status'])
# reactivate image
self.admin_client.reactivate_image(image_id)
body = self.client.show_image(image_id)
self.assertEqual("active", body['status'])

View File

@ -158,3 +158,23 @@ class BaseV2MemberImageTest(BaseV2ImageTest):
image_id = image['id']
self.addCleanup(self.os_img_client.delete_image, image_id)
return image_id
class BaseV1ImageAdminTest(BaseImageTest):
credentials = ['admin', 'primary']
@classmethod
def setup_clients(cls):
super(BaseV1ImageAdminTest, cls).setup_clients()
cls.client = cls.os.image_client
cls.admin_client = cls.os_adm.image_client
class BaseV2ImageAdminTest(BaseImageTest):
credentials = ['admin', 'primary']
@classmethod
def setup_clients(cls):
super(BaseV2ImageAdminTest, cls).setup_clients()
cls.client = cls.os.image_client_v2
cls.admin_client = cls.os_adm.image_client_v2

View File

@ -433,6 +433,10 @@ ImageFeaturesGroup = [
cfg.BoolOpt('api_v1',
default=True,
help="Is the v1 image API enabled"),
cfg.BoolOpt('deactivate_image',
default=False,
help="Is the deactivate-image feature enabled."
" The feature has been integrated since Kilo."),
]
network_group = cfg.OptGroup(name='network',

View File

@ -96,6 +96,18 @@ class ImageClientV2JSON(service_client.ServiceClient):
body = json.loads(body)
return service_client.ResponseBody(resp, body)
def deactivate_image(self, image_id):
url = 'v2/images/%s/actions/deactivate' % image_id
resp, body = self.post(url, None)
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
def reactivate_image(self, image_id):
url = 'v2/images/%s/actions/reactivate' % image_id
resp, body = self.post(url, None)
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
def delete_image(self, image_id):
url = 'v2/images/%s' % image_id
resp, _ = self.delete(url)