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

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
Aanand Prasad 2016-07-25 16:48:28 +01:00
parent 619bf4c4df
commit 887ed8d1b6
3 changed files with 62 additions and 62 deletions

View File

@ -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)

View File

@ -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))

View File

@ -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():