Skip to content

Commit

Permalink
manifest: explicitly error if whitespace reconstruction has failed
Browse files Browse the repository at this point in the history
This behavior should not break any more use cases than before.
Previously, if the mismatch occured, we would actually push a manifest
that we then never referred to in the manifest list! If this was done in
a new repository, the command would fail with an obscure error from the
registry - the content wouldn't exist with the descriptor we expect it
to.

Signed-off-by: Justin Chadwell <me@jedevc.com>
  • Loading branch information
jedevc committed Jan 27, 2023
1 parent 7b0df1b commit b1bb913
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions cli/command/manifest/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,28 +218,41 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere
return mountRequest{}, err
}

// Attempt to reconstruct indentation of the manifest to ensure sha parity
// with the registry.
//
// This is neccessary because our previous internal storage format did not
// preserve whitespace. If we don't have the newer format present, we can
// attempt the reconstruction like before, but explicitly error if the
// reconstruction failed!
switch {
case imageManifest.SchemaV2Manifest != nil:
// This indentation has to be added to ensure sha parity with the registry
dt, err := json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ")
if err != nil {
return mountRequest{}, err
}
// indent only the DeserializedManifest portion of this, in order to maintain parity with the registry
// and not alter the sha

dig := imageManifest.Descriptor.Digest
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
return mountRequest{}, errors.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
}

var manifest schema2.DeserializedManifest
if err = manifest.UnmarshalJSON(dt); err != nil {
return mountRequest{}, err
}
imageManifest.SchemaV2Manifest = &manifest
case imageManifest.OCIManifest != nil:
// This indentation has to be added to ensure sha parity with the registry
dt, err := json.MarshalIndent(imageManifest.OCIManifest, "", " ")
if err != nil {
return mountRequest{}, err
}
// indent only the DeserializedManifest portion of this, in order to maintain parity with the registry
// and not alter the sha

dig := imageManifest.Descriptor.Digest
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
return mountRequest{}, errors.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
}

var manifest ocischema.DeserializedManifest
if err = manifest.UnmarshalJSON(dt); err != nil {
return mountRequest{}, err
Expand Down

0 comments on commit b1bb913

Please sign in to comment.