Skip to content

Commit

Permalink
Pass dockercfg path straight to docker-py's login
Browse files Browse the repository at this point in the history
This also reuses utils.Dockercfg class
  • Loading branch information
vrutkovs committed Jun 22, 2016
1 parent 20c9769 commit 888d7ac
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 33 deletions.
42 changes: 26 additions & 16 deletions atomic_reactor/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
from atomic_reactor.constants import CONTAINER_SHARE_PATH, CONTAINER_SHARE_SOURCE_SUBDIR,\
BUILD_JSON, DOCKER_SOCKET_PATH
from atomic_reactor.source import get_source_instance_for
from atomic_reactor.util import ImageName, wait_for_command, clone_git_repo, figure_out_dockerfile
from atomic_reactor.util import (
ImageName, wait_for_command, clone_git_repo, figure_out_dockerfile, Dockercfg)


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -440,21 +441,30 @@ def tag_image(self, image, target_image, force=False):
logger.debug('image already tagged correctly, nothing to do')
return target_image.to_str() # this will be the proper name, not just repo/img

def login(self, registry, login, password, email):
logger.info("logging in: registry '%s', login '%s', email '%s'" % (registry, login, email))
response = self.d.login(
username=login,
password=password,
email=email,
registry=registry)
def login(self, registry, docker_secret_path):
"""
login to docker registry
:param registry: registry name
:param docker_secret_path: path to docker config directory
"""
logger.info("logging in: registry '%s', secret path '%s'", registry, docker_secret_path)
# Docker-py needs username
dockercfg = Dockercfg(docker_secret_path)
username = dockercfg.get_credentials(registry)['username']
logger.info("found username %s for registry %s", username, registry)

response = self.d.login(registry=registry, username=username,
dockercfg_path=dockercfg.json_secret_path)
if not response:
raise RuntimeError(
"Failed to login to '%s': email = '%s', login = '%s', password = '%s'" %
(registry, email, login, password))
raise RuntimeError("Failed to login to '%s' with config '%s'" % (registry, dockercfg))
if u'Status' in response and response[u'Status'] == u'Login Succeeded':
logger.info("login succeeded")
else:
logger.debug("response: %r", response)
if not(isinstance(response, dict) and 'password' in response.keys()):
# for some reason docker-py returns the contents of the dockercfg - we shouldn't be
# displaying that
logger.debug("response: %r", response)

def push_image(self, image, insecure=False):
"""
Expand All @@ -479,22 +489,22 @@ def push_image(self, image, insecure=False):
raise RuntimeError("Failed to push image %s" % image)
return command_result.parsed_logs

def tag_and_push_image(self, image, target_image, insecure=False, force=False,
login=None, password=None, email=None):
def tag_and_push_image(self, image, target_image, insecure=False, force=False, dockercfg=None):
"""
tag provided image and push it to registry
:param image: str or ImageName, image id or name
:param target_image: ImageName, img
:param insecure: bool, allow connecting to registry over plain http
:param force: bool, force the tag?
:param dockercfg: path to docker config
:return: str, image (reg.com/img:v1)
"""
logger.info("tagging and pushing image '%s' as '%s'", image, target_image)
logger.debug("image = '%s', target_image = '%s'", image, target_image)
self.tag_image(image, target_image, force=force)
if login and password and email:
self.login(registry=target_image.registry, login=login, password=password, email=email)
if dockercfg:
self.login(registry=target_image.registry, docker_secret_path=dockercfg)
return self.push_image(target_image, insecure=insecure)

def inspect_image(self, image_id):
Expand Down
15 changes: 1 addition & 14 deletions atomic_reactor/plugins/post_tag_and_push.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

from atomic_reactor.plugin import PostBuildPlugin
from atomic_reactor.plugins.exit_remove_built_image import defer_removal
from atomic_reactor.util import Dockercfg


__all__ = ('TagAndPushPlugin', )
Expand Down Expand Up @@ -57,17 +56,6 @@ def run(self):

docker_push_secret = registry_conf.get('secret', None)
self.log.info("Registry %s secret %s", registry, docker_push_secret)
login = password = email = None
if docker_push_secret:
dockercfg = Dockercfg(docker_push_secret)
credentials = dockercfg.get_credentials(registry)
try:
login = credentials['username']
password = credentials['password']
email = credentials['email']
except Exception as e:
self.log.warn("error retrieving credentials", exc_info=True)
login = password = email = None

for image in self.workflow.tag_conf.images:
if image.registry:
Expand All @@ -77,8 +65,7 @@ def run(self):
registry_image.registry = registry
logs = self.tasker.tag_and_push_image(self.workflow.builder.image_id,
registry_image, insecure=insecure,
force=True,
login=login, password=password, email=email)
force=True, dockercfg=docker_push_secret)

pushed_images.append(registry_image)
defer_removal(self.workflow, registry_image)
Expand Down
4 changes: 2 additions & 2 deletions atomic_reactor/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,9 +603,9 @@ def __init__(self, secret_path):
:param secret_path: str, dirname of .dockercfg location
"""

json_secret_path = os.path.join(secret_path, '.dockercfg')
self.json_secret_path = os.path.join(secret_path, '.dockercfg')
try:
with open(json_secret_path) as fp:
with open(self.json_secret_path) as fp:
self.json_secret = json.load(fp)
except Exception:
msg = "failed to read registry secret"
Expand Down
2 changes: 1 addition & 1 deletion tests/plugins/test_tag_and_push.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def test_tag_and_push_plugin(tmpdir, image_name, logs, should_raise, use_secret)
if MOCK:
mock_docker()
flexmock(docker.Client, push=lambda iid, **kwargs: iter(logs),
login=lambda username, password, email, registry: {'Status': 'Login Succeeded'})
login=lambda username, registry, dockercfg_path: {'Status': 'Login Succeeded'})

tasker = DockerTasker()
workflow = DockerBuildWorkflow({"provider": "git", "uri": "asd"}, TEST_IMAGE)
Expand Down

0 comments on commit 888d7ac

Please sign in to comment.