After introducing Go 1.18 to a project, it's required by law to convert at
least one method to a generic one.
Everyone hates IntToPtr, StringToPtr, BoolToPtr and Uint64ToPtr, so let's
convert them to the ultimate generic ToPtr one.
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
Worker
------
Add configuration for the default container registry.
Use the default container registry if not provided as part
of the image name.
When using the default registry use the configured values
Return the image url as part of the result.
Composer Worker API
-------------------
Add `ContainerTargetResultOptions` to return the image url
Composer API
------------
Add UploadOptions to allow setting of the image name and tag
Add UploadStatus to return the url of the uploaded image
Co-Developed-By: Christian Kellner <christian@kellner.me>
This issue was found by Coverity:
Error: DEADCODE (CWE-561): [#def1]
osbuild-composer-58/_build/src/github.com/osbuild/osbuild-composer/internal/container/client.go:386: cond_null: Condition "err != nil", taking false branch. Now the value of "err" is "nil".
osbuild-composer-58/_build/src/github.com/osbuild/osbuild-composer/internal/container/client.go:390: null: At condition "err != nil", the value of "err" must be "nil".
osbuild-composer-58/_build/src/github.com/osbuild/osbuild-composer/internal/container/client.go:390: dead_error_condition: The condition "err != nil" cannot be true.
osbuild-composer-58/_build/src/github.com/osbuild/osbuild-composer/internal/container/client.go:391: dead_error_line: Execution cannot reach this statement: "<temporary>.$0 = container....".
389|
390| if err != nil {
391|-> return resolvedIds{}, nil
392| }
393|
Instead of using a cached result `GetDefaultAuthFile`, always
do call the function when a new `Client` is created, since at
least `/run/containers` can get created as a side-effect by
one of the container. Now that we check eagerly and often the
path check function was reworked to only return paths that do
exist and are accessible.
Also check if `REGISTRY_AUTH_FILE` is set and if so, and it
is accessible use that.
To check accessability, use `unix.Access` instead of `os.Stat`,
since On Fedora/RHEL 9 `os.Stat` is implemented via `statx` and
will indeed return `EACCES` for inaccessible paths. But on RHEL
8 `lstat` is used and that will return `ENOENT` but then later
when trying to open the file we will get `EPERM`.
We never want an empty path but always force a specific auth
file location, even if the location does not actually exist,
due to the peculiarities mentioned in the comment of the
`container.GetDefaultAuthFile` function.
Add a new class `container.Resolver` which can be used to resolve
multiple container images to their respective ids in parallel.
It should make it easy for all existing tools and api endpoints
to adpot container resultion.
Create a small only mock container registry to test `Client`.
Currently the registry is read-only and thus cannot be used
for upload tests but it can and will be used for container
resolution checks.
Add a new `Resolve` method to `Client` that will resolve its `Target`
to the corresponding manifest digest id and its corresponding iamge
identifier. The former can be used in the URL to fetch a specific
image from the registry via `<name>@<digest>` and the latter uniquely
identifies a container image via the hash of its configuration object.
This should stay the same across pulls and is also the id returned via
`podman pull` and `podman images`.
Since (most) container images are OS and architecture specific a tag
often points to a manifest list that contains all available options.
Therefore the resolve operation needs to choose the correct arch for
image. A new pair of getters `Set{Architecture,Variant}Choice` lets
the user control which architecture/variant is selected during the
resolution process.
Ensure that the `Client.AuthFilePath` points to a sane location,
which here means that the location is either accessible by the
current user or does not exist. This is because any other error
opening the auth file with lead to a overall failure when trying
to access container registries, even if the target resources is
public.
The reason we have to set it ourselves is that by default the
containers library looks in a sub-path of `XDG_RUNTIME_DIR` and if
that variable is not set it falls-back to `/run/containers/<uid>`.
Since `XDG_RUNTIME_DIR` is indeed not set for the composer process
started via systemd, it will fall-back, but it does not have access
to `/run/containers` and finding the authorization info for any
request will fail with "permission denied".
Add a setter so that we can set the `Client.AuthFilePath` to a
different location than the default one.
Instead of keeping an extra field in `Client`, we just use the
existing `sysCtx.DockerAuthConfig` structure. When the context
is later copied during the upload operation the credentials
will be copied as well. It also saves us from syncing the
credentials if we directly use said `sysCtx` for operations.
Instead of having an extra field, `TlsVerify`, on the `Client` and
then later setting the corresponding `SystemContext` options, use
the existing `SystemContext` field of `Client`. The corresponding
field is a tri-state: unset, true, false, which is represented as
a pointer to boolean in the `Client`'s new getter and setter. This
also inverts the boolean logic from verify TLS to skip TLS which
aligns very well with the corresponding fields in the upload target
struct.
In addition we properly capitalize some existing variables.
Add a new generic container registry client via a new `container`
package. Use this to create a command line utility as well as a
new upload target for container registries.
The code uses the github.com/containers/* project and packages to
interact with container registires that is also used by skopeo,
podman et al. One if the dependencies is `proglottis/gpgme` that
is using cgo to bind libgpgme, so we have to add the corresponding
devel package to the BuildRequires as well as installing it on CI.
Checks will follow later via an integration test.