Created
May 1, 2022 02:20
-
-
Save cognifloyd/effee107fc62ee4f722814ce94ee6d63 to your computer and use it in GitHub Desktop.
Docker Registry client in go (rough outline)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package image // import "github.com/go-vela/worker/internal/image" | |
import ( | |
"context" | |
dist "github.com/docker/distribution" | |
"github.com/docker/distribution/reference" | |
"github.com/docker/docker/api/types" | |
"github.com/docker/docker/distribution" | |
"github.com/docker/docker/dockerversion" | |
"github.com/docker/docker/registry" | |
) | |
// ImageExists queries the registry to see if the image exists. | |
func ImageExists(ctx context.Context, image string) (bool, error) { | |
// this should be a vela user agent instead | |
userAgent := dockerversion.DockerUserAgent(ctx) | |
authConfig := &types.AuthConfig{ | |
// stored in user docker file | |
Username: "", | |
Password: "", | |
Auth: "", // replaces plaintext Username+Password | |
ServerAddress: "", | |
IdentityToken: "", // used to authenticate user and get registry access token | |
RegistryToken: "", // bearer token to send to registry | |
} | |
registryService, err := registry.NewService(registry.ServiceOptions{ | |
AllowNondistributableArtifacts: []string{"...", "..."}, | |
Mirrors: []string{"...", "..."}, | |
InsecureRegistries: []string{"...", "..."}, | |
}) | |
_, _, err = registryService.Auth(ctx, authConfig, userAgent) | |
if err != nil { | |
return false, err | |
} | |
// on success: | |
// status = "Login Succeded" | |
// token = authConfig.IdentityToken | |
// err = nil | |
ref, err := reference.ParseAnyReference(image) | |
if err != nil { | |
return false, err | |
} | |
namedRef, ok := ref.(reference.Named) | |
if !ok { | |
if _, ok := ref.(reference.Digested); ok { | |
// image is a full image ID with a digest instead of a tag | |
return false, nil | |
} | |
return false, nil | |
} | |
repoInfo, err := registryService.ResolveRepository(namedRef) | |
if err := distribution.ValidateRepoName(repoInfo.Name); err != nil { | |
// name is empty or `scratch` | |
return false, nil | |
} | |
var ( | |
confirmedV2 bool | |
distrepo dist.Repository // this is a registry client with the repo path | |
lastError error | |
) | |
endpoints, err := registryService.LookupPullEndpoints(reference.Domain(repoInfo.Name)) | |
for _, endpoint := range endpoints { | |
if endpoint.Version == registry.APIVersion1 { | |
continue | |
} | |
distrepo, confirmedV2, lastError = distribution.NewV2Repository(ctx, repoInfo, endpoint, nil, authConfig, "pull") | |
if lastError == nil && confirmedV2 { | |
break | |
} | |
} | |
taggedRef, ok := namedRef.(reference.NamedTagged) | |
_, err = distrepo.Tags(ctx).Get(ctx, taggedRef.Tag()) | |
if err != nil { | |
return false, err | |
} | |
return true, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment