github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/machine.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "github.com/juju/errors" 8 9 "github.com/juju/juju/apiserver/params" 10 "github.com/juju/juju/core/instance" 11 "github.com/juju/juju/core/status" 12 "github.com/juju/juju/state" 13 "github.com/juju/juju/state/multiwatcher" 14 ) 15 16 // StateJobs translates a slice of multiwatcher jobs to their equivalents in state. 17 func StateJobs(jobs []multiwatcher.MachineJob) ([]state.MachineJob, error) { 18 newJobs := make([]state.MachineJob, len(jobs)) 19 for i, job := range jobs { 20 newJob, err := machineJobFromParams(job) 21 if err != nil { 22 return nil, err 23 } 24 newJobs[i] = newJob 25 } 26 return newJobs, nil 27 } 28 29 // machineJobFromParams returns the job corresponding to multiwatcher.MachineJob. 30 func machineJobFromParams(job multiwatcher.MachineJob) (state.MachineJob, error) { 31 switch job { 32 case multiwatcher.JobHostUnits: 33 return state.JobHostUnits, nil 34 case multiwatcher.JobManageModel: 35 return state.JobManageModel, nil 36 default: 37 return -1, errors.Errorf("invalid machine job %q", job) 38 } 39 } 40 41 type origStateInterface interface { 42 Machine(string) (*state.Machine, error) 43 } 44 45 type stateInterface interface { 46 Machine(string) (Machine, error) 47 } 48 49 type stateShim struct { 50 origStateInterface 51 } 52 53 func (st *stateShim) Machine(id string) (Machine, error) { 54 return st.origStateInterface.Machine(id) 55 } 56 57 type Machine interface { 58 Id() string 59 InstanceId() (instance.Id, error) 60 InstanceNames() (instance.Id, string, error) 61 WantsVote() bool 62 HasVote() bool 63 Status() (status.StatusInfo, error) 64 ContainerType() instance.ContainerType 65 HardwareCharacteristics() (*instance.HardwareCharacteristics, error) 66 Life() state.Life 67 ForceDestroy() error 68 Destroy() error 69 AgentPresence() (bool, error) 70 IsManager() bool 71 } 72 73 func DestroyMachines(st origStateInterface, force bool, ids ...string) error { 74 return destroyMachines(&stateShim{st}, force, ids...) 75 } 76 77 func destroyMachines(st stateInterface, force bool, ids ...string) error { 78 var errs []error 79 for _, id := range ids { 80 machine, err := st.Machine(id) 81 switch { 82 case errors.IsNotFound(err): 83 err = errors.Errorf("machine %s does not exist", id) 84 case err != nil: 85 case force: 86 err = machine.ForceDestroy() 87 case machine.Life() != state.Alive: 88 continue 89 default: 90 err = machine.Destroy() 91 } 92 if err != nil { 93 errs = append(errs, err) 94 } 95 } 96 return DestroyErr("machines", ids, errs) 97 } 98 99 // ModelMachineInfo returns information about machine hardware for 100 // alive top level machines (not containers). 101 func ModelMachineInfo(st ModelManagerBackend) (machineInfo []params.ModelMachineInfo, _ error) { 102 machines, err := st.AllMachines() 103 if err != nil { 104 return nil, errors.Trace(err) 105 } 106 for _, m := range machines { 107 if m.Life() != state.Alive { 108 continue 109 } 110 var status string 111 // This is suboptimal as if there are many machines, 112 // we are making many calls into the DB for each machine. 113 statusInfo, err := m.Status() 114 if err == nil { 115 status = string(statusInfo.Status) 116 } else { 117 status = err.Error() 118 } 119 mInfo := params.ModelMachineInfo{ 120 Id: m.Id(), 121 HasVote: m.HasVote(), 122 WantsVote: m.WantsVote(), 123 Status: status, 124 Message: statusInfo.Message, 125 } 126 instId, displayName, err := m.InstanceNames() 127 switch { 128 case err == nil: 129 mInfo.InstanceId = string(instId) 130 mInfo.DisplayName = displayName 131 case errors.IsNotProvisioned(err): 132 // ok, but no instance ID to get. 133 default: 134 return nil, errors.Trace(err) 135 } 136 if m.ContainerType() != "" && m.ContainerType() != instance.NONE { 137 machineInfo = append(machineInfo, mInfo) 138 continue 139 } 140 // Only include cores for physical machines. 141 hw, err := m.HardwareCharacteristics() 142 if err != nil && !errors.IsNotFound(err) { 143 return nil, errors.Trace(err) 144 } 145 if hw != nil && hw.String() != "" { 146 hwParams := ¶ms.MachineHardware{ 147 Cores: hw.CpuCores, 148 Arch: hw.Arch, 149 Mem: hw.Mem, 150 RootDisk: hw.RootDisk, 151 CpuPower: hw.CpuPower, 152 Tags: hw.Tags, 153 AvailabilityZone: hw.AvailabilityZone, 154 } 155 mInfo.Hardware = hwParams 156 } 157 machineInfo = append(machineInfo, mInfo) 158 } 159 return machineInfo, nil 160 }