/
modules.go
177 lines (161 loc) · 5.71 KB
/
modules.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package utiltest
import (
"fmt"
"io"
"io/ioutil"
"os"
goexec "os/exec"
"strings"
"testing"
"v.io/v23"
"v.io/v23/rpc"
"v.io/x/lib/gosh"
"v.io/x/ref"
"v.io/x/ref/internal/logger"
"v.io/x/ref/lib/signals"
"v.io/x/ref/services/device/deviced/internal/starter"
"v.io/x/ref/services/device/deviced/internal/versioning"
"v.io/x/ref/services/device/internal/config"
"v.io/x/ref/services/device/internal/suid"
"v.io/x/ref/test"
"v.io/x/ref/test/v23test"
)
const (
RedirectEnv = "DEVICE_MANAGER_DONT_REDIRECT_STDOUT_STDERR"
TestEnvVarName = "V23_RANDOM_ENV_VALUE"
NoPairingToken = ""
)
// ExecScript launches the script passed as argument.
var ExecScript = gosh.RegisterFunc("ExecScript", func(script string) error {
osenv := []string{RedirectEnv + "=1"}
if os.Getenv("PAUSE_BEFORE_STOP") == "1" {
osenv = append(osenv, "PAUSE_BEFORE_STOP=1")
}
cmd := goexec.Cmd{
Path: script,
Env: osenv,
Stdin: os.Stdin,
Stderr: os.Stderr,
Stdout: os.Stdout,
}
return cmd.Run()
})
// DeviceManager sets up a device manager server. It accepts the name to
// publish the server under as an argument. Additional arguments can optionally
// specify device manager config settings.
var DeviceManager = gosh.RegisterFunc("DeviceManager", deviceManagerFunc)
func waitForEOF(r io.Reader) {
io.Copy(ioutil.Discard, r)
}
func deviceManagerFunc(publishName string, args ...string) error {
ctx, shutdown := test.V23Init()
defer shutdown()
defer fmt.Printf("%v terminated\n", publishName)
defer ctx.VI(1).Infof("%v terminated", publishName)
// Satisfy the contract described in doc.go by passing the config state
// through to the device manager dispatcher constructor.
configState, err := config.Load()
if err != nil {
ctx.Fatalf("Failed to decode config state: %v", err)
}
// This exemplifies how to override or set specific config fields, if,
// for example, the device manager is invoked 'by hand' instead of via a
// script prepared by a previous version of the device manager.
var pairingToken string
if len(args) > 0 {
if want, got := 4, len(args); want > got {
ctx.Fatalf("expected atleast %d additional arguments, got %d instead: %q", want, got, args)
}
configState.Root, configState.Helper, configState.Origin, configState.CurrentLink = args[0], args[1], args[2], args[3]
if len(args) > 4 {
pairingToken = args[4]
}
}
// We grab the shutdown channel at this point in order to ensure that we
// register a listener for the app cycle manager Stop before we start
// running the device manager service. Otherwise, any device manager
// method that calls Stop on the app cycle manager (e.g. the Stop RPC)
// will precipitate an immediate process exit.
shutdownChan := signals.ShutdownOnSignals(ctx)
listenSpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
blessings, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
claimableEps, stop, err := starter.Start(ctx, starter.Args{
Namespace: starter.NamespaceArgs{
ListenSpec: listenSpec,
},
Device: starter.DeviceArgs{
Name: publishName,
ListenSpec: listenSpec,
ConfigState: configState,
TestMode: strings.HasSuffix(fmt.Sprint(blessings), ":testdm"),
RestartCallback: func() { fmt.Println("restart handler") },
PairingToken: pairingToken,
},
// TODO(rthellend): Wire up the local mounttable like the real device
// manager, i.e. mount the device manager and the apps on it, and mount
// the local mounttable in the global namespace.
// MountGlobalNamespaceInLocalNamespace: true,
})
if err != nil {
ctx.Errorf("starter.Start failed: %v", err)
return err
}
defer stop()
// Update the namespace roots to remove the server blessing from the
// endpoints. This is needed to be able to publish into the 'global'
// mounttable before we have compatible credentials.
ctx, err = SetNamespaceRootsForUnclaimedDevice(ctx)
if err != nil {
return err
}
// Manually mount the claimable service in the 'global' mounttable.
for _, ep := range claimableEps {
v23.GetNamespace(ctx).Mount(ctx, "claimable", ep.Name(), 0)
}
fmt.Println("READY")
<-shutdownChan
if os.Getenv("PAUSE_BEFORE_STOP") == "1" {
waitForEOF(os.Stdin)
}
// TODO(ashankar): Figure out a way to incorporate this check in the test.
// if impl.DispatcherLeaking(dispatcher) {
// ctx.Fatalf("device manager leaking resources")
// }
return nil
}
// This is the same as DeviceManager above, except that it has a different major
// version number.
var DeviceManagerV10 = gosh.RegisterFunc("DeviceManagerV10", func(publishName string, args ...string) error {
versioning.CurrentVersion = versioning.Version{10, 0} // Set the version number to 10.0
return deviceManagerFunc(publishName, args...)
})
func DeviceManagerCmd(sh *v23test.Shell, f *gosh.Func, args ...interface{}) *v23test.Cmd {
dm := sh.FuncCmd(f, args...)
// Make sure the device manager command is not provided with credentials.
delete(dm.Vars, ref.EnvCredentials)
delete(dm.Vars, ref.EnvAgentPath)
return dm
}
func TestMainImpl(m *testing.M) {
isSuidHelper := len(os.Getenv("V23_SUIDHELPER_TEST")) > 0
if isSuidHelper {
os.Exit(m.Run())
}
v23test.TestMain(m)
}
// TestSuidHelper is testing boilerplate for suidhelper that does not
// create a runtime because the suidhelper is not a Vanadium application.
func TestSuidHelperImpl(t *testing.T) {
if os.Getenv("V23_SUIDHELPER_TEST") != "1" {
return
}
logger.Global().VI(1).Infof("TestSuidHelper starting")
if err := suid.Run(os.Environ()); err != nil {
logger.Global().Fatalf("Failed to Run() setuidhelper: %v", err)
}
// Don't show "PASS"
os.Exit(0)
}