diff --git a/compose/cli/main.py b/compose/cli/main.py index 2b95040ca..ff30d9701 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -33,7 +33,7 @@ def main(): except KeyboardInterrupt: log.error("\nAborting.") sys.exit(1) - except (UserError, NoSuchService, ConfigurationError) as e: + except (UserError, NoSuchService, ConfigurationError, legacy.LegacyContainersError) as e: log.error(e.msg) sys.exit(1) except NoSuchCommand as e: diff --git a/compose/legacy.py b/compose/legacy.py index 8deabfa24..af0c8700b 100644 --- a/compose/legacy.py +++ b/compose/legacy.py @@ -10,6 +10,20 @@ log = logging.getLogger(__name__) # TODO: remove this section when migrate_project_to_labels is removed NAME_RE = re.compile(r'^([^_]+)_([^_]+)_(run_)?(\d+)$') +ERROR_MESSAGE_FORMAT = """ +Compose found the following containers without labels: + +{names_list} + +As of Compose 1.3.0, containers are identified with labels instead of naming convention. If you want to continue using these containers, run: + + $ docker-compose migrate-to-labels + +Alternatively, remove them: + + $ docker rm -f {rm_args} +""" + def check_for_legacy_containers( client, @@ -21,20 +35,30 @@ def check_for_legacy_containers( and warn the user that those containers may need to be migrated to using labels, so that compose can find them. """ - names = get_legacy_container_names( + names = list(get_legacy_container_names( client, project, services, stopped=stopped, - one_off=one_off) + one_off=one_off)) - for name in names: - log.warn( - "Compose found a found a container named %s without any " - "labels. As of compose 1.3.0 containers are identified with " - "labels instead of naming convention. If you'd like compose " - "to use this container, please run " - "`docker-compose migrate-to-labels`" % (name,)) + if names: + raise LegacyContainersError(names) + + +class LegacyContainersError(Exception): + def __init__(self, names): + self.names = names + + self.msg = ERROR_MESSAGE_FORMAT.format( + names_list="\n".join(" {}".format(name) for name in names), + rm_args=" ".join(names), + ) + + def __unicode__(self): + return self.msg + + __str__ = __unicode__ def add_labels(project, container, name): diff --git a/tests/integration/legacy_test.py b/tests/integration/legacy_test.py index 8b0a9b7fc..f3c33e600 100644 --- a/tests/integration/legacy_test.py +++ b/tests/integration/legacy_test.py @@ -1,5 +1,3 @@ -import mock - from compose import legacy from compose.project import Project from .testcases import DockerClientTestCase @@ -49,9 +47,13 @@ class ProjectTest(DockerClientTestCase): self.assertEqual(len(self.get_names(one_off=True)), 1) def test_migration_to_labels(self): - with mock.patch.object(legacy, 'log', autospec=True) as mock_log: + with self.assertRaises(legacy.LegacyContainersError) as cm: self.assertEqual(self.project.containers(stopped=True), []) - self.assertEqual(mock_log.warn.call_count, len(self.services)) + + self.assertEqual( + set(cm.exception.names), + set(['composetest_web_1', 'composetest_db_1']), + ) legacy.migrate_project_to_labels(self.project) self.assertEqual(len(self.project.containers(stopped=True)), len(self.services))