mirror of https://github.com/docker/compose.git
The updated unit test simulates the error in the bug. What's happening
is that the container has an image sha (represented by 'shaDOES_NOT_EXIST') which causes an error when client.inspect_image is called on it, because the image has actually been removed. Signed-off-by: Ian Glen Neal <ian.gl.neal@gmail.com>
This commit is contained in:
parent
2d986dff79
commit
4042121f6e
|
@ -971,10 +971,9 @@ class TopLevelCommand(object):
|
||||||
if ignore_orphans and remove_orphans:
|
if ignore_orphans and remove_orphans:
|
||||||
raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.")
|
raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.")
|
||||||
|
|
||||||
if no_start:
|
opts = ['-d', '--abort-on-container-exit', '--exit-code-from']
|
||||||
opts = ['-d', '--abort-on-container-exit', '--exit-code-from']
|
for excluded in [x for x in opts if options.get(x) and no_start]:
|
||||||
for excluded in [x for x in opts if options.get(x)]:
|
raise UserError('--no-start and {} cannot be combined.'.format(excluded))
|
||||||
raise UserError('--no-start and {} cannot be combined.'.format(excluded))
|
|
||||||
|
|
||||||
with up_shutdown_context(self.project, service_names, timeout, detached):
|
with up_shutdown_context(self.project, service_names, timeout, detached):
|
||||||
def up(rebuild):
|
def up(rebuild):
|
||||||
|
|
|
@ -1306,24 +1306,6 @@ def merge_volume_bindings(volumes, tmpfs, previous_container, mounts):
|
||||||
return list(volume_bindings.values()), affinity
|
return list(volume_bindings.values()), affinity
|
||||||
|
|
||||||
|
|
||||||
def try_get_image_volumes(container):
|
|
||||||
"""
|
|
||||||
Try to get the volumes from the existing container. If the image does
|
|
||||||
not exist, raise an exception that will be caught at the CLI level to
|
|
||||||
prompt user for a rebuild.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
image_volumes = [
|
|
||||||
VolumeSpec.parse(volume)
|
|
||||||
for volume in
|
|
||||||
container.image_config['ContainerConfig'].get('Volumes') or {}
|
|
||||||
]
|
|
||||||
return image_volumes
|
|
||||||
except ImageNotFound:
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def get_container_data_volumes(container, volumes_option, tmpfs_option, mounts_option):
|
def get_container_data_volumes(container, volumes_option, tmpfs_option, mounts_option):
|
||||||
"""
|
"""
|
||||||
Find the container data volumes that are in `volumes_option`, and return
|
Find the container data volumes that are in `volumes_option`, and return
|
||||||
|
@ -1339,7 +1321,11 @@ def get_container_data_volumes(container, volumes_option, tmpfs_option, mounts_o
|
||||||
for mount in container.get('Mounts') or {}
|
for mount in container.get('Mounts') or {}
|
||||||
)
|
)
|
||||||
|
|
||||||
image_volumes = try_get_image_volumes(container)
|
image_volumes = [
|
||||||
|
VolumeSpec.parse(volume)
|
||||||
|
for volume in
|
||||||
|
container.image_config['ContainerConfig'].get('Volumes') or {}
|
||||||
|
]
|
||||||
|
|
||||||
for volume in set(volumes_option + image_volumes):
|
for volume in set(volumes_option + image_volumes):
|
||||||
# No need to preserve host volumes
|
# No need to preserve host volumes
|
||||||
|
|
|
@ -5,6 +5,7 @@ import docker
|
||||||
import pytest
|
import pytest
|
||||||
from docker.constants import DEFAULT_DOCKER_API_VERSION
|
from docker.constants import DEFAULT_DOCKER_API_VERSION
|
||||||
from docker.errors import APIError
|
from docker.errors import APIError
|
||||||
|
from docker.errors import ImageNotFound
|
||||||
|
|
||||||
from .. import mock
|
from .. import mock
|
||||||
from .. import unittest
|
from .. import unittest
|
||||||
|
@ -926,7 +927,7 @@ class ServiceVolumesTest(unittest.TestCase):
|
||||||
volumes, _ = get_container_data_volumes(container, options, ['/dev/tmpfs'], [])
|
volumes, _ = get_container_data_volumes(container, options, ['/dev/tmpfs'], [])
|
||||||
assert sorted(volumes) == sorted(expected)
|
assert sorted(volumes) == sorted(expected)
|
||||||
|
|
||||||
def test_get_container_data_volumes_image_is_none(self):
|
def test_get_container_data_volumes_image_does_not_exist(self):
|
||||||
# Issue 5465, check for non-existant image.
|
# Issue 5465, check for non-existant image.
|
||||||
options = [VolumeSpec.parse(v) for v in [
|
options = [VolumeSpec.parse(v) for v in [
|
||||||
'/host/volume:/host/volume:ro',
|
'/host/volume:/host/volume:ro',
|
||||||
|
@ -936,8 +937,15 @@ class ServiceVolumesTest(unittest.TestCase):
|
||||||
'/dev/tmpfs'
|
'/dev/tmpfs'
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
def inspect_fn(image):
|
||||||
|
if image == 'shaDOES_NOT_EXIST':
|
||||||
|
raise ImageNotFound("inspect_fn: {}".format(image))
|
||||||
|
return {'ContainerConfig': None}
|
||||||
|
|
||||||
|
self.mock_client.inspect_image = inspect_fn
|
||||||
|
|
||||||
container = Container(self.mock_client, {
|
container = Container(self.mock_client, {
|
||||||
'Image': None,
|
'Image': 'shaDOES_NOT_EXIST',
|
||||||
'Mounts': []
|
'Mounts': []
|
||||||
}, has_been_inspected=True)
|
}, has_been_inspected=True)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue