github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/upgradesteps/manifold.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package upgradesteps 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/agent" 11 "github.com/juju/juju/api" 12 apiagent "github.com/juju/juju/api/agent" 13 apimachiner "github.com/juju/juju/api/machiner" 14 "github.com/juju/juju/state" 15 "github.com/juju/juju/worker" 16 "github.com/juju/juju/worker/dependency" 17 "github.com/juju/juju/worker/gate" 18 ) 19 20 // ManifoldConfig defines the names of the manifolds on which a 21 // Manifold will depend. 22 type ManifoldConfig struct { 23 AgentName string 24 APICallerName string 25 UpgradeStepsGateName string 26 OpenStateForUpgrade func() (*state.State, error) 27 PreUpgradeSteps func(*state.State, agent.Config, bool, bool) error 28 } 29 30 // Manifold returns a dependency manifold that runs an upgrader 31 // worker, using the resource names defined in the supplied config. 32 func Manifold(config ManifoldConfig) dependency.Manifold { 33 return dependency.Manifold{ 34 Inputs: []string{ 35 config.AgentName, 36 config.APICallerName, 37 config.UpgradeStepsGateName, 38 }, 39 Start: func(context dependency.Context) (worker.Worker, error) { 40 // Sanity checks 41 if config.OpenStateForUpgrade == nil { 42 return nil, errors.New("missing OpenStateForUpgrade in config") 43 } 44 if config.PreUpgradeSteps == nil { 45 return nil, errors.New("missing PreUpgradeSteps in config") 46 } 47 48 // Get machine agent. 49 var agent agent.Agent 50 if err := context.Get(config.AgentName, &agent); err != nil { 51 return nil, err 52 } 53 54 // Grab the tag and ensure that it's for a machine. 55 tag, ok := agent.CurrentConfig().Tag().(names.MachineTag) 56 if !ok { 57 return nil, errors.New("agent's tag is not a machine tag") 58 } 59 60 // Get API connection. 61 // TODO(fwereade): can we make the worker use an 62 // APICaller instead? should be able to depend on 63 // the Engine to abort us when conn is closed... 64 var apiConn api.Connection 65 if err := context.Get(config.APICallerName, &apiConn); err != nil { 66 return nil, err 67 } 68 69 // Get the machine agent's jobs. 70 // TODO(fwereade): use appropriate facade! 71 agentFacade := apiagent.NewState(apiConn) 72 entity, err := agentFacade.Entity(tag) 73 if err != nil { 74 return nil, err 75 } 76 jobs := entity.Jobs() 77 78 // Get machine instance for setting status on. 79 // TODO(fwereade): use appropriate facade! 80 machinerFacade := apimachiner.NewState(apiConn) 81 machine, err := machinerFacade.Machine(tag) 82 if err != nil { 83 return nil, err 84 } 85 86 // Get upgradesteps completed lock. 87 var upgradeStepsLock gate.Lock 88 if err := context.Get(config.UpgradeStepsGateName, &upgradeStepsLock); err != nil { 89 return nil, err 90 } 91 92 return NewWorker( 93 upgradeStepsLock, 94 agent, 95 apiConn, 96 jobs, 97 config.OpenStateForUpgrade, 98 config.PreUpgradeSteps, 99 machine, 100 ) 101 }, 102 } 103 }