Commit graph

431 commits

Author SHA1 Message Date
Christian Kellner
68f5c38e61 main: print all pipeline names and ids
Instead of printing the tree_id and output_id, which are format
dependent, print all pipelines, with their name and ids.
2021-02-10 17:50:41 +01:00
Christian Kellner
931eac23c3 sources: introduce source items
All sources fetch various types of `items`, the specific nature
of which is dependent on the source type, but they are all
identifyable by a opaque identifier. In order for osbuild to
check that all the inputs that a stage needs are are indeed
contained in the manifest description, osbuild must learn what
ids are fetched by what source. This is done by standarzing
the common "items" part, i.e. the "id" -> "options for that id"
mapping that is common to all sources.
For the version 1 of the format, extract the files and ostree
the item information from the respective options.
Adapt the sources (files, ostree) so that they use the new items
information, but also fall back to the old style; the latter is
needed since the sources tests still uses the SourceServer.
2021-02-10 15:44:24 +01:00
Christian Kellner
3b7141417c formats/v1: extract source loading code
Extract the code that loads individual source into its own
function.
2021-02-10 15:44:24 +01:00
Christian Kellner
6d674a0970 main_cli: detect format
Now that meta.Index provides a way to detect the format given the
input data, use that method instead of the hard-coded use of the
version 1 format via the input. This should make the main entry
point format independent.
2021-02-09 13:08:24 +01:00
Christian Kellner
8f97c13dda formats/v1: specify format version
Specify the version, i.e. "1", that this format is able to read
and write. Additionally add a proper doc string describing the
format.
2021-02-09 13:08:24 +01:00
Christian Kellner
7e2c0c7000 meta: introduce format information
Introdcue a `FormatInfo` class that, very much like `ModuleInfo`
can be used to obtain meta information about a format. Methods
are added to `Index` to allow the enumeration of available formats,
getting the `FormatInfo` for a format given its name and to detect
a format via the manifest description data.

Change the top-level documentation to reflect the changes. Also
remove an outdated section about validation of the schema; this
was moved to the format specific code some time ago.
2021-02-09 13:08:24 +01:00
Christian Kellner
7ffae5669c osbuild: convert ostree stage to inputs
Convert the `org.osbuild.ostree` stage to use inputs instead of
sources. In the format (version 1) loading code, convert the
stage to use an input based on the existing stage options.
2021-02-06 12:04:30 +01:00
Christian Kellner
0256396270 osbuild: convert rpm stage to use inputs
Convert the `org.osbuild.rpm` stage to use inputs instead of
sources. When loading v1 formats the input is generated from
the stage options.
2021-02-06 12:04:30 +01:00
Christian Kellner
57ccf403e1 formats/v1: use new Stage.add_input
Instead of manually constructing and appending the input for
stages (here the stages that replace the assembler), use the
new `Stage.add_input` method.
2021-02-06 12:04:30 +01:00
Christian Kellner
9e8b254687 stage: introduce add_input method
In much the same way has `Pipeline` has `add_stage` and `Manifest`
has `add_pipeline`, introduce an `add_input` method to `Stage` to
be able add `Inputs` to stages.
2021-02-06 12:04:30 +01:00
Christian Kellner
ad8baab819 inputs: remove type info for info param
The `info` parameter for Input constructor is of type `PModuleInfo`,
which is located in `meta`. This in turn imports jsonschema. Ergo,
importing importing `inputs` will create a dependency on jsonschema.
At the same time the `osbuild` package globally imports `Pipeline`,
via `__init__.py`, and `osbuild.api` is used in the runners and
stages, which are run inside the buildroot. If one now wanted to
use `inputs` from `Pipeline`, it would lead to jsonschema being
imported (via `meta`) which might not be available on the build-
root and it is a rather random dependency to have.
On obvious solution would be to use a construct with `TYPE_CHECKING`,
a la:
  if TYPE_CHECKING:
    from .meta import ModuleInfo
Sadly, pylint will now complain about it. This could be fixed with:
  if TYPE_CHECKING:
    from .meta import ModuleInfo
  else:
    ModuleInfo = "osbuild.meta.ModuleInfo"
But this is just gross. So we will have to accept that Python is,
well, Python und omit the type information for the `info` param.
2021-02-06 12:04:30 +01:00
Christian Kellner
ba7f6fe7c7 formats/v1: extract stage parsing into function
Extract the code that creates a stage given its description into
its own function.
2021-02-06 12:04:30 +01:00
Christian Kellner
aa9fee7b51 objectstore: add source method to api
Add a new jsoncomm rpc method call, `source`, that will return
the directory within the store where resources for that specific
type of resource, like e.g. tree, files, or ostree can be found
or stored.
2021-02-06 12:04:30 +01:00
Christian Kellner
eb1d17d8ac input: add references and origin
Currently all options for inputs are totally opaque to osbuild
itself. This is neat from a seperation of concerns point of view
but has one major downside: osbuild can not verify the integrity
of the pipeline graph, i.e. if all inputs that need pipelines or
sources do indeed exists. Therefore intrdouce two generic fields
for inputs: `origin` and `references`. The former can either be
a source or a pipeline. The latter is an array of identifiers or
a dictionary where the keys are the identifiers and the values
are additional options for that id. The identifiers then refer
to either resources obtained via a source or a pipeline that has
already been built.
2021-02-06 12:04:30 +01:00
Christian Kellner
12c9173faf manifest: use newly introduced Source class
Add a new `add_source` method that will add an individual `Source`
to a `Manifest` give its `ModuleInfo` and options. The dictionary
of source options in the manifest is replaced with a list of such
`Sources` and `add_source` will append to it. Adap the version 1
format code to use `add_source` and reconstruct the source options
from the list of source on `describe`.
Remove the `sources_options` constructor parameter for `Manifest`
and adapt all the source base for this.
2021-02-06 12:04:30 +01:00
Christian Kellner
8423da368a sources: introduce the Source class
Very much like, stages and inputs, a new `Source` calls represents
a source type with its options. A `download` method on the `Source`
class can be used to only donwload content to the cache.
2021-02-06 12:04:30 +01:00
Christian Kellner
0fba88d7a9 stage: include inputs in id calculation
Include all inputs of a stage during the calculation of its id,
since they determine, very much like options, the content the
stage produces; thus different inputs should lead to different
ids.
2021-01-22 15:03:19 +01:00
Christian Kellner
684c408914 inputs: add an id property
Add an `id` property that, like `Stage.id`, can be used to uniquely
identify an input based on its name and options. Two stages with
the same name and options will have the same `id`.
2021-01-22 15:03:19 +01:00
Christian Kellner
9f4861e58f inputs: properly mark name as a property
It was meant to be a property not a function.
2021-01-22 15:03:19 +01:00
Christian Kellner
c6432d0adb pipeline: replace tree_id with id
Now that `Pipelines` have no assemblers anymore and thus only one
identifier, i.e. the one corresponding to the tree (`tree_id`),
the `id` and `tree_id` are now the same. Therefore replace the
usage of `tree_id` with `id` and drop the former. Add some extra
documentation including some caveats about the uniquness of `id`.
2021-01-22 15:03:19 +01:00
Christian Kellner
53e9ec850b osbuild: assemblers are pipelines now
Convert the assembler phase of the main pipeline in the old format
into a new Pipeline that as the assembler as a stage, where the
input of that stage is the main pipeline. This removes the need of
having "assemblers" as special concepts and thus the corresponding
code in `Pipeline` is removed. The new assembler pipeline is marked
as exported, but the pipeline that builds the tree is not anymore.
Adapt the `describe` and `output` functions of the `v1` format to
handle the assembler pipeline. Also change the tests accordingly.

NB: The id reported for the assembler via `--inspect` and the result
will change as a result of this, since the assembler stage is now
the first and only stage of a new pipeline and thus has no base
anymore.
2021-01-22 15:03:19 +01:00
Christian Kellner
91aa0c6e88 manifest: add __contains__ method
Since `__iter__` is return an iterator over the `Pipeline` objects,
the `"name" in manifest` check would not work for name or ids. Thus
provide an implemention of `__contains__` that does exactly that.
2021-01-22 15:03:19 +01:00
Christian Kellner
18671686ee manifest: add get method to lookup pipelines
Add a new helper helper, `Manfifest.get` that will return a
pipeline give a name or an id or `None` if no pipeline could
be found with either. The implementation is taken from the
existing `__getitem__` method and the latter as now based on
the new `get` method.
2021-01-22 15:03:19 +01:00
Christian Kellner
569345cc72 pipeline: identify pipelines by name
Every pipeline that gets added to the `Manifest` now need to have
a unique name by which it can be identified. The version 1 format
loader is changed so that the main pipeline that builds the tree
is always called `tree`. The build pipeline for it will be called
`build` and further recursive build pipelines `build-build`, where
the number of repetitions of `build` corresponds to their level of
nesting. An assembler, if it exists, will be added as `assembler`.
The `Manifest.__getitem__` helper is changed so it will first try
to access pipeline via its name and then fall back to an id based
search. NB: in the degenrate case of multiple pipelines that have
exactly the same `id`, i.e. same stages, with the same options and
same build pipeline, only the first one will be return; but only
the first one here will be built as well, so this is in practice
not a problem.
The formatter uses this helper to get the tree pipeline  via its
name wherever it is needed.
This also adds an `__iter__` method `Manifest` to ease iterating
over just the pipeline values, a la `for pipeline in manifet`.
2021-01-22 15:03:19 +01:00
Christian Kellner
88acd7bb00 pipeline: make them "exportable"
Add a new `export` property to the `Pipeline` object that indicates
whether a the result, i.e. the tree after the pipelines has been
built, should be exported, i.e. copied to the output directory.
In the current format (v1), the main pipeline, gets marked as such
by the corresponding loader.
2021-01-22 15:03:19 +01:00
Christian Kellner
42dd3c1e2d manifest: add and use add_pipeline method
Instead of passing all pre-created pipelines to the Manifest
constructor, add a `add_pipeline` method, analogous to the
existing `Pipeline.add_{stage, assembler}` methods. Convert
the format loading code to use that and remove the constructor
parameter.
2021-01-22 15:03:19 +01:00
Christian Kellner
673ea0dfca formats/v1: properly format failed results
When the build fails, not all pipelines might have been built and
those pipelines will be missing from the results. Currently the
code assumes that all pipelines will have a result and this will
crash when trying to find an id for an pipeline that did not get
built.
2021-01-20 21:27:17 +01:00
Christian Kellner
6c02002cbd pipeline: remove Assembler class
Now that assemblers are represented via the `Stage` class, the
Assembler class is not needed anymore. Adjust the monitor method
to take an `pipeline.Stage` for the `assembler` method as well.
2021-01-19 10:42:26 +01:00
Christian Kellner
8ccc73d1c3 pipeline assemblers are stages now
Instead of using the `Assemblers` class to represent assemblers,
use the `Stage` class: The `Pipeline.add_assembler` method will
now instantiate and `Stage` instead of an `Assembler`. The tree
that the pipeline built is converted to an Input (while loading
the manifest description in `format/v1.py`) and all existing
assemblers are converted to use that input as the tree input.

The assembler run test is removed as the Assembler class itself
is not used (i.e. run) anymore.
2021-01-18 17:44:46 +01:00
Christian Kellner
ff7696a92e pipeline: return objects from add methods
Return the Assembler and Stage that got added from their respective
methods.
2021-01-18 17:44:46 +01:00
Christian Kellner
1a3c8e85c6 stage: temp dirs within store's tmp dir
Instead of creating the temporary directory for the BuildRoot and
the sources output directly at the store root, create them inside
the store's temporary directory.
2021-01-18 17:44:46 +01:00
Christian Kellner
0bb3121273 stage: provide loop-server to stages
This makes it possible for stages to create loop devices and further
aligns Stages and Assemblers.
2021-01-18 17:44:46 +01:00
Christian Kellner
1297922a57 stage: add support for inputs
Support for inputs. Before the stage is executed all inputs of the
stage are run. The returned path is mapped inside the sandbox and
pass, along with the returned data, as part of the arguments to the
stage via new "inputs" dictionary. They keys represent the input
keys as given in the manifest.
2021-01-18 17:44:46 +01:00
Christian Kellner
7084c2a600 meta: support for inputs
Inputs are modules like Stages, Assemblers and Sources. Add them
as a new module klass to the various functions. Include them in
the schema test, so the schema of all inputs is validated.
Also sort the module classes alphabetically in the class mapping
and class list.
2021-01-18 17:44:46 +01:00
Christian Kellner
3bccc82ce9 inputs: introduce new input concept
A pipeline input provides data in various forms to a `Stage`, like
files, OSTree commits or trees. The content can either be obtained
via a `Source` or have been built by a `Pipeline`. Thus an `Input`
is the bridge between various types of content that originate from
different types of sources.

The acceptable origin of the data is determined by the `Input`
itself. What types of input are allowed and required is determined
by the `Stage`.

To osbuild itself this is all transparent. The only data visible to
osbuild is the path. The input options are just passed to the
`Input` as is and the result is forwarded to the `Stage`.
2021-01-18 17:44:46 +01:00
Christian Kellner
93010c7e16 stage: use exist stack in the run method
Simplify context management in the `Stage.run` method by using an
`ExitStack` instead of a multiline `with` statement.
2021-01-18 17:44:46 +01:00
Christian Kellner
79d9066861 objectstore: add api server and client
The StoreServer and corresponding Client provide access to small
subset of the store methods to other process than the main osbuild one.
Currently it can be used to read trees of objects given their id and
create  temporary directories within the store's tmp path.
The lifetime of the result of both operations are bound to the Server.
2021-01-18 17:44:46 +01:00
Christian Kellner
d028ea5b16 stage: pass store instead of cache & var
Instead of passing separate `cache` and `var` variables, which are
both determined by the store, just pass the store.
2021-01-18 17:44:46 +01:00
Christian Kellner
de021b468a stage: use path meta info to run the stage
Now that the `Stage` contains the `ModuleInfo`, which contains the
path the to executable, this can directly be used to execute the
stage. To do so, the path to the executable is bind-mounted to a
well known path inside the sandbox (`/run/osbuild/bin/$id`) and
this is then supplied to the build root as executable to run.
2021-01-18 17:44:46 +01:00
Christian Kellner
7a6c2df910 stage: add module information about itself
Add a new `info` property that holds the `meta.ModuleInfo` info
for the stage. This gives each instance of a stage access to
meta (or class) information about it, i.e. its schema, docs but,
more importantly, also its name and path to the executable.
Thefore the `name` property is coverted into a transient property
which access the `name` member of `info`.
Change the `formats/v1` load mechanism to carry a new `index`
argument which is used to load the `ModuleInfo` for each stage.
Adapt all tests to load the info as well when creating stages.
2021-01-18 17:44:46 +01:00
Christian Kellner
a26b7291d1 meta: add module path to module info
Add the path to the executable for that module to the ModuleInfo.
This can then later be used to actually execute said module. The
information is already readily available since we used the path
to load the information from the file in the first place.
2021-01-18 17:44:46 +01:00
Christian Kellner
a0e862f083 formats/v1: determine build_id outside param
Instead of determining the build id while constructing the
Pipeline object, do so beforehand. This makes it clearer
what is going.
2021-01-18 17:44:46 +01:00
Christian Kellner
da16fe30bf formats/v1: set stage sources after loading
Instead of carrying around the `sources_options` parameter
through the recursive `load` and `load_build` calls, set
the sources options after loading has completed by iterating
through all stages of all pipelines.
2021-01-18 17:44:46 +01:00
Christian Kellner
698635171c pipeline: refactor args for add_stage
All tests and invocations of `add_stage` actually pass a valid
options dictionary. Thefore move the `options` args before
the `sources` arg and remove the default value (`None`).
2021-01-18 17:44:46 +01:00
Christian Kellner
262877091f osbuild: flatten the pipeline
Instead of having build pipelines nested within the pipeline it is
the build pipeline for, the nested structure is transferred into a
flat list of pipelines. As a result the recursion is gone and all
the pipelines and trees are build one after the other. This is now
possible since floating objects are kept alive by the store itself
and all trees that are being built are transparently via them.
The immediate result dictionary changed accordingly. To keep the
JSON output of osbuild the same, the result is now routed through
a format specific converter.
Additionally, the v1 format module gained a function to retrieve
the global tree_id and output_id. With the new models those global
ids will go away eventually and thus need to go through the format
specific code.
2021-01-15 13:20:31 +01:00
Christian Kellner
54761e8a13 pipeline: introduce generic pipeline id
This is a step towards generic pipelines, i.e. replacing assemblers
with pipelines, thus creating an acyclic graph of pipelines. There
the pipeline id will be what is now the tree_id. For now though the
generic id is either the output_id or the tree_id.
2021-01-15 13:20:31 +01:00
Christian Kellner
76e72b1c3f objectstore: keep strong reference of objects
The objectstore always tracked all objects that were returned from
it, but it did so via weak references, which means it did not keep
the objects alive itself. With the introduction of identifiers for
temporary objects (floating objects), it makes sense to keep all
created objects alive so that they can in fact be used.
2021-01-15 13:20:31 +01:00
Christian Kellner
e5b12e55f4 objectstore: transparant access for floating objs
A "floating" object is a temporary object that is identified, i.e.
has an `id` and is thus also locked, but is not committed to the
store.
The `contains` and `get` methods of ObjectStore will now return such
floating objects as if they were committed ones, provind transparent
access to object that have been built during the exectuin of osbuild.
2021-01-15 13:20:31 +01:00
Christian Kellner
e24dfbd23f pipeline: don't use a non-existing base for trees
The current pipeline code used to set a base for a tree object
that might or might not exist. Depending on it it would either
use that object or reset its base. Avoid doing that because it
prohibits us from properly interpreting the `id` of an object
if the latter is also set when `base_id` is assigned, since
that base might not exist and thus the `id` would not actually
mean that the the contents of tree associated with the object.
Therefore we use `ObjectStore.get` and return the result if it
is not None or a fresh Object otherwise.
2021-01-15 13:20:31 +01:00
Christian Kellner
b039761544 pipeline: identify tree objects during build
Every time a stage has been successfully built, the contents of
the tree now corresponds to the stage and can thus be identified
via the id of the stage.
When the tree is being written to, i.e. on consecutive attempts
of stage builds, the `id` of the tree object will automatically
be reset.
2021-01-15 13:20:31 +01:00