为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Go 访问远程 docker 存储库

使用 Go 访问远程 docker 存储库

Go
HUWWW 2022-05-05 17:47:28
我需要使用 Go 和协议 V2 访问私有 docker 注册表。我需要在私有注册表中列出存储库,获取它们的所有标签和其他信息。我应该为此使用 docker/distribution/registry/client 吗?是否有此类任务的样本?找不到。。。官网只提供http api文档。我写了一些代码:    registry, err := client.NewRegistry("https://registry-1.docker.io/", http.DefaultTransport)    if err != nil {        log.Error("Error creating the registry: {}", err)        return    }    ctx := context.Background()    entries := make([]string, 5)    numFilled, err := registry.Repositories(ctx, entries, "")    if err != io.EOF {        log.Error("Error getting the registry: {}", err)        return    }    log.Info("Number of repositories: {}", numFilled)    _ = registry当然,docker repo 需要认证。但是我应该如何提供呢?是否有此类任务的文档?
查看完整描述

2 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

改编自源码包中的测试代码:



import (

    "github.com/docker/distribution/registry/client"

    "github.com/docker/distribution/registry/client/auth"

    "github.com/docker/distribution/registry/client/auth/challenge"

    "github.com/docker/distribution/registry/client/transport"

)

    

type regCredentialStore struct {

    username      string

    password      string

    refreshTokens map[string]string

}


func (tcs *regCredentialStore) Basic(*url.URL) (string, string) {

    return tcs.username, tcs.password

}


func (tcs *regCredentialStore) RefreshToken(u *url.URL, service string) string {

    return tcs.refreshTokens[service]

}


func (tcs *regCredentialStore) SetRefreshToken(u *url.URL, service string, token string) {

    if tcs.refreshTokens != nil {

        tcs.refreshTokens[service] = token

    }

}


func main() {

    creds := &regCredentialStore{username: "user", password: "pwd"}

    challengeManager := challenge.NewSimpleManager()

    _, err = ping(challengeManager, "https://registry-1.docker.io/v2/", "")

    if err != nil {

        .... exit .....

    }

    transport1 := transport.NewTransport(

        nil, auth.NewAuthorizer(challengeManager, auth.NewBasicHandler(creds)))

    reg, err := client.NewRegistry("https://registry-1.docker.io/", transport1)

    ...

}   


func ping(manager challenge.Manager, endpoint, versionHeader string) ([]auth.APIVersion, error) {

    resp, err := http.Get(endpoint)

    if err != nil {

        return nil, err

    }

    defer resp.Body.Close()


    if err := manager.AddResponse(resp); err != nil {

        return nil, err

    }


    return auth.APIVersions(resp, versionHeader), err

}


查看完整回答
反对 回复 2022-05-05
?
aluckdog

TA贡献1847条经验 获得超7个赞

您可以使用 auth 标头触发简单的 http 调用(因为它只是 HTTP API),例如所选图像的列表标签:


req, _ := http.NewRequest("GET", "https://"+privateDockerRegistry+"/v2/"+dockerImage+"/tags/list", nil)

req.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(os.Getenv("DOCKER_USER")+":"+os.Getenv("DOCKER_PASSWORD"))))

req.Header.Add("Accept", "application/json")

resp, _ := client.Do(req)

...


查看完整回答
反对 回复 2022-05-05
  • 2 回答
  • 0 关注
  • 221 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号