Skip to content
Open
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
4 changes: 4 additions & 0 deletions cmd/uncloud/image/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func NewListCommand() *cobra.Command {
uncli := cmd.Context().Value("cli").(*cli.CLI)
return list(cmd.Context(), uncli, opts)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
uncli := cmd.Context().Value("cli").(*cli.CLI)
return completion.Images(cmd.Context(), uncli, args, toComplete)
},
}

cmd.Flags().StringSliceVarP(&opts.machines, "machine", "m", nil,
Expand Down
3 changes: 3 additions & 0 deletions cmd/uncloud/image/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ The image is uploaded to all cluster machines (default) or the specified machine
opts.image = args[0]
return push(cmd.Context(), uncli, opts)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
return completion.LocalImages(cmd.Context(), args, toComplete)
},
}

cmd.Flags().StringSliceVarP(&opts.machines, "machine", "m", nil,
Expand Down
6 changes: 6 additions & 0 deletions cmd/uncloud/service/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ func NewRunCommand(groupID string) *cobra.Command {

return run(cmd.Context(), uncli, opts)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
if len(args) > 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
return completion.LocalImages(cmd.Context(), args, toComplete)
},
GroupID: groupID,
}

Expand Down
70 changes: 70 additions & 0 deletions internal/cli/completion/image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package completion

import (
"context"
"slices"
"strings"

"github.com/docker/docker/api/types/image"
dockerclient "github.com/docker/docker/client"
"github.com/psviderski/uncloud/internal/cli"
"github.com/psviderski/uncloud/internal/docker"
"github.com/psviderski/uncloud/pkg/api"
"github.com/spf13/cobra"
)

// Images allows for completion of remote images.
func Images(ctx context.Context, uncli *cli.CLI, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
client, err := uncli.ConnectCluster(ctx)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
defer client.Close()

machineImages, err := client.ListImages(ctx, api.ImageFilter{})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
names := []cobra.Completion{}
for _, machineImage := range machineImages {
for _, image := range machineImage.Images {
if len(image.RepoTags) > 0 {
if slices.Contains(args, image.RepoTags[0]) {
continue
}
if strings.HasPrefix(image.RepoTags[0], toComplete) {
names = append(names, image.RepoTags[0])
}
}
}
}
return names, cobra.ShellCompDirectiveNoFileComp
}

// LocalImages allows for local image completion.
func LocalImages(ctx context.Context, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
dockerCliWrapped, err := dockerclient.NewClientWithOpts(dockerclient.FromEnv, dockerclient.WithAPIVersionNegotiation())
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
dockerCli := &docker.Client{Client: dockerCliWrapped}
defer dockerCli.Close()

images, err := dockerCli.ImageList(context.Background(), image.ListOptions{})
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

names := []cobra.Completion{}
for _, image := range images {
if len(image.RepoTags) > 0 {
if slices.Contains(args, image.RepoTags[0]) {
continue
}
if strings.HasPrefix(image.RepoTags[0], toComplete) {
names = append(names, image.RepoTags[0])
}
}
}
return names, cobra.ShellCompDirectiveNoFileComp
}
Loading