1)修正不同架构下载错误的问题 #I7F9CQ

2)提供设置proxy的入口 #I7EUMM
This commit is contained in:
刘铭 2023-07-06 16:19:08 +08:00
parent 28abc044bb
commit 24470eccba
6 changed files with 57 additions and 14 deletions

View File

@ -50,3 +50,15 @@ dget alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:
```bash
dget -arch linux/arm influxdb:1.8.3
```
## 设置代理
使用参数 -proxy 设置下载和获取时需要使用的代理
## 直接下载链接
[windows x64版本](./bin/windows_amd64/dget.exe)
[linux amd64版本](./bin/linux_amd64/dget)
[linux arm版本](./bin/linux_arm/dget)
[Mac 传统版本](./bin/darwin_amd64/dget)
[Mac arm64版本](./bin/darwin_arm64/dget)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,6 +2,8 @@ package main
import (
"flag"
"net/http"
"net/url"
"os"
"strings"
@ -13,6 +15,7 @@ func main() {
debug := flag.Bool("debug", false, "打印调试信息")
printInfo := flag.Bool("print", false, "只打印获取信息")
arch := flag.String("arch", "linux/amd64", "指定架构")
proxy := flag.String("proxy", "", "http proxy")
var registry string
flag.StringVar(&registry, "registry", "registry-1.docker.io", "指定镜像仓库")
@ -44,7 +47,23 @@ func main() {
pkg = strings.Join(partsOfPkg[1:], "/")
}
}
err := dget.Install(registry, pkg, tag, *arch, *printInfo)
var client dget.Client
if *proxy != "" {
proxyUrl, err := url.Parse("http://proxyIp:proxyPort")
if err != nil {
logrus.Fatalln("代理地址"+*proxy+"错误", err)
}
client.SetClient(&http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyUrl),
},
})
} else {
client.SetClient(http.DefaultClient)
}
err := client.Install(registry, pkg, tag, *arch, *printInfo)
if err != nil {
logrus.Fatalln("下载发生错误", err)
}

View File

@ -12,6 +12,7 @@ import (
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
@ -69,7 +70,15 @@ type PackageConfig struct {
Layers []string
}
func Install(_registry, d, tag string, arch string, printInfo bool) (err error) {
type Client struct {
c *http.Client
}
func (m *Client) SetClient(c *http.Client) {
m.c = c
}
func (m *Client) Install(_registry, d, tag string, arch string, printInfo bool) (err error) {
var authUrl = _authUrl
var regService = _regService
resp, err := http.Get(fmt.Sprintf("https://%s/v2/", _registry))
@ -99,9 +108,9 @@ func Install(_registry, d, tag string, arch string, printInfo bool) (err error)
var req *http.Request
var url = fmt.Sprintf("https://%s/v2/%s/manifests/%s", _registry, d, tag)
req, err = http.NewRequest("GET", url, nil)
logrus.Infoln("获取manifests信息", url)
var manifestURL = fmt.Sprintf("https://%s/v2/%s/manifests/%s", _registry, d, tag)
req, err = http.NewRequest("GET", manifestURL, nil)
logrus.Infoln("获取manifests信息", manifestURL)
if err == nil {
logrus.Debugln("Authorization by", accessToken)
req.Header.Add("Authorization", "Bearer "+accessToken)
@ -109,7 +118,7 @@ func Install(_registry, d, tag string, arch string, printInfo bool) (err error)
var authHeader = req.Header
resp, err = http.DefaultClient.Do(req)
resp, err = m.c.Do(req)
if resp.StatusCode != 200 {
bts, er := ioutil.ReadAll(resp.Body)
resp.Body.Close()
@ -118,10 +127,10 @@ func Install(_registry, d, tag string, arch string, printInfo bool) (err error)
case 401:
logrus.Errorf("[-] Cannot fetch manifest for %s [HTTP %d] with error access_token", d, resp.StatusCode)
case 404:
logrus.Errorf("[-] Cannot fetch manifest for %s [HTTP %d] with url %s", d, resp.StatusCode, url)
logrus.Errorf("[-] Cannot fetch manifest for %s [HTTP %d] with url %s", d, resp.StatusCode, manifestURL)
resp.Body.Close()
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.list.v2+json")
resp, err = http.DefaultClient.Do(req)
resp, err = m.c.Do(req)
bts, er := ioutil.ReadAll(resp.Body)
fmt.Println(string(bts), er)
}
@ -150,6 +159,8 @@ func Install(_registry, d, tag string, arch string, printInfo bool) (err error)
if m.Platform.OS+"/"+m.Platform.Architecture == arch {
logrus.Infoln("找到匹配的架构,开始下载")
selectedManifest = &m
req.URL, _ = url.Parse(fmt.Sprintf("https://%s/v2/%s/manifests/%s", _registry, d, m.Digest.String()))
break
}
}
if printInfo {
@ -161,13 +172,14 @@ func Install(_registry, d, tag string, arch string, printInfo bool) (err error)
return errors.New("未找到匹配的架构:" + arch)
}
logrus.Debug("找到的架构信息为", selectedManifest)
req.Header.Set("Accept", selectedManifest.MediaType)
}
case "application/vnd.docker.distribution.manifest.v1+prettyjws":
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
}
resp, err = http.DefaultClient.Do(req)
resp, err = m.c.Do(req)
if err == nil {
@ -178,7 +190,7 @@ func Install(_registry, d, tag string, arch string, printInfo bool) (err error)
resp.Body.Close()
logrus.Infof("获得Manifest信息共%d层需要下载", len(info.Layers))
err = download(_registry, d, tag, info.Config.Digest, authHeader, info.Layers)
err = m.download(_registry, d, tag, info.Config.Digest, authHeader, info.Layers)
if err != nil {
goto response
}
@ -193,7 +205,7 @@ response:
return
}
func download(_registry, d, tag string, digest digest.Digest, authHeader http.Header, layers []Layer) (err error) {
func (m *Client) download(_registry, d, tag string, digest digest.Digest, authHeader http.Header, layers []Layer) (err error) {
var tmpDir = fmt.Sprintf("tmp_%s_%s", d, tag)
err = os.MkdirAll(tmpDir, 0777)
if err == nil {
@ -205,7 +217,7 @@ func download(_registry, d, tag string, digest digest.Digest, authHeader http.He
if err == nil {
req.Header = authHeader
var resp *http.Response
resp, err = http.DefaultClient.Do(req)
resp, err = m.c.Do(req)
if err == nil {
var dest *os.File
dest, err = os.OpenFile(filepath.Join(tmpDir, digest.Encoded()+".json"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
@ -247,7 +259,7 @@ func download(_registry, d, tag string, digest digest.Digest, authHeader http.He
if err == nil {
req.Header = authHeader
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
resp, err = http.DefaultClient.Do(req)
resp, err = m.c.Do(req)
if err == nil {
if resp.StatusCode != 200 {
defer resp.Body.Close()
@ -256,7 +268,7 @@ func download(_registry, d, tag string, digest digest.Digest, authHeader http.He
if err == nil {
req.Header = authHeader
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
resp, err = http.DefaultClient.Do(req)
resp, err = m.c.Do(req)
if err == nil {
if resp.StatusCode != 200 {
err = fmt.Errorf("download from customized url fail for layer[%d]", n)