Compare commits

...

6 commits

Author SHA1 Message Date
Alex Pyrgiotis
92d8a4c556
FIXUP: Improve readability 2025-01-14 23:49:43 +02:00
Alex Pyrgiotis
aa710e84c9
FIXUP: Improve the reproducibility check section 2025-01-14 23:47:16 +02:00
Alex Pyrgiotis
c1f25484ff
FIXUP: Invalidate downloaded diffoci helper if checksum differs 2025-01-14 23:43:53 +02:00
Alex Pyrgiotis
6cf4c5cc46
Update docs/developer/reproducibility.md
Co-authored-by: Alexis Métaireau <alexis@freedom.press>
2025-01-14 23:43:46 +02:00
Alex Pyrgiotis
e77580f845
Update docs/developer/reproducibility.md
Co-authored-by: Alexis Métaireau <alexis@freedom.press>
2025-01-14 23:42:49 +02:00
Alex Pyrgiotis
b8755f26ee
FIXUP: Remove stray comment 2025-01-14 23:14:05 +02:00
3 changed files with 46 additions and 34 deletions

View file

@ -25,7 +25,6 @@ def run(*args):
args,
check=True,
stdout=subprocess.PIPE,
# stderr=subprocess.PIPE
).stdout
@ -40,15 +39,27 @@ def git_verify(commit, source):
)
def diffoci_hash_matches(diffoci):
"""Check if the hash of the downloaded diffoci bin matches the expected one."""
m = hashlib.sha256()
m.update(DIFFOCI_PATH.open().read())
diffoci_checksum = m.hexdigest()
return diffoci_checksum == DIFFOCI_CHECKSUM
def diffoci_exists():
"""Check if the diffoci helper exists, and if the hash matches."""
if not DIFFOCI_PATH.exists():
return False
return diffoci_hash_matches(DIFFOCI_PATH.open().read())
def diffoci_download():
"""Download the diffoci tool, based on a URL and its checksum."""
with urllib.request.urlopen(DIFFOCI_URL) as f:
diffoci_bin = f.read()
m = hashlib.sha256()
m.update(diffoci_bin)
diffoci_checksum = m.hexdigest()
if not diffoci_checksum == DIFFOCI_CHECKSUM:
if not diffoci_hash_matches(diffoci_bin):
raise ValueError(
"Unexpected checksum for downloaded diffoci binary:"
f" {diffoci_checksum} !={DIFFOCI_CHECKSUM}"
@ -123,7 +134,7 @@ def main():
commit = git_commit_get()
git_verify(commit, args.source)
if not DIFFOCI_PATH.exists():
if diffoci_exists():
logger.info(f"Downloading diffoci helper from {DIFFOCI_URL}")
diffoci_download()

View file

@ -92,7 +92,7 @@ Here are a few other obstacles that we need to overcome:
### Updating the image
The fact that our image is reproducible also means that it's frozen in time.
This means that rebuilding the image without updating our Dockerfile will not
This means that rebuilding the image without updating our Dockerfile will **not**
receive security updates.
We list the necessary variables that make up our image in the `Dockerfile.env`
@ -103,7 +103,7 @@ file. These are:
* `H2ORESTART_CHECKSUM`: The SHA-256 checksum of the H2ORestart plugin
* `H2ORESTART_VERSION`: The version of the H2ORestart plugin
If you bump these values in `Dockerfile.env`, you can create a new Dockerfile
If you update these values in `Dockerfile.env`, you can create a new Dockerfile
with:
```
@ -113,8 +113,9 @@ poetry run jinja2 Dockerfile.in Dockerfile.env > Dockerfile
### Reproducing the image
For a simple way to reproduce a Dangerzone container image, either local or
pushed to a container registry, you can run the following command in a Linux
environment:
pushed to a container registry, you can checkout the commit this image was built
from (you can find it from the image tag in its `g<commit>` portion), and run
the following command in a Linux environment:
```
./dev_scripts/reproduce.py <image>

View file

@ -27,6 +27,29 @@ def str2bool(v):
raise argparse.ArgumentTypeError("Boolean value expected.")
def determine_tag():
# Designate a unique tag for this image, depending on the Git commit it was created
# from:
# 1. If created from a Git tag (e.g., 0.8.0), the image tag will be `0.8.0`.
# 2. If created from a commit, it will be something like `0.8.0-31-g6bdaa7a`.
# 3. If the contents of the Git repo are dirty, we will append a unique identifier
# for this run, something like `0.8.0-31-g6bdaa7a-fdcb` or `0.8.0-fdcb`.
dirty_ident = secrets.token_hex(2)
return (
subprocess.check_output(
[
"git",
"describe",
"--long",
"--first-parent",
f"--dirty=-{dirty_ident}",
],
)
.decode()
.strip()[1:] # remove the "v" prefix of the tag.
)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
@ -67,30 +90,7 @@ def main():
print(f"Building for architecture '{ARCH}'")
if args.tag:
tag = args.tag
else:
# Designate a unique tag for this image, depending on the Git commit it was created
# from:
# 1. If created from a Git tag (e.g., 0.8.0), the image tag will be `0.8.0`.
# 2. If created from a commit, it will be something like `0.8.0-31-g6bdaa7a`.
# 3. If the contents of the Git repo are dirty, we will append a unique identifier
# for this run, something like `0.8.0-31-g6bdaa7a-fdcb` or `0.8.0-fdcb`.
dirty_ident = secrets.token_hex(2)
tag = (
subprocess.check_output(
[
"git",
"describe",
"--long",
"--first-parent",
f"--dirty=-{dirty_ident}",
],
)
.decode()
.strip()[1:] # remove the "v" prefix of the tag.
)
tag = args.tag or determine_tag()
image_name_tagged = IMAGE_NAME + ":" + tag
print(f"Will tag the container image as '{image_name_tagged}'")