func testTokenPassThru(t *testing.T, ts *httptest.Server) { tmp, err := utils.TestDirectory("") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmp) uri, err := url.Parse(ts.URL) if err != nil { t.Fatalf("could not parse url from test server: %v", err) } endpoint := registry.APIEndpoint{ Mirror: false, URL: uri, Version: 2, Official: false, TrimHostname: false, TLSConfig: nil, //VersionHeader: "verheader", } n, _ := reference.ParseNamed("testremotename") repoInfo := ®istry.RepositoryInfo{ Named: n, Index: ®istrytypes.IndexInfo{ Name: "testrepo", Mirrors: nil, Secure: false, Official: false, }, Official: false, } imagePullConfig := &ImagePullConfig{ MetaHeaders: http.Header{}, AuthConfig: &types.AuthConfig{ RegistryToken: secretRegistryToken, }, } puller, err := newPuller(endpoint, repoInfo, imagePullConfig) if err != nil { t.Fatal(err) } p := puller.(*v2Puller) ctx := context.Background() p.repo, _, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull") if err != nil { t.Fatal(err) } logrus.Debug("About to pull") // We expect it to fail, since we haven't mock'd the full registry exchange in our handler above tag, _ := reference.WithTag(n, "tag_goes_here") _ = p.pullV2Repository(ctx, tag) }
func TestLookupImage(t *testing.T) { tmp, err := utils.TestDirectory("") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmp) store := mkTestTagStore(tmp, t) defer store.graph.driver.Cleanup() if img, err := store.LookupImage(testImageName); err != nil { t.Fatal(err) } else if img == nil { t.Errorf("Expected 1 image, none found") } if img, err := store.LookupImage(testImageName + ":" + DEFAULTTAG); err != nil { t.Fatal(err) } else if img == nil { t.Errorf("Expected 1 image, none found") } if img, err := store.LookupImage(testImageName + ":" + "fail"); err == nil { t.Errorf("Expected error, none found") } else if img != nil { t.Errorf("Expected 0 image, 1 found") } if img, err := store.LookupImage("fail:fail"); err == nil { t.Errorf("Expected error, none found") } else if img != nil { t.Errorf("Expected 0 image, 1 found") } if img, err := store.LookupImage(testImageID); err != nil { t.Fatal(err) } else if img == nil { t.Errorf("Expected 1 image, none found") } if img, err := store.LookupImage(testImageName + ":" + testImageID); err != nil { t.Fatal(err) } else if img == nil { t.Errorf("Expected 1 image, none found") } }
func TestLookupImage(t *testing.T) { tmp, err := utils.TestDirectory("") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmp) store := mkTestTagStore(tmp, t) defer store.graph.driver.Cleanup() officialLookups := []string{ testOfficialImageID, testOfficialImageIDShort, testOfficialImageName + ":" + testOfficialImageID, testOfficialImageName + ":" + testOfficialImageIDShort, testOfficialImageName, testOfficialImageName + ":" + tags.DefaultTag, "docker.io/" + testOfficialImageName, "docker.io/" + testOfficialImageName + ":" + tags.DefaultTag, "index.docker.io/" + testOfficialImageName, "index.docker.io/" + testOfficialImageName + ":" + tags.DefaultTag, "library/" + testOfficialImageName, "library/" + testOfficialImageName + ":" + tags.DefaultTag, "docker.io/library/" + testOfficialImageName, "docker.io/library/" + testOfficialImageName + ":" + tags.DefaultTag, "index.docker.io/library/" + testOfficialImageName, "index.docker.io/library/" + testOfficialImageName + ":" + tags.DefaultTag, } privateLookups := []string{ testPrivateImageID, testPrivateImageIDShort, testPrivateImageName + ":" + testPrivateImageID, testPrivateImageName + ":" + testPrivateImageIDShort, testPrivateImageName, testPrivateImageName + ":" + tags.DefaultTag, } invalidLookups := []string{ testOfficialImageName + ":" + "fail", "fail:fail", } digestLookups := []string{ testPrivateImageName + "@" + testPrivateImageDigest, } for _, name := range officialLookups { if img, err := store.LookupImage(name); err != nil { t.Errorf("Error looking up %s: %s", name, err) } else if img == nil { t.Errorf("Expected 1 image, none found: %s", name) } else if img.ID != testOfficialImageID { t.Errorf("Expected ID '%s' found '%s'", testOfficialImageID, img.ID) } } for _, name := range privateLookups { if img, err := store.LookupImage(name); err != nil { t.Errorf("Error looking up %s: %s", name, err) } else if img == nil { t.Errorf("Expected 1 image, none found: %s", name) } else if img.ID != testPrivateImageID { t.Errorf("Expected ID '%s' found '%s'", testPrivateImageID, img.ID) } } for _, name := range invalidLookups { if img, err := store.LookupImage(name); err == nil { t.Errorf("Expected error, none found: %s", name) } else if img != nil { t.Errorf("Expected 0 image, 1 found: %s", name) } } for _, name := range digestLookups { if img, err := store.LookupImage(name); err != nil { t.Errorf("Error looking up %s: %s", name, err) } else if img == nil { t.Errorf("Expected 1 image, none found: %s", name) } else if img.ID != testPrivateImageID { t.Errorf("Expected ID '%s' found '%s'", testPrivateImageID, img.ID) } } }
func newTestDirectory(templateDir string) (dir string, err error) { return utils.TestDirectory(templateDir) }
func TestTokenPassThru(t *testing.T) { authConfig := &types.AuthConfig{ RegistryToken: "mysecrettoken", } gotToken := false handler := func(w http.ResponseWriter, r *http.Request) { if strings.Contains(r.Header.Get("Authorization"), authConfig.RegistryToken) { logrus.Debug("Detected registry token in auth header") gotToken = true } if r.RequestURI == "/v2/" { w.Header().Set("WWW-Authenticate", `Bearer realm="foorealm"`) w.WriteHeader(401) } } ts := httptest.NewServer(http.HandlerFunc(handler)) defer ts.Close() tmp, err := utils.TestDirectory("") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmp) endpoint := registry.APIEndpoint{ Mirror: false, URL: ts.URL, Version: 2, Official: false, TrimHostname: false, TLSConfig: nil, //VersionHeader: "verheader", } n, _ := reference.ParseNamed("testremotename") repoInfo := ®istry.RepositoryInfo{ Named: n, Index: ®istrytypes.IndexInfo{ Name: "testrepo", Mirrors: nil, Secure: false, Official: false, }, Official: false, } imagePullConfig := &ImagePullConfig{ MetaHeaders: http.Header{}, AuthConfig: authConfig, } puller, err := newPuller(endpoint, repoInfo, imagePullConfig) if err != nil { t.Fatal(err) } p := puller.(*v2Puller) ctx := context.Background() p.repo, _, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull") if err != nil { t.Fatal(err) } logrus.Debug("About to pull") // We expect it to fail, since we haven't mock'd the full registry exchange in our handler above tag, _ := reference.WithTag(n, "tag_goes_here") _ = p.pullV2Repository(ctx, tag) if !gotToken { t.Fatal("Failed to receive registry token") } }
func TestManifestTarsumCache(t *testing.T) { tmp, err := utils.TestDirectory("") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmp) store := mkTestTagStore(tmp, t) defer store.graph.driver.Cleanup() archive, err := fakeTar() if err != nil { t.Fatal(err) } img := &image.Image{ID: testManifestImageID} if err := store.graph.Register(img, archive); err != nil { t.Fatal(err) } if err := store.Set(testManifestImageName, testManifestTag, testManifestImageID, false); err != nil { t.Fatal(err) } if cs, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID)); err != nil { t.Fatal(err) } else if cs != "" { t.Fatalf("Non-empty checksum file after register") } // Generate manifest payload, err := store.newManifest(testManifestImageName, testManifestImageName, testManifestTag) if err != nil { t.Fatal(err) } manifestChecksum, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID)) if err != nil { t.Fatal(err) } var manifest registry.ManifestData if err := json.Unmarshal(payload, &manifest); err != nil { t.Fatalf("error unmarshalling manifest: %s", err) } if len(manifest.FSLayers) != 1 { t.Fatalf("Unexpected number of layers, expecting 1: %d", len(manifest.FSLayers)) } if manifest.FSLayers[0].BlobSum != manifestChecksum { t.Fatalf("Unexpected blob sum, expecting %q, got %q", manifestChecksum, manifest.FSLayers[0].BlobSum) } if len(manifest.History) != 1 { t.Fatalf("Unexpected number of layer history, expecting 1: %d", len(manifest.History)) } v1compat, err := img.RawJson() if err != nil { t.Fatal(err) } if manifest.History[0].V1Compatibility != string(v1compat) { t.Fatalf("Unexpected json value\nExpected:\n%s\nActual:\n%s", v1compat, manifest.History[0].V1Compatibility) } }
// TestManifestDigestCheck ensures that loadManifest properly verifies the // remote and local digest. func TestManifestDigestCheck(t *testing.T) { tmp, err := utils.TestDirectory("") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmp) store := mkTestTagStore(tmp, t) defer store.graph.driver.Cleanup() archive, err := fakeTar() if err != nil { t.Fatal(err) } img := &Image{ID: testManifestImageID} if err := store.graph.Register(img, archive); err != nil { t.Fatal(err) } if err := store.Tag(testManifestImageName, testManifestTag, testManifestImageID, false); err != nil { t.Fatal(err) } if _, err := store.graph.GetDigest(testManifestImageID); err == nil { t.Fatalf("Non-empty checksum file after register") } else if err != ErrDigestNotSet { t.Fatal(err) } // Generate manifest payload, err := store.newManifest(testManifestImageName, testManifestImageName, testManifestTag) if err != nil { t.Fatalf("unexpected error generating test manifest: %v", err) } pk, err := libtrust.GenerateECP256PrivateKey() if err != nil { t.Fatalf("unexpected error generating private key: %v", err) } sig, err := libtrust.NewJSONSignature(payload) if err != nil { t.Fatalf("error creating signature: %v", err) } if err := sig.Sign(pk); err != nil { t.Fatalf("error signing manifest bytes: %v", err) } signedBytes, err := sig.PrettySignature("signatures") if err != nil { t.Fatalf("error getting signed bytes: %v", err) } dgst, err := digest.FromBytes(payload) if err != nil { t.Fatalf("error getting digest of manifest: %v", err) } // use this as the "bad" digest zeroDigest, err := digest.FromBytes([]byte{}) if err != nil { t.Fatalf("error making zero digest: %v", err) } // Remote and local match, everything should look good local, _, _, err := store.loadManifest(signedBytes, dgst.String(), dgst) if err != nil { t.Fatalf("unexpected error verifying local and remote digest: %v", err) } if local != dgst { t.Fatalf("local digest not correctly calculated: %v", err) } // remote and no local, since pulling by tag local, _, _, err = store.loadManifest(signedBytes, "tag", dgst) if err != nil { t.Fatalf("unexpected error verifying tag pull and remote digest: %v", err) } if local != dgst { t.Fatalf("local digest not correctly calculated: %v", err) } // remote and differing local, this is the most important to fail local, _, _, err = store.loadManifest(signedBytes, zeroDigest.String(), dgst) if err == nil { t.Fatalf("error expected when verifying with differing local digest") } // no remote, no local (by tag) local, _, _, err = store.loadManifest(signedBytes, "tag", "") if err != nil { t.Fatalf("unexpected error verifying manifest without remote digest: %v", err) } if local != dgst { t.Fatalf("local digest not correctly calculated: %v", err) } // no remote, with local local, _, _, err = store.loadManifest(signedBytes, dgst.String(), "") if err != nil { t.Fatalf("unexpected error verifying manifest without remote digest: %v", err) } if local != dgst { t.Fatalf("local digest not correctly calculated: %v", err) } // bad remote, we fail the check. local, _, _, err = store.loadManifest(signedBytes, dgst.String(), zeroDigest) if err == nil { t.Fatalf("error expected when verifying with differing remote digest") } }