This commit adds a very in-depth test for multi-tenancy. It queues several
composes and then runs all jobs belonging to them while checking that
they are run by the correct tenant.
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
Yeah, we have TestRoute. It has one issue though: It doesn't have support
for passing a custom context. One option is to extend the method with yet
argument but since it already has 9 (!!!), this seems like a huge mess.
Therefore, I decided to invent a new small library for writing API tests.
It uses structs heavily which means that adding features to it doesn't
mean changing 100 lines of code (like adding another arg to TestRoute does).
I hope that we can start using this library more in our tests as it was
designed to be very flexible and powerfule.
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
This commit implements multi-tenancy. A tenant is defined based on a value
from JWT claims. The key of this value must be specified in the configuration
file. This allows us to pick different values when using multiple SSOs.
Let me explain more in depth how this works:
Cloud API gets a new compose request. Firstly, it extracts a tenant name from
JWT claims. The considered claims are configured as an array in
cloud_api.jwt.tenant_provider_fields in composer's config file. The channel
name for all jobs belonging to this compose is created by `"org-" + tenant`.
Why is the channel prefixed by "org-"? To give us options in the future. I can
imagine the request having a channel override. This basically means that
multiple tenants can share a channel. A real use-case for this is multiple
Fedora projects sharing one pool of workers.
Why this commit adds a whole new cloud_api section to the config? Because the
current config is a mess and we should stop adding new stuff into the koji
section. As the Koji API is basically deprecated, we will need to remove it
soon nevertheless.
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
jobqueue.Job must return the channel specified in jobqueue.Enqueue during
the whole lifecycle of the given job.
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
Channels are a concept similar to job types. Callers must specify a channel
name when queueing a new job. A list of channels is also specified when
dequeueing a job. The dequeued job's channel will always be from one of the
specified channel. Of course, the job types are also respected. The dequeued
job will also always be from one of the specified type.
Currently, all calls to jobqueue were changed so all queue operations use
an empty channel name and all dequeue operations use a list containing
an empty channel.
Thus, this is a non-functional change.
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
Add a new option `GPGKeyFiles` to ImageConfig that indicates which files
containing GPG keys should be imported into rpm. For now it will be used
by the osPipeline in rhel{86,90} to set the corresponding option in the
`org.osbuild.rpm` stage.
The `org.osbuild.rpm` stage gained a new option `gpgkeys.fromtree`
which is a list of paths with files containing gpgkeys that will
be imported after the package installation phase is done.
rpmmd_mock fixture are complex and unneeded in the context of cloudapi, let's
just copy 3 lines from them and drop the dependency.
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
The edge installer and edge simplified installer build roots have
diverged, i.e. the latter need clevis/luks, so define a new pkg
set for the simplified installer extending the edge installer one.
Co-Authored-By: Christian Kellner <christian@kellner.me>
This is only required in RHEL9.0, but best practice is to always pin these things
down. Also increases uniformity between distros.
Simplify a bit the volid generator by making it require `rand.Rand` rather than
`io.Reader`, and hence eliminating the need for error handling.
In LUKSContainer and LVMLogicalVolume we neglected to clone the Payload
which means we would modify the base PartitionTable when manipulating
the clone.
Specify a size for the root filesystem in the partition table,
which basically equates to a minimum size. In reality all image
types specify a larger image size and thus we enlarge the root
file system to more than the specified size for plain layouts.
But if we auto-convert an partition layout to LVM we need a size
for the root partition.
Does not change any existing manifests.
This does not apply for ostree based systems like the simplified
installer.
Whenever we create a new mountpoint due to a user customization,
ensure the layout uses LVM, i.e. convert plain layouts to it, if
needed. It uses the existing lvm-ification code but enhances it
so that we also create a `/boot` partition in case it does not
yet exist.
Adjust the existing tests that assumed we can not create more
than 4 partitions on mbr layouts, since that is now not true
anymore.
Since udev will probe block devices it is advisable to hold a lock
on the device when modifying its partition table or the superblock
of the filesystem (see [1]). osbuild loopback devices do support
this via the `lock` option. Set this option for all operation that
involve changing block device "metadata" that could potentionally
race with udev, such as sfdisk, mkfs, creating a luks2 container
and creating LVM2 volume groups and logical volumes.
NB: osbuild also has its own device inhibition logic to prevent
udev/lvm2 from auto activating devices and in general to limit the
interaction between the host and devices used by osbuild. See [2]
for more information.
NB: this also locks the loopback device in situation where we the
it is strickly not the right thing to do, e.g. when creating a fs
on a logical voume that is located on a loopback device, since in
this case the device we would need to lock is the logical volume.
Sadly, LVM/DM devices are exempt from block device locking. But,
due to a bug in osbuild < 50, the udev inhibitor does *not* work
for loopback devices and therefore we have to use the actual lock
to preven LVM device auto-activation via `69-dm-lvm-metad.rules`.
The change was implemented by adding a new boolean to `getDevices`
indicating if the loopback device should be locked or not. Once
we depend on osbuild 50 we can change the logic in `getDevices`
to only lock the loopback device if the number of devices is one,
i.e. we are working directly on the loopback device.
[1] https://systemd.io/BLOCK_DEVICE_LOCKING/
[2] /usr/lib/udev/rules.d/10-osbuild-inhibitor.rules
Whenever we create a new mountpoint due to a user customization,
ensure the layout uses LVM, i.e. convert plain layouts to it, if
needed. This does not apply to rpm-ostree based systems, e.g. the
simplified installer since they will be using LUKS in 9.0.
Add "lvm2" to the build pipeline and thus generate new manifests
and image infos.
Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
Specify a size for the root filesystem in the partition table,
which basically equates to a minimum size. In reality all image
types specify a lager image size and thus we enlarge the root
file system to more than the specified size for plain layouts.
But if we auto-convert an partiton layout to LVM we need a size
for the root partition.
Does not change any existing manifests.
This does not apply for ostree based systems like the simplified
installer.
Re-introduce the VolumeContainer interface but with a different
meaning: it is supposed to be implemented by all container that
contain volumes and as a result have themselves a size, like eg
LVM2, LUKS2 and PartitionTable (the latter is not yet included).
The sole method on the interface for now is MetadataSize, which
should return the metadata for the container itself.
Use that new `VolumeContainer.MetadataSize` method when we up-
date the sizes of elements in `resizeEntitybranch`.
Add a new parameter `lvmify` to `NewPartitionTable` that, if set to
`true`, will cause the root partition to be wrapped in LVM in case
it is not in a LVM volume group. Set this to `false` for now so no
actual change should happen anywhere. Layouts where the root is
directly on a LUKS container are not yet supported.
Add tests for this.
Add support for building images for the Azure marketplace: add a
new image type "azure-rhui" that can be used to build images
tailored to the Azure marketplace.
Add two sample manifests for 8.5 and 8.6, but note that even the
8.5 is using the 8.6 distro definitions. Also no image-info is
included since `image-info` cannot (yet) handle LVM setups and
the azure marketplace images use the LVM setup.
The previous code assumed that the first partition is the location to
write the grub2 core image, implying it needs to always be a PReP or
BIOS-Boot partition. This is not an assumption we can easily make;
instead we now try to detect the correct partition based on its type.
When creating a new logical volume via the `CreateVolume` method,
the logical volume name was left blank. Generate an name based
on the mountpoint.
We will detect collisions for names and will try to correct them
by attaching a suffix. We do give up after 100 attempts though.
Add a simple test for it.