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