Skip to content

Commit

Permalink
Avoid v1.Manifest in crane edit config
Browse files Browse the repository at this point in the history
Because of how omitempty works, an empty Layers and a nil Layers will
both be omitted. We don't want that, because different registries
support different variants of that. Instead, we just pass through
whatever was there before by treating the manifest as a map[string]any
and manipulating that rather than using v1.Manifest-based helpers.
  • Loading branch information
jonjohnsonjr committed Mar 2, 2023
1 parent 1b8dc2b commit 599b4aa
Showing 1 changed file with 30 additions and 6 deletions.
36 changes: 30 additions & 6 deletions internal/cmd/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,37 @@ func editConfig(in io.Reader, out io.Writer, src, dst string, options ...crane.O
return nil, err
}

m, err := img.Manifest()
mt, err := img.MediaType()
if err != nil {
return nil, err
}
mt, err := img.MediaType()

// We want to omit Layers in certain situations, so we don't use v1.Image.Manifest() here.
// Instead, we treat the manifest as a map[string]any and just manipulate the config desc.
mb, err := img.RawManifest()
if err != nil {
return nil, err
}

jsonMap := map[string]any{}
if err := json.Unmarshal(mb, &jsonMap); err != nil {
return nil, err
}

cv, ok := jsonMap["config"]
if !ok {
return nil, fmt.Errorf("config missing")
}
cb, err := json.Marshal(cv)
if err != nil {
return nil, fmt.Errorf("json.Marshal config: %w", err)
}

config := v1.Descriptor{}
if err := json.Unmarshal(cb, &config); err != nil {
return nil, fmt.Errorf("json.Unmarshal config: %w", err)
}

var edited []byte
if interactive(in, out) {
rcf, err := img.RawConfigFile()
Expand All @@ -188,15 +210,17 @@ func editConfig(in io.Reader, out io.Writer, src, dst string, options ...crane.O
edited = b
}

l := static.NewLayer(edited, m.Config.MediaType)
l := static.NewLayer(edited, config.MediaType)
layerDigest, err := l.Digest()
if err != nil {
return nil, err
}

m.Config.Digest = layerDigest
m.Config.Size = int64(len(edited))
b, err := json.Marshal(m)
config.Digest = layerDigest
config.Size = int64(len(edited))

jsonMap["config"] = config
b, err := json.Marshal(jsonMap)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 599b4aa

Please sign in to comment.