diff --git a/cli/command/manifest/push.go b/cli/command/manifest/push.go index 848f18c8f0..41ab4941d8 100644 --- a/cli/command/manifest/push.go +++ b/cli/command/manifest/push.go @@ -219,7 +219,7 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere } // Attempt to reconstruct indentation of the manifest to ensure sha parity - // with the registry. + // with the registry - if we haven't preserved the raw content. // // This is necessary because our previous internal storage format did not // preserve whitespace. If we don't have the newer format present, we can @@ -227,9 +227,12 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere // reconstruction failed! switch { case imageManifest.SchemaV2Manifest != nil: - dt, err := json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ") - if err != nil { - return mountRequest{}, err + dt := imageManifest.Raw + if len(dt) == 0 { + dt, err = json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ") + if err != nil { + return mountRequest{}, err + } } dig := imageManifest.Descriptor.Digest @@ -243,9 +246,12 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere } imageManifest.SchemaV2Manifest = &manifest case imageManifest.OCIManifest != nil: - dt, err := json.MarshalIndent(imageManifest.OCIManifest, "", " ") - if err != nil { - return mountRequest{}, err + dt := imageManifest.Raw + if len(dt) == 0 { + dt, err = json.MarshalIndent(imageManifest.OCIManifest, "", " ") + if err != nil { + return mountRequest{}, err + } } dig := imageManifest.Descriptor.Digest diff --git a/cli/command/manifest/testdata/inspect-annotate.golden b/cli/command/manifest/testdata/inspect-annotate.golden index 5fe5bd5a9b..f594d518cb 100644 --- a/cli/command/manifest/testdata/inspect-annotate.golden +++ b/cli/command/manifest/testdata/inspect-annotate.golden @@ -14,6 +14,7 @@ "variant": "v7" } }, + "Raw": "ewogICAic2NoZW1hVmVyc2lvbiI6IDIsCiAgICJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLmRvY2tlci5kaXN0cmlidXRpb24ubWFuaWZlc3QudjIranNvbiIsCiAgICJjb25maWciOiB7CiAgICAgICJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLmRvY2tlci5jb250YWluZXIuaW1hZ2UudjEranNvbiIsCiAgICAgICJzaXplIjogMTUyMCwKICAgICAgImRpZ2VzdCI6ICJzaGEyNTY6NzMyOGY2ZjhiNDE4OTA1OTc1NzVjYmFhZGM4ODRlNzM4NmFlMGFjYzUzYjc0NzQwMWViY2U1Y2YwZDYyNDU2MCIKICAgfSwKICAgImxheWVycyI6IFsKICAgICAgewogICAgICAgICAibWVkaWFUeXBlIjogImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuaW1hZ2Uucm9vdGZzLmRpZmYudGFyLmd6aXAiLAogICAgICAgICAic2l6ZSI6IDE5OTA0MDIsCiAgICAgICAgICJkaWdlc3QiOiAic2hhMjU2Ojg4Mjg2ZjQxNTMwZTkzZGZmZDRiOTY0ZTFkYjIyY2U0OTM5ZmZmYTRhNGM2NjVkYWI4NTkxZmJhYjAzZDQ5MjYiCiAgICAgIH0KICAgXQp9", "SchemaV2Manifest": { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", diff --git a/cli/command/manifest/util.go b/cli/command/manifest/util.go index 1d530d9f2f..16aba15c74 100644 --- a/cli/command/manifest/util.go +++ b/cli/command/manifest/util.go @@ -76,6 +76,8 @@ func getManifest(ctx context.Context, dockerCli command.Cli, listRef, namedRef r return dockerCli.RegistryClient(insecure).GetManifest(ctx, namedRef) case err != nil: return types.ImageManifest{}, err + case len(data.Raw) == 0: + return dockerCli.RegistryClient(insecure).GetManifest(ctx, namedRef) default: return data, nil } diff --git a/cli/manifest/types/types.go b/cli/manifest/types/types.go index 76c742e20d..ca2a3e7866 100644 --- a/cli/manifest/types/types.go +++ b/cli/manifest/types/types.go @@ -17,8 +17,7 @@ import ( type ImageManifest struct { Ref *SerializableNamed Descriptor ocispec.Descriptor - - // TODO: Deprecate this and store manifest blobs + Raw []byte `json:",omitempty"` // SchemaV2Manifest is used for inspection SchemaV2Manifest *schema2.DeserializedManifest `json:",omitempty"` @@ -99,9 +98,15 @@ func (i ImageManifest) References() []distribution.Descriptor { // NewImageManifest returns a new ImageManifest object. The values for Platform // are initialized from those in the image func NewImageManifest(ref reference.Named, desc ocispec.Descriptor, manifest *schema2.DeserializedManifest) ImageManifest { + raw, err := manifest.MarshalJSON() + if err != nil { + raw = nil + } + return ImageManifest{ Ref: &SerializableNamed{Named: ref}, Descriptor: desc, + Raw: raw, SchemaV2Manifest: manifest, } } @@ -109,9 +114,15 @@ func NewImageManifest(ref reference.Named, desc ocispec.Descriptor, manifest *sc // NewOCIImageManifest returns a new ImageManifest object. The values for // Platform are initialized from those in the image func NewOCIImageManifest(ref reference.Named, desc ocispec.Descriptor, manifest *ocischema.DeserializedManifest) ImageManifest { + raw, err := manifest.MarshalJSON() + if err != nil { + raw = nil + } + return ImageManifest{ Ref: &SerializableNamed{Named: ref}, Descriptor: desc, + Raw: raw, OCIManifest: manifest, } }