Commit graph

829 commits

Author SHA1 Message Date
Christian Kellner
e610fa9659 objectstore: use private bind mounts for get()
Use `--make-private` for the bind mount in `ObjectStore.get`.
2020-02-28 16:11:49 +01:00
Christian Kellner
9b61f50792 objectstore: make Object.open a private method
Analogous to `_path`, it is not possible to identify the intended
mode of the i/o operation from using `open` (whether it is a read
or a write operation) and thus make it an internal method and only
use it for read operations.
2020-02-28 16:11:49 +01:00
Christian Kellner
3258bb62d4 objectstore: make Object.path a private property
Since it is hard to infer the intended modus of the i/o operation,
i.e. whether it is going to be a read or a write from accessing the
`path` property make it an internal method. Do not initialize the
method on property access but return the writable tree, if Object
is initialized, the path to its base tree otherwise.
Adapt all the usage internally: Use `path` for read operations and
initialize the object and then directly use `_tree` for write ops.
2020-02-28 16:11:49 +01:00
Christian Kellner
0ef5de3c94 objectstore: Object stores it base id not path
Instead of storing the base path, store the object id of its base
and resolve it to the path via the ObjectStore whenever needed.
2020-02-28 16:11:49 +01:00
Christian Kellner
6a2a7d99f7 objectstore: unify commit and snapshot code paths
As a result of the previous commits that implement copy on write
semantics, `commit` can now be used to create snapshots. Whenever
an Object is committed, its tree is moved to the store and it is
being reset, i.e. a new clean workdir is created and the old one
discarded. The moved tree is then set as the base of the reset
Object. On the next call to `write` the moved tree will be copied
over and forms the basis of the Object again. Should nobody want
to write to Object after the snapshot, i.e. the `commit`, no copy
will be made.
NB: snapshots/commits will act now act as synchronization points:
if a object with the same treesum, i.e. the very same content
already exists, the move (i.e. `store_tree`) will gracefully fail
and the existing content will be set as the base for Object.
2020-02-28 16:11:49 +01:00
Christian Kellner
39213b7f44 objectstore: copy on write semantics for Object
Since Object knows its base now, the initialization of the tree
with the content of its base can be delayed until the moment
someone wants to actually modify the tree, thus implementing
copy on write semantics. For this a new `write` method is added
that will initialize the base and return the writable tree. It
should be used instead of `path` whenever the a client wants to
write to the tree of the Object.
Adapt the pipeline and the tests to use the new `write` method
in all the appropriate places.
NB: since the intention can not be inferred when using `path`
directly, the Object is still being initialized there.
2020-02-28 16:11:49 +01:00
Christian Kellner
0874b80734 objectstore: Object knows its base
When a new Object is created it can have a `base`, i.e. another
object that is already committed to the store, which is then used
to initialize the tree of the new object. That is, the contents
of the new Object will be based on the contents of the existing.
The initialization of an Object with its base (if any) was done
by the ObjectStore. Move all of that logic inside `Object`:
The Object will store its base, which `Object.init` will use to
initialize itself. Additionally, if `Object.path` is accessed
`init` is being called as well to make sure it is properly
initialized, i.e. the tree initialized with the base content.
2020-02-28 16:11:49 +01:00
Christian Kellner
25b3807a5b objectstore: snapshot takes Object not path
Refactor the `ObjectStore.snapshot` method to take an `Object` not
a plain filesystem tree, so the latter is more encapsulated from
the ObjectStore user (e.g. the pipeline) and prepares a unified
code-path for `snapshot` and `commit` in the future.
2020-02-28 16:11:49 +01:00
Christian Kellner
5deb1be514 objectstore: change Object.move to .store_tree
Now that Object manages its work directory itself, re-create the
latter when the its tree is moved, i.e. when the object is being
committed to the store. This means that after the object has been
written to the store it is in the same state is if it was new and
can be used in the very same way.
If the move itself fails (the rename(2) fails), the tree and its
contents is cleaned up with the reset of the work directory.
Rename the `move` method to `store_tree` to better reflect how the
method should be used, i.e. to store the tree corresponding to the
Object instance.
2020-02-28 16:11:49 +01:00
Christian Kellner
6d14dee9a2 objectstore: object manages its work dir
When a new object is being created, a corresponding temporary
directory is created within the file system tree of the object
store, which shall be called the "work dir". Within that dir a
well-known directory ('tree') is created that then is the root
of the filesystem tree[1] that clients use to store the tree
or the resulting image in.
Previously, the work dir was managed, i.e. created and cleaned
up (via a context manager) by the ObjectStore. Now the Object
itself manages the tree and thus the lifetime of the work dir
is more directly integrated and controlled by it. As a result
the Object itself is now a context manager. On exit of the
context the work dir is cleaned up.

[1] For the assembler this is the output directory that will
    contain the final image.
2020-02-28 16:11:49 +01:00
Christian Kellner
399606528c objectstore: helper to create temp dirs inside the store
Create a small helper method that creates a new temporary directory
of type tempfile.TemporaryDirectory within the store and returns it.
2020-02-28 16:11:49 +01:00
Christian Kellner
d10537da42 objectstore: yield Object not path from .new()
Instead of just returning the path of the temporary object that is
created in .new() the actual instance of the new `Object` is being
returned, which can then provide a richer interface for clients
than a plain directory path.
2020-02-28 16:11:49 +01:00
Christian Kellner
52736169f1 objectstore: Object keeps reference to store
Keep are reference to the parent store, which this object is tied
to. It is currently not yet used directly but is a preparation for
a closer Object and ObjectStore integration that will happen in
commits to follow.
2020-02-28 16:11:49 +01:00
Christian Kellner
19f49e5dc3 objectstore: rename TreeObject to Object
As the name implies, the ObjectStore stores objects, which can be
trees but also everything an Assembler can make of the input tree,
like qcow2 images, tarballs and other non tree-like outputs.
Therefore rename the TreeObject to Object to better reflect that it
is representing any object, not only trees, in the store.
2020-02-28 16:11:49 +01:00
Christian Kellner
3b7c87d563 objectstore: helper to resolve references to paths
Introduce a small helper function to resolve object_id references
into their paths inside the object store and use that throughout
the store.
2020-02-28 16:11:49 +01:00
Lars Karlitski
294431ace1 test: add test for host detection
Includes a test for each of the runners we currently have, except for
fedora27, which is (hopefully) not used as a host OS anymore.
2020-02-28 16:06:30 +01:00
Lars Karlitski
a578a2b7e7 pipeline: detect host instead of using org.osbuild.host
Detect the host dynamically from os-release(5) instead of relying on the
`org.osbuild.host` symlink.

It is awkward to install a symlink that tells osbuild which distro is is
running on, when there is a standard way to detect this.

This makes it easier to run osbuild from sources and removes the need to
include every host in the spec file. The latter became hard to do,
because there's no obvious way to distinguish RHEL minor releases.
2020-02-28 16:06:30 +01:00
Jacob Kozol
c5b31ff2ac runners: add rhel 8.1 runner
The rhel 8.1 runner is based off of the rhel 8.2 runner with the only
difference being the etc/os-release content.
2020-02-28 16:05:35 +01:00
Major Hayden
7d53835bba 🤦‍♂️ Restore the Fedora modularity workaround
Signed-off-by: Major Hayden <major@redhat.com>
2020-02-27 20:19:51 +01:00
Major Hayden
4b2089bbf6 🌮 Merge GitHub Actions workflows
A single workflow allows us to re-use artifacts throughout all jobs.

Also, we can fail the tests early if there's a linting issue before
we spend time waiting for RPMs to build.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-27 19:59:03 +01:00
Major Hayden
4ad4587683 📦 Disable Fedora modular repos
Avoid delays and problems with the modularity repositories
by disabling them before building RPMs.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-27 19:51:48 +01:00
Major Hayden
cd4c6944c6 🧨 Run all RPM builds even if one fails
By default, GitHub Actions stops running all RPM builds if one fails.
This means that a temporary repository issue (like what is happening
with F32 today) stops all RPM builds.

Set the `fail-fast` option to `false` to disable this behavior.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-27 19:25:29 +01:00
Major Hayden
7b8f70fc5b Allow osbuild to run on rawhide (f33)
Add an additional symlink and spec update for Fedora Rawhide,
which is currently set as release 33.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-26 15:25:47 +01:00
Major Hayden
31a8eb8d93 Remove unit tests from Travis CI job
The unit tests are no longer needed in the Travis CI job since we are running
them with GitHub Actions.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-25 20:16:49 +01:00
Major Hayden
4c92b7a28b Run unit tests in GitHub Actions
Rename `lint.yml` to `tests.yml` to allow us to put more jobs under the
same test name.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-25 20:16:49 +01:00
Tom Gundersen
9d0f6bd85e github: build RPMs without git checkout
Make RPM building more similar to how RPMs will be built in koji.

This downloads the specfile from github at the given commit, appends
the commit sha to the specfile and uses spectools to download the
correct sources from github.

This should be equivalent to what is done in the makefile, the only
behavioral difference is that the rpms are now versioned based on
the git sha they are built from.

The main purpose of this change is to avoid any differences between
the CI and the real RPMs due to bugs in the Makefile. Correctly
versioned RPMs will also be handy for testing/debugging/deployment.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-25 16:13:31 +01:00
Tom Gundersen
d24d594173 test/sources/files: use baseurl
The chosen mirror was flakey, causing CI to fail. Move to using the baseurl.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-25 15:04:09 +01:00
Major Hayden
d0b50db067 Remove pylint from Travis CI job
The pylint test is now run within GitHub Actions, so the Travis CI
pylint job is no longer needed.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-24 23:10:16 +01:00
Major Hayden
f2c9276765 Run pylint via GitHub Actions
Get pylint results much easier by using GitHub Actions.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-24 23:10:16 +01:00
Major Hayden
461348b652 Remove redundant RPM build from Travis CI
Now that RPMs are built natively in Fedora containers via GitHub
Actions, we no longer need to build them in Travis CI.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-24 20:02:30 +01:00
Major Hayden
cdc84a9ce2 Build RPMs via GitHub Actions
Signed-off-by: Major Hayden <major@redhat.com>
2020-02-24 20:02:30 +01:00
Major Hayden
a1f4bb1459 Bump setup.py to version 8
Signed-off-by: Major Hayden <major@redhat.com>
2020-02-24 20:02:30 +01:00
Tom Gundersen
e9cb75891e 8
Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-24 12:47:07 +01:00
Tom Gundersen
31f3533886 spec: use forgemeta
This changes the name of the source tarball, but apart from that has
no effect as-is.

However, if the `commit` global is set, then the source tarball is
expected to be the standard git-archive at that commit, and the
release field is set to contain the date and the git sha. This is
useful for when we want to build rpms between releases.

This works analogously to how osbulid-composer currently works.

See <https://fedoraproject.org/wiki/Forge-hosted_projects_packaging_automation>
for details.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-24 12:17:54 +01:00
Ondřej Budai
bd6e6bde56 ci: run the rpm build tests in Fedora containers
Building rpm directly on Ubuntu is somewhat possible but it's fragile and
it cannot cover all quirks of rpm build. This commit switches the rpm build
tests to using fedora containers. This isn't also the best solution but
imho it's much better than the previous one.
2020-02-22 10:31:44 +01:00
Major Hayden
ddb652ecc7 dnf: enable fastestmirror by default
Enabling the fastestmirror plugin allows dnf to choose the fastest
(also usually the closest) mirror to the instance of osbuild. It
has no effect on builds that force the use of a specific server
or mirror.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-22 02:01:17 +01:00
Tom Gundersen
e48c2f178c osbuild: allow the sources to be passed in on stdin
Currently stdin is taken to be the pipeline to be built, this allows
it to be instead a map containing the suorces and the pipeline.
We would imagine passing around the sources and pipeline together, so
this just makes the behavior of osbuild more closely match the intended
use and semantics of the sources configuration.

This keeps backwards compatibility for now, but that may be dropped as
soon as osbuild-composer no longer relies on the old behavior.

Disable too-many-{branches,statements} pylint warnings in __main__.py.
These do not seem helpful, but could be reenabled if we drop some
options in the future.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-19 15:59:11 +01:00
Tom Gundersen
481213a8dd pipeline: pin the sources options in the pipeline object
Make the sources options a static property of the pipeline, in
particular of each stage, rather than being passed in on `run()`.

This more closely matches the intended semantics of sources and
pipeline having similar lifetimes and being fairly coupled together.

The difference between the pipeline and the sources is that the
sources do not contribute to identifying the pipeline (they are not
part of the hash for the pipeline id), and they could be swapped
out without changing the output image (as long as they are valid).
However, a pipeline without A sources object would not be useful,
and typically the pipeline and the sources are generated, passed
around and used together.

This is different from the build environment and the secrets object,
which both are specific to either the host or the caller, unlike
the pipeline which should be universal.

This changes the `load()` function to take a `manifest`, which is
a map containing both the pipeline and the sources.

Note that the semantics of the build-env parameter remains unchanged:
It shares the sources with the rest of the pipeline. We may want to
reconsider this in future commits, as the build-env is specific to
the host, whereas the regular pipeline is not.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-19 15:59:11 +01:00
Major Hayden
961322d959 Remove unused GitLab CI configuration
We're not using the GitLab CI integration yet and we will need to
rethink how to implement it anyway.

Signed-off-by: Major Hayden <major@redhat.com>
2020-02-19 15:12:52 +01:00
Tom Gundersen
be663bd3d5 stages/rpm: be a bit more verbose to give some progress indication
The dnf stage was very verbose, probably overly so. Rather than
benig completely silent, let's print basic progress indication
so we have some idea what's going on.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-06 19:01:12 +01:00
Tom Gundersen
16dfd7eec1 remoteloop: drop O_DIRECT
Appart from giving us a hard time on s390x, this feature did not seem
to have a measurable effect. Moreover, O_DIRECT is not supported by
tmpfs so without this patch we could not use tmpfs as backing store,
which does speed up image generation considerably.

Drop the flag and and rather put the store on tmpfs in order to speed
things up.
2020-02-06 19:01:12 +01:00
Tom Gundersen
1d588b8e86 stages/rpm: adapt to use the files source
Drop the rpm downloading and instead use the files source. This gives
us caching for free, and is the last missing step before we can
deprecate the dnf stage.

The main benefit of the rpm over the dnf stage is that we pin the package
versions rather than the repo metadata version. This will allow us to
support continuously changing repositories as individual packages are much
less likely to change than the repos iteself, and old packages are meant
to stay around for some time, unlike the repo metadata which is instantly
swapped out.

Depsolving is also slow on the first run, which we were always hitting as
the depsolving was always happening in a fresh container.

Based on a patch by Lars Karlitski.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-06 19:01:12 +01:00
Tom Gundersen
be0ff68411 fixup: files 2020-02-06 19:01:12 +01:00
Tom Gundersen
7817ae5e8b sources: add org.osbuild.files source
This source adds support for downloaded files. The files are
indexed by their content hash, and the only option is their URL.

The main usecase for this will be downloading rpms. Allowing depsolving
to be done outside of osbuild, network access to be restricted and
downloaded rpms to be reused between runs.

Each source is now passed two additional arguments, a cache directory
and an output directory. Both are in the source's namespace, and
the source is responsible for managing them. Each directory may
contain contents from previous runs, but neither is ever guaranteed
to do so.

Downloaded contents may be saved to the cache and resued between
runs, and the requested content should be written to the output dir.
If secrets are used, the source must only ever write contents to
the output that corresponds to the available secrets (rather than
contents from the cache from previous runs).

Each stage is passed an additional argument, a sources directory.
The directory is read-only, and contains a subdirectory named after
each used source, which will contain the requseted contents when
the `Get()` call returns (if the source uses this functionality).

Based on a patch by Lars Karlitski.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-06 19:01:12 +01:00
Tom Gundersen
794ec97bf3 api: add barriers
Ensure that the api sockets are created before entering the with clause.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-06 19:01:12 +01:00
Christian Kellner
5a61d8c869 objectstore: extract method to open a TreeObject
Extract the opening a TreeObject out of the treesum property so
that the latter is easier to read.
2020-02-06 16:10:35 +01:00
Christian Kellner
6f4d286ff4 osbuild: support for checkpoints during build
Add a new `--checkpoint` option, which can be provided multiple
times, that indicate after which stages a the current stage of
the tree should be committed to the object store; the tree id
will be the treesum of the tree at that point and a reference
is created with the id of the stage at the point.
The argument to `--checkpoint` is the id of the stage. If not
all the given checkpoints can be found the execution will be
aborted.
2020-02-06 16:10:35 +01:00
Christian Kellner
8d98696f47 tests: check duplicate objects are supported
Check that creating two trees with the exact same content, i.e.
exact same treesum only lead to exactly one object and two
references.
2020-02-06 16:10:35 +01:00
Christian Kellner
4fe69b756f tests: check basic properties of objectstore
Check the very basic operations of the object store, i.e. creating
multiple trees with different object_ids works and results in the
correct number of objects and references.
2020-02-06 16:10:35 +01:00
Christian Kellner
1cf0e944c9 tests: new object store unit test
Basic functional checks, including the new snapshot support.
2020-02-06 16:10:35 +01:00