github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/migrationmaster/migrationmaster.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/names" 9 10 "github.com/juju/juju/apiserver/common" 11 "github.com/juju/juju/apiserver/params" 12 coremigration "github.com/juju/juju/core/migration" 13 "github.com/juju/juju/migration" 14 "github.com/juju/juju/state" 15 ) 16 17 func init() { 18 common.RegisterStandardFacade("MigrationMaster", 1, NewAPI) 19 } 20 21 // API implements the API required for the model migration 22 // master worker. 23 type API struct { 24 backend Backend 25 authorizer common.Authorizer 26 resources *common.Resources 27 } 28 29 // NewAPI creates a new API server endpoint for the model migration 30 // master worker. 31 func NewAPI( 32 st *state.State, 33 resources *common.Resources, 34 authorizer common.Authorizer, 35 ) (*API, error) { 36 if !authorizer.AuthModelManager() { 37 return nil, common.ErrPerm 38 } 39 return &API{ 40 backend: getBackend(st), 41 authorizer: authorizer, 42 resources: resources, 43 }, nil 44 } 45 46 // Watch starts watching for an active migration for the model 47 // associated with the API connection. The returned id should be used 48 // with the NotifyWatcher facade to receive events. 49 func (api *API) Watch() (params.NotifyWatchResult, error) { 50 w, err := api.backend.WatchForModelMigration() 51 if err != nil { 52 return params.NotifyWatchResult{}, errors.Trace(err) 53 } 54 return params.NotifyWatchResult{ 55 NotifyWatcherId: api.resources.Register(w), 56 }, nil 57 } 58 59 // GetMigrationStatus returns the details and progress of the latest 60 // model migration. 61 func (api *API) GetMigrationStatus() (params.FullMigrationStatus, error) { 62 empty := params.FullMigrationStatus{} 63 64 mig, err := api.backend.GetModelMigration() 65 if err != nil { 66 return empty, errors.Annotate(err, "retrieving model migration") 67 } 68 69 target, err := mig.TargetInfo() 70 if err != nil { 71 return empty, errors.Annotate(err, "retrieving target info") 72 } 73 74 attempt, err := mig.Attempt() 75 if err != nil { 76 return empty, errors.Annotate(err, "retrieving attempt") 77 } 78 79 phase, err := mig.Phase() 80 if err != nil { 81 return empty, errors.Annotate(err, "retrieving phase") 82 } 83 84 return params.FullMigrationStatus{ 85 Spec: params.ModelMigrationSpec{ 86 ModelTag: names.NewModelTag(mig.ModelUUID()).String(), 87 TargetInfo: params.ModelMigrationTargetInfo{ 88 ControllerTag: target.ControllerTag.String(), 89 Addrs: target.Addrs, 90 CACert: target.CACert, 91 AuthTag: target.AuthTag.String(), 92 Password: target.Password, 93 }, 94 }, 95 Attempt: attempt, 96 Phase: phase.String(), 97 }, nil 98 } 99 100 // SetPhase sets the phase of the active model migration. The provided 101 // phase must be a valid phase value, for example QUIESCE" or 102 // "ABORT". See the core/migration package for the complete list. 103 func (api *API) SetPhase(args params.SetMigrationPhaseArgs) error { 104 mig, err := api.backend.GetModelMigration() 105 if err != nil { 106 return errors.Annotate(err, "could not get migration") 107 } 108 109 phase, ok := coremigration.ParsePhase(args.Phase) 110 if !ok { 111 return errors.Errorf("invalid phase: %q", args.Phase) 112 } 113 114 err = mig.SetPhase(phase) 115 return errors.Annotate(err, "failed to set phase") 116 } 117 118 var exportModel = migration.ExportModel 119 120 // Export serializes the model associated with the API connection. 121 func (api *API) Export() (params.SerializedModel, error) { 122 var serialized params.SerializedModel 123 124 bytes, err := exportModel(api.backend) 125 if err != nil { 126 return serialized, err 127 } 128 129 serialized.Bytes = bytes 130 return serialized, nil 131 }