Przeglądaj źródła

Rename --fetch-digests to --push-images and remove auto-pull

Signed-off-by: Aanand Prasad <[email protected]>
Aanand Prasad 9 lat temu
rodzic
commit
887ed8d1b6
3 zmienionych plików z 55 dodań i 55 usunięć
  1. 18 21
      compose/bundle.py
  2. 27 10
      compose/cli/main.py
  3. 10 24
      tests/unit/bundle_test.py

+ 18 - 21
compose/bundle.py

@@ -60,7 +60,7 @@ def serialize_bundle(config, image_digests):
     return json.dumps(to_bundle(config, image_digests), indent=2, sort_keys=True)
 
 
-def get_image_digests(project, allow_fetch=False):
+def get_image_digests(project, allow_push=False):
     digests = {}
     needs_push = set()
     needs_pull = set()
@@ -69,7 +69,7 @@ def get_image_digests(project, allow_fetch=False):
         try:
             digests[service.name] = get_image_digest(
                 service,
-                allow_fetch=allow_fetch,
+                allow_push=allow_push,
             )
         except NeedsPush as e:
             needs_push.add(e.image_name)
@@ -82,7 +82,7 @@ def get_image_digests(project, allow_fetch=False):
     return digests
 
 
-def get_image_digest(service, allow_fetch=False):
+def get_image_digest(service, allow_push=False):
     if 'image' not in service.options:
         raise UserError(
             "Service '{s.name}' doesn't define an image tag. An image name is "
@@ -108,27 +108,24 @@ def get_image_digest(service, allow_fetch=False):
         # digests
         return image['RepoDigests'][0]
 
-    if not allow_fetch:
-        if 'build' in service.options:
-            raise NeedsPush(service.image_name)
-        else:
-            raise NeedsPull(service.image_name)
+    if 'build' not in service.options:
+        raise NeedsPull(service.image_name)
 
-    return fetch_image_digest(service)
+    if not allow_push:
+        raise NeedsPush(service.image_name)
 
+    return push_image(service)
 
-def fetch_image_digest(service):
-    if 'build' not in service.options:
-        digest = service.pull()
-    else:
-        try:
-            digest = service.push()
-        except:
-            log.error(
-                "Failed to push image for service '{s.name}'. Please use an "
-                "image tag that can be pushed to a Docker "
-                "registry.".format(s=service))
-            raise
+
+def push_image(service):
+    try:
+        digest = service.push()
+    except:
+        log.error(
+            "Failed to push image for service '{s.name}'. Please use an "
+            "image tag that can be pushed to a Docker "
+            "registry.".format(s=service))
+        raise
 
     if not digest:
         raise ValueError("Failed to get digest for %s" % service.name)

+ 27 - 10
compose/cli/main.py

@@ -223,15 +223,16 @@ class TopLevelCommand(object):
         Generate a Distributed Application Bundle (DAB) from the Compose file.
 
         Images must have digests stored, which requires interaction with a
-        Docker registry. If digests aren't stored for all images, you can pass
-        `--fetch-digests` to automatically fetch them. Images for services
-        with a `build` key will be pushed. Images for services without a
-        `build` key will be pulled.
+        Docker registry. If digests aren't stored for all images, you can fetch
+        them with `docker-compose pull` or `docker-compose push`. To push images
+        automatically when bundling, pass `--push-images`. Only services with
+        a `build` option specified will have their images pushed.
 
         Usage: bundle [options]
 
         Options:
-            --fetch-digests            Automatically fetch image digests if missing
+            --push-images              Automatically push images for any services
+                                       which have a `build` option specified.
 
             -o, --output PATH          Path to write the bundle file to.
                                        Defaults to "<project name>.dab".
@@ -247,7 +248,7 @@ class TopLevelCommand(object):
             try:
                 image_digests = get_image_digests(
                     self.project,
-                    allow_fetch=options['--fetch-digests'],
+                    allow_push=options['--push-images'],
                 )
             except MissingDigests as e:
                 def list_images(images):
@@ -256,12 +257,28 @@ class TopLevelCommand(object):
                 paras = ["Some images are missing digests."]
 
                 if e.needs_push:
-                    paras += ["The following images need to be pushed:", list_images(e.needs_push)]
+                    command_hint = (
+                        "Use `docker-compose push {}` to push them. "
+                        "You can do this automatically with `docker-compose bundle --push-images`."
+                        .format(" ".join(sorted(e.needs_push)))
+                    )
+                    paras += [
+                        "The following images can be pushed:",
+                        list_images(e.needs_push),
+                        command_hint,
+                    ]
 
                 if e.needs_pull:
-                    paras += ["The following images need to be pulled:", list_images(e.needs_pull)]
-
-                paras.append("If this is OK, run `docker-compose bundle --fetch-digests`.")
+                    command_hint = (
+                        "Use `docker-compose pull {}` to pull them. "
+                        .format(" ".join(sorted(e.needs_pull)))
+                    )
+
+                    paras += [
+                        "The following images need to be pulled:",
+                        list_images(e.needs_pull),
+                        command_hint,
+                    ]
 
                 raise UserError("\n\n".join(paras))
 

+ 10 - 24
tests/unit/bundle_test.py

@@ -41,44 +41,30 @@ def test_get_image_digest_no_image(mock_service):
     assert "doesn't define an image tag" in exc.exconly()
 
 
-def test_fetch_image_digest_for_image_with_saved_digest(mock_service):
+def test_push_image_with_saved_digest(mock_service):
+    mock_service.options['build'] = '.'
     mock_service.options['image'] = image_id = 'abcd'
-    mock_service.pull.return_value = expected = 'sha256:thedigest'
+    mock_service.push.return_value = expected = 'sha256:thedigest'
     mock_service.image.return_value = {'RepoDigests': ['digest1']}
 
-    digest = bundle.fetch_image_digest(mock_service)
-    assert digest == image_id + '@' + expected
-
-    mock_service.pull.assert_called_once_with()
-    assert not mock_service.push.called
-    assert not mock_service.client.pull.called
-
-
-def test_fetch_image_digest_for_image(mock_service):
-    mock_service.options['image'] = image_id = 'abcd'
-    mock_service.pull.return_value = expected = 'sha256:thedigest'
-    mock_service.image.return_value = {'RepoDigests': []}
-
-    digest = bundle.fetch_image_digest(mock_service)
+    digest = bundle.push_image(mock_service)
     assert digest == image_id + '@' + expected
 
-    mock_service.pull.assert_called_once_with()
-    assert not mock_service.push.called
-    mock_service.client.pull.assert_called_once_with(digest)
+    mock_service.push.assert_called_once_with()
+    assert not mock_service.client.push.called
 
 
-def test_fetch_image_digest_for_build(mock_service):
+def test_push_image(mock_service):
     mock_service.options['build'] = '.'
     mock_service.options['image'] = image_id = 'abcd'
     mock_service.push.return_value = expected = 'sha256:thedigest'
-    mock_service.image.return_value = {'RepoDigests': ['digest1']}
+    mock_service.image.return_value = {'RepoDigests': []}
 
-    digest = bundle.fetch_image_digest(mock_service)
+    digest = bundle.push_image(mock_service)
     assert digest == image_id + '@' + expected
 
     mock_service.push.assert_called_once_with()
-    assert not mock_service.pull.called
-    assert not mock_service.client.pull.called
+    mock_service.client.pull.assert_called_once_with(digest)
 
 
 def test_to_bundle():