Merge "veyron/services/mgmt/node/impl: node manager to pass NAMESPACE_ROOT to apps"
diff --git a/services/mgmt/node/impl/app_service.go b/services/mgmt/node/impl/app_service.go
index 30582ef..c85e75e 100644
--- a/services/mgmt/node/impl/app_service.go
+++ b/services/mgmt/node/impl/app_service.go
@@ -707,7 +707,7 @@
 	return "", verror2.Make(ErrOperationFailed, ctx)
 }
 
-func genCmd(instanceDir, helperPath, systemName string) (*exec.Cmd, error) {
+func genCmd(instanceDir, helperPath, systemName string, nsRoots []string) (*exec.Cmd, error) {
 	versionLink := filepath.Join(instanceDir, "version")
 	versionDir, err := filepath.EvalSymlinks(versionLink)
 	if err != nil {
@@ -727,9 +727,11 @@
 	cmd := exec.Command(helperPath)
 	cmd.Args = append(cmd.Args, "--username", systemName)
 
-	// TODO(caprita): Also pass in configuration info like NAMESPACE_ROOT to
-	// the app (to point to the device mounttable).
-	cmd.Env = envelope.Env
+	var nsRootEnvs []string
+	for i, r := range nsRoots {
+		nsRootEnvs = append(nsRootEnvs, fmt.Sprintf("%s%d=%s", consts.NamespaceRootPrefix, i, r))
+	}
+	cmd.Env = append(nsRootEnvs, envelope.Env...)
 	rootDir := filepath.Join(instanceDir, "root")
 	if err := mkdir(rootDir); err != nil {
 		return nil, err
@@ -755,7 +757,7 @@
 	cmd.Args = append(cmd.Args, "--run", binPath)
 	cmd.Args = append(cmd.Args, "--")
 
-	// Set up args and env.
+	// Args to be passed by helper to the app.
 	cmd.Args = append(cmd.Args, "--log_dir=../logs")
 	cmd.Args = append(cmd.Args, envelope.Args...)
 	return cmd, nil
@@ -846,12 +848,12 @@
 	return nil
 }
 
-func (i *appService) run(instanceDir, systemName string) error {
+func (i *appService) run(nsRoots []string, instanceDir, systemName string) error {
 	if err := transitionInstance(instanceDir, suspended, starting); err != nil {
 		return err
 	}
 
-	cmd, err := genCmd(instanceDir, i.config.Helper, systemName)
+	cmd, err := genCmd(instanceDir, i.config.Helper, systemName, nsRoots)
 	if err == nil {
 		err = i.startCmd(instanceDir, cmd)
 	}
@@ -882,7 +884,9 @@
 		return nil, err
 	}
 
-	if err = i.run(instanceDir, systemName); err != nil {
+	// For now, use the namespace roots of the node manager runtime to pass
+	// to the app.
+	if err = i.run(veyron2.RuntimeFromContext(call).Namespace().Roots(), instanceDir, systemName); err != nil {
 		// TODO(caprita): We should call cleanupDir here, but we don't
 		// in order to not lose the logs for the instance (so we can
 		// debug why run failed).  Clean this up.
@@ -930,7 +934,7 @@
 	if startSystemName != systemName {
 		return verror2.Make(verror2.NoAccess, call, "Not allowed to resume an application under a different system name.")
 	}
-	return i.run(instanceDir, systemName)
+	return i.run(veyron2.RuntimeFromContext(call).Namespace().Roots(), instanceDir, systemName)
 }
 
 func stopAppRemotely(ctx context.T, appVON string) error {
diff --git a/services/mgmt/node/impl/impl_test.go b/services/mgmt/node/impl/impl_test.go
index 62fabd7..f5dd9e2 100644
--- a/services/mgmt/node/impl/impl_test.go
+++ b/services/mgmt/node/impl/impl_test.go
@@ -571,7 +571,7 @@
 
 	// Set up the node manager.  Since we won't do node manager updates,
 	// don't worry about its application envelope and current link.
-	nmh, nms := runShellCommand(t, sh, crEnv, nodeManagerCmd, "nm", root, helperPath, "unused_app_rep_ name", "unused_curr_link")
+	nmh, nms := runShellCommand(t, sh, crEnv, nodeManagerCmd, "nm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
 	readPID(t, nms)
 
 	// Create the local server that the app uses to let us know it's ready.