github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/agent/uniter/state.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package uniter
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"gopkg.in/juju/names.v2"
     9  
    10  	"github.com/juju/juju/state"
    11  )
    12  
    13  type storageAccess interface {
    14  	storageInterface
    15  	VolumeAccess() storageVolumeInterface
    16  	FilesystemAccess() storageFilesystemInterface
    17  }
    18  
    19  type storageInterface interface {
    20  	StorageInstance(names.StorageTag) (state.StorageInstance, error)
    21  	UnitStorageAttachments(names.UnitTag) ([]state.StorageAttachment, error)
    22  	RemoveStorageAttachment(names.StorageTag, names.UnitTag) error
    23  	DestroyUnitStorageAttachments(names.UnitTag) error
    24  	StorageAttachment(names.StorageTag, names.UnitTag) (state.StorageAttachment, error)
    25  	AddStorageForUnit(tag names.UnitTag, name string, cons state.StorageConstraints) ([]names.StorageTag, error)
    26  	WatchStorageAttachments(names.UnitTag) state.StringsWatcher
    27  	WatchStorageAttachment(names.StorageTag, names.UnitTag) state.NotifyWatcher
    28  }
    29  
    30  type storageVolumeInterface interface {
    31  	StorageInstanceVolume(names.StorageTag) (state.Volume, error)
    32  	BlockDevices(names.MachineTag) ([]state.BlockDeviceInfo, error)
    33  	WatchVolumeAttachment(names.Tag, names.VolumeTag) state.NotifyWatcher
    34  	WatchBlockDevices(names.MachineTag) state.NotifyWatcher
    35  	VolumeAttachment(names.Tag, names.VolumeTag) (state.VolumeAttachment, error)
    36  	VolumeAttachmentPlan(names.Tag, names.VolumeTag) (state.VolumeAttachmentPlan, error)
    37  }
    38  
    39  type storageFilesystemInterface interface {
    40  	StorageInstanceFilesystem(names.StorageTag) (state.Filesystem, error)
    41  	FilesystemAttachment(names.Tag, names.FilesystemTag) (state.FilesystemAttachment, error)
    42  	WatchFilesystemAttachment(names.Tag, names.FilesystemTag) state.NotifyWatcher
    43  }
    44  
    45  var getStorageState = func(st *state.State) (storageAccess, error) {
    46  	m, err := st.Model()
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	sb, err := state.NewStorageBackend(st)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	storageAccess := &storageShim{
    55  		storageInterface: sb,
    56  		va:               sb,
    57  		fa:               sb,
    58  	}
    59  	// CAAS models don't support volume storage yet.
    60  	if m.Type() == state.ModelTypeCAAS {
    61  		storageAccess.va = nil
    62  	}
    63  	return storageAccess, nil
    64  }
    65  
    66  type storageShim struct {
    67  	storageInterface
    68  	fa storageFilesystemInterface
    69  	va storageVolumeInterface
    70  }
    71  
    72  func (s *storageShim) VolumeAccess() storageVolumeInterface {
    73  	return s.va
    74  }
    75  
    76  func (s *storageShim) FilesystemAccess() storageFilesystemInterface {
    77  	return s.fa
    78  }
    79  
    80  type backend interface {
    81  	Unit(string) (Unit, error)
    82  }
    83  
    84  type Unit interface {
    85  	AssignedMachineId() (string, error)
    86  	ShouldBeAssigned() bool
    87  	StorageConstraints() (map[string]state.StorageConstraints, error)
    88  }
    89  
    90  type stateShim struct {
    91  	*state.State
    92  }
    93  
    94  func (s stateShim) Unit(name string) (Unit, error) {
    95  	return s.State.Unit(name)
    96  }
    97  
    98  // unitAssignedMachine returns the tag of the machine that the unit
    99  // is assigned to, or an error if the unit cannot be obtained or is
   100  // not assigned to a machine.
   101  func unitAssignedMachine(backend backend, tag names.UnitTag) (names.MachineTag, error) {
   102  	unit, err := backend.Unit(tag.Id())
   103  	if err != nil {
   104  		return names.MachineTag{}, errors.Trace(err)
   105  	}
   106  	mid, err := unit.AssignedMachineId()
   107  	if err != nil {
   108  		return names.MachineTag{}, errors.Trace(err)
   109  	}
   110  	return names.NewMachineTag(mid), nil
   111  }
   112  
   113  // unitStorageConstraints returns storage constraints for this unit,
   114  // or an error if the unit or its constraints cannot be obtained.
   115  func unitStorageConstraints(backend backend, u names.UnitTag) (map[string]state.StorageConstraints, error) {
   116  	unit, err := backend.Unit(u.Id())
   117  	if err != nil {
   118  		return nil, errors.Trace(err)
   119  	}
   120  
   121  	cons, err := unit.StorageConstraints()
   122  	if err != nil {
   123  		return nil, errors.Trace(err)
   124  	}
   125  	return cons, nil
   126  }