lib/modules: change the NewShell factory to take a security.Principal arg.
- NewShell now takes a Principal as an argument and allows the
created shell and its subprocesses to share that principal. Taking
this a parameter allows the shell to be used with the runtime's
in-memory Principal when required or with any other.
Change-Id: Ib2dc07fdc4edf1c23afed9b37661eb484f56717e
diff --git a/lib/filelocker/locker_test.go b/lib/filelocker/locker_test.go
index f3ce658..fc23e17 100644
--- a/lib/filelocker/locker_test.go
+++ b/lib/filelocker/locker_test.go
@@ -63,7 +63,10 @@
filepath := newFile()
defer os.Remove(filepath)
- sh := modules.NewShell()
+ 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("testLockChild", nil, filepath)
if err != nil {
@@ -133,7 +136,10 @@
filepath := newFile()
defer os.Remove(filepath)
- sh := modules.NewShell()
+ 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("testLockChild", nil, filepath)
if err != nil {
diff --git a/lib/modules/core/core_test.go b/lib/modules/core/core_test.go
index 5f72ee9..86bbb0e 100644
--- a/lib/modules/core/core_test.go
+++ b/lib/modules/core/core_test.go
@@ -23,8 +23,8 @@
)
func TestCommands(t *testing.T) {
- sh := modules.NewShell()
- defer sh.Cleanup(nil, os.Stderr)
+ sh, fn := newShell(t)
+ defer fn()
for _, c := range []string{core.RootMTCommand, core.MTCommand} {
if len(sh.Help(c)) == 0 {
t.Fatalf("missing command %q", c)
@@ -37,8 +37,11 @@
rt.Init()
}
-func newShell() (*modules.Shell, func()) {
- sh := modules.NewShell()
+func newShell(t *testing.T) (*modules.Shell, func()) {
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
return sh, func() {
if testing.Verbose() {
vlog.Infof("------ cleanup ------")
@@ -55,7 +58,7 @@
}
func TestRoot(t *testing.T) {
- sh, fn := newShell()
+ sh, fn := newShell(t)
defer fn()
root, err := sh.Start(core.RootMTCommand, nil, testArgs()...)
if err != nil {
@@ -128,7 +131,7 @@
}
func TestMountTableAndGlob(t *testing.T) {
- sh, fn := newShell()
+ sh, fn := newShell(t)
defer fn()
mountPoints := []string{"a", "b", "c", "d", "e"}
@@ -201,7 +204,7 @@
}
func TestEcho(t *testing.T) {
- sh, fn := newShell()
+ sh, fn := newShell(t)
defer fn()
srv, err := sh.Start(core.EchoServerCommand, nil, testArgs("test", "")...)
@@ -223,7 +226,7 @@
}
func TestResolve(t *testing.T) {
- sh, fn := newShell()
+ sh, fn := newShell(t)
defer fn()
mountPoints := []string{"a", "b"}
diff --git a/lib/modules/modules_internal_test.go b/lib/modules/modules_internal_test.go
index 8ce9b17..b8229e3 100644
--- a/lib/modules/modules_internal_test.go
+++ b/lib/modules/modules_internal_test.go
@@ -26,7 +26,10 @@
}
func TestState(t *testing.T) {
- sh := NewShell()
+ sh, err := NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
RegisterFunction("echoff", "[args]*", Echo)
assertNumHandles(t, sh, 0)
diff --git a/lib/modules/modules_test.go b/lib/modules/modules_test.go
index ffdd2a0..cee9708 100644
--- a/lib/modules/modules_test.go
+++ b/lib/modules/modules_test.go
@@ -133,7 +133,10 @@
}
func TestChild(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
key, val := "simpleVar", "foo & bar"
sh.SetVar(key, val)
@@ -141,19 +144,25 @@
}
func TestChildNoRegistration(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(os.Stderr, os.Stderr)
key, val := "simpleVar", "foo & bar"
sh.SetVar(key, val)
testCommand(t, sh, "envtest", key, val)
- _, err := sh.Start("non-existent-command", nil, "random", "args")
+ _, err = sh.Start("non-existent-command", nil, "random", "args")
if err == nil {
t.Fatalf("expected error")
}
}
func TestFunction(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
key, val := "simpleVar", "foo & bar & baz"
sh.SetVar(key, val)
@@ -161,7 +170,10 @@
}
func TestErrorChild(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
h, err := sh.Start("errortestChild", nil)
if err != nil {
@@ -198,14 +210,21 @@
}
func TestShutdownSubprocess(t *testing.T) {
- testShutdown(t, modules.NewShell(), "echos", false)
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
+ testShutdown(t, sh, "echos", false)
}
// TestShutdownSubprocessIgnoresStdin verifies that Shutdown doesn't wait
// forever if a child does not die upon closing stdin; but instead times out and
// returns an appropriate error.
func TestShutdownSubprocessIgnoresStdin(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
sh.SetWaitTimeout(time.Second)
h, err := sh.Start("ignores_stdin", nil)
if err != nil {
@@ -227,7 +246,10 @@
// implementation inappropriately sets stdout to the file that is to be closed
// in Wait.
func TestStdoutRace(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
sh.SetWaitTimeout(time.Second)
h, err := sh.Start("ignores_stdin", nil)
if err != nil {
@@ -256,11 +278,18 @@
}
func TestShutdownFunction(t *testing.T) {
- testShutdown(t, modules.NewShell(), "echof", true)
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
+ testShutdown(t, sh, "echof", true)
}
func TestErrorFunc(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
h, err := sh.Start("errortestFunc", nil)
if err != nil {
@@ -281,7 +310,10 @@
}
func TestEnvelope(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
sh.SetVar("a", "1")
sh.SetVar("b", "2")
@@ -381,7 +413,10 @@
// Test child credentials when runtime is not initialized and VeyronCredentials
// is not set.
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
if err := validateCredentials(startChildAndGetCredentials(sh, nil), "test-shell/child"); err != nil {
t.Fatal(err)
@@ -401,7 +436,10 @@
if err := os.Setenv(consts.VeyronCredentials, dir); err != nil {
t.Fatal(err)
}
- sh = modules.NewShell()
+ sh, err = modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
if err := validateCredentials(startChildAndGetCredentials(sh, nil), "root/os/child"); err != nil {
t.Fatal(err)
}
@@ -415,7 +453,10 @@
// Test that VeyronCredentials specified on the shell override the OS ones.
dir = tsecurity.NewVeyronCredentials(root, "shell")
defer os.RemoveAll(dir)
- sh = modules.NewShell()
+ sh, err = modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
sh.SetVar(consts.VeyronCredentials, dir)
if err := validateCredentials(startChildAndGetCredentials(sh, nil), "root/shell/child"); err != nil {
t.Fatal(err)
@@ -443,7 +484,10 @@
}
func TestEnvMerge(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
sh.SetVar("a", "1")
os.Setenv("a", "wrong, should be 1")
diff --git a/lib/modules/shell.go b/lib/modules/shell.go
index 87aa85a..8d4324b 100644
--- a/lib/modules/shell.go
+++ b/lib/modules/shell.go
@@ -50,15 +50,16 @@
"fmt"
"io"
"io/ioutil"
+ "math/rand"
"os"
"sync"
"time"
+ "veyron.io/veyron/veyron2/security"
+
"veyron.io/veyron/veyron/lib/exec"
"veyron.io/veyron/veyron/lib/flags/consts"
vsecurity "veyron.io/veyron/veyron/security"
-
- "veyron.io/veyron/veyron2/security"
)
const (
@@ -76,37 +77,51 @@
tempCredDirs []string
startTimeout, waitTimeout time.Duration
config exec.Config
+ principal security.Principal
+ blessing security.Blessings
}
-// NewShell creates a new instance of Shell.
-//
-// The VeyronCredentials environment variable of the shell is set
-// as follows. If the OS's VeyronCredentials is set then the shell's
-// VeyronCredentials is set to the same value, otherwise it is set
-// to a freshly created credentials directory.
-//
-// The shell's credentials are used to bless the principal supplied
-// to any children of this shell (see Start).
-// TODO(cnicolaou): this should use the principal already setup
-// with the runtime if the runtime has been initialized, if not,
-// it should create a new principal. As of now, this approach only works
-// for child processes that talk to each other, but not to the parent
-// process that started them since it's running with a different set of
-// credentials setup elsewhere. When this change is made it should
-// be possible to remove creating credentials in many unit tests.
-func NewShell() *Shell {
+// NewShell creates a new instance of Shell. It will also add a blessing
+// to the supplied principal and ensure that any child processes are
+// created with principals that are in turn blessed with it. A typical
+// use case is to pass in the runtime's principal and hence allow the
+// process hosting the shell to interact with its children and vice
+// versa. If a nil principal is passed in then NewShell will create a new
+// principal that shares a blessing with all of its children, in this mode,
+// any child processes can interact with each other but not with the parent.
+func NewShell(p security.Principal) (*Shell, error) {
sh := &Shell{
env: make(map[string]string),
handles: make(map[Handle]struct{}),
startTimeout: time.Minute,
waitTimeout: 10 * time.Second,
config: exec.NewConfig(),
+ principal: p,
}
- if err := sh.initShellCredentials(); err != nil {
- // TODO(cnicolaou): return an error rather than panic.
- panic(err)
+ if p == nil {
+ if err := sh.initShellCredentials(); err != nil {
+ return nil, err
+ }
+ return sh, nil
}
- return sh
+ gen := rand.New(rand.NewSource(time.Now().UnixNano()))
+ // Use a unique blessing tree per shell.
+ blessingName := fmt.Sprintf("%s-%d", shellBlessingExtension, gen.Int63())
+ blessing, err := p.BlessSelf(blessingName)
+ if err != nil {
+ return nil, err
+ }
+ sh.blessing = blessing
+ if _, err := p.BlessingStore().Set(blessing, security.BlessingPattern(blessingName+"/"+childBlessingExtension+"/...")); err != nil {
+ return nil, err
+ }
+ if err := p.AddToRoots(blessing); err != nil {
+ return nil, err
+ }
+ // Our blessing store now contains a blessing with our unique prefix
+ // and the principal has that blessing's root added to its trusted
+ // list so that it will accept blessings derived from it.
+ return sh, nil
}
func (sh *Shell) initShellCredentials() error {
@@ -127,34 +142,64 @@
}
func (sh *Shell) getChildCredentials(shellCredDir string) (string, error) {
- root, err := principalFromDir(shellCredDir)
- if err != nil {
- return "", err
+ root := sh.principal
+ rootBlessing := sh.blessing
+ if root == nil {
+ r, err := principalFromDir(shellCredDir)
+ if err != nil {
+ return "", err
+ }
+ root = r
+ rootBlessing = root.BlessingStore().Default()
}
dir, err := ioutil.TempDir("", "shell_child_credentials")
if err != nil {
return "", err
}
+ // Create a principal and default blessing for the child that is
+ // derived from the blessing created for this shell. This can
+ // be used by the parent to invoke RPCs on any children and for the
+ // children to invoke RPCs on each other.
p, err := vsecurity.CreatePersistentPrincipal(dir, nil)
if err != nil {
return "", err
}
-
- blessing, err := root.Bless(p.PublicKey(), root.BlessingStore().Default(), childBlessingExtension, security.UnconstrainedUse())
+ blessingForChild, err := root.Bless(p.PublicKey(), rootBlessing, childBlessingExtension, security.UnconstrainedUse())
if err != nil {
return "", err
}
- if err := p.BlessingStore().SetDefault(blessing); err != nil {
+ if err := p.BlessingStore().SetDefault(blessingForChild); err != nil {
return "", err
}
- if _, err := p.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
+ if _, err := p.BlessingStore().Set(blessingForChild, security.AllPrincipals); err != nil {
return "", err
}
- if err := p.AddToRoots(blessing); err != nil {
+ if err := p.AddToRoots(blessingForChild); err != nil {
return "", err
}
+ if sh.blessing != nil {
+ // Create a second blessing for the child, that will be accepted
+ // by the parent, should the child choose to invoke RPCs on the parent.
+ blessingFromChild, err := root.Bless(p.PublicKey(), root.BlessingStore().Default(), childBlessingExtension, security.UnconstrainedUse())
+ if err != nil {
+ return "", err
+ }
+ // We store this blessing as the one to use with a pattern that matches
+ // the root's name.
+ // TODO(cnicolaou,caprita): at some point there will be a nicer API
+ // for getting the name of a blessing.
+ ctx := security.NewContext(&security.ContextParams{LocalPrincipal: root})
+ rootName := root.BlessingStore().Default().ForContext(ctx)[0]
+ if _, err := p.BlessingStore().Set(blessingFromChild, security.BlessingPattern(rootName)); err != nil {
+ return "", err
+ }
+
+ if err := p.AddToRoots(blessingFromChild); err != nil {
+ return "", err
+ }
+ }
sh.tempCredDirs = append(sh.tempCredDirs, dir)
return dir, nil
}
diff --git a/lib/signals/signals_test.go b/lib/signals/signals_test.go
index d57c65c..e48e373 100644
--- a/lib/signals/signals_test.go
+++ b/lib/signals/signals_test.go
@@ -112,7 +112,10 @@
}
func newShell(t *testing.T, command string) (*modules.Shell, modules.Handle, *expect.Session) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
handle, err := sh.Start(command, nil)
if err != nil {
sh.Cleanup(os.Stderr, os.Stderr)
@@ -328,7 +331,10 @@
r := rt.Init()
defer r.Cleanup()
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(os.Stderr, os.Stderr)
// Set the child process up with a blessing from the parent so that
diff --git a/runtimes/google/ipc/client_test.go b/runtimes/google/ipc/client_test.go
index c4e8b8a..aa159a7 100644
--- a/runtimes/google/ipc/client_test.go
+++ b/runtimes/google/ipc/client_test.go
@@ -26,7 +26,10 @@
}
func runMountTable(t *testing.T) (*modules.Shell, func()) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
root, err := sh.Start(core.RootMTCommand, nil, testArgs()...)
if err != nil {
t.Fatalf("unexpected error for root mt: %s", err)
diff --git a/runtimes/google/ipc/server_test.go b/runtimes/google/ipc/server_test.go
index a918f00..8e43cca 100644
--- a/runtimes/google/ipc/server_test.go
+++ b/runtimes/google/ipc/server_test.go
@@ -29,7 +29,10 @@
func TestReconnect(t *testing.T) {
b := createBundle(t, tsecurity.NewPrincipal("client"), nil, nil) // We only need the client from the bundle.
defer b.cleanup(t)
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(os.Stderr, os.Stderr)
server, err := sh.Start("runServer", nil, "127.0.0.1:0")
if err != nil {
@@ -86,7 +89,10 @@
}
func (h *proxyHandle) Start(t *testing.T) error {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
server, err := sh.Start("runProxy", nil)
if err != nil {
t.Fatalf("unexpected error: %s", err)
diff --git a/runtimes/google/ipc/stream/manager/manager_test.go b/runtimes/google/ipc/stream/manager/manager_test.go
index 8d4d872..829800f 100644
--- a/runtimes/google/ipc/stream/manager/manager_test.go
+++ b/runtimes/google/ipc/stream/manager/manager_test.go
@@ -544,7 +544,10 @@
func TestServerRestartDuringClientLifetime(t *testing.T) {
client := InternalNew(naming.FixedRoutingID(0xcccccccc))
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
h, err := sh.Start("runServer", nil, "127.0.0.1:0")
if err != nil {
@@ -583,7 +586,10 @@
func TestServerRestartDuringClientLifetimeWS(t *testing.T) {
client := InternalNew(naming.FixedRoutingID(0xcccccccc))
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer sh.Cleanup(nil, nil)
h, err := sh.Start("runServer", nil, "127.0.0.1:0")
if err != nil {
diff --git a/runtimes/google/rt/mgmt_test.go b/runtimes/google/rt/mgmt_test.go
index 355014f..cae8d50 100644
--- a/runtimes/google/rt/mgmt_test.go
+++ b/runtimes/google/rt/mgmt_test.go
@@ -116,7 +116,10 @@
// TestNoWaiters verifies that the child process exits in the absence of any
// wait channel being registered with its runtime.
func TestNoWaiters(t *testing.T) {
- sh := modules.NewShell()
+ 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(noWaitersCmd, nil)
if err != nil {
@@ -143,7 +146,10 @@
// TestForceStop verifies that ForceStop causes the child process to exit
// immediately.
func TestForceStop(t *testing.T) {
- sh := modules.NewShell()
+ 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(forceStopCmd, nil)
if err != nil {
@@ -295,7 +301,10 @@
childcreds := security.NewVeyronCredentials(r.Principal(), appCmd)
configServer, configServiceName, ch := createConfigServer(t, r)
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
sh.SetVar(consts.VeyronCredentials, childcreds)
sh.SetConfigKey(mgmt.ParentNameConfigKey, configServiceName)
sh.SetConfigKey(mgmt.ProtocolConfigKey, "tcp")
diff --git a/runtimes/google/rt/rt_test.go b/runtimes/google/rt/rt_test.go
index 15f9de7..0666b61 100644
--- a/runtimes/google/rt/rt_test.go
+++ b/runtimes/google/rt/rt_test.go
@@ -69,7 +69,10 @@
}
func TestInitArgs(t *testing.T) {
- sh := modules.NewShell()
+ 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", "--vv=3", "--", "foobar")
if err != nil {
@@ -136,7 +139,10 @@
return err
}
fmt.Fprintf(stdout, "RUNNER_DEFAULT_BLESSING=%v\n", defaultBlessing(r.Principal()))
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ return err
+ }
if _, err := sh.Start("principal", nil, args[1:]...); err != nil {
return err
}
@@ -156,7 +162,10 @@
}
func TestPrincipalInheritance(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
defer func() {
sh.Cleanup(os.Stdout, os.Stderr)
}()
@@ -216,7 +225,10 @@
t.Fatal(err)
}
- sh := modules.NewShell()
+ 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)
diff --git a/runtimes/google/rt/shutdown_test.go b/runtimes/google/rt/shutdown_test.go
index f0a57aa..4ee9468 100644
--- a/runtimes/google/rt/shutdown_test.go
+++ b/runtimes/google/rt/shutdown_test.go
@@ -25,10 +25,18 @@
}
}
+func newShell(t *testing.T) *modules.Shell {
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
+ return sh
+}
+
// TestSimpleServerSignal verifies that sending a signal to the simple server
// causes it to exit cleanly.
func TestSimpleServerSignal(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("simpleServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -44,7 +52,7 @@
// TestSimpleServerLocalStop verifies that sending a local stop command to the
// simple server causes it to exit cleanly.
func TestSimpleServerLocalStop(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("simpleServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -61,7 +69,7 @@
// signals to the simple server causes it to initiate the cleanup sequence on
// the first signal and then exit immediately on the second signal.
func TestSimpleServerDoubleSignal(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("simpleServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -81,7 +89,7 @@
// TestSimpleServerLocalForceStop verifies that sending a local ForceStop
// command to the simple server causes it to exit immediately.
func TestSimpleServerLocalForceStop(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("simpleServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -100,7 +108,7 @@
// TestSimpleServerKill demonstrates that a SIGKILL still forces the server
// to exit regardless of our signal handling.
func TestSimpleServerKill(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("simpleServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -120,7 +128,7 @@
// corresponding to all the simulated sequential/parallel and
// blocking/interruptible shutdown steps), and then exits cleanly.
func TestComplexServerSignal(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("complexServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -142,7 +150,7 @@
// printouts corresponding to all the simulated sequential/parallel and
// blocking/interruptible shutdown steps), and then exits cleanly.
func TestComplexServerLocalStop(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("complexServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -169,7 +177,7 @@
// the corresponding printouts from the server). Note that we have no
// expectations on whether or not the interruptible shutdown steps execute.
func TestComplexServerDoubleSignal(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("complexServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -193,7 +201,7 @@
// TestComplexServerLocalForceStop verifies that sending a local ForceStop
// command to the complex server forces it to exit immediately.
func TestComplexServerLocalForceStop(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("complexServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
@@ -212,7 +220,7 @@
// TestComplexServerKill demonstrates that a SIGKILL still forces the server to
// exit regardless of our signal handling.
func TestComplexServerKill(t *testing.T) {
- sh := modules.NewShell()
+ sh := newShell(t)
defer sh.Cleanup(os.Stdout, cstderr)
h, _ := sh.Start("complexServerProgram", nil)
s := expect.NewSession(t, h.Stdout(), time.Minute)
diff --git a/runtimes/google/rt/signal_test.go b/runtimes/google/rt/signal_test.go
index df93748..2d819a9 100644
--- a/runtimes/google/rt/signal_test.go
+++ b/runtimes/google/rt/signal_test.go
@@ -73,7 +73,10 @@
}
func TestWithRuntime(t *testing.T) {
- sh := modules.NewShell()
+ 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("withRuntime", nil)
if err != nil {
@@ -90,7 +93,10 @@
}
func TestWithoutRuntime(t *testing.T) {
- sh := modules.NewShell()
+ 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("withoutRuntime", nil)
if err != nil {
diff --git a/services/mgmt/node/impl/util_test.go b/services/mgmt/node/impl/util_test.go
index 52e1af6..a720983 100644
--- a/services/mgmt/node/impl/util_test.go
+++ b/services/mgmt/node/impl/util_test.go
@@ -79,7 +79,10 @@
}
func createShellAndMountTable(t *testing.T) (*modules.Shell, func()) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
// The shell, will, by default share credentials with its children.
sh.ClearVar(consts.VeyronCredentials)
diff --git a/tools/naming/simulator/driver.go b/tools/naming/simulator/driver.go
index 7826391..01685f9 100644
--- a/tools/naming/simulator/driver.go
+++ b/tools/naming/simulator/driver.go
@@ -108,7 +108,11 @@
return
}
- shell := modules.NewShell()
+ shell, err := modules.NewShell(nil)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "unexpected error: %s\n", err)
+ os.Exit(1)
+ }
defer shell.Cleanup(os.Stderr, os.Stderr)
scanner := bufio.NewScanner(os.Stdin)
diff --git a/tools/naming/simulator/driver_test.go b/tools/naming/simulator/driver_test.go
index d4dac88..5ccb5cb 100644
--- a/tools/naming/simulator/driver_test.go
+++ b/tools/naming/simulator/driver_test.go
@@ -40,7 +40,10 @@
}
func TestVariables(t *testing.T) {
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
sh.SetVar("foo", "bar")
cases := []struct {
input string
diff --git a/tools/servicerunner/main.go b/tools/servicerunner/main.go
index 861592c..2e8560e 100644
--- a/tools/servicerunner/main.go
+++ b/tools/servicerunner/main.go
@@ -64,7 +64,10 @@
vars := map[string]string{}
- sh := modules.NewShell()
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ panic(fmt.Sprintf("modules.NewShell: %s", err))
+ }
defer sh.Cleanup(os.Stderr, os.Stderr)
v, ok := sh.GetVar(consts.VeyronCredentials)
if !ok {