func newTestEnvWithConfig(t *testing.T, config *configuration.Configuration) *testEnv { ctx := context.Background() app := NewApp(ctx, *config) server := httptest.NewServer(handlers.CombinedLoggingHandler(os.Stderr, app)) builder, err := v2.NewURLBuilderFromString(server.URL + config.HTTP.Prefix) if err != nil { t.Fatalf("error creating url builder: %v", err) } pk, err := libtrust.GenerateECP256PrivateKey() if err != nil { t.Fatalf("unexpected error generating private key: %v", err) } return &testEnv{ pk: pk, ctx: ctx, config: *config, app: app, server: server, builder: builder, } }
// New returns a new Client which operates against a registry with the // given base endpoint // This endpoint should not include /v2/ or any part of the url after this. func New(endpoint string) (Client, error) { ub, err := v2.NewURLBuilderFromString(endpoint) if err != nil { return nil, err } return &clientImpl{ endpoint: endpoint, ub: ub, }, nil }
// NewRegistry creates a registry namespace which can be used to get a listing of repositories func NewRegistry(ctx context.Context, baseURL string, transport http.RoundTripper) (Registry, error) { ub, err := v2.NewURLBuilderFromString(baseURL) if err != nil { return nil, err } client := &http.Client{ Transport: transport, Timeout: 1 * time.Minute, } return ®istry{ client: client, ub: ub, context: ctx, }, nil }
// All returns all tag// NewRepository creates a new Repository for the given repository name and base URL. func newRegistry(baseURL string, transport http.RoundTripper) (*registry, error) { ub, err := v2.NewURLBuilderFromString(baseURL, false) if err != nil { return nil, err } client := &http.Client{ Transport: transport, CheckRedirect: checkHTTPRedirect, // TODO(dmcgowan): create cookie jar } return ®istry{ client: client, ub: ub, }, nil }
// NewRegistry creates a registry namespace which can be used to get a listing of repositories func NewRegistryOld(ctx context.Context, baseURL string, transport http.RoundTripper) (*oldRegistry, error) { ub, err := v2.NewURLBuilderFromString(baseURL, false) if err != nil { return nil, err } client := &http.Client{ Transport: transport, Timeout: 1 * time.Minute, CheckRedirect: checkHTTPRedirect, } return &oldRegistry{ client: client, ub: ub, context: ctx, }, nil }
// NewRepository creates a new Repository for the given repository name and base URL. func NewRepository(ctx context.Context, name reference.Named, baseURL string, transport http.RoundTripper) (distribution.Repository, error) { ub, err := v2.NewURLBuilderFromString(baseURL) if err != nil { return nil, err } client := &http.Client{ Transport: transport, // TODO(dmcgowan): create cookie jar } return &repository{ client: client, ub: ub, name: name, context: ctx, }, nil }
func main() { var request CheckRequest err := json.NewDecoder(os.Stdin).Decode(&request) fatalIf("failed to read request", err) registryHost, repo := parseRepository(request.Source.Repository) tag := request.Source.Tag if tag == "" { tag = "latest" } transport, registryURL := makeTransport(request, registryHost, repo) ub, err := v2.NewURLBuilderFromString(registryURL) fatalIf("failed to construct registry URL builder", err) client := &http.Client{Transport: transport} manifestURL, err := ub.BuildManifestURL(repo, tag) fatalIf("failed to build manifest URL", err) manifestResponse, err := client.Get(manifestURL) fatalIf("failed to fetch manifest", err) manifestResponse.Body.Close() if manifestResponse.StatusCode != http.StatusOK { fatal("failed to fetch digest: " + manifestResponse.Status) } digest := manifestResponse.Header.Get("Docker-Content-Digest") if digest == "" { fatal("no digest returned") } response := CheckResponse{} if digest != request.Version.Digest { response = append(response, Version{digest}) } json.NewEncoder(os.Stdout).Encode(response) }
// TestNewApp covers the creation of an application via NewApp with a // configuration. func TestNewApp(t *testing.T) { ctx := context.Background() config := configuration.Configuration{ Storage: configuration.Storage{ "inmemory": nil, }, Auth: configuration.Auth{ // For now, we simply test that new auth results in a viable // application. "silly": { "realm": "realm-test", "service": "service-test", }, }, } // Mostly, with this test, given a sane configuration, we are simply // ensuring that NewApp doesn't panic. We might want to tweak this // behavior. app := NewApp(ctx, config) server := httptest.NewServer(app) builder, err := v2.NewURLBuilderFromString(server.URL) if err != nil { t.Fatalf("error creating urlbuilder: %v", err) } baseURL, err := builder.BuildBaseURL() if err != nil { t.Fatalf("error creating baseURL: %v", err) } // TODO(stevvooe): The rest of this test might belong in the API tests. // Just hit the app and make sure we get a 401 Unauthorized error. req, err := http.Get(baseURL) if err != nil { t.Fatalf("unexpected error during GET: %v", err) } defer req.Body.Close() if req.StatusCode != http.StatusUnauthorized { t.Fatalf("unexpected status code during request: %v", err) } if req.Header.Get("Content-Type") != "application/json; charset=utf-8" { t.Fatalf("unexpected content-type: %v != %v", req.Header.Get("Content-Type"), "application/json; charset=utf-8") } expectedAuthHeader := "Bearer realm=\"realm-test\",service=\"service-test\"" if e, a := expectedAuthHeader, req.Header.Get("WWW-Authenticate"); e != a { t.Fatalf("unexpected WWW-Authenticate header: %q != %q", e, a) } var errs errcode.Errors dec := json.NewDecoder(req.Body) if err := dec.Decode(&errs); err != nil { t.Fatalf("error decoding error response: %v", err) } err2, ok := errs[0].(errcode.ErrorCoder) if !ok { t.Fatalf("not an ErrorCoder: %#v", errs[0]) } if err2.ErrorCode() != v2.ErrorCodeUnauthorized { t.Fatalf("unexpected error code: %v != %v", err2.ErrorCode(), v2.ErrorCodeUnauthorized) } }
"github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/reference" "github.com/docker/distribution/registry/api/v2" "github.com/docker/distribution/uuid" "github.com/docker/libtrust" ) var ( // common environment for expected manifest events. repo = "test/repo" source = SourceRecord{ Addr: "remote.test", InstanceID: uuid.Generate().String(), } ub = mustUB(v2.NewURLBuilderFromString("http://test.example.com/")) actor = ActorRecord{ Name: "test", } request = RequestRecord{} m = schema1.Manifest{ Name: repo, Tag: "latest", } sm *schema1.SignedManifest payload []byte dgst digest.Digest )
func main() { logger := lager.NewLogger("http") var request CheckRequest err := json.NewDecoder(os.Stdin).Decode(&request) fatalIf("failed to read request", err) os.Setenv("AWS_ACCESS_KEY_ID", request.Source.AWSAccessKeyID) os.Setenv("AWS_SECRET_ACCESS_KEY", request.Source.AWSSecretAccessKey) // silence benign ecr-login errors/warnings seelog.UseLogger(seelog.Disabled) ecrUser, ecrPass, err := ecr.ECRHelper{ ClientFactory: ecrapi.DefaultClientFactory{}, }.Get(request.Source.Repository) if err == nil { request.Source.Username = ecrUser request.Source.Password = ecrPass } registryHost, repo := parseRepository(request.Source.Repository) if len(request.Source.RegistryMirror) > 0 { registryMirrorUrl, err := url.Parse(request.Source.RegistryMirror) fatalIf("failed to parse registry mirror URL", err) registryHost = registryMirrorUrl.Host } tag := request.Source.Tag if tag == "" { tag = "latest" } transport, registryURL := makeTransport(logger, request, registryHost, repo) client := &http.Client{ Transport: retryRoundTripper(logger, transport), } ub, err := v2.NewURLBuilderFromString(registryURL, false) fatalIf("failed to construct registry URL builder", err) namedRef, err := reference.WithName(repo) fatalIf("failed to construct named reference", err) var response CheckResponse taggedRef, err := reference.WithTag(namedRef, tag) fatalIf("failed to construct tagged reference", err) latestManifestURL, err := ub.BuildManifestURL(taggedRef) fatalIf("failed to build latest manifest URL", err) latestDigest, foundLatest := fetchDigest(client, latestManifestURL) if request.Version.Digest != "" { digestRef, err := reference.WithDigest(namedRef, digest.Digest(request.Version.Digest)) fatalIf("failed to build cursor manifest URL", err) cursorManifestURL, err := ub.BuildManifestURL(digestRef) fatalIf("failed to build manifest URL", err) cursorDigest, foundCursor := fetchDigest(client, cursorManifestURL) if foundCursor && cursorDigest != latestDigest { response = append(response, Version{cursorDigest}) } } if foundLatest { response = append(response, Version{latestDigest}) } json.NewEncoder(os.Stdout).Encode(response) }