Skip to content

Commit

Permalink
Refactor: Use *repository.Repository abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanilves committed Feb 7, 2018
1 parent c786bed commit 9380458
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 39 deletions.
12 changes: 3 additions & 9 deletions main.go
Expand Up @@ -133,18 +133,15 @@ func main() {
username, password, _ := dockerConfig.GetCredentials(repo.Registry())

remoteTags, err := remote.FetchTags(
repo.Registry(),
repo.Path(),
repo.Filter(),
repo,
username,
password,
repo.WebSchema(),
)
if err != nil {
suicide(err, true)
}

localTags, err := local.FetchTags(repo.Name(), repo.Filter(), dc)
localTags, err := local.FetchTags(repo, dc)
if err != nil {
suicide(err, true)
}
Expand Down Expand Up @@ -191,12 +188,9 @@ func main() {
pushRepo, _ := repository.ParseRef(pushRef)

alreadyPushedTags, err := remote.FetchTags(
pushRepo.Registry(),
pushRepo.Path(),
pushRepo.Filter(),
pushRepo,
username,
password,
pushRepo.WebSchema(),
)
if err != nil {
if !strings.Contains(err.Error(), "404 Not Found") {
Expand Down
17 changes: 7 additions & 10 deletions main_test.go
Expand Up @@ -42,16 +42,13 @@ func runTestForFetchTags(
) {
repo, _ := repository.ParseRef(repoName)

registry := repo.Registry()
repoPath := repo.Path()

tags, err := remote.FetchTags(registry, repoPath, filter, username, password, repo.WebSchema())
tags, err := remote.FetchTags(repo, username, password)
if err != nil {
t.Fatalf(
"Failed to fetch tags (%s~/%s/) from '%s' registry: %s",
repoPath,
filter,
registry,
repo.Path(),
repo.Filter(),
repo.Registry(),
err.Error(),
)
}
Expand All @@ -62,9 +59,9 @@ func runTestForFetchTags(
t.Fatalf(
"Tag '%s' not found in query (%s~/%s/) to '%s' registry.\nTags: %#v",
name,
repoPath,
filter,
registry,
repo.Path(),
repo.Filter(),
repo.Registry(),
tags,
)
}
Expand Down
9 changes: 5 additions & 4 deletions tag/local/local.go
Expand Up @@ -4,13 +4,14 @@ import (
"strings"

dockerclient "github.com/ivanilves/lstags/docker/client"
"github.com/ivanilves/lstags/repository"
"github.com/ivanilves/lstags/tag"
"github.com/ivanilves/lstags/util"
)

// FetchTags looks up Docker repo tags and IDs present on local Docker daemon
func FetchTags(repoName, filter string, dc *dockerclient.DockerClient) (map[string]*tag.Tag, error) {
imageSummaries, err := dc.ListImagesForRepo(repoName)
func FetchTags(repo *repository.Repository, dc *dockerclient.DockerClient) (map[string]*tag.Tag, error) {
imageSummaries, err := dc.ListImagesForRepo(repo.Name())
if err != nil {
return nil, err
}
Expand All @@ -19,14 +20,14 @@ func FetchTags(repoName, filter string, dc *dockerclient.DockerClient) (map[stri

for _, imageSummary := range imageSummaries {
repoDigest := extractRepoDigest(imageSummary.RepoDigests)
tagNames := extractTagNames(imageSummary.RepoTags, repoName)
tagNames := extractTagNames(imageSummary.RepoTags, repo.Name())

if repoDigest == "" {
repoDigest = "this.image.is.bad.it.has.no.digest.fuuu!"
}

for _, tagName := range tagNames {
if !util.DoesMatch(tagName, filter) {
if !util.DoesMatch(tagName, repo.Filter()) {
continue
}

Expand Down
7 changes: 4 additions & 3 deletions tag/remote/auth/auth.go
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"
"strings"

"github.com/ivanilves/lstags/repository"
"github.com/ivanilves/lstags/tag/remote/auth/basic"
"github.com/ivanilves/lstags/tag/remote/auth/bearer"
"github.com/ivanilves/lstags/tag/remote/auth/none"
Expand Down Expand Up @@ -64,8 +65,8 @@ func validateParams(method string, params map[string]string) (map[string]string,
// NewToken is a high-level function which:
// * detects authentication type (e.g. Bearer or Basic)
// * delegates actual authentication to type-specific implementation
func NewToken(registry, repoPath, username, password, webSchema string) (TokenResponse, error) {
url := webSchema + registry + "/v2"
func NewToken(repo *repository.Repository, username, password string) (TokenResponse, error) {
url := repo.WebSchema() + repo.Registry() + "/v2"

resp, err := http.Get(url)
if err != nil {
Expand All @@ -87,7 +88,7 @@ func NewToken(registry, repoPath, username, password, webSchema string) (TokenRe
case "Basic":
return basic.RequestToken(url, username, password)
case "Bearer":
return bearer.RequestToken(params["realm"], params["service"], repoPath, username, password)
return bearer.RequestToken(params["realm"], params["service"], repo.Path(), username, password)
default:
return nil, errors.New("Unknown authentication method: " + method)
}
Expand Down
37 changes: 24 additions & 13 deletions tag/remote/remote.go
Expand Up @@ -14,6 +14,7 @@ import (
"strings"
"time"

"github.com/ivanilves/lstags/repository"
"github.com/ivanilves/lstags/tag"
"github.com/ivanilves/lstags/tag/remote/auth"
"github.com/ivanilves/lstags/util"
Expand Down Expand Up @@ -146,8 +147,8 @@ func parseTagNamesJSON(data io.ReadCloser) ([]string, error) {
return tn.TagNames, nil
}

func fetchTagNames(registry, repoPath, authorization, webSchema string) ([]string, error) {
url := webSchema + registry + "/v2/" + repoPath + "/tags/list"
func fetchTagNames(repo *repository.Repository, authorization string) ([]string, error) {
url := repo.WebSchema() + repo.Registry() + "/v2/" + repo.Path() + "/tags/list"

resp, err := httpRetriableRequest(url, authorization, "v2")
if err != nil {
Expand Down Expand Up @@ -224,8 +225,8 @@ func fetchDigest(url, authorization string) (string, error) {
return digests[0], nil
}

func fetchDetails(registry, repoPath, tagName, authorization, webSchema string) (string, imageMetadata, error) {
url := webSchema + registry + "/v2/" + repoPath + "/manifests/" + tagName
func fetchDetails(repo *repository.Repository, tagName, authorization string) (string, imageMetadata, error) {
url := repo.WebSchema() + repo.Registry() + "/v2/" + repo.Path() + "/manifests/" + tagName

dc := make(chan string, 0)
mc := make(chan imageMetadata, 0)
Expand Down Expand Up @@ -313,27 +314,27 @@ func calculateBatchStepSize(stepNumber, stepsTotal, remain, limit int) int {
}

// FetchTags looks up Docker repoPath tags present on remote Docker registry
func FetchTags(registry, repoPath, filter, username, password, webSchema string) (map[string]*tag.Tag, error) {
func FetchTags(repo *repository.Repository, username, password string) (map[string]*tag.Tag, error) {
batchLimit, err := validateConcurrentRequests()
if err != nil {
return nil, err
}

tr, err := auth.NewToken(registry, repoPath, username, password, webSchema)
tr, err := auth.NewToken(repo, username, password)
if err != nil {
return nil, err
}

authorization := tr.AuthHeader()

allTagNames, err := fetchTagNames(registry, repoPath, authorization, webSchema)
allTagNames, err := fetchTagNames(repo, authorization)
if err != nil {
return nil, err
}

tagNames := make([]string, 0)
for _, tagName := range allTagNames {
if util.DoesMatch(tagName, filter) {
if util.DoesMatch(tagName, repo.Filter()) {
tagNames = append(tagNames, tagName)
}
}
Expand All @@ -350,11 +351,21 @@ func FetchTags(registry, repoPath, filter, username, password, webSchema string)
ch := make(chan detailResponse, stepSize)

for s := 1; s <= stepSize; s++ {
go func(registry, repoPath, tagName, authorization, webSchema string, ch chan detailResponse) {
digest, metadata, err := fetchDetails(registry, repoPath, tagName, authorization, webSchema)

ch <- detailResponse{TagName: tagName, Digest: digest, Created: metadata.Created, ContainerID: metadata.ContainerID, Error: err}
}(registry, repoPath, tagNames[tagIndex], authorization, webSchema, ch)
go func(
repo *repository.Repository,
tagName, authorization string,
ch chan detailResponse,
) {
digest, metadata, err := fetchDetails(repo, tagName, authorization)

ch <- detailResponse{
TagName: tagName,
Digest: digest,
Created: metadata.Created,
ContainerID: metadata.ContainerID,
Error: err,
}
}(repo, tagNames[tagIndex], authorization, ch)

tagIndex++
}
Expand Down

0 comments on commit 9380458

Please sign in to comment.