diff --git a/README.md b/README.md index 20127142..4a7a390f 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,8 @@ assembles it into an image. Pipelines are defined as JSON files like this one: "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": [ "@Core", "grub2-pc", "httpd" ] diff --git a/samples/base-from-yum.json b/samples/base-from-yum.json index 81ee988d..a786c99a 100644 --- a/samples/base-from-yum.json +++ b/samples/base-from-yum.json @@ -32,7 +32,8 @@ "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": [ diff --git a/samples/base-qcow2.json b/samples/base-qcow2.json index 8adafbfd..d4325266 100644 --- a/samples/base-qcow2.json +++ b/samples/base-qcow2.json @@ -10,7 +10,8 @@ "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": [ diff --git a/samples/base.json b/samples/base.json index 2ced87e7..9ae42f1b 100644 --- a/samples/base.json +++ b/samples/base.json @@ -9,7 +9,8 @@ "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": [ diff --git a/stages/org.osbuild.dnf b/stages/org.osbuild.dnf index 30a32feb..9971750a 100755 --- a/stages/org.osbuild.dnf +++ b/stages/org.osbuild.dnf @@ -1,5 +1,6 @@ #!/usr/bin/python3 +import hashlib import json import subprocess import sys @@ -27,6 +28,29 @@ def write_repofile(f, repoid, repo): write_option("gpgkey", f"file://{keyfile}") +def dnf_cachedir(repoid, repo, releasever, basearch): + """Return the relative cache directory for a repository. + + Using the same algorithm as libdnf: + + https://github.com/rpm-software-management/libdnf/blob/master/libdnf/repo/Repo.cpp#L1288 + """ + + if "metalink" in repo: + url = repo["metalink"] + elif "mirrorlist" in repo: + url = repo["mirrorlist"] + elif "baseurl" in repo: + url = repo["baseurl"] + else: + raise RuntimeError(f"one of metalink, mirrorlist, or baseurl must be given for repository '{repoid}'") + + url = url.replace("$basearch", basearch).replace("$releasever", releasever) + digest = hashlib.sha256(url.encode()).hexdigest()[:16] + + return f"{repoid}-{digest}" + + def main(tree, options): repos = options["repos"] packages = options["packages"] @@ -65,7 +89,18 @@ def main(tree, options): ] + packages print(" ".join(cmd), flush=True) - return subprocess.run(cmd).returncode + subprocess.run(cmd, check=True) + + # verify metadata checksum + for repoid, repo in repos.items(): + algorithm, checksum = repo["checksum"].split(":") + assert algorithm == "sha256" + cachedir = dnf_cachedir(repoid, repo, releasever, basearch) + with open(f"{tree}/var/cache/dnf/{cachedir}/repodata/repomd.xml", "rb") as f: + repomd = f.read() + assert hashlib.sha256(repomd).hexdigest() == checksum + + return 0 if __name__ == '__main__': diff --git a/test/pipelines/f30-boot.json b/test/pipelines/f30-boot.json index c334eae8..53beb04b 100644 --- a/test/pipelines/f30-boot.json +++ b/test/pipelines/f30-boot.json @@ -12,7 +12,8 @@ "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": [ @@ -36,7 +37,8 @@ "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": [ diff --git a/test/pipelines/firewall.json b/test/pipelines/firewall.json index a91a70a5..2687aa40 100644 --- a/test/pipelines/firewall.json +++ b/test/pipelines/firewall.json @@ -9,7 +9,8 @@ "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": ["@Core", "firewalld"] diff --git a/test/pipelines/locale.json b/test/pipelines/locale.json index 3f5b251f..0e7937cb 100644 --- a/test/pipelines/locale.json +++ b/test/pipelines/locale.json @@ -9,7 +9,8 @@ "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": ["@Core"] diff --git a/test/pipelines/timezone.json b/test/pipelines/timezone.json index edcbf611..ec204ad0 100644 --- a/test/pipelines/timezone.json +++ b/test/pipelines/timezone.json @@ -9,7 +9,8 @@ "repos": { "fedora": { "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch", - "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9" + "gpgkey": "F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9", + "checksum": "sha256:9f596e18f585bee30ac41c11fb11a83ed6b11d5b341c1cb56ca4015d7717cb97" } }, "packages": ["@Core"]