From 0733804ec30f80d46a4dbc75ea93fa1a931769ad Mon Sep 17 00:00:00 2001 From: weikeyou Date: Sat, 16 May 2020 17:44:47 +0800 Subject: [PATCH] Resolve error when create container with bind volume The function _refresh_attached_volumes() used the requested_volume in the parameters passed in, but the volume is not created in the DB. Then it will raise the following error: "Object action obj_load_attr failed because: attribute volume_id not lazy-loadable" Co-Authored-By: Hongbin Lu Change-Id: Iabc0f83982881453ae2e266f90d7ac7ca79651ec --- zun/api/controllers/v1/containers.py | 9 +++++---- zun/compute/api.py | 11 +++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/zun/api/controllers/v1/containers.py b/zun/api/controllers/v1/containers.py index faa04a96a..e0ddbf31f 100644 --- a/zun/api/controllers/v1/containers.py +++ b/zun/api/controllers/v1/containers.py @@ -581,7 +581,6 @@ class ContainersController(base.Controller): for mount in mounts: volume_dict = { 'cinder_volume_id': None, - 'container_path': None, 'auto_remove': False, 'contents': None, 'user_id': context.user_id, @@ -593,20 +592,22 @@ class ContainersController(base.Controller): volume = cinder_api.search_volume(mount['source']) cinder_api.ensure_volume_usable(volume) volume_dict['cinder_volume_id'] = volume.id - volume_dict['container_path'] = mount['destination'] volume_dict['volume_provider'] = 'cinder' elif mount.get('size'): volume = cinder_api.create_volume(mount['size']) cinder_api.ensure_volume_usable(volume) volume_dict['cinder_volume_id'] = volume.id - volume_dict['container_path'] = mount['destination'] volume_dict['volume_provider'] = 'cinder' volume_dict['auto_remove'] = True elif volume_type == 'bind': volume_dict['contents'] = mount.pop('source', '') - volume_dict['container_path'] = mount['destination'] volume_dict['volume_provider'] = 'local' + volume_object = objects.Volume(context, **volume_dict) + volume_object.create(context) + volume_dict['volume_id'] = volume_object.id + volume_dict['container_path'] = mount['destination'] + volmapp = objects.VolumeMapping(context, **volume_dict) requested_volumes[container.uuid].append(volmapp) diff --git a/zun/compute/api.py b/zun/compute/api.py index c9caafd83..e72fed051 100644 --- a/zun/compute/api.py +++ b/zun/compute/api.py @@ -48,7 +48,8 @@ class API(object): pci_requests=None): requested_host = extra_spec.get('requested_host') if requested_host: - self._validate_host(context, new_container, requested_host) + self._validate_host(context, new_container, requested_host, + requested_volumes) try: host_state = self._schedule_container(context, new_container, @@ -100,13 +101,14 @@ class API(object): requested_networks, requested_volumes, run, pci_requests) - def _validate_host(self, context, container, host): + def _validate_host(self, context, container, host, requested_volumes): """Check whether compute nodes exist by validating the host. If host is supplied, we can lookup the ComputeNode in the API DB. :param context: The API request context. :param host: Target host. + :param requested_volumes: the requested volumes. :raises: exception.RequestedHostNotFound if we find no compute nodes with host and/or hypervisor_hostname. """ @@ -119,6 +121,11 @@ class API(object): LOG.info('No compute node record found for host %(host)s.', {'host': host}) container.destroy(context) + for volmap in requested_volumes[container.uuid]: + try: + volmap._destroy_volume(context) + except exception.VolumeNotFound: + pass raise exception.RequestedHostNotFound(host=host) def _schedule_container(self, context, new_container, extra_spec):