mirror of
https://github.com/d9pouces/id_configurator.git
synced 2026-11-09 01:47:21 +01:00
4e4b0592c0
Signed-off-by: d9pouces <github@19pouces.net>
174 lines
7.0 KiB
Python
174 lines
7.0 KiB
Python
import logging
|
|
import subprocess
|
|
import tempfile
|
|
|
|
import typer
|
|
|
|
from id_tools.config import SourceConfig
|
|
|
|
app = typer.Typer(help="Build utilities for JS/CSS files and emails templates")
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# noinspection SpellCheckingInspection
|
|
DOCKER_FILE_BUILDER = r"""# This file is part of Interdiode
|
|
# Copyright (c) {build_year} InterDiode <contact@mail.interdiode.fr>
|
|
# All Rights Reserved
|
|
########################################################################################################################
|
|
# This file is generated by id_tools/build.py. Do not edit it manually.
|
|
########################################################################################################################
|
|
FROM dhi.io/python:{python_version}-{docker_version} AS interdiode-base
|
|
########################################################################################################################
|
|
# generate the package and download required some tools in a first image
|
|
########################################################################################################################
|
|
FROM interdiode-base AS interdiode-builder
|
|
ENV{docker_env}
|
|
USER root
|
|
RUN mkdir -p /src /usr/local/interdiode
|
|
RUN chown -R {docker_user}:{docker_group} /src /usr/local/interdiode
|
|
COPY ./pyproject.toml /src/pyproject.toml
|
|
COPY ./README.md /src/README.md
|
|
COPY ./LICENSE /src/LICENSE
|
|
COPY ./id_configurator /src/id_configurator
|
|
COPY ./tests /src/tests
|
|
RUN chown -R {docker_user}:{docker_group} /src
|
|
USER {docker_user}
|
|
RUN python3 -m pip install --user pip uv --upgrade
|
|
WORKDIR /src
|
|
RUN python3 -m uv build
|
|
"""
|
|
# noinspection SpellCheckingInspection
|
|
DOCKER_FILE_INSTALL = r"""
|
|
########################################################################################################################
|
|
# install the package without the build dependencies
|
|
########################################################################################################################
|
|
FROM interdiode-base AS interdiode-install
|
|
ENV{docker_env}
|
|
COPY --from=interdiode-builder /src/dist /tmp/dist
|
|
RUN apt-get update
|
|
RUN DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confnew" --allow-downgrades --allow-remove-essential --allow-unauthenticated -fuy dist-upgrade
|
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install --yes -qq --no-install-recommends build-essential
|
|
RUN mkdir -p /src/build /chroot/usr/local/bin /usr/local/interdiode \
|
|
&& chown -R {docker_user}:{docker_group} /usr/local/interdiode /tmp/dist
|
|
USER {docker_user}
|
|
RUN /bin/sh -c "python3 -m pip install --user /tmp/dist/*.whl"
|
|
"""
|
|
# noinspection SpellCheckingInspection
|
|
DOCKER_FILE_RUNTIME = r"""########################################################################################################################
|
|
# copy the installed packages
|
|
########################################################################################################################
|
|
FROM interdiode-base AS interdiode-runtime
|
|
ENV{docker_env}
|
|
LABEL org.opencontainers.image.authors="contact@mail.interdiode.fr"
|
|
LABEL org.opencontainers.image.created="{build_date}"
|
|
LABEL org.opencontainers.image.description="Air gap made simple!"
|
|
LABEL org.opencontainers.image.documentation="{documentation_url}"
|
|
LABEL org.opencontainers.image.licenses="LicenseRef-InterDiode-Commercial-1.0"
|
|
LABEL org.opencontainers.image.revision="{vcs_revision}"
|
|
LABEL org.opencontainers.image.title="InterDiode Configurator"
|
|
LABEL org.opencontainers.image.url="{interdiode_url}"
|
|
LABEL org.opencontainers.image.vendor="InterDiode"
|
|
LABEL org.opencontainers.image.version="{id_configurator_version}"
|
|
LABEL description="Air gap made simple!"
|
|
COPY --from=interdiode-install --chown=0:0 /chroot/usr/local/bin /usr/local/bin
|
|
COPY --from=interdiode-install /usr/local/interdiode /usr/local/interdiode
|
|
RUN DEBIAN_FRONTEND=noninteractive mkdir -p /usr/local/interdiode \
|
|
&& chown -R {docker_user}:{docker_group} /usr/local/interdiode
|
|
COPY ./LICENSE /chroot/licenses/LICENSE
|
|
COPY ./LICENSE /chroot/usr/share/doc/interdiode/LICENSE
|
|
WORKDIR /
|
|
"""
|
|
|
|
|
|
def build_docker_image(
|
|
config: SourceConfig,
|
|
registry: str | None = None,
|
|
platform: str = "linux/amd64",
|
|
push: bool = False,
|
|
) -> bool:
|
|
"""Build the Docker image."""
|
|
if push and not registry:
|
|
raise ValueError("--push requires --registry to be set.")
|
|
version = config.get_project_version()
|
|
name = config.get_project_name()
|
|
values = config.get_parameters()
|
|
package_build = DOCKER_FILE_BUILDER.format(**values)
|
|
v_tag = f"{name}:{version}"
|
|
l_tag = f"{name}:latest"
|
|
image_install = DOCKER_FILE_INSTALL.format(**values)
|
|
image_build = DOCKER_FILE_RUNTIME.format(**values)
|
|
with (
|
|
tempfile.NamedTemporaryFile(
|
|
mode="w", delete=True, prefix="Dockerfile.", suffix=".package"
|
|
) as fd,
|
|
):
|
|
fd.write(package_build)
|
|
fd.write(image_install)
|
|
fd.write(image_build)
|
|
fd.flush()
|
|
# noinspection SpellCheckingInspection
|
|
cmd = [
|
|
"docker",
|
|
"buildx",
|
|
"build",
|
|
"--no-cache",
|
|
"--attest",
|
|
"type=provenance,mode=max,version=v1",
|
|
"--attest",
|
|
"type=sbom",
|
|
"--platform",
|
|
platform,
|
|
"-f",
|
|
fd.name,
|
|
]
|
|
if registry:
|
|
cmd += ["-t", f"{registry}/{v_tag}", "-t", f"{registry}/{l_tag}"]
|
|
else:
|
|
cmd += ["-t", f"{registry}/{v_tag}", "-t", f"{registry}/{l_tag}"]
|
|
if push and registry:
|
|
cmd.insert(3, "--push")
|
|
cmd.append(".")
|
|
try:
|
|
typer.echo(f"Building Docker image {v_tag} for platform {platform}...")
|
|
typer.echo(" ".join(cmd))
|
|
subprocess.check_call(cmd, cwd=config.source_dir)
|
|
except subprocess.CalledProcessError:
|
|
return False
|
|
return True
|
|
|
|
|
|
# noinspection SpellCheckingInspection
|
|
@app.command(name="docker", help="Build the Docker image.")
|
|
def docker_image(
|
|
registry: str = typer.Option(
|
|
"interdiode", help="The registry to publish the Docker image to."
|
|
),
|
|
platform: str = typer.Option(
|
|
"linux/amd64", help="Platform(s) of the Docker image."
|
|
),
|
|
docker_version: str = typer.Option(
|
|
"debian13-dev", help="Version of the base Docker image."
|
|
),
|
|
push: bool = typer.Option(
|
|
False, "--push", help="Push the built image(s) to the registry."
|
|
),
|
|
docker_login: str = typer.Option(
|
|
"", envvar="DOCKER_HUB_LOGIN", help="Nom d'utilisateur Docker"
|
|
),
|
|
docker_token: str = typer.Option(
|
|
"", envvar="DOCKER_HUB_TOKEN", help="Jeton d'accès Docker"
|
|
),
|
|
):
|
|
config = SourceConfig(docker_version)
|
|
if docker_login and docker_token:
|
|
cmd = ["docker", "login", "-u", docker_login, "--password-stdin"]
|
|
subprocess.run(
|
|
cmd, input=docker_token, text=True, check=True, cwd=config.source_dir
|
|
)
|
|
|
|
success = build_docker_image(
|
|
config, registry=registry, platform=platform, push=push
|
|
)
|
|
if not success:
|
|
raise typer.Exit(code=1)
|