Commit graph

123 commits

Author SHA1 Message Date
Lars Karlitski
9c2c92f729 jobqueue: Introduce jobqueue backed by a postgres database
Co-authored-by: sanne <sanne.raymaekers@gmail.com>
2021-07-28 21:52:31 +01:00
Lars Karlitski
871c6e9cbb fsjobqueue: make canceling a finished job an error
This mirrors FinishJob(), which also errors when the job is already
finished.
2021-07-28 21:52:31 +01:00
Lars Karlitski
30492bfc60 jobqueue: move fsjobqueue's generic tests into new package
fsjobqueue_test contained tests that are generically testing the
JobQueue interface. Split those out into its own package `jobqueuetest`.

These tests will be useful when implementing a new package that conforms
to the JobQueue interface.
2021-07-28 21:52:31 +01:00
sanne
4385c39d66 worker: Introduce heartbeats
An occupied worker checks about every 15 seconds if it's current job was
cancelled. Use this to introduce a heartbeat mechanism, where if
composer hasn't heard from the worker in 2 minutes, the job times out
and is set to fail.
2021-07-08 21:14:38 +01:00
sanne
0fcb44e617 worker: Move job tokens to the queue itself
This removes state from the worker server, as it no longer contains the
list of running jobs. Instead only the queue knows if jobs are running
or not.
2021-07-08 21:14:38 +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
6967333759 jobqueue: Add JobArgs() method
JobArgs() returns the arguments submitted with a job in raw form.
Since the structure of the args are opaque to job queue, it's the
responsibility of the caller to deserialize the arguments.

Args retrieval is added to the existing TestArgs() function.
2021-01-16 13:39:30 +01:00
Lars Karlitski
cb894ccf68 jobqueue: remove testjobqueue
testjobqueue did not implement the JobQueue interface correctly (noted
in its package comment), making it impossible to write tests for
JobQueue itself.

Replace its use everywhere with fsjobqueue operating on a temporary
directory.
2021-01-12 12:19:25 +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
Ondřej Budai
e007f9964e fsjobqueue: extract channelSize constant 2020-11-12 15:30:30 +00:00
Tom Gundersen
c777a18df0 jobqueue: expose dependencies when querying status
The status of a job may depend on the status of its dependenices,
as we do not repeat for instance the failed state in each dependent
job.

Return also the list of dependencies so these can be queried too.
2020-11-11 18:16:42 +01:00
Tom Gundersen
11d0da0b5c jobqueue/JobStatus: return result as json.RawMessage
Similarly to the recent changes to Dequeue(), let the caller unmarshal the
return JSON. This allows us to pass the result on without being able
to unmarshal it.

In follow-up patches, we will pass results of jobs to dependent jobs,
but the worker API does not know about the different job types, nor how
to unmarshal them.
2020-11-11 18:16:42 +01:00
Tom Gundersen
e277501ca3 jobqueue: return dependencies on dequeue
Once a job has been enqueued, there is no way to query its dependencies.

This makes dequeue more symmetric to enqueue by returning the
dependencies that were passed to enqueue, allowing the caller to
query the dependencies and their results.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-11-11 18:16:42 +01:00
Tom Gundersen
e72b14bdd1 jobqueue: do not sort dependencies
While dependencies are purely internal, sorting and pruning them is a
reasonable optimization. However, we wish to expose them in follow-up
commits and then we want them to remain unchanged from the input.

Nothing in the internal logic seems to rely on the fact the dependencies
were sorted.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-11-11 18:16:42 +01:00
Tom Gundersen
f355bdd426 testjobqueue: initialize dependants map
Adding to a nil map leads to panic. We must ensure that all maps are
initialized before use.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-11-11 18:16:42 +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
27e8e4b5d5 jobqueue: allow canceling jobs
This is not exposed to a worker yet. It will continue the job and get an
error when it tries to update the job's status to finished.
2020-05-13 16:45:09 +02:00
Lars Karlitski
b795ca25a2 fsjobqueue: remove unnecessary variable declaration 2020-05-13 16:45:09 +02:00
Lars Karlitski
8df143fabe fsjobqueue: pass accepted job types to New()
This makes the queue more type safe and allows to get rid of the
`pendingChannel` and `pendingChannels` helpers, which only existed to
create not-yet-existing pending channels.
2020-05-13 16:45:09 +02:00
Lars Karlitski
3240f11647 fsjobqueue: factor common functionality into maybeEnqueue() 2020-05-13 16:45:09 +02:00
Lars Karlitski
e599a95067 fsjobqueue: use a single mutex to protect all fields
In addition, it protects that all public functions operate on `db`
in transactions.
2020-05-13 16:45:09 +02:00
Lars Karlitski
e03c1fff65 fsjobqueue: factor reflect.Select out of Dequeue()
Hopefully this make it easier to read.
2020-05-13 16:45:09 +02:00
Lars Karlitski
6773c01722 jobqueue: drop JobStatus type
The enum is redundant information that can be deduced from the job's
times: queuedAt, startedAt, and finishedAt. Not having it reduces the
potential for inconsistent state.
2020-05-13 16:45:09 +02:00
Lars Karlitski
e1805d5f62 fsjobqueue: only update dependants when necessary
This is the same as the code in Enqueue(). There is no need to add a job
to q.dependants if all of its dependencies have finished.
2020-05-13 16:45:09 +02:00
Lars Karlitski
459181a650 fsjobqueue: fix spelling errors and json field names 2020-05-13 16:45:09 +02:00
Lars Karlitski
dde3d459f5 Add jobqueue package
Now that the "old" `jobqueue` package was renamed to `worker`, add a new
package that contains an interface to an actual job queue. Also add two
implementations: fsjobqueue, a job queue backed by the file system, and
testjobqueue, which can be used as a mock implementation for testing.

These packages are not yet used.
2020-05-08 14:53:00 +02:00
Lars Karlitski
ac40b0e73b jobqueue: rename to worker
This package does not contain an actual queue, but a server and client
implementation for osbuild's worker API. Name it accordingly.

The queue is in package `store` right now, but about to be split off.
This rename makes the `jobqueue` name free for that effort.
2020-04-16 01:02:16 +02:00
Lars Karlitski
8ef4db816d jobqueue/api: return errors as JSON
The API is always advertising a content type of application/json, but
not sending JSON on errors.

Change it to send simple JSON objects like this:

    { "message": "something went wrong" }

This can be extended to include more structured information in the
future.

Also return an (for now) empty JSON object from `addJobHandler()`. It
returned nothing before, which is invalid JSON.

Stop testing for the actual error strings in `api_test.go`. These are
meant for humans and can change. Only check what a client could
meaningfully check for, which is only the HTTP status code right now.
2020-04-06 19:51:36 +02:00
Lars Karlitski
ce6d3c511a jobqueue/api: don't panic when error cannot be returned
Don't panic when the error message cannot be written to the connection.
Ignore it, because there's nothing we can do in this case. The standard
library has the same behavior.
2020-04-06 19:51:36 +02:00
Lars Karlitski
2ac76602bb jobqueue/api: add additional test cases 2020-04-06 19:51:36 +02:00
Lars Karlitski
6083eb3867 jobqueue/api: don't redundantly set 200 OK
This wasn't done in all cases and is redundant, because the default
status is 200 OK.
2020-04-06 19:51:36 +02:00
Lars Karlitski
4cc459c5cc jobqueue: move remaining request struct to json.go 2020-04-06 19:51:36 +02:00
Lars Karlitski
ada058f2c3 jobqueue: move Job struct to client.go
`Job` is now a simple data struct, which is only used to return
multiple arguments from `AddJob()`. Move it to that file.
2020-04-06 12:11:54 +02:00
Lars Karlitski
1ece08414c jobqueue: move Job.Run() to the worker
This makes the jobqueue package independent of forking osbuild, the
choices for which (exact invocation, location of the cache directory)
should be made in the worker.
2020-04-06 12:11:54 +02:00
Lars Karlitski
54b63a645f jobqueue: remove JSON tags on Job
Job is not used for serialization anymore.
2020-04-06 12:11:54 +02:00
Lars Karlitski
ab2c8aff08 jobqueue: make import declarations consistent
The usual style is three blocks: standard library, external
dependencies, internal dependencies.

Also run through `go fmt`, which sorts each of those blocks
alphabetically.
2020-04-06 12:11:54 +02:00
Lars Karlitski
1f06d78362 jobqueue: rename ID to ComposeID in job structs
It's not an id of the job, but the compose id.
2020-04-06 12:11:54 +02:00
Lars Karlitski
269988a737 jobqueue: start moving API types to json.go
Similar to `weldr/json.go`, this file will contain structs that are
shared between client and server and only meant to be used to
serialize from and to JSON.

This immediate change allows us to make fields in `Job` private in a
future commit.
2020-04-06 12:11:54 +02:00
Lars Karlitski
cef7267a2d store: create compose id from PushCompose
Every caller had to make their own uuid and pass that into
PushCompose(). Make PushCompose() create the id and return it.
2020-04-01 00:29:13 +02:00
Lars Karlitski
eb10cf3124 store: remove unused arguments from PushCompose 2020-04-01 00:29:13 +02:00
Lars Karlitski
b5432e78b9 worker: move ComposerClient to jobqueue package
This moves the client code into the same package as the server code,
which makes it easier to change (and version) the two in sync. Also, it
will allow to make some structs private to the jobqueue package and to
test `Client`.

Also rename it to jobqueue.Client.
2020-03-25 14:05:44 +01:00
Lars Karlitski
ad1a12f7aa tree-wide: use uuid.MustParse() when possible
According to the new guidelines in docs/errors.md.
2020-03-25 10:22:16 +01:00
Lars Karlitski
f386ae43dc jobqueue: remove Job.OutputType
It is not used. The worker does not need to know the name of the
originating output type. It has all information it needs in the
manifest.
2020-03-24 22:29:41 +01:00
Tom Gundersen
d7aad58897 store/PushCompose: take ImageType and Arch as argumnet rather than strings
Resolve eagerly into real objects, and avoid having to resolve and
error-check again.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-23 15:43:55 +01:00
Tom Gundersen
1345ca77fd store: drop the distro registry
This was now unused.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-22 22:26:09 +01:00
Tom Gundersen
839b22026e target: pass the image filename in each target
Rather than having to assume that we only ever produce one
artifact, have each upload target contain the filename it expects
to upload from the osbuild output.

An image file is always explicitly named in the manifest, and we
leave it up to each distro to decide how this is done, but the
convention is to use the same image filename as used when
downloading the image through weldr.

Now make this policy explicit, by quering the distro for the image
name and inserting it into each upload target.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-22 22:26:09 +01:00
Lars Karlitski
069ccba894 store: pass repos to PushCompose
Repositories were not passed down into `Distro.Manifest()`. This makes
all builds fail, because these repositories are use to access gpgkeys.
2020-03-21 11:08:16 +01:00
Lars Karlitski
1b7cb6c11b store/jobqueue: remove distro field from jobs
A job's purpose is to build an osbuild manifest and upload the results
somewhere. It should not know about which distro was used to generate
the pipeline.

Workers depended on the distro package in two ways:

1. To set an osbuild `--build-env`. This is not necessary anymore in new
   versions of osbuild. More importantly, it was wrong: it passed the
   runner from the distro that is being built, instead of one that
   matches the host.

   This patch simply removes that logic.

2. To fetch the output filename with `Distro.FilenameFromType()`. While
   that is useful, I don't think it warrants the dependency.

   This patch uses the fact that all current pipelines output exactly
   one file and uploads that. This should probably be extended in the
   future to upload all output files, or to name them explicitly in the
   upload target.

The worker should now compile to a smaller binary and do less
unnecessary work on startup (like reading repository files).
2020-03-18 12:24:20 +01:00
Lars Karlitski
0f1a014aca store: don't keep a "default" distro
Only the weldr API has the concept of a default distro. Pass that distro
explicitly to `PushCompose()` and fetch the distro from the compose in
all other functions that accessed Store.Distro.
2020-03-18 08:33:42 +01:00
Tom Gundersen
8400b39577 distro.Manifest: drop checksums parameter
This is no longer used to generate pipelines, but has been replaced
by the package specs.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-03-15 19:38:59 +01:00