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/mgmt.go b/runtimes/google/rt/mgmt.go
index e617410..6d3b521 100644
--- a/runtimes/google/rt/mgmt.go
+++ b/runtimes/google/rt/mgmt.go
@@ -1,7 +1,6 @@
 package rt
 
 import (
-	"fmt"
 	"time"
 
 	"v.io/core/veyron2"
@@ -58,25 +57,6 @@
 	return server, 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 (rt *vrt) callbackToParent(parentName, myName string) error {
 	ctx, _ := context.WithTimeout(rt.NewContext(), 10*time.Second)
 	call, err := rt.Client().StartCall(ctx, parentName, "Set", []interface{}{mgmt.AppCycleManagerConfigKey, myName})
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
+}
diff --git a/runtimes/google/rt/rt.go b/runtimes/google/rt/rt.go
index f38deb6..77f1258 100644
--- a/runtimes/google/rt/rt.go
+++ b/runtimes/google/rt/rt.go
@@ -1,7 +1,6 @@
 package rt
 
 import (
-	"flag"
 	"fmt"
 	"os"
 	"path/filepath"
@@ -55,12 +54,8 @@
 
 var _ veyron2.Runtime = (*vrt)(nil)
 
-var flagsOnce sync.Once
-var runtimeFlags *flags.Flags
-
 func init() {
 	rt.RegisterRuntime(veyron2.GoogleRuntimeName, New)
-	runtimeFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime)
 }
 
 // Implements veyron2/rt.New
diff --git a/runtimes/google/rt/rt_test.go b/runtimes/google/rt/rt_test.go
index c8e803d..44cf67f 100644
--- a/runtimes/google/rt/rt_test.go
+++ b/runtimes/google/rt/rt_test.go
@@ -3,7 +3,6 @@
 import (
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"reflect"
 	"regexp"
@@ -13,7 +12,6 @@
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/options"
 	"v.io/core/veyron2/rt"
-	"v.io/core/veyron2/security"
 	"v.io/core/veyron2/vlog"
 
 	"v.io/core/veyron/lib/expect"
@@ -104,33 +102,6 @@
 	h.Shutdown(os.Stderr, os.Stderr)
 }
 
-func validatePrincipal(p security.Principal) error {
-	if p == nil {
-		return fmt.Errorf("nil principal")
-	}
-	blessings := p.BlessingStore().Default()
-	if blessings == nil {
-		return fmt.Errorf("rt.Principal().BlessingStore().Default() returned nil")
-	}
-	ctx := security.NewContext(&security.ContextParams{LocalPrincipal: p})
-	if n := len(blessings.ForContext(ctx)); n != 1 {
-		fmt.Errorf("rt.Principal().BlessingStore().Default() returned Blessing %v with %d recognized blessings, want exactly one recognized blessing", blessings, n)
-	}
-	return nil
-}
-
-func defaultBlessing(p security.Principal) string {
-	return p.BlessingStore().Default().ForContext(security.NewContext(&security.ContextParams{LocalPrincipal: p}))[0]
-}
-
-func tmpDir(t *testing.T) string {
-	dir, err := ioutil.TempDir("", "rt_test_dir")
-	if err != nil {
-		t.Fatalf("unexpected error: %s", err)
-	}
-	return dir
-}
-
 func principal(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
 	r, err := rt.New()
 	if err != nil {
@@ -173,16 +144,6 @@
 	return nil
 }
 
-func createCredentialsInDir(t *testing.T, dir string, blessing string) {
-	principal, err := vsecurity.CreatePersistentPrincipal(dir, nil)
-	if err != nil {
-		t.Fatalf("unexpected error: %s", err)
-	}
-	if err := vsecurity.InitDefaultBlessings(principal, blessing); err != nil {
-		t.Fatalf("unexpected error: %s", err)
-	}
-}
-
 func TestPrincipalInheritance(t *testing.T) {
 	sh, err := modules.NewShell(nil)
 	if err != nil {
diff --git a/runtimes/google/rt/rtx_test.go b/runtimes/google/rt/rtx_test.go
new file mode 100644
index 0000000..212075d
--- /dev/null
+++ b/runtimes/google/rt/rtx_test.go
@@ -0,0 +1,283 @@
+package rt_test
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"regexp"
+	"testing"
+	"time"
+
+	"v.io/core/veyron2"
+	"v.io/core/veyron2/context"
+	"v.io/core/veyron2/security"
+	"v.io/core/veyron2/vlog"
+
+	"v.io/core/veyron/lib/expect"
+	"v.io/core/veyron/lib/flags/consts"
+	"v.io/core/veyron/lib/modules"
+	"v.io/core/veyron/lib/testutil"
+	"v.io/core/veyron/runtimes/google/rt"
+	vsecurity "v.io/core/veyron/security"
+)
+
+func init() {
+	testutil.Init()
+	modules.RegisterChild("childX", "", childX)
+	modules.RegisterChild("principalX", "", principalX)
+	modules.RegisterChild("runnerX", "", runnerX)
+}
+
+// initForTest creates a context for use in a test.
+func initForTest() (*context.T, context.CancelFunc) {
+	r := &rt.RuntimeX{}
+	var ctx *context.T
+	var cancel context.CancelFunc
+	var err error
+	ctx, cancel = context.WithCancel(ctx)
+	ctx, err = r.Init(ctx, nil)
+	if err != nil {
+		panic(err)
+	}
+	return ctx, cancel
+}
+
+func TestHelperProcessX(t *testing.T) {
+	modules.DispatchInTest()
+}
+
+func TestInitX(t *testing.T) {
+	ctx, cancel := initForTest()
+	defer cancel()
+
+	l := veyron2.GetLogger(ctx)
+	fmt.Println(l)
+	args := fmt.Sprintf("%s", l)
+	expected := regexp.MustCompile("name=veyron logdirs=\\[/tmp\\] logtostderr=true|false alsologtostderr=false|true max_stack_buf_size=4292608 v=[0-9] stderrthreshold=2 vmodule= log_backtrace_at=:0")
+	if !expected.MatchString(args) {
+		t.Errorf("unexpected default args: %s", args)
+	}
+	p := veyron2.GetPrincipal(ctx)
+	if p == nil {
+		t.Fatalf("A new principal should have been created")
+	}
+	if p.BlessingStore() == nil {
+		t.Fatalf("The principal must have a BlessingStore")
+	}
+	if p.BlessingStore().Default() == nil {
+		t.Errorf("Principal().BlessingStore().Default() should not be nil")
+	}
+	if p.BlessingStore().ForPeer() == nil {
+		t.Errorf("Principal().BlessingStore().ForPeer() should not be nil")
+	}
+}
+
+func childX(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+	ctx, cancel := veyron2.Init()
+	defer cancel()
+
+	logger := veyron2.GetLogger(ctx)
+	vlog.Infof("%s\n", logger)
+	fmt.Fprintf(stdout, "%s\n", logger)
+	modules.WaitForEOF(stdin)
+	fmt.Fprintf(stdout, "done\n")
+	return nil
+}
+
+func TestInitArgsX(t *testing.T) {
+	sh, err := modules.NewShell(nil)
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	defer sh.Cleanup(os.Stderr, os.Stderr)
+	h, err := sh.Start("child", nil, "--logtostderr=true", "--vmodule=*=3", "--", "foobar")
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	s := expect.NewSession(t, h.Stdout(), time.Minute)
+	s.Expect(fmt.Sprintf("name=veyron "+
+		"logdirs=[%s] "+
+		"logtostderr=true "+
+		"alsologtostderr=true "+
+		"max_stack_buf_size=4292608 "+
+		"v=0 "+
+		"stderrthreshold=2 "+
+		"vmodule=*=3 "+
+		"log_backtrace_at=:0",
+		os.TempDir()))
+	h.CloseStdin()
+	s.Expect("done")
+	s.ExpectEOF()
+	h.Shutdown(os.Stderr, os.Stderr)
+}
+
+func validatePrincipal(p security.Principal) error {
+	if p == nil {
+		return fmt.Errorf("nil principal")
+	}
+	blessings := p.BlessingStore().Default()
+	if blessings == nil {
+		return fmt.Errorf("rt.Principal().BlessingStore().Default() returned nil")
+	}
+	ctx := security.NewContext(&security.ContextParams{LocalPrincipal: p})
+	if n := len(blessings.ForContext(ctx)); n != 1 {
+		fmt.Errorf("rt.Principal().BlessingStore().Default() returned Blessing %v with %d recognized blessings, want exactly one recognized blessing", blessings, n)
+	}
+	return nil
+}
+
+func defaultBlessing(p security.Principal) string {
+	return p.BlessingStore().Default().ForContext(security.NewContext(&security.ContextParams{LocalPrincipal: p}))[0]
+}
+
+func tmpDir(t *testing.T) string {
+	dir, err := ioutil.TempDir("", "rt_test_dir")
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	return dir
+}
+
+func principalX(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+	ctx, cancel := veyron2.Init()
+	defer cancel()
+
+	p := veyron2.GetPrincipal(ctx)
+	if err := validatePrincipal(p); err != nil {
+		return err
+	}
+	fmt.Fprintf(stdout, "DEFAULT_BLESSING=%s\n", defaultBlessing(p))
+	return nil
+}
+
+// Runner runs a principal as a subprocess and reports back with its
+// own security info and it's childs.
+func runnerX(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+	ctx, cancel := veyron2.Init()
+	defer cancel()
+
+	p := veyron2.GetPrincipal(ctx)
+	if err := validatePrincipal(p); err != nil {
+		return err
+	}
+	fmt.Fprintf(stdout, "RUNNER_DEFAULT_BLESSING=%v\n", defaultBlessing(p))
+	sh, err := modules.NewShell(nil)
+	if err != nil {
+		return err
+	}
+	if _, err := sh.Start("principal", nil, args[1:]...); err != nil {
+		return err
+	}
+	// Cleanup copies the output of sh to these Writers.
+	sh.Cleanup(stdout, stderr)
+	return nil
+}
+
+func createCredentialsInDir(t *testing.T, dir string, blessing string) {
+	principal, err := vsecurity.CreatePersistentPrincipal(dir, nil)
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	if err := vsecurity.InitDefaultBlessings(principal, blessing); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+}
+
+func TestPrincipalInheritanceX(t *testing.T) {
+	sh, err := modules.NewShell(nil)
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	defer func() {
+		sh.Cleanup(os.Stdout, os.Stderr)
+	}()
+
+	// Test that the child inherits from the parent's credentials correctly.
+	// The running test process may or may not have a credentials directory set
+	// up so we have to use a 'runner' process to ensure the correct setup.
+	cdir := tmpDir(t)
+	defer os.RemoveAll(cdir)
+
+	createCredentialsInDir(t, cdir, "test")
+
+	// directory supplied by the environment.
+	credEnv := []string{consts.VeyronCredentials + "=" + cdir}
+
+	h, err := sh.Start("runner", credEnv)
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+
+	s := expect.NewSession(t, h.Stdout(), time.Minute)
+	runnerBlessing := s.ExpectVar("RUNNER_DEFAULT_BLESSING")
+	principalBlessing := s.ExpectVar("DEFAULT_BLESSING")
+	if err := s.Error(); err != nil {
+		t.Fatalf("failed to read input from children: %s", err)
+	}
+	h.Shutdown(os.Stdout, os.Stderr)
+
+	wantRunnerBlessing := "test"
+	wantPrincipalBlessing := "test/child"
+	if runnerBlessing != wantRunnerBlessing || principalBlessing != wantPrincipalBlessing {
+		t.Fatalf("unexpected default blessing: got runner %s, principal %s, want runner %s, principal %s", runnerBlessing, principalBlessing, wantRunnerBlessing, wantPrincipalBlessing)
+	}
+
+}
+
+func TestPrincipalInitX(t *testing.T) {
+	// Collect the process' public key and error status
+	collect := func(sh *modules.Shell, env []string, args ...string) string {
+		h, err := sh.Start("principal", env, args...)
+		if err != nil {
+			t.Fatalf("unexpected error: %s", err)
+		}
+		s := expect.NewSession(t, h.Stdout(), time.Minute)
+		s.SetVerbosity(testing.Verbose())
+		return s.ExpectVar("DEFAULT_BLESSING")
+	}
+
+	// A credentials directory may, or may, not have been already specified.
+	// Either way, we want to use our own, so we set it aside and use our own.
+	origCredentialsDir := os.Getenv(consts.VeyronCredentials)
+	defer os.Setenv(consts.VeyronCredentials, origCredentialsDir)
+
+	// Test that with VEYRON_CREDENTIALS unset the runtime's Principal
+	// is correctly initialized.
+	if err := os.Setenv(consts.VeyronCredentials, ""); err != nil {
+		t.Fatal(err)
+	}
+
+	sh, err := modules.NewShell(nil)
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	defer sh.Cleanup(os.Stderr, os.Stderr)
+
+	blessing := collect(sh, nil)
+	if len(blessing) == 0 {
+		t.Fatalf("child returned an empty default blessings set")
+	}
+
+	// Test specifying credentials via VEYRON_CREDENTIALS environment.
+	cdir1 := tmpDir(t)
+	defer os.RemoveAll(cdir1)
+	createCredentialsInDir(t, cdir1, "test_env")
+	credEnv := []string{consts.VeyronCredentials + "=" + cdir1}
+
+	blessing = collect(sh, credEnv)
+	if got, want := blessing, "test_env"; got != want {
+		t.Errorf("got default blessings: %q, want %q", got, want)
+	}
+
+	// Test specifying credentials via the command line and that the
+	// comand line overrides the environment
+	cdir2 := tmpDir(t)
+	defer os.RemoveAll(cdir2)
+	createCredentialsInDir(t, cdir2, "test_cmd")
+
+	blessing = collect(sh, credEnv, "--veyron.credentials="+cdir2)
+	if got, want := blessing, "test_cmd"; got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+}
diff --git a/runtimes/google/rt/runtimex.go b/runtimes/google/rt/runtimex.go
index c50f693..ef249cc 100644
--- a/runtimes/google/rt/runtimex.go
+++ b/runtimes/google/rt/runtimex.go
@@ -1,26 +1,38 @@
 package rt
 
 import (
+	"flag"
 	"fmt"
+	"os"
+	"os/signal"
+	"path/filepath"
+	"strings"
+	"sync"
+	"syscall"
 	"time"
 
-	_ "v.io/core/veyron/lib/stats/sysstats"
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/config"
 	"v.io/core/veyron2/context"
+	"v.io/core/veyron2/i18n"
 	"v.io/core/veyron2/ipc"
 	"v.io/core/veyron2/ipc/stream"
 	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/options"
 	"v.io/core/veyron2/security"
+	"v.io/core/veyron2/verror2"
 	"v.io/core/veyron2/vlog"
+	"v.io/core/veyron2/vtrace"
 
-	//iipc "v.io/core/veyron/runtimes/google/ipc"
+	"v.io/core/veyron/lib/exec"
+	"v.io/core/veyron/lib/flags"
+	_ "v.io/core/veyron/lib/stats/sysstats"
 	iipc "v.io/core/veyron/runtimes/google/ipc"
 	imanager "v.io/core/veyron/runtimes/google/ipc/stream/manager"
 	"v.io/core/veyron/runtimes/google/ipc/stream/vc"
 	inaming "v.io/core/veyron/runtimes/google/naming"
 	"v.io/core/veyron/runtimes/google/naming/namespace"
+	ivtrace "v.io/core/veyron/runtimes/google/vtrace"
 )
 
 type contextKey int
@@ -39,8 +51,14 @@
 	publisherKey
 )
 
+// TODO(suharshs,mattr): Panic instead of flagsOnce after the transition to veyron.Init is completed.
+var flagsOnce sync.Once
+var runtimeFlags *flags.Flags
+var signals chan os.Signal
+
 func init() {
 	veyron2.RegisterRuntime("google", &RuntimeX{})
+	runtimeFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime)
 }
 
 // initRuntimeXContext provides compatibility between Runtime and RuntimeX.
@@ -68,18 +86,140 @@
 // individiual methods.
 type RuntimeX struct{}
 
-// TODO(mattr): This function isn't used yet.  We'll implement it later
-// in the transition.
-func (*RuntimeX) Init(ctx *context.T, protocols []string) *context.T {
-	// TODO(mattr): Here we need to do a bunch of one time init, like parsing flags
-	// and reading the credentials, init logging and verror, start an appcycle manager.
-	// TODO(mattr): Here we need to arrange for a long of one time cleanup
-	// when cancel is called. Dump vtrace, shotdown signalhandling, shutdownlogging,
-	// shutdown the appcyclemanager.
+func (r *RuntimeX) Init(ctx *context.T, protocols []string) (*context.T, error) {
+	handle, err := exec.GetChildHandle()
+	switch err {
+	case exec.ErrNoVersion:
+		// The process has not been started through the veyron exec
+		// library. No further action is needed.
+	case nil:
+		// The process has been started through the veyron exec
+		// library.
+	default:
+		return nil, err
+	}
+
+	r.initLogging(ctx)
+	ctx = context.WithValue(ctx, loggerKey, vlog.Log)
+
+	// Set the preferred protocols.
 	if len(protocols) > 0 {
 		ctx = context.WithValue(ctx, protocolsKey, protocols)
 	}
-	return ctx
+
+	// Parse runtime flags.
+	flagsOnce.Do(func() {
+		var config map[string]string
+		if handle != nil {
+			config = handle.Config.Dump()
+		}
+		runtimeFlags.Parse(os.Args[1:], config)
+	})
+	flags := runtimeFlags.RuntimeFlags()
+
+	// Setup i18n.
+	ctx = i18n.ContextWithLangID(ctx, i18n.LangIDFromEnv())
+	if len(flags.I18nCatalogue) != 0 {
+		cat := i18n.Cat()
+		for _, filename := range strings.Split(flags.I18nCatalogue, ",") {
+			err := cat.MergeFromFile(filename)
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "%s: i18n: error reading i18n catalogue file %q: %s\n", os.Args[0], filename, err)
+			}
+		}
+	}
+
+	// Setup the program name.
+	ctx = verror2.ContextWithComponentName(ctx, filepath.Base(os.Args[0]))
+
+	// Setup the initial trace.
+	ctx, err = ivtrace.Init(ctx, flags.Vtrace)
+	if err != nil {
+		return nil, err
+	}
+	ctx, _ = vtrace.SetNewTrace(ctx)
+
+	// Enable signal handling.
+	initSignalHandling(ctx)
+
+	// Set the initial namespace.
+	ctx, _, err = r.setNewNamespace(ctx, flags.NamespaceRoots...)
+	if err != nil {
+		return nil, err
+	}
+
+	// Set the initial stream manager.
+	ctx, _, err = r.setNewStreamManager(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	// The clinet we attach here is incomplete (has a nil principal) and only works
+	// because the agent uses anonymous unix sockets and VCSecurityNone.
+	// After security is initialized we will attach a real client.
+	ctx, _, err = r.SetNewClient(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	// Initialize security.
+	principal, err := initSecurity(ctx, handle, flags.Credentials)
+	if err != nil {
+		return nil, err
+	}
+	ctx = context.WithValue(ctx, principalKey, principal)
+
+	// Set up secure client.
+	ctx, _, err = r.SetNewClient(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	// Initialize management.
+	if err := initMgmt(ctx, r.GetAppCycle(ctx), handle); err != nil {
+		return nil, err
+	}
+
+	// TODO(suharshs,mattr): Go through the rt.Cleanup function and make sure everything
+	// gets cleaned up.
+
+	return ctx, nil
+}
+
+// initLogging configures logging for the runtime. It needs to be called after
+// flag.Parse and after signal handling has been initialized.
+func (*RuntimeX) initLogging(ctx *context.T) error {
+	if done := ctx.Done(); done != nil {
+		go func() {
+			<-done
+			vlog.FlushLog()
+		}()
+	}
+	return vlog.ConfigureLibraryLoggerFromFlags()
+}
+
+func initSignalHandling(ctx *context.T) {
+	// TODO(caprita): Given that our device manager implementation is to
+	// kill all child apps when the device manager dies, we should
+	// enable SIGHUP on apps by default.
+
+	// Automatically handle SIGHUP to prevent applications started as
+	// daemons from being killed.  The developer can choose to still listen
+	// on SIGHUP and take a different action if desired.
+	signals = make(chan os.Signal, 1)
+	signal.Notify(signals, syscall.SIGHUP)
+	go func() {
+		for {
+			vlog.Infof("Received signal %v", <-signals)
+		}
+	}()
+
+	if done := ctx.Done(); done != nil {
+		go func() {
+			<-done
+			signal.Stop(signals)
+		}()
+	}
 }
 
 func (*RuntimeX) NewEndpoint(ep string) (naming.Endpoint, error) {
diff --git a/runtimes/google/rt/runtimex_test.go b/runtimes/google/rt/runtimex_test.go
index 46881eb..a78ad3a 100644
--- a/runtimes/google/rt/runtimex_test.go
+++ b/runtimes/google/rt/runtimex_test.go
@@ -10,17 +10,16 @@
 )
 
 // InitForTest creates a context for use in a test.
-// TODO(mattr): We should call runtimeX.Init once that is implemented.
 func InitForTest(t *testing.T) (*context.T, context.CancelFunc) {
-	rt, err := rt.New(profileOpt)
+	r := &rt.RuntimeX{}
+	var ctx *context.T
+	var cancel context.CancelFunc
+	var err error
+	ctx, cancel = context.WithCancel(ctx)
+	ctx, err = r.Init(ctx, nil)
 	if err != nil {
-		t.Fatalf("Could not create runtime: %v", err)
+		t.Fatal(err)
 	}
-	ctx, cancel := context.WithCancel(rt.NewContext())
-	go func() {
-		<-ctx.Done()
-		rt.Cleanup()
-	}()
 	return ctx, cancel
 }
 
diff --git a/runtimes/google/rt/security.go b/runtimes/google/rt/security.go
index 59f5497..f8df35c 100644
--- a/runtimes/google/rt/security.go
+++ b/runtimes/google/rt/security.go
@@ -1,12 +1,8 @@
 package rt
 
 import (
-	"fmt"
 	"os"
-	"os/user"
-	"strconv"
 
-	"v.io/core/veyron2/mgmt"
 	"v.io/core/veyron2/security"
 
 	"v.io/core/veyron/lib/exec"
@@ -29,23 +25,6 @@
 	return nil
 }
 
-// agentFD returns a non-negative file descriptor to be used to communicate with
-// the security agent if the current process has been configured to use the
-// agent.
-func agentFD(handle *exec.ChildHandle) (int, error) {
-	var fd string
-	if handle != nil {
-		// We were started by a parent (presumably, device manager).
-		fd, _ = handle.Config.Get(mgmt.SecurityAgentFDConfigKey)
-	} else {
-		fd = os.Getenv(agent.FdVarName)
-	}
-	if fd == "" {
-		return -1, nil
-	}
-	return strconv.Atoi(fd)
-}
-
 func (rt *vrt) setupPrincipal(handle *exec.ChildHandle, credentials string) error {
 	if rt.principal != nil {
 		return nil
@@ -80,19 +59,6 @@
 	return vsecurity.InitDefaultBlessings(rt.principal, defaultBlessingName())
 }
 
-func defaultBlessingName() string {
-	var name string
-	if user, _ := user.Current(); user != nil && len(user.Username) > 0 {
-		name = user.Username
-	} else {
-		name = "anonymous"
-	}
-	if host, _ := os.Hostname(); len(host) > 0 {
-		name = name + "@" + host
-	}
-	return fmt.Sprintf("%s-%d", name, os.Getpid())
-}
-
 func (rt *vrt) connectToAgent(fd int) (security.Principal, error) {
 	return agent.NewAgentPrincipal(rt.NewContext(), fd)
 }
diff --git a/runtimes/google/rt/securityx.go b/runtimes/google/rt/securityx.go
new file mode 100644
index 0000000..8ebb15d
--- /dev/null
+++ b/runtimes/google/rt/securityx.go
@@ -0,0 +1,92 @@
+package rt
+
+import (
+	"fmt"
+	"os"
+	"os/user"
+	"strconv"
+
+	"v.io/core/veyron2/context"
+	"v.io/core/veyron2/mgmt"
+	"v.io/core/veyron2/security"
+
+	"v.io/core/veyron/lib/exec"
+	"v.io/core/veyron/lib/stats"
+	vsecurity "v.io/core/veyron/security"
+	"v.io/core/veyron/security/agent"
+)
+
+func initSecurity(ctx *context.T, handle *exec.ChildHandle, credentials string) (security.Principal, error) {
+	principal, err := setupPrincipal(ctx, handle, credentials)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO(suharshs,mattr): Move this code to SetNewPrincipal and determine what their string should be.
+	stats.NewString("security/principal/key").Set(principal.PublicKey().String())
+	stats.NewStringFunc("security/principal/blessingstore", principal.BlessingStore().DebugString)
+	stats.NewStringFunc("security/principal/blessingroots", principal.Roots().DebugString)
+	return principal, nil
+}
+
+func setupPrincipal(ctx *context.T, handle *exec.ChildHandle, credentials string) (security.Principal, error) {
+	var err error
+	var principal security.Principal
+	if principal, _ = ctx.Value(principalKey).(security.Principal); principal != nil {
+		return principal, nil
+	}
+	if fd, err := agentFD(handle); err != nil {
+		return nil, err
+	} else if fd >= 0 {
+		return agent.NewAgentPrincipal(ctx, fd)
+	}
+	if len(credentials) > 0 {
+		// TODO(ataly, ashankar): If multiple runtimes are getting
+		// initialized at the same time from the same VEYRON_CREDENTIALS
+		// we will need some kind of locking for the credential files.
+		if principal, err = vsecurity.LoadPersistentPrincipal(credentials, nil); err != nil {
+			if os.IsNotExist(err) {
+				if principal, err = vsecurity.CreatePersistentPrincipal(credentials, nil); err != nil {
+					return principal, err
+				}
+				return principal, vsecurity.InitDefaultBlessings(principal, defaultBlessingName())
+			}
+			return nil, err
+		}
+		return principal, nil
+	}
+	if principal, err = vsecurity.NewPrincipal(); err != nil {
+		return principal, err
+	}
+	return principal, vsecurity.InitDefaultBlessings(principal, defaultBlessingName())
+}
+
+// agentFD returns a non-negative file descriptor to be used to communicate with
+// the security agent if the current process has been configured to use the
+// agent.
+func agentFD(handle *exec.ChildHandle) (int, error) {
+	var fd string
+	if handle != nil {
+		// We were started by a parent (presumably, device manager).
+		fd, _ = handle.Config.Get(mgmt.SecurityAgentFDConfigKey)
+	} else {
+		fd = os.Getenv(agent.FdVarName)
+	}
+	if fd == "" {
+		return -1, nil
+	}
+	return strconv.Atoi(fd)
+}
+
+func defaultBlessingName() string {
+	var name string
+	if user, _ := user.Current(); user != nil && len(user.Username) > 0 {
+		name = user.Username
+	} else {
+		name = "anonymous"
+	}
+	if host, _ := os.Hostname(); len(host) > 0 {
+		name = name + "@" + host
+	}
+	return fmt.Sprintf("%s-%d", name, os.Getpid())
+}