github.com/khulnasoft/cli@v0.0.0-20240402070845-01bcad7beefa/cli/command/volume/list.go (about) 1 package volume 2 3 import ( 4 "context" 5 "sort" 6 7 "github.com/docker/docker/api/types/volume" 8 "github.com/fvbommel/sortorder" 9 "github.com/khulnasoft/cli/cli" 10 "github.com/khulnasoft/cli/cli/command" 11 "github.com/khulnasoft/cli/cli/command/completion" 12 "github.com/khulnasoft/cli/cli/command/formatter" 13 flagsHelper "github.com/khulnasoft/cli/cli/flags" 14 "github.com/khulnasoft/cli/opts" 15 "github.com/spf13/cobra" 16 ) 17 18 const ( 19 clusterTableFormat = "table {{.Name}}\t{{.Group}}\t{{.Driver}}\t{{.Availability}}\t{{.Status}}" 20 ) 21 22 type listOptions struct { 23 quiet bool 24 format string 25 cluster bool 26 filter opts.FilterOpt 27 } 28 29 func newListCommand(dockerCli command.Cli) *cobra.Command { 30 options := listOptions{filter: opts.NewFilterOpt()} 31 32 cmd := &cobra.Command{ 33 Use: "ls [OPTIONS]", 34 Aliases: []string{"list"}, 35 Short: "List volumes", 36 Args: cli.NoArgs, 37 RunE: func(cmd *cobra.Command, args []string) error { 38 return runList(cmd.Context(), dockerCli, options) 39 }, 40 ValidArgsFunction: completion.NoComplete, 41 } 42 43 flags := cmd.Flags() 44 flags.BoolVarP(&options.quiet, "quiet", "q", false, "Only display volume names") 45 flags.StringVar(&options.format, "format", "", flagsHelper.FormatHelp) 46 flags.VarP(&options.filter, "filter", "f", `Provide filter values (e.g. "dangling=true")`) 47 flags.BoolVar(&options.cluster, "cluster", false, "Display only cluster volumes, and use cluster volume list formatting") 48 flags.SetAnnotation("cluster", "version", []string{"1.42"}) 49 flags.SetAnnotation("cluster", "swarm", []string{"manager"}) 50 51 return cmd 52 } 53 54 func runList(ctx context.Context, dockerCli command.Cli, options listOptions) error { 55 client := dockerCli.Client() 56 volumes, err := client.VolumeList(ctx, volume.ListOptions{Filters: options.filter.Value()}) 57 if err != nil { 58 return err 59 } 60 61 format := options.format 62 if len(format) == 0 && !options.cluster { 63 if len(dockerCli.ConfigFile().VolumesFormat) > 0 && !options.quiet { 64 format = dockerCli.ConfigFile().VolumesFormat 65 } else { 66 format = formatter.TableFormatKey 67 } 68 } else if options.cluster { 69 // TODO(dperny): write server-side filter for cluster volumes. For this 70 // proof of concept, we'll just filter out non-cluster volumes here 71 72 // trick for filtering in place 73 n := 0 74 for _, vol := range volumes.Volumes { 75 if vol.ClusterVolume != nil { 76 volumes.Volumes[n] = vol 77 n++ 78 } 79 } 80 volumes.Volumes = volumes.Volumes[:n] 81 if !options.quiet { 82 format = clusterTableFormat 83 } else { 84 format = formatter.TableFormatKey 85 } 86 } 87 88 sort.Slice(volumes.Volumes, func(i, j int) bool { 89 return sortorder.NaturalLess(volumes.Volumes[i].Name, volumes.Volumes[j].Name) 90 }) 91 92 volumeCtx := formatter.Context{ 93 Output: dockerCli.Out(), 94 Format: formatter.NewVolumeFormat(format, options.quiet), 95 } 96 return formatter.VolumeWrite(volumeCtx, volumes.Volumes) 97 }