diff options
Diffstat (limited to 'scripts/obs/lib/docker.py')
-rw-r--r-- | scripts/obs/lib/docker.py | 89 |
1 files changed, 73 insertions, 16 deletions
diff --git a/scripts/obs/lib/docker.py b/scripts/obs/lib/docker.py index a5dbcd9..779099b 100644 --- a/scripts/obs/lib/docker.py +++ b/scripts/obs/lib/docker.py @@ -8,11 +8,41 @@ import lib import lib.config -def build_image(): - print(f"docker: building image {lib.config.docker_image_name}") +def get_image_name(distro, image_type): + ret = f"{distro}-osmocom-obs-{image_type}" + ret = ret.replace(":","-").replace("_","-") + return ret + + +def get_distro_from(distro, image_type): + # Manuals: depend on regular image (data/build_binpkg_manuals.Dockerfile) + if image_type.endswith("_manuals"): + return get_image_name(distro, image_type.replace("_manuals", "")) + + return distro + + +def build_image(distro, image_type): + image_name = get_image_name(distro, image_type) + distro_from = get_distro_from(distro, image_type) + + print(f"docker: building image {image_name}") + + # Set the feed of packages to be configured inside the docker container + # (master, nightly, latest). This can be set with build_binpkg.py --feed, + # to reproduce a build error that happens with a distro that is only in + # nightly but not in the master feed (all ubuntu versions as of writing). + build_arg_feed = [] + if getattr(lib.args, "docker_feed", None): + build_arg_feed = ["--build-arg", f"FEED={lib.args.docker_feed}"] + lib.run_cmd(["docker", "build", - "--build-arg", f"UID={os.getuid()}", - "-t", lib.config.docker_image_name, + "--build-arg", f"DISTRO={distro}", + "--build-arg", f"DISTRO_FROM={distro_from}", + "--build-arg", f"UID={os.getuid()}"] + + build_arg_feed + + ["-t", image_name, + "-f", f"{lib.config.path_top}/data/{image_type}.Dockerfile", f"{lib.config.path_top}/data"]) @@ -25,38 +55,65 @@ def get_oscrc(): return os.path.realpath(ret) print("ERROR: couldn't find ~/.oscrc. Put it there or set OSCRC.") - exit(1) + sys.exit(1) -def run_in_docker_and_exit(script_path, args, add_oscrc=False): +def run_in_docker_and_exit(script_path, add_oscrc=False, + image_type="build_srcpkg", distro=None, + pass_argv=True, env={}, docker_args=[]): + """ + :param script_path: what to run inside docker, relative to scripts/obs/ + :param add_oscrc: put user's oscrc in docker (contains obs credentials!) + :param image_type: which Dockerfile to use (data/{image_type}.Dockerfile) + :param distro: which Linux distribution to use, e.g. "debian:11" + :param pass_argv: pass arguments from sys.argv to the script + :param env: dict of environment variables + :param docker_args: extra arguments to pass to docker + """ if "INSIDE_DOCKER" in os.environ: return if not shutil.which("docker"): print("ERROR: docker is not installed") - exit(1) + sys.exit(1) + + if not distro: + distro = lib.config.docker_distro_default + image_name = get_image_name(distro, image_type) oscrc = None if add_oscrc: oscrc = get_oscrc() - # Build the docker image. Unless it is up-to-date, this will take a few - # minutes or so, therefore print the output. + # Unless the docker image is up-to-date, building will take a few + # minutes or so, therefore print the output. No need to restore + # set_cmds_verbose, as we use subprocess.run() below and exit afterwards. lib.set_cmds_verbose(True) - build_image() - lib.set_cmds_verbose(args.verbose) + + # Manuals: build regular image first (data/build_binpkg_manuals.Dockerfile) + if image_type.endswith("_manuals"): + build_image(distro, image_type.replace("_manuals","")) + + build_image(distro, image_type) cmd = ["docker", "run", + "--rm", "-e", "INSIDE_DOCKER=1", "-e", "PYTHONUNBUFFERED=1", - "--rm", "-v", f"{lib.config.path_top}:/obs"] + "-v", f"{lib.config.path_top}:/obs"] + + for env_key, env_val in env.items(): + cmd += ["-e", f"{env_key}={env_val}"] if oscrc: cmd += ["-v", f"{oscrc}:/home/user/.oscrc"] - script_path = f"/obs/{os.path.basename(script_path)}" - cmd += [lib.config.docker_image_name, script_path] + sys.argv[1:] + cmd += docker_args + cmd += [image_name, f"/obs/{script_path}"] + + if pass_argv: + cmd += sys.argv[1:] - print(f"docker: running: {os.path.basename(script_path)} inside docker") + print(f"docker: running: {script_path} inside docker") ret = subprocess.run(cmd) - exit(ret.returncode) + sys.exit(ret.returncode) |