From f4c164d9b8824a564f1f729f165e59f9bb43ec00 Mon Sep 17 00:00:00 2001 From: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:33:49 +0200 Subject: [PATCH 1/4] feat: pull completion using hub Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> --- cli/command/completion/functions.go | 124 ++++++++++++++++++++++++++++ cli/command/container/run.go | 28 ++++++- cli/command/image/pull.go | 7 +- scripts/build/binary | 2 +- 4 files changed, 158 insertions(+), 3 deletions(-) diff --git a/cli/command/completion/functions.go b/cli/command/completion/functions.go index b217ec54b05d..917c84ff1f07 100644 --- a/cli/command/completion/functions.go +++ b/cli/command/completion/functions.go @@ -1,8 +1,12 @@ package completion import ( + "encoding/json" + "net/http" + "net/url" "os" "strings" + "time" "github.com/docker/cli/cli/command/formatter" "github.com/docker/docker/api/types/container" @@ -10,6 +14,7 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -189,3 +194,122 @@ var commonPlatforms = []string{ func Platforms(_ *cobra.Command, _ []string, _ string) (platforms []string, _ cobra.ShellCompDirective) { return commonPlatforms, cobra.ShellCompDirectiveNoFileComp } + +type ImageSearchResult struct { + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Type string `json:"type"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + ShortDesc string `json:"short_description"` + Source string `json:"source"` + StarCount int `json:"star_count"` +} + +type ImageSearch struct { + Totals int `json:"totals"` + Results []ImageSearchResult `json:"results"` +} + +type Image struct { + ID int `json:"id"` + Name string `json:"name"` + TagStatus string `json:"tag_status"` + V2 bool `json:"v2"` + Digest string `json:"digest"` + LastUpdated time.Time `json:"last_updated"` + LastUpdater int `json:"last_updater"` + Creator int `json:"creator"` + Repository int `json:"repository"` +} +type ImageTags struct { + Count int `json:"count"` + Next string `json:"next"` + Prev string `json:"prev"` + Results []Image `json:"results"` +} + +func Images(cmd *cobra.Command, arg []string, toComplete string) ([]string, cobra.ShellCompDirective) { + ctx := cmd.Context() + c := &http.Client{ + Timeout: 2 * time.Second, + } + + if imageName, imageTag, ok := strings.Cut(toComplete, ":"); ok { + u, err := url.Parse("https://hub.docker.com/v2/repositories/library/" + imageName + "/tags/") + if err != nil { + logrus.Errorf("Error parsing hub image tags URL: %v", err) + return nil, cobra.ShellCompDirectiveError + } + q := u.Query() + q.Set("ordering", "last_updated") + q.Set("page_size", "25") + q.Set("name", imageTag) + u.RawQuery = q.Encode() + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) + if err != nil { + logrus.Errorf("Error creating hub image tags request: %v", err) + return nil, cobra.ShellCompDirectiveError + } + + resp, err := c.Do(req) + if err != nil { + logrus.Errorf("Error sending hub image tags request: %v", err) + return nil, cobra.ShellCompDirectiveError + } + + defer resp.Body.Close() + + var tags *ImageTags + if err := json.NewDecoder(resp.Body).Decode(&tags); err != nil { + logrus.Errorf("Error decoding hub image tags response: %v", err) + return nil, cobra.ShellCompDirectiveError + } + + names := make([]string, 0, len(tags.Results)) + for _, i := range tags.Results { + names = append(names, imageName+":"+i.Name) + } + return names, cobra.ShellCompDirectiveNoFileComp + } + + u, err := url.Parse("https://hub.docker.com/api/search/v3/catalog/search") + if err != nil { + logrus.Errorf("Error parsing hub image search URL: %v", err) + return nil, cobra.ShellCompDirectiveNoFileComp + } + q := u.Query() + q.Set("query", toComplete) + q.Set("extension_reviewed", "") + q.Set("from", "0") + q.Set("size", "25") + u.RawQuery = q.Encode() + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) + if err != nil { + logrus.Errorf("Error creating hub image search request: %v", err) + return nil, cobra.ShellCompDirectiveNoFileComp + } + + resp, err := c.Do(req) + if err != nil { + logrus.Errorf("Error sending hub image search request: %v", err) + return nil, cobra.ShellCompDirectiveNoFileComp + } + defer resp.Body.Close() + + var images *ImageSearch + if err := json.NewDecoder(resp.Body).Decode(&images); err != nil { + logrus.Errorf("Error decoding hub image search response: %v", err) + return nil, cobra.ShellCompDirectiveNoFileComp + } + + names := make([]string, 0, len(images.Results)) + for _, i := range images.Results { + names = append(names, i.Name) + } + + return names, cobra.ShellCompDirectiveNoFileComp +} diff --git a/cli/command/container/run.go b/cli/command/container/run.go index a3fc5f983a3d..dc115df2ee8e 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -43,7 +43,33 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command { } return runRun(cmd.Context(), dockerCli, cmd.Flags(), &options, copts) }, - ValidArgsFunction: completion.ImageNames(dockerCli), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + unique := map[string]struct{}{} + localImages, shellComp := completion.ImageNames(dockerCli)(cmd, args, toComplete) + + var all []string + if shellComp != cobra.ShellCompDirectiveError { + all = make([]string, 0, len(localImages)) + for _, img := range localImages { + unique[img] = struct{}{} + all = append(all, fmt.Sprintf("%s\tlocal", img)) + } + } + + remoteImages, shellCompRemote := completion.Images(cmd, args, toComplete) + if shellCompRemote != cobra.ShellCompDirectiveError { + if len(all) == 0 { + all = make([]string, 0, len(remoteImages)) + } + for _, img := range remoteImages { + if _, ok := unique[img]; !ok { + all = append(all, fmt.Sprintf("%s\tremote", img)) + } + } + } + + return all, cobra.ShellCompDirectiveKeepOrder | cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveDefault + }, Annotations: map[string]string{ "category-top": "1", "aliases": "docker container run, docker run", diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index 93388253f75a..928a3c0b81e0 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -39,7 +39,12 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command { "category-top": "5", "aliases": "docker image pull, docker pull", }, - ValidArgsFunction: completion.NoComplete, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return completion.Images(cmd, args, toComplete) + }, } flags := cmd.Flags() diff --git a/scripts/build/binary b/scripts/build/binary index 44cd4f14fdd8..33f37628c20d 100755 --- a/scripts/build/binary +++ b/scripts/build/binary @@ -24,6 +24,6 @@ if [ "$(go env GOOS)" = "windows" ]; then fi fi -(set -x ; go build -o "${TARGET}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} "${SOURCE}") +(set -x ; go build -o "${TARGET}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} -buildvcs=false "${SOURCE}") ln -sf "$(basename "${TARGET}")" "$(dirname "${TARGET}")/docker" From 5760a3d201961e0452902e815ac839647f6825e6 Mon Sep 17 00:00:00 2001 From: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:19:09 +0200 Subject: [PATCH 2/4] feat: run with hub completion Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> --- cli/command/completion/functions.go | 12 ++++++------ cli/command/container/run.go | 15 ++++++++++----- cli/command/image/pull.go | 2 +- cmd/docker/docker.go | 2 +- scripts/build/binary | 2 +- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/cli/command/completion/functions.go b/cli/command/completion/functions.go index 917c84ff1f07..978615bfb3d3 100644 --- a/cli/command/completion/functions.go +++ b/cli/command/completion/functions.go @@ -223,6 +223,7 @@ type Image struct { Creator int `json:"creator"` Repository int `json:"repository"` } + type ImageTags struct { Count int `json:"count"` Next string `json:"next"` @@ -230,7 +231,7 @@ type ImageTags struct { Results []Image `json:"results"` } -func Images(cmd *cobra.Command, arg []string, toComplete string) ([]string, cobra.ShellCompDirective) { +func RemoteImages(cmd *cobra.Command, arg []string, toComplete string) ([]string, cobra.ShellCompDirective) { ctx := cmd.Context() c := &http.Client{ Timeout: 2 * time.Second, @@ -259,7 +260,6 @@ func Images(cmd *cobra.Command, arg []string, toComplete string) ([]string, cobr logrus.Errorf("Error sending hub image tags request: %v", err) return nil, cobra.ShellCompDirectiveError } - defer resp.Body.Close() var tags *ImageTags @@ -278,7 +278,7 @@ func Images(cmd *cobra.Command, arg []string, toComplete string) ([]string, cobr u, err := url.Parse("https://hub.docker.com/api/search/v3/catalog/search") if err != nil { logrus.Errorf("Error parsing hub image search URL: %v", err) - return nil, cobra.ShellCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveError } q := u.Query() q.Set("query", toComplete) @@ -290,20 +290,20 @@ func Images(cmd *cobra.Command, arg []string, toComplete string) ([]string, cobr req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { logrus.Errorf("Error creating hub image search request: %v", err) - return nil, cobra.ShellCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveError } resp, err := c.Do(req) if err != nil { logrus.Errorf("Error sending hub image search request: %v", err) - return nil, cobra.ShellCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveError } defer resp.Body.Close() var images *ImageSearch if err := json.NewDecoder(resp.Body).Decode(&images); err != nil { logrus.Errorf("Error decoding hub image search response: %v", err) - return nil, cobra.ShellCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveError } names := make([]string, 0, len(images.Results)) diff --git a/cli/command/container/run.go b/cli/command/container/run.go index dc115df2ee8e..aeaffe680eb9 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -37,13 +37,18 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command { Short: "Create and run a new container from an image", Args: cli.RequiresMinArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - copts.Image = args[0] + replacer := strings.NewReplacer("(local)", "", "(remote)", "") + copts.Image = replacer.Replace(args[0]) if len(args) > 1 { copts.Args = args[1:] } return runRun(cmd.Context(), dockerCli, cmd.Flags(), &options, copts) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + unique := map[string]struct{}{} localImages, shellComp := completion.ImageNames(dockerCli)(cmd, args, toComplete) @@ -52,23 +57,23 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command { all = make([]string, 0, len(localImages)) for _, img := range localImages { unique[img] = struct{}{} - all = append(all, fmt.Sprintf("%s\tlocal", img)) + all = append(all, img+"\tlocal") } } - remoteImages, shellCompRemote := completion.Images(cmd, args, toComplete) + remoteImages, shellCompRemote := completion.RemoteImages(cmd, args, toComplete) if shellCompRemote != cobra.ShellCompDirectiveError { if len(all) == 0 { all = make([]string, 0, len(remoteImages)) } for _, img := range remoteImages { if _, ok := unique[img]; !ok { - all = append(all, fmt.Sprintf("%s\tremote", img)) + all = append(all, img+"\tremote") } } } - return all, cobra.ShellCompDirectiveKeepOrder | cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveDefault + return all, cobra.ShellCompDirectiveKeepOrder | cobra.ShellCompDirectiveNoFileComp }, Annotations: map[string]string{ "category-top": "1", diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index 928a3c0b81e0..2d81bfa7bc73 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -43,7 +43,7 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command { if len(args) > 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - return completion.Images(cmd, args, toComplete) + return completion.RemoteImages(cmd, args, toComplete) }, } diff --git a/cmd/docker/docker.go b/cmd/docker/docker.go index 8b15b76f8ec7..23c536dbaf9e 100644 --- a/cmd/docker/docker.go +++ b/cmd/docker/docker.go @@ -92,7 +92,7 @@ func newDockerCommand(dockerCli *command.DockerCli) *cli.TopLevelCommand { CompletionOptions: cobra.CompletionOptions{ DisableDefaultCmd: false, HiddenDefaultCmd: true, - DisableDescriptions: true, + DisableDescriptions: false, }, } cmd.SetIn(dockerCli.In()) diff --git a/scripts/build/binary b/scripts/build/binary index 33f37628c20d..44cd4f14fdd8 100755 --- a/scripts/build/binary +++ b/scripts/build/binary @@ -24,6 +24,6 @@ if [ "$(go env GOOS)" = "windows" ]; then fi fi -(set -x ; go build -o "${TARGET}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} -buildvcs=false "${SOURCE}") +(set -x ; go build -o "${TARGET}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} "${SOURCE}") ln -sf "$(basename "${TARGET}")" "$(dirname "${TARGET}")/docker" From 5667a952c5fbaaab6de161645e7f20fb90be2470 Mon Sep 17 00:00:00 2001 From: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:42:47 +0200 Subject: [PATCH 3/4] feat: use engine API instead of Hub directly Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> --- cli/command/completion/functions.go | 124 ---------------------------- cli/command/container/run.go | 43 ++++++++-- cli/command/image/pull.go | 46 ++++++++++- 3 files changed, 82 insertions(+), 131 deletions(-) diff --git a/cli/command/completion/functions.go b/cli/command/completion/functions.go index 978615bfb3d3..b217ec54b05d 100644 --- a/cli/command/completion/functions.go +++ b/cli/command/completion/functions.go @@ -1,12 +1,8 @@ package completion import ( - "encoding/json" - "net/http" - "net/url" "os" "strings" - "time" "github.com/docker/cli/cli/command/formatter" "github.com/docker/docker/api/types/container" @@ -14,7 +10,6 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -194,122 +189,3 @@ var commonPlatforms = []string{ func Platforms(_ *cobra.Command, _ []string, _ string) (platforms []string, _ cobra.ShellCompDirective) { return commonPlatforms, cobra.ShellCompDirectiveNoFileComp } - -type ImageSearchResult struct { - ID string `json:"id"` - Name string `json:"name"` - Slug string `json:"slug"` - Type string `json:"type"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - ShortDesc string `json:"short_description"` - Source string `json:"source"` - StarCount int `json:"star_count"` -} - -type ImageSearch struct { - Totals int `json:"totals"` - Results []ImageSearchResult `json:"results"` -} - -type Image struct { - ID int `json:"id"` - Name string `json:"name"` - TagStatus string `json:"tag_status"` - V2 bool `json:"v2"` - Digest string `json:"digest"` - LastUpdated time.Time `json:"last_updated"` - LastUpdater int `json:"last_updater"` - Creator int `json:"creator"` - Repository int `json:"repository"` -} - -type ImageTags struct { - Count int `json:"count"` - Next string `json:"next"` - Prev string `json:"prev"` - Results []Image `json:"results"` -} - -func RemoteImages(cmd *cobra.Command, arg []string, toComplete string) ([]string, cobra.ShellCompDirective) { - ctx := cmd.Context() - c := &http.Client{ - Timeout: 2 * time.Second, - } - - if imageName, imageTag, ok := strings.Cut(toComplete, ":"); ok { - u, err := url.Parse("https://hub.docker.com/v2/repositories/library/" + imageName + "/tags/") - if err != nil { - logrus.Errorf("Error parsing hub image tags URL: %v", err) - return nil, cobra.ShellCompDirectiveError - } - q := u.Query() - q.Set("ordering", "last_updated") - q.Set("page_size", "25") - q.Set("name", imageTag) - u.RawQuery = q.Encode() - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) - if err != nil { - logrus.Errorf("Error creating hub image tags request: %v", err) - return nil, cobra.ShellCompDirectiveError - } - - resp, err := c.Do(req) - if err != nil { - logrus.Errorf("Error sending hub image tags request: %v", err) - return nil, cobra.ShellCompDirectiveError - } - defer resp.Body.Close() - - var tags *ImageTags - if err := json.NewDecoder(resp.Body).Decode(&tags); err != nil { - logrus.Errorf("Error decoding hub image tags response: %v", err) - return nil, cobra.ShellCompDirectiveError - } - - names := make([]string, 0, len(tags.Results)) - for _, i := range tags.Results { - names = append(names, imageName+":"+i.Name) - } - return names, cobra.ShellCompDirectiveNoFileComp - } - - u, err := url.Parse("https://hub.docker.com/api/search/v3/catalog/search") - if err != nil { - logrus.Errorf("Error parsing hub image search URL: %v", err) - return nil, cobra.ShellCompDirectiveError - } - q := u.Query() - q.Set("query", toComplete) - q.Set("extension_reviewed", "") - q.Set("from", "0") - q.Set("size", "25") - u.RawQuery = q.Encode() - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) - if err != nil { - logrus.Errorf("Error creating hub image search request: %v", err) - return nil, cobra.ShellCompDirectiveError - } - - resp, err := c.Do(req) - if err != nil { - logrus.Errorf("Error sending hub image search request: %v", err) - return nil, cobra.ShellCompDirectiveError - } - defer resp.Body.Close() - - var images *ImageSearch - if err := json.NewDecoder(resp.Body).Decode(&images); err != nil { - logrus.Errorf("Error decoding hub image search response: %v", err) - return nil, cobra.ShellCompDirectiveError - } - - names := make([]string, 0, len(images.Results)) - for _, i := range images.Results { - names = append(names, i.Name) - } - - return names, cobra.ShellCompDirectiveNoFileComp -} diff --git a/cli/command/container/run.go b/cli/command/container/run.go index aeaffe680eb9..9d6777714207 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -12,6 +12,7 @@ import ( "github.com/docker/cli/cli/command/completion" "github.com/docker/cli/opts" "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/hub" "github.com/moby/sys/signal" "github.com/moby/term" "github.com/pkg/errors" @@ -61,14 +62,44 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command { } } - remoteImages, shellCompRemote := completion.RemoteImages(cmd, args, toComplete) - if shellCompRemote != cobra.ShellCompDirectiveError { + if image, tag, found := strings.Cut(toComplete, ":"); found { + remoteTags, err := dockerCli.Client().ImageHubTags(cmd.Context(), image, hub.ImageOptions{ + Name: tag, + Ordering: "last_updated", + Page: 0, + PageSize: 25, + }) + if err == nil { + if len(all) == 0 { + all = make([]string, 0, len(remoteTags.Results)) + } + for _, tag := range remoteTags.Results { + fullName := image + ":" + tag.Name + if _, ok := unique[fullName]; !ok { + all = append(all, fullName+"\tremote") + } + } + } + return all, cobra.ShellCompDirectiveKeepOrder | cobra.ShellCompDirectiveNoFileComp + } + + remoteImages, err := dockerCli.Client().ImageHubSearch(cmd.Context(), toComplete, hub.SearchOptions{ + From: 0, + Size: 25, + Type: hub.SearchTypeImage, + Order: hub.SearchOrderDesc, + Official: true, + Source: hub.SearchSourceStore, + OpenSource: true, + ExtensionReviewed: true, + }) + if err == nil { if len(all) == 0 { - all = make([]string, 0, len(remoteImages)) + all = make([]string, 0, len(remoteImages.Results)) } - for _, img := range remoteImages { - if _, ok := unique[img]; !ok { - all = append(all, img+"\tremote") + for _, img := range remoteImages.Results { + if _, ok := unique[img.Name]; !ok { + all = append(all, img.Name+"\tremote") } } } diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index 2d81bfa7bc73..e051b9e6edbc 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -10,6 +10,7 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/trust" + "github.com/docker/docker/api/types/hub" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -43,7 +44,50 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command { if len(args) > 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - return completion.RemoteImages(cmd, args, toComplete) + + if image, tag, found := strings.Cut(toComplete, ":"); found { + remoteTags, err := dockerCli.Client().ImageHubTags(cmd.Context(), image, hub.ImageOptions{ + Name: tag, + Ordering: "last_updated", + Page: 0, + PageSize: 25, + }) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + images := make([]string, 0, len(remoteTags.Results)) + for _, tag := range remoteTags.Results { + fullName := image + ":" + tag.Name + images = append(images, fullName+"\t"+tag.LastUpdated.String()) + } + return images, cobra.ShellCompDirectiveKeepOrder | cobra.ShellCompDirectiveNoFileComp + } + + remoteImages, err := dockerCli.Client().ImageHubSearch(cmd.Context(), toComplete, hub.SearchOptions{ + From: 0, + Size: 25, + Type: hub.SearchTypeImage, + Order: hub.SearchOrderDesc, + Official: true, + Source: hub.SearchSourceStore, + OpenSource: true, + ExtensionReviewed: true, + }) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + images := make([]string, 0, len(remoteImages.Results)) + for _, img := range remoteImages.Results { + categories := make([]string, 0, len(img.Categories)) + for _, cat := range img.Categories { + categories = append(categories, cat.Name) + } + images = append(images, img.Name+"\t"+strings.Join(categories, ", ")) + } + + return images, cobra.ShellCompDirectiveKeepOrder | cobra.ShellCompDirectiveNoFileComp }, } From eea706f6f46a4fa82a17983cadfab25209d6ff2e Mon Sep 17 00:00:00 2001 From: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> Date: Thu, 14 Nov 2024 09:44:36 +0100 Subject: [PATCH 4/4] chore: update docker client Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> --- cli/command/container/run.go | 4 ++-- cli/command/image/pull.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/command/container/run.go b/cli/command/container/run.go index 9d6777714207..2818af849ca4 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -63,7 +63,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command { } if image, tag, found := strings.Cut(toComplete, ":"); found { - remoteTags, err := dockerCli.Client().ImageHubTags(cmd.Context(), image, hub.ImageOptions{ + remoteTags, err := dockerCli.Client().HubImageTags(cmd.Context(), image, hub.ImageOptions{ Name: tag, Ordering: "last_updated", Page: 0, @@ -83,7 +83,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command { return all, cobra.ShellCompDirectiveKeepOrder | cobra.ShellCompDirectiveNoFileComp } - remoteImages, err := dockerCli.Client().ImageHubSearch(cmd.Context(), toComplete, hub.SearchOptions{ + remoteImages, err := dockerCli.Client().HubImageSearch(cmd.Context(), toComplete, hub.SearchOptions{ From: 0, Size: 25, Type: hub.SearchTypeImage, diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index e051b9e6edbc..3f5ba8ec773b 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -46,7 +46,7 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command { } if image, tag, found := strings.Cut(toComplete, ":"); found { - remoteTags, err := dockerCli.Client().ImageHubTags(cmd.Context(), image, hub.ImageOptions{ + remoteTags, err := dockerCli.Client().HubImageTags(cmd.Context(), image, hub.ImageOptions{ Name: tag, Ordering: "last_updated", Page: 0, @@ -64,7 +64,7 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command { return images, cobra.ShellCompDirectiveKeepOrder | cobra.ShellCompDirectiveNoFileComp } - remoteImages, err := dockerCli.Client().ImageHubSearch(cmd.Context(), toComplete, hub.SearchOptions{ + remoteImages, err := dockerCli.Client().HubImageSearch(cmd.Context(), toComplete, hub.SearchOptions{ From: 0, Size: 25, Type: hub.SearchTypeImage,