Skip to content

Commit 98dd3e9

Browse files
authored
Support podman auth file REGISTRY_AUTH_FILE. (#1914)
1 parent 051d642 commit 98dd3e9

File tree

2 files changed

+61
-29
lines changed

2 files changed

+61
-29
lines changed

pkg/authn/keychain.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ func (dk *defaultKeychain) Resolve(target Resource) (Authenticator, error) {
8686
// config.Load, which may fail if the config can't be parsed.
8787
//
8888
// If neither was found, look for Podman's auth at
89-
// $XDG_RUNTIME_DIR/containers/auth.json and attempt to load it as a
90-
// Docker config.
89+
// $REGISTRY_AUTH_FILE or $XDG_RUNTIME_DIR/containers/auth.json
90+
// and attempt to load it as a Docker config.
9191
//
9292
// If neither are found, fallback to Anonymous.
9393
var cf *configfile.ConfigFile
@@ -96,16 +96,28 @@ func (dk *defaultKeychain) Resolve(target Resource) (Authenticator, error) {
9696
if err != nil {
9797
return nil, err
9898
}
99-
} else {
99+
} else if fileExists(os.Getenv("REGISTRY_AUTH_FILE")) {
100+
f, err := os.Open(os.Getenv("REGISTRY_AUTH_FILE"))
101+
if err != nil {
102+
return nil, err
103+
}
104+
defer f.Close()
105+
cf, err = config.LoadFromReader(f)
106+
if err != nil {
107+
return nil, err
108+
}
109+
} else if fileExists(filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "containers/auth.json")) {
100110
f, err := os.Open(filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "containers/auth.json"))
101111
if err != nil {
102-
return Anonymous, nil
112+
return nil, err
103113
}
104114
defer f.Close()
105115
cf, err = config.LoadFromReader(f)
106116
if err != nil {
107117
return nil, err
108118
}
119+
} else {
120+
return Anonymous, nil
109121
}
110122

111123
// See:

pkg/authn/keychain_test.go

+45-25
Original file line numberDiff line numberDiff line change
@@ -92,27 +92,31 @@ func TestNoConfig(t *testing.T) {
9292
}
9393
}
9494

95+
func writeConfig(t *testing.T, dir, file, content string) {
96+
if err := os.MkdirAll(dir, 0777); err != nil {
97+
t.Fatalf("mkdir %s: %v", dir, err)
98+
}
99+
if err := os.WriteFile(filepath.Join(dir, file), []byte(content), 0600); err != nil {
100+
t.Fatalf("write %q: %v", file, err)
101+
}
102+
}
103+
95104
func TestPodmanConfig(t *testing.T) {
96105
tmpdir := os.Getenv("TEST_TMPDIR")
97106
if tmpdir == "" {
98107
tmpdir = t.TempDir()
99108
}
100109
fresh++
101-
p := filepath.Join(tmpdir, fmt.Sprintf("%d", fresh))
102-
t.Setenv("XDG_RUNTIME_DIR", p)
103-
os.Unsetenv("DOCKER_CONFIG")
104-
if err := os.MkdirAll(filepath.Join(p, "containers"), 0777); err != nil {
105-
t.Fatalf("mkdir %s/containers: %v", p, err)
106-
}
107-
cfg := filepath.Join(p, "containers/auth.json")
108-
content := fmt.Sprintf(`{"auths": {"test.io": {"auth": %q}}}`, encode("foo", "bar"))
109-
if err := os.WriteFile(cfg, []byte(content), 0600); err != nil {
110-
t.Fatalf("write %q: %v", cfg, err)
111-
}
112110

111+
os.Unsetenv("DOCKER_CONFIG")
113112
// At first, $DOCKER_CONFIG is unset and $HOME/.docker/config.json isn't
114-
// found, but Podman auth is configured. This should return Podman's
115-
// auth.
113+
// found, but Podman auth $XDG_RUNTIME_DIR/containers/auth.json is configured.
114+
// This should return Podman's auth $XDG_RUNTIME_DIR/containers/auth.json.
115+
p := filepath.Join(tmpdir, fmt.Sprintf("%d", fresh))
116+
t.Setenv("XDG_RUNTIME_DIR", p)
117+
writeConfig(t, filepath.Join(p, "containers"), "auth.json",
118+
fmt.Sprintf(`{"auths": {"test.io": {"auth": %q}}}`,
119+
encode("XDG_RUNTIME_DIR-foo", "XDG_RUNTIME_DIR-bar")))
116120
auth, err := DefaultKeychain.Resolve(testRegistry)
117121
if err != nil {
118122
t.Fatalf("Resolve() = %v", err)
@@ -122,24 +126,40 @@ func TestPodmanConfig(t *testing.T) {
122126
t.Fatal(err)
123127
}
124128
want := &AuthConfig{
125-
Username: "foo",
126-
Password: "bar",
129+
Username: "XDG_RUNTIME_DIR-foo",
130+
Password: "XDG_RUNTIME_DIR-bar",
127131
}
128132
if !reflect.DeepEqual(got, want) {
129133
t.Errorf("got %+v, want %+v", got, want)
130134
}
131135

132-
// Now, configure $HOME/.docker/config.json, which should override
133-
// Podman auth and be used.
134-
if err := os.MkdirAll(filepath.Join(os.Getenv("HOME"), ".docker"), 0777); err != nil {
135-
t.Fatalf("mkdir $HOME/.docker: %v", err)
136+
// Then, configure Podman auth $REGISTRY_AUTH_FILE.
137+
// This demonstrates that $REGISTRY_AUTH_FILE is preferred over $XDG_RUNTIME_DIR/containers/auth.json.
138+
t.Setenv("REGISTRY_AUTH_FILE", filepath.Join(p, "auth.json"))
139+
writeConfig(t, p, "auth.json",
140+
fmt.Sprintf(`{"auths": {"test.io": {"auth": %q}}}`,
141+
encode("REGISTRY_AUTH_FILE-foo", "REGISTRY_AUTH_FILE-bar")))
142+
auth, err = DefaultKeychain.Resolve(testRegistry)
143+
if err != nil {
144+
t.Fatalf("Resolve() = %v", err)
145+
}
146+
got, err = auth.Authorization()
147+
if err != nil {
148+
t.Fatal(err)
136149
}
137-
cfg = filepath.Join(os.Getenv("HOME"), ".docker/config.json")
138-
content = fmt.Sprintf(`{"auths": {"test.io": {"auth": %q}}}`, encode("home-foo", "home-bar"))
139-
if err := os.WriteFile(cfg, []byte(content), 0600); err != nil {
140-
t.Fatalf("write %q: %v", cfg, err)
150+
want = &AuthConfig{
151+
Username: "REGISTRY_AUTH_FILE-foo",
152+
Password: "REGISTRY_AUTH_FILE-bar",
153+
}
154+
if !reflect.DeepEqual(got, want) {
155+
t.Errorf("got %+v, want %+v", got, want)
141156
}
142-
defer func() { os.Remove(cfg) }()
157+
158+
// Now, configure $HOME/.docker/config.json, which should override
159+
// Podman auth and be used.
160+
writeConfig(t, filepath.Join(os.Getenv("HOME"), ".docker"), "config.json",
161+
fmt.Sprintf(`{"auths": {"test.io": {"auth": %q}}}`, encode("home-foo", "home-bar")))
162+
defer func() { os.Remove(filepath.Join(os.Getenv("HOME"), ".docker/config.json")) }()
143163
auth, err = DefaultKeychain.Resolve(testRegistry)
144164
if err != nil {
145165
t.Fatalf("Resolve() = %v", err)
@@ -160,7 +180,7 @@ func TestPodmanConfig(t *testing.T) {
160180
// auth configured.
161181
// This demonstrates that DOCKER_CONFIG is preferred over Podman auth
162182
// and $HOME/.docker/config.json.
163-
content = fmt.Sprintf(`{"auths": {"test.io": {"auth": %q}}}`, encode("another-foo", "another-bar"))
183+
content := fmt.Sprintf(`{"auths": {"test.io": {"auth": %q}}}`, encode("another-foo", "another-bar"))
164184
cd := setupConfigFile(t, content)
165185
defer os.RemoveAll(filepath.Dir(cd))
166186

0 commit comments

Comments
 (0)