Skip to content

Commit c66b9d0

Browse files
feat: change image pull auth args (#2780)
feat: change image pull auth args feat: change image pull auth args feat: change image pull auth args feat: change image pull auth args feat: feat ssh connect exec sudo error with non-root user feat: feat ssh connect exec sudo error with non-root user feat: change image pull auth args Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com>
1 parent ea70663 commit c66b9d0

File tree

4 files changed

+80
-11
lines changed

4 files changed

+80
-11
lines changed

builtin/core/playbooks/artifact_images.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
tags: ["pull","image_registry"]
1515
image:
1616
pull:
17+
auths: "{{ .cri.registry.auths | toJson }}"
1718
images_dir: >-
1819
{{ .binary_dir }}/images/
1920
manifests: "{{ .image_manifests | toJson }}"

docs/zh/modules/image.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ image模块允许用户下载镜像到本地目录或上传镜像到远程目录
99
| pull | 把镜像从远程仓库中拉取到本地目录 | map || - |
1010
| pull.images_dir | 镜像存放的本地目录 | 字符串 || - |
1111
| pull.manifests | 需要拉取的镜像列表 | 字符串数组 || - |
12-
| pull.username | 用于认证远程仓库的用户 | 字符串 || - |
13-
| pull.password | 用于认证远程仓库的密码 | 字符串 || - |
12+
| pull.auths | 远程仓库的认证信息 | Object数组 || - |
13+
| pull.auths.repo | 用于认证远程仓库的地址 | 字符串 || - |
14+
| pull.auths.username | 用于认证远程仓库的用户名 | 字符串 || - |
15+
| pull.auths.password | 用于认证远程仓库的密码 | 字符串 || - |
1416
| pull.platform | 镜像的架构信息 | 字符串 || - |
1517
| pull.skip_tls_verify | 是否跳过远程仓库的tls认证 | bool || - |
1618
| push | 从本地目录中推送镜像到远程仓库 | map || - |

pkg/modules/image.go

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ image:
5959
manifests: []string # required: list of image manifests to pull
6060
images_dir: string # required: directory to store pulled images
6161
skipTLSVerify: bool # optional: skip TLS verification
62+
autus: # optional: target image repo access information, slice type
63+
- repo: string # optional: target image repo
64+
username: string # optional: target image repo access username
65+
password: string # optional: target image repo access password
6266
push: # optional: push configuration
6367
username: string # optional: registry username
6468
password: string # optional: registry password
@@ -77,6 +81,13 @@ Usage Examples in Playbook Tasks:
7781
- nginx:latest
7882
- prometheus:v2.45.0
7983
images_dir: /path/to/images
84+
auths:
85+
- repo: docker.io
86+
username: MyDockerAccount
87+
password: my_password
88+
- repo: my.dockerhub.local
89+
username: MyHubAccount
90+
password: my_password
8091
register: pull_result
8192
```
8293
@@ -109,9 +120,14 @@ type imagePullArgs struct {
109120
imagesDir string
110121
manifests []string
111122
skipTLSVerify *bool
112-
username string
113-
password string
114123
platform string
124+
auths []imagePullAuth
125+
}
126+
127+
type imagePullAuth struct {
128+
Repo string `json:"repo"`
129+
Username string `json:"username"`
130+
Password string `json:"password"`
115131
}
116132

117133
// pull retrieves images from a remote registry and stores them locally
@@ -129,11 +145,8 @@ func (i imagePullArgs) pull(ctx context.Context, platform string) error {
129145
},
130146
},
131147
},
132-
Cache: auth.NewCache(),
133-
Credential: auth.StaticCredential(src.Reference.Registry, auth.Credential{
134-
Username: i.username,
135-
Password: i.password,
136-
}),
148+
Cache: auth.NewCache(),
149+
Credential: i.pullAuthFunc(),
137150
}
138151

139152
dst, err := newLocalRepository(filepath.Join(src.Reference.Registry, src.Reference.Repository)+":"+src.Reference.Reference, i.imagesDir)
@@ -159,6 +172,30 @@ func (i imagePullArgs) pull(ctx context.Context, platform string) error {
159172
return nil
160173
}
161174

175+
func (i imagePullArgs) pullAuthFunc() func(ctx context.Context, hostport string) (auth.Credential, error) {
176+
var creds = make(map[string]auth.Credential)
177+
for _, inputAuth := range i.auths {
178+
var rp = inputAuth.Repo
179+
if rp == "docker.io" {
180+
rp = "registry-1.docker.io"
181+
}
182+
if rp == "" {
183+
continue
184+
}
185+
creds[rp] = auth.Credential{
186+
Username: inputAuth.Username,
187+
Password: inputAuth.Password,
188+
}
189+
}
190+
return func(_ context.Context, hostport string) (auth.Credential, error) {
191+
cred, ok := creds[hostport]
192+
if !ok {
193+
cred = auth.EmptyCredential
194+
}
195+
return cred, nil
196+
}
197+
}
198+
162199
// parse platform string to ocispec.Platform
163200
func parsePlatform(platformStr string) (imagev1.Platform, error) {
164201
parts := strings.Split(platformStr, "/")
@@ -259,8 +296,13 @@ func newImageArgs(_ context.Context, raw runtime.RawExtension, vars map[string]a
259296
}
260297
ipl := &imagePullArgs{}
261298
ipl.manifests, _ = variable.StringSliceVar(vars, pull, "manifests")
262-
ipl.username, _ = variable.StringVar(vars, pull, "username")
263-
ipl.password, _ = variable.StringVar(vars, pull, "password")
299+
ipl.auths = make([]imagePullAuth, 0)
300+
_ = variable.AnyVar(vars, &ipl.auths, "cri", "registry", "auths")
301+
for _, a := range ipl.auths {
302+
a.Repo, _ = tmpl.ParseFunc(vars, a.Repo, func(b []byte) string { return string(b) })
303+
a.Username, _ = tmpl.ParseFunc(vars, a.Username, func(b []byte) string { return string(b) })
304+
a.Password, _ = tmpl.ParseFunc(vars, a.Password, func(b []byte) string { return string(b) })
305+
}
264306
ipl.imagesDir, _ = variable.StringVar(vars, pull, "images_dir")
265307
ipl.skipTLSVerify, _ = variable.BoolVar(vars, pull, "skip_tls_verify")
266308
if ipl.skipTLSVerify == nil {

pkg/variable/helper.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,30 @@ func DurationVar(ctx map[string]any, args map[string]any, key string) (time.Dura
343343
return time.ParseDuration(stringVar)
344344
}
345345

346+
// AnyVar get data from input args and keys,unmarshal data into dest
347+
func AnyVar(args map[string]any, dest any, keys ...string) error {
348+
val, found, err := unstructured.NestedFieldNoCopy(args, keys...)
349+
if err != nil {
350+
return errors.WithStack(err)
351+
}
352+
if !found {
353+
return errors.Errorf("cannot find variable %q", strings.Join(keys, "."))
354+
}
355+
valBytes, err := json.Marshal(val)
356+
if err != nil {
357+
return errors.Wrapf(err, "failed to marshal variable %q", strings.Join(keys, "."))
358+
}
359+
valBytes, err = tmpl.Parse(args, string(valBytes))
360+
if err != nil {
361+
return err
362+
}
363+
err = json.Unmarshal(valBytes, dest)
364+
if err != nil {
365+
return errors.Wrapf(err, "failed to unmarshal variable %q to dest", strings.Join(keys, "."))
366+
}
367+
return nil
368+
}
369+
346370
// Extension2Variables convert runtime.RawExtension to variables
347371
func Extension2Variables(ext runtime.RawExtension) map[string]any {
348372
if len(ext.Raw) == 0 {

0 commit comments

Comments
 (0)