Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions cli/command/manifest/annotate.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"slices"

"github.com/containerd/errdefs"
"github.com/containerd/platforms"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
Expand Down Expand Up @@ -139,8 +140,15 @@ func runManifestAnnotate(dockerCLI command.Cli, opts annotateOptions) error {
imageManifest.Descriptor.Platform.OSVersion = opts.osVersion
}

if !isValidOSArch(imageManifest.Descriptor.Platform.OS, imageManifest.Descriptor.Platform.Architecture) {
return fmt.Errorf("manifest entry for image has unsupported os/arch combination: %s/%s", opts.os, opts.arch)
// Validate platform syntax, without restricting OS/architecture combinations.
//
// TODO(thaJeztah): Implement a platforms.Validate in containerd/platforms and replace this code.
p := imageManifest.Descriptor.Platform
Comment on lines +143 to +146

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if p.OS == "" || p.Architecture == "" {
return fmt.Errorf("manifest entry for image has missing os/architecture: %q/%q", p.OS, p.Architecture)
}
if _, err := platforms.Parse(platforms.FormatAll(*p)); err != nil {
return fmt.Errorf("manifest entry for image has invalid platform: %w", err)
}
return manifestStore.Save(targetRef, imgRef, imageManifest)
}
Expand Down
15 changes: 8 additions & 7 deletions cli/command/manifest/annotate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,16 @@ func TestManifestAnnotate(t *testing.T) {
assert.ErrorContains(t, cmd.Execute(), expectedError)

cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.Flags().Set("os", "freebsd")
cmd.Flags().Set("arch", "fake")
cmd.Flags().Set("os-version", "1")
cmd.Flags().Set("os-features", "feature1")
cmd.Flags().Set("variant", "v7")
expectedError = "manifest entry for image has unsupported os/arch combination"
assert.NilError(t, cmd.Flags().Set("os", "freebsd"))
assert.NilError(t, cmd.Flags().Set("arch", "<invalid>"))
assert.NilError(t, cmd.Flags().Set("os-version", "1"))
assert.NilError(t, cmd.Flags().Set("os-features", "feature1"))
assert.NilError(t, cmd.Flags().Set("variant", "v7"))

expectedError = "manifest entry for image has invalid platform"
assert.ErrorContains(t, cmd.Execute(), expectedError)

cmd.Flags().Set("arch", "arm")
assert.NilError(t, cmd.Flags().Set("arch", "arm"))
assert.NilError(t, cmd.Execute())

cmd = newInspectCommand(cli)
Expand Down
47 changes: 0 additions & 47 deletions cli/command/manifest/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,53 +9,6 @@ import (
"github.com/docker/cli/cli/manifest/types"
)

type osArch struct {
os string
arch string
}

// Remove any unsupported os/arch combo
// list of valid os/arch values (see "Optional Environment Variables" section
// of https://go.dev/doc/install/source
// Added linux/s390x as we know System z support already exists
// Keep in sync with _docker_manifest_annotate in contrib/completion/bash/docker
var validOSArches = map[osArch]bool{
{os: "darwin", arch: "386"}: true,
{os: "darwin", arch: "amd64"}: true,
{os: "darwin", arch: "arm"}: true,
{os: "darwin", arch: "arm64"}: true,
{os: "dragonfly", arch: "amd64"}: true,
{os: "freebsd", arch: "386"}: true,
{os: "freebsd", arch: "amd64"}: true,
{os: "freebsd", arch: "arm"}: true,
{os: "linux", arch: "386"}: true,
{os: "linux", arch: "amd64"}: true,
{os: "linux", arch: "arm"}: true,
{os: "linux", arch: "arm64"}: true,
{os: "linux", arch: "ppc64le"}: true,
{os: "linux", arch: "mips64"}: true,
{os: "linux", arch: "mips64le"}: true,
{os: "linux", arch: "riscv64"}: true,
{os: "linux", arch: "s390x"}: true,
{os: "netbsd", arch: "386"}: true,
{os: "netbsd", arch: "amd64"}: true,
{os: "netbsd", arch: "arm"}: true,
{os: "openbsd", arch: "386"}: true,
{os: "openbsd", arch: "amd64"}: true,
{os: "openbsd", arch: "arm"}: true,
{os: "plan9", arch: "386"}: true,
{os: "plan9", arch: "amd64"}: true,
{os: "solaris", arch: "amd64"}: true,
{os: "windows", arch: "386"}: true,
{os: "windows", arch: "amd64"}: true,
}

func isValidOSArch(os string, arch string) bool {
// check for existence of this combo
_, ok := validOSArches[osArch{os, arch}]
return ok
}

func normalizeReference(ref string) (reference.Named, error) {
namedRef, err := reference.ParseNormalizedNamed(ref)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions contrib/completion/bash/docker
Original file line number Diff line number Diff line change
Expand Up @@ -4156,6 +4156,7 @@ _docker_manifest_annotate() {
amd64
arm
arm64
loong64
mips64
mips64le
ppc64le
Expand Down
Loading