Commit graph

126 commits

Author SHA1 Message Date
Martin Sehnoutka
9ba6dcec4e osbuild-worker: log unknown upload type
Make the target error a bit more useful by sending the name of unknown
upload target.
2021-03-19 15:59:57 +01:00
Martin Sehnoutka
dfa227e82f osbuild-worker: s|errored|failed| because error is a noun
Fix grammar issue.
2021-03-19 15:59:57 +01:00
Martin Sehnoutka
34d165be6c osbuild-worker: unify logging statements
The code previously used both fmt.Printf and log.Printf. Simplify this
by using log.Printf everywhere.
2021-03-19 15:59:57 +01:00
Martin Sehnoutka
a3d80cc924 osbuild-worker: simplify jobimpl osbuild code
The previous version constructed multiple temporary variables and then
create job result from them. This was needed because we had multiple
upload targets but now that we have only one, this is only fragile
version of what can be done in a simplified way.

This PR removes the temporary variables and assigns errors and success
states right after the upload or build has finished.
2021-03-19 15:59:57 +01:00
Martin Sehnoutka
3f9f8c7487 osbuild-worker: drop support for multiple upload targets
Multiple upload targets are not supported by osbuild-composer any more.
Dropping support for this in worker therefore doesn't change anything
from the user's perspective, but it allows us to simplify the code a
bit.

Replace calls to "continue" with "return nil" because the job finished
correctly even though it failed to perform the task. But the failure was
reported to osbuild-composer for further processing so there is no need
to duplicate and report the same error in worker process
2021-03-19 15:59:57 +01:00
Martin Sehnoutka
086a9270b4 osbuild-worker: drop support for local and koji target
Drop support for LocalTarget, this has not been used in a long time,
and we don't really need to stay compatible across many releases
(just as long as we don't get problems with having to deploy in
lock-step), at least not yet.

Also drop support for KojiTarget, this has been replaced by the
osbuild-koji job type.
2021-03-19 15:59:57 +01:00
Martin Sehnoutka
87942865ba osbuild-worker: refactor reporting the job status to deref
The previous implementation exited before reporting back to the worker
API in few branches. This left the compose status in RUNNING state even
though the worker did not work of the job any more. Refactoring the
API call into the `deref` part makes sure it gets called every time.

This commit only moves bits of the code around so that the status gets
back to osbuild-composer, but it still doesn't contain any useful
information in case osbuild fails etc. This will be introduced in
subsequent commits.
2021-03-19 15:59:57 +01:00
Achilleas Koutsou
12d4f82428 osbuild-worker: handle 0 and > 1 exports in job
If exports is undefined in request, add the default "assembler" for the
old image types.

If more than 1 export is requested, fail with an error.
2021-03-17 18:12:17 +00:00
Achilleas Koutsou
2cce81093f osbuld-worker: call osbuild with --export flag
osbuild now supports using the `--export` flag (can be invoked multiple
times) to request the exporting of one or more artefacts.  Omitting it
causes the build job to export nothing.

The Koji API doesn't support the new image types (yet) so it simply uses
the "assembler" name, which is the final stage of the old (v1)
Manifests.
2021-03-17 18:12:17 +00:00
Achilleas Koutsou
8090621300 osbuild: rename package to osbuild1
Preparing for version 2 of the manifest schema, which will be
implemented in a separate package (osbuild2) alongside the original.
2021-03-17 18:12:17 +00:00
Tomas Hozza
fb089cf00d GCP: Report the right error when image import fails
Fix a bug in the worker job implementation and GCP CLI upload tool,
which causes the code to report wrong error instance in case the image
import failed for some reason.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2021-03-16 15:26:17 +01:00
Tomas Hozza
e698080bc7 GCP: Set image name as custom metadata on uploaded image object
Extend StorageObjectUpload() to allow setting custom metadata on the
uploaded object.

Modify worker's osbuild job implementation and GCP CLI upload tool to
set the chosen image name as a custom metadata on the uploaded object.
This will make it possible to connect Storage objects to specific
images.

Add News entry about image name being added as metadata to uploaded GCP
Storage object as part of worker job.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2021-03-15 16:48:40 +00:00
Tomas Hozza
075373a51e internal: Move GCP library to internal/cloud
The internal GCP library was originally placed into `internal/upload`
directory, since its purpose was mainly to upload and import built
images to GCP.

Functionality for other cloud-provider-specific libraries is broader,
however scattered around the `internal/` directory based on purpose (e.g. in
`internal/boot` and `internal/upload`). Since all parts of provider-specific
library usually share some common pieces (e.g. authentication), it makes
sense to consolidate them into a single package (e.g. in
`internal/cloud/<provider>`).

Create `internal/cloud` directory, where all cloud-provider-specific
internal libraries should be consolidated. Start with GCP.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2021-03-15 16:48:40 +00:00
Tomas Hozza
7e6adec695 worker: refactor handling of GCP credentials
Make the handling of GCP credentials more consistent with what is being
done e.g. for Azure. Make the GCP section in worker's configuration a
pointer so that it does not show up in the printed worker's
configuration during start up if it was not specified in the actual
configuration file.

Load the GCP credentials file, if provided, during the worker start up to
prevent failure later on while processing a job with GCP upload target.
Pass the loaded GCP credentials as []byte to the OSBuildJobImpl.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2021-03-12 12:17:02 +01:00
Tomas Hozza
bbae190e99 worker: share GCP image only if the accounts list is not empty
Modify worker's job implementation to try to share GCP image only if the
provided list of accounts is not empty.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2021-03-12 12:17:02 +01:00
Tomas Hozza
7de2011beb GCP: refactor logging and storage cleanup
Originally, the internal GCP library in `internal/upload/gcp` was
logging various information and errors. Refactor the code to move all
logging to callers of the library. As a result, some methods now return
additional information to preserve the same amount of information being
logged for GCP.

Refactor methods to have only single purpose and not do any extra work,
such as storage cleanup. Methods which create new resources now don't do
any cleanup at all. The caller is responsible to check for any errors
and perform any cleanup necessary. Necessary methods to perform cleanup
are provided.

Modify worker's job implementation and GCP CLI tool to explicitly do all
necessary cleanup, including in case of errors.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2021-03-12 12:17:02 +01:00
Ondřej Budai
d9cd9f228f worker: log target errors
This should make debugging of target uploads so much easier.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2021-03-08 18:22:27 +01:00
Tom Gundersen
b062d1070d worker/jobimpl-osbuild/azure: set storage account
This was lost in a refactor.
2021-03-06 15:40:48 +00:00
Ondřej Budai
2e39d629a9 worker: add azure image upload target
This commit adds and implements org.osbuild.azure.image target.

Let's talk about the already implemented org.osbuild.azure target firstly:
The purpose of this target is to authenticate using the Azure Storage
credentials and upload the image file as a Page Blob. Page Blob is basically
an object in storage and it cannot be directly used to launch a VM. To achieve
that, you need to define an actual Azure Image with the Page Blob attached.

For the cloud API, we would like to create an actual Azure Image that is
immediately available for new VMs. The new target accomplishes it.
To achieve this, it must use a different authentication method: Azure OAuth.
The other important difference is that currently, the credentials are stored
on the worker and not in target options. This should lead to better security
because we don't send the credentials over network. In the future, we would
like to have credential-less setup using workers in Azure with the right
IAM policies applied but this requires more investigation and is not
implemented in this commit.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2021-03-06 15:40:48 +00:00
Ondřej Budai
4f66ab5d7c upload/azure: rename Image to PageBlob
The UploadImage method doesn't actually create an image. It creates a Page
Blob. Blob is something like S3 object but in the Azure terminology. Page
Blob means that's optimized for random access and it's the only blob type
that can be used to create images.

This commit cleans up the terminology so it's less confusing.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2021-03-06 15:40:48 +00:00
Ondřej Budai
478f69e092 upload/azure: move UploadImage under a new StorageClient struct
We will soon introduce new methods to the storage client.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2021-03-06 15:40:48 +00:00
Tomas Hozza
319400c280 cloudapi: implement GCP target results and include UploadOptions
Return GCP-specific target results form the worker, similar as it is
done for AWS.

Extend Cloud API to allow GCP-specific upload Options.

Modify Cloud API to return UploadOptions as part of the UploadStatus.

Modify Cloud API integration test to check returned upload Options and
upload Type.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2021-03-04 15:44:04 +01:00
Chloe Kaubisch
f091af55d8 cloudapi: add targetresults
Add the TargetResult struct to OSBuildJobResult. Include the 'options'
interface on TargetResult to contain target-specific information,
for example amiID and region from AWS. Expose 'options' on a status
call as an UploadStatus field. Add logic to support AWS within this
format, which can be used as a template for other targets.
2021-03-02 13:22:11 +01:00
Tomas Hozza
94d399f010 cloudapi: Add support for GCP as upload target
Add support for GCP as an upload target to the internal API.

Extend the cloudapi to allow GCP as an upload target in the compose
request. Regenerate the cloudapi go code. Added GCP-specific upload
result component in the API definition, similar to AWS. It is not yet
used, but it will be once returning a target-specific result from
worker is supported.

Add support for GCP upload target to the worker job implementation.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2021-02-25 18:44:21 +00:00
Tom Gundersen
f0b7cc0973 worker: keep output directory in /var/cache
Let's keep this on the same filesystem as the osbuild store, and
in particular stay away from /var/tmp and its scary semantics.

We are not aware of any issues caused by /var/tmp, but getting
rid of it means we don't have to think about that when debugging,
if nothing else.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2021-02-20 14:53:49 +01:00
Jozef Mikovic
5a9d2fe8b1 test: Add integration test for VMWare upload 2021-02-16 19:06:01 +00:00
Jozef Mikovic
0597ac48a7 upload/vmware: document uploadImage function 2021-02-16 19:06:01 +00:00
Jozef Mikovic
d497bc3b83 osbuild-worker: ensure that uploaded vmdk image has the user specified name
VMDK image has default name 'disk.vmdk' and there is no option to change the name when uploading to vSphere,
so I'm using symlink so that uploaded image has the name user specified instead of the default one.
2021-02-16 19:06:01 +00:00
Jozef Mikovic
08cfc08805 weldr: add vmware upload target to api
Extend Weldr API to allow user to specify option to upload built image to VMWare,
makes use of previously define upload target.
2021-02-16 19:06:01 +00:00
Jozef Mikovic
1a81489ef1 osbuild-worker: add target for upload to vmware
New upload target for VMWare, similar to the ones for AWS and Azure,
allowing users to set credentials for their vSphere instance.
Commit also includes function that performs the actual upload.
2021-02-16 19:06:01 +00:00
Chloe Kaubisch
899d78f7e1
cloudapi: expose upload status
Expose a more detailed job status result - specifically, include upload status
alongside image status. Expand openapi.yml accordingly and add an UploadStatus
field to the OSBuildJobResult struct. At the moment, only represent the
"success" and "failure" states of UploadStatus - to differentiate between
"pending" and "running" would involve significant design decisions and should be
addressed in a separate commit.
2021-02-05 12:34:28 +01:00
Ondřej Budai
4548923a09 upload/aws: fix architecture for aarch64 images
Previously, composer wrongly set x86_64 architecture even for aarch64 images.
This commit fixes it.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-12-01 08:27:44 +01:00
Sanne Raymaekers
22c9f6af61 cloudapi: Share an ec2 snapshot/ami with an account 2020-11-26 13:08:18 +00:00
Ondřej Budai
69e7883421 worker/koji-finalize: check the dependencies early
Previously, the checks that dependencies were successful were all over the
Run() method. This led to a issue #1101 (lovely binary number btw).

This commit rewrites the Run() method to:

1) Extract dynamic args. Return an error if they cannot be unmarshalled.
2) Check if dependencies were successful. If not, call kojiFail, update the
   job and return.
3) Create the CGImport metadata and call kojiImport.

Fixes #1101

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-11-25 22:24:22 +00:00
Ondřej Budai
2070800244 worker/osbuild: print raw osbuild output if it cannot be parsed
osbuild output should be always JSON-parsable. However, if a user has a weird
installation of osbuild, it can return malformed JSON. In this case, it's
very hard to debug what happened because the worker doesn't provide any
useful information. This commit adds the non-parsable osbuild output to the
error so there's at least some clue in the logs what happened.

Let me reiterate: In 99% these cases, this shouldn't be needed. It will give
us some hints in these 1% cases though.

You may want to ask if using json.Decoder isn't better because it doesn't
buffer the input. However, it does buffer. Firstly, json.Decoder.Decode()
buffers the whole JSON value (it contains kinda cool state machine to do it)
and in the second run, it parses the buffer. Therefore, the only thing that
this commit actually does is that it moves the buffer out of json.Decoder.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2020-11-25 07:37:44 +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
Tom Gundersen
0e382e9cf4 worker: implement koji job types
The three new job types osbuild-koji, koji-init, and koji-finalize
allows the different tasks to be split appart and in particular for
there to be several builds on different architectures as part of a
given compose.
2020-11-11 18:16:42 +01:00
Lars Karlitski
6b6cd7ca9f worker: introduce JobImplementation interface
Introduce JobImplementation and turn the current RunJob() into
OSBuildJobImpl. Make main() select a job impl based on job type.

This is in preparation to add additional impls.
2020-11-09 14:17:19 +01:00
Lars Karlitski
3bc642e4aa worker: split osbuild job implementation into separate file
No code was changed.
2020-11-09 14:17:19 +01:00
Lars Karlitski
c15c17960b worker: make worker.Client job-agnostic
Move the fact that the worker is requesting jobs of type "osbuild" out
of the client library.

For one, require consumers to pass accepted job types to RequestJobs()
and allow querying for the job type with the new Type() function.

Also, make OSBuildArgs() and Update() generic, requiring to pass an
argument that matches the job type.
2020-11-09 14:17:19 +01:00
Lars Karlitski
07f21d089e worker: move job.Update() into RunJob()
Now, main() does not deal with OSBuildJobResult anymore, and RunJob()
doesn't return it. This means we can add more job types (i.e., different
RunJob()s) now.
2020-11-09 14:17:19 +01:00
Lars Karlitski
1184d78494 worker: remove race from WatchJob()
WatchJob() regularly checks if a job was canceled in a goroutine. It
does so by accessing composer's `/jobs/{token}` route. However, once the
main goroutine marks the job as done (by sending PATCH to that same
route), the `token` is no longer valid and thus the route not accessible
anymore.

main() does cancel the goroutine running WatchJob, but it's not
guaranteed that it gets scheduled in time to actually stop watching the
job.

Thus, don't cancel the job when fetching the `/jobs/{token}` fails. This
means that it won't cancel the job anymore when the connection to
composer goes down.

Also, we will be able to move job.Update() into RunJob().
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
a0f080c497 worker: remove FailJob()
This function is almost the same as the koji uploader, except that it
calls `CGFailBuild` instead of `CGImport` at the end.

Don't exit early from RunJob() when the job failed. Instead, go through
all the uploaders anyway. All the others don't do anything when the job
fails, but now we have the chance to do the necessary `CGFailBuild` call
for koji.

This moves more logic from main() into RunJob(), so that we can support
different job kinds in the future.
2020-11-09 14:17:19 +01:00
Lars Karlitski
f6f4f1fd9b worker: add missing continue 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
d1f322ec6f worker: always send status "FINISHED"
The server hasn't used common.ImageBuildState to mark a job as
successful or failed for a long time. Instead, it's using the job's
return argument for that. (Jobs don't have a high-level concept of
failing).

Drop the check in the server, and always send "FINISHED" from the client
for backwards compatibility.
2020-11-09 14:17:19 +01:00
Lars Karlitski
b7cb2cff62 worker: only remove temp output directory once
We already do this in a defer.
2020-11-09 14:17:19 +01:00
Lars Karlitski
4e46eacd64 worker: handle error when closing osbuild's stdin
This will only happen rarely, but it will be good to know it happened
when it does.
2020-11-09 14:17:19 +01:00
Lars Karlitski
89814c3107 worker: mark builds as failed based on osbuild's output
osbuild reports failing builds in two ways: it sets the "success" field
in its output to `false` and it returns with a non-zero exit status. The
worker used both, returning an `OSBuildError` when osbuild return
non-zero, but also forwarding the resulting object with the "success"
field.

Change this to only use the "success" field and ignore the return value.
The latter is useful for people running osbuild in a terminal or script,
but is redundant for this use-case.

This makes error reporting more consistent: `RunOSBuild` only returns an
error when *running* osbuild failed, not when the build fails.
2020-11-09 14:17:19 +01:00