Commit graph

898 commits

Author SHA1 Message Date
Tom Gundersen
506b012f08 distro: take architecture as an argument
Allow bootloader specific packages to be defined per architecture,
and allow repositories to depend on the architecture.

This does not altert he pipelines we produce, part from the ami
image now contains the grub2-pc package, rather than the grub2
package. This should make no difference.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-12-14 17:23:31 +01:00
Lars Karlitski
2b42612336 distro: insert custom sources into pipeline
This is an additional argument on `distro.Pipeline` right now. In the
future, we probably want this per-blueprint.
2019-12-11 21:19:32 +00:00
Tom Gundersen
118b185fdd osbuild-{composer/worker}: exit cleanly
Only panic on compile-time errors (e.g., built for unsupported
architecture). Otherwise, use log.Fatalf(), which is equivalent to
printing and exiting with return code 1. Only ever do this from
main(), in all other cases pass on the error object.

This is mostly relevant when the server disconects, in which case
we'll get EOF, and will now restart cleanly instead of panicing.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-12-11 15:23:24 +01:00
Tom Gundersen
d33fc5f010 composer: add provisional multi-arch support
The pipeline generation now takes the architecture as an argument.
Currently only x86_64 is supported. The architecture is detected
at start-up, and passed down to each pipeline translation.

For osbuild-pipeline we now requrie the architecture to be passed
in.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-12-11 15:23:24 +01:00
Lars Karlitski
167e09fc54 osbuild-pipeline: display blueprint parse errors 2019-12-10 20:21:47 +00:00
Lars Karlitski
d3a0b788a2 distro: set the repository checksum dynamically
Instead of having a static repository checksum, set it dynamically from
the metadata that osbuild-composer last saw. This is implemented in
dnf-json, which returns the checksums for each repository on every call.

This enables the use of repositories that change over time, such as
fedora-updates. Note that the osbuild pipeline will break when such a
repository changes. This is intentional: pipelines have to be
reproducible.
2019-12-10 20:38:22 +01:00
Ondřej Budai
6d15833e4e store: introduce state directory
Prior to this commit outputs directory used by local target was owned by root.
This made impossible for osbuild-composer to delete images. (osbuild-composer
doesn't run as root).

This commit introduces state directory in which osbuild-composer creates
outputs directory. Because this directory is owned by osbuild-composer, it's
able to delete files inside.
2019-12-10 01:14:36 +01:00
Ondřej Budai
f89a9671be store: add image struct into compose struct
As a part of f4991cb1 ComposeEntry struct was removed from store package.
This change made sense because this struct is connected more with API than
with store - store uses its own Compose struct. In addition, converters
between Compose and ComposeEntry were added. Unfortunately, ComposeEntry
contains ImageSize which was not stored in Compose but retrieved from store
using GetImage method. This made those converters dependent on the store,
which was messy.

To solve this issue this commit adds image struct into Compose struct.
The content of image struct is generated on the worker side - when the worker
sets the compose status to FINISHED, it also sends Image struct with detailed
information about the result.
2019-12-05 09:48:21 +01:00
Martin Sehnoutka
364ea62f59 Introduce Azure upload test
The test is very simple, it first upload a file with random content and
then downloads it back and compare hashes.
2019-11-29 12:19:40 +01:00
Lars Karlitski
5dad3bfc8e worker: pass build environment to osbuild
Detect it from the host using the distro package.
2019-11-29 00:46:05 +01:00
Lars Karlitski
85e6182bdc distro: don't fall back to fedora-30
Make osbuild-composer use FromHost() directly. Everywhere else needs to
specify the distro explicitly.

Also don't panic when a distro doesn't exist. Instead, return nil. Make
sure all callers check for that.
2019-11-29 00:46:05 +01:00
Lars Karlitski
70857963bb osbuild-composer: don't try creating state directory
systemd creates it for us. We don't support running this binary outside
of systemd.
2019-11-29 00:46:05 +01:00
Lars Karlitski
14ebed46da distro: register distros explicitly
Automatically registering on `init()` is clever, but a bit too magical
and easy to get wrong, because every binary must include all distros
somewhere.

Flip this inside out: distros now have a `New()`, which returns
something that implements the `Distro` interface. The distro package
explicitly creates all of them.

This means that distros cannot import distro itself anymore, because go
forbids import cycles. This only affected `InvalidOutputFormatError`.
Return a generic error for now.
2019-11-29 00:46:05 +01:00
Tom Gundersen
caff96bd4f job/run: never panic on failed job
Return the error code of the osbuild run, and an array of errors,
one for each target provided. If a target fails, all other targets
are still attempted.

If either osbuild or one of the targets retursn an error, the worker
notifies osbuild-composer that the job failed.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-11-28 05:56:11 +01:00
Lars Karlitski
da311f13eb distro: add rhel82
This takes a different approach to outputs and customizations, which is
much shorter and duplicates less code.

This uses links to internal repositories for now, because 8.2 hasn't
been released yet.

Add a `distro` flag to `osbuild-pipeline`.
2019-11-27 17:08:51 +01:00
Martin Sehnoutka
1135e9fe01 Refactor Azure upload code to a separate package
as part of this, move also the AWS upload code to the same directory
2019-11-27 12:14:07 +01:00
Tom Gundersen
7f5c869cd2 upload/aws: add a sample AWS upload client
This commandline tools uploads a file to S3, as a proof of concept.

All options are mandatory. Credentials are only read from the
commandline and not from the environment or configuration files.

The next step is to add support for importing from S3 to EC2,
currently the images we produce cannot be imported as-is, so this
requires more research.

To try this out: create an S3 bucket, get your credentials and
call the tool, passing any value as `key`. Note that if the key
already exists, it will be overwritten.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-11-26 01:05:34 +01:00
Martin Sehnoutka
78ea0e0b6f Introduce Azure upload CLI utility
It uses Azure SDK to connect to Azure storage, creates a container there
and uploads the image. Unfortunately the API for page blobs does not
include some thread pool for upload so I implemented one myself. The
performance can be tweaked using the upload chunk size and number of
parallel threads.

The package is prepared to be refactored into common module within
internals package as soon as we agree on the of these common packages
for image upload.

Add azure-blob-storage rpm package as a dependency

It didn't work for me using the `golang(package)` syntax. Using the
package name explicitly works.
2019-11-25 17:10:11 +01:00
Lars Karlitski
b911d0b928 weldr: get repositories from distro
Make distros export repository information and use those in the weldr
API. This means that repos are only specified once and that the API
returns the right packages when we allow different distros.
2019-11-18 12:22:10 +01:00
Jacob Kozol
c882bebfb4 remove packages from weldr API initialization
The package list is generated on each request for a package so there is
no longer a need to generate the package list in main or to store these
packages in the API object.
2019-11-14 12:16:07 +01:00
Ondřej Budai
495f5b558b Add support for mocking rpmmd
We want to test API methods which calls dnf. Unfortunately, calling dnf
is expensive operation - it requires network access and downloading
a lot of (meta)data. This commit changes the rpmmd implementation
so that it can be mocked.
2019-11-13 14:54:02 +01:00
Lars Karlitski
f9cbc8593f distro: add DetectHost
lorax-composer uses the host's repositories for building images. This is
prone to accidental configuration errors and duplicates functionality
(adding custom repositories via the source API is much more explicit).

However, blueprints don't specify the distribution they're based on.
This is something they should do in the future to enable cross-distro
image builds. Until then, read `/etc/os-release` to detect the host OS
and use that as the base distro for a blueprint.

Detection works by concatenating the ID field with a `-` and the
VERSION_ID field. This mandates how additional distributions should
register themselves to the `distro` package.

If composer cannot build the detected distro, fall back to fedora-30.

Use this detection everywhere that fedora-30 was hard-coded before.
2019-11-10 17:23:14 +01:00
Lars Karlitski
b33ed9e5d2 blueprint: move pipeline generation into its own package
Introduce the `distro` package, which contains an interface for OS
implementations. Its main purpose is to convert a blueprint to a
distro-specific pipeline.

Also introduce the `distro/fedora30` package. It is the first
implementation of the distro interface. Most of its code has been copied
with minimal modifications from the blueprint package.

The `blueprint` package is now back to serving a single purpose:
representing a weldr blueprint. It does not depend on the `pipeline`
package anymore.

Change osbuild-composer and osbuild-pipeline to use the new API,
hard-coding "fedora-30". This looks a bit weird now, but is the same
behavior as before.

All test cases now also take an "distro" key in the "compose" object.
2019-11-07 17:13:20 +01:00
Martin Sehnoutka
24e3e5f8be enable passing of a blueprint to osbuild-pipeline
It is enabled via a command-line argument `-blueprint`.
2019-11-04 18:37:03 +01:00
Lars Karlitski
c3e029ae82 dnf-json: don't hard-code Fedora 30
Make each command accept a `repos` key containing repository
descriptions.

Make weldr API pass the repository like this. Nothing should change,
because the repos were the same (Fedora 30).
2019-11-04 00:17:25 +01:00
Tom Gundersen
aa404dcb99 worker: move Job type to the jobqueue package
The main purpose of this is to share the structs between the server
and the client, and let the compiler ensure that our marshaling and
unmarshaling matches.

In the future we also want to make it easier to write unittests for
this code.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-29 16:08:54 +01:00
Ondřej Budai
6e790bc62d osbuild-composer: Fix imports broken by new module name
We've merged some stuff with old module name used in imports. This
commit fixes it.
2019-10-09 08:06:07 +02:00
Ondřej Budai
15b82a15d2 osbuild-composer: Rename module to github.com/osbuild/osbuild-composer
This should be the best practice according to other popular go projects:
- https://github.com/prometheus/prometheus
- https://github.com/syncthing/syncthing
- https://github.com/drone/drone
- https://github.com/hashicorp/terraform

Also, this change fixes go get command (it currently fails due to bad package
name).
2019-10-08 21:44:57 +02:00
Tom Gundersen
b0d9423b73 osbuild-pipeline: add tool to print pipelines to stdout
This tool outputs the pipeline associated with each output type. In
the future this should grow to take a blueprint as an input, and
also allow the arch/os/version/variant to be configured.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-08 21:03:45 +02:00
Tom Gundersen
68ade23fcc store: make state (de)serialization internal
This hides the state hanlding in the store package. As before, it
can be disabled by passing `nil` instead of the path to the state
file.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +02:00
Tom Gundersen
ad637b46f8 osbuild-composer: rename the state file state.json
It is no longer specific to the weldr API, so drop the weldr prefix.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +02:00
Tom Gundersen
b6c63b6d59 store: don't initialize the store with an example
We probably want to ship in a pristine state, so let's leave this out
for now.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +02:00
Tom Gundersen
9cb140795e store: add {Push,Pop}Compose methods and hide channel
Wrap the channel in Pop and Push methods, so it is not exposed to
the callers. PushCompose replaces the old AddCompose for consistency,
and PopCompose simply reads from the other end of the channel.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +02:00
Tom Gundersen
3ff4f59fc7 store: pass the store to the jobqueue API
Drop the jobUpdates channel, and instead add an UpdateCompose method
to the store, which updates the status of a compose directly.

This allows us to report back errors directly, rather than having to
mirror the staet in the jobqueue API.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +02:00
Tom Gundersen
89fd2e6037 store: move creation to main.go
Let the weldr API take the store as an argument, rather than create it
itself. This will allow us to share the store with the jobqueue API in
follow-up patches.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +02:00
Tom Gundersen
0880014edf jobqueue: cleanup API a bit and unify the two job stores
Let the store in weldr be the only one that keeps state, and push
updates directly there. This fixes a bug where there was an ID mismatch.

Change the API to not let the caller pick the UUID, but provide it
in the response. Use the same UUID as is used to identify composes,
this makes it simpler to trace what is going on.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +02:00
Martin Sehnoutka
ed185b41ce Integration of osbuild composer with systemd
osbuild-composer now uses socket activation instead of hardcoded paths
in the code. osbuild-worker is an http client therefore it uses only
service unit. osbuild-worker must be started after the socket is
created. osbuild-composer service requires osbuild-worker to run, because without
it no jobs can be started.

osbuild-composer is executed as a regular user (newly created
_osbuild-composer user) as opposed to the worker which must run as root
in order to execute osbuild itself
2019-10-02 17:56:59 +02:00
Tom Gundersen
96f3cbf655 weldr/store/compose: store information exposed in the API
Use the exact same status strings as is used in the API,
making it clearer that they are the same (and avoiding any
translation). Remember the creation/start/finish timestamps.
And store the output type.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-09-29 14:51:22 +02:00
Tom Gundersen
d231694bae worker/target/local: copy to the right location
We were copying the containing directory from our object store, we
only want the contents.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-09-28 17:49:07 +02:00
Tom Gundersen
7625d26ff5 pipeline/target: implement as variant types
Go doesn't really do variants, so we must somehow emulate it. The
json objects we use are essentially tagged unions, with a `name`
field in reverse domain name notation identifying the type and a
type specific 'options' object.

In Go we represent this by having an BarOptions interface, which
implements a private method `isBarOptions()`, making sure that only
types in the same package are able to implement it. Each type FooBar
that should belong to the variant implements the interface, and a
constructor `NewFooBar(options *FooBarOptions) *Bar` that makes sure
the `name` field is set correctly.

This would be enough to represent our types and marshal them into
JSON, but unmarshalling would not work (json does not know about
our tags, so would not know what concrete types to demarshal to).
We therefore must also implement the Unmarshall interface for Bar,
to select the right types for the Options field.

We implement his logic for Target, Stage and Assembler. A handful
of concrete types are also implemented, matching what osbuild
supports.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-09-28 17:49:07 +02:00
Lars Karlitski
87bcd7f9d3 worker: run osbuild 2019-09-27 17:42:52 +02:00
Tom Gundersen
f880581a14 weldr/store: keep the compose status up-to-date
This way it can be correctly exposed in the API. We listen on a channel
from the job-queue, where status updates are pushed when the worker is
running/finished (or, in the future, failed).

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-09-27 14:34:51 +02:00
Lars Karlitski
cfe89eaed5 Add simple osbuild-worker
It doesn't actually build anything yet, but talks to the queue API.
2019-09-26 23:58:03 +02:00
Tom Gundersen
3221112d35 composer/job-queue: add scaffolding for the job queue API
This is by no means done, and needs more tests, docs and bugfixes,
but push it early so we have a common base to work on.

Based on work by Martin Sehnoutka.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-09-26 19:53:06 +02:00
Lars Karlitski
6576fe45dc main: move http serving to weldr
Also make sure that /run/weldr exists.
2019-09-26 19:53:06 +02:00
Martin Sehnoutka
0861b80c99 create jobs queue for scheduling new builds 2019-09-25 14:31:15 +02:00
Tom Gundersen
da887a43fb tree-wide: format the code
$ go fmt ./...

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-09-24 01:03:27 +02:00
Tom Gundersen
b60f580d92 tree-wide: use a standard project layout
Keep main.go files under cmd/ and internal libraries under internal/.
This will allow us to add more exutables under cmd/ (whereas only one
was possible when main.go was kept in the root).

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-09-24 00:03:53 +02:00