mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
Build container image using repro-build
Invoke the `repro-build` script when building a container image, instead of the underlying Docker/Podman commands. The `repro-build` script handles the underlying complexity to call Docker/Podman in a manner that makes the image reproducible. Moreover, mirror some arguments from the `repro-build` script, so that consumers of `build-image.py` can pass them to it. Important: the resulting image will be in .tar format, not .tar.gz, starting from this commit. This means that our tests will be broken for the next few commits. Fixes #1074
This commit is contained in:
parent
94fad78f94
commit
69234507c4
1 changed files with 55 additions and 50 deletions
|
@ -1,5 +1,4 @@
|
|||
import argparse
|
||||
import gzip
|
||||
import platform
|
||||
import secrets
|
||||
import subprocess
|
||||
|
@ -13,8 +12,6 @@ if platform.system() in ["Darwin", "Windows"]:
|
|||
elif platform.system() == "Linux":
|
||||
CONTAINER_RUNTIME = "podman"
|
||||
|
||||
ARCH = platform.machine()
|
||||
|
||||
|
||||
def str2bool(v):
|
||||
if isinstance(v, bool):
|
||||
|
@ -50,6 +47,16 @@ def determine_git_tag():
|
|||
)
|
||||
|
||||
|
||||
def determine_debian_archive_date():
|
||||
"""Get the date of the Debian archive from Dockerfile.env."""
|
||||
for env in Path("Dockerfile.env").read_text().split("\n"):
|
||||
if env.startswith("DEBIAN_ARCHIVE_DATE"):
|
||||
return env.split("=")[1]
|
||||
raise Exception(
|
||||
"Could not find 'DEBIAN_ARCHIVE_DATE' build argument in Dockerfile.env"
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
|
@ -59,16 +66,15 @@ def main():
|
|||
help=f"The container runtime for building the image (default: {CONTAINER_RUNTIME})",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-save",
|
||||
action="store_true",
|
||||
help="Do not save the container image as a tarball in share/container.tar.gz",
|
||||
"--platform",
|
||||
default=None,
|
||||
help=f"The platform for building the image (default: current platform)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--compress-level",
|
||||
type=int,
|
||||
choices=range(0, 10),
|
||||
default=9,
|
||||
help="The Gzip compression level, from 0 (lowest) to 9 (highest, default)",
|
||||
"--output",
|
||||
"-o",
|
||||
default=str(Path("share") / "container.tar"),
|
||||
help="Path to store the container image",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--use-cache",
|
||||
|
@ -83,63 +89,62 @@ def main():
|
|||
default=None,
|
||||
help="Provide a custom tag for the image (for development only)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debian-archive-date",
|
||||
"-d",
|
||||
default=determine_debian_archive_date(),
|
||||
help="Use a specific Debian snapshot archive, by its date (default %(default)s)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Do not run any commands, just print what would happen",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
tarball_path = Path("share") / "container.tar.gz"
|
||||
image_id_path = Path("share") / "image-id.txt"
|
||||
|
||||
print(f"Building for architecture '{ARCH}'")
|
||||
|
||||
tag = args.tag or determine_git_tag()
|
||||
image_name_tagged = IMAGE_NAME + ":" + tag
|
||||
tag = args.tag or f"{args.debian_archive_date}-{determine_git_tag()}"
|
||||
image_name_tagged = f"{IMAGE_NAME}:{tag}"
|
||||
|
||||
print(f"Will tag the container image as '{image_name_tagged}'")
|
||||
with open(image_id_path, "w") as f:
|
||||
f.write(tag)
|
||||
image_id_path = Path("share") / "image-id.txt"
|
||||
if not args.dry:
|
||||
with open(image_id_path, "w") as f:
|
||||
f.write(tag)
|
||||
|
||||
# Build the container image, and tag it with the calculated tag
|
||||
print("Building container image")
|
||||
cache_args = [] if args.use_cache else ["--no-cache"]
|
||||
platform_args = [] if not args.platform else ["--platform", args.platform]
|
||||
rootless_args = [] if args.runtime == "docker" else ["--rootless"]
|
||||
rootless_args = []
|
||||
dry_args = [] if not args.dry else ["--dry"]
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
args.runtime,
|
||||
"./dev_scripts/repro-build.py",
|
||||
"build",
|
||||
BUILD_CONTEXT,
|
||||
"--runtime",
|
||||
args.runtime,
|
||||
"--build-arg",
|
||||
f"DEBIAN_ARCHIVE_DATE={args.debian_archive_date}",
|
||||
"--datetime",
|
||||
args.debian_archive_date,
|
||||
*dry_args,
|
||||
*cache_args,
|
||||
"-f",
|
||||
"Dockerfile",
|
||||
*platform_args,
|
||||
*rootless_args,
|
||||
"--tag",
|
||||
image_name_tagged,
|
||||
"--output",
|
||||
args.output,
|
||||
"-f",
|
||||
"Dockerfile",
|
||||
BUILD_CONTEXT,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
|
||||
if not args.no_save:
|
||||
print("Saving container image")
|
||||
cmd = subprocess.Popen(
|
||||
[
|
||||
CONTAINER_RUNTIME,
|
||||
"save",
|
||||
image_name_tagged,
|
||||
],
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
print("Compressing container image")
|
||||
chunk_size = 4 << 20
|
||||
with gzip.open(
|
||||
tarball_path,
|
||||
"wb",
|
||||
compresslevel=args.compress_level,
|
||||
) as gzip_f:
|
||||
while True:
|
||||
chunk = cmd.stdout.read(chunk_size)
|
||||
if len(chunk) > 0:
|
||||
gzip_f.write(chunk)
|
||||
else:
|
||||
break
|
||||
cmd.wait(5)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
Loading…
Reference in a new issue