pkg/machine/ocipull: add custom policy.json location

The default policy file /etc/containers/policy.json location does not
work on windows and for packages that ship a default.

Now we search for the policy.json in the following overwrite locations:
macos and linux:
 - ~/.config/containers/policy.json
 - /etc/containers/policy.json
windows:
 - %APPDATA%\containers\policy.json

Also it offers an additional DefaultPolicyJSONPath var that should be
overwritten at built time with the path of the file that is shipped by
packagers. Thile file is used when none of the overwrite paths exist.

[NO NEW TESTS NEEDED]

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2024-02-20 14:47:22 +01:00
parent 6dd8454a54
commit a02aa8f6a2
No known key found for this signature in database
GPG Key ID: EB145DD938A3CAF2
4 changed files with 83 additions and 2 deletions

View File

@ -0,0 +1,47 @@
package ocipull
import (
"fmt"
"os"
"path/filepath"
)
// DefaultPolicyJSONPath should be overwritten at build time with the real path to the directory where
// the shipped policy.json file is located. This can either be absolute path or a relative path. If it
// is relative it will be resolved relative to the podman binary and NOT the CWD.
//
// use "-X github.com/containers/podman/v5/pkg/machine/ocipull.DefaultPolicyJSONPath=/somepath" in go ldflags to overwrite this
var DefaultPolicyJSONPath = ""
const policyfile = "policy.json"
type defaultPolicyError struct {
errs []error
}
func (e *defaultPolicyError) Error() string {
return fmt.Sprintf("no DefaultPolicyJSONPath defined and no local overwrites found: %q", e.errs)
}
func policyPath() (string, error) {
paths := localPolicyOverwrites()
errs := make([]error, 0, len(paths))
for _, path := range paths {
_, err := os.Stat(path)
if err == nil {
return path, nil
}
errs = append(errs, err)
}
if DefaultPolicyJSONPath != "" {
if filepath.IsAbs(DefaultPolicyJSONPath) {
return filepath.Join(DefaultPolicyJSONPath, policyfile), nil
}
p, err := os.Executable()
if err != nil {
return "", fmt.Errorf("could not resolve relative path to binary: %w", err)
}
return filepath.Join(p, DefaultPolicyJSONPath, policyfile), nil
}
return "", &defaultPolicyError{errs: errs}
}

View File

@ -0,0 +1,19 @@
//go:build !windows
package ocipull
import (
"path/filepath"
"github.com/containers/common/pkg/config"
"github.com/containers/storage/pkg/homedir"
)
func localPolicyOverwrites() []string {
var dirs []string
if p, err := homedir.GetConfigHome(); err == nil {
dirs = append(dirs, filepath.Join(p, "containers", policyfile))
}
dirs = append(dirs, config.DefaultSignaturePolicyPath)
return dirs
}

View File

@ -0,0 +1,10 @@
package ocipull
import (
"os"
"path/filepath"
)
func localPolicyOverwrites() []string {
return []string{filepath.Join(os.Getenv("APPDATA"), "containers", policyfile)}
}

View File

@ -44,9 +44,14 @@ func Pull(ctx context.Context, imageInput types.ImageReference, localDestPath *d
sysCtx.DockerAuthConfig = authConf
}
policy, err := signature.DefaultPolicy(sysCtx)
path, err := policyPath()
if err != nil {
return fmt.Errorf("obtaining default signature policy: %w", err)
return err
}
policy, err := signature.NewPolicyFromFile(path)
if err != nil {
return fmt.Errorf("obtaining signature policy: %w", err)
}
policyContext, err := signature.NewPolicyContext(policy)
if err != nil {