Skip to content

Commit b2de358

Browse files
committed
cli/push: Emit stripped push note
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
1 parent b8a7ca7 commit b2de358

1 file changed

Lines changed: 50 additions & 6 deletions

File tree

cli/command/image/push.go

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package image
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"io"
78
"os"
@@ -73,9 +74,8 @@ func RunPush(ctx context.Context, dockerCli command.Cli, opts pushOptions) error
7374

7475
printNote(dockerCli, `Selecting a single platform will only push one matching image manifest from a multi-platform image index.
7576
This means that any other components attached to the multi-platform image index (like Buildkit attestations) won't be pushed.
76-
If you want to only push a single platform image while preserving the attestations, please build an image with only that platform and push it instead.
77-
Example: echo "FROM %s" | docker build - --platform %s -t <NEW-TAG>
78-
`, opts.remote, opts.platform)
77+
If you want to only push a single platform image while preserving the attestations, please use 'docker convert\n'
78+
`)
7979
}
8080

8181
ref, err := reference.ParseNormalizedNamed(opts.remote)
@@ -116,20 +116,64 @@ Example: echo "FROM %s" | docker build - --platform %s -t <NEW-TAG>
116116
return err
117117
}
118118

119+
defer func() {
120+
if strippedNote != "" {
121+
fmt.Fprintln(dockerCli.Err(), "")
122+
printNote(dockerCli, strippedNote)
123+
}
124+
}()
125+
119126
defer responseBody.Close()
120127
if !opts.untrusted {
121128
// TODO PushTrustedReference currently doesn't respect `--quiet`
122129
return PushTrustedReference(dockerCli, repoInfo, ref, authConfig, responseBody)
123130
}
124131

125132
if opts.quiet {
126-
err = jsonmessage.DisplayJSONMessagesToStream(responseBody, streams.NewOut(io.Discard), nil)
133+
err = jsonmessage.DisplayJSONMessagesToStream(responseBody, streams.NewOut(io.Discard), handleAux(dockerCli))
127134
if err == nil {
128135
fmt.Fprintln(dockerCli.Out(), ref.String())
129136
}
130137
return err
131138
}
132-
return jsonmessage.DisplayJSONMessagesToStream(responseBody, dockerCli.Out(), nil)
139+
return jsonmessage.DisplayJSONMessagesToStream(responseBody, dockerCli.Out(), handleAux(dockerCli))
140+
}
141+
142+
var strippedNote = ""
143+
144+
func handleAux(dockerCli command.Cli) func(jm jsonmessage.JSONMessage) {
145+
return func(jm jsonmessage.JSONMessage) {
146+
b := []byte(*jm.Aux)
147+
148+
aux := map[string]string{}
149+
err := json.Unmarshal(b, &aux)
150+
if err != nil {
151+
return
152+
}
153+
154+
strippedNote = string(b)
155+
156+
_, stripped := aux["Stripped"]
157+
if stripped {
158+
index := aux["Index"]
159+
mfst := aux["Manifest"]
160+
161+
strippedNote = fmt.Sprintf(`Not all multiplatform-content is present and only the available single-platform image was pushed
162+
%s -> %s`, red(index), green(mfst))
163+
}
164+
}
165+
}
166+
167+
func red(text string) string {
168+
return fmt.Sprintf("\033[31m%s\033[0m", text)
169+
}
170+
171+
func green(text string) string {
172+
return fmt.Sprintf("\033[32m%s\033[0m", text)
173+
}
174+
175+
func bold(text string) string {
176+
return fmt.Sprintf("\033[1m%s\033[0m", text)
133177
}
134178

135179
func printNote(dockerCli command.Cli, format string, args ...any) {
@@ -138,5 +182,5 @@ func printNote(dockerCli command.Cli, format string, args ...any) {
138182
} else {
139183
_, _ = fmt.Fprint(dockerCli.Err(), "[ NOTE ] ")
140184
}
141-
_, _ = fmt.Fprintf(dockerCli.Err(), format+"\n\n", args...)
185+
_, _ = fmt.Fprintf(dockerCli.Err(), bold(format)+"\n", args...)
142186
}

0 commit comments

Comments
 (0)