blob: 7362b436013d43125b9e97f559a5343ce1b07947 [file] [log] [blame]
package main
import (
"flag"
"time"
"v.io/lib/cmdline"
vexec "v.io/core/veyron/lib/exec"
"v.io/core/veyron/lib/signals"
_ "v.io/core/veyron/profiles/roaming"
"v.io/core/veyron/services/mgmt/device/config"
"v.io/core/veyron/services/mgmt/device/impl"
"v.io/core/veyron2"
"v.io/core/veyron2/mgmt"
"v.io/core/veyron2/vlog"
)
var (
// TODO(caprita): publishAs and restartExitCode should be provided by the
// config?
publishAs = flag.String("name", "", "name to publish the device manager at")
restartExitCode = flag.Int("restart_exit_code", 0, "exit code to return when device manager should be restarted")
)
func runServer(*cmdline.Command, []string) error {
ctx, shutdown := veyron2.Init()
defer shutdown()
var testMode bool
// If this device manager was started by another device manager, it must
// be part of a self update to test that this binary works. In that
// case, we need to disable a lot of functionality.
if handle, err := vexec.GetChildHandle(); err == nil {
if _, err := handle.Config.Get(mgmt.ParentNameConfigKey); err == nil {
testMode = true
vlog.Infof("TEST MODE")
}
}
server, err := veyron2.NewServer(ctx)
if err != nil {
vlog.Errorf("NewServer() failed: %v", err)
return err
}
defer server.Stop()
ls := veyron2.GetListenSpec(ctx)
endpoints, err := server.Listen(ls)
if err != nil {
vlog.Errorf("Listen(%s) failed: %v", ls, err)
return err
}
name := endpoints[0].Name()
vlog.VI(0).Infof("Device manager object name: %v", name)
configState, err := config.Load()
if err != nil {
vlog.Errorf("Failed to load config passed from parent: %v", err)
return err
}
configState.Name = name
// TODO(caprita): We need a way to set config fields outside of the
// update mechanism (since that should ideally be an opaque
// implementation detail).
var exitErr error
dispatcher, err := impl.NewDispatcher(veyron2.GetPrincipal(ctx), configState, testMode, func() { exitErr = cmdline.ErrExitCode(*restartExitCode) })
if err != nil {
vlog.Errorf("Failed to create dispatcher: %v", err)
return err
}
var publishName string
if testMode == false {
publishName = *publishAs
}
if err := server.ServeDispatcher(publishName, dispatcher); err != nil {
vlog.Errorf("Serve(%v) failed: %v", publishName, err)
return err
}
vlog.VI(0).Infof("Device manager published as: %v", publishName)
impl.InvokeCallback(ctx, name)
// Wait until shutdown. Ignore duplicate signals (sent by agent and
// received as part of process group).
signals.SameSignalTimeWindow = 500 * time.Millisecond
<-signals.ShutdownOnSignals(ctx)
return exitErr
}