Commit graph

52 commits

Author SHA1 Message Date
Ondřej Budai
55d3854033 targets/local: drop Location field
When support for osbuild result was added into osbuild-composer it was in
a bit hacky way - localtarget's location was reused as a path for the
result. This didn't make much sense because we want to store the result
even when image build has no localtarget.

Several past commits made store less dependant on the localtarget. The
responsibility for "holding the paths" to build artifacts was gradually
switched from the localtarget to the store while still maintaining
backwards compatibility - localtarget.Location still pointed at the
correct location.

This commit finishes the switch: local target now has no Location field.
The store is now fully responsible for managing the artifacts and paths
to them. LocalTarget is now just a simple "switch" - if image build has it,
then worker uploads an image into the store and it's then available for
download using the weldr API.
2020-02-14 11:53:38 +01:00
Ondřej Budai
98aac91083 api/jobqueue: add route to upload images 2020-02-14 11:53:38 +01:00
Ondřej Budai
08c5eaf6a6 store disk artifacts per image build instead of per compose
In #221 Compose was refactored: Now it can have multiple image builds. More
image builds result in more jobs. Each job has its own result (logs from
osbuild). Additionally, also targets are now a part of image build. With
local target this effectively means we can have multiple images per compose.

However, these artifacts (images & results) were stored only per compose
prior this commit, thus rendering the behaviour of composes with multiple
image builds undefined and racy.

This commit fixes it by storing all the artifacts per image build instead of
per compose. To achieve this feature, getComposeDirectory and
getImageBuildDirectory methods were created to centralize the path assembly.

Paths to artifacts prior this commit:
${COMPOSER_STATE_DIR}/outputs/${COMPOSE_ID}/*

Paths to artifacts after this commit:
${COMPOSER_STATE_DIR}/outputs/${COMPOSE_ID}/${IMAGE_BUILD_ID}/*
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
962365251d store: refactor compose handling
All the preceding changes in jobqueue, compose package, common types
etc. were a base for refactoring the store so that a compose can handle
multiple image builds. This commit introduces the change in a backwards
compatible way, so that the weldr api don't change.
2020-02-12 11:17:26 +01:00
Jacob Kozol
abb5469b30 distro: get proper image size from distro
When a user does not define the image size for a compose the default
image size of that image type is used. In order to properly store the
compose's image size even if the default is used the store calls the
distro function GetSizeForOutputType. This function accepts an output
format and image size. If the image size is 0 then the default
value for the output format will be returned. Also, for vhd images the
size must be rounded. This is now handled in the distro function instead
of the api.
2020-02-07 14:49:15 +01:00
Jacob Kozol
e30f40873d store: add image size to compose
When a use defines the image size for a compose this size is stored in
the compose struct so that the virtual image size can be returned by the
api instead of the file size of the image.
2020-02-07 14:49:15 +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
Brian C. Lane
642b90c977 Switch blueprint commit to use a random SHA-1
Generating a SHA-1 based on time is not safe. A collision can easily be
generated, and if parallel operations are used they will eventually
collide. This reads random bytes and uses them for the SHA-1 hash. It
will return an error if the rand.Read() fails.
2020-02-04 09:10:38 +01:00
Jacob Kozol
e3d64ea1eb store: custom image size
When pushing a compose to the store an image size can be included in the
parameters.
2020-01-23 00:57:31 +01:00
Jacob Kozol
a86e697171 distro: add custom image size
When creating a pipeline the assembler includes an image size. This
image size can be set when creating the pipeline but if it is 0 then a
default image size will be used. The default is 2 GB except for ami
images which are 6 GB.
2020-01-23 00:57:31 +01:00
Tom Gundersen
fb7fb0156d store: keep our state to ourselves
Our state directory can contain credentials, so do not allow access
to anyone else.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-01-03 22:35:52 +01:00
Ondřej Budai
665a7d81a8 api: return actual logs in /compose/logs
Commit b1c5ef2a introduced support for retrieving logs from osbuild.
This commit finishes the second part - actually returning the logs
from /compose/logs route.
2019-12-20 11:43:39 +01:00
Ondřej Budai
afe515fd4f store: clean up method order 2019-12-20 11:43:39 +01:00
Tom Gundersen
0ef89aa864 store: fix compose state handling on restart
When restarting composer, we were not handling the compose states
correctly.

This resolves that as follows:
 * any running composes are marked as failed,
 * any waiting composes are put back in the pending jobs queue

As a consequence of needing the ability to reinitialize the job
queue, we must include the depsolved pipeline in the compose object.
This is the correct thing to do, as the semantics we currently
adhere to is that pipelines are depsolved when the compose is
started (and restarting composer should not affect this by for
instance re-depsolve the pipeline).

Resolves rhbz#1784062.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-12-17 21:49:11 +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
305b2dda5c rpmmd: add IgnoreSSL key to RepoConfig
This is the opposite of dnf.conf's `sslverify`, because go's default for
booleans is always false. This is error prone: we'd like to default to
true.
2019-12-12 01:27:04 +00: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
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
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
6bbc89d5f3 api: implement /compose/delete route 2019-12-10 01:14:36 +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
24faab8c18 store: clean up blueprint API
Prior to this commit blueprint getters looked like C-style API with output
parameters. This commit refactors them to more conventional multiple return
values API.
2019-12-05 13:08:50 +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
94bfcc518c weldr: bump blueprint version
According to the same rules as lorax-compposer:

  https://weldr.io/lorax/lorax-composer.html#blueprints
2019-12-04 18:35:18 +01:00
Ondřej Budai
f4991cb1ca api: Add support for upload API
This commit introduces basic support for upload API. Currently, all the routes
required by cockpit-composer are supported (except for /compose/log).

Also, ComposeEntry struct is moved outside of the store package. I decided
to do it because it isn't connected in any way to store, it's more connected
to API. Due to this move there's currently a known bug that image size is
not returned. This should be solved by moving Image struct inside Compose
struct by follow-up PR.
2019-12-01 00:05:17 +01:00
Ondřej Budai
268befa435 store: make ListQueue return value more predictable by sorting it
The return value hasn't been predictable prior to this commit. This is
probably caused by internal implementation of Golang map. This commit
fixes it by sorting the output.
2019-12-01 00:05:17 +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
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
e98b189b82 targets: add dummy azure and aws targets
These are not currently implemented in the backend, but shows how
the API will look like.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-11-25 07:53:50 +01:00
Lars Karlitski
d06a39bd51 weldr: move RepoConfig → SourceConfig conversion to store
This puts it aside the already existing SourceConfig → RepoConfig
conversion and makes `sourceInfoHandler` a bit easier to parse.
2019-11-18 12:22:10 +01:00
Lars Karlitski
740e4da733 rpmmd: move SourceToRepo to store
This removes the `store` dependency from `rpmmd`, which is the more
generic package.

It's also nicer to have this on a method of `SourceConfig`.
2019-11-18 12:22:10 +01:00
Jacob Kozol
1b46a83522 store: add getBlueprintChange update blueprint commit message
Add function to get a single blueprint change given the blueprint name
and the commit hash. Update the PushBlueprint function to allow a commit
message to be passed to it which will be used when adding a change.
2019-11-14 20:36:17 +01:00
Jacob Kozol
080bd4968c store: add function to get blueprint changes
For a given blueprint name the store returns a list of the changes made
to that blueprint.
2019-11-13 14:51:06 +01:00
Jacob Kozol
7d2650a2e3 store: add blueprint changes
When a blueprint is pushed to the store it will also add a change to the
BlueprintChanges map. Each blueprint has a list of changes mapped to
their commit. This commmit is a hex string based off of the sha1 hash of
the current time so every commit is unique. The message and timestamp
follow the format of lorax-composer.
2019-11-13 14:51:06 +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
Jacob Kozol
29ebb9ff51 store: add sources to store
The api is initialized with a base repo but users may want to add their
own custom repos. Based on lorax's implementation, the store now
supports sources. The source object is similar to but not the same as
the repos used by dnf. The store can now add, delete, and get info about
sources.
2019-11-06 21:40:31 +00:00
Ondřej Budai
0feb4e4d44 api: improve error handling when compose push fails
There was missing condition for the case when compose push fails.
As the previous commit introduces customizations which can return even more
errors it is important to report such errors.

For now the API is returning only 500 HTTP code. In future we should
distinguish between failures and blueprint validation errors.
2019-11-02 14:10:13 +01:00
Ondřej Budai
93e7a26785 blueprint: fix groups definition
Group has no version field, remove it.
2019-10-31 21:49:09 +01:00
Jacob Kozol
4366e390cf store: add image size to compose status response
All composes now include the image size in their status response. The
image size will be 0 except for finished composes where it will be the
file length in bytes.
2019-10-28 02:02:16 +01:00
Jacob Kozol
4d94207488 store: update Image to include size
Alongside File, Name, and Mime type, each Image in the store will
contain the image size. This will default to 0 unless the compose's
status is FINISHED. Then, it  will be the length in bytes of the file.
2019-10-28 02:02:16 +01:00
Jacob Kozol
320eaf4b0c store: update ComposeEntry to include version and type
Each compose now includes the blueprint version and compose type it is
based off of.
2019-10-28 02:02:16 +01:00
Tom Gundersen
f055ba2e07 store: change semantics of queue states
A job is now in "WAITING" state exactly when it is in the channel,
once it is popped it enters "RUNNING" state. It is only possible
to update the state of a job that is in the running state.

This mean that updating to "RUNNING" is entirely optional, but in
the future we may want to use this as a watchdog logic, and require
the worker to update at regular intervals to avoid being restarted.

The job queue API is updated to require a POST followed by one
or several PATCH messages to the returned ID. If a patch is sent
to an ID before the POST it is as if the object does not exist
(regarldess of it being in the queue in WAITING state or not).

Once a job has been POSTed it can be PATCHed to update it zero or
more times with (still) RUNNING before exactly oncee with either
FINISHED or FAILED.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-25 10:18:47 +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
4845826048 blueprint: add proper error handling for querying invalid output types
Otherwise an invalid output type would crash composer.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-08 21:03:45 +02:00
Tom Gundersen
94e1e6f42b store: add error types and rudimentary error handling
This will allow us to better distinguish between different error
conditions in the API.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +02:00
Tom Gundersen
2e4063c78b job: drop the job package
This was only used internally in the store package, so moved the
one type that was still used and remove the rest.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2019-10-07 10:37:43 +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
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