请用golang写一个调用阿里云docker api方法获取镜像的所有信息方法
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
type Image struct {
Architecture string `json:"architecture"`
Digest string `json:"digest"`
ImageID string `json:"imageId"`
ImageName string `json:"imageName"`
ImageTag string `json:"imageTag"`
Os string `json:"os"`
Size int `json:"size"`
}
type Repository struct {
Namespace string `json:"namespace"`
RepoName string `json:"repoName"`
RepoFull string `json:"repoFullName"`
RepoType string `json:"repoType"`
Summary Summary `json:"summary"`
}
type Summary struct {
ImageCount int64 `json:"imageCount"`
TotalSize int64 `json:"totalSize"`
}
func main() {
accessKeyId := "your_access_key_id"
accessKeySecret := "your_access_key_secret"
endpoint := "https://registry.cn-hangzhou.aliyuncs.com"
namespace := "your_namespace"
repoName := "your_repo_name"
// get token
tokenUrl := fmt.Sprintf("https://%s/token?namespace=%s&access_token=1&service=registry.aliyuncs.com", endpoint, namespace)
tokenResp, err := http.Get(tokenUrl)
if err != nil {
fmt.Println("get token error:", err)
return
}
defer tokenResp.Body.Close()
tokenBody, err := ioutil.ReadAll(tokenResp.Body)
if err != nil {
fmt.Println("read token body error:", err)
return
}
var tokenMap map[string]string
err = json.Unmarshal(tokenBody, &tokenMap)
if err != nil {
fmt.Println("unmarshal token body error:", err)
return
}
token := tokenMap["token"]
// get repo info
repoUrl := fmt.Sprintf("https://%s/v2/%s/%s/?last=0", endpoint, namespace, repoName)
req, err := http.NewRequest("GET", repoUrl, nil)
if err != nil {
fmt.Println("new request error:", err)
return
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
client := &http.Client{}
repoResp, err := client.Do(req)
if err != nil {
fmt.Println("get repo info error:", err)
return
}
defer repoResp.Body.Close()
repoBody, err := ioutil.ReadAll(repoResp.Body)
if err != nil {
fmt.Println("read repo body error:", err)
return
}
var repoMap map[string]interface{}
err = json.Unmarshal(repoBody, &repoMap)
if err != nil {
fmt.Println("unmarshal repo body error:", err)
return
}
repoInfo := Repository{
Namespace: namespace,
RepoName: repoName,
RepoFull: fmt.Sprintf("%s/%s", namespace, repoName),
RepoType: "public",
Summary: Summary{
ImageCount: int64(repoMap["catalog"].(float64)),
TotalSize: 0,
},
}
// get image info
imageUrl := fmt.Sprintf("https://%s/v2/%s/%s/tags/list", endpoint, namespace, repoName)
imageReq, err := http.NewRequest("GET", imageUrl, nil)
if err != nil {
fmt.Println("new request error:", err)
return
}
imageReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
imageClient := &http.Client{}
imageResp, err := imageClient.Do(imageReq)
if err != nil {
fmt.Println("get image info error:", err)
return
}
defer imageResp.Body.Close()
imageBody, err := ioutil.ReadAll(imageResp.Body)
if err != nil {
fmt.Println("read image body error:", err)
return
}
var imageMap map[string]interface{}
err = json.Unmarshal(imageBody, &imageMap)
if err != nil {
fmt.Println("unmarshal image body error:", err)
return
}
imageList := imageMap["tags"].([]interface{})
for _, imageName := range imageList {
imageUrl := fmt.Sprintf("https://%s/v2/%s/%s/manifests/%s", endpoint, namespace, repoName, imageName.(string))
req, err := http.NewRequest("GET", imageUrl, nil)
if err != nil {
fmt.Println("new request error:", err)
return
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("get image info error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read body error:", err)
return
}
var manifestMap map[string]interface{}
err = json.Unmarshal(body, &manifestMap)
if err != nil {
fmt.Println("unmarshal manifest error:", err)
return
}
configDigest := manifestMap["config"].(map[string]interface{})["digest"].(string)
configUrl := fmt.Sprintf("https://%s/v2/%s/%s/blobs/%s", endpoint, namespace, repoName, configDigest)
configReq, err := http.NewRequest("GET", configUrl, nil)
if err != nil {
fmt.Println("new request error:", err)
return
}
configReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
configClient := &http.Client{}
configResp, err := configClient.Do(configReq)
if err != nil {
fmt.Println("get config error:", err)
return
}
defer configResp.Body.Close()
configBody, err := ioutil.ReadAll(configResp.Body)
if err != nil {
fmt.Println("read config body error:", err)
return
}
var configMap map[string]interface{}
err = json.Unmarshal(configBody, &configMap)
if err != nil {
fmt.Println("unmarshal config body error:", err)
return
}
image := Image{
Architecture: configMap["architecture"].(string),
Digest: manifestMap["config"].(map[string]interface{})["digest"].(string),
ImageID: manifestMap["config"].(map[string]interface{})["digest"].(string),
ImageName: fmt.Sprintf("%s/%s:%s", namespace, repoName, imageName),
ImageTag: imageName.(string),
Os: configMap["os"].(string),
Size: int(configMap["size"].(float64)),
}
repoInfo.Summary.TotalSize += int64(image.Size)
fmt.Println(image)
}
fmt.Println(repoInfo)
}
注意事项:
- 需要替换
your_access_key_id和your_access_key_secret为自己的 access key id 和 access key secret。 - 需要替换
your_namespace和your_repo_name为自己的镜像仓库命名空间和镜像仓库名称。 - 需要安装
github.com/json-iterator/go包
原文地址: https://www.cveoy.top/t/topic/fnak 著作权归作者所有。请勿转载和采集!