mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-28 12:03:33 +00:00
feat(images): list images filtered by name
This commit is contained in:
+55
-7
@@ -20,27 +20,38 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type listOptions struct {
|
type listOptions struct {
|
||||||
machines []string
|
machines []string
|
||||||
context string
|
nameFilter string
|
||||||
|
context string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewListCommand() *cobra.Command {
|
func NewListCommand() *cobra.Command {
|
||||||
opts := listOptions{}
|
opts := listOptions{}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "ls",
|
Use: "ls [IMAGE]",
|
||||||
Aliases: []string{"list"},
|
Aliases: []string{"list"},
|
||||||
Short: "List images on machines in the cluster.",
|
Short: "List images on machines in the cluster.",
|
||||||
Long: "List images on machines in the cluster. By default, on all machines.",
|
Long: "List images on machines in the cluster. By default, on all machines. Optionally filter by image name.",
|
||||||
Example: ` # List images on all machines.
|
Example: ` # List all images on all machines.
|
||||||
uc image ls
|
uc image ls
|
||||||
|
|
||||||
# List images on specific machine.
|
# List images on specific machine.
|
||||||
uc image ls -m machine1
|
uc image ls -m machine1
|
||||||
|
|
||||||
# List images on multiple machines.
|
# List images on multiple machines.
|
||||||
uc image ls -m machine1,machine2`,
|
uc image ls -m machine1,machine2
|
||||||
|
|
||||||
|
# List images filtered by name (with any tag) on all machines.
|
||||||
|
uc image ls myapp
|
||||||
|
|
||||||
|
# List images filtered by name and tag on specific machine.
|
||||||
|
uc image ls myapp:1.2.3 -m machine1`,
|
||||||
|
Args: cobra.MaximumNArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) > 0 {
|
||||||
|
opts.nameFilter = args[0]
|
||||||
|
}
|
||||||
uncli := cmd.Context().Value("cli").(*cli.CLI)
|
uncli := cmd.Context().Value("cli").(*cli.CLI)
|
||||||
return list(cmd.Context(), uncli, opts)
|
return list(cmd.Context(), uncli, opts)
|
||||||
},
|
},
|
||||||
@@ -145,8 +156,14 @@ func list(ctx context.Context, uncli *cli.CLI, opts listOptions) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rows = filterImagesByName(rows, opts.nameFilter)
|
||||||
|
|
||||||
if len(rows) == 0 {
|
if len(rows) == 0 {
|
||||||
fmt.Println("No images found.")
|
if opts.nameFilter != "" {
|
||||||
|
fmt.Printf("No images matching '%s' found.\n", opts.nameFilter)
|
||||||
|
} else {
|
||||||
|
fmt.Println("No images found.")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +181,37 @@ func list(ctx context.Context, uncli *cli.CLI, opts listOptions) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filterImagesByName filters the image rows by image name. It matches any tag of the image if only the name
|
||||||
|
// is provided. For example, if filter is "nginx", it matches "nginx", "nginx:latest", "nginx:1.25", etc.
|
||||||
|
// If filter is "nginx:latest", it matches only "nginx:latest".
|
||||||
|
func filterImagesByName(rows []imageRow, nameFilter string) []imageRow {
|
||||||
|
if nameFilter == "" {
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
|
var filteredRows []imageRow
|
||||||
|
for _, row := range rows {
|
||||||
|
if row.name == "<none>" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(nameFilter, ":") {
|
||||||
|
// Exact match if filter contains a tag.
|
||||||
|
if row.name == nameFilter {
|
||||||
|
filteredRows = append(filteredRows, row)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match by name prefix if filter does not contain a tag.
|
||||||
|
if strings.HasPrefix(row.name, nameFilter) &&
|
||||||
|
len(row.name) > len(nameFilter) && row.name[len(nameFilter)] == ':' {
|
||||||
|
filteredRows = append(filteredRows, row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredRows
|
||||||
|
}
|
||||||
|
|
||||||
// imagePlatforms returns a list of platforms supported by the image and a boolean indicating if it's multi-platform.
|
// imagePlatforms returns a list of platforms supported by the image and a boolean indicating if it's multi-platform.
|
||||||
func imagePlatforms(img image.Summary) ([]string, bool) {
|
func imagePlatforms(img image.Summary) ([]string, bool) {
|
||||||
var formattedPlatforms []string
|
var formattedPlatforms []string
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
// NewImagesCommand returns the 'image ls' command modified to work as 'images'.
|
// NewImagesCommand returns the 'image ls' command modified to work as 'images'.
|
||||||
func NewImagesCommand() *cobra.Command {
|
func NewImagesCommand() *cobra.Command {
|
||||||
listCmd := image.NewListCommand()
|
listCmd := image.NewListCommand()
|
||||||
listCmd.Use = "images"
|
listCmd.Use = "images [IMAGE]"
|
||||||
// Remove 'list' alias since this command is already an alias.
|
// Remove 'list' alias since this command is already an alias.
|
||||||
listCmd.Aliases = nil
|
listCmd.Aliases = nil
|
||||||
listCmd.Example = strings.ReplaceAll(listCmd.Example, "uc image ls", "uc images")
|
listCmd.Example = strings.ReplaceAll(listCmd.Example, "uc image ls", "uc images")
|
||||||
|
|||||||
Reference in New Issue
Block a user