Commit graph

897 commits

Author SHA1 Message Date
Christian Kellner
0aa44c23bb objectstore: use types.PathLike
Use the new `types.PathLike`, which is exactly the type that this
module defined too.
2020-07-27 12:50:38 +01:00
Christian Kellner
2fd83ac90d util: add types module defining PathLike type
Add a simple new module meant to define types that are commonly
used throughout the code-base. For starters, define `PathLike`
meant to represent file system paths, i.e. strings, bytes, or
anything that provides the `os.PathLike` protocol, i.e. that
can be used with `os.fspath`.
2020-07-27 12:50:38 +01:00
Christian Kellner
21a60324bc buildroot: bind mount individual API endpoints
The current way API end points, i.e. sockets for API providers,
are provided to the sandbox is via a temporary directory that
is created by `BuildRoot` which later gets bind-mounted to a well
known path, i.e. /run/osbuild/api inside the sandbox. API providers
are expected to create their socket in that temporary directory.

Now that `BuildRoot` has a `regsiter_api` method and each API has
an `endpoint` property, the socket of each API provider, no matter
where it is located, will get bind-mounted individually inside
the sandbox at /run/osbuild/api using the `endpoint` identifier.

For backwards compatibility reasons the temporary api directory
will still be created by `BuildRoot`, but it is no longer bind
mounted inside the container. This paves the way to remove that
directory completely once all API providers are converted to not
use that directory anymore.
2020-07-27 12:50:38 +01:00
Christian Kellner
bc81e68727 api: each API defines its 'endpoint' name
Add a new abstract class property to `BaseAPI` called `endpoint`,
meant to be implemented by deriving classes in order to identify
the end point name for the API provider.
Implement the new property in all existing API providers.
2020-07-27 12:50:38 +01:00
Christian Kellner
144019a40c pipeline: use buildroot.regsiter_api
Register all API end point providers with the `BuildRoot` via the
new `BuildRoot.register_api` call. The context management is now
done via the `BuildRoot` itself.
2020-07-27 12:50:38 +01:00
Christian Kellner
03c5cfb37e buildroot: ability to register api endpoints
Add a new `register_api` method that is meant to be used by clients
to register API end point providers, i.e. instances of `api.BaseAPI`.
When the context of the `BuildRoot` is enter, all providers are
activated, i.e. their context is entered. In case `regsiter_api` is
called with an already active context, the provider will immediately
be activated. In both cases their lifetime is thus bound to the
context of the `BuildRoot`. This also means that they are cleaned-up
with the `BuildRoot`, i.e. when its context is exited.
2020-07-27 12:50:38 +01:00
Christian Kellner
38e714f229 test/monitor: use osbuild.api.setup_stdio
Use the new `api.setup_stdio` instead of providing an exact copy
of that in the test code.
2020-07-27 12:50:38 +01:00
Christian Kellner
71adfced70 runners: use osbuild.api.setup_stdio
Each runner used the exact same copy of `setup_stdio`, which is
now provided by `api.setup_stdio`. Use that and remove the code
duplication.
2020-07-27 12:50:38 +01:00
Christian Kellner
58e9211d71 api: implement canonical setup_stdio method
The `api.API` provides a `setup-stdio` method, that is meant to
be used by clients to replace their stdio with the supplied fds
from the server. Provide a canonical `api.setup_stdio` method
that will do exactly that.
2020-07-27 12:50:38 +01:00
Christian Kellner
9edc2b0362 remoteloop: port LoopServer to use BaseAPI
Now that `api.BaseAPI` provides the basic scaffolding for API
servers, use that base class and remove the code duplication.
2020-07-27 12:50:38 +01:00
Christian Kellner
3ae056bf0f sources: port to use api.BaseAPI
Now that `api.BaseAPI` provides the basic scaffolding for API
servers, use that base class and remove the code duplication.
2020-07-27 12:50:38 +01:00
Christian Kellner
b86b6a4bf8 test/api: add checks for the api infrastructure
Add a check for `api.BaseAPI` by implementing a test API and test
that receiving messages and dispatching them works as planned.
2020-07-27 12:50:38 +01:00
Christian Kellner
1ce517e595 api: extract base class
Split out the part of `api.API` that is responsible for providing
the server infrastructure for the API; i.e. setting up the server
and the corresponding context manager and asynchronous event
handling. This leaves `API` itself which just the implementation
of the high level protocol and makes the API-server part re-usable.

NB: pylint, for some reason, confuses `API` and `BaseAPI`, like in
`test_monitor`. Annotate that accordingly.
2020-07-27 12:50:38 +01:00
Tom Gundersen
2423bf12f0 stages: drop script stage
The `script` and `test` stages should not be used in produciton, and
their use should be discouraged in general. They may make sense for
debugging, but should not be shipped.

The test stage is still used by the boot tests, so leave that for now,
and only drop the scripts stage.

Signed-off-by: Tom Gundersen <teg@jlkm.no>
2020-07-24 18:06:39 +02:00
Christian Kellner
5142046396 test/osbuild: add run tests for stages, assembler
Create small test cases that check the execution of Stages and
Assembler. This ensure that path handling, the sandbox, as well
as basic result reporting works as expected.
2020-07-22 09:37:30 +01:00
Christian Kellner
38f282e3ce pipeline: proper path handling for sources cache
Use `os.path.join` to build the path for the source cache, instead
of string interpolation. This makes it possible to use other Path
representations, like `pathlib.Path`, transparently.
2020-07-22 09:37:30 +01:00
Christian Kellner
ec531ee9ed test/osbuild: fix whitespace
Fix indent of pipeline definition.
2020-07-22 09:37:30 +01:00
Christian Kellner
276019530c pipeline: support for trees being os.PathLike
Currently `objectstore.Object.{read, write}` directly return
strings but in the future they might return an Object that is
an `os.PathLike`, i.e. has a `__fspath__` method, instead.
Prepare for that by ensuring all `tree`s are converted to their
file system representation via `os.fspath` when needed, e.g.
when creating the bind-mount arguments for the `BuildRoot`.
2020-07-22 09:37:30 +01:00
Christian Kellner
80e96c8494 test/objectstore: proper path concatenation
Instead of using string interpolation and concatenation to build
file system paths, use `os.path.join` or directly the constructor
for `pathlib.Path`, which can take path segments.
2020-07-22 09:37:30 +01:00
Christian Kellner
6813fa4acc objectstore: proper path handling for ObjectStore
Instead of using string interpolation, use `os.path.join` in all
places. This should allow the use of `os.PathLike` objects as well
as bytes (i.e. `objectstore.PathLike` types) to be used and is
generally cleaner.
2020-07-22 09:37:30 +01:00
Christian Kellner
833a79ee6f objectstore: support os.PathLike in Object.export
Support `os.PathLike` arguments in `Object.export` by explicitly
converting the supplied argument via `os.fspath`. Additionally,
declare the support for those via the Python typing system with
a new Union type for general `PathLike` type, i.e. all valid
types for `os.fspath`, which are `str`, `bytes`, `os.PathLike`.
2020-07-22 09:37:30 +01:00
Christian Kellner
8250bd0b94 objectstore: re-use Object.export in Object.init
Instead of having a duplication of the invocation of `cp`, once in
`init`, once in `export`, re-use the latter in the former: the to
be copied object is accessed in the normal way via the store, and
then "exported" to the new location. This gets rid of the call to
resolve_ref as a nice side effect, which means less poking into
the internals of the store.
2020-07-22 09:37:30 +01:00
David Rheinsberg
d1b9304a56 buildroot: use bwrap to contain stages
This swaps the `systemd-nspawn` implementation for `bubblewrap` to
contain sub-processes. It also adjusts the `BuildRoot` implementation
to reduce the number of mounts required to keep locally.

This has the following advantages:

  * We know exactly how the build-root looks like. Only the bits and
    pieces we select will end up in the build-root. We can let RPM
    authors know what environment their post-install scripts need to
    run in, and we can reliably test this.

  * We no longer need any D-Bus access or access to other PID1
    facilities. Bubblewrap allows us to execute from any environment,
    including containers and sandboxes.

  * Bubblewrap setup is significantly faster than nspawn. This is a
    minor point though, since nspawn is still fast enough compared to
    the operations we perform in the container.

  * Bubblewrap does not require root.

At the same time, we have a bunch of downsides which might increase the
workload in the future:

  * We now control the build-root, which also means we have to make sure
    it works on all our supported architectures, all quirks are
    included, and all required resources are accessible from within the
    build-root.
    The good thing here is that we have lots of previous-art we can
    follow, and all the other ones just play whack-a-mole, so we can
    join that fun.

The `bubblewrap` project is used by podman and flatpak, it is packaged
for all major distributions, and looks like a stable dependency.
2020-07-21 14:20:32 +02:00
Christian Kellner
d3a97a90a5 test/monitor: check monitor functions are invoked
Create a new monitor that records all the invocations of the
monitoring (virtual) functions and use that to check that when
running (i.e. building) a pipeline all of them are executed
the excepted number of times (and with the correct arguments).
2020-07-21 13:25:04 +02:00
Christian Kellner
5d226b2e15 test: add basic checks for monitoring and API
Add a basic test that will set up an 'API' endpoint, then spawn a
child process that uses that 'API' endpoint to setup its stdio in
very much the same way as runners do. This is used to verify that
the API itself works properly as well as the new LogMonitor class
by comparing the inputs and outputs.
2020-07-21 13:25:04 +02:00
Christian Kellner
3e18d8118c api: introduce pipeline monitoring
Introduce the concept of pipeline monitoring: A new monitor class is
passed to the pipeline.run() function. The main idea is to separate
the monitoring from the code that builds pipeline. Through the build
process various methods will be called on that object, representing
the different steps and their targets during the build process. This
can be used to fully stream the output of the various stages or just
indicate the start and finish of the individual stages.

This replaces the 'interactive' argument throughout the pipeline
code. The old interactive behavior is replicated via the new
`LogMonitor` class that logs the beginning of stages/assembler,
but also streams all the output of them to stdout.
The non-interactive behavior of not reporting anything is done by
using the `NullMonitor` class, which in turn outputs nothing.
2020-07-21 13:25:04 +02:00
Christian Kellner
5d55bc9aca api: use io.StringIO as output data buffer
Instead of using plain python strings and appending to them, use
'io.StringIO' which is a data structure meant to be used for i/o.
This should increase performance compared to plain strings.
2020-07-21 13:25:04 +02:00
Christian Kellner
1e88ee62e3 api: use pipe for output
Instead of either using a text file, in non-interactive mode, or
directly stdout otherwise, create a pipe and always use that as
for stdout/stderr when preparing the output for 'setup_stdio'.
This streamlines the two cases (interactive, non-interactive) and
as a result 'API.output' will always contain the full output data.
2020-07-21 13:25:04 +02:00
Christian Kellner
4c6ca0b4a0 api: properly close the event loop
Close the event loop when the context is exited, which will clear
the internal queues and shut down the executor of the event loop.
Not doing this will create a warning when the object is garbage
collected.
2020-07-21 13:25:04 +02:00
Christian Kellner
e9c4075bb3 remoteloop: properly close the event loop
Close the event loop when the context is exited, which will clear
the internal queues and shut down the executor of the event loop.
Not doing this will create a warning when the object is garbage
collected.
2020-07-21 13:25:04 +02:00
Christian Kellner
291fadd0b2 pylint: increase max attributes to 10
In three places we have more than 7 instances attributes, but less
then 10; instead of disabling the warning for all these cases,
increase the limit to a reasonable size of 10 and re-enable the
warnings in all the places.
2020-07-21 13:25:04 +02:00
Ondřej Budai
4b290dd2a4 test: use a dummy pipeline when testing assemblers
#471 extends the assembler test suite to also test xfs and btrfs filesystems
in raw and qemu assemblers. However, this change leads to long running times
of this suite.

The running time of these test consist of 3 main steps:

1) Building the build pipeline
2) Building the stages
3) Running the assembler

There are two optimization approaches:

1) Caching
   OSBuild supports caching, therefore it's possible to cache results of first
   two steps.

2) Minimizing the operating system tree
   Assemblers don't care about the image contents. Therefore, it's possible
   to create just a small tree which would be used to test the assemblers.
   This should lead to speed up in the step 2 (smaller tree should be built
   quicker) and in step 3 (big part of assembling is just copying files over
   to the image).

This commit implements the second approach. A new test manifest is now added,
which just installs the filesystem package and its dependencies and this tree
is then labeled. This solution was chosen, so that the assemblers get
something that looks as a proper filesystem tree but also can be built pretty
quickly.

Before this change, the test_rawfs method with #471 merged ran for 842 seconds.
After this change, it ran for 391 seconds.
2020-07-21 10:25:47 +02:00
chloenayon
58bd7a204a osbuild: return if output-directory not specified
If the user does not specify an output directory or checkpoints
to osbuild, exit successfully without building.

Previously, if a user did not include an output directory or
checkpoints, it would build the manifest and throw out the result.
Returning early will be clearer to the user and avoid wasting work.
2020-07-20 19:17:30 +02:00
Major Hayden
dd6981c481 Use script for telegram notification
Jenkins' declarative pipelines have interesting requirements around when
you can use traditional groovy scripting in the pipeline and some items
in `post` require special handling.

Signed-off-by: Major Hayden <major@redhat.com>
2020-07-20 16:22:21 +02:00
Ondřej Budai
cc494ec04b schutzbot: remove enabling of rcm socket unit
The whole rcm subpackage was removed in osbuild-composer's commit fbfa191.
Unfortunately, this broke osbuild's schutzbot because it tries to start
the rcm socket.

This commit removes enabling of the not-anymore-existing socket unit.
2020-07-20 08:57:27 +02:00
Major Hayden
be2f7dc795 💣 Notify via telegram on master CI failure
We've come a long way and we need to triage failures that occur during
CI for the master branch. This will help us find problems with CI as
well as find other issues that could show up in a customer environment.

Also, let's send a happy notification when everything goes well. 💚

Signed-off-by: Major Hayden <major@redhat.com>
2020-07-17 13:56:30 -05:00
Christian Kellner
53f6c41917 osbuild: use osbuild_cli directly as main entry
Instead of having a another indirection via `main_cli`, directly
use `osbuild_cli` in as main function in `__main__.py`. Also use
that in as the entry point for the generated `osbuild` executable.
Change `osbuild_cli` to be self-contained, i.e. it directly uses
`sys.argv` and `sys.exit`.
2020-07-17 16:30:46 +01:00
Christian Kellner
7e392f819e stages/noop: fix the schema to allow any props
The documentation states that the stage accepts any options and
dumps them but the schema was not allowing any. Fix that and also
change the sample to include a random option.
2020-07-16 19:02:25 +02:00
Major Hayden
1a7f286578 ⚙ Bring over CI improvements from osbuild-composer
Signed-off-by: Major Hayden <major@redhat.com>
2020-07-14 13:05:18 +02:00
Christian Kellner
e3eccbe491 osbuild: remove ability to pass in secrets
The way secrets work has been changed via commit 372b117: instead
of passing them in via the command line, the information how to
obtain secrets are encoded along the sources themselves.
The only stage that still has support for the old style way is the
deprecated org.osbuild.dnf stage, which might be removed in the
near future.
2020-07-10 11:44:15 +02:00
Christian Kellner
9fd28c8c21 pipeline: remove extra empty line
More PEP-8. No semantic change.
2020-07-10 11:44:15 +02:00
Christian Kellner
a505a82169 ci: schedule coverity only for osbuild/osbuild
Don't schedule the run of coverity on forks of osbuild, but only
on the main repository.
2020-07-07 08:26:53 +02:00
Martin Sehnoutka
cd0db46601 samples/ppc64le: change the URL to the RPM packages
The mirror used in f30-ppc64le example did contain the RPM packages but
there were two issues
 * f32 is not in development any more
 * ppc64le is available as a secondary arch

The patch also renames the file as it contains packages for fedora 32.
2020-07-02 12:39:16 +02:00
Martin Sehnoutka
a4bdf965e3 samples/s390: Modify the URL to the RPM packages
mirrors.kernel.org does include packages for s390 but they are available
in /fedora-secondary directory.
2020-07-02 12:39:16 +02:00
Ondřej Budai
7b0db90c76 sources/files: do not pass floats to --max-time
curl uses strtod from the C standard library to convert the --max-time's value
from string to double. However, this is what strtod expects:

nonempty sequence of decimal digits optionally containing decimal-point
character (as determined by the current C locale)

Yeah, unfortunately, the decimal-point character is determined by the current
C locale. For example, Czech and German locale uses a comma as the
decimal-point character.

For reasons I don't fully understand, Python thinks it's running on en_US
locale, even though LC_NUMERIC is set to cs_CZ, so it uses a full stop as the
decimal-point character when converting float to string. However, as written
before, curl fails to parse this because it expects comma.

The fix I chose is simple: Use math.ceil, so only an integer can be passed to
curl. Why ceil? Because --max-time == 0 sounds fishy. math.ceil should return
an integer (and it does in Python 3.8) but the documentation is not 100% clear
on this topic, so let's be paranoid and also convert it to int after the
ceiling.
2020-06-25 21:25:17 +02:00
Christian Kellner
6baacf14ee stages/systemd: small whitespaces fixes
Be more PEP-8 conforming.
2020-06-24 10:05:11 +02:00
Christian Kellner
23aa98bfe6 stages/systemd: make enabled_services optional
It should be possible to use the stage to only set the default
target or disable services. There is no need to always require
having `enabled_services`.
2020-06-24 10:05:11 +02:00
Christian Kellner
7ac8f41798 stages/systemd: ability to mask services
Add the ability to mask services, which is done e.g. when building
installers. See systemctl(1) for more information about masked
services.
Modify the existing stage test to include a test for it.
2020-06-24 10:05:11 +02:00
Christian Kellner
3d13c825c0 ci: run coverity check every night
Add a github workflow that will trigger the run of coverity every
night at 05:00 UTC. Uses the new Makefile coverity targets.
2020-06-24 10:01:24 +02:00
Christian Kellner
b5cc1a6f1a test: add coverity targets to the Makefile
Add the scaffolding and various targets to run a coverity analysis,
including downloading the tool, running the "build", archiving
the results and submitting it to coverity for analysis.
The downloading and submitting need COVERITY_{EMAIL, TOKEN} to be
defined in the environment.

Co-authored-by: David Rheinsberg <david.rheinsberg@gmail.com>
2020-06-24 10:01:24 +02:00