Commit graph

43 commits

Author SHA1 Message Date
Achilleas Koutsou
a2c4622930 kojiapi: Check job type when retrieving from queue
When a job's arguments are retrieved (for the /manifests API endpoint),
the incoming ID should correspond to a Finalize Job.  The new
worker.Job() method helps us verify the type and produce an error if the
wrong type is found.
Similarly, the dependencies of a Finalize Job should be in order (Init
Job first followed by Build Jobs).  The types are validated while
iterating the dependency list.

Added convenience functions that check the retrieved job type and return
the initialised struct or an error if the ID is not found or does not
match the type.

Currently the getInitJob() function isn't used but it will be useful
later.
2021-01-19 10:37:51 +01:00
Achilleas Koutsou
668fb003ef jobqueue: Replace JobArgs() with Job()
JobArgs() function replaced with more general Job() function that
returns all the parameters used to originally define a job during
Enqueue(). This new function enables access to the type of a job in the
queue, which wasn't available until now (except when Dequeueing).
2021-01-19 10:37:51 +01:00
Achilleas Koutsou
75a96bd99d test: Job args/manifests retrieval
1. Test retrieving the job arguments from the worker using an
   OSBuildJob.
   Very basic test with an empty manifest.
2. Test retrieving job manifests through the Koji API. Uses the existing
   TestCompose test. The returned manifests are empty for all cases.
2021-01-16 13:39:30 +01:00
Achilleas Koutsou
8f4c72b0a3 kojiapi: Fix common typo in comments 2021-01-16 13:39:30 +01:00
Achilleas Koutsou
7ec084fa56 kojiapi: Add endpoint for retrieving job manifest
Add and implement an API endpoint that returns the manifests for a given
osbuild-koji job. The route returns an array of manifests, one for each
image in the request.

Retrieves the arguments of each Build Job to extract the Manifest.
2021-01-16 13:39:30 +01:00
Lars Karlitski
90e15da032 kojiapi/test: use the worker of the fixture
No need to create a second one.
2021-01-12 12:19:25 +01:00
Jacob Kozol
da6f5ba701 kojiapi,cloudapi: exclude packages when depsolving
When rpmmd's Depsolve function is called we need to pass in the image
type's excluded packages. These excluded packages are retrieved when we
get the packages we include from each image type.
2021-01-06 21:34:37 +01:00
Ondřej Budai
1dd4eb7e38 composer: seed the random number generator
I thought rand in Go is auto-seeded but I was wrong, see [1].
This commit adds seed initialization.

[1]: https://golang.org/pkg/math/rand/#Seed

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-12-15 21:26:40 +01:00
Ondřej Budai
973639d372 distro/rhel84: use a random uuid for XFS partition
Imagine this situation: You have a RHEL system booted from an image produced
by osbuild-composer. On this system, you want to use osbuild-composer to
create another image of RHEL.

However, there's currently something funny with partitions:

All RHEL images built by osbuild-composer contain a root xfs partition. The
interesting bit is that they all share the same xfs partition UUID. This might
sound like a good thing for reproducibility but it has a quirk.

The issue appears when osbuild runs the qemu assembler: it needs to mount all
partitions of the future image to copy the OS tree into it.

Imagine that osbuild-composer is running on a system booted from an imaged
produced by osbuild-composer. This means that its root xfs partition has this
uuid:

efe8afea-c0a8-45dc-8e6e-499279f6fa5d

When osbuild-composer builds an image on this system, it runs osbuild that
runs the qemu assembler at some point. As I said previously, it will mount
all partitions of the future image. That means that it will also try to
mount the root xfs partition with this uuid:

efe8afea-c0a8-45dc-8e6e-499279f6fa5d

Do you remember this one? Yeah, it's the same one as before. However, the xfs
kernel driver doesn't like that. It contains a global table[1] of all xfs
partitions that forbids to mount 2 xfs partitions with the same uuid.

I mean... uuids are meant to be unique, right?

This commit changes the way we build RHEL 8.4 images: Each one now has a
unique uuid. It's now literally a unique universally unique identifier. haha

[1]: a349e4c659/fs/xfs/xfs_mount.c (L51)
2020-12-15 16:43:39 +01:00
Ondřej Budai
3d465a4778 api/koji: invert the compose status condition
This is just easier to grasp.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-12-02 10:27:31 +01:00
Ondřej Budai
00cd4cb346 api/koji: return pending status until all jobs are finished
Previously, the compose status returned failure as soon as possible.
koji-osbuild considers the job as done when its status == failure and proceeds
with uploading the logs to koji and marking the job as failed. However, not
all osbuild-composer jobs might be done at this point so the logs might be
incomplete making the debugging hard.

This commit changes the behaviour: Now, the compose status is pending until
ALL jobs belonging to it are finished.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-12-02 10:27:31 +01:00
Ondřej Budai
e10a7f1ccc {koji,worker}/server: log errors returned from handlers
Previously, we had no clue what errors were catched by the default echo's
error handler. Thus, in the case of an error, we were basically blind. Let's
log all errors so we can investigate them later.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-12-02 08:52:27 +01:00
Ondřej Budai
978e309153 worker/server: move it to the style of koji server
The previous code was smelling a bit (e.g. Server.server field) so I decided
to rewrite it in the style of the much nicer koji server.

Not a functional change.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-11-19 17:39:24 +00:00
Tom Gundersen
bf86e8ad79 workerapi: serialize koji errors as strings
Serializing an interface does not work, let us simply use the string
representation and treat the empty string as no error. This is
compatible with the current API in the success case, and fixes the
error case, which is currently broken.

Also extend the test matrix for the kojiapi to ensure that all the
different kinds of errors can be serialized correctly and leads to
the correct status being returned.

Fixes #1079 and #1080.
2020-11-13 09:39:55 +01:00
Ondřej Budai
a6df2877a3 fsjobqueue: accept jobs of any type
Soon, we want to begin tagging the jobs with the name of its submitter.
The simplest way to add a tag to a job is to put it into its type string.
However, as we don't know (and don't want to know) the submitters' names when
osbuild-composer is initialized, we need to be able to push arbitrary job
types into the jobqueue.

This commit therefore lifts the restriction that a jobqueue accepts only
a predefined set of job types. Now, jobqueue clients can push jobs of
arbitrary names.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-11-12 15:30:30 +00:00
Tom Gundersen
f9af1e3e13 kojiapi/logs: adjust for multi-build composes
Return the full array of image build logs, as well as logs for the
init and import tasks.
2020-11-11 18:16:42 +01:00
Tom Gundersen
a99127aed9 kojiapi: add basic test
This test schedules a compose, pops the jobs off the queue, marks each
as done and verifies that the compose is correctly marked as successful.
2020-11-11 18:16:42 +01:00
Tom Gundersen
5dac422b9c cmd/composer: drop koji configuration
Now that all interaciton with the koji API happens in the workers
we can drop koji configuration from composer itself. This means
that composer no longer needs to be provisioned with kerberos
credentials, and does not need to know about which koji servers
the workers support.
2020-11-11 18:16:42 +01:00
Tom Gundersen
654daf96c1 kojiapi: return BuildID from status route
This is no longer returned when creating a compose, as it is obtained
asynchronously.

The TaskID is still returned, and is always set to 0. This is not right,
and should either be fixed or dropped. The caller should know the TaskID
(if they have one), so this is redundant and currently unused.
2020-11-11 18:16:42 +01:00
Tom Gundersen
9adae8a3a7 kojiapi: support multi-build composes
This removes the restriction of only having a single build per compose
and uses the new job types to schedule the broken-appart build.

A small change in behavior is introduced: the koji build ID is not
known when the call to `compose` returns, so it is always set to
`0`. In the future we should remove this from the API, and instead
rely on the status call to return this information, when it is
known.

The status route will be updated in follow-up commits to reflect the
changes introduced here.
2020-11-11 18:16:42 +01:00
Tom Gundersen
98fd290a08 worker: make Enqueue() specific for each job type
Most of the worker API is now untyped, but keep Enqueu() typed to
ensure the job objects match the names in the queue. This means we
must add a version of Enqueue() for each job type we support.
2020-11-11 18:16:42 +01:00
Lars Karlitski
e47b44329e kojiapi: expose logs on the API
Add an API route that returns logs for a specific compose.

For now, this contains the result of the job, in JSON. The idea is to
put more and more of this information into structured APIs. This is a
first step to make logs available at all.

Amend koji-compose.py to check that the route exist and contains as many
"image_logs" as images that were requested (currently always 1).

Based on a patch by Chloe Kaubisch <chloe.kaubisch@gmail.com>.
2020-11-10 16:23:49 +01:00
Chloe Kaubisch
263f8d6360 koji: add tests
Add some simple tests to ensure invalid routes
and bad requests are handled.
2020-11-10 16:23:49 +01:00
Lars Karlitski
59e73a686a worker: generalize job types in the server
The worker server was heavily tied to OSBuildJob(Result). Untie it so
that it can deal with different job types in the future.

This necessitates a change in the jobqueue: Dequeue() now returns the
job type, as well as job arguments as json.RawMessage. This is so that
the server can wait on multiple job types with different argument
types.

The weldr, composer, and koji APIs continue to use only "osbuild" jobs.
2020-11-09 14:17:19 +01:00
Lars Karlitski
299a5e52ab worker: use OSBuildJobResult consistently
Workers reported status via an `osbuild.Result`, which only includes
osbuild output. Make it report OSBuildJobResult instead, which was meant
to be used for this purpose and is already used as the result type in
the jobqueue.

While at it, add any errors produced by targets into this struct, as
well as an overall success flag.

Note that this breaks older workers returning the result of an osbuild
job to a new composer. I think this is fine in this case, for two
reasons:

1. We don't support running different versions of the worker and
composer in the weldr API, and remote workers aren't widely used yet.

2. Both osbuild.Result and worker.OSBuildJobResult have a top-level
`Success` boolean. Thus, logs are lost in such cases, but the overall
status of the compose is not.
2020-11-09 14:17:19 +01:00
Lars Karlitski
0cd7174598 worker: deprecate the local target
Add "image_name" and "stream_optimized" fields to the osbuild job as
replacement for the local target options. The former signifies the name
of the uploaded artifact and whether an artifact should be uploaded at
all (only weldr API). The latter will be deprecated at some point, when
osbuild itself can make streamoptimized vmdk images.

This change separates what have always been two distinct concepts:
artifacts that are reported back to the composer node (in practice
always running on the same machine), and upload targets to clouds and
such. Separating them makes it easier to add job types that only allow
one upload target while keeping artifacts.

Keep the local target around, so that jobs that are scheduled can still
be run after an upgrade.
2020-11-09 14:17:19 +01:00
Lars Karlitski
7441012e62 kojiapi: don't rely on common.State
This is similar to the previous commit, which did this change in
package cloudapi.

Use constants instead of string literals for compose status, and derive
the status from worker.JobStatus directly, instead of via common.State.
2020-11-09 14:17:19 +01:00
Ondřej Budai
befeef34a5 koji: use nvra as the filename for images
We have the same thing for AWS. The AWS target also specifies under what name
should be the image available in EC2.

As requested by Brew maintainers Tomáš Kopeček and Lubomír Sedlář.
2020-10-27 19:01:30 +00:00
Lars Karlitski
b25a350502 osbuild-composer: merge cloud API into main binary
This removes the osbuild-composer-cloud package, binary, systemd units,
the (unused) test binary, and the (only-run-on-RHEL) test in aws.sh.

Instead, move the cloud API into the main package, using the same
socket as the koji API, osbuild-composer-api.socket. Expose it next to
the koji API on route `/api/composer/v1`.

This is a backwards incompatible change, but only of the -cloud parts,
which have been marked as subject to change.
2020-10-16 09:37:04 +02:00
Lars Karlitski
d7bff4bd3b kojiapi: add simple test for the /status API
Add a simple unit test for the koji API.

This adds a Handler() method to the koji.Server struct, which made
writing the test easier. This is a direction we want to go in anyway in
the future.
2020-10-13 18:52:44 +02:00
Ondřej Budai
9fc924fbf4 kojiapi: make repo gpgkey optional
The kojiapi actually shouldn't require it as we need to build images from
unsigned packages.

Fixes #985
2020-10-13 08:10:22 +02:00
Lars Karlitski
40d8440660 kojiapi: prefix all routes with /api/composer-koji/v1
The cloud API will be moved to `/api/composer/v1` in the future.

Mention this in the `servers` section of the openapi.yml (relative URLs
are allowed) too, even though our generator does not consider it.
2020-09-24 21:08:56 +01:00
Lars Karlitski
9008a1defc worker: require workers to pass their architecture
Jobs are scheduled with type "osbuild:{arch}", to ensure that workers
only get jobs with the right architecture assigned.
2020-09-23 14:28:52 +01:00
Ondřej Budai
c6b5dd8977 kojiapi: add /status route
It works the same way as in the worker API. It's very handy when we just want
to test whether the API is up and running.
2020-09-23 11:08:21 +01:00
Ondřej Budai
03768e5f18 api/worker, koji: fix race condition when using multiple listeners
When remote worker socket was enabled, this was happening:

e := echo.New()

go func() {
    e.Listener = listener1
    e.Start("")
}()

e.Listener = listener2
e.Start("")

Yeah, this is a race condition. None of the echo's Start methods cannot safely
handle multiple listeners.

This commit fixes this issue by using Echo only as a router for standard
http.Server which handles multiple listeners in a non-racy way.
2020-09-23 09:38:29 +02:00
Tom Gundersen
6bab73f378 kojiapi: move from chi to echo
Follow the worker API so we standardise on one library. This simplifies
the code quite a bit.

No functional change.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-09-21 11:18:45 +01:00
Tom Gundersen
504a5890d9 kojiapi: move api definition
Move the API definition into a sub-directory to follow the style
of the worker API.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-09-21 11:18:45 +01:00
Tom Gundersen
c6cf9de85d koji: add config files to configure kerberos settings
Kerberos keytabs and principals are configured per koji server both in
composer and in the worker.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-09-16 00:15:02 +01:00
Tom Gundersen
e52830f530 upload/koji: don't pass task_id to cg_init_build
Contrary to our assumption, we cannot initialize the build with the
link to the task. We can only update the link once the build has
completed.

This seems like a bug in koji, but we keep it like this for now.
2020-09-16 00:15:02 +01:00
Tom Gundersen
f446613d4a upload/koji: use CGInitBuild and clarify metadata structs
Move to requiring CGInitBuild to be called before CGImport. In the
future we could make the former optional again, but for now we want to
allow the caller to have done CGInitBuild and for composer only to do
the CGImport using the passed in build_id and token.

Also rename and document some struct fields in the metadata struct to
make them more specific to our use-case and hopefully easier to read.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-09-16 00:15:02 +01:00
Ondřej Budai
e4b839b31f kojiapi: add koji target to composes
So far, composes created by kojiapi didn't have any targets. This commit
adds the koji target to them.

This is the last piece of the puzzle. From now on, osbuild-composer has
a koji API, which is actually able to upload images to Koji! Yay!
2020-09-16 00:15:02 +01:00
Tom Gundersen
67e4182ba4 kojiapi: add a server/client implementation of the OpenAPI spec
This just translates between the OpenAPI spec and our internal
API.

This still lacks tests, but a follow-up commit adds integration tests.

`internal/kojiapi/openapi.gen.go` was automatically generated from
`internal/kojiapi/openapi.yml`. To regenerate use `go generate ./...`.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-09-16 00:15:02 +01:00
Tom Gundersen
7109f49692 kojiapi: add OpenAPI spec
This adds the OpenAPI spec for the new composer-koji API. This API is meant
to expose expose just the functionality needed to generate images and push
them to koji.

Each compose may consist of several images, each image may have a
different architecture and image type, and the set of repositories with
their contents may be distinct. However, a compose is restricted to one
distro and one koji transaction.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-09-16 00:15:02 +01:00