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