From 39c06b1fe7366dab25d9e039989c8d94ea62c663 Mon Sep 17 00:00:00 2001 From: Pavel Raiskup Date: Wed, 18 Sep 2024 20:37:34 +0200 Subject: [PATCH] =?UTF-8?q?hermetic:=20rename=20the=20feature=20from=20"is?= =?UTF-8?q?olated=20=E2=86=92=20hermetic"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has been discussed within the Mock/Copr and Konflux teams, and the new term seems to better reflect what Mock actually does. It also avoids confusion with the "rpmbuild isolation" that Mock has always implemented. --- ...d-build.feature => hermetic-build.feature} | 14 +- behave/features/steps/other.py | 6 +- behave/testlib.py | 10 +- docs/Plugin-BuildrootLock.md | 12 +- ...d-builds.md => feature-hermetic-builds.md} | 132 ++++++++++-------- docs/index.md | 2 +- mock/docs/mock.1 | 12 +- mock/docs/site-defaults.cfg | 4 +- ...{isolated-build.cfg => hermetic-build.cfg} | 10 +- mock/mock.spec | 12 +- ...isolated-repo.py => mock-hermetic-repo.py} | 4 +- mock/py/mock.py | 20 +-- mock/py/mockbuild/buildroot.py | 2 +- mock/py/mockbuild/config.py | 16 +-- mock/py/mockbuild/plugins/buildroot_lock.py | 10 +- ...d-build.feature => hermetic-build.feature} | 6 +- 16 files changed, 146 insertions(+), 126 deletions(-) rename behave/features/{isolated-build.feature => hermetic-build.feature} (70%) rename docs/{feature-isolated-builds.md => feature-hermetic-builds.md} (57%) rename mock/etc/mock/{isolated-build.cfg => hermetic-build.cfg} (73%) rename mock/py/{mock-isolated-repo.py => mock-hermetic-repo.py} (97%) rename releng/release-notes-next/{isolated-build.feature => hermetic-build.feature} (69%) diff --git a/behave/features/isolated-build.feature b/behave/features/hermetic-build.feature similarity index 70% rename from behave/features/isolated-build.feature rename to behave/features/hermetic-build.feature index ffd623f5b..61ba8bd58 100644 --- a/behave/features/isolated-build.feature +++ b/behave/features/hermetic-build.feature @@ -1,22 +1,22 @@ -Feature: Mock 5.7+ supports isolated builds +Feature: Mock 5.7+ supports hermetic builds - @isolated_build - Scenario: Isolated build against a DNF5 distribution + @hermetic_build + Scenario: Hermetic build against a DNF5 distribution Given an unique mock namespace When deps for python-copr-999-1.src.rpm are calculated against fedora-rawhide-x86_64 And a local repository is created from lockfile - And an isolated build is retriggered with the lockfile and repository + And a hermetic build is retriggered with the lockfile and repository Then the build succeeds And the produced lockfile is validated properly - @isolated_build - Scenario: Isolated build against a DNF4 distribution + @hermetic_build + Scenario: Hermetic build against a DNF4 distribution Given an unique mock namespace # Temporary image, until we resolve https://issues.redhat.com/browse/CS-2506 And next mock call uses --config-opts=bootstrap_image=quay.io/mock/behave-testing-c9s-bootstrap option And next mock call uses --config-opts=bootstrap_image_ready=True option When deps for mock-test-bump-version-1-0.src.rpm are calculated against centos-stream+epel-9-x86_64 And a local repository is created from lockfile - And an isolated build is retriggered with the lockfile and repository + And a hermetic build is retriggered with the lockfile and repository Then the build succeeds And the produced lockfile is validated properly diff --git a/behave/features/steps/other.py b/behave/features/steps/other.py index 190582264..849635522 100644 --- a/behave/features/steps/other.py +++ b/behave/features/steps/other.py @@ -206,14 +206,14 @@ def step_impl(context): lockfile = mock_run["lockfile"] context.local_repo = tempfile.mkdtemp(prefix="mock-tests-local-repo-") - cmd = ["mock-isolated-repo", "--lockfile", lockfile, "--output-repo", + cmd = ["mock-hermetic-repo", "--lockfile", lockfile, "--output-repo", context.local_repo] assert_that(run(cmd)[0], equal_to(0)) -@when('an isolated build is retriggered with the lockfile and repository') +@when('a hermetic build is retriggered with the lockfile and repository') def step_impl(context): - context.mock.isolated_build() + context.mock.hermetic_build() @then('the produced lockfile is validated properly') diff --git a/behave/testlib.py b/behave/testlib.py index 267457b22..d2cd61354 100644 --- a/behave/testlib.py +++ b/behave/testlib.py @@ -123,13 +123,13 @@ def calculate_deps(self, srpm, chroot): "lockfile": os.path.join(self.resultdir, "buildroot_lock.json") }) - def isolated_build(self): + def hermetic_build(self): """ - From the previous calculate_deps() run, perform isolated build + From the previous calculate_deps() run, perform hermetic build """ mock_calc = self.context.mock_runs["calculate-build-deps"][-1] out, err = run_check(self.basecmd + [ - "--isolated-build", mock_calc["lockfile"], self.context.local_repo, + "--hermetic-build", mock_calc["lockfile"], self.context.local_repo, mock_calc["srpm"] ]) self.context.mock_runs["rebuild"].append({ @@ -137,8 +137,8 @@ def isolated_build(self): "out": out, "err": err, }) - # We built into an isolated-build.cfg! - self.context.chroot = "isolated-build" + # We built into a hermetic-build.cfg! + self.context.chroot = "hermetic-build" def clean(self): """ Clean chroot, but keep dnf/yum caches """ diff --git a/docs/Plugin-BuildrootLock.md b/docs/Plugin-BuildrootLock.md index 7a17898d2..7c9f74b69 100644 --- a/docs/Plugin-BuildrootLock.md +++ b/docs/Plugin-BuildrootLock.md @@ -12,7 +12,7 @@ This plugin generates an additional build artifact—the buildroot *lockfile* The *lockfile* describes both the list of buildroot sources (e.g., a list of installed RPMs, bootstrap image info, etc.) and a set of Mock configuration options. Using this information, Mock can later reproduce the buildroot -preparation (see the [Isolated Builds feature page](feature-isolated-builds)). +preparation (see the [Hermetic Builds feature page](feature-hermetic-builds)). This plugin is **disabled** by default but is automatically enabled with the `--calculate-build-dependencies` option. You can enable it (for all builds) by @@ -36,4 +36,12 @@ installed together with the Mock RPM package: Currently, we do not provide a compatibility promise. Only the exact same version of Mock that produced the file is guaranteed to read and process it. -For more information, see [Isolated Builds](feature-isolated-builds). +For more information, see [Hermetic Builds](feature-hermetic-builds). + +Also, in the future we plan to switch to a standardized tooling so we operate +with a standardized format, too. For more info see the [DNF5 feature +request][discussion], [rpm-lockfile-prototype][] and [libpkgmanifest][]. + +[discussion]: https://github.com/rpm-software-management/dnf5/issues/833 +[rpm-lockfile-prototype]: https://github.com/konflux-ci/rpm-lockfile-prototype +[libpkgmanifest]: https://github.com/rpm-software-management/libpkgmanifest diff --git a/docs/feature-isolated-builds.md b/docs/feature-hermetic-builds.md similarity index 57% rename from docs/feature-isolated-builds.md rename to docs/feature-hermetic-builds.md index c15028a59..acda51e71 100644 --- a/docs/feature-isolated-builds.md +++ b/docs/feature-hermetic-builds.md @@ -1,19 +1,19 @@ --- layout: default -title: Isolated builds with Mock +title: Hermetic builds with Mock --- -Isolated builds with Mock +Hermetic builds with Mock ========================= -Mock (v5.7+) supports isolated RPM builds, sometimes referred to as "hermetic" +Mock (v5.7+) supports hermetic RPM builds, sometimes referred to as "isolated" or "offline" builds. For more details, see the -[SLSA "isolated" definition][SLSA]. +[SLSA "hermetic" definition][SLSA future]. Quick start ----------- -For the impatient, the TL;DR steps of the HOWTO are as follows: +For the impatient, the TL;DR steps are as follows: # we want to build this package srpm=your-package.src.rpm @@ -28,29 +28,32 @@ For the impatient, the TL;DR steps of the HOWTO are as follows: lockfile=/var/lib/mock/fedora-rawhide-x86_64/result/buildroot_lock.json # create a local RPM repository (+ download bootstrap image) - mock-isolated-repo --lockfile "$lockfile" --output-repo "$repo" + mock-hermetic-repo --lockfile "$lockfile" --output-repo "$repo" - # perform the isolated build! - mock --isolated-build "$lockfile" "$repo" "$srpm" + # perform the hermetic build! + mock --hermetic-build "$lockfile" "$repo" "$srpm" -What an "isolated build" is.. +What an "hermetic build" is.. ----------------------------- -The term "isolated build" is often used in different contexts, even within -Mock's terminology. Historically, when we said that "Mock isolates the build," +The term "isolated build" is often used in different contexts within +Mock's terminology. Historically, when we said that "Mock isolates the build," we typically meant that Mock creates a *buildroot* (also referred to as a *build directory* or *build chroot*) and runs the (Turing-complete, and thus potentially insecure) *RPM build* process (i.e., a call to `/usr/bin/rpmbuild`) inside it. In this sense, Mock "isolates" the RPM build process from the rest of the system, or protects the system from potential mishaps. However, the **buildroot preparation** process was never "isolated" in this manner—only the -*RPM build* was. Even the *RPM build* "isolation" was always performed on a +*RPM build* was. Also, the *RPM build* "isolation" was always performed on a best-effort basis. For more details, see [Mock's Scope](index). -When we now talk about making builds and the corresponding built artifacts -safer, more predictable, and more reproducible, we refer to the [SLSA -isolation][SLSA] definition. This involves using Mock in an *isolated* -environment, free from unintended external influence. +This document focuses on making builds and their corresponding artifacts safer, +more predictable, and more reproducible. When we refer to *isolation*, we are +specifically referencing the [SLSA platform isolation][SLSA]. SLSA outlines +various security levels, and for the future, it introduces the concept of +[*hermetic builds*][SLSA future]. This is where Mock steps in, enabling builds +to be performed in a *hermetic* environment, free from unintended external +influences. Mock itself doesn't aim to provide this level of *isolation*. Mock is still just a tool that runs in "some" build environment to perform the `SRPM → RPM` @@ -60,14 +63,15 @@ may be (un)intentionally altered. Therefore, the preparation of the environment to **run Mock** and the **isolation** itself is the responsibility of a different tool (for example, `podman run --privileged --network=none`). -So, what does Mock `--isolated-build` do if it doesn't isolate? -Essentially, it just does less work than it usually does! It optimizes out any -action (primarily during the *buildroot* preparation) that would rely on -"external" factors—specifically, it never expects Internet connectivity. +So, what does Mock `--hermetic-build` do if it doesn't isolate? Essentially, it +just does less work than it usually does! It optimizes out any action +(primarily during the *buildroot* preparation) that would rely on "external" +factors—specifically, it never expects Internet connectivity. However, for the eventual build to succeed, **something else** still needs to -perform these omitted actions. Every single component required for *buildroot* -preparation must be prepared in advance for the `mock --isolated-build` -call (within **the** properly *isolated* environment, of course). +perform these omitted actions. Every single component/artifact required for +*buildroot* preparation must be prepared in advance for the `mock +--hermetic-build` call (within the properly *isolated* or *hermetic* +environment, of course). Challenges @@ -75,25 +79,26 @@ Challenges You’ve probably noticed that what used to be a simple command—like `mock -r "$chroot" "$srpm"`—has now become a more complicated set of commands. - This complexity arises because the *buildroot* in Mock is always prepared by installing a set of RPMs (Mock calls DNF, DNF calls RPM, ...), which normally requires a network connection. Additionally, it’s not always guaranteed that the DNF/RPM variant on the build -host (e.g., an EPEL 8 host) is sufficient or up-to-date for building the target -distribution (e.g., the newest Fedora Rawhide). Therefore, we need network -access [to obtain the appropriate bootstrap tooling](Feature-bootstrap). - -The [dynamic build dependencies][] further complicate the process. Without -them, we could at least make the `/bin/rpmbuild` fully offline—but with them, -it’s not so simple. Mock needs to interrupt the ongoing *RPM build* process, -resolve additional `%generate_buildrequires` (installing more packages on -demand), restart the *RPM build*, interrupt it again, and so on. This process -also requires a network connection! +host is sufficient or up-to-date for building the target distribution (e.g., +building the newest *Fedora Rawhide* packages on *EPEL 8* host). Therefore, we +need network access [to obtain the appropriate bootstrap +tooling](Feature-bootstrap). + +[Dynamic build dependencies][] add further complexity to the process. Without +them, we could potentially make the `/bin/rpmbuild` process fully offline—but +with their inclusion, it becomes much more challenging. Mock must interrupt the +ongoing *RPM build* process, resolve additional `%generate_buildrequires` +(installing more packages on demand), restart the *RPM build*, and potentially +repeat this cycle. This process also requires an (intermittent) network +connection! All of this is further complicated by the goal of making the *buildroot* as -*minimal* as possible—the fewer packages installed, the better. We can’t even +*minimal* as possible—the fewer packages installed, the better. We can’t even afford to install DNF into the buildroot, and as you’ve probably realized, we definitely don’t want to blindly install all available RPMs. @@ -102,7 +107,7 @@ The solution ------------ To address the challenges, we needed to separate the online -(`--calculate-build-dependencies`) and offline (`--isolated-build`) tasks +(`--calculate-build-dependencies`) and offline (`--hermetic-build`) tasks that Mock performs. 1. **Online Tasks:** These need to be executed first. We let Mock prepare the @@ -113,34 +118,35 @@ that Mock performs. The format of lockfile is defined by provided JSON Schema file(s), see documentation for the [buildroot_lock plugin](Plugin-BuildrootLock). - **Note:** The *buildroot* preparation also includes the installation of - dynamic build dependencies! Therefore, we **have to start an RPM build**. - Although we don’t finish the build (we terminate it once the - `%generate_buildrequires` is resolved, before reaching the `%build` phase, - etc.), it must be initiated. + **Note:** The *buildroot* preparation includes the installation of dynamic + build dependencies! That's why we have to **initiate** `rpmbuild`. + But we don’t **finish** the build—we terminate it once the + `%generate_buildrequires` section is resolved, before reaching the `%build` + phase. 2. **Offline Repository Creation:** With the *lockfile* from the previous step, we can easily retrieve the referenced components from the network. The Mock project provides an example implementation for this step in the - `mock-isolated-repo(1)` utility. This tool downloads all the referenced + `mock-hermetic-repo(1)` utility. This tool downloads all the referenced components from the internet and places them into a single local directory—let's call it an *offline repository*. **Note:** This step doesn’t necessarily have to be done by the Mock project - itself. The *lockfile* is concise enough for further processing and + itself. The *lockfile* is concise enough for further processing and validation (e.g., ensuring the set of RPMs and the buildroot image come from trusted sources) and could be parsed by build-system-specific tools like [cachi2][] (potentially in the future). 3. **Offline Build:** With the *srpm* and the *offline repository*, we can - instruct Mock to restart the build using the `--isolated-build - LOCKFILE OFFLINE_REPO SRPM` command. The *lockfile* is still needed at this + instruct Mock to restart the build using the `--hermetic-build + LOCKFILE OFFLINE_REPO SRPM` command. The *lockfile* is still needed at this stage because it contains some of the configuration options used in step 1 that must be inherited by the current Mock call. This step creates a new *buildroot #2* using the pre-downloaded RPMs in the *offline repository* (installing them all at once) and then (re)starts the - RPM build process. + RPM build process. This `rpmbuild` run **finishes** though, and provides the + binary RPM artifacts as usually. You might notice that some steps are performed twice, specifically downloading the RPMs (steps 1 and 2) and running the RPM build (steps 1 and 3). This @@ -155,16 +161,17 @@ Also, while you can calmly experiment with mock --calculate-build-dependencies -r fedora-rawhide-x86_64 "$srpm" mock --no-clean -r fedora-rawhide-x86_64 "$srpm" -and it is very close to the TL;DR variant, such an approach is not the same -thing! The *buildroot #1* **was not** prepared by Mock in **isolated** -environment. +This approach might seem similar to the TL;DR version, but it's not the same! +There is no *buildroot #1* and *buildroot #2*, only one buildroot. And that one +was prepared while Mock was online, meaning that something could **have +influenced** the environment preparation, and the subsequent **build**. Limitations ----------- - Let us stress out that this feature itself, while related or at least a bit - helpful, doesn't provide reproducible builds. For reproducible builds, build - systems need to take in account state of host machine, the full + helpful for, doesn't provide reproducible builds. For reproducible builds, + build systems need to take in account state of host machine, the full software/hardware stack. There's still a big influence of external factors! - We rely heavily on @@ -176,24 +183,29 @@ Limitations the implementation, as we don't need to recall the set of commands (or list of packages to install into) needed for bootstrap preparation. -- It is known fact that *normal builds* and *isolated builds* may result in +- It is known fact that *normal builds* and *hermetic builds* may result in slightly different outputs (at least in theory). This issue relates to the topic of *reproducible builds*. Normally, the *buildroot* is installed using - several DNF commands (RPM transactions), whereas the *isolated* build installs - all dependencies in a single DNF command (RPM transaction). While this - difference might cause the outputs of *normal* and *isolated* builds to vary - (in theory, because the chroot depends on RPM installation order), it OTOH - introduces more determinism! + several DNF commands (RPM transactions), whereas the *hermetic build* installs + all dependencies in a single DNF command (single RPM transaction). While this + difference might cause the outputs of *normal* and *hermetic* builds to vary + (in theory, because the chroot shape depends on the complex RPM installation + order), the *hermetic* variant introduces more determinism! - The *lockfile* provides a list of the required RPMs, referenced by URLs. These URLs point to the corresponding RPM repositories (online) from which they were installed in step 1. However, in many cases, RPMs are downloaded from `metalink://` or `mirrorlist://` repositories, meaning the URL might be selected non-deterministically, and the specific mirrors chosen could be - rather ephemeral. For this reason, users should—for isolated builds—avoid - using mirrored repositories (as in the case of Koji builders) or avoid making - large delays between step 1 and step 2. + rather ephemeral. For this reason, users should—for *hermetic* builds, for + now—avoid using mirrored repositories (and prefer Koji buildroots only) and + avoid making large delays between step 1 and step 2. Especially that, at the + time of writing this document, we know about [two][bug1] [bugs][bug2] that + will complicate the *lockfile* generation. [SLSA]: https://slsa.dev/spec/v1.0/requirements +[SLSA future]: https://slsa.dev/spec/v1.0/future-directions [dynamic build dependencies]: https://github.com/rpm-software-management/mock/issues/1359 [cachi2]: https://github.com/containerbuildsystem/cachi2 +[bug1]: https://github.com/rpm-software-management/dnf/issues/2130 +[bug2]: https://github.com/rpm-software-management/dnf5/issues/1673 diff --git a/docs/index.md b/docs/index.md index 78964f378..c5e460409 100644 --- a/docs/index.md +++ b/docs/index.md @@ -226,7 +226,7 @@ Every plugin has a corresponding wiki page with docs. * [package managers](Feature-package-managers) - supported package managers * [rhel chroots](Feature-rhelchroots) - builds for RHEL * [GPG keys and SSL](feature-gpg-and-ssl) - how to get your GPG keys and SSL certificates to buildroot -* [Isolated (offline) Builds](feature-isolated-builds) - doing offline builds with Mock +* [Hermetic (offline) Builds](feature-hermetic-builds) - doing hermetic builds with Mock ## Using Mock outside your git sandbox diff --git a/mock/docs/mock.1 b/mock/docs/mock.1 index 0e5bfd1bd..d4319d3c0 100644 --- a/mock/docs/mock.1 +++ b/mock/docs/mock.1 @@ -50,7 +50,7 @@ mock [options] \fB\-\-dnf\-cmd\fR [\fIarguments ...\fR] .LP mock [options] \fB\-\-calculate\-build\-dependencies\fR \fISRPM\fR .LP -mock [options] \fB\-\-isolated\-build \fILOCKFILE\fR \fIREPO\fR \fISRPM\fR +mock [options] \fB\-\-hermetic\-build \fILOCKFILE\fR \fIREPO\fR \fISRPM\fR .LP mock [options] {\fB\-\-scrub\fR=\fITYPE\fP,\fB\-\-scrub\-all\-chroots\fR} @@ -109,7 +109,7 @@ corresponding static list of build dependencies (= \fIBuildRequires\fR). The Test with \fIrpm -qpR [*.src.rpm|*.nosrc.rpm]\fR. Additionally, provide a \fIbuildroot_lock.json\fR file; this records the -metadata needed for an isolated build (see also \fB\-\-isolated\-build\fR). +metadata needed for a hermetic build (see also \fB\-\-hermetic\-build\fR). .TP \fB\-\-chain\fR When passing more than one SRPM, it will try to build failed builds if at least one subsequent SRPM succeed. This mimic the behaviour of deprecated mockchain. @@ -162,18 +162,18 @@ into the buildroot. No 'cleanup' is performed. Dynamic build dependencies (\fI%generate_buildrequires\fR specfile section) are not installed, see \fB\-\-calculate\-build\-dependencies\fR. .TP -\fB\-\-isolated\-build \fILOCKFILE\fR \fIREPO\fR \fISRPM\fR -Perform an isolated RPM build (i.e., an offline build without the need to access +\fB\-\-hermetic\-build \fILOCKFILE\fR \fIREPO\fR \fISRPM\fR +Perform a hermetic RPM build (i.e., an offline build without the need to access the Internet at all) from the given \fISRPM\fR (= file name, path on your system). After running Mock with the \fB\-\-calculate\-build\-dependencies\fR option to generate the \fILOCKFILE\fR file (typically named \fIbuildroot_lock.json\fR in the result directory), and then running the -\fImock\-isolated\-repo(1)\fR helper to generate \fIREPO\fR (a directory on the +\fImock\-hermetic\-repo(1)\fR helper to generate \fIREPO\fR (a directory on the host that provides RPMs with metadata and a bootstrap image tarball), Mock has all the necessary information to build RPMs from the given \fISRPM\fR fully offline. More info in the feature page: -\fIhttps://rpm-software-management.github.io/mock/feature-isolated-builds\fR +\fIhttps://rpm-software-management.github.io/mock/feature-hermetic-builds\fR .TP \fB\-\-list-chroots\fP List all available chroots names and their description - both system-wide and user ones. diff --git a/mock/docs/site-defaults.cfg b/mock/docs/site-defaults.cfg index 6e990004b..a4c46d599 100644 --- a/mock/docs/site-defaults.cfg +++ b/mock/docs/site-defaults.cfg @@ -661,10 +661,10 @@ #config_opts["recursion_limit"] = 5000 # Mock internals used by the --calculated-build-dependencies and -# --isolated-build options. Please do not set these options in Mock +# --hermetic-build options. Please do not set these options in Mock # configuration files. # config_opts["calculatedeps"] = None -# config_opts["isolated_build"] = False +# config_opts["hermetic_build"] = False # List of usernames (strings) that will be pre-created in buildroot. The UID # and GID in-chroot is going to be the same as on-host. This option is for diff --git a/mock/etc/mock/isolated-build.cfg b/mock/etc/mock/hermetic-build.cfg similarity index 73% rename from mock/etc/mock/isolated-build.cfg rename to mock/etc/mock/hermetic-build.cfg index 56bb4b50e..79416de34 100644 --- a/mock/etc/mock/isolated-build.cfg +++ b/mock/etc/mock/hermetic-build.cfg @@ -1,12 +1,12 @@ -# used by https://rpm-software-management.github.io/mock/feature-isolated-builds +# used by https://rpm-software-management.github.io/mock/feature-hermetic-builds -config_opts['root'] = 'isolated-build' -config_opts['description'] = 'Isolated Build' +config_opts['root'] = 'hermetic-build' +config_opts['description'] = 'Configuration file for Hermetic Builds' -# Isolated-build configuration file is re-used for multiple chroot +# Hermetic build configuration file is re-used for multiple chroot # configurations (particular chroot used depends on the previous # --calculate-build-dependencies run). That's why Mock automatically runs -# --scrub=all with --isolated-build. It doesn't make sense to waste the time +# --scrub=all with --hermetic-build. It doesn't make sense to waste the time # with creating caches. config_opts['plugin_conf']['root_cache_enable'] = False diff --git a/mock/mock.spec b/mock/mock.spec index 49548c6ec..d2eedff22 100644 --- a/mock/mock.spec +++ b/mock/mock.spec @@ -174,7 +174,7 @@ done # this is what %%sysusers_create_compat will expand to %{_rpmconfigdir}/sysusers.generate-pre.sh mock.conf > sysusers_script -argparse-manpage --pyfile ./py/mock-isolated-repo.py --function _argparser > mock-isolated-repo.1 +argparse-manpage --pyfile ./py/mock-hermetic-repo.py --function _argparser > mock-hermetic-repo.1 %install @@ -185,7 +185,7 @@ mkdir -p %{buildroot}%{_sysconfdir}/mock/templates install -d %{buildroot}%{_bindir} install -d %{buildroot}%{_libexecdir}/mock install mockchain %{buildroot}%{_bindir}/mockchain -install py/mock-isolated-repo.py %{buildroot}%{_bindir}/mock-isolated-repo +install py/mock-hermetic-repo.py %{buildroot}%{_bindir}/mock-hermetic-repo install py/mock-parse-buildlog.py %{buildroot}%{_bindir}/mock-parse-buildlog install py/mock.py %{buildroot}%{_libexecdir}/mock/mock ln -s consolehelper %{buildroot}%{_bindir}/mock @@ -212,7 +212,7 @@ install -d %{buildroot}%{python_sitelib}/ cp -a py/mockbuild %{buildroot}%{python_sitelib}/ install -d %{buildroot}%{_mandir}/man1 -cp -a docs/mock.1 docs/mock-parse-buildlog.1 mock-isolated-repo.1 %{buildroot}%{_mandir}/man1/ +cp -a docs/mock.1 docs/mock-parse-buildlog.1 mock-hermetic-repo.1 %{buildroot}%{_mandir}/man1/ install -d %{buildroot}%{_datadir}/cheat cp -a docs/mock.cheat %{buildroot}%{_datadir}/cheat/mock @@ -257,7 +257,7 @@ pylint-3 py/mockbuild/ py/*.py py/mockbuild/plugins/* || : # executables %{_bindir}/mock %{_bindir}/mockchain -%{_bindir}/mock-isolated-repo +%{_bindir}/mock-hermetic-repo %{_bindir}/mock-parse-buildlog %{_libexecdir}/mock @@ -272,7 +272,7 @@ pylint-3 py/mockbuild/ py/*.py py/mockbuild/plugins/* || : # config files %config(noreplace) %{_sysconfdir}/%{name}/*.ini -%config(noreplace) %{_sysconfdir}/%{name}/isolated-build.cfg +%config(noreplace) %{_sysconfdir}/%{name}/hermetic-build.cfg %config(noreplace) %{_sysconfdir}/pam.d/%{name} %config(noreplace) %{_sysconfdir}/security/console.apps/%{name} @@ -283,7 +283,7 @@ pylint-3 py/mockbuild/ py/*.py py/mockbuild/plugins/* || : # docs %{_mandir}/man1/mock.1* %{_mandir}/man1/mock-parse-buildlog.1* -%{_mandir}/man1/mock-isolated-repo.1* +%{_mandir}/man1/mock-hermetic-repo.1* %{_datadir}/cheat/mock # cache & build dirs diff --git a/mock/py/mock-isolated-repo.py b/mock/py/mock-hermetic-repo.py similarity index 97% rename from mock/py/mock-isolated-repo.py rename to mock/py/mock-hermetic-repo.py index 2de7a4c53..9410e611a 100755 --- a/mock/py/mock-isolated-repo.py +++ b/mock/py/mock-hermetic-repo.py @@ -49,9 +49,9 @@ def download_file(url, outputdir): def _argparser(): parser = argparse.ArgumentParser( - prog='mock-isolated-repo', + prog='mock-hermetic-repo', description=( - "Prepare a repository for a `mock --isolated-build` build. " + "Prepare a repository for a `mock --hermetic-build` build. " "Given a Mock buildroot \"lockfile\"\n\n" " a) create an output repo directory,\n" " b) download and place all the necessary RPM files there,\n" diff --git a/mock/py/mock.py b/mock/py/mock.py index 01008406f..3d1a5f42e 100755 --- a/mock/py/mock.py +++ b/mock/py/mock.py @@ -398,9 +398,9 @@ def command_parse(): type=str, dest="additional_packages", help=("Additional package to install into the buildroot before " "the build is done. Can be specified multiple times.")) - parser.add_option("--isolated-build", nargs=2, + parser.add_option("--hermetic-build", nargs=2, metavar=("LOCKFILE", "REPO_DIRECTORY"), - help="Perform an isolated (fully offline) SRPM build") + help="Perform a hermetic (fully offline) build") (options, args) = parser.parse_known_args() @@ -413,14 +413,14 @@ def command_parse(): else: options.mode = 'rebuild' - if options.isolated_build and options.chroot != 'default': + if options.hermetic_build and options.chroot != 'default': raise mockbuild.exception.BadCmdline( - "The --isolated-build mode uses a special chroot configuration, " + "The --hermetic-build mode uses a special chroot configuration, " "you can not select the chroot configuration with the " "-r/--root option.") - if options.isolated_build and options.mode != "rebuild": - raise mockbuild.exception.BadCmdline("--rebuild mode needed with --isolated-build") + if options.hermetic_build and options.mode != "rebuild": + raise mockbuild.exception.BadCmdline("--rebuild mode needed with --hermetic-build") options.calculatedeps = None if options.mode == "calculatedeps": @@ -701,8 +701,8 @@ def main(): if options.configdir: config_path = options.configdir - if options.isolated_build: - options.chroot = "isolated-build" + if options.hermetic_build: + options.chroot = "hermetic-build" config_opts = uidManager.run_in_subprocess_without_privileges( config.load_config, config_path, options.chroot) @@ -977,8 +977,8 @@ def run_command(options, args, config_opts, commands, buildroot): buildroot.remove(*args) elif options.mode == 'rebuild': - if options.isolated_build: - # No caches with isolated builds! Bootstrap is extracted from + if options.hermetic_build: + # No caches with hermetic builds! Bootstrap is extracted from # given tarball, buildroot installed from pre-fetched RPMs. commands.scrub(["all"]) diff --git a/mock/py/mockbuild/buildroot.py b/mock/py/mockbuild/buildroot.py index 4ab519384..936a15835 100644 --- a/mock/py/mockbuild/buildroot.py +++ b/mock/py/mockbuild/buildroot.py @@ -268,7 +268,7 @@ def _fallback(message): getLog().info("Using local image %s (pull skipped)", self.bootstrap_image) - if self.config["isolated_build"]: + if self.config["hermetic_build"]: tarball = os.path.join(self.config["offline_local_repository"], "bootstrap.tar") podman.import_tarball(tarball) diff --git a/mock/py/mockbuild/config.py b/mock/py/mockbuild/config.py index 3f763dac6..047326822 100644 --- a/mock/py/mockbuild/config.py +++ b/mock/py/mockbuild/config.py @@ -396,7 +396,7 @@ def setup_default_config_opts(): config_opts["recursion_limit"] = 5000 config_opts["calculatedeps"] = None - config_opts["isolated_build"] = False + config_opts["hermetic_build"] = False return config_opts @@ -413,7 +413,7 @@ def multiply_platform_multiplier(config_opts): def set_config_opts_per_cmdline(config_opts, options, args): "takes processed cmdline args and sets config options." - process_isolated_build_config(options, config_opts) + process_hermetic_build_config(options, config_opts) cli_opt_new = {} for cli_opt in options.cli_config_opts: @@ -723,19 +723,19 @@ def update_config_from_dict(config_opts, updates): config_opts[key] = value -def process_isolated_build_config(cmdline_opts, config_opts): +def process_hermetic_build_config(cmdline_opts, config_opts): """ Read the lockfile file generated by the previous --calculate-build-dependencies run, and adjust the current set of options in CONFIG_OPTS. """ - if not cmdline_opts.isolated_build: + if not cmdline_opts.hermetic_build: return - config_opts["isolated_build"] = True + config_opts["hermetic_build"] = True - json_conf, repo_reference = cmdline_opts.isolated_build + json_conf, repo_reference = cmdline_opts.hermetic_build with open(json_conf, "r", encoding="utf-8") as fd: data = json.load(fd) @@ -743,7 +743,7 @@ def process_isolated_build_config(cmdline_opts, config_opts): raise exception.BadCmdline( f"The file {json_conf} did not record the bootstrap_image_ready=True " "config which means we are not able to prepare the bootstrap chroot " - "in an isolated mode.") + "in a hermetic mode.") update_config_from_dict(config_opts, data["config"]) @@ -768,7 +768,7 @@ def process_isolated_build_config(cmdline_opts, config_opts): # should make sure the config_opts["bootstrap_image"] is already downloaded. config_opts["bootstrap_image_skip_pull"] = True - # With isolated build, we always assert that we are reproducing the build + # With hermetic builds, we always assert that we are reproducing the build # with the same image. config_opts["bootstrap_image_assert_digest"] = data["bootstrap"]["image_digest"] diff --git a/mock/py/mockbuild/plugins/buildroot_lock.py b/mock/py/mockbuild/plugins/buildroot_lock.py index 530f0d1e3..13d5b74fc 100644 --- a/mock/py/mockbuild/plugins/buildroot_lock.py +++ b/mock/py/mockbuild/plugins/buildroot_lock.py @@ -72,8 +72,8 @@ def _executor(cmd): }, # Try to keep this as minimal as possible. If possible, # implement the config options as DEFAULTS in the - # isolated-build.cfg, or in the - # process_isolated_build_config() method. + # hermetic-build.cfg, or in the + # process_hermetic_build_config() method. "config": {} } for cfg_option in [ @@ -83,10 +83,10 @@ def _executor(cmd): "legal_host_arches", "dist", "package_manager", - # At this point, we only support isolated builds iff + # At this point, we only support hermetic builds iff # bootstrap_image_ready=True, so these two options are # useful for implementing "assertion" in the - # process_isolated_build_config() method. + # process_hermetic_build_config() method. "bootstrap_image", "bootstrap_image_ready", # Macros need to be inherited, e.g., to keep the original @@ -98,7 +98,7 @@ def _executor(cmd): if "bootstrap_image" in data["config"]: # Optional object, only if bootstrap image used (we still - # produce lockfiles even if these are useless for isolated + # produce lockfiles even if these are useless for hermetic # builds). with self.buildroot.uid_manager.elevated_privileges(): podman = Podman(self.buildroot, diff --git a/releng/release-notes-next/isolated-build.feature b/releng/release-notes-next/hermetic-build.feature similarity index 69% rename from releng/release-notes-next/isolated-build.feature rename to releng/release-notes-next/hermetic-build.feature index e9980912f..819096e21 100644 --- a/releng/release-notes-next/isolated-build.feature +++ b/releng/release-notes-next/hermetic-build.feature @@ -1,7 +1,7 @@ -Support for [isolated builds](feature-isolated-builds) has been +Support for [hermetic builds](feature-hermetic-builds) has been [implemented][PR#1393]. This update introduces two new command-line options: -`--calculate-build-deps` and `--isolated-build`, along with the new -`mock-isolated-repo(1)` utility. +`--calculate-build-deps` and `--hermetic-build`, along with the new +`mock-hermetic-repo(1)` utility. Additionally, this change introduces a new [`buildroot_lock` plugin](Plugin-BuildrootLock), which generates a new artifact in the buildroot—a