Turn push and load into params for the build arg

pull/1421/head
YuviPanda 2025-02-28 14:16:28 -08:00
rodzic e066ca04a1
commit 07e97ee5ce
3 zmienionych plików z 39 dodań i 72 usunięć

Wyświetl plik

@ -572,55 +572,6 @@ class Repo2Docker(Application):
if self.volumes and not self.run: if self.volumes and not self.run:
raise ValueError("Cannot mount volumes if container is not run") raise ValueError("Cannot mount volumes if container is not run")
def push_image(self):
"""Push docker image to registry"""
client = self.get_engine()
# Build a progress setup for each layer, and only emit per-layer
# info every 1.5s
progress_layers = {}
layers = {}
last_emit_time = time.time()
for chunk in client.push(self.output_image_spec):
if client.string_output:
self.log.info(chunk, extra=dict(phase=R2dState.PUSHING))
continue
# else this is Docker output
# each chunk can be one or more lines of json events
# split lines here in case multiple are delivered at once
for line in chunk.splitlines():
line = line.decode("utf-8", errors="replace")
try:
progress = json.loads(line)
except Exception as e:
self.log.warning("Not a JSON progress line: %r", line)
continue
if "error" in progress:
self.log.error(progress["error"], extra=dict(phase=R2dState.FAILED))
raise ImageLoadError(progress["error"])
if "id" not in progress:
continue
# deprecated truncated-progress data
if "progressDetail" in progress and progress["progressDetail"]:
progress_layers[progress["id"]] = progress["progressDetail"]
else:
progress_layers[progress["id"]] = progress["status"]
# include full progress data for each layer in 'layers' data
layers[progress["id"]] = progress
if time.time() - last_emit_time > 1.5:
self.log.info(
"Pushing image\n",
extra=dict(
progress=progress_layers,
layers=layers,
phase=R2dState.PUSHING,
),
)
last_emit_time = time.time()
self.log.info(
f"Successfully pushed {self.output_image_spec}",
extra=dict(phase=R2dState.PUSHING),
)
def run_image(self): def run_image(self):
"""Run docker container from built image """Run docker container from built image
@ -847,6 +798,12 @@ class Repo2Docker(Application):
extra=dict(phase=R2dState.BUILDING), extra=dict(phase=R2dState.BUILDING),
) )
extra_build_kwargs = self.extra_build_kwargs.copy()
# Set "push" and "load" parameters in a backwards compat way, without
# having to change the signature of every buildpack
extra_build_kwargs["push"] = self.push
extra_build_kwargs["load"] = self.run
for l in picked_buildpack.build( for l in picked_buildpack.build(
docker_client, docker_client,
self.output_image_spec, self.output_image_spec,
@ -854,7 +811,7 @@ class Repo2Docker(Application):
self.build_memory_limit, self.build_memory_limit,
build_args, build_args,
self.cache_from, self.cache_from,
self.extra_build_kwargs, extra_build_kwargs,
platform=self.platform, platform=self.platform,
): ):
if docker_client.string_output: if docker_client.string_output:
@ -886,8 +843,5 @@ class Repo2Docker(Application):
def start(self): def start(self):
self.build() self.build()
if self.push:
self.push_image()
if self.run: if self.run:
self.run_image() self.run_image()

Wyświetl plik

@ -2,13 +2,14 @@
Docker container engine for repo2docker Docker container engine for repo2docker
""" """
from argparse import ArgumentError
import json import json
import os import os
import shutil import shutil
import subprocess import subprocess
import tarfile import tarfile
import tempfile import tempfile
from contextlib import contextmanager from contextlib import ExitStack, contextmanager
from pathlib import Path from pathlib import Path
from iso8601 import parse_date from iso8601 import parse_date
@ -89,6 +90,8 @@ class DockerEngine(ContainerEngine):
def build( def build(
self, self,
push=False,
load=False,
*, *,
buildargs=None, buildargs=None,
cache_from=None, cache_from=None,
@ -104,7 +107,15 @@ class DockerEngine(ContainerEngine):
): ):
if not shutil.which("docker"): if not shutil.which("docker"):
raise RuntimeError("The docker commandline client must be installed") raise RuntimeError("The docker commandline client must be installed")
args = ["docker", "buildx", "build", "--progress", "plain", "--load"] args = ["docker", "buildx", "build", "--progress", "plain"]
if load:
if push:
raise ValueError("Setting push=True and load=True is currently not supported")
args.append("--load")
if push:
args.append("--push")
if buildargs: if buildargs:
for k, v in buildargs.items(): for k, v in buildargs.items():
args += ["--build-arg", f"{k}={v}"] args += ["--build-arg", f"{k}={v}"]
@ -129,19 +140,22 @@ class DockerEngine(ContainerEngine):
# place extra args right *before* the path # place extra args right *before* the path
args += self.extra_buildx_build_args args += self.extra_buildx_build_args
if fileobj: with ExitStack() as stack:
with tempfile.TemporaryDirectory() as d: if self.registry_credentials:
tarf = tarfile.open(fileobj=fileobj) stack.enter_context(self.docker_login(**self.registry_credentials))
tarf.extractall(d) if fileobj:
with tempfile.TemporaryDirectory() as d:
tarf = tarfile.open(fileobj=fileobj)
tarf.extractall(d)
args += [d] args += [d]
yield from execute_cmd(args, True)
else:
# Assume 'path' is passed in
args += [path]
yield from execute_cmd(args, True) yield from execute_cmd(args, True)
else:
# Assume 'path' is passed in
args += [path]
yield from execute_cmd(args, True)
def inspect_image(self, image): def inspect_image(self, image):
""" """
@ -194,13 +208,6 @@ class DockerEngine(ContainerEngine):
else: else:
del os.environ["DOCKER_CONFIG"] del os.environ["DOCKER_CONFIG"]
def push(self, image_spec):
if self.registry_credentials:
with self.docker_login(**self.registry_credentials):
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,
image_spec, image_spec,

Wyświetl plik

@ -212,6 +212,8 @@ class ContainerEngine(LoggingConfigurable):
def build( def build(
self, self,
push=False,
load=False,
*, *,
buildargs={}, buildargs={},
cache_from=[], cache_from=[],
@ -230,6 +232,10 @@ class ContainerEngine(LoggingConfigurable):
Parameters Parameters
---------- ----------
push: bool
Push the resulting image to a registry
load: bool
Load the resulting image into the container store ready to be run
buildargs : dict buildargs : dict
Dictionary of build arguments Dictionary of build arguments
cache_from : list[str] cache_from : list[str]