Commit graph

551 commits

Author SHA1 Message Date
Christian Kellner
56e0ac7c92 pipeline: eagerly cleanup trees in error case
The `build_stages` method short-circuits and returns early in case
any of the stages fail to build and returns None for the tree, and
build tree, therefore both of those can immediately cleaned up at
that point.
For this add a small helper `cleanup` that will call the cleanup
method for all supplied arguments, after filtering out None values.
2020-03-22 15:30:35 +01:00
Christian Kellner
08fc223276 pipeline: delay cleanup of build tree
Delay the cleanup of the build tree of the build pipeline, and
first check the result and only cleanup the tree when the build
did not fail, because in that case both returned trees will be
None and trying to cleanup them up will result in an exception.
Therefore, also don't clean up `tree` in the error case.
2020-03-22 15:30:35 +01:00
Christian Kellner
67dfe0965e spec: include NEWS.md in docs
We have some news for the world to read, therefore include the
recently added NEWS.md file in the rpm package.
2020-03-19 11:17:31 +01:00
Christian Kellner
61420d1496 10
This completes osbuild version 10.
2020-03-18 18:41:39 +01:00
David Rheinsberg
22eeb9a095 build: extend release information and layout
This extends on our model how we do releases. It introduces `NEWS.md`
as the authoritative source of our release-notes. It is pre-populated
with the release-notes from the previous 'v9' release, and contains a
suggestion for the upcoming 'v10'.

Furthermore, this adds `make release` as a simple checklist target that
contains instructions how to create a new release. Note that it is a
passive make-target which has no side-effects at all. It only prints
release information.

With this in place, we can drop `RELEASE.md`, as all information is now
combined in `make release`.
2020-03-18 11:21:40 +01:00
David Rheinsberg
1ab282b906 docs: fix incorrect option-list formatting
The used format of `-X, --long=VALUE` is not a valid option-list entry,
even though it is very commonly used all over the linux man-pages. Use
the supported format of `-X VALUE, --long=VALUE`, which will format
correctly in the man-page and html outputs.

For reference, these formats are valid in RST option-lists:

        -a                      Short option
        -c arg                  Short option with arg.
        --long                  Long option.
        -2, --two               Aliases on a single line.
        -f FILE, --file=FILE    Aliases with arguments.
        /V                      VMS/DOS-style option.
2020-03-18 09:34:40 +01:00
Tom Gundersen
c8465ce06f sources/files: time-out curl
Add a 10s connection timeout for each file transfer. Also add an
increasing max timeout for a given file transfer (30s to 180s).

Also increase the retries to 10 and the concurrent threads to 15.

Hopefully this should make things a bit more stable in the face of
bad mirrors. We were encountering mirrors that would hang either
on connect or download at such slow speeds that they might as well
have stalled (~1kB in 45s).

Follow-up patches will provide a more long-term solution, by
allowing the same mirror selection as dnf currently uses.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-15 17:07:01 +01:00
David Rheinsberg
c73328a1fc build: drop packit configuration
We do not use PackIt, anymore. Drop the configuration. We can easily
reinstate it if we need it again.
2020-03-09 13:23:01 +01:00
David Rheinsberg
7271d0b8f7 spec: use make man and copy all man-pages
Use `make man` rather than hard-coding man-page creation in the
spec-file. Furthermore, install all man-pages, not just the base one.

The commands are adjusted to account for possibly more man-pages being
added. Tree-wide the only place to adjust for new man-pages being added
is the `%files` list in the spec-file.
2020-03-09 13:20:42 +01:00
David Rheinsberg
3e1aa25cf1 spec: make indentation consistent
We already indent the values in the spec-file to all start at the same
column. However, we use different indentation sizes for different
blocks of values. This makes it really confusing to read. Lets use a
consistent indentation and align everything with the main assignments in
the spec-file.
2020-03-09 13:20:42 +01:00
David Rheinsberg
9064788fdf ci: add job for documentation build and test
This adds another job to the CI runner. This builds and tests the
documentation. The tests are currently reduced to just verifying the
respective man-pages are actually generated. This can be extended on in
the future.
2020-03-09 13:20:42 +01:00
David Rheinsberg
bc88508487 build: improve make man
This improves `make man` in the following ways:

  * The recently added `osbuild-manifest.5` man-page is now generated
    as well.

  * The target now honors `SRCDIR` and `BUILDDIR` variables.

  * Any newly added man-page is now automatically picked up and
    generated as well.

  * The output directory structure now mirrors the input directory
    structure.
2020-03-09 13:20:42 +01:00
David Rheinsberg
d5b990bac0 build: document makefile and prepare for out-of-tree builds
This documents the structure of `Makefile` as well as its supported
targets. Furthermore, we add support for SRCDIR and BUILDDIR so we can
use this makefile to ultimately deploy generated documentation to our
website and more.

This commit does not convert all of the makefile to honor SRCDIR. It
merely sets up the infrastructure to support SRCDIR. Follow-ups will
improve the different targets.
2020-03-09 13:20:42 +01:00
Christian Kellner
5d0f6aa981 pipeline: short-circuit if final object exists
If the final object, image, artifact, already exists in the store,
short-circuit and return directly from `Pipeline.run`. Otherwise
the situation might arise that the final result is in the store,
but the tree (and build trees) are not and thus the tree would be
built, just to be thrown away when the assembler phase detects
that the final output already exists.
2020-03-07 17:13:21 +01:00
Christian Kellner
b755e69bca pipeline: extract assembler code into method
Extract the code that assembles the tree into its own method as
it was previously done for the stages. This should make the new
method as well as `Pipeline.run` method easier to read.
2020-03-07 17:13:21 +01:00
Christian Kellner
170ccd4722 pipeline: no auto-commit for build stages
Refactor the building of stages and the build tree so that no auto
commit is done at the end of the build pipeline anymore, i.e. the
respective build tree(s) are not commit to the store unless that
was explicitly enabled via a checkpoint.

NB: `objectstore.Object`s are used not via a context manager
anymore, because they are returned from the `build_stages` method
to make the code easier to use and read. Cleanup of Objects during
a KeyboardInterrupt exception (Ctrl-C) are handled by using the
ObjectStore with a context manager, which on exit of the context
will cleanup all objects. Due to a big in python[1] this is indeed
more robust than using `with object_store.new() as tree` because
that is translated[2] to something like:

     1: mgr = (EXPR)
     2: exit = type(mgr).__exit__
     3: value = type(mgr).__enter__(mgr)
 ->  4: # NOTE: KeyboardInterrupt here will "leak" value
     5: try:
     6:	[...]
     7: finally:
     8:	   if exc:
     9:        exit(mgr, None, None, None)

Which can leave the tree initialized but not cleaned up if the
KeyboardInterrupt happens exactly line 4.

[1] https://bugs.python.org/issue29988
[2] https://www.python.org/dev/peps/pep-0343/
2020-03-07 17:13:21 +01:00
Christian Kellner
457f21a336 objectstore: add HostTree class to access host fs
Simple new object that should expose the root file system with the
same API as `objectstore.Object` but as read-only. This means that
the `read` call works exactly as for `Object` but `write` raises
an exception.
Add tests to specifically check the read-only properties.
2020-03-07 17:13:21 +01:00
Christian Kellner
01efa9f817 tests/objectstore: check tracking of objects
Ensure all objects are properly cleaned up when ObjectStore is
used as a context manager and the context is exited.
2020-03-07 17:13:21 +01:00
Christian Kellner
856698ee9c objectstore: keep track of created objects
Keep track of all created objects via weak references. Add support
to use ObjectStore as context manager and ensure that all objects
are cleaned up when the context is exited.
2020-03-07 17:13:21 +01:00
Christian Kellner
5fbf5bb431 objectstore: use 'tmp' subdir for temp directories
Instead of creating temporary directories at the root of the store
create them in a sub-directory called 'tmp'. This should make it
easy to cleanup left-over (temporary) dirs in case of crashes.
Additionally, it has the nice side effect that it is possible to
check that there are no objects that are still in-flight, i.e. not
cleaned-up.
2020-03-07 17:13:21 +01:00
Christian Kellner
01d989e718 objectstore: remove context manager for new method
Turn `ObjectStore.new` into a plain method, since `Object` itself
can be used as a context manager, which is now directly returned,
instead of internally wrapped in a `with` statement and then
yielded. Thus for callers of the method nothing changes and the
behavior of `with objectstore.new() as x` is exactly the same.
2020-03-07 17:13:21 +01:00
David Rheinsberg
b28ec66f5a docs: provide a separate manifest description
This rips out the `PIPELINE` section from osbuild(1) and instead adds a
new osbuild-manifest(5) man-page. This new man-page contains a rather
formal definition of the manifest, with a separate section for each
part of a manifest.

The man-page is exhaustive, in that it describes all available options.
However, it does *NOT* document the available stages, runners, and
assemblers. It does document the available (and supported) sources.
This should serve as an example how to document available stages and
assemblers in the future.

Note that it is not clear whether we should document these right now.
Once we decided to support the available stages for a reasonable
time-frame, we can start on documenting them as well.
2020-03-07 13:43:24 +01:00
David Rheinsberg
911fa1d92b schema: add json-schema describing our manifest
This adds a non-binding, documentational-only json-schema to
schemas/osbuild1.json which describes the format of the pipeline
manifest taken as input to osbuild. This is currently for
documentational purposes, but is definitely open to be used for actual
runtime verification.

The manifest does not describe options to assemblers, stages, or
sources. These are left as arbitrary json-objects and need separate
validation, if required. Note that most stages already contain an
embedded schema for their parameters.
2020-03-07 13:43:24 +01:00
David Rheinsberg
108aa87232 docs/osbuild.1: extend EXAMPLES section
This extends the EXAMPLES section with more examples, reduces their
complexity, and also restructures the layout to make it nicer to read
in the resulting TROFF file.
2020-03-07 13:43:24 +01:00
David Rheinsberg
ad3a1a8a58 samples: bring base-rpm-qcow2.json up-to-date
We will mention this example in our man-page, so make sure it actually
works. This imports all sources into the pipeline definition and
adjusts the syntax to match what we expect.
2020-03-07 13:43:24 +01:00
Christian Kellner
012269dc31 setup.py: remove unused import
Remove the unused 'glob' import. Issue found by lgtm.com
2020-03-07 13:42:36 +01:00
Christian Kellner
0df46c6759 Makefile: add target to build the man-page
Add a simple 'man' target to build the osbuild(1) man page.
2020-03-06 14:47:19 +01:00
Christian Kellner
5c465220b4 spec: build and install man page
Build and install the osbuild(1) man page. Requires rst2man, which
is provided by the python3-docutils package.
2020-03-06 14:47:19 +01:00
Lars Karlitski
c09b7b007e test: remove README.md
It only contained references to a Vagrant workflow that doesn't exist
anymore.
2020-03-06 11:57:17 +01:00
Lars Karlitski
52a703de55 Makefile: remove sdist target
It is not used anywhere and might be confusing to newcomers, because it
only contains the (private) osbuild library, without the command line
tool and runners/stages/assemblers.
2020-03-06 11:57:17 +01:00
Lars Karlitski
5a05f7ac11 .gitignore: remove old ignored directory 2020-03-06 11:57:17 +01:00
Lars Karlitski
59b7b545b2 Makefile: remove vagrant rules
They seem to be a remnant, because they couldn't have worked since at
least d15bbaa05d (October 2019).
2020-03-06 11:57:17 +01:00
Major Hayden
94912a8759 📦 Use new 'make rpm' in GitHub Actions
Signed-off-by: Major Hayden <major@redhat.com>
2020-03-05 22:32:01 +01:00
Lars Karlitski
c5543562b8 Makefile: simplify make rpm
Prior to this patch, `make rpm` would produce rpms that have the latest
tag as their versions. This was confusing, because one could never know
which contents are in a locally built rpm.

Change this so that the is version always based on the commit hash of
HEAD. This is easy: the golang macros read a `%commit` macro when it
exists and do this for us.

To simplify more, only define `%_topdir` to ./rpmbuild and use
rpmbuild's known directory structure (SPEC, SOURCES, RPMS, ...)
otherwise, to make it easier to find build results.

Build the specfile, tarball, source rpms, and rpms with `make rpm`,
without separate sub-targets. We can reintroduce them if they're needed
somewhere.
2020-03-05 13:04:18 -06:00
Lars Karlitski
792f5062e7 .gitignore: remove unused directives 2020-03-05 13:04:18 -06:00
Christian Kellner
6fdc52e2ec 9
Release osbuild version 9
2020-03-05 12:42:59 +01:00
Christian Kellner
6a31747aa6 RELEASE.md: update to mention 'v' tag prefix
The rule for the tag name is to have a 'v' prefix, update the
release instruction to reflect that. Also remove the Packit
header, because we don't use Packit at all anymore.
2020-03-05 12:39:46 +01:00
David Rheinsberg
cc6db4c776 build: drop unused MANIFEST.in
The MANIFEST.in file is used to include `LICENSE` in our python source
distribution. However, we never use this. In our spec-files we use the
rpm `%license` macro which copies from the source checkout, anyway.

Lets drop this file so we can forget about it.
2020-03-03 14:30:26 +01:00
Christian Kellner
fecc62f5c8 pipeline: don't commit checkpoints on error
Only commit checkpoints to the object store if the run of the
stage or assembler was successful. Otherwise we commit a empty,
corrupted or old tree to the store. Any subsequent run might
then pick up that bogus tree as a starting point.
2020-03-03 13:38:45 +01:00
Martin Sehnoutka
2227648ad5 Use make bump-version instead of the shell script 2020-03-03 13:05:51 +01:00
msehnout
0f1a70cda0 Remove section about Packit from RELEASE.md
We don't use Packit any more, so just remove it from the RELEASE document. If we ever want to reintroduce it, feel free to simply revert this commit.
2020-03-03 13:05:51 +01:00
David Rheinsberg
ccf050f6a7 build: avoid random tab in specfile
The specfile uses space-based alignment all over the place, except for
one line. Fix this up.
2020-03-03 10:53:30 +01:00
David Rheinsberg
c19175f905 build: make bump-version keep whitespace
Rather than always converting the whitespace to an hard-coded tab, use
reflective expressions to keep them unchanged.
2020-03-03 10:53:30 +01:00
David Rheinsberg
d379cc1a6f build: merge bump-version.sh into local makefile
We already have a makefile for maintenance work. Merge the
`bump-version.sh` script into `Makefile` as a new target so we avoid
placing scripts spread around the repository.

While at it, this commit also uses immediate assignment for
shell-evaluated make variables. This ensures the shell commands are
only executed once, and then are guaranteed to be of the same value for
the remainder of the execution.
2020-03-03 10:53:30 +01:00
David Rheinsberg
adc3465879 osbuild: avoid n^2 loops in checkout handling
When marking stages for checkpointing, let us make use of the local set
datastructure we already allocate, rather than iterating over it
linearly.

Apart from the negligible performance improvement, it makes the code
quite a lot simpler.
2020-03-03 09:48:44 +01:00
David Rheinsberg
179f210e26 osbuild: fix coding style with missing newline
We generally surround function definitions with newlines. Make sure
this is also true for local function definitions.

Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com>
2020-03-03 09:48:44 +01:00
Tom Gundersen
352024830c build-env: drop unnccessary ubuntu build env
Even on ubuntu we can build rpm-based pipelines without bootstrapping
via fedora 27. Drop the build env from the travis config and from our
samples directory.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-03 00:05:26 +01:00
Tom Gundersen
26f5135a5f tests: move from dnf- to rpm-based pipelines
This should produce the same images (except for no more dnf metadata),
but avoids depsolving (and network access) from stages.

The following helper script around osbuild-composer's dnf-json was
used for the translation:

```

import json
import os
import subprocess
import sys

def fetch_repos(sources, repo):
    if isinstance(repo, str):
        repo = sources["org.osbuild.dnf"]["repos"][repo]

    return repo, repo["gpgkey"]

def convert_stage(sources, stage, cachedir):
    gpgkeys = []
    repos = []
    for repoid, repo in enumerate(stage["options"]["repos"]):
        repo, gpgkey = fetch_repos(sources, repo)
        repo["id"] = repoid
        repo["name"] = f"repo-{repoid}"
        repos.append(repo)
        gpgkeys.append(gpgkey)

    arguments = {}
    arguments["cachedir"] = cachedir
    arguments["module_platform_id"] = stage["options"]["module_platform_id"]
    arguments["package-specs"] = stage["options"]["packages"]
    arguments["exclude-specs"] = stage["options"].get("exclude_packages", [])
    arguments["repos"] = repos

    call = {}
    call["command"] = "depsolve"
    call["arguments"] = arguments

    r = subprocess.run(["./dnf-json"],
                   input=json.dumps(call),
                   stdout=subprocess.PIPE,
                   encoding="utf-8",
                   check=True)
    pkgs = json.loads(r.stdout)["dependencies"]

    packages = []
    urls = {}
    for p in pkgs:
        packages.append(p["checksum"])
        urls[p["checksum"]] = p["remote_location"]

    options = {}
    options["gpgkeys"] = gpgkeys
    options["packages"] = packages

    stage["name"] = "org.osbuild.rpm"
    stage["options"] = options

    return urls

def convert_pipeline(sources, pipeline, cachedir):
    urls = {}
    if "build" in pipeline:
        u = convert_pipeline(sources, pipeline["build"]["pipeline"], cachedir)
        urls = {**urls, **u}
    for stage in pipeline["stages"]:
        if stage["name"] == "org.osbuild.dnf":
            u = convert_stage(sources, stage, cachedir)
            urls = {**urls, **u}
    return urls

manifest = json.load(sys.stdin)
urls = convert_pipeline(manifest["sources"], manifest["pipeline"], f"{os.getcwd()}/dnf-cache")
sources = { "org.osbuild.files": { "urls": urls }}
json.dump({"sources": sources, "pipeline": manifest["pipeline"]}, sys.stdout)
                                                                                                                                                                                                                            75,9          Bot
```

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-03 00:05:26 +01:00
Tom Gundersen
320c08b76c tests/dnf: use baseurl over metalink
Using a metalink resolves to a specific mirror at runtime, and
downloads each rpm from that repository.

We want to move to using the org.osbuild.files source, which means
that we must save the url to each rpm in the source definition, which
will be determined by which mirror is used to generate the config.

If we use metalinks to generate the source configuration, the mirror
used will be arbitrary. Instead, we want to pick the best mirror
explicitly, ideally in a way that is independent of the location
depsolving happens in (which will be different from the location
the rpms are downloaded to).

We can choose explicitly by passing baseurl rather than metalink
to dnf, so move in that direction now by replacing all metalinks
by baseurls in our dnf configuration.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-03 00:05:26 +01:00
Tom Gundersen
4e9f5d4473 tests/pipelines: embed all sources with their respective pipelines
We now support sources and pipelines being passed to osbuild as one.

This will make the transformation from dnf to rpm stage simpler, as
the source object will then be different for each stage, so having
a shared one as now would be cumbersome.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-03 00:05:26 +01:00