Beispiel #1
0
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.Tag(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)
	}
}
Beispiel #2
0
// 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.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 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.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")
	}
}
Beispiel #3
0
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 + ":" + DEFAULTTAG,
		"docker.io/" + testOfficialImageName,
		"docker.io/" + testOfficialImageName + ":" + DEFAULTTAG,
		"index.docker.io/" + testOfficialImageName,
		"index.docker.io/" + testOfficialImageName + ":" + DEFAULTTAG,
		"library/" + testOfficialImageName,
		"library/" + testOfficialImageName + ":" + DEFAULTTAG,
		"docker.io/library/" + testOfficialImageName,
		"docker.io/library/" + testOfficialImageName + ":" + DEFAULTTAG,
		"index.docker.io/library/" + testOfficialImageName,
		"index.docker.io/library/" + testOfficialImageName + ":" + DEFAULTTAG,
	}

	privateLookups := []string{
		testPrivateImageID,
		testPrivateImageIDShort,
		testPrivateImageName + ":" + testPrivateImageID,
		testPrivateImageName + ":" + testPrivateImageIDShort,
		testPrivateImageName,
		testPrivateImageName + ":" + 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)
		}
	}
}