blob: ccaad6280c189cc2ba39be5c813ddadd1a25ecec [file] [log] [blame]
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -08001package rt
2
3import (
4 "fmt"
5 "time"
6
7 "v.io/core/veyron2"
8 "v.io/core/veyron2/context"
9 "v.io/core/veyron2/ipc"
10 "v.io/core/veyron2/mgmt"
11 "v.io/core/veyron2/naming"
12 "v.io/core/veyron2/options"
13
14 "v.io/core/veyron/lib/exec"
15)
16
Matt Rosencrantz31995882015-01-27 20:00:48 -080017func (rt *Runtime) initMgmt(ctx *context.T) error {
18 handle, err := exec.GetChildHandle()
19 if err == exec.ErrNoVersion {
20 // Do not initialize the mgmt runtime if the process has not
21 // been started through the veyron exec library by a device
22 // manager.
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080023 return nil
Matt Rosencrantz31995882015-01-27 20:00:48 -080024 } else if err != nil {
25 return err
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080026 }
Matt Rosencrantz31995882015-01-27 20:00:48 -080027
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080028 parentName, err := handle.Config.Get(mgmt.ParentNameConfigKey)
29 if err != nil {
30 return nil
31 }
32 listenSpec, err := getListenSpec(handle)
33 if err != nil {
34 return err
35 }
36 var serverOpts []ipc.ServerOpt
37 parentPeerPattern, err := handle.Config.Get(mgmt.ParentBlessingConfigKey)
38 if err == nil && parentPeerPattern != "" {
39 // Grab the blessing from our blessing store that the parent
40 // told us to use so they can talk to us.
Suharsh Sivakumard5049b72015-01-21 14:11:35 -080041 serverBlessing := rt.GetPrincipal(ctx).BlessingStore().ForPeer(parentPeerPattern)
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080042 serverOpts = append(serverOpts, options.ServerBlessings{serverBlessing})
43 }
Suharsh Sivakumard5049b72015-01-21 14:11:35 -080044 server, err := rt.NewServer(ctx, serverOpts...)
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080045 if err != nil {
46 return err
47 }
48 eps, err := server.Listen(*listenSpec)
49 if err != nil {
50 return err
51 }
Matt Rosencrantz31995882015-01-27 20:00:48 -080052 if err := server.Serve("", veyron2.GetAppCycle(ctx).Remote(), nil); err != nil {
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080053 server.Stop()
54 return err
55 }
Suharsh Sivakumard5049b72015-01-21 14:11:35 -080056 err = rt.callbackToParent(ctx, parentName, naming.JoinAddressName(eps[0].String(), ""))
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080057 if err != nil {
58 server.Stop()
59 return err
60 }
61
Matt Rosencrantz31995882015-01-27 20:00:48 -080062 // Note(mattr): that we ignore the error here.
63 // As far as I can tell this is because the modules framework actually calls
64 // SetReady(), so we would then call it here a second time and get
65 // an error.
66 // TODO(mattr): We should change the modules framework so we can properly check
67 // errors here.
68 handle.SetReady()
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080069 return nil
70}
71
72func getListenSpec(handle *exec.ChildHandle) (*ipc.ListenSpec, error) {
73 protocol, err := handle.Config.Get(mgmt.ProtocolConfigKey)
74 if err != nil {
75 return nil, err
76 }
77 if protocol == "" {
78 return nil, fmt.Errorf("%v is not set", mgmt.ProtocolConfigKey)
79 }
80
81 address, err := handle.Config.Get(mgmt.AddressConfigKey)
82 if err != nil {
83 return nil, err
84 }
85 if address == "" {
86 return nil, fmt.Errorf("%v is not set", mgmt.AddressConfigKey)
87 }
88 return &ipc.ListenSpec{Addrs: ipc.ListenAddrs{{protocol, address}}}, nil
89}
90
Matt Rosencrantzba470a52015-01-26 13:36:13 -080091func (rt *Runtime) callbackToParent(ctx *context.T, parentName, myName string) error {
Suharsh Sivakumard5049b72015-01-21 14:11:35 -080092 ctx, _ = context.WithTimeout(ctx, time.Minute)
Matt Rosencrantz31995882015-01-27 20:00:48 -080093 call, err := rt.GetClient(ctx).StartCall(ctx, parentName, "Set", []interface{}{mgmt.AppCycleManagerConfigKey, myName})
Suharsh Sivakumard5049b72015-01-21 14:11:35 -080094
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080095 if err != nil {
96 return err
97 }
98 if ierr := call.Finish(&err); ierr != nil {
99 return ierr
100 }
101 return err
102}