Commit graph

664 commits

Author SHA1 Message Date
Ondřej Budai
d827be2fb2 rename all .mpp.json files to .mpp.yaml
osbuild-mpp supports yaml files. The advantage of yaml is that it's less
verbose and allows comments. This way, we can start documenting all the
test manifests in this repository.

This is the first step: This commit just renames the files, so we keep the
history intact. Remember: YAML is a super-set(*) of JSON, so this is fine.

There is no functional change in this commit.

(*) There are some caveats, but we don't need to care in this case.
2023-08-08 12:41:17 +02:00
Ondřej Budai
2d23f9c17c samples: remove empty el8-ostree-bootiso.json
No idea why this is here.
2023-08-08 12:41:17 +02:00
Simon de Vlieger
d60690ce46 tox: add tox
`tox` is a standard testing tool for Python projects, this allows you to
test locally with all your installed Python version with the following
command:

`tox -m test -p all`

To run the tests in parallel for all supported Python versions.

To run linters or type analysis:

```
tox -m lint -p all
tox -m type -p all
```

This commit *also* disables the `import-error` warning from `pylint`,
not all Python versions have the system-installed Python libraries
available and they can't be fetched from PyPI.

Some linters have been added and the general order linters run in has
been changed. This allows for quicker test failure when running
`tox -m lint`. As a consequence the `test_pylint` test has been removed
as it's role can now be fulfilled by `tox`.

Other assorted linter fixes due to newer versions:
- use a str.join method (`consider-using-join`)
- fix various (newer) mypy and pylint issues
- comments starting with `#` and no space due to `autopep8`

This also changes our CI to use the new `tox` setup and on top of that
pins the versions of linters used. This might move into separate
requirements.txt files later on to allow for easier updating of those
dependencies.
2023-08-01 15:01:13 +02:00
Gianluca Zuccarelli
74eed6a33b stages: add openscap autotailor stage
Add a new stage to generate an OpenSCAP tailoring file. The stage
overrides a base OpenSCAP profile by enabling and disabling user
selected rules and creates a new profile name which can be used for
OpenSCAP scanning and remediation.
2023-07-18 15:29:13 -07:00
Ondřej Budai
4439297cc4 test/data: introduce UKI also for CentOS Stream
This is a straightforward port of the UKI from Fedora to CentOS Stream.
Changes:

- Packages that does not exist in CS9 were removed:
  - shim-ia32
  - grub2-efi-ia32-cdboot
  - btrfs-progs
- Squashfs compression was changed from lz4 to gzip, because lz4 for squashfs
  isn't enabled in RHEL 9 kernel
2023-07-18 11:30:09 +02:00
Simon de Vlieger
82e72f1b64 test: update test for sysconfig 2023-07-17 12:15:12 +02:00
Antonio Murdaca
4bfd646b0d stages: add new zstd stage
typo fix test/data/stages/README.md
add updated test-data after adding zstd to fedora-34-build-v2.mpp.json

Signed-off-by: Sarita Mahajan <sarmahaj@redhat.com>
2023-06-14 09:44:00 +02:00
Simon de Vlieger
4bd169c20e stage: add a livesys stage
This stage is necessary for the live image work being done in
`osbuild-composer` at the moment.
2023-05-31 09:30:55 +02:00
Tomáš Hozza
15b7b6fab3 test/stages: add helper function for testing partitioning stages
Refactor unit test implementation for `parted`, `sfdisk` and `sgdisk`
stages by extracting the common parts into a helper function. Each stage
now implements only its own function for filtering `sfdisk --json`
output and calls the common helper function.

In addition, flip the oder when comparing the expected and actual output
from `sfdisk --json`, to make it more easier to comprehend.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-05-30 12:05:33 +02:00
Tomáš Hozza
17ebae23dc test: add unit test for sfdisk stage
Add a missing unit test for the `sfdisk` stage.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-05-30 12:05:33 +02:00
Tomáš Hozza
66301ae5c3 test/sgdisk: delete sectorsize from expected data if not in output
The `sfdisk` tool on RHEL-8 does not include the `sectorsize` in its
output when we are testing the `sgdisk` stage. As a result, the test
case fails, because the expected and actual output differs. Modify the
test to delete the `sectorsize` key from the expected output if it is
not present in the actual output.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-05-30 12:05:33 +02:00
Tomáš Hozza
560fcc099d test/parted: delete sectorsize from expected data if not in output
The `sfdisk` tool on RHEL-8 does not include the `sectorsize` in its
output when we are testing the `parted` stage. As a result, the test
case fails, because the expected and actual output differs. Modify the
test to delete the `sectorsize` key from the expected output if it is
not present in the actual output.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-05-30 12:05:33 +02:00
Tomáš Hozza
3e780762cb stages/sgdisk: option to not quote partition names passed to sgdisk
The partition name in the sgdisk stage was previously quoted when
passed to sgdisk as an argument. I think that this was done because
the sgdisk man page states that:

```
If you want to set a name that includes a space, enclose it in
quotation marks, as in sgdisk -c 1:"Sample Name" /dev/sdb.
```

However, this should apply only when sgdisk is run in a shell, so that
the argument is not split by shell into multiple arguments and passes
as a single string.

The stage is executing sgdisk using Python `subprocess` module, which
does not need strings with spaces to be quoted, because they are passed
to the command as separate items which are not split in any way.

The previous behavior of the stage was that these quotes became part of
the actual partition name in the partition table.

After a discussion within the team, we determined that this is a bug.
However, fixing it would result in osbuild producing a different
artifact for the same manifest, compared to osbuild version without such
fix. This is undesired.

For backward compatibility, a new `quote_partition_name` property is
added to the stage options, which can be used to make the stage not
quote the partition name when passed to `sgdisk`. As a result, the
partition name won't be quoted in the partition table.

The default stage behavior us kept.

Modify unit tests to use this option by default.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-05-26 08:43:52 +02:00
Thomas Lavocat
da11ef4eb0 loop: use LOOP_CONFIGURE instead of LOOP_SET_FD
LOOP_CONFIGURE allows to atomically configure the decive when opening
it. This avoid the possibility of a race condition where between set_fd
and set_status some operations are already accepted by the loopback
device. See https://lwn.net/Articles/820408/

This feature was included in the linux kernel 5.8 however it is safe to
not include any kind of fallback to the previous method as @obudai
points out that:

LOOP_CONFIGURE was backported into RHEL 8 kernel in RHEL 8.4 as a part
of https://bugzilla.redhat.com/show_bug.cgi?id=1881760 (block layer:
update to upstream v5.8).

Since RHEL 8.4 is currently the oldest supported release that we support
running osbuild on, it might be just fine implementing this without the
fallback.

From a centos stream 8 container:
kernel-4.18.0-448.el8.x86_64
- loop: Fix missing discard support when using LOOP_CONFIGURE (Ming Lei) [1997338]
- [block] loop: Set correct device size when using LOOP_CONFIGURE (Ming Lei) [1881760]
- [block] loop: unset GENHD_FL_NO_PART_SCAN on LOOP_CONFIGURE (Ming Lei) [1881760]
- [block] loop: Add LOOP_CONFIGURE ioctl (Ming Lei) [1881760]
2023-05-05 15:42:47 +02:00
Gianluca Zuccarelli
586d6bbe43 stages/yum.repo: add sslverify field
Add `sslverify` field to the yum.repo stage.
2023-05-03 20:53:52 +02:00
Tomáš Hozza
5946a013ee Test: some tests depending on rpm-ostree were not checking its presence
Add conditional skip to some tests that depend on rpm-ostree
availability, but were not checking for its presence. These tests would
previously fail if rpm-ostree is not available. They will be skipped
now.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-04-28 22:02:35 +02:00
Tomáš Hozza
3100882019 Don't use directory argument with SimpleHTTPRequestHandler constructor
The `directory` argument has been added only since Python 3.7, which
breaks the unit test on Python 3.6.

Reimplement the intended behavior by overriding the `translate_path()`
method, which takes the `directory` value into account on newer Python
versions.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-04-26 11:43:13 +02:00
Tomáš Hozza
eb427e2513 Don't use capture_output=True with subprocess.run()
The `capture_output` argument does not exist on Python 3.6 used by
default on RHEL-8.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-04-26 11:43:13 +02:00
Tomáš Hozza
d9e97a4830 Test/assemblers/assertImageFile: don't set default argument values
Do not specify the default value for 'expected_size' argument in
assertImageFile() function declaration. Previously, it was set to
`None`, which was never taken into account. Moreover, all callers of the
function always provide an explicit value, so the default was never
really used.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-04-21 17:13:10 +02:00
Tomáš Hozza
ff6b96bee5 Test: add ability to skip tests for unsupported file-systems
Add a new optional pytest CLI argument `--unsupported-fs` allowing to
specify file-systems which should be treated as unsupported in the
platform where running tests. Any test cases dependent on such
file-system support will be sipped.

This will allow to run unit tests and selectively skipping test cases
for unsupported file-systems.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-04-21 17:13:10 +02:00
Tomáš Hozza
db89984465 Test: port assembler tests from unittest to pytest
Port assembler tests from unittest to pytest. In addition, use
parametrized tests when testing various filesystems and various
combinations.

This is important to be able to selectively skip the test for if a
specific filesystem is not supported by the kernel (e.g. btrfs is not
supported on RHEL). Skipping a unittest subtest is not possible, which
is the motivation to move away from it and use only pytest.

Test output is now also much nicer for parametrized test cases.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-04-21 17:13:10 +02:00
Tomáš Hozza
56987fdda4 Test: make run/test_mount.py not depend on installed osbuild
Previously, the unit test depended on osbuild modules being installed on
the system. As a result, this made the test not work in CI where we do
not install osbuild when running unit tests. In addition, the stage
executed by the unit test would use different version of osbuild
internals than the version that is being tests, which could result in
issues or not testing the intended code.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-04-12 11:57:18 +02:00
Tomáš Hozza
975965510b Test: handle non-existence of /run/osbuild in test/run/test_mount.py
The directory does not exist when the unit test is run in CI. Handle
this case by ensuring that parent directories are created as needed.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-04-12 11:57:18 +02:00
Sanne Raymaekers
33597e82a3 test/data/stages: add wsl.conf test 2023-04-11 10:11:08 +02:00
Simon de Vlieger
12e4e541c3 stage/systemd.preset: be able to write a preset file
The right way to enable services is to use a preset file instead of
writing directly into /etc. This adds a new stage called
`org.osbuild.systemd.preset` to do so.
2023-04-05 14:34:39 +02:00
Achilleas Koutsou
532a4c1166 test: add manifest-list test for skopeo stage
Added another skopeo stage to skopeo/a.mpp.json with a skopeo source for
a container hosted on the osbuild-composer gitlab registry.  The name
points to a manifest list, which refers to two containers (amd64 and
arm64) that contain a single text file (README.md).  The `index` field
is enabled to include the manifest-list as an extra input to the stage.

The diff is updated with the new expected file list.
The containers were created with buildah:

  amd=$(buildah from --arch=amd64 scratch)
  arm=$(buildah from --arch=arm64 scratch)
  buildah config --created-by "Achilleas Koutsou" "${amd}"
  buildah config --created-by "Achilleas Koutsou" "${arm}"
  buildah copy "${amd}" README.md
  buildah copy "${arm}" README.md
  amdid=$(buildah commit --format=docker --rm "${amd}")
  armid=$(buildah commit --format=docker --rm "${arm}")
  name="registry.gitlab.com/redhat/services/products/image-builder/ci/osbuild-composer/manifest-list-test"
  buildah manifest create "${name}" "${amdid}" "${armid}"

  podman manifest push --all "${name}" dir:container
2023-03-31 14:57:26 +02:00
Sanne Raymaekers
bae4f77661 stages: add ovf stage
This stage generates an ovf descriptor and a manifest intended for
vSphere. The resulting artifacts can be tarred together with the vmdk
into an ova.
2023-03-28 23:07:38 +02:00
Simon de Vlieger
162587724a test: this test requires to be able to bindmount 2023-03-20 16:32:47 +01:00
Tomáš Hozza
200c2b0129 stages/copy: add option to remove destination before copying
Extend the copy stage to optionally allow removing the destination
before copying. This allows one to not follow symlinks if the
destination is a symlink to a file. By default, `cp` would change
the file pointed to by the destination if it is symlink.

Extend the stage doc text to cover the behavior with regard to
destination being a symlink.

Add unit tests for the copy stage to also test the newly added option.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-02-20 10:31:06 +01:00
Achilleas Koutsou
d3229dc929 stages/shell.init: add top-level files property
Add a top level property "files" to the schema and move the rest of the
existing schema one level down.  This way we can support adding global
properties in the future if we ever need to expand the scope of the
stage.
2023-02-15 18:14:01 +01:00
Achilleas Koutsou
b848e5d9df stages/shell.init: add pattern for env var names
Pattern for valid environment variable names as defined in
The Open Group Base Specifications Issue 7, 2018 edition
IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008)

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html

Updated tests to match UPPERCASE ONLY var names.
2023-02-15 18:14:01 +01:00
Achilleas Koutsou
d5701dac28 test: add unit test for org.osbuild.shell.init 2023-02-08 13:30:39 +01:00
Tomáš Hozza
16063fff57 Add org.osbuild.chown stage
Add a new `org.osbuild.chown` stage for setting user and group ownershop
of files. The stage runs the `chown` from the image using `chroot` to
enable it to use users and groups that exist only in the (image) tree.

Add unit test testing the stage in various scenarios.

Co-authored-by: Janine Olear <pninak@web.de>
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-02-07 12:14:01 +01:00
Thomas Lavocat
8f08433804 mounts: accept more mount options
Before we could only ask OSBuild to mount a device as readonly. But
devices can have more mount options than this. Supporting more options
is necessary for the new version of image-info that is using OSBuild's
internals in order to mount the image it wants to work on. Otherwise,
for instance, some umasks aren't applied properly and we can get
differences in rpm-verify results, thus corrupting the DB.

Mount is now accepting:
* readonly
* uid
* gid
* umask
* shortname
2023-02-01 12:29:58 +01:00
Tomáš Hozza
d3a63cf056 Revert "stages/mkdir: explicitly set mode using os.chmod"
This reverts commit a988aacf99.

After some discussion, the original behavior was intentional. With the
added support for gracefully handling the existence of directories, the
stage would originally not set the mode of an existing directory, while
now it will. Additional issue is that `mkdir` applies the provided mode
- umask, which was intentional. Setting the same mode without taking
umask value into account is not desired.
2023-01-20 14:28:36 +01:00
Tomáš Hozza
b8e1450a35 stages/mkdir: add exist_ok option to not fail if directory exists
Add a new optional stage option to not fail if the specified directory
already exists. This will make it easier to support creation of custom
repositories via customizations in osbuild-composer. The reason is that
if a specified directory exists in an image, because it was created by
an RPM, then creating it would fail. However, the user may have
specified different mode for the directory, than it already has. Since
there is no way to know for sure if the directory already exists on the
image, without building the image itself, it is desired to handle this
case gracefully as valid in specific use cases.

The default behavior stays the same - specifying an existing directory
path will lead to an error.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2023-01-16 20:19:27 +01:00
Achilleas Koutsou
fdf064b15a test: update rhsm.facts diff 2023-01-03 09:27:13 +01:00
Christian Kellner
d466d5d66a test/objectstore: use os.stat instead Path.stat
Instead of using `Path.stat` use `os.stat` since the former only
gained the `follow_symlinks` argument in 3.10 but we still need
to support Python 3.6 for RHEL 7 and 8.
Additionally, reduce the precision by converting timestamps to an
integer to avoid false negatives due to floating point arithmetic.
2022-12-28 11:35:37 +01:00
David Rheinsberg
18c69d2620 util/fscache: add cachedir-tag support
The cachedir-tag specification defines how to mark directories as
cache-directories. This allows tools like `tar` to ignore those
directories if desired (e.g., see `tar --ignore-caches`). This is very
useful to avoid huge cache-directories in backups and remote
synchronizations.

The spec simply defines a file called `CACHEDIR.TAG` with the first 43
bytes to be: "Signature: 8a477f597d28d172789f06886806bc55" (which
happens to be the MD5-checksum of ".IsCacheDirectory". Further content
is to be ignored. Any such files marks the directory in question as a
cache-directory.

The cachedir-tag has been successfully deployed in tools like `cargo`
and `VLC`, and is currently discussed to be implemented in Firefox. More
information is available here: https://bford.info/cachedir/

Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com>
2022-12-20 16:56:43 +01:00
David Rheinsberg
a3e49df619 test/fscache-coherency: add coherency tests
Add an extension to the FsCache tests which verifies cache coherency and
atomicity of the FsCache implementation. Additionally, if available, it
utilizes a cache on NFS storage to test network-support.

Unfortunately, the stress-tests keep triggering kernel-oopses in the NFS
client driver, so they are disabled for now. However, once investigated,
we can re-enable them.

Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com>
2022-12-20 16:56:32 +01:00
David Rheinsberg
8a9efa89fc util/fscache: provide store_tree() helper
Add a helper that copies an entire directory tree including all metadata
into the cache. Use it in the ObjectStore to commit entries.

Unlike FsCache.store() this does not require entering the context from
the call-site. Instead, all data is directly passed to the cache and the
operation is under full control of the cache.

The ObjectStore is adjusted to make use of this. This requires exposing
the root-path (rather than the tree-path) to be accessible for
individual objects, hence a `path`-@property is added alongside the
`tree`-@property. Note that `__fspath__` still refers to the tree-path,
since this is the only path really required for outside access other
than from the object-manager itself.

Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com>
2022-12-20 16:56:32 +01:00
Christian Kellner
1d193008d4 test/data: set source epoch for certain pipelines
For selected pipelines, set the source epoch. The date is set to
the current updates snapshot date (in epoch).
2022-12-15 13:10:35 +00:00
Christian Kellner
76197c70c4 objectstore: support source_epoch for Object
Add a new `source_epoch` attribute that if set, will lead to all
mtimes that are newer or equal to the creation date being clamped
to the specified `source_epoch` time when the object is finalized.
2022-12-15 13:10:35 +00:00
Christian Kellner
39d38d33fd util/path: new clamp mtime function
New utility function to clamp all mtimes of a given path to a
certain timestamp. Clamp here means that any timestamp later
than the specified upper bound will be set to the upper bound.
2022-12-15 13:10:35 +00:00
Christian Kellner
acc54c5202 test/ostree-image: +fedora-ostree-native-container
Test building the new fedora-ostree-native-container manifest.
2022-12-15 11:13:19 +01:00
David Rheinsberg
ef20b40faa util/fscache: introduce versioning
Add a new field to the cache-information called `version`, which is a
simple integer that is incremented on any backward-incompatible change.

The cache-implementation is modified to avoid any access to the cache
except for `<cache>/staging/`. This means, changes to the staging area
must be backwards compatible at all cost. Furthermore, it means we can
always successfully run osbuild even on possibly incompatible caches,
because we can always just ignore the cache and fully rely on the
staging area being accessible.

The `load()` method will always return cache-misses. The `store()`
method simply discards the entry instead of storing it. Note that
`store()` needs to provide a context to the caller, hence this
implementation simply creates another staging-context to provide to the
caller and then discard. This is non-optimal, but keeps the API simple
and avoids raising an exception to the caller (but this can be changed
if it turns out to be problematic or unwanted).

Lastly, the `cache.info` field behaves as usual, since this is also the
field used to read the cache-version. However, this file is never
written to improve resiliency and allow blacklisting buggy versions from
the past.

Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com>
2022-12-15 08:55:39 +01:00
Christian Kellner
fdd9e859dc test: convert objectstore test to pytest
Port the existing object store tests from `unittest` to `pytest`.
Allow all tests that can run without root privileges to do so. No
functional change of the test itself.
2022-12-14 13:50:28 +01:00
Christian Kellner
ae0680da11 osbuid: integrate FsCache into ObjectStore
Integrate the recently added file system cache `FsCache` into our
object store `ObjectStore`. NB: This changes the semantics of it:
previously a call to `ObjectStore.commit` resulted in the object
being in the cache (i/o errors aside). But `FsCache.store`, which
is now the backing store for objects, will only commit objects if
there is enough space left. Thus we cannot rely that objects are
present for reading after a call to `FsCache.store`. To cope with
this we now always copy the object into the cache, even for cases
where we previously moved it: for the case where commit is called
with `object_id` matching `Object.id`, which is the case for when
`commit` is called for last stage in the pipeline. We could keep
this optimization but then we would have to special case it and
not call `commit` for these cases but only after we exported all
objects; or in other words, after we are sure we will never read
from any committed object again. The extra complexity seems not
worth it for the little gain of the optimization.
Convert all the tests for the new semantic and also remove a lot
of them that make no sense under this new paradigm.

Add a new command line option `--cache-max-size` which will set
the maximum size of the cache, if specified.
2022-12-09 12:03:40 +01:00
Christian Kellner
1e0e1fa2c2 util: add helper to parse size strings
Code is based on `common.DataSizeToUint64` in Composer, with a
modification to allow `unlimited` so that the result is compatible
with `fscache.MaximumSizeType`.

[1] f4aed3e6e2/internal/common/helpers.go (L46)
2022-12-09 12:03:40 +01:00
Christian Kellner
e2c687e363 test/objectstore: properly enter store context
In the `store_server` test, pass the store to `enter_context`,
instead of the `stack`; the latter is an interesting form of
recursion, and totally not what we want.
2022-12-09 12:03:40 +01:00