Merge "Reject boot request for unsupported images" into stable/queens

This commit is contained in:
Zuul 2020-07-21 03:45:55 +00:00 committed by Gerrit Code Review
commit faa8bf83cc
4 changed files with 52 additions and 0 deletions

View File

@ -582,6 +582,7 @@ class ServersController(wsgi.Controller):
exception.ImageNotActive,
exception.ImageBadRequest,
exception.ImageNotAuthorized,
exception.ImageUnacceptable,
exception.FixedIpNotFoundForAddress,
exception.FlavorNotFound,
exception.FlavorDiskTooSmall,

View File

@ -557,6 +557,31 @@ class API(base.Base):
# reason, we rely on the DB to cast True to a String.
return True if bool_val else ''
@staticmethod
def _detect_nonbootable_image_from_properties(image_id, image):
"""Check image for a property indicating it's nonbootable.
This is called from the API service to ensure that there are
no known image properties indicating that this image is of a
type that we do not support booting from.
Currently the only such property is 'cinder_encryption_key_id'.
:param image_id: UUID of the image
:param image: a dict representation of the image including properties
:raises: ImageUnacceptable if the image properties indicate
that booting this image is not supported
"""
if not image:
return
image_properties = image.get('properties', {})
if image_properties.get('cinder_encryption_key_id'):
reason = _('Direct booting of an image uploaded from an '
'encrypted volume is unsupported.')
raise exception.ImageUnacceptable(image_id=image_id,
reason=reason)
def _check_requested_image(self, context, image_id, image,
instance_type, root_bdm):
if not image:
@ -773,6 +798,7 @@ class API(base.Base):
self._check_injected_file_quota(context, files_to_inject)
self._check_requested_image(context, image_id, image,
instance_type, root_bdm)
self._detect_nonbootable_image_from_properties(image_id, image)
def _validate_and_build_base_options(self, context, instance_type,
boot_meta, image_href, image_id,

View File

@ -3050,6 +3050,22 @@ class ServersControllerCreateTest(test.TestCase):
"Flavor's disk is too small for requested image."):
self.controller.create(self.req, body=self.body)
@mock.patch.object(fake._FakeImageService, 'show',
return_value=dict(
id='76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
status='active',
properties=dict(
cinder_encryption_key_id=fakes.FAKE_UUID)))
def test_create_server_image_nonbootable(self, mock_show):
self.req.body = jsonutils.dump_as_bytes(self.body)
expected_msg = ("Image {} is unacceptable: Direct booting of an image "
"uploaded from an encrypted volume is unsupported.")
with testtools.ExpectedException(
webob.exc.HTTPBadRequest,
expected_msg.format(self.image_uuid)):
self.controller.create(self.req, body=self.body)
def test_create_instance_with_image_non_uuid(self):
self.body['server']['imageRef'] = 'not-uuid'
self.assertRaises(exception.ValidationError,

View File

@ -0,0 +1,9 @@
---
fixes:
- |
The Compute service has never supported direct booting of an instance from
an image that was created by the Block Storage service from an encrypted
volume. Previously, this operation would result in an ACTIVE instance that
was unusable. Beginning with this release, an attempt to boot from such an
image will result in the Compute API returning a 400 (Bad Request)
response.