Commit graph

309 commits

Author SHA1 Message Date
Will Woods
6164b38fb9 Add STAGE_DESC, STAGE_INFO, and STAGE_OPTS to stages
This commit adds semi-structured documentation to all osbuild stages and
assemblers. The variables added work like this:

* STAGE_DESC: Short description of the stage.
* STAGE_INFO: Longer documentation of the stage, including expected
              behavior, required binaries, etc.
* STAGE_OPTS: A JSON Schema describing the stage's expected/allowed
              options. (see https://json-schema.org/ for details)

It also has a little unittest to check stageinfo - specifically:

1. All (executable) stages in stages/* and assemblers/ must define strings named
   STAGE_DESC, STAGE_INFO, and STAGE_OPTS
2. The contents of STAGE_OPTS must be valid JSON (if you put '{' '}'
   around it)
3. STAGE_OPTS, if non-empty, should have a "properties" object
4. if STAGE_OPTS lists "required" properties, those need to be present
   in the "properties" object.

The test is *not* included in .travis.yml because I'm not sure we want
to fail the build for this, but it's still helpful as a lint-style
check.
2019-11-13 21:47:03 +01:00
Will Woods
9d4b526a25 org.osbuild.rpm: make rpm --install check signatures
It turns out that rpm will happily check signatures on `--install`,
that's just not the default behavior, because of Historical Reasons.

This commit enables RPM's signature checking and drops our manual check,
which will probably speed up the RPM stage a little bit. Fun!

Oh, also there's two bonus code cleanups: one to use f-strings harder,
and one to make sure we ignore whitespace in package checksum strings.
2019-11-13 21:11:39 +01:00
Will Woods
d6ce127a8e org.osbuild.rpm: safe tempfiles
This makes the org.osbuild.rpm stage use safe temporary files for
handling keys and the package manifest.
2019-11-13 21:11:39 +01:00
Will Woods
8b8493cf04 org.osbuild.{dnf,yum}: use safe tempfiles
As a general rule, using temporary files with predictable names is a
security risk. It probably isn't _actually_ a security risk inside
osbuild stages, since they're usually running in some kind of isolated
container environment, but it's still a better idea to use tempfiles.

This makes the dnf and yum stages put their temporary files into a
temporary directory that gets deleted after dnf/yum finishes.
2019-11-13 21:11:39 +01:00
msehnout
93a3f68a31 Fill in the license template
Fixed #159
2019-11-12 12:41:21 +01:00
Lars Karlitski
1f526477d2 5 2019-10-30 18:49:56 +01:00
Christian Kellner
6e5b838892 pipeline: use API to setup stdio inside the container
Use the new the osbuild API to setup the standard input/output
inside the container, i.e. replace stdin, stdout, and stderr with
sockets provided by the host.
2019-10-30 18:44:55 +01:00
Christian Kellner
93e1c60460 api: new host side API to be used by the container
Introduce an osbuild API that can be used by the container to talk
to the osbuild host. It currently supports one method 'setup-stdio'
which should be used by the container to setup its standard input/
output so the stages can transparently do i/o with the osbuild host
via stdio.
The input data (args) is written to a temp-file backed buffer. The
output is either the host's stdout directly or another temp-file
backed buffer; the latter is re-opened (via /proc/self/fd) to get
another file-descriptor for the container, so in theory the host
and the container could do i/o to the same buffer independently.
2019-10-30 18:44:55 +01:00
Christian Kellner
76518db26b dump_fds: add flags and address parameter
Expose the flags, address parameter of the underlying sock.sendmsg
method, in order to be able to explicitly specify the recipient of
the message; as needed in connection-less mode.
2019-10-30 18:44:55 +01:00
Christian Kellner
1c5b97afbc load_fds: use frombytes instead of fromstring
Python 3.2 renamed array.fromstring to array.frombytes, but kept
the former as an, now deprecated, alias. Use the canonical form
which indeed better describes what is going on.
2019-10-30 18:44:55 +01:00
Martin Sehnoutka
27cf84edd5 bind osbuild module from dynamically discovered path 2019-10-21 15:20:31 +02:00
Martin Sehnoutka
831459e9e9 fix execv /usr/lib/osbuild/osbuild-run does not exist
In case osbuild is invoked without libdir parameter, the osbuild files
are not propagated into the buildroot container and therefore all
pipelines containing buildroot fail.

Example:
```
$ sudo osbuild --store /var/osbuild/ qcow2-pipeline.json
...
execv(/usr/lib/osbuild/osbuild-run) failed: No such file or directory
```

Unfortunately this is only the first error. Once you fix it, you realize
that also the symlink from "assemblers" directory is missing and
therefore you cannot import osbuild because it is not available anywhere
in the path. This is why I had to bind the osbuild module from host to
the build container.
2019-10-21 15:20:31 +02:00
Ondřej Budai
ce6f77cbdc stages: add org.osbuild.chrony stage
lorax-composer supports modifying timeservers, this stage implements it.

I was concerned if I should name this stage timeservers or chrony, but
I've decided to go with chrony. If some day in future Fedora/RHEL
changes the ntp client, we can easily introduce new stage named after
the new ntp client. Additionally, this solution enables us to create
systemd-timesyncd stage, which can change timeservers when chrony is not
installed (in that case systemd-timesyncd takes over the ntp
synchronization).
2019-10-19 18:38:17 +02:00
Ondřej Budai
21d91fd6df stages: add org.osbuild.groups stage
lorax-composer supports adding groups, therefore we need it as well.
2019-10-17 16:14:20 +01:00
Ondřej Budai
d0a3f99342 stages/users: set authorized_keys file permissions to 600
Otherwise user may be unable to login. More information:
https://stackoverflow.com/questions/6377009/adding-public-key-to-ssh-authorized-keys-does-not-log-me-in-automatically
2019-10-17 16:11:01 +01:00
Ondřej Budai
dff8d6591b tests: fix ResourceWarning: unclosed file when running osbuild
We don't close osbuild's stdin when no input is given. Don't open stdin
at all when no input is specified.
2019-10-17 16:07:03 +01:00
Tom Gundersen
2457635bac assemblers/qemu: simplify mkfs
Rather than relying on the offset parameter, simply run mkfs on the
loopback device which is anyway being set up. This also allows us
not to specify the size explicitly.

Before this patch mkfs would complain (uneccesarily) about the
backing file containing a partition table. This is a false positive
as the partition table is in the region of the file before the
passed offset.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-16 13:44:01 +02:00
Lars Karlitski
26d29b646b stages/rpm: whitelist checksum algorithms 2019-10-15 22:53:53 +01:00
msehnout
bd02c4d8a4 Update packit.yaml for f31
ssia
2019-10-15 14:04:57 +02:00
Lars Karlitski
2b872bbbfb stages: add org.osbuild.rpm
A new stage that downloads a list of packages and installs them using
`rpm`.
2019-10-15 00:00:13 +02:00
Tom Gundersen
06bc4996a2 test/assembler: verify the bootloader
Verify the level 1 and level 1.5 GRUB2 bootloaders are as expected.

Fixes #134.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-13 12:08:08 +02:00
Tom Gundersen
ea4a6d135e assembler/qemu/grub: don't search for the root partition
We know the root partition we want, as we are setting it up. There
is no need to search for it by filesystem UUID. This simplifies the
setup and means the level 1.5 bootloader is always the same, and
not dependent on an embedded UUID.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-13 12:08:08 +02:00
Tom Gundersen
d15bbaa05d test: remove redundant tests and Vagrant integration
The tests from the integration_tests directory, were superseded
by the new stage tests.

The Vagrant integration seems not to have been working since
ea68bb0c26, as a test-setup.py was
dropped there, which it relies on. Remove it for now. If we want
that back, we should consider that in a separate PR.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-13 12:08:08 +02:00
Tom Gundersen
21df63ba31 stages/dnf: embed the gpgkey in the pipeline
Downloading the gpg key is fragile and kept causing our tests to fail.
In general, we want to limit the network access, so let's just embed
the gpg keys directly in the pipeline.

Fixes #133.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-12 14:59:01 +02:00
Lars Karlitski
8d62bed7e4 test: give osbuild time to clean up on SIGINT
When the test runner receives SIGINT, osbuild's mounts stay around.
osbuild handles SIGING correctly, but it doesn't have time before being
killed because it's parent went away.

Fix this by waiting on it explicitly in the test runner.

Fixes #119
2019-10-11 18:02:04 +02:00
Lars Karlitski
3e00117d35 test: prefix temporary directory with osbuild-test-
This makes it easier to spot which process temporary files are coming
from.
2019-10-11 18:02:04 +02:00
Lars Karlitski
1b9305b024 travis: make unittest more verbose
This prints the name of each test before running it, which might help
with travis' limit of stopping a test when it takes longer than 10
minutes.
2019-10-10 18:08:58 +02:00
Lars Karlitski
2819d07296 test: test qemu assembler
Similar to the existing test, but uses qemu-nbd to mount the generated
image.

Using unittest.TestCase.subTest() for now, which means that the tests
aren't very independent. I think this is fine in this case, because
we're testing images independently from each other, reusing the base
tree in the store.
2019-10-10 18:08:58 +02:00
Lars Karlitski
eab8cbff5e assemblers/qemu: don't try to compress raw or vdi formats
qemu-img convert fails when passing `-c` to vdi or raw outputs.
2019-10-10 18:08:58 +02:00
Ondřej Budai
2be0530047 tests: Use one store per class instead of per test method
For stages testing it is too slow to rebuild the a image containing
@Core packages every time. Let's just reuse the a image for all tests.
This should speed up the test running time a LOT.
2019-10-08 21:39:35 +02:00
Ondřej Budai
85ebb084b5 tests: introduce stage testing
The stage testing is based on an output from the tree-diff tool. During
one test two pipelines are run and their outputs are compared using
tree-diff. The diff is then compared with expected diff included in
the repository.
2019-10-08 21:39:35 +02:00
Ondřej Budai
5edac4ee58 tools/tree-diff: strip NULL character from selinux xattr 2019-10-08 21:39:35 +02:00
Ondřej Budai
fd2a20d247 tools/tree-diff: Use hash for content diffs
We need to know the exact difference of modified files in both trees.
Outputting the whole files into a diff might make a huge diff file,
therefore only their hashes are written.
2019-10-08 21:39:35 +02:00
Ondřej Budai
9fd9270c53 tools/tree-diff: List all dirs and files inside added/deleted dirs
In my opinion it is better to dump everything and then filter out
unneeded entries elsewhere.
2019-10-08 21:39:35 +02:00
Martin Sehnoutka
0862722b03 Introduce cloud-base sample
It is similar to the official Fedora cloud base image except for few
minor differences. The reason for this divergence is that we don't want
to include all hacks that are currently present in the official
kickstart file. You can see it here as a reference:
https://pagure.io/fedora-kickstarts/blob/master/f/fedora-cloud-base.ks#_149
2019-10-07 21:25:18 +02:00
Ondřej Budai
e12f55aa21 tests: print stdout from osbuild when it fails 2019-10-07 10:10:51 +02:00
Lars Karlitski
9fbe80722b assemblers: add org.osbuild.rawfs
This assembler outputs an image file which only contains the file
system.
2019-10-07 10:10:51 +02:00
Lars Karlitski
7375e4f5dd tree-diff: change shebang to respect $PATH 2019-10-07 10:10:51 +02:00
Lars Karlitski
cb2f383601 remoteloop: make LoopClient.device a context manager 2019-10-07 10:10:51 +02:00
Lars Karlitski
0dd60b3abf remoteloop: pass filename to create_device
This makes LoopClient simpler to use in the common case.
2019-10-07 10:10:51 +02:00
Lars Karlitski
356f62058f remoteloop: remove dir_fd argument in create_device
If dir_fd wasn't passed, create_device() openend it to `/dev` and forgot
about closing it. To fix this, it would have to gain logic to only close
the fd if it wasn't passed in.

Side-step the problem by removing dir_fd, since nothing is using it
right now. We can add it back if something needs it.
2019-10-07 10:10:51 +02:00
Lars Karlitski
3d3ffda5d8 remoteloop: don't close a socket it didn't open
Closing the socket is the responsibility of whoever opened it.

Fix this in the only user (qemu assembler) by using socket() in a `with`
block, which closes the socket on exit.
2019-10-07 10:10:51 +02:00
Lars Karlitski
c1dca86505 samples: remove base-from-yum.json
build-from-yum.json is the one that's being used for testing on Ubuntu.
Remove base-from-yum.json, because it's confusing to have two similarly
named pipelines like this.
2019-10-07 00:17:43 +02:00
Lars Karlitski
ff56cb7f6a test: introduce OSBUILD_TEST_STORE
The testosbuild.TestCase class creates a fresh store for each test,
because tests should run independent of each other.

This can lead to long waiting times while developing a new test case.

Allow overriding the store used with OSBUILD_TEST_STORE. This should
never be used where tests are actually run. It is a development-only
feature.
2019-10-07 00:06:23 +02:00
Martin Sehnoutka
23edc18bed sum up the procedure necessary for releasing new version 2019-10-04 22:27:06 +02:00
Lars Karlitski
434a01602b 3 2019-10-04 11:13:21 +02:00
Martin Sehnoutka
cd49e2407c replace _libdir with _prefix/lib
_libdir is platform dependant, but that is not what we want because we
would need additional runtime logic to handle platforms. this patch
overrides the defautl location
2019-10-03 15:35:50 +02:00
Ondřej Budai
f9b2da9ad3 osbuild: print tree id and output id also in non-json mode 2019-10-03 14:50:29 +02:00
Lars Karlitski
3e57f13380 stages/dnf: exclude-packages → exclude_packages 2019-10-03 12:53:01 +02:00
Tom Gundersen
72c3157162 assemblers/qemu: replace grub2-install
Background:

grub2 works in three stages:
 - The first stage is found in the first 440 bytes of the master
   boot record, and its only purpose is to load and execute the
   second stage. This stage is static, and just copied from the rpm
   without modification.
 - The second stage is found in the gap between the MBR and the
   first partition, and may be up to 31kB in size. This stage is
   specific to the host and must contain the instructions for
   finding the right file system and subdirectory for the grub2
   config and modules on the host, as well as the modules needed
   to do this.
 - The third stage is found in the `normal` module, which loads
   grub2.conf, which in turn may load more modules and perform
   arbitrary instructions.

Problem:

grub2-install is responsible for installing all these stages on the
target image. This goes against our design, as modifications outside
the filesystem should happen in the assembler, but modifications to
the filesystem should happen in a stage. In particular, we don't
want the contents of the image to differ in any way from the output
tree that is stored in our content store (the output of our last
stage). This causes a practical problem at the moment, as our
selinux stage is ran before the assembler, and as such the grub
modules do not get selinux labels applied.

It turns out that we could split grub2-install in two as we want,
by passing `--no-bootsector` to it to install only the modules,
and copy/genereta the two first stages as files under /boot and
then run `grub2-bios-setup` to write the stages from /boot into
the image where they belong.

Regrettably, this does not work as both `grub2-install` and
`grub2-bios-setup` introspect the system and block devices they
are being run on to generate the right configuration. This is not
what we want, as we would like to specifcy the config explicitly
and run them independently of the target image. The specific bug
we get in both cases is that the canonical path containing our
object store cannot be found.

Before osbuild this was not a problem, as other installers would
instal and assemble everything directly in the target image as a
loopback device. Something we explicitly do not want to do.

Solution:

This patch essentially reimplements grub2-install, or rather the
parts of it that we need. One change in behavior from the upstream
tool is that we no longer write the level one and level two boot
loaders to /boot before moving them into place, but just write them
directly where they belong (so they do not end up on the
filesystem).

The parts that copy files into /boot are now in the grub2 installer
and the parts that write the level one/two bootloaders are in the
qemu assembler.

This achieves a few principles I think we should always adher to:
 - never run tools from the target image (no chroot)
 - don't read/copy files from the target image that was written
   by other stages. We already try to avoid sharing state, and
   by treating the image as write-only, we avoid accidentally
   sharing state through the target tree.

Based-on-suggestions-from: Javier Martinez Canillas <javierm@redhat.com>
With-god-like-debugging-and-fixes-by: Lars Karlitski <lubreni@redhat.com>
Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-02 15:10:37 +02:00