kopia lustrzana https://github.com/jupyterhub/repo2docker
Add registry optional credentials to push()
rodzic
1e61d4f1ae
commit
5e8ee1ca7d
|
@ -120,6 +120,8 @@ class DockerEngine(ContainerEngine):
|
|||
return Image(tags=image["RepoTags"], config=image["ContainerConfig"])
|
||||
|
||||
def push(self, image_spec):
|
||||
if self.registry_credentials:
|
||||
self._apiclient.login(**self.registry_credentials)
|
||||
return self._apiclient.push(image_spec, stream=True)
|
||||
|
||||
def run(
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
Interface for a repo2docker container engine
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from traitlets import Dict, default
|
||||
from traitlets.config import LoggingConfigurable
|
||||
|
||||
# Based on https://docker-py.readthedocs.io/en/4.2.0/containers.html
|
||||
|
@ -142,6 +145,37 @@ class ContainerEngine(LoggingConfigurable):
|
|||
Initialised with a reference to the parent so can also be configured using traitlets.
|
||||
"""
|
||||
|
||||
registry_credentials = Dict(
|
||||
help="""
|
||||
Credentials dictionary, if set will be used to authenticate with
|
||||
the registry. Typically this will include the keys:
|
||||
|
||||
- `username`: The registry username
|
||||
- `password`: The registry password or token
|
||||
- `registry`: The registry URL
|
||||
|
||||
This can also be set by passing a JSON object in the
|
||||
CONTAINER_ENGINE_REGISTRY_CREDENTIALS environment variable.
|
||||
""",
|
||||
config=True,
|
||||
)
|
||||
|
||||
@default("registry_credentials")
|
||||
def _registry_credentials_default(self):
|
||||
"""
|
||||
Set the registry credentials from CONTAINER_ENGINE_REGISTRY_CREDENTIALS
|
||||
"""
|
||||
obj = os.getenv("CONTAINER_ENGINE_REGISTRY_CREDENTIALS")
|
||||
if obj:
|
||||
try:
|
||||
return json.loads(obj)
|
||||
except json.JSONDecodeError:
|
||||
self.log.error(
|
||||
"CONTAINER_ENGINE_REGISTRY_CREDENTIALS is not valid JSON"
|
||||
)
|
||||
raise
|
||||
return {}
|
||||
|
||||
string_output = True
|
||||
"""
|
||||
Whether progress events should be strings or an object.
|
||||
|
@ -251,6 +285,9 @@ class ContainerEngine(LoggingConfigurable):
|
|||
"""
|
||||
Push image to a registry
|
||||
|
||||
If the registry_credentials traitlets is set it should be used to
|
||||
authenticate with the registry before pushing.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image_spec : str
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
import os
|
||||
from subprocess import check_output
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from repo2docker.docker import DockerEngine
|
||||
|
||||
repo_root = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)
|
||||
|
@ -19,3 +22,43 @@ def test_git_credential_env():
|
|||
.strip()
|
||||
)
|
||||
assert out == credential_env
|
||||
|
||||
|
||||
class MockDockerEngine(DockerEngine):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._apiclient = Mock()
|
||||
|
||||
|
||||
def test_docker_push_no_credentials():
|
||||
engine = MockDockerEngine()
|
||||
|
||||
engine.push("image")
|
||||
|
||||
assert len(engine._apiclient.method_calls) == 1
|
||||
engine._apiclient.push.assert_called_once_with("image", stream=True)
|
||||
|
||||
|
||||
def test_docker_push_dict_credentials():
|
||||
engine = MockDockerEngine()
|
||||
engine.registry_credentials = {"username": "abc", "password": "def"}
|
||||
|
||||
engine.push("image")
|
||||
|
||||
assert len(engine._apiclient.method_calls) == 2
|
||||
engine._apiclient.login.assert_called_once_with(username="abc", password="def")
|
||||
engine._apiclient.push.assert_called_once_with("image", stream=True)
|
||||
|
||||
|
||||
def test_docker_push_env_credentials():
|
||||
engine = MockDockerEngine()
|
||||
with patch.dict(
|
||||
"os.environ",
|
||||
{
|
||||
"CONTAINER_ENGINE_REGISTRY_CREDENTIALS": '{"username": "abc", "password": "def"}'
|
||||
},
|
||||
):
|
||||
engine.push("image")
|
||||
|
||||
assert len(engine._apiclient.method_calls) == 2
|
||||
engine._apiclient.login.assert_called_once_with(username="abc", password="def")
|
||||
engine._apiclient.push.assert_called_once_with("image", stream=True)
|
||||
|
|
Ładowanie…
Reference in New Issue