Skip to content

Commit 528fd63

Browse files
committed
image/storage: allow building container images with --digest
Allow the user to specify non-Canonical digest algorithm via `supporteddigests.TmpDigestForNewObjects()` instead of hardcoded `digest.Canonical` references. Without --digest or with --digest=sha256, behavior remains unchanged (SHA256 is the default). Tested with a scratch built image. Signed-off-by: Lokesh Mandvekar <[email protected]>
1 parent fb1cbee commit 528fd63

File tree

2 files changed

+119
-16
lines changed

2 files changed

+119
-16
lines changed

image/storage/storage_dest.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"go.podman.io/storage/pkg/chunked"
3838
"go.podman.io/storage/pkg/chunked/toc"
3939
"go.podman.io/storage/pkg/ioutils"
40+
supporteddigests "go.podman.io/storage/pkg/supported-digests"
4041
)
4142

4243
var (
@@ -288,7 +289,7 @@ func (s *storageImageDestination) putBlobToPendingFile(stream io.Reader, blobinf
288289
}
289290
defer decompressed.Close()
290291

291-
diffID := digest.Canonical.Digester()
292+
diffID := supporteddigests.TmpDigestForNewObjects().Digester()
292293
// Copy the data to the file.
293294
// TODO: This can take quite some time, and should ideally be cancellable using context.Context.
294295
_, err = io.Copy(diffID.Hash(), decompressed)
@@ -856,7 +857,7 @@ func (s *storageImageDestination) computeID(m manifest.Manifest) (string, error)
856857
}
857858
// ordinaryImageID is a digest of a config, which is a JSON value.
858859
// To avoid the risk of collisions, start the input with @ so that the input is not a valid JSON.
859-
tocImageID := digest.FromString("@With TOC:" + tocIDInput).Encoded()
860+
tocImageID := supporteddigests.TmpDigestForNewObjects().FromString("@With TOC:" + tocIDInput).String()
860861
logrus.Debugf("Ordinary storage image ID %s; a layer was looked up by TOC, so using image ID %s", ordinaryImageID, tocImageID)
861862
return tocImageID, nil
862863
}
@@ -1070,7 +1071,7 @@ func layerID(parentID string, trusted trustedLayerIdentityData) string {
10701071
if parentID == "" && !mustHash {
10711072
return component
10721073
}
1073-
return digest.Canonical.FromString(parentID + "+" + component).Encoded()
1074+
return supporteddigests.TmpDigestForNewObjects().FromString(parentID + "+" + component).String()
10741075
}
10751076

10761077
// createNewLayer creates a new layer newLayerID for (index, trusted) on top of parentLayer (which may be "").
@@ -1488,13 +1489,13 @@ func (s *storageImageDestination) CommitWithOptions(ctx context.Context, options
14881489
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
14891490
Key: s.lockProtected.configDigest.String(),
14901491
Data: v,
1491-
Digest: digest.Canonical.FromBytes(v),
1492+
Digest: supporteddigests.TmpDigestForNewObjects().FromBytes(v),
14921493
})
14931494
}
14941495
// Set up to save the options.UnparsedToplevel's manifest if it differs from
14951496
// the per-platform one, which is saved below.
14961497
if !bytes.Equal(toplevelManifest, s.manifest) {
1497-
manifestDigest, err := manifest.Digest(toplevelManifest)
1498+
manifestDigest, err := manifest.DigestWithAlgorithm(toplevelManifest, supporteddigests.TmpDigestForNewObjects())
14981499
if err != nil {
14991500
return fmt.Errorf("digesting top-level manifest: %w", err)
15001501
}
@@ -1530,7 +1531,7 @@ func (s *storageImageDestination) CommitWithOptions(ctx context.Context, options
15301531
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
15311532
Key: "signatures",
15321533
Data: s.signatures,
1533-
Digest: digest.Canonical.FromBytes(s.signatures),
1534+
Digest: supporteddigests.TmpDigestForNewObjects().FromBytes(s.signatures),
15341535
})
15351536
}
15361537
for instanceDigest, signatures := range s.signatureses {
@@ -1541,7 +1542,7 @@ func (s *storageImageDestination) CommitWithOptions(ctx context.Context, options
15411542
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
15421543
Key: key,
15431544
Data: signatures,
1544-
Digest: digest.Canonical.FromBytes(signatures),
1545+
Digest: supporteddigests.TmpDigestForNewObjects().FromBytes(signatures),
15451546
})
15461547
}
15471548

@@ -1643,7 +1644,7 @@ func (s *storageImageDestination) CommitWithOptions(ctx context.Context, options
16431644

16441645
// PutManifest writes the manifest to the destination.
16451646
func (s *storageImageDestination) PutManifest(ctx context.Context, manifestBlob []byte, instanceDigest *digest.Digest) error {
1646-
digest, err := manifest.Digest(manifestBlob)
1647+
digest, err := manifest.DigestWithAlgorithm(manifestBlob, supporteddigests.TmpDigestForNewObjects())
16471648
if err != nil {
16481649
return err
16491650
}

image/storage/storage_dest_test.go

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,76 +6,178 @@ import (
66
"github.com/opencontainers/go-digest"
77
"github.com/stretchr/testify/assert"
88
"github.com/stretchr/testify/require"
9+
supporteddigests "go.podman.io/storage/pkg/supported-digests"
910
)
1011

1112
func TestLayerID(t *testing.T) {
12-
blobDigest, err := digest.Parse("sha256:0000000000000000000000000000000000000000000000000000000000000000")
13+
blobDigestSHA256, err := digest.Parse("sha256:0000000000000000000000000000000000000000000000000000000000000000")
14+
require.NoError(t, err)
15+
blobDigestSHA512, err := digest.Parse("sha512:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
1316
require.NoError(t, err)
1417

1518
for _, c := range []struct {
19+
algorithm digest.Algorithm
20+
blobDigest digest.Digest
1621
parentID string
1722
identifiedByTOC bool
1823
diffID string
1924
tocDigest string
2025
expected string
2126
}{
2227
{
28+
algorithm: digest.SHA256,
29+
blobDigest: blobDigestSHA256,
2330
parentID: "",
2431
identifiedByTOC: false,
2532
diffID: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
2633
tocDigest: "",
2734
expected: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
2835
},
2936
{
37+
algorithm: digest.SHA256,
38+
blobDigest: blobDigestSHA256,
3039
parentID: "",
3140
identifiedByTOC: false,
3241
diffID: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
3342
expected: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
3443
tocDigest: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
3544
},
3645
{
46+
algorithm: digest.SHA256,
47+
blobDigest: blobDigestSHA256,
3748
parentID: "",
3849
identifiedByTOC: true,
3950
diffID: "",
4051
tocDigest: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
41-
expected: "07f60ddaf18a3d1fa18a71bf40f0b9889b473e26555d6fffdfbd72ba6a59469e",
52+
expected: "sha256:07f60ddaf18a3d1fa18a71bf40f0b9889b473e26555d6fffdfbd72ba6a59469e",
4253
},
4354
{
55+
algorithm: digest.SHA256,
56+
blobDigest: blobDigestSHA256,
4457
parentID: "",
4558
identifiedByTOC: true,
4659
diffID: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
4760
tocDigest: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
48-
expected: "07f60ddaf18a3d1fa18a71bf40f0b9889b473e26555d6fffdfbd72ba6a59469e",
61+
expected: "sha256:07f60ddaf18a3d1fa18a71bf40f0b9889b473e26555d6fffdfbd72ba6a59469e",
4962
},
5063
{
64+
algorithm: digest.SHA256,
65+
blobDigest: blobDigestSHA256,
5166
parentID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
5267
identifiedByTOC: false,
5368
diffID: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
5469
tocDigest: "",
55-
expected: "76f79efda453922cda1cecb6ec9e7cf9d86ea968c6dd199d4030dd00078a1686",
70+
expected: "sha256:76f79efda453922cda1cecb6ec9e7cf9d86ea968c6dd199d4030dd00078a1686",
5671
},
5772
{
73+
algorithm: digest.SHA256,
74+
blobDigest: blobDigestSHA256,
5875
parentID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
5976
identifiedByTOC: false,
6077
diffID: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
6178
tocDigest: "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
62-
expected: "76f79efda453922cda1cecb6ec9e7cf9d86ea968c6dd199d4030dd00078a1686",
79+
expected: "sha256:76f79efda453922cda1cecb6ec9e7cf9d86ea968c6dd199d4030dd00078a1686",
6380
},
6481
{
82+
algorithm: digest.SHA256,
83+
blobDigest: blobDigestSHA256,
6584
parentID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
6685
identifiedByTOC: true,
6786
diffID: "",
6887
tocDigest: "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
69-
expected: "468becc3d25ee862f81fd728d229a2b2487cfc9b3e6cf3a4d0af8c3fdde0e7a9",
88+
expected: "sha256:468becc3d25ee862f81fd728d229a2b2487cfc9b3e6cf3a4d0af8c3fdde0e7a9",
7089
},
7190
{
91+
algorithm: digest.SHA256,
92+
blobDigest: blobDigestSHA256,
7293
parentID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
7394
identifiedByTOC: true,
7495
diffID: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
7596
tocDigest: "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
76-
expected: "468becc3d25ee862f81fd728d229a2b2487cfc9b3e6cf3a4d0af8c3fdde0e7a9",
97+
expected: "sha256:468becc3d25ee862f81fd728d229a2b2487cfc9b3e6cf3a4d0af8c3fdde0e7a9",
98+
},
99+
{
100+
algorithm: digest.SHA512,
101+
blobDigest: blobDigestSHA512,
102+
parentID: "",
103+
identifiedByTOC: false,
104+
diffID: "sha512:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
105+
tocDigest: "",
106+
expected: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
107+
},
108+
{
109+
algorithm: digest.SHA512,
110+
blobDigest: blobDigestSHA512,
111+
parentID: "",
112+
identifiedByTOC: false,
113+
diffID: "sha512:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
114+
tocDigest: "sha512:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
115+
expected: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
116+
},
117+
{
118+
algorithm: digest.SHA512,
119+
blobDigest: blobDigestSHA512,
120+
parentID: "",
121+
identifiedByTOC: true,
122+
diffID: "",
123+
tocDigest: "sha512:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
124+
expected: "sha512:129fa63234ab81f43f298346bb7159cc1c8fab6d8ae93f3438f8637f5079ea6dec6ea4740eb6bdbcae3ad1eb00af76011341b2f19fe590daf6f64f06e1302f52",
125+
},
126+
{
127+
algorithm: digest.SHA512,
128+
blobDigest: blobDigestSHA512,
129+
parentID: "",
130+
identifiedByTOC: true,
131+
diffID: "sha512:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
132+
tocDigest: "sha512:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
133+
expected: "sha512:129fa63234ab81f43f298346bb7159cc1c8fab6d8ae93f3438f8637f5079ea6dec6ea4740eb6bdbcae3ad1eb00af76011341b2f19fe590daf6f64f06e1302f52",
134+
},
135+
{
136+
algorithm: digest.SHA512,
137+
blobDigest: blobDigestSHA512,
138+
parentID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
139+
identifiedByTOC: false,
140+
diffID: "sha512:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
141+
tocDigest: "",
142+
expected: "sha512:391623fa853a82d2795e8648f06b7c0eb880e345138dd6b9429132d9aa329ff1e6f7b76a3295b8b34d8682090056a798901b9b700e4059b1011d32b68a7bca21",
143+
},
144+
{
145+
algorithm: digest.SHA512,
146+
blobDigest: blobDigestSHA512,
147+
parentID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
148+
identifiedByTOC: false,
149+
diffID: "sha512:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
150+
tocDigest: "sha512:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
151+
expected: "sha512:391623fa853a82d2795e8648f06b7c0eb880e345138dd6b9429132d9aa329ff1e6f7b76a3295b8b34d8682090056a798901b9b700e4059b1011d32b68a7bca21",
152+
},
153+
{
154+
algorithm: digest.SHA512,
155+
blobDigest: blobDigestSHA512,
156+
parentID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
157+
identifiedByTOC: true,
158+
diffID: "",
159+
tocDigest: "sha512:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
160+
expected: "sha512:0263be0fd3b851ffe02c877574d1d2b19625e36888e63eec2682de2210b6bbaea262e04085843eda16b7014fd59db6aafa0628c2a02443111ae568ea545b112e",
161+
},
162+
{
163+
algorithm: digest.SHA512,
164+
blobDigest: blobDigestSHA512,
165+
parentID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
166+
identifiedByTOC: true,
167+
diffID: "sha512:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
168+
tocDigest: "sha512:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
169+
expected: "sha512:0263be0fd3b851ffe02c877574d1d2b19625e36888e63eec2682de2210b6bbaea262e04085843eda16b7014fd59db6aafa0628c2a02443111ae568ea545b112e",
77170
},
78171
} {
172+
origAlg := supporteddigests.TmpDigestForNewObjects()
173+
defer func() {
174+
err := supporteddigests.TmpSetDigestForNewObjects(origAlg)
175+
require.NoError(t, err)
176+
}()
177+
178+
err := supporteddigests.TmpSetDigestForNewObjects(c.algorithm)
179+
require.NoError(t, err)
180+
79181
var diffID, tocDigest digest.Digest
80182
if c.diffID != "" {
81183
diffID, err = digest.Parse(c.diffID)
@@ -98,7 +200,7 @@ func TestLayerID(t *testing.T) {
98200
layerIdentifiedByTOC: c.identifiedByTOC,
99201
diffID: diffID,
100202
tocDigest: tocDigest,
101-
blobDigest: blobDigest,
203+
blobDigest: c.blobDigest,
102204
})
103205
assert.Equal(t, c.expected, res)
104206
}

0 commit comments

Comments
 (0)