Merge "Make custom_image context glance v2 compatible"
This commit is contained in:
commit
c602fdd17f
@ -26,6 +26,7 @@ from rally import osclients
|
|||||||
from rally.plugins.openstack.scenarios.nova import utils as nova_utils
|
from rally.plugins.openstack.scenarios.nova import utils as nova_utils
|
||||||
from rally.plugins.openstack.scenarios.vm import vmtasks
|
from rally.plugins.openstack.scenarios.vm import vmtasks
|
||||||
from rally.plugins.openstack import types
|
from rally.plugins.openstack import types
|
||||||
|
from rally.plugins.openstack.wrappers import glance as glance_wrapper
|
||||||
from rally.task import context
|
from rally.task import context
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -125,7 +126,6 @@ class BaseCustomImageGenerator(context.Context):
|
|||||||
nics = [{"net-id": tenant["networks"][0]["id"]}]
|
nics = [{"net-id": tenant["networks"][0]["id"]}]
|
||||||
|
|
||||||
custom_image = self.create_one_image(user, nics=nics)
|
custom_image = self.create_one_image(user, nics=nics)
|
||||||
self.make_image_public(custom_image)
|
|
||||||
|
|
||||||
for tenant in self.context["tenants"].values():
|
for tenant in self.context["tenants"].values():
|
||||||
tenant["custom_image"] = custom_image
|
tenant["custom_image"] = custom_image
|
||||||
@ -146,6 +146,7 @@ class BaseCustomImageGenerator(context.Context):
|
|||||||
"""Create one image for the user."""
|
"""Create one image for the user."""
|
||||||
|
|
||||||
clients = osclients.Clients(user["credential"])
|
clients = osclients.Clients(user["credential"])
|
||||||
|
admin_clients = osclients.Clients(self.context["admin"]["credential"])
|
||||||
|
|
||||||
image_id = types.GlanceImage.transform(
|
image_id = types.GlanceImage.transform(
|
||||||
clients=clients, resource_config=self.config["image"])
|
clients=clients, resource_config=self.config["image"])
|
||||||
@ -154,6 +155,8 @@ class BaseCustomImageGenerator(context.Context):
|
|||||||
|
|
||||||
vm_scenario = vmtasks.VMTasks(self.context, clients=clients)
|
vm_scenario = vmtasks.VMTasks(self.context, clients=clients)
|
||||||
|
|
||||||
|
glance_wrap = glance_wrapper.wrap(admin_clients.glance, self)
|
||||||
|
|
||||||
server, fip = vm_scenario._boot_server_with_fip(
|
server, fip = vm_scenario._boot_server_with_fip(
|
||||||
image=image_id, flavor=flavor_id,
|
image=image_id, flavor=flavor_id,
|
||||||
floating_network=self.config.get("floating_network"),
|
floating_network=self.config.get("floating_network"),
|
||||||
@ -170,21 +173,19 @@ class BaseCustomImageGenerator(context.Context):
|
|||||||
vm_scenario._stop_server(server)
|
vm_scenario._stop_server(server)
|
||||||
|
|
||||||
LOG.debug("Creating snapshot for %r", server)
|
LOG.debug("Creating snapshot for %r", server)
|
||||||
custom_image = vm_scenario._create_image(server).to_dict()
|
custom_image = vm_scenario._create_image(server)
|
||||||
|
glance_wrap.set_visibility(custom_image)
|
||||||
finally:
|
finally:
|
||||||
vm_scenario._delete_server_with_fip(server, fip)
|
vm_scenario._delete_server_with_fip(server, fip)
|
||||||
|
|
||||||
|
if hasattr(custom_image, "to_dict"):
|
||||||
|
# NOTE(stpierre): Glance v1 images are objects that can be
|
||||||
|
# converted to dicts; Glance v2 images are already
|
||||||
|
# dict-like
|
||||||
|
custom_image = custom_image.to_dict()
|
||||||
|
|
||||||
return custom_image
|
return custom_image
|
||||||
|
|
||||||
def make_image_public(self, custom_image):
|
|
||||||
"""Make the image available publicly."""
|
|
||||||
|
|
||||||
admin_clients = osclients.Clients(self.context["admin"]["credential"])
|
|
||||||
|
|
||||||
LOG.debug("Making image %r public", custom_image["id"])
|
|
||||||
admin_clients.glance().images.get(
|
|
||||||
custom_image["id"]).update(is_public=True)
|
|
||||||
|
|
||||||
@logging.log_task_wrapper(LOG.info, _("Exit context: `custom_image`"))
|
@logging.log_task_wrapper(LOG.info, _("Exit context: `custom_image`"))
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
"""Delete created custom image(s)."""
|
"""Delete created custom image(s)."""
|
||||||
|
@ -78,6 +78,10 @@ class GlanceWrapper(object):
|
|||||||
Accepts all Glance v2 parameters.
|
Accepts all Glance v2 parameters.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def set_visibility(self, image, visibility="public"):
|
||||||
|
"""Set an existing image to public or private."""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def list_images(self, **filters):
|
def list_images(self, **filters):
|
||||||
"""List images.
|
"""List images.
|
||||||
@ -123,6 +127,9 @@ class GlanceV1Wrapper(GlanceWrapper):
|
|||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
def set_visibility(self, image, visibility="public"):
|
||||||
|
self.client.images.update(image.id, is_public=(visibility == "public"))
|
||||||
|
|
||||||
def list_images(self, **filters):
|
def list_images(self, **filters):
|
||||||
kwargs = {"filters": filters}
|
kwargs = {"filters": filters}
|
||||||
if "owner" in filters:
|
if "owner" in filters:
|
||||||
@ -187,6 +194,9 @@ class GlanceV2Wrapper(GlanceWrapper):
|
|||||||
check_interval=CONF.benchmark.
|
check_interval=CONF.benchmark.
|
||||||
glance_image_create_poll_interval)
|
glance_image_create_poll_interval)
|
||||||
|
|
||||||
|
def set_visibility(self, image, visibility="public"):
|
||||||
|
self.client.images.update(image.id, visibility=visibility)
|
||||||
|
|
||||||
def list_images(self, **filters):
|
def list_images(self, **filters):
|
||||||
return self.client.images.list(filters=filters)
|
return self.client.images.list(filters=filters)
|
||||||
|
|
||||||
|
@ -66,9 +66,10 @@ class BaseCustomImageContextVMTestCase(test.TestCase):
|
|||||||
@mock.patch("%s.osclients.Clients" % BASE)
|
@mock.patch("%s.osclients.Clients" % BASE)
|
||||||
@mock.patch("%s.types.GlanceImage.transform" % BASE, return_value="image")
|
@mock.patch("%s.types.GlanceImage.transform" % BASE, return_value="image")
|
||||||
@mock.patch("%s.types.Flavor.transform" % BASE, return_value="flavor")
|
@mock.patch("%s.types.Flavor.transform" % BASE, return_value="flavor")
|
||||||
|
@mock.patch("rally.plugins.openstack.wrappers.glance.wrap")
|
||||||
def test_create_one_image(
|
def test_create_one_image(
|
||||||
self, mock_flavor_transform, mock_glance_image_transform,
|
self, mock_glance_wrap, mock_flavor_transform,
|
||||||
mock_clients, mock_vm_tasks):
|
mock_glance_image_transform, mock_clients, mock_vm_tasks):
|
||||||
ip = {"ip": "foo_ip", "id": "foo_id", "is_floating": True}
|
ip = {"ip": "foo_ip", "id": "foo_id", "is_floating": True}
|
||||||
fake_server = mock.Mock()
|
fake_server = mock.Mock()
|
||||||
|
|
||||||
@ -93,6 +94,9 @@ class BaseCustomImageContextVMTestCase(test.TestCase):
|
|||||||
custom_image = generator_ctx.create_one_image(user,
|
custom_image = generator_ctx.create_one_image(user,
|
||||||
foo_arg="foo_value")
|
foo_arg="foo_value")
|
||||||
|
|
||||||
|
mock_glance_wrap.assert_called_once_with(
|
||||||
|
mock_clients.return_value.glance, generator_ctx)
|
||||||
|
|
||||||
mock_flavor_transform.assert_called_once_with(
|
mock_flavor_transform.assert_called_once_with(
|
||||||
clients=mock_clients.return_value,
|
clients=mock_clients.return_value,
|
||||||
resource_config={"name": "flavor"})
|
resource_config={"name": "flavor"})
|
||||||
@ -114,6 +118,8 @@ class BaseCustomImageContextVMTestCase(test.TestCase):
|
|||||||
fake_server, ip, user)
|
fake_server, ip, user)
|
||||||
|
|
||||||
mock_vm_scenario._create_image.assert_called_once_with(fake_server)
|
mock_vm_scenario._create_image.assert_called_once_with(fake_server)
|
||||||
|
mock_glance_wrap.return_value.set_visibility.assert_called_once_with(
|
||||||
|
fake_image)
|
||||||
|
|
||||||
mock_vm_scenario._delete_server_with_fip.assert_called_once_with(
|
mock_vm_scenario._delete_server_with_fip.assert_called_once_with(
|
||||||
fake_server, ip)
|
fake_server, ip)
|
||||||
@ -126,8 +132,9 @@ class BaseCustomImageContextVMTestCase(test.TestCase):
|
|||||||
return_value="image")
|
return_value="image")
|
||||||
@mock.patch("%s.types.Flavor.transform" % BASE,
|
@mock.patch("%s.types.Flavor.transform" % BASE,
|
||||||
return_value="flavor")
|
return_value="flavor")
|
||||||
|
@mock.patch("rally.plugins.openstack.wrappers.glance.wrap")
|
||||||
def test_create_one_image_cleanup(
|
def test_create_one_image_cleanup(
|
||||||
self, mock_flavor_transform,
|
self, mock_glance_wrap, mock_flavor_transform,
|
||||||
mock_glance_image_transform, mock_clients,
|
mock_glance_image_transform, mock_clients,
|
||||||
mock_vm_tasks):
|
mock_vm_tasks):
|
||||||
ip = {"ip": "foo_ip", "id": "foo_id", "is_floating": True}
|
ip = {"ip": "foo_ip", "id": "foo_id", "is_floating": True}
|
||||||
@ -163,24 +170,6 @@ class BaseCustomImageContextVMTestCase(test.TestCase):
|
|||||||
mock_vm_scenario._delete_server_with_fip.assert_called_once_with(
|
mock_vm_scenario._delete_server_with_fip.assert_called_once_with(
|
||||||
fake_server, ip)
|
fake_server, ip)
|
||||||
|
|
||||||
@mock.patch("%s.osclients.Clients" % BASE)
|
|
||||||
def test_make_image_public(self, mock_clients):
|
|
||||||
fc = mock.MagicMock()
|
|
||||||
mock_clients.return_value = fc
|
|
||||||
|
|
||||||
generator_ctx = TestImageGenerator(self.context)
|
|
||||||
custom_image = {"id": "image"}
|
|
||||||
|
|
||||||
generator_ctx.make_image_public(custom_image=custom_image)
|
|
||||||
|
|
||||||
mock_clients.assert_called_once_with(
|
|
||||||
self.context["admin"]["credential"])
|
|
||||||
|
|
||||||
fc.glance.assert_called_once_with()
|
|
||||||
fc.glance.return_value.images.get.assert_called_once_with("image")
|
|
||||||
(fc.glance.return_value.images.get.
|
|
||||||
return_value.update.assert_called_once_with(is_public=True))
|
|
||||||
|
|
||||||
@mock.patch("%s.nova_utils.NovaScenario" % BASE)
|
@mock.patch("%s.nova_utils.NovaScenario" % BASE)
|
||||||
@mock.patch("%s.osclients.Clients" % BASE)
|
@mock.patch("%s.osclients.Clients" % BASE)
|
||||||
def test_delete_one_image(self, mock_clients, mock_nova_scenario):
|
def test_delete_one_image(self, mock_clients, mock_nova_scenario):
|
||||||
@ -217,8 +206,6 @@ class BaseCustomImageContextVMTestCase(test.TestCase):
|
|||||||
|
|
||||||
generator_ctx.create_one_image.assert_called_once_with(
|
generator_ctx.create_one_image.assert_called_once_with(
|
||||||
self.context["users"][0], nics=[{"net-id": "network_id"}])
|
self.context["users"][0], nics=[{"net-id": "network_id"}])
|
||||||
generator_ctx.make_image_public.assert_called_once_with(
|
|
||||||
"custom_image")
|
|
||||||
|
|
||||||
def test_cleanup_admin(self):
|
def test_cleanup_admin(self):
|
||||||
tenant = self.context["tenants"]["tenant_id0"]
|
tenant = self.context["tenants"]["tenant_id0"]
|
||||||
|
@ -115,6 +115,19 @@ class GlanceV1WrapperTestCase(test.ScenarioTestCase):
|
|||||||
self.assertEqual(self.mock_wait_for_status.mock.return_value,
|
self.assertEqual(self.mock_wait_for_status.mock.return_value,
|
||||||
return_image)
|
return_image)
|
||||||
|
|
||||||
|
@ddt.data({"expected": True},
|
||||||
|
{"visibility": "public", "expected": True},
|
||||||
|
{"visibility": "private", "expected": False})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_set_visibility(self, visibility=None, expected=None):
|
||||||
|
image = mock.Mock()
|
||||||
|
if visibility is None:
|
||||||
|
self.wrapped_client.set_visibility(image)
|
||||||
|
else:
|
||||||
|
self.wrapped_client.set_visibility(image, visibility=visibility)
|
||||||
|
self.client().images.update.assert_called_once_with(
|
||||||
|
image.id, is_public=expected)
|
||||||
|
|
||||||
@ddt.data({}, {"fakearg": "fake"})
|
@ddt.data({}, {"fakearg": "fake"})
|
||||||
def test_list_images_basic(self, filters):
|
def test_list_images_basic(self, filters):
|
||||||
self.assertEqual(self.wrapped_client.list_images(**filters),
|
self.assertEqual(self.wrapped_client.list_images(**filters),
|
||||||
@ -233,6 +246,20 @@ class GlanceV2WrapperTestCase(test.ScenarioTestCase):
|
|||||||
timeout=mock.ANY)])
|
timeout=mock.ANY)])
|
||||||
self.assertEqual(uploaded_image, return_image)
|
self.assertEqual(uploaded_image, return_image)
|
||||||
|
|
||||||
|
@ddt.data({},
|
||||||
|
{"visibility": "public"},
|
||||||
|
{"visibility": "private"})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_set_visibility(self, visibility=None):
|
||||||
|
image = mock.Mock()
|
||||||
|
if visibility is None:
|
||||||
|
self.wrapped_client.set_visibility(image)
|
||||||
|
visibility = "public"
|
||||||
|
else:
|
||||||
|
self.wrapped_client.set_visibility(image, visibility=visibility)
|
||||||
|
self.client().images.update.assert_called_once_with(
|
||||||
|
image.id, visibility=visibility)
|
||||||
|
|
||||||
@ddt.data({}, {"fakearg": "fake"})
|
@ddt.data({}, {"fakearg": "fake"})
|
||||||
def test_list_images(self, filters):
|
def test_list_images(self, filters):
|
||||||
self.assertEqual(self.wrapped_client.list_images(**filters),
|
self.assertEqual(self.wrapped_client.list_images(**filters),
|
||||||
|
Loading…
Reference in New Issue
Block a user