veyron2: veyron2.Init function for new API.
The veyron2.Init function will do the following.
(1) Construct an empty context.
(2) Calls a profileInitFunc that returns a RuntimeX instace and an initialized context.
(3) Returns the *context.T and a context.CancelFunc.
Change-Id: I4130499bba7955c57291654ca1aa7504bdb78a2d
diff --git a/runtimes/google/rt/mgmtx.go b/runtimes/google/rt/mgmtx.go
new file mode 100644
index 0000000..cef0cb7
--- /dev/null
+++ b/runtimes/google/rt/mgmtx.go
@@ -0,0 +1,97 @@
+package rt
+
+import (
+ "fmt"
+ "time"
+
+ "v.io/core/veyron2"
+ "v.io/core/veyron2/context"
+ "v.io/core/veyron2/ipc"
+ "v.io/core/veyron2/mgmt"
+ "v.io/core/veyron2/naming"
+ "v.io/core/veyron2/options"
+
+ "v.io/core/veyron/lib/exec"
+)
+
+func initMgmt(ctx *context.T, appCycle veyron2.AppCycle, handle *exec.ChildHandle) error {
+ // Do not initialize the mgmt runtime if the process has not
+ // been started through the veyron exec library by a device
+ // manager.
+ if handle == nil {
+ return nil
+ }
+ parentName, err := handle.Config.Get(mgmt.ParentNameConfigKey)
+ if err != nil {
+ return nil
+ }
+ listenSpec, err := getListenSpec(handle)
+ if err != nil {
+ return err
+ }
+ var serverOpts []ipc.ServerOpt
+ parentPeerPattern, err := handle.Config.Get(mgmt.ParentBlessingConfigKey)
+ if err == nil && parentPeerPattern != "" {
+ // Grab the blessing from our blessing store that the parent
+ // told us to use so they can talk to us.
+ serverBlessing := veyron2.GetPrincipal(ctx).BlessingStore().ForPeer(parentPeerPattern)
+ serverOpts = append(serverOpts, options.ServerBlessings{serverBlessing})
+ }
+ server, err := veyron2.NewServer(ctx, serverOpts...)
+ if err != nil {
+ return err
+ }
+ eps, err := server.Listen(*listenSpec)
+ if err != nil {
+ return err
+ }
+ if err := server.Serve("", appCycle.Remote(), nil); err != nil {
+ server.Stop()
+ return err
+ }
+ err = callbackToParent(ctx, parentName, naming.JoinAddressName(eps[0].String(), ""))
+ if err != nil {
+ server.Stop()
+ return err
+ }
+
+ if done := ctx.Done(); done != nil {
+ go func() {
+ <-done
+ server.Stop()
+ }()
+ }
+
+ return nil
+}
+
+func getListenSpec(handle *exec.ChildHandle) (*ipc.ListenSpec, error) {
+ protocol, err := handle.Config.Get(mgmt.ProtocolConfigKey)
+ if err != nil {
+ return nil, err
+ }
+ if protocol == "" {
+ return nil, fmt.Errorf("%v is not set", mgmt.ProtocolConfigKey)
+ }
+
+ address, err := handle.Config.Get(mgmt.AddressConfigKey)
+ if err != nil {
+ return nil, err
+ }
+ if address == "" {
+ return nil, fmt.Errorf("%v is not set", mgmt.AddressConfigKey)
+ }
+ return &ipc.ListenSpec{Addrs: ipc.ListenAddrs{{protocol, address}}}, nil
+}
+
+func callbackToParent(ctx *context.T, parentName, myName string) error {
+ ctx, _ = context.WithTimeout(ctx, 10*time.Second)
+ call, err := veyron2.GetClient(ctx).StartCall(ctx, parentName, "Set", []interface{}{mgmt.AppCycleManagerConfigKey, myName})
+ if err != nil {
+ return err
+ }
+ if ierr := call.Finish(&err); ierr != nil {
+ return ierr
+ }
+ return err
+}