container: set default auth file path to sane location

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.
This commit is contained in:
Christian Kellner 2022-07-20 21:07:50 +02:00 committed by Ondřej Budai
parent e53b9c8bb2
commit bd42243882

View file

@ -7,6 +7,7 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
_ "github.com/containers/image/v5/docker/archive"
@ -30,6 +31,43 @@ const (
DefaultPolicyPath = "/etc/containers/policy.json"
)
var (
defaultAuthFile = GetDefaultAuthFile()
)
// GetDefaultAuthFile returns the authentication file to use for the
// current environment.
//
// This is basically a re-implementation of `getPathToAuthWithOS` from
// containers/image/pkg/docker/config/config.go[1], but we ensure that
// the returned path is either accessible or nonexistent. This is needed
// since any other error than os.ErrNotExist will lead to an overall
// failure and thus prevent any operation even with public resources.
//
// [1] https://github.com/containers/image/blob/55ea76c7db702ed1af60924a0b57c8da533d9e5a/pkg/docker/config/config.go#L506
func GetDefaultAuthFile() string {
dirExistsOrEmpty := func(path string) bool {
_, err := os.Stat(path)
// document the error case
return err == nil || os.IsNotExist(err)
}
if runtimeDir := os.Getenv("XDG_RUNTIME_DIR"); runtimeDir != "" {
path := filepath.Join(runtimeDir, "containers", "auth.json")
if dirExistsOrEmpty(path) {
return path
}
}
path := fmt.Sprintf("/run/containers/%d/auth.json", os.Getuid())
if dirExistsOrEmpty(path) {
return path
}
return filepath.Join("var", "empty", "containers-auth.json")
}
// A Client to interact with the given Target object at a
// container registry, like e.g. uploading an image to.
// All mentioned defaults are only set when using the
@ -88,6 +126,8 @@ func NewClient(target string) (*Client, error) {
RegistriesDirPath: "",
SystemRegistriesConfPath: "",
BigFilesTemporaryDir: "/var/tmp",
AuthFilePath: defaultAuthFile,
},
policy: policy,
}
@ -95,6 +135,11 @@ func NewClient(target string) (*Client, error) {
return &client, nil
}
// SetAuthFilePath sets the location of the `containers-auth.json(5)` file.
func (cl *Client) SetAuthFilePath(path string) {
cl.sysCtx.AuthFilePath = path
}
// SetCredentials will set username and password for Client
func (cl *Client) SetCredentials(username, password string) {