diff --git a/README.md b/README.md index 44430fb..54fc0ee 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/bin/linux_amd64/dget b/bin/linux_amd64/dget index 4256929..f964992 100644 Binary files a/bin/linux_amd64/dget and b/bin/linux_amd64/dget differ diff --git a/bin/linux_arm/dget b/bin/linux_arm/dget index 21b5632..9d4a7e1 100644 Binary files a/bin/linux_arm/dget and b/bin/linux_arm/dget differ diff --git a/bin/windows_amd64/dget.exe b/bin/windows_amd64/dget.exe index 58f0a96..ffe850d 100644 Binary files a/bin/windows_amd64/dget.exe and b/bin/windows_amd64/dget.exe differ diff --git a/cmd/dget/main.go b/cmd/dget/main.go index 39f9741..d908153 100644 --- a/cmd/dget/main.go +++ b/cmd/dget/main.go @@ -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(®istry, "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) } diff --git a/install.go b/install.go index 1dc6151..55195e2 100644 --- a/install.go +++ b/install.go @@ -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)