github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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/instance"
    11  	"github.com/juju/juju/state"
    12  	"github.com/juju/juju/state/multiwatcher"
    13  	"github.com/juju/juju/status"
    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  	WantsVote() bool
    61  	HasVote() bool
    62  	Status() (status.StatusInfo, error)
    63  	ContainerType() instance.ContainerType
    64  	HardwareCharacteristics() (*instance.HardwareCharacteristics, error)
    65  	Life() state.Life
    66  	ForceDestroy() error
    67  	Destroy() error
    68  	AgentPresence() (bool, error)
    69  }
    70  
    71  func DestroyMachines(st origStateInterface, force bool, ids ...string) error {
    72  	return destroyMachines(&stateShim{st}, force, ids...)
    73  }
    74  
    75  func destroyMachines(st stateInterface, force bool, ids ...string) error {
    76  	var errs []string
    77  	for _, id := range ids {
    78  		machine, err := st.Machine(id)
    79  		switch {
    80  		case errors.IsNotFound(err):
    81  			err = errors.Errorf("machine %s does not exist", id)
    82  		case err != nil:
    83  		case force:
    84  			err = machine.ForceDestroy()
    85  		case machine.Life() != state.Alive:
    86  			continue
    87  		default:
    88  			err = machine.Destroy()
    89  		}
    90  		if err != nil {
    91  			errs = append(errs, err.Error())
    92  		}
    93  	}
    94  	return DestroyErr("machines", ids, errs)
    95  }
    96  
    97  // ModelMachineInfo returns information about machine hardware for
    98  // alive top level machines (not containers).
    99  func ModelMachineInfo(st ModelManagerBackend) (machineInfo []params.ModelMachineInfo, _ error) {
   100  	machines, err := st.AllMachines()
   101  	if err != nil {
   102  		return nil, errors.Trace(err)
   103  	}
   104  	for _, m := range machines {
   105  		if m.Life() != state.Alive {
   106  			continue
   107  		}
   108  		var status string
   109  		statusInfo, err := MachineStatus(m)
   110  		if err == nil {
   111  			status = string(statusInfo.Status)
   112  		} else {
   113  			status = err.Error()
   114  		}
   115  		mInfo := params.ModelMachineInfo{
   116  			Id:        m.Id(),
   117  			HasVote:   m.HasVote(),
   118  			WantsVote: m.WantsVote(),
   119  			Status:    status,
   120  		}
   121  		instId, err := m.InstanceId()
   122  		switch {
   123  		case err == nil:
   124  			mInfo.InstanceId = string(instId)
   125  		case errors.IsNotProvisioned(err):
   126  			// ok, but no instance ID to get.
   127  		default:
   128  			return nil, errors.Trace(err)
   129  		}
   130  		if m.ContainerType() != "" && m.ContainerType() != instance.NONE {
   131  			machineInfo = append(machineInfo, mInfo)
   132  			continue
   133  		}
   134  		// Only include cores for physical machines.
   135  		hw, err := m.HardwareCharacteristics()
   136  		if err != nil && !errors.IsNotFound(err) {
   137  			return nil, errors.Trace(err)
   138  		}
   139  		if hw != nil && hw.String() != "" {
   140  			hwParams := &params.MachineHardware{
   141  				Cores:            hw.CpuCores,
   142  				Arch:             hw.Arch,
   143  				Mem:              hw.Mem,
   144  				RootDisk:         hw.RootDisk,
   145  				CpuPower:         hw.CpuPower,
   146  				Tags:             hw.Tags,
   147  				AvailabilityZone: hw.AvailabilityZone,
   148  			}
   149  			mInfo.Hardware = hwParams
   150  		}
   151  		machineInfo = append(machineInfo, mInfo)
   152  	}
   153  	return machineInfo, nil
   154  }