pax_global_header00006660000000000000000000000064145570033340014516gustar00rootroot0000000000000052 comment=09a5c786c19d9a045b59a12746315c431eccdeaa golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/000077500000000000000000000000001455700333400243465ustar00rootroot00000000000000golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/.gitignore000066400000000000000000000000071455700333400263330ustar00rootroot00000000000000.tools/golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/.golangci.yml000066400000000000000000000014761455700333400267420ustar00rootroot00000000000000# See https://github.com/golangci/golangci-lint#config-file run: deadline: 1m #Default issues-exit-code: 1 #Default tests: true #Default linters: enable: - misspell - goimports - golint - stylecheck - unconvert - dupl - gosec - scopelint - nakedret - gochecknoinits - goconst - gocritic - gocyclo - lll - maligned - prealloc - unparam - errcheck linters-settings: misspell: locale: US #ignore-words: # - someword goimports: local-prefixes: github.com/heroku/docker-registry-client gocyclo: # minimal code complexity to report, 30 by default (but we recommend 10-20) min-complexity: 14 lll: # max line length, lines longer will be reported. Default is 120. line-length: 130 maligned: suggest-new: true golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/.travis.yml000066400000000000000000000003051455700333400264550ustar00rootroot00000000000000language: go go: - 1.13.x - 1.12.x - 1.11.x sudo: false env: global: - GO111MODULE=on - GOTEST_OPT="-v -race" - LINT_RUN_OPTS="" script: make test notifications: email: false golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/CODEOWNERS000066400000000000000000000002141455700333400257360ustar00rootroot00000000000000# Comment line immediately above ownership line is reserved for related gus information. Please be careful while editing. #ECCN:Open Source golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/LICENSE.md000066400000000000000000000027361455700333400257620ustar00rootroot00000000000000Copyright (c) 2015, Salesforce.com, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/Makefile000066400000000000000000000020051455700333400260030ustar00rootroot00000000000000PKG_SPEC = ./registry/... MOD = -mod=readonly GOTEST = go test $(MOD) GOTEST_COVERAGE_OPT = -coverprofile=coverage.txt -covermode=atomic TOOLS_DIR = $(shell git rev-parse --show-toplevel)/.tools GOBUILD = go build $(MOD) ENV ?= development LINT_RUN_OPTS ?= --fix override GOTEST_OPT += -timeout 30s .DEFAULT_GOAL := precommit $(TOOLS_DIR)/golangci-lint: go.mod go.sum tools.go $(GOBUILD) -o $(TOOLS_DIR)/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint .PHONY: vars vars: @echo "PKG_SPEC=$(PKG_SPEC)" @echo "MOD=$(MOD)" @echo "GOTEST=$(GOTEST)" @echo "COVERAGE_OPT=$(COVERAGE_OPT)" @echo "TOOLS_DIR=$(TOOLS_DIR)" @echo "GOBUILD=$(GOBUILD)" @echo "ENV=$(ENV)" .PHONY: precommit precommit: lint test coverage .PHONY: lint lint: $(TOOLS_DIR)/golangci-lint $(TOOLS_DIR)/golangci-lint run $(LINT_RUN_OPTS) .PHONY: coverage coverage: $(GOTEST) $(GOTEST_OPT) $(GOTEST_COVERAGE_OPT) $(PKG_SPEC) go tool cover -html=coverage.txt -o coverage.html .PHONY: test test: $(GOTEST) $(GOTEST_OPT) $(PKG_SPEC)golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/README.md000066400000000000000000000067061455700333400256360ustar00rootroot00000000000000# Docker Registry Client An API client for the [V2 Docker Registry API](http://docs.docker.com/registry/spec/api/), for Go applications. ## Imports ```go import ( "github.com/heroku/docker-registry-client/registry" "github.com/docker/distribution/digest" "github.com/docker/distribution/manifest" "github.com/docker/libtrust" ) ``` ## Creating A Client ```go url := "https://registry-1.docker.io/" username := "" // anonymous password := "" // anonymous hub, err := registry.New(url, username, password) ``` Creating a registry will also ping it to verify that it supports the registry API, which may fail. Failures return non-`nil` err values. Authentication supports both HTTP Basic authentication and OAuth2 token negotiation. ## Listing Repositories ```go repositories, err := hub.Repositories() ``` The repositories will be returned as a slice of `string`s. ## Listing Tags Each Docker repository has a set of tags -- named images that can be downloaded. ```go tags, err := hub.Tags("heroku/cedar") ``` The tags will be returned as a slice of `string`s. ## Downloading Manifests Each tag has a corresponding manifest, which lists the layers and image configuration for that tag. ```go manifest, err := hub.Manifest("heroku/cedar", "14") ``` Schema V2 ```go manifest, err := hub.ManifestV2("heroku/cedar", "14") ``` The returned manifest will be a `manifest.SignedManifest` pointer. For details, see the `github.com/docker/distribution/manifest` library. ## Retrieving Manifest Digest A manifest is identified by a digest. ```go digest, err := hub.ManifestDigest("heroku/cedar", "14") ``` The returned digest will be a `digest.Digest`. See `github.com/docker/distribution/digest`. ## Deleting Manifest To delete a manifest ```go digest, err := hub.ManifestDigest("heroku/cedar", "14") err = hub.DeleteManifest("heroku/cedar", digest) ``` Please notice that, as specified by the Registry v2 API, this call doesn't actually remove the fs layers used by the image. ## Downloading Layers Each manifest contains a list of layers, filesystem images that Docker will compose to create containers. ```go // or obtain the digest from an existing manifest's FSLayer list digest := digest.NewDigestFromHex( "sha256", "a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", ) reader, err := hub.DownloadBlob("heroku/cedar", digest) if reader != nil { defer reader.Close() } if err != nil { return err } ``` ## Uploading Layers This library can also publish new layers: ```go digest := digest.NewDigestFromHex( "sha256", "a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", ) exists, err := hub.HasBlob("example/repo", digest) if err != nil { // … } if !exists { stream := … hub.UploadBlob("example/repo", digest, stream) } ``` ## Uploading Manifests First, create a signed manifest: ```go manifest := &manifest.Manifest{ Versioned: manifest.Versioned{ SchemaVersion: 1, }, Tag: "latest", // … } key, err := libtrust.GenerateECP256PrivateKey() if err != nil { // … } signedManifest := manifest.Sign(manifest, key) if err != nil { // … } ``` Production applications should probably reuse keys, rather than generating ephemeral keys. See the libtrust documentation for details. Then, upload the signed manifest: ```go err := hub.PutManifest("example/repo", "latest", signedManifest) if err != nil { // … } ``` This will also create or update tags, as necessary. golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/bin/000077500000000000000000000000001455700333400251165ustar00rootroot00000000000000golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/bin/git-pre-commit.sh000077500000000000000000000001211455700333400303040ustar00rootroot00000000000000#!/bin/sh git stash -q --keep-index trap "git stash pop -q" EXIT make precommit golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/go.mod000066400000000000000000000015001455700333400254500ustar00rootroot00000000000000module github.com/heroku/docker-registry-client go 1.12 require ( github.com/docker/distribution v0.0.0-20171011171712-7484e51bf6af github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/golangci/golangci-lint v1.17.2-0.20190909185456-6163a8a79084 github.com/gorilla/mux v1.7.3 // indirect github.com/opencontainers/go-digest v1.0.0-rc1 github.com/sirupsen/logrus v1.4.2 // indirect github.com/stretchr/testify v1.4.0 // indirect ) // From/For golangci-lint. Can be removed once v1.17.2 (or newer) is released replace ( // https://github.com/ultraware/funlen/pull/1 github.com/ultraware/funlen => github.com/golangci/funlen v0.0.0-20190909161642-5e59b9546114 // https://github.com/golang/tools/pull/139 golang.org/x/tools => github.com/golangci/tools v0.0.0-20190909104219-979bdb7f8cc8 ) golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/go.sum000066400000000000000000000547711455700333400255170ustar00rootroot00000000000000github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OpenPeeDeeP/depguard v1.0.0 h1:k9QF73nrHT3nPLz3lu6G5s+3Hi8Je36ODr1F5gjAXXM= github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v0.0.0-20171011171712-7484e51bf6af h1:ujR+JcSHkOZMctuIgvi+a/VHpTn0nSy0W7eV5p34xjg= github.com/docker/distribution v0.0.0-20171011171712-7484e51bf6af/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/fatih/color v1.6.0 h1:66qjqZk8kalYAvDRtM1AdAJQI0tj4Wrue3Eq3B3pmFU= github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540 h1:djv/qAomOVj8voCHt0M0OYwR/4vfDq1zNKSPKjJCexs= github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA= github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/mock v1.0.0 h1:HzcpUG60pfl43n9d2qbdi/3l1uKpAmxlfWEPWtV/QxM= github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= github.com/golangci/funlen v0.0.0-20190909161642-5e59b9546114 h1:eubR6yxVUUlbUuBBn1ONXalxuCjCrDfKvRc0eF6Xnio= github.com/golangci/funlen v0.0.0-20190909161642-5e59b9546114/go.mod h1:kJMYlbyWK6uaK+J3BjNrQMk0t3CgLgsXgQnOlS4iGeg= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c h1:/7detzz5stiXWPzkTlPTzkBEIIE4WGpppBJYjKqBiPI= github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM= github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70uaOiMbNnluTg7gyQhtGqLQncQh+4J8= github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98 h1:0OkFarm1Zy2CjCiDKfK9XHgmc2wbDlRMD2hD8anAJHU= github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= github.com/golangci/golangci-lint v1.17.2-0.20190909185456-6163a8a79084 h1:Z4/yXcGr9zrQrcvHkC8f3agyK1dwt/t6zC/8gi6X64Q= github.com/golangci/golangci-lint v1.17.2-0.20190909185456-6163a8a79084/go.mod h1:jXakAOSd+FMU9dP3D6IfBK7HyD1q/RLHI9NOY8veycY= github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547 h1:fUdgm/BdKvwOHxg5AhNbkNRp2mSy8sxTXyBVs/laQHo= github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU= github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217 h1:En/tZdwhAn0JNwLuXzP3k2RVtMqMmOEK7Yu/g3tmtJE= github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770 h1:EL/O5HGrF7Jaq0yNhBLucz9hTuRzj2LdwGBOaENgxIk= github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0 h1:HVfrLniijszjS1aiNg8JbBMO2+E1WIQ+j/gL4SQqGPg= github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= github.com/golangci/tools v0.0.0-20190909104219-979bdb7f8cc8 h1:zlLYFLThJpbBZwGgIjfUzDg3gi32safjHB0omx3qtvo= github.com/golangci/tools v0.0.0-20190909104219-979bdb7f8cc8/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno= github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.7.6 h1:U+1DqNen04MdEPgFiIwdOUiqZ8qPa37xgogX/sd3+54= github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238 h1:+MZW2uvHgN8kYvksEN3f7eFL2wpzk0GxmlFsMybWc7E= github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663 h1:Ri1EhipkbhWsffPJ3IPlrb4SkTOPa2PfRXp3jchBczw= github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/pelletier/go-toml v1.1.0 h1:cmiOvKzEunMsAxyhXSzpL5Q1CRKpVv0KQsnAIcSEVYM= github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/sirupsen/logrus v1.0.5 h1:8c8b5uO0zS4X6RPl/sd1ENwSkIc0/H2PaHxE3udaE8I= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs= github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/spf13/afero v1.1.0 h1:bopulORc2JeYaxfHLvJa5NzxviA9PoWhpiiJkru7Ji4= github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg= github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cobra v0.0.2 h1:NfkwRbgViGoyjBKsLI0QMDcuMnhM+SBg3T0cGfpvKDE= github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig= github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso= github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec h1:AmoEvWAO3nDx1MEcMzPh+GzOOIA5Znpv6++c7bePPY0= github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a h1:YX8ljsm6wXlHZO+aRz9Exqr0evNhKRNe5K/gi+zKh4U= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34 h1:duVSyluuJA+u0BnkcLR01smoLrGgDTfWt5c8ODYG8fU= mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/000077500000000000000000000000001455700333400262165ustar00rootroot00000000000000golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/authchallenge.go000066400000000000000000000064621455700333400313610ustar00rootroot00000000000000package registry import ( "net/http" "strings" ) // Octet types from RFC 2616. type octetType byte // AuthorizationChallenge carries information // from a WWW-Authenticate response header. type AuthorizationChallenge struct { Scheme string Parameters map[string]string } var octetTypes [256]octetType const ( isToken octetType = 1 << iota isSpace ) //nolint:gochecknoinits func init() { // OCTET = // CHAR = // CTL = // CR = // LF = // SP = // HT = // <"> = // CRLF = CR LF // LWS = [CRLF] 1*( SP | HT ) // TEXT = // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT // token = 1* // qdtext = > for c := 0; c < 256; c++ { var t octetType isCtl := c <= 31 || c == 127 isChar := 0 <= c && c <= 127 isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) if strings.ContainsRune(" \t\r\n", rune(c)) { t |= isSpace } if isChar && !isCtl && !isSeparator { t |= isToken } octetTypes[c] = t } } func parseAuthHeader(header http.Header) []*AuthorizationChallenge { var challenges []*AuthorizationChallenge for _, h := range header[http.CanonicalHeaderKey("WWW-Authenticate")] { v, p := parseValueAndParams(h) if v != "" { challenges = append(challenges, &AuthorizationChallenge{Scheme: v, Parameters: p}) } } return challenges } func parseValueAndParams(header string) (value string, params map[string]string) { params = make(map[string]string) value, s := expectToken(header) if value == "" { return } value = strings.ToLower(value) s = "," + skipSpace(s) for strings.HasPrefix(s, ",") { var pkey string pkey, s = expectToken(skipSpace(s[1:])) if pkey == "" { return } if !strings.HasPrefix(s, "=") { return } var pvalue string pvalue, s = expectTokenOrQuoted(s[1:]) if pvalue == "" { return } pkey = strings.ToLower(pkey) params[pkey] = pvalue s = skipSpace(s) } return } func skipSpace(s string) (rest string) { i := 0 for ; i < len(s); i++ { if octetTypes[s[i]]&isSpace == 0 { break } } return s[i:] } func expectToken(s string) (token, rest string) { i := 0 for ; i < len(s); i++ { if octetTypes[s[i]]&isToken == 0 { break } } return s[:i], s[i:] } func expectTokenOrQuoted(s string) (value string, rest string) { if !strings.HasPrefix(s, "\"") { return expectToken(s) } s = s[1:] for i := 0; i < len(s); i++ { switch s[i] { case '"': return s[:i], s[i+1:] case '\\': p := make([]byte, len(s)-1) j := copy(p, s[:i]) escape := true for i += i; i < len(s); i++ { b := s[i] switch { case escape: escape = false p[j] = b j++ case b == '\\': escape = true case b == '"': return string(p[:j]), s[i+1:] default: p[j] = b j++ } } return "", "" } } return "", "" } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/basictransport.go000066400000000000000000000007051455700333400316050ustar00rootroot00000000000000package registry import ( "net/http" "strings" ) type BasicTransport struct { Transport http.RoundTripper URL string Username string Password string } func (t *BasicTransport) RoundTrip(req *http.Request) (*http.Response, error) { if strings.HasPrefix(req.URL.String(), t.URL) { if t.Username != "" || t.Password != "" { req.SetBasicAuth(t.Username, t.Password) } } resp, err := t.Transport.RoundTrip(req) return resp, err } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/blob.go000066400000000000000000000054461455700333400274740ustar00rootroot00000000000000package registry import ( "io" "net/http" "net/url" "github.com/docker/distribution" digest "github.com/opencontainers/go-digest" ) func (registry *Registry) DownloadBlob(repository string, digest digest.Digest) (io.ReadCloser, error) { url := registry.url("/v2/%s/blobs/%s", repository, digest) registry.Logf("registry.blob.download url=%s repository=%s digest=%s", url, repository, digest) resp, err := registry.Client.Get(url) if err != nil { return nil, err } return resp.Body, nil } func (registry *Registry) UploadBlob(repository string, digest digest.Digest, content io.Reader) error { uploadURL, err := registry.initiateUpload(repository) if err != nil { return err } q := uploadURL.Query() q.Set("digest", digest.String()) uploadURL.RawQuery = q.Encode() registry.Logf("registry.blob.upload url=%s repository=%s digest=%s", uploadURL, repository, digest) upload, err := http.NewRequest("PUT", uploadURL.String(), content) if err != nil { return err } upload.Header.Set("Content-Type", "application/octet-stream") _, err = registry.Client.Do(upload) return err } func (registry *Registry) HasBlob(repository string, digest digest.Digest) (bool, error) { checkURL := registry.url("/v2/%s/blobs/%s", repository, digest) registry.Logf("registry.blob.check url=%s repository=%s digest=%s", checkURL, repository, digest) resp, err := registry.Client.Head(checkURL) if resp != nil { defer resp.Body.Close() } if err == nil { return resp.StatusCode == http.StatusOK, nil } urlErr, ok := err.(*url.Error) if !ok { return false, err } httpErr, ok := urlErr.Err.(*HTTPStatusError) if !ok { return false, err } if httpErr.Response.StatusCode == http.StatusNotFound { return false, nil } return false, err } func (registry *Registry) BlobMetadata(repository string, digest digest.Digest) (distribution.Descriptor, error) { checkURL := registry.url("/v2/%s/blobs/%s", repository, digest) registry.Logf("registry.blob.check url=%s repository=%s digest=%s", checkURL, repository, digest) resp, err := registry.Client.Head(checkURL) if resp != nil { defer resp.Body.Close() } if err != nil { return distribution.Descriptor{}, err } return distribution.Descriptor{ Digest: digest, Size: resp.ContentLength, }, nil } func (registry *Registry) initiateUpload(repository string) (*url.URL, error) { initiateURL := registry.url("/v2/%s/blobs/uploads/", repository) registry.Logf("registry.blob.initiate-upload url=%s repository=%s", initiateURL, repository) resp, err := registry.Client.Post(initiateURL, "application/octet-stream", nil) if resp != nil { defer resp.Body.Close() } if err != nil { return nil, err } location := resp.Header.Get("Location") locationURL, err := url.Parse(location) if err != nil { return nil, err } return locationURL, nil } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/errortransport.go000066400000000000000000000017561455700333400316640ustar00rootroot00000000000000package registry import ( "fmt" "io/ioutil" "net/http" ) type HTTPStatusError struct { Response *http.Response // Copied from `Response.Body` to avoid problems with unclosed bodies later. // Nobody calls `err.Response.Body.Close()`, ever. Body []byte } func (err *HTTPStatusError) Error() string { return fmt.Sprintf("http: non-successful response (status=%v body=%q)", err.Response.StatusCode, err.Body) } var _ error = &HTTPStatusError{} type ErrorTransport struct { Transport http.RoundTripper } func (t *ErrorTransport) RoundTrip(request *http.Request) (*http.Response, error) { resp, err := t.Transport.RoundTrip(request) if err != nil { return resp, err } if resp.StatusCode >= 400 { defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("http: failed to read response body (status=%v, err=%q)", resp.StatusCode, err) } return nil, &HTTPStatusError{ Response: resp, Body: body, } } return resp, err } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/json.go000066400000000000000000000026071455700333400275230ustar00rootroot00000000000000package registry import ( "encoding/json" "errors" "net/http" "regexp" ) var ( ErrNoMorePages = errors.New("no more pages") ) // getPaginatedJSON accepts a string and a pointer, and returns the // next page URL while updating pointed-to variable with a parsed JSON // value. When there are no more pages it returns `ErrNoMorePages`. func (registry *Registry) getPaginatedJSON(url string, response interface{}) (string, error) { resp, err := registry.Client.Get(url) if err != nil { return "", err } defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) err = decoder.Decode(response) if err != nil { return "", err } return getNextLink(resp) } // Matches an RFC 5988 (https://tools.ietf.org/html/rfc5988#section-5) // Link header. For example, // // ; type="application/json"; rel="next" // // The URL is _supposed_ to be wrapped by angle brackets `< ... >`, // but e.g., quay.io does not include them. Similarly, params like // `rel="next"` may not have quoted values in the wild. var nextLinkRE = regexp.MustCompile(`^ *]+)>? *(?:;[^;]*)*; *rel="?next"?(?:;.*)?`) func getNextLink(resp *http.Response) (string, error) { for _, link := range resp.Header[http.CanonicalHeaderKey("Link")] { parts := nextLinkRE.FindStringSubmatch(link) if parts != nil { return parts[1], nil } } return "", ErrNoMorePages } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/manifest.go000066400000000000000000000063371455700333400303640ustar00rootroot00000000000000package registry import ( "bytes" "io/ioutil" "net/http" "github.com/docker/distribution" "github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema2" digest "github.com/opencontainers/go-digest" ) func (registry *Registry) Manifest(repository, reference string) (*schema1.SignedManifest, error) { url := registry.url("/v2/%s/manifests/%s", repository, reference) registry.Logf("registry.manifest.get url=%s repository=%s reference=%s", url, repository, reference) req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } req.Header.Set("Accept", schema1.MediaTypeManifest) resp, err := registry.Client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } signedManifest := &schema1.SignedManifest{} err = signedManifest.UnmarshalJSON(body) if err != nil { return nil, err } return signedManifest, nil } func (registry *Registry) ManifestV2(repository, reference string) (*schema2.DeserializedManifest, error) { url := registry.url("/v2/%s/manifests/%s", repository, reference) registry.Logf("registry.manifest.get url=%s repository=%s reference=%s", url, repository, reference) req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } req.Header.Set("Accept", schema2.MediaTypeManifest) resp, err := registry.Client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } deserialized := &schema2.DeserializedManifest{} err = deserialized.UnmarshalJSON(body) if err != nil { return nil, err } return deserialized, nil } func (registry *Registry) ManifestDigest(repository, reference string) (digest.Digest, error) { url := registry.url("/v2/%s/manifests/%s", repository, reference) registry.Logf("registry.manifest.head url=%s repository=%s reference=%s", url, repository, reference) resp, err := registry.Client.Head(url) if resp != nil { defer resp.Body.Close() } if err != nil { return "", err } return digest.Parse(resp.Header.Get("Docker-Content-Digest")) } func (registry *Registry) DeleteManifest(repository string, digest digest.Digest) error { url := registry.url("/v2/%s/manifests/%s", repository, digest) registry.Logf("registry.manifest.delete url=%s repository=%s reference=%s", url, repository, digest) req, err := http.NewRequest("DELETE", url, nil) if err != nil { return err } resp, err := registry.Client.Do(req) if resp != nil { defer resp.Body.Close() } if err != nil { return err } return nil } func (registry *Registry) PutManifest(repository, reference string, manifest distribution.Manifest) error { url := registry.url("/v2/%s/manifests/%s", repository, reference) registry.Logf("registry.manifest.put url=%s repository=%s reference=%s", url, repository, reference) mediaType, payload, err := manifest.Payload() if err != nil { return err } buffer := bytes.NewBuffer(payload) req, err := http.NewRequest("PUT", url, buffer) if err != nil { return err } req.Header.Set("Content-Type", mediaType) resp, err := registry.Client.Do(req) if resp != nil { defer resp.Body.Close() } return err } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/registry.go000066400000000000000000000055431455700333400304240ustar00rootroot00000000000000package registry import ( "crypto/tls" "fmt" "log" "net/http" "strings" ) type LogfCallback func(format string, args ...interface{}) /* * Discard log messages silently. */ func Quiet(format string, args ...interface{}) { /* discard logs */ } /* * Pass log messages along to Go's "log" module. */ func Log(format string, args ...interface{}) { log.Printf(format, args...) } type Registry struct { URL string Client *http.Client Logf LogfCallback } /* * Create a new Registry with the given URL and credentials, then Ping()s it * before returning it to verify that the registry is available. * * You can, alternately, construct a Registry manually by populating the fields. * This passes http.DefaultTransport to WrapTransport when creating the * http.Client. */ func New(registryURL, username, password string) (*Registry, error) { transport := http.DefaultTransport return newFromTransport(registryURL, username, password, transport, Log) } /* * Create a new Registry, as with New, using an http.Transport that disables * SSL certificate verification. */ func NewInsecure(registryURL, username, password string) (*Registry, error) { transport := &http.Transport{ TLSClientConfig: &tls.Config{ // TODO: Why? InsecureSkipVerify: true, //nolint:gosec }, } return newFromTransport(registryURL, username, password, transport, Log) } /* * Given an existing http.RoundTripper such as http.DefaultTransport, build the * transport stack necessary to authenticate to the Docker registry API. This * adds in support for OAuth bearer tokens and HTTP Basic auth, and sets up * error handling this library relies on. */ func WrapTransport(transport http.RoundTripper, url, username, password string) http.RoundTripper { tokenTransport := &TokenTransport{ Transport: transport, Username: username, Password: password, } basicAuthTransport := &BasicTransport{ Transport: tokenTransport, URL: url, Username: username, Password: password, } errorTransport := &ErrorTransport{ Transport: basicAuthTransport, } return errorTransport } func newFromTransport(registryURL, username, password string, transport http.RoundTripper, logf LogfCallback) (*Registry, error) { url := strings.TrimSuffix(registryURL, "/") transport = WrapTransport(transport, url, username, password) registry := &Registry{ URL: url, Client: &http.Client{ Transport: transport, }, Logf: logf, } if err := registry.Ping(); err != nil { return nil, err } return registry, nil } func (r *Registry) url(pathTemplate string, args ...interface{}) string { pathSuffix := fmt.Sprintf(pathTemplate, args...) url := fmt.Sprintf("%s%s", r.URL, pathSuffix) return url } func (r *Registry) Ping() error { url := r.url("/v2/") r.Logf("registry.ping url=%s", url) resp, err := r.Client.Get(url) if resp != nil { defer resp.Body.Close() } return err } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/repositories.go000066400000000000000000000012521455700333400312740ustar00rootroot00000000000000package registry type repositoriesResponse struct { Repositories []string `json:"repositories"` } func (registry *Registry) Repositories() ([]string, error) { url := registry.url("/v2/_catalog") repos := make([]string, 0, 10) var err error //We create this here, otherwise url will be rescoped with := var response repositoriesResponse for { registry.Logf("registry.repositories url=%s", url) url, err = registry.getPaginatedJSON(url, &response) switch err { case ErrNoMorePages: repos = append(repos, response.Repositories...) return repos, nil case nil: repos = append(repos, response.Repositories...) continue default: return nil, err } } } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/tags.go000066400000000000000000000010751455700333400275060ustar00rootroot00000000000000package registry type tagsResponse struct { Tags []string `json:"tags"` } func (registry *Registry) Tags(repository string) (tags []string, err error) { url := registry.url("/v2/%s/tags/list", repository) var response tagsResponse for { registry.Logf("registry.tags url=%s repository=%s", url, repository) url, err = registry.getPaginatedJSON(url, &response) switch err { case ErrNoMorePages: tags = append(tags, response.Tags...) return tags, nil case nil: tags = append(tags, response.Tags...) continue default: return nil, err } } } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/registry/tokentransport.go000066400000000000000000000053101455700333400316410ustar00rootroot00000000000000package registry import ( "encoding/json" "fmt" "net/http" "net/url" ) type TokenTransport struct { Transport http.RoundTripper Username string Password string } func (t *TokenTransport) RoundTrip(req *http.Request) (*http.Response, error) { resp, err := t.Transport.RoundTrip(req) if err != nil { return resp, err } if authService := isTokenDemand(resp); authService != nil { resp.Body.Close() resp, err = t.authAndRetry(authService, req) } return resp, err } type authToken struct { Token string `json:"token"` } func (t *TokenTransport) authAndRetry(authService *authService, req *http.Request) (*http.Response, error) { token, authResp, err := t.auth(authService) if err != nil { return authResp, err } retryResp, err := t.retry(req, token) return retryResp, err } func (t *TokenTransport) auth(authService *authService) (string, *http.Response, error) { authReq, err := authService.Request(t.Username, t.Password) if err != nil { return "", nil, err } client := http.Client{ Transport: t.Transport, } response, err := client.Do(authReq) if err != nil { return "", nil, err } if response.StatusCode != http.StatusOK { return "", response, err } defer response.Body.Close() var authToken authToken decoder := json.NewDecoder(response.Body) err = decoder.Decode(&authToken) if err != nil { return "", nil, err } return authToken.Token, nil, nil } func (t *TokenTransport) retry(req *http.Request, token string) (*http.Response, error) { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) resp, err := t.Transport.RoundTrip(req) return resp, err } type authService struct { Realm string Service string Scope string } func (authService *authService) Request(username, password string) (*http.Request, error) { url, err := url.Parse(authService.Realm) if err != nil { return nil, err } q := url.Query() q.Set("service", authService.Service) if authService.Scope != "" { q.Set("scope", authService.Scope) } url.RawQuery = q.Encode() request, err := http.NewRequest("GET", url.String(), nil) if username != "" || password != "" { request.SetBasicAuth(username, password) } return request, err } func isTokenDemand(resp *http.Response) *authService { if resp == nil { return nil } if resp.StatusCode != http.StatusUnauthorized { return nil } return parseOauthHeader(resp) } func parseOauthHeader(resp *http.Response) *authService { challenges := parseAuthHeader(resp.Header) for _, challenge := range challenges { if challenge.Scheme == "bearer" { return &authService{ Realm: challenge.Parameters["realm"], Service: challenge.Parameters["service"], Scope: challenge.Parameters["scope"], } } } return nil } golang-github-heroku-docker-registry-client-0.0~git20211012.9463674/tools.go000066400000000000000000000001721455700333400260350ustar00rootroot00000000000000// +build tools package tools import ( _ "github.com/golangci/golangci-lint/cmd/golangci-lint" // CLI mega lint tool )