github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/commands/volumes.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"sort"
     7  	"strings"
     8  
     9  	"sigs.k8s.io/yaml"
    10  
    11  	"github.com/pf-qiu/concourse/v6/atc"
    12  	"github.com/pf-qiu/concourse/v6/fly/commands/internal/displayhelpers"
    13  	"github.com/pf-qiu/concourse/v6/fly/rc"
    14  	"github.com/pf-qiu/concourse/v6/fly/ui"
    15  	"github.com/fatih/color"
    16  )
    17  
    18  type VolumesCommand struct {
    19  	Details bool `short:"d" long:"details" description:"Print additional information for each volume"`
    20  	Json    bool `long:"json" description:"Print command result as JSON"`
    21  }
    22  
    23  func (command *VolumesCommand) Execute([]string) error {
    24  	target, err := rc.LoadTarget(Fly.Target, Fly.Verbose)
    25  	if err != nil {
    26  		return err
    27  	}
    28  
    29  	err = target.Validate()
    30  	if err != nil {
    31  		return err
    32  	}
    33  
    34  	volumes, err := target.Team().ListVolumes()
    35  	if err != nil {
    36  		return err
    37  	}
    38  
    39  	if command.Json {
    40  		err = displayhelpers.JsonPrint(volumes)
    41  		if err != nil {
    42  			return err
    43  		}
    44  		return nil
    45  	}
    46  
    47  	table := ui.Table{
    48  		Headers: ui.TableRow{
    49  			{Contents: "handle", Color: color.New(color.Bold)},
    50  			{Contents: "worker", Color: color.New(color.Bold)},
    51  			{Contents: "type", Color: color.New(color.Bold)},
    52  			{Contents: "identifier", Color: color.New(color.Bold)},
    53  		},
    54  	}
    55  
    56  	sort.Sort(volumesByWorkerAndHandle(volumes))
    57  
    58  	for _, c := range volumes {
    59  		row := ui.TableRow{
    60  			{Contents: c.ID},
    61  			{Contents: c.WorkerName},
    62  			{Contents: c.Type},
    63  			{Contents: command.volumeIdentifier(c)},
    64  		}
    65  
    66  		table.Data = append(table.Data, row)
    67  	}
    68  
    69  	return table.Render(os.Stdout, Fly.PrintTableHeaders)
    70  }
    71  
    72  func (command *VolumesCommand) volumeIdentifier(volume atc.Volume) string {
    73  	switch volume.Type {
    74  	case "container":
    75  		if command.Details {
    76  			identifier := fmt.Sprintf("container:%s,path:%s", volume.ContainerHandle, volume.Path)
    77  			if volume.ParentHandle != "" {
    78  				identifier = fmt.Sprintf("%s,parent:%s", identifier, volume.ParentHandle)
    79  			}
    80  			return identifier
    81  		}
    82  
    83  		return volume.ContainerHandle
    84  	case "task-cache":
    85  		return fmt.Sprintf("%s/%s/%s", volume.PipelineName, volume.JobName, volume.StepName)
    86  	case "resource":
    87  		if command.Details {
    88  			return presentResourceType(volume.ResourceType)
    89  		}
    90  		return presentMap(volume.ResourceType.Version)
    91  	case "resource-type":
    92  		if command.Details {
    93  			return presentMap(volume.BaseResourceType)
    94  		}
    95  		return volume.BaseResourceType.Name
    96  	}
    97  
    98  	return "n/a"
    99  }
   100  
   101  func presentMap(version interface{}) string {
   102  	marshalled, _ := yaml.Marshal(version)
   103  	lines := strings.Split(strings.TrimSpace(string(marshalled)), "\n")
   104  	return strings.Replace(strings.Join(lines, ","), " ", "", -1)
   105  }
   106  
   107  func presentResourceType(resourceType *atc.VolumeResourceType) string {
   108  	if resourceType.BaseResourceType != nil {
   109  		return presentMap(resourceType.BaseResourceType)
   110  	}
   111  
   112  	if resourceType.ResourceType != nil {
   113  		innerResourceType := presentResourceType(resourceType.ResourceType)
   114  		version := presentMap(resourceType.Version)
   115  		return fmt.Sprintf("type:resource(%s),version:%s", innerResourceType, version)
   116  	}
   117  
   118  	return ""
   119  }
   120  
   121  type volumesByWorkerAndHandle []atc.Volume
   122  
   123  func (cs volumesByWorkerAndHandle) Len() int          { return len(cs) }
   124  func (cs volumesByWorkerAndHandle) Swap(i int, j int) { cs[i], cs[j] = cs[j], cs[i] }
   125  func (cs volumesByWorkerAndHandle) Less(i int, j int) bool {
   126  	if cs[i].WorkerName == cs[j].WorkerName {
   127  		return cs[i].ID < cs[j].ID
   128  	}
   129  
   130  	return cs[i].WorkerName < cs[j].WorkerName
   131  }