github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/state/api/provisioner/provisioner.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package provisioner 5 6 import ( 7 "fmt" 8 9 "github.com/juju/names" 10 11 "github.com/juju/juju/state/api/base" 12 "github.com/juju/juju/state/api/common" 13 "github.com/juju/juju/state/api/params" 14 "github.com/juju/juju/state/api/watcher" 15 "github.com/juju/juju/tools" 16 ) 17 18 // State provides access to the Machiner API facade. 19 type State struct { 20 *common.EnvironWatcher 21 *common.APIAddresser 22 23 caller base.Caller 24 } 25 26 const provisionerFacade = "Provisioner" 27 28 // NewState creates a new client-side Machiner facade. 29 func NewState(caller base.Caller) *State { 30 return &State{ 31 EnvironWatcher: common.NewEnvironWatcher(provisionerFacade, caller), 32 APIAddresser: common.NewAPIAddresser(provisionerFacade, caller), 33 caller: caller} 34 } 35 36 func (st *State) call(method string, params, result interface{}) error { 37 return st.caller.Call(provisionerFacade, "", method, params, result) 38 } 39 40 // machineLife requests the lifecycle of the given machine from the server. 41 func (st *State) machineLife(tag string) (params.Life, error) { 42 return common.Life(st.caller, provisionerFacade, tag) 43 } 44 45 // Machine provides access to methods of a state.Machine through the facade. 46 func (st *State) Machine(tag string) (*Machine, error) { 47 life, err := st.machineLife(tag) 48 if err != nil { 49 return nil, err 50 } 51 return &Machine{ 52 tag: tag, 53 life: life, 54 st: st, 55 }, nil 56 } 57 58 // WatchEnvironMachines returns a StringsWatcher that notifies of 59 // changes to the lifecycles of the machines (but not containers) in 60 // the current environment. 61 func (st *State) WatchEnvironMachines() (watcher.StringsWatcher, error) { 62 var result params.StringsWatchResult 63 err := st.call("WatchEnvironMachines", nil, &result) 64 if err != nil { 65 return nil, err 66 } 67 if err := result.Error; err != nil { 68 return nil, result.Error 69 } 70 w := watcher.NewStringsWatcher(st.caller, result) 71 return w, nil 72 } 73 74 func (st *State) WatchMachineErrorRetry() (watcher.NotifyWatcher, error) { 75 var result params.NotifyWatchResult 76 err := st.call("WatchMachineErrorRetry", nil, &result) 77 if err != nil { 78 return nil, err 79 } 80 if err := result.Error; err != nil { 81 return nil, result.Error 82 } 83 w := watcher.NewNotifyWatcher(st.caller, result) 84 return w, nil 85 } 86 87 // StateAddresses returns the list of addresses used to connect to the state. 88 func (st *State) StateAddresses() ([]string, error) { 89 var result params.StringsResult 90 err := st.call("StateAddresses", nil, &result) 91 if err != nil { 92 return nil, err 93 } 94 return result.Result, nil 95 } 96 97 // Tools returns the agent tools for the given entity. 98 func (st *State) Tools(tag string) (*tools.Tools, error) { 99 var results params.ToolsResults 100 args := params.Entities{ 101 Entities: []params.Entity{{Tag: tag}}, 102 } 103 err := st.call("Tools", args, &results) 104 if err != nil { 105 // TODO: Not directly tested 106 return nil, err 107 } 108 if len(results.Results) != 1 { 109 // TODO: Not directly tested 110 return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results)) 111 } 112 result := results.Results[0] 113 if err := result.Error; err != nil { 114 return nil, err 115 } 116 return result.Tools, nil 117 } 118 119 // ContainerManagerConfig returns information from the environment config that is 120 // needed for configuring the container manager. 121 func (st *State) ContainerManagerConfig(args params.ContainerManagerConfigParams) (result params.ContainerManagerConfig, err error) { 122 err = st.call("ContainerManagerConfig", args, &result) 123 return result, err 124 } 125 126 // ContainerConfig returns information from the environment config that is 127 // needed for container cloud-init. 128 func (st *State) ContainerConfig() (result params.ContainerConfig, err error) { 129 err = st.call("ContainerConfig", nil, &result) 130 return result, err 131 } 132 133 // MachinesWithTransientErrors returns a slice of machines and corresponding status information 134 // for those machines which have transient provisioning errors. 135 func (st *State) MachinesWithTransientErrors() ([]*Machine, []params.StatusResult, error) { 136 var results params.StatusResults 137 err := st.call("MachinesWithTransientErrors", nil, &results) 138 if err != nil { 139 return nil, nil, err 140 } 141 machines := make([]*Machine, len(results.Results)) 142 for i, status := range results.Results { 143 if status.Error != nil { 144 continue 145 } 146 machines[i] = &Machine{ 147 tag: names.MachineTag(status.Id), 148 life: status.Life, 149 st: st, 150 } 151 } 152 return machines, results.Results, nil 153 }