mirror of https://github.com/docker/compose.git
Rename --fetch-digests to --push-images and remove auto-pull
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
parent
619bf4c4df
commit
887ed8d1b6
|
@ -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)
|
||||
|
||||
return fetch_image_digest(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
|
||||
raise NeedsPull(service.image_name)
|
||||
|
||||
if not allow_push:
|
||||
raise NeedsPush(service.image_name)
|
||||
|
||||
return push_image(service)
|
||||
|
||||
|
||||
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)
|
||||
|
|
|
@ -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)]
|
||||
command_hint = (
|
||||
"Use `docker-compose pull {}` to pull them. "
|
||||
.format(" ".join(sorted(e.needs_pull)))
|
||||
)
|
||||
|
||||
paras.append("If this is OK, run `docker-compose bundle --fetch-digests`.")
|
||||
paras += [
|
||||
"The following images need to be pulled:",
|
||||
list_images(e.needs_pull),
|
||||
command_hint,
|
||||
]
|
||||
|
||||
raise UserError("\n\n".join(paras))
|
||||
|
||||
|
|
|
@ -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):
|
||||
mock_service.options['image'] = image_id = 'abcd'
|
||||
mock_service.pull.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)
|
||||
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)
|
||||
|
||||
|
||||
def test_fetch_image_digest_for_build(mock_service):
|
||||
def test_push_image_with_saved_digest(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']}
|
||||
|
||||
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
|
||||
assert not mock_service.client.push.called
|
||||
|
||||
|
||||
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': []}
|
||||
|
||||
digest = bundle.push_image(mock_service)
|
||||
assert digest == image_id + '@' + expected
|
||||
|
||||
mock_service.push.assert_called_once_with()
|
||||
mock_service.client.pull.assert_called_once_with(digest)
|
||||
|
||||
|
||||
def test_to_bundle():
|
||||
|
|
Loading…
Reference in New Issue