github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/storage/filesystem.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 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "github.com/juju/names" 10 11 "github.com/juju/juju/apiserver/params" 12 jujucmd "github.com/juju/juju/cmd" 13 "github.com/juju/juju/cmd/envcmd" 14 "github.com/juju/juju/cmd/juju/common" 15 ) 16 17 const filesystemCmdDoc = ` 18 "juju storage filesystem" is used to manage storage filesystems in 19 the Juju environment. 20 ` 21 22 const filesystemCmdPurpose = "manage storage filesystems" 23 24 // NewFilesystemSuperCommand creates the storage filesystem super subcommand and 25 // registers the subcommands that it supports. 26 func NewFilesystemSuperCommand() cmd.Command { 27 supercmd := jujucmd.NewSubSuperCommand(cmd.SuperCommandParams{ 28 Name: "filesystem", 29 Doc: filesystemCmdDoc, 30 UsagePrefix: "juju storage", 31 Purpose: filesystemCmdPurpose, 32 }) 33 supercmd.Register(envcmd.Wrap(&FilesystemListCommand{})) 34 return supercmd 35 } 36 37 // FilesystemCommandBase is a helper base structure for filesystem commands. 38 type FilesystemCommandBase struct { 39 StorageCommandBase 40 } 41 42 // FilesystemInfo defines the serialization behaviour for storage filesystem. 43 type FilesystemInfo struct { 44 // from params.Filesystem. This is provider-supplied unique filesystem id. 45 ProviderFilesystemId string `yaml:"provider-id,omitempty" json:"provider-id,omitempty"` 46 47 // Volume is the ID of the volume that the filesystem is backed by, if any. 48 Volume string 49 50 // Storage is the ID of the storage instance that the filesystem is 51 // assigned to, if any. 52 Storage string 53 54 // Attachments is the set of entities attached to the filesystem. 55 Attachments *FilesystemAttachments 56 57 // from params.FilesystemInfo 58 Size uint64 `yaml:"size" json:"size"` 59 60 // from params.FilesystemInfo. 61 Status EntityStatus `yaml:"status,omitempty" json:"status,omitempty"` 62 } 63 64 type FilesystemAttachments struct { 65 Machines map[string]MachineFilesystemAttachment `yaml:"machines,omitempty" json:"machines,omitempty"` 66 Units map[string]UnitStorageAttachment `yaml:"units,omitempty" json:"units,omitempty"` 67 } 68 69 type MachineFilesystemAttachment struct { 70 MountPoint string `yaml:"mount-point" json:"mount-point"` 71 ReadOnly bool `yaml:"read-only" json:"read-only"` 72 } 73 74 // convertToFilesystemInfo returns a map of filesystem IDs to filesystem info. 75 func convertToFilesystemInfo(all []params.FilesystemDetailsResult) (map[string]FilesystemInfo, error) { 76 result := make(map[string]FilesystemInfo) 77 for _, one := range all { 78 filesystemTag, info, err := createFilesystemInfo(one) 79 if err != nil { 80 return nil, errors.Trace(err) 81 } 82 result[filesystemTag.Id()] = info 83 } 84 return result, nil 85 } 86 87 func createFilesystemInfo(result params.FilesystemDetailsResult) (names.FilesystemTag, FilesystemInfo, error) { 88 details := result.Result 89 90 filesystemTag, err := names.ParseFilesystemTag(details.FilesystemTag) 91 if err != nil { 92 return names.FilesystemTag{}, FilesystemInfo{}, errors.Trace(err) 93 } 94 95 var info FilesystemInfo 96 info.ProviderFilesystemId = details.Info.FilesystemId 97 info.Size = details.Info.Size 98 info.Status = EntityStatus{ 99 details.Status.Status, 100 details.Status.Info, 101 // TODO(axw) we should support formatting as ISO time 102 common.FormatTime(details.Status.Since, false), 103 } 104 105 if details.VolumeTag != "" { 106 volumeId, err := idFromTag(details.VolumeTag) 107 if err != nil { 108 return names.FilesystemTag{}, FilesystemInfo{}, errors.Trace(err) 109 } 110 info.Volume = volumeId 111 } 112 113 if len(details.MachineAttachments) > 0 { 114 machineAttachments := make(map[string]MachineFilesystemAttachment) 115 for machineTag, attachment := range details.MachineAttachments { 116 machineId, err := idFromTag(machineTag) 117 if err != nil { 118 return names.FilesystemTag{}, FilesystemInfo{}, errors.Trace(err) 119 } 120 machineAttachments[machineId] = MachineFilesystemAttachment{ 121 attachment.MountPoint, 122 attachment.ReadOnly, 123 } 124 } 125 info.Attachments = &FilesystemAttachments{ 126 Machines: machineAttachments, 127 } 128 } 129 130 if details.Storage != nil { 131 storageTag, storageInfo, err := createStorageInfo(*details.Storage) 132 if err != nil { 133 return names.FilesystemTag{}, FilesystemInfo{}, errors.Trace(err) 134 } 135 info.Storage = storageTag.Id() 136 if storageInfo.Attachments != nil { 137 info.Attachments.Units = storageInfo.Attachments.Units 138 } 139 } 140 141 return filesystemTag, info, nil 142 }