1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
13
"github.com/dustin/go-humanize"
14
"github.com/juju/errors"
17
// formatVolumeListTabular returns a tabular summary of volume instances.
18
func formatVolumeListTabular(value interface{}) ([]byte, error) {
19
infos, ok := value.(map[string]VolumeInfo)
21
return nil, errors.Errorf("expected value of type %T, got %T", infos, value)
23
return formatVolumeListTabularTyped(infos), nil
26
func formatVolumeListTabularTyped(infos map[string]VolumeInfo) []byte {
29
// To format things into columns.
36
tw := tabwriter.NewWriter(&out, minwidth, tabwidth, padding, padchar, flags)
38
print := func(values ...string) {
39
fmt.Fprintln(tw, strings.Join(values, "\t"))
41
print("MACHINE", "UNIT", "STORAGE", "ID", "PROVIDER-ID", "DEVICE", "SIZE", "STATE", "MESSAGE")
43
volumeAttachmentInfos := make(volumeAttachmentInfos, 0, len(infos))
44
for volumeId, info := range infos {
45
volumeAttachmentInfo := volumeAttachmentInfo{
49
if info.Attachments == nil {
50
volumeAttachmentInfos = append(volumeAttachmentInfos, volumeAttachmentInfo)
53
// Each unit attachment must have a corresponding volume
54
// attachment. Enumerate each of the volume attachments,
55
// and locate the corresponding unit attachment if any.
56
// Each volume attachment has at most one corresponding
58
for machineId, machineInfo := range info.Attachments.Machines {
59
volumeAttachmentInfo := volumeAttachmentInfo
60
volumeAttachmentInfo.MachineId = machineId
61
volumeAttachmentInfo.MachineVolumeAttachment = machineInfo
62
for unitId, unitInfo := range info.Attachments.Units {
63
if unitInfo.MachineId == machineId {
64
volumeAttachmentInfo.UnitId = unitId
65
volumeAttachmentInfo.UnitStorageAttachment = unitInfo
69
volumeAttachmentInfos = append(volumeAttachmentInfos, volumeAttachmentInfo)
72
sort.Sort(volumeAttachmentInfos)
74
for _, info := range volumeAttachmentInfos {
77
size = humanize.IBytes(info.Size * humanize.MiByte)
80
info.MachineId, info.UnitId, info.Storage,
81
info.VolumeId, info.ProviderVolumeId,
82
info.DeviceName, size,
83
string(info.Status.Current), info.Status.Message,
91
type volumeAttachmentInfo struct {
96
MachineVolumeAttachment
102
type volumeAttachmentInfos []volumeAttachmentInfo
104
func (v volumeAttachmentInfos) Len() int {
108
func (v volumeAttachmentInfos) Swap(i, j int) {
109
v[i], v[j] = v[j], v[i]
112
func (v volumeAttachmentInfos) Less(i, j int) bool {
113
switch compareStrings(v[i].MachineId, v[j].MachineId) {
120
switch compareSlashSeparated(v[i].UnitId, v[j].UnitId) {
127
switch compareSlashSeparated(v[i].Storage, v[j].Storage) {
134
return v[i].VolumeId < v[j].VolumeId