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  }