@@ -20,8 +20,6 @@ import (
2020 "go.podman.io/storage/pkg/fileutils"
2121)
2222
23- const version = "Directory Transport Version: 1.1\n "
24-
2523// ErrNotContainerImageDir indicates that the directory doesn't match the expected contents of a directory created
2624// using the 'dir' transport
2725var ErrNotContainerImageDir = errors .New ("not a containers image directory, don't want to overwrite important data" )
@@ -33,7 +31,8 @@ type dirImageDestination struct {
3331 stubs.NoPutBlobPartialInitialize
3432 stubs.AlwaysSupportsSignatures
3533
36- ref dirReference
34+ ref dirReference
35+ usesNonSHA256Digest bool
3736}
3837
3938// newImageDestination returns an ImageDestination for writing to a directory.
@@ -76,9 +75,14 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (private.Im
7675 return nil , err
7776 }
7877 // check if contents of version file is what we expect it to be
79- if string (contents ) != version {
78+ versionStr := string (contents )
79+ parsedVersion , err := parseVersion (versionStr )
80+ if err != nil {
8081 return nil , ErrNotContainerImageDir
8182 }
83+ if parsedVersion .isGreaterThan (maxSupportedVersion ) {
84+ return nil , UnsupportedVersionError {Version : versionStr , Path : ref .resolvedPath }
85+ }
8286 } else {
8387 return nil , ErrNotContainerImageDir
8488 }
@@ -94,11 +98,6 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (private.Im
9498 return nil , fmt .Errorf ("unable to create directory %q: %w" , ref .resolvedPath , err )
9599 }
96100 }
97- // create version file
98- err = os .WriteFile (ref .versionPath (), []byte (version ), 0o644 )
99- if err != nil {
100- return nil , fmt .Errorf ("creating version file %q: %w" , ref .versionPath (), err )
101- }
102101
103102 d := & dirImageDestination {
104103 PropertyMethodsInitialize : impl .PropertyMethods (impl.Properties {
@@ -151,13 +150,17 @@ func (d *dirImageDestination) PutBlobWithOptions(ctx context.Context, stream io.
151150 }
152151 }()
153152
154- digester , stream := putblobdigest .DigestIfCanonicalUnknown (stream , inputInfo )
153+ digester , stream := putblobdigest .DigestIfUnknown (stream , inputInfo )
154+
155155 // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done().
156156 size , err := io .Copy (blobFile , stream )
157157 if err != nil {
158158 return private.UploadedBlob {}, err
159159 }
160160 blobDigest := digester .Digest ()
161+ if blobDigest .Algorithm () != digest .Canonical { // compare the special case in layerPath
162+ d .usesNonSHA256Digest = true
163+ }
161164 if inputInfo .Size != - 1 && size != inputInfo .Size {
162165 return private.UploadedBlob {}, fmt .Errorf ("Size mismatch when copying %s, expected %d, got %d" , blobDigest , inputInfo .Size , size )
163166 }
@@ -257,6 +260,14 @@ func (d *dirImageDestination) PutSignaturesWithFormat(ctx context.Context, signa
257260// - Uploaded data MAY be visible to others before CommitWithOptions() is called
258261// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
259262func (d * dirImageDestination ) CommitWithOptions (ctx context.Context , options private.CommitOptions ) error {
263+ versionToWrite := version1_1
264+ if d .usesNonSHA256Digest {
265+ versionToWrite = version1_2
266+ }
267+ err := os .WriteFile (d .ref .versionPath (), []byte (versionToWrite .String ()), 0o644 )
268+ if err != nil {
269+ return fmt .Errorf ("writing version file %q: %w" , d .ref .versionPath (), err )
270+ }
260271 return nil
261272}
262273
0 commit comments