kopia lustrzana https://github.com/jupyterhub/repo2docker
Use CLI to push docker image
Preserves existing authentication information handling behavior: 1. If registry_credentials are present, they are used but not leaked on to existing ~/.docker/config 2. If registry_credentials are not present, they are not used 3. Regardless of registry_credentials being present, we still will use existing authentication info in DOCKER_CONFIGpull/1421/head
rodzic
17a23c4ae6
commit
ac0def4028
|
@ -2,9 +2,13 @@
|
||||||
Docker container engine for repo2docker
|
Docker container engine for repo2docker
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import subprocess
|
||||||
import tarfile
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from contextlib import contextmanager
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from iso8601 import parse_date
|
from iso8601 import parse_date
|
||||||
from traitlets import Dict, List, Unicode
|
from traitlets import Dict, List, Unicode
|
||||||
|
@ -58,7 +62,7 @@ class DockerEngine(ContainerEngine):
|
||||||
https://docker-py.readthedocs.io/en/4.2.0/api.html#module-docker.api.build
|
https://docker-py.readthedocs.io/en/4.2.0/api.html#module-docker.api.build
|
||||||
"""
|
"""
|
||||||
|
|
||||||
string_output = False
|
string_output = True
|
||||||
|
|
||||||
extra_init_args = Dict(
|
extra_init_args = Dict(
|
||||||
{},
|
{},
|
||||||
|
@ -141,18 +145,12 @@ class DockerEngine(ContainerEngine):
|
||||||
|
|
||||||
args += [d]
|
args += [d]
|
||||||
|
|
||||||
for line in execute_cmd(args, True):
|
yield from execute_cmd(args, True)
|
||||||
# Simulate structured JSON output from buildx build, since we
|
|
||||||
# do get structured json output from pushing and running
|
|
||||||
yield {"stream": line}
|
|
||||||
else:
|
else:
|
||||||
# Assume 'path' is passed in
|
# Assume 'path' is passed in
|
||||||
args += [path]
|
args += [path]
|
||||||
|
|
||||||
for line in execute_cmd(args, True):
|
yield from execute_cmd(args, True)
|
||||||
# Simulate structured JSON output from buildx build, since we
|
|
||||||
# do get structured json output from pushing and running
|
|
||||||
yield {"stream": line}
|
|
||||||
|
|
||||||
def images(self):
|
def images(self):
|
||||||
images = self._apiclient.images()
|
images = self._apiclient.images()
|
||||||
|
@ -162,10 +160,42 @@ class DockerEngine(ContainerEngine):
|
||||||
image = self._apiclient.inspect_image(image)
|
image = self._apiclient.inspect_image(image)
|
||||||
return Image(tags=image["RepoTags"], config=image["Config"])
|
return Image(tags=image["RepoTags"], config=image["Config"])
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def docker_login(self, username, password, registry):
|
||||||
|
# Determine existing DOCKER_CONFIG
|
||||||
|
dc_path = Path(
|
||||||
|
os.environ.get("DOCKER_CONFIG", os.path.expanduser("~/.docker/config.json"))
|
||||||
|
)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
new_dc_path = Path(d) / "config.json"
|
||||||
|
if dc_path.exists():
|
||||||
|
# If there is an existing DOCKER_CONFIG, copy it to new location so we inherit
|
||||||
|
# whatever configuration the user has already set
|
||||||
|
shutil.copy2(dc_path, new_dc_path)
|
||||||
|
|
||||||
|
env = os.environ.copy()
|
||||||
|
subprocess.check_call(
|
||||||
|
# FIXME: This should be using --password-stdin instead
|
||||||
|
[
|
||||||
|
"docker",
|
||||||
|
"login",
|
||||||
|
"--username",
|
||||||
|
username,
|
||||||
|
"--password",
|
||||||
|
password,
|
||||||
|
registry,
|
||||||
|
],
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
|
||||||
def push(self, image_spec):
|
def push(self, image_spec):
|
||||||
if self.registry_credentials:
|
if self.registry_credentials:
|
||||||
self._apiclient.login(**self.registry_credentials)
|
with self.docker_login(**self.registry_credentials):
|
||||||
return self._apiclient.push(image_spec, stream=True)
|
yield from execute_cmd(["docker", "push", image_spec], capture=True)
|
||||||
|
else:
|
||||||
|
yield from execute_cmd(["docker", "push", image_spec], capture=True)
|
||||||
|
|
||||||
def run(
|
def run(
|
||||||
self,
|
self,
|
||||||
|
|
Ładowanie…
Reference in New Issue