mirror of https://github.com/docker/cli.git
manifest: explicitly error if whitespace reconstruction has failed
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>
This commit is contained in:
parent
070825bc74
commit
285e137aa4
|
@ -218,28 +218,41 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere
|
||||||
return mountRequest{}, err
|
return mountRequest{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attempt to reconstruct indentation of the manifest to ensure sha parity
|
||||||
|
// with the registry.
|
||||||
|
//
|
||||||
|
// This is necessary 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 {
|
switch {
|
||||||
case imageManifest.SchemaV2Manifest != nil:
|
case imageManifest.SchemaV2Manifest != nil:
|
||||||
// This indentation has to be added to ensure sha parity with the registry
|
|
||||||
dt, err := json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ")
|
dt, err := json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mountRequest{}, err
|
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
|
var manifest schema2.DeserializedManifest
|
||||||
if err = manifest.UnmarshalJSON(dt); err != nil {
|
if err = manifest.UnmarshalJSON(dt); err != nil {
|
||||||
return mountRequest{}, err
|
return mountRequest{}, err
|
||||||
}
|
}
|
||||||
imageManifest.SchemaV2Manifest = &manifest
|
imageManifest.SchemaV2Manifest = &manifest
|
||||||
case imageManifest.OCIManifest != nil:
|
case imageManifest.OCIManifest != nil:
|
||||||
// This indentation has to be added to ensure sha parity with the registry
|
|
||||||
dt, err := json.MarshalIndent(imageManifest.OCIManifest, "", " ")
|
dt, err := json.MarshalIndent(imageManifest.OCIManifest, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mountRequest{}, err
|
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
|
var manifest ocischema.DeserializedManifest
|
||||||
if err = manifest.UnmarshalJSON(dt); err != nil {
|
if err = manifest.UnmarshalJSON(dt); err != nil {
|
||||||
return mountRequest{}, err
|
return mountRequest{}, err
|
||||||
|
|
Loading…
Reference in New Issue