diff --git a/CHANGELOG.md b/CHANGELOG.md index ea0ddf802..e8cd889f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,31 @@ Change log ========== -1.25.1-rc1 (2019-11-29) ------------------------ +1.25.1 (2020-01-06) +------------------- + +### Features + +- Bump `pytest-cov` 2.8.1 + +- Bump `flake8` 3.7.9 + +- Bump `coverage` 4.5.4 ### Bugfixes -- Discard label `com.docker.compose.filepaths` having `None` as value. Typically, when coming from stdin +- Decode APIError explanation to unicode before usage on start and create of a container -- Add OSX binary as a directory to solve slow start up time caused by MacOS Catalina binary scan +- Reports when images that cannot be pulled and must be built -- Pass in HOME env-var in container mode (running with `script/run/run.sh`) +- Discard label `com.docker.compose.filepaths` having None as value. Typically, when coming from stdin + +- Added OSX binary as a directory to solve slow start up time caused by MacOS Catalina binary scan + +- Passed in HOME env-var in container mode (running with `script/run/run.sh`) + +- Reverted behavior of "only pull images that we can't build" and replace by a warning informing the image we can't pull and must be built -- Revert behavior of "only pull images that we can't build" and replace by a warning informing the image we can't pull and must be built 1.25.0 (2019-11-18) ------------------- diff --git a/compose/__init__.py b/compose/__init__.py index cda820978..8112b4e16 100644 --- a/compose/__init__.py +++ b/compose/__init__.py @@ -1,4 +1,4 @@ from __future__ import absolute_import from __future__ import unicode_literals -__version__ = '1.25.1-rc1' +__version__ = '1.25.1' diff --git a/compose/service.py b/compose/service.py index d329be979..024e7fbde 100644 --- a/compose/service.py +++ b/compose/service.py @@ -60,6 +60,7 @@ from .utils import parse_bytes from .utils import parse_seconds_float from .utils import truncate_id from .utils import unique_everseen +from compose.cli.utils import binarystr_to_unicode if six.PY2: import subprocess32 as subprocess @@ -343,7 +344,7 @@ class Service(object): return Container.create(self.client, **container_options) except APIError as ex: raise OperationFailedError("Cannot create container for service %s: %s" % - (self.name, ex.explanation)) + (self.name, binarystr_to_unicode(ex.explanation))) def ensure_image_exists(self, do_build=BuildAction.none, silent=False, cli=False): if self.can_be_built() and do_build == BuildAction.force: @@ -624,9 +625,10 @@ class Service(object): try: container.start() except APIError as ex: - if "driver failed programming external connectivity" in ex.explanation: + expl = binarystr_to_unicode(ex.explanation) + if "driver failed programming external connectivity" in expl: log.warn("Host is already in use by another container") - raise OperationFailedError("Cannot start service %s: %s" % (self.name, ex.explanation)) + raise OperationFailedError("Cannot start service %s: %s" % (self.name, expl)) return container @property diff --git a/requirements-dev.txt b/requirements-dev.txt index 27b71a268..00a2c6447 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,6 @@ -coverage==4.4.2 +coverage==4.5.4 ddt==1.2.0 -flake8==3.5.0 +flake8==3.7.9 mock==3.0.5 pytest==3.6.3 -pytest-cov==2.5.1 +pytest-cov==2.8.1 diff --git a/script/run/run.sh b/script/run/run.sh index 744766a06..7df5fe979 100755 --- a/script/run/run.sh +++ b/script/run/run.sh @@ -15,7 +15,7 @@ set -e -VERSION="1.25.1-rc1" +VERSION="1.25.1" IMAGE="docker/compose:$VERSION" diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py index a6a633db8..592e22f75 100644 --- a/tests/unit/service_test.py +++ b/tests/unit/service_test.py @@ -521,7 +521,37 @@ class ServiceTest(unittest.TestCase): assert 'was built because it did not already exist' in args[0] assert self.mock_client.build.call_count == 1 - self.mock_client.build.call_args[1]['tag'] == 'default_foo' + assert self.mock_client.build.call_args[1]['tag'] == 'default_foo' + + def test_create_container_binary_string_error(self): + service = Service('foo', client=self.mock_client, build={'context': '.'}) + service.image = lambda: {'Id': 'abc123'} + + self.mock_client.create_container.side_effect = APIError(None, + None, + b"Test binary string explanation") + with pytest.raises(OperationFailedError) as ex: + service.create_container() + + assert ex.value.msg == "Cannot create container for service foo: Test binary string explanation" + + def test_start_binary_string_error(self): + service = Service('foo', client=self.mock_client) + container = Container(self.mock_client, {'Id': 'abc123'}) + + self.mock_client.start.side_effect = APIError(None, + None, + b"Test binary string explanation with " + b"driver failed programming external " + b"connectivity") + with mock.patch('compose.service.log', autospec=True) as mock_log: + with pytest.raises(OperationFailedError) as ex: + service.start_container(container) + + assert ex.value.msg == "Cannot start service foo: " \ + "Test binary string explanation " \ + "with driver failed programming external connectivity" + mock_log.warn.assert_called_once_with("Host is already in use by another container") def test_ensure_image_exists_no_build(self): service = Service('foo', client=self.mock_client, build={'context': '.'})