github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/migrationmaster/manifold.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package migrationmaster 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/utils/clock" 9 10 "github.com/juju/juju/agent" 11 "github.com/juju/juju/api" 12 "github.com/juju/juju/api/base" 13 "github.com/juju/juju/migration" 14 "github.com/juju/juju/worker" 15 "github.com/juju/juju/worker/dependency" 16 "github.com/juju/juju/worker/fortress" 17 ) 18 19 // ManifoldConfig defines the names of the manifolds on which a 20 // Worker manifold will depend. 21 type ManifoldConfig struct { 22 AgentName string 23 APICallerName string 24 FortressName string 25 26 Clock clock.Clock 27 NewFacade func(base.APICaller) (Facade, error) 28 NewWorker func(Config) (worker.Worker, error) 29 } 30 31 // Validate is called by start to check for bad configuration. 32 func (config ManifoldConfig) Validate() error { 33 if config.AgentName == "" { 34 return errors.NotValidf("empty AgentName") 35 } 36 if config.APICallerName == "" { 37 return errors.NotValidf("empty APICallerName") 38 } 39 if config.FortressName == "" { 40 return errors.NotValidf("empty FortressName") 41 } 42 if config.NewFacade == nil { 43 return errors.NotValidf("nil NewFacade") 44 } 45 if config.NewWorker == nil { 46 return errors.NotValidf("nil NewWorker") 47 } 48 if config.Clock == nil { 49 return errors.NotValidf("nil Clock") 50 } 51 return nil 52 } 53 54 // start is a StartFunc for a Worker manifold. 55 func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) { 56 if err := config.Validate(); err != nil { 57 return nil, errors.Trace(err) 58 } 59 60 var agent agent.Agent 61 if err := context.Get(config.AgentName, &agent); err != nil { 62 return nil, errors.Trace(err) 63 } 64 var apiConn api.Connection 65 if err := context.Get(config.APICallerName, &apiConn); err != nil { 66 return nil, errors.Trace(err) 67 } 68 var guard fortress.Guard 69 if err := context.Get(config.FortressName, &guard); err != nil { 70 return nil, errors.Trace(err) 71 } 72 facade, err := config.NewFacade(apiConn) 73 if err != nil { 74 return nil, errors.Trace(err) 75 } 76 apiClient := apiConn.Client() 77 worker, err := config.NewWorker(Config{ 78 ModelUUID: agent.CurrentConfig().Model().Id(), 79 Facade: facade, 80 Guard: guard, 81 APIOpen: api.Open, 82 UploadBinaries: migration.UploadBinaries, 83 CharmDownloader: apiClient, 84 ToolsDownloader: apiClient, 85 Clock: config.Clock, 86 }) 87 if err != nil { 88 return nil, errors.Trace(err) 89 } 90 return worker, nil 91 } 92 93 func errorFilter(err error) error { 94 switch err { 95 case ErrMigrated: 96 // If the model has migrated, the migrationmaster should no 97 // longer be running. 98 return dependency.ErrUninstall 99 case ErrInactive: 100 // If the migration is no longer active, restart the 101 // migrationmaster immediately so it can wait for the next 102 // attempt. 103 return dependency.ErrBounce 104 default: 105 return err 106 } 107 } 108 109 // Manifold packages a Worker for use in a dependency.Engine. 110 func Manifold(config ManifoldConfig) dependency.Manifold { 111 return dependency.Manifold{ 112 Inputs: []string{ 113 config.AgentName, 114 config.APICallerName, 115 config.FortressName, 116 }, 117 Start: config.start, 118 Filter: errorFilter, 119 } 120 }