Commit graph

739 commits

Author SHA1 Message Date
Michael Vogt
d38665a2af util: tweak bls.options_append() support no/multiple options
The BLS specification [0] says the `options` field is optional and
can also appear multiple times. This commit tweaks the code to
deal with these corner cases and also adds tests that ensure that
this works correctly.

It also tweaks the file handling to be atomic.

[0] https://uapi-group.org/specifications/specs/boot_loader_specification/
2024-02-28 10:37:01 +01:00
schutzbot
87dce84b90 Post release version bump
[skip ci]
2024-02-28 08:13:32 +00:00
Michael Vogt
c219160b8f osbuild: add warning when lazy umount in containers_storage_source fails 2024-02-27 15:07:42 +01:00
schutzbot
3824c9c868 Post release version bump
[skip ci]
2024-02-26 15:06:35 +00:00
Renata Ravanelli
ddf4478ea9 util: Add bls module
- Add functions for appending kernel parameters to the
Boot Loader Specification (BLS) as needed.

Signed-off-by: Renata Ravanelli <rravanel@redhat.com>
2024-02-26 16:02:28 +01:00
schutzbot
badca79801 Post release version bump
[skip ci]
2024-02-22 11:53:23 +00:00
Achilleas Koutsou
700dc8ded3 test/stages: build manifest and check tree
Copy hello.img into the host storage, build the manifest, export the
tree, and check the storage in the tree for the expected files and data.
2024-02-21 17:55:37 +01:00
Achilleas Koutsou
423819a80e util/containers: add the checksum to the image data
When parsing a container input, add the checksum to the data as well.

Usually with other inputs, the stage only needs to know the filepath
where it can find the source content.  In most (all, so far) cases, this
is a checksum appended to the content type.

In this case, the filepath is the location of the storage bind mount and
the checksum is needed to retrieve the container.  The name might only
be a destination name (a name to use for storing the container in the
image), so we can't rely on it being valid in the source.
2024-02-21 17:55:37 +01:00
Achilleas Koutsou
591593ea00 testutil: make_container context manager
Make make_container a context manager so we can reliably clean up
containers that were created in tests.
2024-02-21 17:55:37 +01:00
Michael Vogt
f7e4febb2c stage,test: extract make_container() test helper 2024-02-21 17:55:37 +01:00
Achilleas Koutsou
6572b1b8e7 util: remove storage_conf arg from get_host_storage()
Let the caller decide if a reload of the storage configuration is needed
and simplify the storage configuration reader.
2024-02-21 17:55:37 +01:00
Achilleas Koutsou
2d779a14e4 util: fall back to /usr/share for storage.conf if no /etc config
The system-wide location for the containers storage.conf is
/usr/share/containers.  The existence of a file in /etc/containers
completely overrides this (see containers-storage.conf(5)).
If no file is found at /etc/containers/storage.conf then fall back to
reading the config from /usr/share/containers/storage.conf.

If neither file exists, this is an error since the default config should
be packaged with any tool that requires it (skopeo, podman, etc).
2024-02-21 17:55:37 +01:00
Gianluca Zuccarelli
06801bb442 util/containers: mount storage
Containers with the `containers-storage` are bind mounted to
the osbuild store. This helper function bind mounts the
containers-storage from the store into the `/containers/storage`
so that stages that require containers can then make use of these
containers.
2024-02-21 17:55:37 +01:00
Gianluca Zuccarelli
26aac90eb4 util/containers: read host config
Add utility function to read the host's container storage config.
2024-02-21 17:55:37 +01:00
Gianluca Zuccarelli
462c498dcf util/mnt: add explicit rw option
Under certain conditions a bind mount without a specified `rw` or `ro`
option gets mounted read-only.  We need a way to be explicit about
needing a rw mount.  We might want to change this in the future to be a
single option (mode optional?) with valid values "rw", "ro".

It's not entirely clear what the conditions are but it occurs when bind
mounting the containers storage into the osbuild store, which we will
need for the next few commits.
2024-02-21 17:55:37 +01:00
schutzbot
c164665db1 Post release version bump
[skip ci]
2024-02-14 08:13:58 +00:00
Michael Vogt
7b5d6e4bd9 testutil: add new mock_command context manager
The new `testutil.mock_command` context manager can be used to
mock commands in PATH and replace them with arbitrary shell
scripts. This is useful in testing to e.g. simulate exact error
conditions that would be hard to trigger otherwise or to replace
long running commands with faked results.

Example:
```
fake_cmd = textwrap.dedent("""\
do-something
""")
with mock_command("some-cmd", fake_cmd):
   your_code
```
2024-02-12 17:41:21 -08:00
Ondřej Budai
226b50eba5 stages: add new org.osbuild.bootc.install-to-filesystem
Support the `boot install to-filesystem` capability to install a
bootc image to a filesystem.
2024-02-09 12:03:09 +01:00
schutzbot
a85b51bb2c Post release version bump
[skip ci]
2024-02-08 14:03:15 +00:00
Dusty Mabe
e1cbf92673 ostree: add convenience function for using default OSTree deployment
This adds a `default: true` option for all cases where OSTree
information is specified in schemas and allows for the information
to be picked up from the filesystem.

This is a safe operation because when building disk images there is
no known case where having two deployments makes sense. In the case
there ever were a case then the osname, ref, and serial options still
exist and can be used.

Co-authored-by: Luke Yang <luyang@redhat.com>
Co-authored-by: Michael Vogt <michael.vogt@gmail.com>
2024-02-07 18:50:38 -05:00
Michael Vogt
6b8c1872f6 fscache: use remove_lru() to reclaim space when the cache is full
This commit adds code that will remove the least recently used
entries when a store() operation does not succeeds because the
cache is full. To be more efficient it will try to free
twice the requested size (this can be configured in the code).
2024-02-06 17:16:48 +01:00
Michael Vogt
6096f999f3 fscache: add FsCache._remove_lru() to remove entries
The FsCache._remove_lru() removes the least recently used entry
from the cache.
2024-02-06 17:16:48 +01:00
Michael Vogt
b2a82beb75 fscache: add new `FsCache._last_used_objs()' helper
This commit adds a helper that can be used to get a sorted list
of cache entries. The list includes the name and the last_used
information.
2024-02-06 17:16:48 +01:00
Dusty Mabe
bd6b8ffb83 mounts/ostree.deployment: support deployments on mount
Instead of operating directly on the tree for a stage we can operate
on a mount too. This is useful in the case where operating on the
directory tree of files isn't sufficient and the modifications need
to be made directly to the filesystems on the disk image that we are
creating.

One such example of this is we are having a problem right now where
the immutable bit being set on an OSTree deployment root doesn't
survive the `cp -a --reflink=auto` in the org.osbuild.copy stage when
being copied from the directory tree into the mounted XFS filesystem
we created on the disk image. Thus we have to workaround this loss
of attribute by applying the attribute directly on the mounted
filesystem from the disk.

In this change here we also add a check in osbuild/mounts.py to not
attempt a umount of the root of the mounts directory if that path
is no longer a mountpoint, which can happen when the umount -R
from the mounts/org.osbuild.ostree.deployment also removes the
overmount.

Here is an example of how this would be used:

```
  - type: org.osbuild.chattr
    options:
      immutable: true
      path: mount://root/
    devices:
      disk:
        type: org.osbuild.loopback
        options:
          filename: disk.img
          partscan: true
    mounts:
      - name: root
        type: org.osbuild.xfs
        source: disk
        partition:
          mpp-format-int: '{image.layout[''root''].partnum}'
        target: /
      - name: ostree.deployment
        type: org.osbuild.ostree.deployment
        options:
          source: mount
          deployment:
            osname: fedora-coreos
            ref: ostree/1/1/0
```

The initial mount on `/` is the filesystem from the root partition
on the disk. The second mount (of type org.osbuild.ostree.deployment)
then reconfigures things similar to how an OSTree system is set up.
2024-01-31 16:46:01 -05:00
schutzbot
21626926f7 Post release version bump
[skip ci]
2024-01-31 17:48:02 +00:00
schutzbot
348438303e Post release version bump
[skip ci]
2024-01-31 08:13:08 +00:00
Simon de Vlieger
f9b55ff6a0 sources: rename download -> fetch_all
Not all sources download things and `fetch_all` is consistent with
`fetch_one`.
2024-01-26 09:58:48 +01:00
Simon de Vlieger
2c42c46c48 sources: move parallelisation into source
This moves the parallelisation decisions into the sources themselves,
making the `download` method abstract inside `osbuild` itself.
2024-01-26 09:58:48 +01:00
Michael Vogt
d8835150c2 osbuild: add "mypy-strict" check 2024-01-23 12:01:45 +01:00
Michael Vogt
a56afcb280 test: add new testutil.assert_jsonschema_error_contains() helper
This commit adds a new helper `assert_jsonschema_error_contains()`
to `testutil` and uses it everywhere where we check errors from
jsonschema.
2024-01-23 12:00:59 +01:00
Michael Vogt
f5d6d11f1d osbuild: error when {Device,Mount} is modified after creation
This is a drive-by change after spending some quality time with the
mount code. The `id` field of `Mount` is calculated only once and
only when creating a `Mount`. This seems slightly dangerous as
any change to an attribute after creation will not update the
id. This means two options:
1. dynamically update the `id` on changes
2. forbid changes after the `id` is calculcated

I went with (2) but happy to discuss of course but it seems more
the spirit of the class.

It also does the same change for "devices.Device"
2024-01-19 02:54:26 +01:00
schutzbot
c4ff215149 Post release version bump
[skip ci]
2024-01-16 13:48:47 +00:00
Dusty Mabe
83a14886d3 add --break for requesting a debug shell
Similar to rd.break for dracut this allows a user to specify:

- --break or --break=*
    - to get a shell before each stage is run
- --break=stage.name
    - to get a shell each time the stage with that name is run
    - example: --break=org.osbuild.copy
- --break=stage.id
    - to get a shell each time the stage with that ID is run
    - get the ID for the stages for your manifest by running
      osbuild on the manifest with --inspect
    - example: --break=dc6e3a66fef3ebe7c815eb24d348215b9e5e2ed0cd808c15ebbe85fc73181a86

and get a bash shell where they can inspect the environment to debug
and develop OSBuild stages.
2024-01-10 08:39:27 -08:00
Michael Vogt
ac5653d9f1 stages: rework container-deploy stage to not use tmp storage
This commit reworks the `org.osbuild.container-deploy` stage to
not use a tmp storage when mounting the container image. This
is needed because of [0] but it should generally be fine because
inside the stages the real /var is a tmpfs (which is why we
triggered the bug in the first place).

[0] https://github.com/containers/storage/issues/1779
2024-01-03 11:25:48 -08:00
Michael Vogt
ad8fd2f532 testutil: extrace new make_fake_tree() helper
Extract a new helper `make_fake_tree()` that generalizes the existing
helper `make_fake_input_tree()`. The later will always create the
content under `{basedir}/tree` which is convinient for input tree
based tests but too specialized when using it in different contexts.

The existing `make_fake_input_tree()` is preserved unchanged and
becomes just a tiny wrapper.
2024-01-03 11:25:48 -08:00
schutzbot
25d198da3c Post release version bump
[skip ci]
2024-01-03 08:14:11 +00:00
Michael Vogt
e76e0e92d6 osbuild: take partition into account in calc_id and add test 2023-12-22 10:18:29 -05:00
Michael Vogt
827b238764 format/v2: add new "partition" field to "describe_mount" 2023-12-22 10:18:29 -05:00
Dusty Mabe
ce8408a9c6 mounts: support mounting partitions
This allows us to map in a whole disk as a loopback device with parition
scanning rather than slicing up the disk and creating several loopback
devices. Something like this:

```
      - type: org.osbuild.copy
        inputs:
          tree:
            type: org.osbuild.tree
            origin: org.osbuild.pipeline
            references:
              - name:tree
        options:
          paths:
            - from: input://tree/
              to: mount://root/
        devices:
          efi:
            type: org.osbuild.loopback
            options:
              filename: disk.img
              start:
                mpp-format-int: '{image.layout[''EFI-SYSTEM''].start}'
              size:
                mpp-format-int: '{image.layout[''EFI-SYSTEM''].size}'
          boot:
            type: org.osbuild.loopback
            options:
              filename: disk.img
              start:
                mpp-format-int: '{image.layout[''boot''].start}'
              size:
                mpp-format-int: '{image.layout[''boot''].size}'
          root:
            type: org.osbuild.loopback
            options:
              filename: disk.img
              start:
                mpp-format-int: '{image.layout[''root''].start}'
              size:
                mpp-format-int: '{image.layout[''root''].size}'
        mounts:
          - name: root
            type: org.osbuild.xfs
            source: root
            target: /
          - name: boot
            type: org.osbuild.ext4
            source: boot
            target: /boot
          - name: efi
            type: org.osbuild.fat
            source: efi
            target: /boot/efi
```

now becomes a little more simple:

```
      - type: org.osbuild.copy
        inputs:
          tree:
            type: org.osbuild.tree
            origin: org.osbuild.pipeline
            references:
              - name:tree
        options:
          paths:
            - from: input://tree/
              to: mount://root/
        devices:
          disk:
            type: org.osbuild.loopback
            options:
              filename: disk.img
              partscan: true
        mounts:
          - name: root
            type: org.osbuild.xfs
            source: disk
            partition:
              mpp-format-int: '{image.layout[''root''].partnum}'
            target: /
          - name: boot
            type: org.osbuild.ext4
            source: disk
            partition:
              mpp-format-int: '{image.layout[''boot''].partnum}'
            target: /boot
          - name: efi
            type: org.osbuild.fat
            source: disk
            partition:
              mpp-format-int: '{image.layout[''EFI-SYSTEM''].partnum}'
            target: /boot/efi
```

Fixes https://github.com/osbuild/osbuild/issues/1495
2023-12-22 10:18:29 -05:00
Michael Vogt
a6fba858ab osbuild: honor OSBUILD_EXPORT_FORCE_NO_PRESERVE_OWNER env
To workaround the issue that inside macOS containers the ownership
cannot be preserved we introduce a new environment that can be
used to forcefully relax the use of `cp -a`.

I did it via an environment instead of a commandline option mostly
because `github.com/osbuild/images/osbuild:RunOBuild()` already has
`extraEnv` option.
2023-12-20 09:28:39 +01:00
Michael Vogt
e35d841509 objectstore: add new skip_preserve_owner to Object.export()
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 :)
2023-12-20 09:28:39 +01:00
schutzbot
975057a0a9 Post release version bump
[skip ci]
2023-12-20 08:12:39 +00:00
Luke Yang
5fc3b565a2 create org.osbuild.ostree.aleph stage
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.
2023-12-19 17:58:39 +01:00
Dusty Mabe
2e6a3c96ce osbuild/util/ostree: convert cli to return the completed process object
And also set stdout=subprocess.PIPE. This will allow for callers to
parse and use the output of the command, but has the side effect of
meaning less gets printed to the screen during run.

Co-authored-by: Luke Yang <luyang@redhat.com>
2023-12-19 17:58:39 +01:00
Dusty Mabe
dfd59a38d9 osbuild/mounts: adjust the source path to use when mounting devices
Adjust the source path to just have /dev in front (i.e. /dev/loop0)
and not be a path to the temporary dev directory that was prepared.
We do this because some tools (like grub2-install) consult
mountinfo to try to canonicalize paths for mounts.

Fixes https://github.com/osbuild/osbuild/issues/1492
2023-12-15 09:54:29 -05:00
Michael Vogt
caddf0adfb fscache: add new FsCache._last_used() helper
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.
2023-12-12 22:57:21 +01:00
Michael Vogt
f52cabc3c1 osutil: add Libc.futimens() wrapper for futimens() call
Python has no wrapper for a futime*() call so we need to implement
it in the `util.linux` package.
2023-12-12 22:57:21 +01:00
Brian C. Lane
9eb9f7f7f2 test: Move make_fake_input_tree to testutil
This is useful for other stage tests, move it and add a test.
2023-12-12 19:45:04 +01:00
Michael Vogt
5416028f2d osbuild: include std{out,err} in FileSystemMountService.mount() errors
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!).
2023-12-12 16:25:35 +01:00
Alexander Larsson
eea81b660a testutils: Add assert_dict_has
This is a convenient way for tests to assert that some nested dicts
(like a parsed json) has a particular key/value somewhere in it.

For example:
  assert_dict_has(config, "toplevel.subitem.key", True)
2023-12-12 09:54:38 +01:00