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 argparse
|
||||||
import gzip
|
|
||||||
import platform
|
import platform
|
||||||
import secrets
|
import secrets
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -13,8 +12,6 @@ if platform.system() in ["Darwin", "Windows"]:
|
||||||
elif platform.system() == "Linux":
|
elif platform.system() == "Linux":
|
||||||
CONTAINER_RUNTIME = "podman"
|
CONTAINER_RUNTIME = "podman"
|
||||||
|
|
||||||
ARCH = platform.machine()
|
|
||||||
|
|
||||||
|
|
||||||
def str2bool(v):
|
def str2bool(v):
|
||||||
if isinstance(v, bool):
|
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():
|
def main():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -59,16 +66,15 @@ def main():
|
||||||
help=f"The container runtime for building the image (default: {CONTAINER_RUNTIME})",
|
help=f"The container runtime for building the image (default: {CONTAINER_RUNTIME})",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--no-save",
|
"--platform",
|
||||||
action="store_true",
|
default=None,
|
||||||
help="Do not save the container image as a tarball in share/container.tar.gz",
|
help=f"The platform for building the image (default: current platform)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--compress-level",
|
"--output",
|
||||||
type=int,
|
"-o",
|
||||||
choices=range(0, 10),
|
default=str(Path("share") / "container.tar"),
|
||||||
default=9,
|
help="Path to store the container image",
|
||||||
help="The Gzip compression level, from 0 (lowest) to 9 (highest, default)",
|
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--use-cache",
|
"--use-cache",
|
||||||
|
@ -83,63 +89,62 @@ def main():
|
||||||
default=None,
|
default=None,
|
||||||
help="Provide a custom tag for the image (for development only)",
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
tarball_path = Path("share") / "container.tar.gz"
|
tag = args.tag or f"{args.debian_archive_date}-{determine_git_tag()}"
|
||||||
image_id_path = Path("share") / "image-id.txt"
|
image_name_tagged = f"{IMAGE_NAME}:{tag}"
|
||||||
|
|
||||||
print(f"Building for architecture '{ARCH}'")
|
|
||||||
|
|
||||||
tag = args.tag or determine_git_tag()
|
|
||||||
image_name_tagged = IMAGE_NAME + ":" + tag
|
|
||||||
|
|
||||||
print(f"Will tag the container image as '{image_name_tagged}'")
|
print(f"Will tag the container image as '{image_name_tagged}'")
|
||||||
|
image_id_path = Path("share") / "image-id.txt"
|
||||||
|
if not args.dry:
|
||||||
with open(image_id_path, "w") as f:
|
with open(image_id_path, "w") as f:
|
||||||
f.write(tag)
|
f.write(tag)
|
||||||
|
|
||||||
# Build the container image, and tag it with the calculated tag
|
# Build the container image, and tag it with the calculated tag
|
||||||
print("Building container image")
|
print("Building container image")
|
||||||
cache_args = [] if args.use_cache else ["--no-cache"]
|
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(
|
subprocess.run(
|
||||||
[
|
[
|
||||||
args.runtime,
|
"./dev_scripts/repro-build.py",
|
||||||
"build",
|
"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,
|
*cache_args,
|
||||||
"-f",
|
*platform_args,
|
||||||
"Dockerfile",
|
*rootless_args,
|
||||||
"--tag",
|
"--tag",
|
||||||
image_name_tagged,
|
image_name_tagged,
|
||||||
|
"--output",
|
||||||
|
args.output,
|
||||||
|
"-f",
|
||||||
|
"Dockerfile",
|
||||||
|
BUILD_CONTEXT,
|
||||||
],
|
],
|
||||||
check=True,
|
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__":
|
if __name__ == "__main__":
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
Loading…
Reference in a new issue