github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/storage/filesystemlistformatters.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package storage
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"sort"
    10  	"strings"
    11  
    12  	"github.com/dustin/go-humanize"
    13  	"github.com/juju/juju/cmd/output"
    14  )
    15  
    16  // formatFilesystemListTabular writes a tabular summary of filesystem instances.
    17  func formatFilesystemListTabular(writer io.Writer, infos map[string]FilesystemInfo) error {
    18  	tw := output.TabWriter(writer)
    19  
    20  	print := func(values ...string) {
    21  		fmt.Fprintln(tw, strings.Join(values, "\t"))
    22  	}
    23  	print("MACHINE", "UNIT", "STORAGE", "ID", "VOLUME", "PROVIDER-ID", "MOUNTPOINT", "SIZE", "STATE", "MESSAGE")
    24  
    25  	filesystemAttachmentInfos := make(filesystemAttachmentInfos, 0, len(infos))
    26  	for filesystemId, info := range infos {
    27  		filesystemAttachmentInfo := filesystemAttachmentInfo{
    28  			FilesystemId:   filesystemId,
    29  			FilesystemInfo: info,
    30  		}
    31  		if info.Attachments == nil {
    32  			filesystemAttachmentInfos = append(filesystemAttachmentInfos, filesystemAttachmentInfo)
    33  			continue
    34  		}
    35  		// Each unit attachment must have a corresponding filesystem
    36  		// attachment. Enumerate each of the filesystem attachments,
    37  		// and locate the corresponding unit attachment if any.
    38  		// Each filesystem attachment has at most one corresponding
    39  		// unit attachment.
    40  		for machineId, machineInfo := range info.Attachments.Machines {
    41  			filesystemAttachmentInfo := filesystemAttachmentInfo
    42  			filesystemAttachmentInfo.MachineId = machineId
    43  			filesystemAttachmentInfo.MachineFilesystemAttachment = machineInfo
    44  			for unitId, unitInfo := range info.Attachments.Units {
    45  				if unitInfo.MachineId == machineId {
    46  					filesystemAttachmentInfo.UnitId = unitId
    47  					filesystemAttachmentInfo.UnitStorageAttachment = unitInfo
    48  					break
    49  				}
    50  			}
    51  			filesystemAttachmentInfos = append(filesystemAttachmentInfos, filesystemAttachmentInfo)
    52  		}
    53  	}
    54  	sort.Sort(filesystemAttachmentInfos)
    55  
    56  	for _, info := range filesystemAttachmentInfos {
    57  		var size string
    58  		if info.Size > 0 {
    59  			size = humanize.IBytes(info.Size * humanize.MiByte)
    60  		}
    61  		print(
    62  			info.MachineId, info.UnitId, info.Storage,
    63  			info.FilesystemId, info.Volume, info.ProviderFilesystemId,
    64  			info.MountPoint, size,
    65  			string(info.Status.Current), info.Status.Message,
    66  		)
    67  	}
    68  
    69  	return tw.Flush()
    70  }
    71  
    72  type filesystemAttachmentInfo struct {
    73  	FilesystemId string
    74  	FilesystemInfo
    75  
    76  	MachineId string
    77  	MachineFilesystemAttachment
    78  
    79  	UnitId string
    80  	UnitStorageAttachment
    81  }
    82  
    83  type filesystemAttachmentInfos []filesystemAttachmentInfo
    84  
    85  func (v filesystemAttachmentInfos) Len() int {
    86  	return len(v)
    87  }
    88  
    89  func (v filesystemAttachmentInfos) Swap(i, j int) {
    90  	v[i], v[j] = v[j], v[i]
    91  }
    92  
    93  func (v filesystemAttachmentInfos) Less(i, j int) bool {
    94  	switch compareStrings(v[i].MachineId, v[j].MachineId) {
    95  	case -1:
    96  		return true
    97  	case 1:
    98  		return false
    99  	}
   100  
   101  	switch compareSlashSeparated(v[i].UnitId, v[j].UnitId) {
   102  	case -1:
   103  		return true
   104  	case 1:
   105  		return false
   106  	}
   107  
   108  	switch compareSlashSeparated(v[i].Storage, v[j].Storage) {
   109  	case -1:
   110  		return true
   111  	case 1:
   112  		return false
   113  	}
   114  
   115  	return v[i].FilesystemId < v[j].FilesystemId
   116  }