mirror of
https://github.com/kubesphere/kubekey.git
synced 2025-12-26 01:22:51 +00:00
feat: image module add copy func
Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com> feat: image module add copy func Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com> feat: image module add copy func Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com> feat: image module add copy func Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com> feat: image module add copy func Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com>
This commit is contained in:
parent
be0a6da9cd
commit
a54e66b92c
|
|
@ -28,23 +28,11 @@ image模块允许用户下载镜像到本地目录或上传镜像到远程目录
|
|||
| push.dest | 模版语法,从本地目录镜像推送到的远程仓库镜像 | map | 否 | - |
|
||||
| copy | 模版语法,将镜像在文件系统和镜像仓库内相互复制 | map | 否 | - |
|
||||
| copy.from | 模版语法,源镜像信息 | map | 否 | - |
|
||||
| copy.from.type | 镜像源类型 | 字符串 | 否 | - |
|
||||
| copy.from.path | 镜像源地址。如果类型为file,则为文件地址,如果类型为hub,则为镜像仓库地址 | 字符串 | 否 | - |
|
||||
| copy.from.skip_tls_verify | 仅在hub类型中生效;源镜像仓库是否跳过tls认证 | bool | 否 | - |
|
||||
| copy.from.path | 镜像源文件路径 | 字符串 | 否 | - |
|
||||
| copy.from.manifests | 源镜像列表 | 字符串数组 | 否 | - |
|
||||
| copy.from.auths | 远程仓库的认证信息 | Object数组 | 否 | - |
|
||||
| copy.from.auths.repo | 用于认证远程仓库的地址 | 字符串 | 否 | - |
|
||||
| copy.from.auths.username | 用于认证远程仓库的用户名 | 字符串 | 否 | - |
|
||||
| copy.from.auths.password | 用于认证远程仓库的密码 | 字符串 | 否 | - |
|
||||
| copy.to | 模版语法,从本地目录镜像推送到的远程仓库镜像 | map | 否 | - |
|
||||
| copy.to.type | 镜像目标类型 | 字符串 | 否 | - |
|
||||
| copy.to.path | 镜像目标地址。如果类型为file,则为文件地址,如果类型为hub,则为仓库中的镜像地址 | 字符串 | 否 | - |
|
||||
| copy.to.skip_tls_verify | 仅在hub类型中生效;目标镜像仓库是否跳过tls认证 | bool | 否 | - |
|
||||
| copy.to.pattern | 正则表达式,过滤推送至目标的镜像 | 字符串 | 否 | - |
|
||||
| copy.to.auths | 远程仓库的认证信息 | Object数组 | 否 | - |
|
||||
| copy.to.auths.repo | 用于认证远程仓库的地址 | 字符串 | 否 | - |
|
||||
| copy.to.auths.username | 用于认证远程仓库的用户名 | 字符串 | 否 | - |
|
||||
| copy.to.auths.password | 用于认证远程仓库的密码 | 字符串 | 否 | - |
|
||||
| copy.to.path | 镜像目标文件路径 | 字符串 | 否 | - |
|
||||
| copy.to.pattern | 正则表达式,过滤复制至目标的镜像 | 字符串 | 否 | - |
|
||||
|
||||
|
||||
每个本地目录存放的镜像对应一个dest镜像。
|
||||
|
|
@ -100,64 +88,9 @@ docker.io/kubesphere/ks-console:3.19 => hub.kubekey/kubesphere/ks-console:v4.1.3
|
|||
image:
|
||||
copy:
|
||||
from:
|
||||
type: file
|
||||
path: "/tmp/images/"
|
||||
manifests:
|
||||
- docker.io/calico/apiserver:v3.28.2
|
||||
to:
|
||||
type: file
|
||||
path: "/tmp/others/images/"
|
||||
```
|
||||
|
||||
4. 将镜像从文件系统推送至镜像仓库
|
||||
```yaml
|
||||
- name: file to hub
|
||||
image:
|
||||
copy:
|
||||
from:
|
||||
type: file
|
||||
path: "/tmp/images/"
|
||||
manifests:
|
||||
- docker.io/calico/apiserver:v3.28.2
|
||||
to:
|
||||
type: hub
|
||||
path: >-
|
||||
hub.kubekey/{{ .module.image.src.reference.repository }}:{{ .module.image.src.reference.reference }}
|
||||
```
|
||||
|
||||
5. 将镜像从仓库推送至文件系统
|
||||
```yaml
|
||||
- name: hub to file
|
||||
image:
|
||||
copy:
|
||||
from:
|
||||
type: hub
|
||||
auths:
|
||||
- repo: docker.io
|
||||
username: DockerAccount
|
||||
password: DockerPassword
|
||||
manifests:
|
||||
- docker.io/calico/apiserver:v3.28.2
|
||||
to:
|
||||
type: file
|
||||
path: /tmp/images/
|
||||
```
|
||||
|
||||
6. 将镜像从仓库推送至其他仓库
|
||||
```yaml
|
||||
- name: hub to hub
|
||||
image:
|
||||
copy:
|
||||
from:
|
||||
type: hub
|
||||
auths:
|
||||
- repo: docker.io
|
||||
username: DockerAccount
|
||||
password: DockerPassword
|
||||
manifests:
|
||||
- docker.io/calico/apiserver:v3.28.2
|
||||
to:
|
||||
type: hub
|
||||
path: >-
|
||||
hub.kubekey/{{ .module.image.src.reference.repository }}:{{ .module.image.src.reference.reference }}
|
||||
```
|
||||
|
|
@ -129,13 +129,13 @@ Usage Examples in Playbook Tasks:
|
|||
- name: file to file
|
||||
image:
|
||||
copy:
|
||||
from:
|
||||
path: "/path/from/images"
|
||||
manifests:
|
||||
- nginx:latest
|
||||
- prometheus:v2.45.0
|
||||
to:
|
||||
path: /path/to/images
|
||||
from:
|
||||
path: "/path/from/images"
|
||||
manifests:
|
||||
- nginx:latest
|
||||
- prometheus:v2.45.0
|
||||
to:
|
||||
path: /path/to/images
|
||||
```
|
||||
|
||||
Return Values:
|
||||
|
|
@ -211,6 +211,20 @@ func (i imagePullArgs) pull(ctx context.Context, platform string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func dockerHostParser(img string) string {
|
||||
// if image is like docker.io/xxx/xxx:tag, then download by pull func will store it to registry-1.docker.io
|
||||
// so we should change host from docker.io to registry-1.docker.io
|
||||
splitedImg := strings.Split(img, "/")
|
||||
if len(splitedImg) == 1 {
|
||||
return img
|
||||
}
|
||||
if splitedImg[0] != "docker.io" {
|
||||
return img
|
||||
}
|
||||
splitedImg[0] = "registry-1.docker.io"
|
||||
return strings.Join(splitedImg, "/")
|
||||
}
|
||||
|
||||
func authFunc(auths []imageAuth) func(ctx context.Context, hostport string) (auth.Credential, error) {
|
||||
var creds = make(map[string]auth.Credential)
|
||||
for _, inputAuth := range auths {
|
||||
|
|
@ -340,14 +354,9 @@ type imageCopyTargetArgs struct {
|
|||
|
||||
func (i *imageCopyArgs) parseFromVars(vars, cp map[string]any) error {
|
||||
i.From.manifests, _ = variable.StringSliceVar(vars, cp, "from", "manifests")
|
||||
fromPath, _ := variable.PrintVar(cp, "from", "path")
|
||||
if fromStr, ok := fromPath.(string); !ok {
|
||||
return errors.New("\"copy.to.path\" must be a string")
|
||||
} else if fromStr == "" {
|
||||
return errors.New("\"copy.to.path\" should not be empty")
|
||||
} else {
|
||||
i.From.Path = fromStr
|
||||
}
|
||||
|
||||
i.From.Path, _ = variable.StringVar(vars, cp, "from", "path")
|
||||
|
||||
toPath, _ := variable.PrintVar(cp, "to", "path")
|
||||
if destStr, ok := toPath.(string); !ok {
|
||||
return errors.New("\"copy.to.path\" must be a string")
|
||||
|
|
@ -367,20 +376,32 @@ func (i *imageCopyArgs) parseFromVars(vars, cp map[string]any) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (i *imageCopyArgs) copy(ctx context.Context, _ map[string]any) error {
|
||||
func (i *imageCopyArgs) copy(ctx context.Context, hostVars map[string]any) error {
|
||||
if sts, err := os.Stat(i.From.Path); err != nil || !sts.IsDir() {
|
||||
return errors.New("\"copy.from.path\" must be a exist directory")
|
||||
}
|
||||
for _, img := range i.From.manifests {
|
||||
img = normalizeImageNameSimple(img)
|
||||
if i.To.Pattern != nil && !i.To.Pattern.MatchString(img) {
|
||||
// skip
|
||||
continue
|
||||
}
|
||||
src, err := newLocalRepository(img, i.From.Path)
|
||||
src, err := newLocalRepository(dockerHostParser(img), i.From.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dst, err := newLocalRepository(filepath.Join(src.Reference.Registry, src.Reference.Repository)+":"+src.Reference.Reference, i.To.Path)
|
||||
dest := i.To.Path
|
||||
if kkprojectv1.IsTmplSyntax(dest) {
|
||||
// add temporary variable
|
||||
_ = unstructured.SetNestedField(hostVars, src.Reference.Registry, "module", "image", "src", "reference", "registry")
|
||||
_ = unstructured.SetNestedField(hostVars, src.Reference.Repository, "module", "image", "src", "reference", "repository")
|
||||
_ = unstructured.SetNestedField(hostVars, src.Reference.Reference, "module", "image", "src", "reference", "reference")
|
||||
dest, err = tmpl.ParseFunc(hostVars, dest, func(b []byte) string { return string(b) })
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst, err := newLocalRepository(filepath.Join(src.Reference.Registry, src.Reference.Repository)+":"+src.Reference.Reference, dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue