Commit graph

375 commits

Author SHA1 Message Date
Lars Karlitski
ee752b0ab8 tree-wide: panic when json marshalling fails
According to the new guidelines in docs/errors.md.

Note that this does not include code that marshals to a writer that
might fail (when a connection drops, for example).
2020-03-25 10:22:16 +01:00
Ondřej Budai
d7cbc22da4 lint: fix unhandled errors 2020-03-02 14:28:55 +01:00
Ondřej Budai
3032abfdbe lint: fix gosimple/S1028 errors 2020-03-02 14:28:55 +01:00
Ondřej Budai
820d23fd9d Add tcp and tls support for worker and job API
There's a usecase for running workers at a different machine than
the composer. For example when there's need for making images for
architecture different then the composer is running at. Although osbuild has
some kind of support for cross-architecture builds, we still consider it
as experimental, not-yet-production-ready feature.

This commit adds a support to composer and worker to communicate using TCP.
To ensure safe communication through the wild worlds of Internet, TLS is not
only supported but even required when using TCP. Both server and client
TLS authentication are required. This means both sides must have their own
private key/certificate pair and both certificates must be signed using one
certificate authority. Examples how to generate all this fancy crypto stuff
can be found in Makefile.

Changes on the composer side:
When osbuild-remote-worker.socket is started before osbuild-composer.service,
osbuild-composer also serves jobqueue API on this socket. The unix domain
socket is not affected by this changes - it is enabled at all times
independently on the remote one. The osbuild-remote-worker.socket listens
by default on TCP port 8700.

When running the composer with remote worker socket enabled, the following
files are required:
- /etc/osbuild-composer/ca-crt.pem     (CA certificate)
- /etc/osbuild-composer/composer-key.pem (composer private key)
- /etc/osbuild-composer/composer-crt.pem (composer certificate)

Changes on the worker side:
osbuild-worker has now --remote argument taking the address to a composer
instance. When present, the worker will try to establish TLS secured TCP
connection with the composer. When not present, the worker will use
the unix domain socket method. The unit template file osbuild-remote-worker
was added to simplify the spawning of workers. For example

systemctl start osbuild-remote-worker@example.com

starts a worker which will attempt to connect to the composer instance
running on the address example.com.

When running the worker with --remote argument, the following files are
required:
- /etc/osbuild-composer/ca-crt.pem     (CA certificate)
- /etc/osbuild-composer/worker-key.pem (worker private key)
- /etc/osbuild-composer/worker-crt.pem (worker certificate)

By default osbuild-composer.service will always spawn one local worker.
If you don't want it you need to mask the default worker unit by:
systemctl mask osbuild-worker@1.service

Closing remarks:
Remember that both composer and worker certificate must be signed by
the same CA!
2020-02-20 13:47:59 +01:00
Ondřej Budai
6902f730cb worker: upload local target image using jobqueue api
Prior this commit local target copied the image from a worker to a composer
using cp(1) command. This prevented the local target to work on remote
workers.

This commit switches the local target implementation to using the jobqueue
API introduced in the previous commit. I had some concerns about speed
of this solution (imho nothing can beat pure cp(1) implementation) but
ad hoc sanity tests showed the copying of the image using the jobqueue API
when running the worker on the same machine as the composer is still
more or less instant.
2020-02-14 11:53:38 +01:00
Ondřej Budai
b64bbaa0bb api/jobqueue: move build id to url
Imho it makes more sense from REST perspective. Also, in the future there
will be ROUTE for uploading image to image build. As it's not a good idea
transport file inside JSON, all the parameters (compose id and image
build id) need to be inside the URL. Therefore for the sake of consistency,
all these routes should have compose id and image build id in the URL.

There is another solution to embedding multiple values inside http body
which allows file transport - multipart/form-data. I think using form-data
is worth when doing more complex stuff, for our usecase transporting all
the metadata in the URL is more appropriate solution.
2020-02-14 11:53:38 +01:00
Ondřej Budai
cc00e0cdc9 drop the Compose.Image field
Everything that this field contained can be computed in another way:

- path: just lookup the local target and read the path from there
- mime: can be derived from distribution and compose output type
- size: can be derived from the path

Therefore it imho doesn't make much sense to store these information multiple
times.
2020-02-14 11:53:38 +01:00
Martin Sehnoutka
05b1093170 osbuild-pipeline: use the new types 2020-02-12 11:17:26 +01:00
Ondřej Budai
8781d41da6 worker: normalize Job.Run() return types 2020-02-05 01:35:50 +01:00
Ondřej Budai
0d4479bbcd worker: save result.json in the composer instead of the worker
In the future remote workers will be introduced. Obviously, the remote worker
cannot support the local target. Unfortunately, the current implementation of
storing the osbuild result is dependant on it.

This commit moves the responsibility of storing osbuild result to the
composer process instead of the worker process. The result is transferred from
a worker to a composer using extended HTTP API.
2020-02-05 01:35:50 +01:00
Lars Karlitski
df99e8b359 worker: log errors that are not returned to composer 2019-12-15 22:05:31 +01:00
Lars Karlitski
5bce59b979 worker: do not get the distro from the host
Add a `Distro` field to both `Job` structures and send that to the
worker.
2019-12-15 22:05:31 +01:00
Lars Karlitski
dff8cb56be worker: don't call log.Fatalf() unconditionally
Oops.
2019-12-15 22:05:31 +01: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
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
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
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
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
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
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
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
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