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  }