This commit allows to exclude preserving ownership from an object
export. This is required to fix the issue that on macOS the an
podman based workflow cannot export objects with preserving
ownerships.
Originally this was a `no_preserve: Optional[List[str]] = None)`
to be super flexible in what we pass to `cp` but then I felt like
YAGNI - if we need more we can trivially change this (internal)
API again :)
Similar to the aleph file created for builds of FCOS based on ostree
commit inputs, this adds an aleph file that contains information about
the initial deployment of data when the disk image was built
A new stage is preferred here as both the org.osbuild.ostree.deploy
and org.osbuild.ostree.deploy.container stages need an aleph file and
use of the aleph file may depend on the project/product. For example,
right now CoreOS is the only project that uses an aleph file, but others
may want it in the future.
Diffs for stage tests have changed after the sources were updated.
Update them to match expected behaviour. This was mostly done with
some form of:
```
foo=update-crypto-policies;
sudo tools/gen-stage-test-diff --libdir . --store /var/osbuild/store/ test/data/stages/$foo > test/data/stages/$foo/diff.json
```
For the dracut one I had to figure out what new kernel was used
and the new modules and update the vanilla.json file to get the
test to pass.
For the rpm one I had to also update the metadata.json with something
like:
```
sudo python3 -m osbuild --libdir . --store /var/osbuild/store/ --export tree \
--output-directory /var/osbuild/out/ test/data/stages/rpm/b.json --json \
| jq .metadata >test/data/stages/rpm/metadata.json
```
This adds a new key masked_generators, similar to masked_services,
which masks systemd generators from running at boot, by creating
symlinks to /dev/null in /etc/systemd/systemd-generators, as
described in:
https://www.freedesktop.org/software/systemd/man/latest/systemd.generator.html#Description
This will be useful for the automotive project, as it allows disabling
of unsupported things like sysv or rc.local legacy support, while
improving boot performance.
This helper can be used to implement a strategy to find the oldest
cache entries and evict them when the cache is full.
The implementation uses the `atime` of the per object `cache.lock`
file and ensures in `load()` that it's actually updated.
This commit adds mount output to the error raised by
FileSystemMountService.mount(). This is useful when running into
mount failures during osbuild runs.
The issue was discovered while debugging a mount failure for
osbuild-composer PR#3820. Initially osbuild PR#1490 was meant
to fix it but it turned out there is a third mount helper in
the code that was originally overlooked (sorry for that!).
While debugging a failure of osbuild-composer [0] on fc39 it was
noticed that a mount failure does not include the output of
the mount command:
```
File "/usr/lib/python3.12/site-packages/osbuild/mounts.py", line 78, in mount
path = client.call("mount", args)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/osbuild/host.py", line 348, in call
ret, _ = self.call_with_fds(method, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/osbuild/host.py", line 384, in call_with_fds
raise error
osbuild.host.RemoteError: CalledProcessError: Command '['mount', '-t', 'xfs', '-o', 'ro,norecovery', '--source', '/dev/rootvg/applv', '--target', '/tmp/tmpjtfmth56/app']' returned non-zero exit status 32.
File "/usr/lib/python3.12/site-packages/osbuild/host.py", line 268, in serve
reply, reply_fds = self._handle_message(msg, fds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/osbuild/host.py", line 301, in _handle_message
ret, fds = self.dispatch(name, args, fds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/osbuild/mounts.py", line 111, in dispatch
r = self.mount(args)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/osbuild/mounts.py", line 160, in mount
subprocess.run(
File "/usr/lib64/python3.12/subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
```
which makes diagnostic errors harder of course. This commit adds
a test that ensures that mount output is visbile and also changes
the code to include it.
[0] https://github.com/osbuild/osbuild-composer/pull/3820
This commit extends the current support for OpenSCAP
tailoring by accepting an array of key/value overrides.
Users will be able to specify override values for specific
rules that will update the value when remediating the
image.
The next commit will add a stage test that requires erofs-utils. Let's add it
into the buildroot in a separate commit, so the history is more readable.
Add a simple stage test for the erofs stage. It uses dump.erofs
instead of mounting the file because the kernel in the GH runners
do not support mounting erofs just yet.
For our Fedora CoreOS disk images we set the partition labels (name)
for the partitions. This is also supported using the primitives here
in OSBuild, but it wasn't obvious that I needed to set the name in
the mpp-define-images definition. Let's set the name there, but let's
also allow osbuild-mpp to set the `id`, which is what is used later
to access that partition from the `name` too if `id` isn't set.
This means we allow something like:
- name: BIOS-BOOT
type: 21686148-6449-6E6F-744E-656564454649
bootable: true
uuid: FAC7F1FB-3E8D-4137-A512-961DE09A5549
size: 100
rather than requiring something like:
- id: BIOS-BOOT
name: BIOS-BOOT
type: 21686148-6449-6E6F-744E-656564454649
bootable: true
uuid: FAC7F1FB-3E8D-4137-A512-961DE09A5549
size: 100
When loop.Loop() is called and a new loop device must be allocated
there is no gurantee that the correct device node is available on
the system. In containers /dev is often just a tmpfs with static
device nodes. So when /dev/loopN is not available when the
container is created the device node will be missing even if
`get_unbound()` create a new loop device for us.
This commit ensures that the device node is available. It creates
it unconditionally and ignores any EEXIST errors to ensure there
is no TOCTOU issue.
Note that the test could have passed a `Loop(dir_fd=open(tmpdir))`
instead of creating/patching loop.DEV_PATH but it seems slightly
nicer to test the flow without a custom dir_path as this is what
the real code that creates a loop device is also using.
Quick rename to have our wording be in-line with the new differences
between stage unit tests and stage integration tests; also being applied
to the guides.
When osbuild.loop.Loop calls `__init__()` it assigns the `self.fd`
on open. However if that open call fails for whatever reason
(not found, permissions) the cleanup in `__del__` will fail in
confusing ways because `self.fd` is not initialized yet. It
also prevents the correct error from getting reported. A tiny
test is added to ensure this does not regress.
This commit removes some unnecessary custom tmpdir() fixtures
and uses the pytest buildin tmp_path instead.
Some custom tmpdir fixtures are left in place as they configure
the tmp location to be under `/var/tmp` which is not trivial to
do with pytests `tmp_path`. Not sure or not if the is a deep
reason there for using /var/tmp. I assume it's to ensure that
the tests run on a real FS not on a potential tmpfs but I don't
have the full background so didn't want to change anything.
This stage calls `update-crypto-policies` to set the
policy applicable for the various cryptographic back-ends,
such as SSL/TLS libraries.
Signed-off-by: Miguel Martín <mmartinv@redhat.com>
Also switch the qcow2 output to be a "qemu" platform image. This
change takes advantage of the recent org.osbuild.kernel-cmdline.bls-append
stage addition to modify kernel arguments in later pipelines.
To get a qemu image output:
- osbuild --output-directory out/ --export qemu test/data/manifests/fedora-coreos-container.json
To get a metal image output:
- osbuild --output-directory out/ --export metal test/data/manifests/fedora-coreos-container.json
This was done via:
```
$ sudo osbuild --export tree --output-directory /tmp/devnull test/data/stages/rpm/b.json --json | jq .metadata >test/data/stages/rpm/metadata.json
```
a outlined in `test/data/stages/rpm`.
Moving to the newer fedora 38 snapshot pulled in some changes
to the `/etc/dnf/automatic.conf` (e.g. [0]) when moving from
dnf 4.16.1 to 4.17.0. This commit updates the diff.
[0] a0acc88efc
The authselect upstream code dropped adding a timestamp to the
auto-geneated content in /etc/authselect [0]. With that the
content diff can be compared again.
[0] 44b9d87f90
Changes in `/etc/shadow` depend on the date, i.e. the last time
the password changed field. So for now exclude them from the
tree diff (until we use `faketime` to fix this :)
With lvm2 the generated fedora fc38 boot image boots in degraded
mode with the following error:
```
[root@localhost ~]# journalctl -u lvm2-monitor.service|more
Nov 13 12:52:04 localhost.localdomain lvm[431]: Failed to create /etc/lvm/devi
ces 2
Nov 13 12:52:04 localhost.localdomain lvm[431]: Failed to set up devices.
Nov 13 12:52:04 localhost.localdomain systemd[1]: lvm2-monitor.service: Main pro
cess exited, code=exited, status=5/NOTINSTALLED
Nov 13 12:52:04 localhost.localdomain systemd[1]: lvm2-monitor.service: Failed w
ith result 'exit-code'.
Nov 13 12:52:04 localhost.localdomain systemd[1]: Failed to start lvm2-monitor.s
ervice - Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress p
olling.
```
This breaks the `test_boot.py` which expects the system after booting
in `running` state (from `systemd is-system-running`).
It looks like this is some sort of race with our generated image,
potentially related to selinux, see
https://github.com/lvmteam/lvm2/blob/v2_03_18/lib/device/dev-cache.c#L1842
and note the lines around dm_prepare_selinux_context(). Note
also that `lvm2-monitor.service` runs with `DefaultDependencies=no`
(c.f.
https://github.com/lvmteam/lvm2/blob/v2_03_18/scripts/lvm2_monitoring_systemd_red_hat.service.in#L7)
Given that the official fc38 cloud image does not use lvm2 and that
it's not needed for the boot test this commit simply removes it
from the fedora-boot manifest. This fixes the test.
The `test_assemblers.py` has an `assertGRUB2` helper that ensures
that the data written in the mbr and first megabyte is unchanged
by the `org.osbuild.qemu` assembler.
With the move to f38 the digests change. The mbr digest is
computed via the following python code and it matches that value
used in the test (440 byte only because the rest is the partition
table).
```
$ python3 -c 'import hashlib,sys; f=open(sys.argv[1], "rb"); m1=hashlib.sha256();m1.update(f.read()[:440]);print(m1.hexdigest())' ./f34/usr/lib/grub/i386-pc/boot.img
26e3327c6b5ac9b5e21d8b86f19ff7cb4d12fb2d0406713f936997d9d89de3ee
```
So with that code we can update the f38 mbr value now.
```
$ python3 -c 'import hashlib,sys; f=open(sys.argv[1], "rb"); m1=hashlib.sha256();m1.update(f.read()[:440]);print(m1.hexdigest())' ./f38/usr/lib/grub/i386-pc/boot.img
b8cea7475422d35cd6f85ad099fb4f921557fd1b25db62cd2a92709ace21cf0f
However computing the second sha256 for the `512:1024*1024` is much
harder to do from first principles because the value depends on the
image generated via `grub2-mkimage` and the hash changes with each
different module or config option. This means one needs to replicate
the exact inputs of:
```
subprocess.run(["grub2-mkimage",
"--verbose",
"--directory", f"/usr/lib/grub/{platform}",
"--prefix", f"(,{partid})/{grub_path}",
"--format", platform,
"--compression", "auto",
"--output", core_path] +
modules,
check=True)
```
in the test. At this point I cheated and just update to the computed
value inside the test.
The authselect stage will generate timestamps as part of the
update to `/etc/authselect/*`, e.g.:
```
Generate by authselect on Fri Nov 10 16:06:29 2023
...
```
this makes the content diff for those files unusable (until we
start to use faketime which maybe we should ;)
Instead of using the F34-based manifests, let's switch to F38. I tried my
best to import the vars into the new manifest, but I don't think that's
currently supported.
Let's not depend on f34-base.json anymore, but instead of a separate,
standardized manifest for it. The test was modified so it supports
v2 manifests. Also, the new manifest installs just a very minimal system.
There's no need to install the whole @core.
Authconfig was completely retired from Fedora. In order to keep this stage
covered, this commit changes the test to use CentOS Stream 9, which still
ships this package.
This gets rid of the old F34 manifest and migrates the to test to the
standardized V2 one based on F38.
Since the metadata format is much saner in V2, I was able to simplify the
assertion quite a lot.
This commit migrates the test to a brand new V2, F38-based manifest. It's
actually based on osbuild-composer interpretation of the Fedora Cloud Base
image.
This commit adds `osbuild.testutil.imports.import_module_from_path`
that can be used to import arbitrary python source files. This
allows importing files from the stages directory that have a
non python friendly filename like `org.osbuild.kickstart`.