github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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  
    14  	"github.com/juju/juju/cmd/output"
    15  )
    16  
    17  // formatFilesystemListTabular writes a tabular summary of filesystem instances.
    18  func formatFilesystemListTabular(writer io.Writer, infos map[string]FilesystemInfo) error {
    19  	tw := output.TabWriter(writer)
    20  
    21  	print := func(values ...string) {
    22  		fmt.Fprintln(tw, strings.Join(values, "\t"))
    23  	}
    24  
    25  	haveMachines := false
    26  	filesystemAttachmentInfos := make(filesystemAttachmentInfos, 0, len(infos))
    27  	for filesystemId, info := range infos {
    28  		filesystemAttachmentInfo := filesystemAttachmentInfo{
    29  			FilesystemId:   filesystemId,
    30  			FilesystemInfo: info,
    31  		}
    32  		if info.Attachments == nil {
    33  			filesystemAttachmentInfos = append(filesystemAttachmentInfos, filesystemAttachmentInfo)
    34  			continue
    35  		}
    36  		// Each unit attachment must have a corresponding filesystem
    37  		// attachment. Enumerate each of the filesystem attachments,
    38  		// and locate the corresponding unit attachment if any.
    39  		// Each filesystem attachment has at most one corresponding
    40  		// unit attachment.
    41  		for machineId, machineInfo := range info.Attachments.Machines {
    42  			filesystemAttachmentInfo := filesystemAttachmentInfo
    43  			filesystemAttachmentInfo.MachineId = machineId
    44  			filesystemAttachmentInfo.FilesystemAttachment = machineInfo
    45  			for unitId, unitInfo := range info.Attachments.Units {
    46  				if unitInfo.MachineId == machineId {
    47  					filesystemAttachmentInfo.UnitId = unitId
    48  					filesystemAttachmentInfo.UnitStorageAttachment = unitInfo
    49  					break
    50  				}
    51  			}
    52  			haveMachines = true
    53  			filesystemAttachmentInfos = append(filesystemAttachmentInfos, filesystemAttachmentInfo)
    54  		}
    55  
    56  		for hostId, containerInfo := range info.Attachments.Containers {
    57  			filesystemAttachmentInfo := filesystemAttachmentInfo
    58  			filesystemAttachmentInfo.FilesystemAttachment = containerInfo
    59  			for unitId, unitInfo := range info.Attachments.Units {
    60  				if hostId == unitId {
    61  					filesystemAttachmentInfo.UnitId = unitId
    62  					filesystemAttachmentInfo.UnitStorageAttachment = unitInfo
    63  					break
    64  				}
    65  			}
    66  			filesystemAttachmentInfos = append(filesystemAttachmentInfos, filesystemAttachmentInfo)
    67  		}
    68  	}
    69  	sort.Sort(filesystemAttachmentInfos)
    70  
    71  	if haveMachines {
    72  		print("Machine", "Unit", "Storage id", "Id", "Volume", "Provider id", "Mountpoint", "Size", "State", "Message")
    73  	} else {
    74  		print("Unit", "Storage id", "Id", "Provider id", "Mountpoint", "Size", "State", "Message")
    75  	}
    76  
    77  	for _, info := range filesystemAttachmentInfos {
    78  		var size string
    79  		if info.Size > 0 {
    80  			size = humanize.IBytes(info.Size * humanize.MiByte)
    81  		}
    82  		if haveMachines {
    83  			print(
    84  				info.MachineId, info.UnitId, info.Storage,
    85  				info.FilesystemId, info.Volume, info.ProviderFilesystemId,
    86  				info.MountPoint, size,
    87  				string(info.Status.Current), info.Status.Message,
    88  			)
    89  		} else {
    90  			print(
    91  				info.UnitId, info.Storage,
    92  				info.FilesystemId, info.ProviderFilesystemId,
    93  				info.MountPoint, size,
    94  				string(info.Status.Current), info.Status.Message,
    95  			)
    96  		}
    97  	}
    98  
    99  	return tw.Flush()
   100  }
   101  
   102  type filesystemAttachmentInfo struct {
   103  	FilesystemId string
   104  	FilesystemInfo
   105  
   106  	MachineId string
   107  	FilesystemAttachment
   108  
   109  	UnitId string
   110  	UnitStorageAttachment
   111  }
   112  
   113  type filesystemAttachmentInfos []filesystemAttachmentInfo
   114  
   115  func (v filesystemAttachmentInfos) Len() int {
   116  	return len(v)
   117  }
   118  
   119  func (v filesystemAttachmentInfos) Swap(i, j int) {
   120  	v[i], v[j] = v[j], v[i]
   121  }
   122  
   123  func (v filesystemAttachmentInfos) Less(i, j int) bool {
   124  	switch compareStrings(v[i].MachineId, v[j].MachineId) {
   125  	case -1:
   126  		return true
   127  	case 1:
   128  		return false
   129  	}
   130  
   131  	switch compareSlashSeparated(v[i].UnitId, v[j].UnitId) {
   132  	case -1:
   133  		return true
   134  	case 1:
   135  		return false
   136  	}
   137  
   138  	switch compareSlashSeparated(v[i].Storage, v[j].Storage) {
   139  	case -1:
   140  		return true
   141  	case 1:
   142  		return false
   143  	}
   144  
   145  	return v[i].FilesystemId < v[j].FilesystemId
   146  }