github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/worker/uniter/runner/export_test.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package runner 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names" 9 "github.com/juju/utils/proxy" 10 "gopkg.in/juju/charm.v5" 11 12 "github.com/juju/juju/api/uniter" 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/worker/leadership" 15 "github.com/juju/juju/worker/uniter/runner/jujuc" 16 ) 17 18 var ( 19 MergeWindowsEnvironment = mergeWindowsEnvironment 20 SearchHook = searchHook 21 HookCommand = hookCommand 22 LookPath = lookPath 23 ValidatePortRange = validatePortRange 24 TryOpenPorts = tryOpenPorts 25 TryClosePorts = tryClosePorts 26 LockTimeout = lockTimeout 27 ) 28 29 func RunnerPaths(rnr Runner) Paths { 30 return rnr.(*runner).paths 31 } 32 33 type LeadershipContextFunc func(LeadershipSettingsAccessor, leadership.Tracker) LeadershipContext 34 35 func PatchNewLeadershipContext(f LeadershipContextFunc) func() { 36 var old LeadershipContextFunc 37 old, newLeadershipContext = newLeadershipContext, f 38 return func() { newLeadershipContext = old } 39 } 40 41 func UpdateCachedSettings(f0 Factory, relId int, unitName string, settings params.Settings) { 42 f := f0.(*factory) 43 members := f.relationCaches[relId].members 44 if members[unitName] == nil { 45 members[unitName] = params.Settings{} 46 } 47 for key, value := range settings { 48 members[unitName][key] = value 49 } 50 } 51 52 func CachedSettings(f0 Factory, relId int, unitName string) (params.Settings, bool) { 53 f := f0.(*factory) 54 settings, found := f.relationCaches[relId].members[unitName] 55 return settings, found 56 } 57 58 // PatchMeterStatus changes the meter status of the context. 59 func (ctx *HookContext) PatchMeterStatus(code, info string) func() { 60 oldMeterStatus := ctx.meterStatus 61 ctx.meterStatus = &meterStatus{ 62 code: code, 63 info: info, 64 } 65 return func() { 66 ctx.meterStatus = oldMeterStatus 67 } 68 } 69 70 func ContextEnvInfo(ctx Context) (name, uuid string) { 71 hctx := ctx.(*HookContext) 72 return hctx.envName, hctx.uuid 73 } 74 75 func ContextMachineTag(ctx Context) names.MachineTag { 76 hctx := ctx.(*HookContext) 77 return hctx.assignedMachineTag 78 } 79 80 func GetStubActionContext(in map[string]interface{}) *HookContext { 81 return &HookContext{ 82 actionData: &ActionData{ 83 ResultsMap: in, 84 }, 85 } 86 } 87 88 func PatchCachedStatus(ctx Context, status, info string, data map[string]interface{}) func() { 89 hctx := ctx.(*HookContext) 90 oldStatus := hctx.status 91 hctx.status = &jujuc.StatusInfo{ 92 Status: status, 93 Info: info, 94 Data: data, 95 } 96 return func() { 97 hctx.status = oldStatus 98 } 99 } 100 101 // PatchMetricsReader patches the metrics reader used by the context with a new 102 // object. 103 func PatchMetricsReader(ctx Context, reader MetricsReader) func() { 104 hctx := ctx.(*HookContext) 105 oldReader := hctx.metricsReader 106 hctx.metricsReader = reader 107 return func() { 108 hctx.metricsReader = oldReader 109 } 110 } 111 112 func NewHookContext( 113 unit *uniter.Unit, 114 state *uniter.State, 115 id, 116 uuid, 117 envName string, 118 relationId int, 119 remoteUnitName string, 120 relations map[int]*ContextRelation, 121 apiAddrs []string, 122 serviceOwner names.UserTag, 123 proxySettings proxy.Settings, 124 canAddMetrics bool, 125 metrics *charm.Metrics, 126 actionData *ActionData, 127 assignedMachineTag names.MachineTag, 128 paths Paths, 129 ) (*HookContext, error) { 130 ctx := &HookContext{ 131 unit: unit, 132 state: state, 133 id: id, 134 uuid: uuid, 135 envName: envName, 136 unitName: unit.Name(), 137 relationId: relationId, 138 remoteUnitName: remoteUnitName, 139 relations: relations, 140 apiAddrs: apiAddrs, 141 serviceOwner: serviceOwner, 142 proxySettings: proxySettings, 143 metricsRecorder: nil, 144 definedMetrics: metrics, 145 metricsSender: unit, 146 actionData: actionData, 147 pendingPorts: make(map[PortRange]PortRangeInfo), 148 assignedMachineTag: assignedMachineTag, 149 } 150 if canAddMetrics { 151 charmURL, err := unit.CharmURL() 152 if err != nil { 153 return nil, err 154 } 155 ctx.metricsRecorder, err = NewJSONMetricsRecorder(paths.GetMetricsSpoolDir(), charmURL.String()) 156 if err != nil { 157 return nil, err 158 } 159 ctx.metricsReader, err = NewJSONMetricsReader(paths.GetMetricsSpoolDir()) 160 if err != nil { 161 return nil, err 162 } 163 } 164 // Get and cache the addresses. 165 var err error 166 ctx.publicAddress, err = unit.PublicAddress() 167 if err != nil && !params.IsCodeNoAddressSet(err) { 168 return nil, err 169 } 170 ctx.privateAddress, err = unit.PrivateAddress() 171 if err != nil && !params.IsCodeNoAddressSet(err) { 172 return nil, err 173 } 174 ctx.availabilityzone, err = unit.AvailabilityZone() 175 if err != nil { 176 return nil, err 177 } 178 ctx.machinePorts, err = state.AllMachinePorts(ctx.assignedMachineTag) 179 if err != nil { 180 return nil, errors.Trace(err) 181 } 182 183 statusCode, statusInfo, err := unit.MeterStatus() 184 if err != nil { 185 return nil, errors.Annotate(err, "could not retrieve meter status for unit") 186 } 187 ctx.meterStatus = &meterStatus{ 188 code: statusCode, 189 info: statusInfo, 190 } 191 return ctx, nil 192 } 193 194 // NewEnvironmentHookContext exists purely to set the fields used in rs. 195 // The returned value is not otherwise valid. 196 func NewEnvironmentHookContext( 197 id, envUUID, envName, unitName, meterCode, meterInfo, availZone string, 198 apiAddresses []string, proxySettings proxy.Settings, 199 machineTag names.MachineTag, 200 ) *HookContext { 201 return &HookContext{ 202 id: id, 203 unitName: unitName, 204 uuid: envUUID, 205 envName: envName, 206 apiAddrs: apiAddresses, 207 proxySettings: proxySettings, 208 meterStatus: &meterStatus{ 209 code: meterCode, 210 info: meterInfo, 211 }, 212 relationId: -1, 213 assignedMachineTag: machineTag, 214 availabilityzone: availZone, 215 } 216 } 217 218 // SetEnvironmentHookContextRelation exists purely to set the fields used in hookVars. 219 // It makes no assumptions about the validity of context. 220 func SetEnvironmentHookContextRelation( 221 context *HookContext, 222 relationId int, endpointName, remoteUnitName string, 223 ) { 224 context.relationId = relationId 225 context.remoteUnitName = remoteUnitName 226 context.relations = map[int]*ContextRelation{ 227 relationId: { 228 endpointName: endpointName, 229 relationId: relationId, 230 }, 231 } 232 } 233 234 func (ctx *HookContext) StorageAddConstraints() map[string][]params.StorageConstraints { 235 return ctx.storageAddConstraints 236 } 237 238 // PatchMetricsSender patches the metricsSender used by the context to use the provided function. 239 func PatchMetricsSender(ctx Context, send func(batches []params.MetricBatch) (map[string]error, error)) func() { 240 hctx := ctx.(*HookContext) 241 oldSender := hctx.metricsSender 242 hctx.metricsSender = &mockMetricsSender{send: send} 243 return func() { 244 hctx.metricsSender = oldSender 245 } 246 } 247 248 type mockMetricsSender struct { 249 send func(batches []params.MetricBatch) (map[string]error, error) 250 } 251 252 func (m mockMetricsSender) AddMetricBatches(batches []params.MetricBatch) (map[string]error, error) { 253 return m.send(batches) 254 }