github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/apiserver/reboot/reboot.go (about) 1 // Copyright 2014 Cloudbase Solutions SRL 2 // Copyright 2014 Canonical Ltd. 3 // Licensed under the AGPLv3, see LICENCE file for details. 4 5 package reboot 6 7 import ( 8 "github.com/juju/errors" 9 "github.com/juju/loggo" 10 "github.com/juju/names" 11 12 "github.com/juju/juju/apiserver/common" 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/state" 15 "github.com/juju/juju/state/watcher" 16 ) 17 18 var logger = loggo.GetLogger("juju.apiserver.reboot") 19 20 // RebootAPI provides access to the Upgrader API facade. 21 type RebootAPI struct { 22 *common.RebootActionGetter 23 // The ability for a machine to reboot itself is not yet used. 24 // It will be used for situations like container support in Windows 25 // Where installing the hyper-v role will require a reboot. 26 *common.RebootRequester 27 *common.RebootFlagClearer 28 29 auth common.Authorizer 30 st *state.State 31 machine *state.Machine 32 resources *common.Resources 33 } 34 35 func init() { 36 common.RegisterStandardFacade("Reboot", 1, NewRebootAPI) 37 } 38 39 // NewRebootAPI creates a new server-side RebootAPI facade. 40 func NewRebootAPI(st *state.State, resources *common.Resources, auth common.Authorizer) (*RebootAPI, error) { 41 if !auth.AuthMachineAgent() { 42 return nil, common.ErrPerm 43 } 44 45 tag, ok := auth.GetAuthTag().(names.MachineTag) 46 if !ok { 47 return nil, errors.Errorf("Expected names.MachineTag, got %T", auth.GetAuthTag()) 48 } 49 machine, err := st.Machine(tag.Id()) 50 if err != nil { 51 return nil, errors.Trace(err) 52 } 53 54 canAccess := func() (common.AuthFunc, error) { 55 return auth.AuthOwner, nil 56 } 57 58 return &RebootAPI{ 59 RebootActionGetter: common.NewRebootActionGetter(st, canAccess), 60 RebootRequester: common.NewRebootRequester(st, canAccess), 61 RebootFlagClearer: common.NewRebootFlagClearer(st, canAccess), 62 st: st, 63 machine: machine, 64 resources: resources, 65 auth: auth, 66 }, nil 67 } 68 69 // WatchForRebootEvent starts a watcher to track if there is a new 70 // reboot request on the machines ID or any of its parents (in case we are a container). 71 func (r *RebootAPI) WatchForRebootEvent() (params.NotifyWatchResult, error) { 72 err := common.ErrPerm 73 var watch state.NotifyWatcher 74 var result params.NotifyWatchResult 75 76 if r.auth.AuthOwner(r.machine.Tag()) { 77 watch, err = r.machine.WatchForRebootEvent() 78 if err != nil { 79 result.Error = common.ServerError(err) 80 return result, nil 81 } 82 // Consume the initial event. Technically, API 83 // calls to Watch 'transmit' the initial event 84 // in the Watch response. But NotifyWatchers 85 // have no state to transmit. 86 if _, ok := <-watch.Changes(); ok { 87 result.NotifyWatcherId = r.resources.Register(watch) 88 } else { 89 err = watcher.EnsureErr(watch) 90 } 91 } 92 result.Error = common.ServerError(err) 93 return result, nil 94 }