summaryrefslogtreecommitdiffhomepage
path: root/runsc
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2019-09-16 08:15:40 -0700
committergVisor bot <gvisor-bot@google.com>2019-09-16 08:17:00 -0700
commit010b0932583711ab3f6a88b1136cf8d87c2a53d2 (patch)
tree5d97437e3f7c03918071a677fe02893f0cc7d76e /runsc
parent239a07aabfad8991556b43c85c30270d09353f86 (diff)
Bring back to life features lost in recent refactor
- Sandbox logs are generated when running tests - Kokoro uploads the sandbox logs - Supports multiple parallel runs - Revive script to install locally built runsc with docker PiperOrigin-RevId: 269337274
Diffstat (limited to 'runsc')
-rw-r--r--runsc/boot/config.go26
-rw-r--r--runsc/container/container.go9
-rw-r--r--runsc/dockerutil/dockerutil.go15
-rw-r--r--runsc/main.go4
-rw-r--r--runsc/sandbox/sandbox.go10
-rw-r--r--runsc/specutils/specutils.go16
6 files changed, 64 insertions, 16 deletions
diff --git a/runsc/boot/config.go b/runsc/boot/config.go
index 05b8f8761..31103367d 100644
--- a/runsc/boot/config.go
+++ b/runsc/boot/config.go
@@ -211,12 +211,6 @@ type Config struct {
// RestoreFile is the path to the saved container image
RestoreFile string
- // TestOnlyAllowRunAsCurrentUserWithoutChroot should only be used in
- // tests. It allows runsc to start the sandbox process as the current
- // user, and without chrooting the sandbox process. This can be
- // necessary in test environments that have limited capabilities.
- TestOnlyAllowRunAsCurrentUserWithoutChroot bool
-
// NumNetworkChannels controls the number of AF_PACKET sockets that map
// to the same underlying network device. This allows netstack to better
// scale for high throughput use cases.
@@ -233,6 +227,19 @@ type Config struct {
// ReferenceLeakMode sets reference leak check mode
ReferenceLeakMode refs.LeakMode
+
+ // TestOnlyAllowRunAsCurrentUserWithoutChroot should only be used in
+ // tests. It allows runsc to start the sandbox process as the current
+ // user, and without chrooting the sandbox process. This can be
+ // necessary in test environments that have limited capabilities.
+ TestOnlyAllowRunAsCurrentUserWithoutChroot bool
+
+ // TestOnlyTestNameEnv should only be used in tests. It looks up for the
+ // test name in the container environment variables and adds it to the debug
+ // log file name. This is done to help identify the log with the test when
+ // multiple tests are run in parallel, since there is no way to pass
+ // parameters to the runtime from docker.
+ TestOnlyTestNameEnv string
}
// ToFlags returns a slice of flags that correspond to the given Config.
@@ -261,9 +268,12 @@ func (c *Config) ToFlags() []string {
"--alsologtostderr=" + strconv.FormatBool(c.AlsoLogToStderr),
"--ref-leak-mode=" + refsLeakModeToString(c.ReferenceLeakMode),
}
+ // Only include these if set since it is never to be used by users.
if c.TestOnlyAllowRunAsCurrentUserWithoutChroot {
- // Only include if set since it is never to be used by users.
- f = append(f, "-TESTONLY-unsafe-nonroot=true")
+ f = append(f, "--TESTONLY-unsafe-nonroot=true")
+ }
+ if len(c.TestOnlyTestNameEnv) != 0 {
+ f = append(f, "--TESTONLY-test-name-env="+c.TestOnlyTestNameEnv)
}
return f
}
diff --git a/runsc/container/container.go b/runsc/container/container.go
index 00f1b1de9..a721c1c31 100644
--- a/runsc/container/container.go
+++ b/runsc/container/container.go
@@ -946,7 +946,14 @@ func (c *Container) createGoferProcess(spec *specs.Spec, conf *boot.Config, bund
}
if conf.DebugLog != "" {
- debugLogFile, err := specutils.DebugLogFile(conf.DebugLog, "gofer")
+ test := ""
+ if len(conf.TestOnlyTestNameEnv) != 0 {
+ // Fetch test name if one is provided and the test only flag was set.
+ if t, ok := specutils.EnvVar(spec.Process.Env, conf.TestOnlyTestNameEnv); ok {
+ test = t
+ }
+ }
+ debugLogFile, err := specutils.DebugLogFile(conf.DebugLog, "gofer", test)
if err != nil {
return nil, nil, fmt.Errorf("opening debug log file in %q: %v", conf.DebugLog, err)
}
diff --git a/runsc/dockerutil/dockerutil.go b/runsc/dockerutil/dockerutil.go
index 41f5fe1e8..c073d8f75 100644
--- a/runsc/dockerutil/dockerutil.go
+++ b/runsc/dockerutil/dockerutil.go
@@ -240,7 +240,7 @@ func (d *Docker) Stop() error {
// Run calls 'docker run' with the arguments provided. The container starts
// running in the background and the call returns immediately.
func (d *Docker) Run(args ...string) error {
- a := []string{"run", "--runtime", d.Runtime, "--name", d.Name, "-d"}
+ a := d.runArgs("-d")
a = append(a, args...)
_, err := do(a...)
if err == nil {
@@ -251,7 +251,7 @@ func (d *Docker) Run(args ...string) error {
// RunWithPty is like Run but with an attached pty.
func (d *Docker) RunWithPty(args ...string) (*exec.Cmd, *os.File, error) {
- a := []string{"run", "--runtime", d.Runtime, "--name", d.Name, "-it"}
+ a := d.runArgs("-it")
a = append(a, args...)
return doWithPty(a...)
}
@@ -259,8 +259,7 @@ func (d *Docker) RunWithPty(args ...string) (*exec.Cmd, *os.File, error) {
// RunFg calls 'docker run' with the arguments provided in the foreground. It
// blocks until the container exits and returns the output.
func (d *Docker) RunFg(args ...string) (string, error) {
- a := []string{"run", "--runtime", d.Runtime, "--name", d.Name}
- a = append(a, args...)
+ a := d.runArgs(args...)
out, err := do(a...)
if err == nil {
d.logDockerID()
@@ -268,6 +267,14 @@ func (d *Docker) RunFg(args ...string) (string, error) {
return string(out), err
}
+func (d *Docker) runArgs(args ...string) []string {
+ // Environment variable RUNSC_TEST_NAME is picked up by the runtime and added
+ // to the log name, so one can easily identify the corresponding logs for
+ // this test.
+ rv := []string{"run", "--runtime", d.Runtime, "--name", d.Name, "-e", "RUNSC_TEST_NAME=" + d.Name}
+ return append(rv, args...)
+}
+
// Logs calls 'docker logs'.
func (d *Docker) Logs() (string, error) {
return do("logs", d.Name)
diff --git a/runsc/main.go b/runsc/main.go
index 0ff68160d..ff74c0a3d 100644
--- a/runsc/main.go
+++ b/runsc/main.go
@@ -79,6 +79,7 @@ var (
// Test flags, not to be used outside tests, ever.
testOnlyAllowRunAsCurrentUserWithoutChroot = flag.Bool("TESTONLY-unsafe-nonroot", false, "TEST ONLY; do not ever use! This skips many security measures that isolate the host from the sandbox.")
+ testOnlyTestNameEnv = flag.String("TESTONLY-test-name-env", "", "TEST ONLY; do not ever use! Used for automated tests to improve logging.")
)
func main() {
@@ -211,6 +212,7 @@ func main() {
ReferenceLeakMode: refsLeakMode,
TestOnlyAllowRunAsCurrentUserWithoutChroot: *testOnlyAllowRunAsCurrentUserWithoutChroot,
+ TestOnlyTestNameEnv: *testOnlyTestNameEnv,
}
if len(*straceSyscalls) != 0 {
conf.StraceSyscalls = strings.Split(*straceSyscalls, ",")
@@ -244,7 +246,7 @@ func main() {
e = newEmitter(*debugLogFormat, f)
} else if *debugLog != "" {
- f, err := specutils.DebugLogFile(*debugLog, subcommand)
+ f, err := specutils.DebugLogFile(*debugLog, subcommand, "" /* name */)
if err != nil {
cmd.Fatalf("error opening debug log file in %q: %v", *debugLog, err)
}
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index df3c0c5ef..4c6c83fbd 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -351,7 +351,15 @@ func (s *Sandbox) createSandboxProcess(conf *boot.Config, args *Args, startSyncF
nextFD++
}
if conf.DebugLog != "" {
- debugLogFile, err := specutils.DebugLogFile(conf.DebugLog, "boot")
+ test := ""
+ if len(conf.TestOnlyTestNameEnv) == 0 {
+ // Fetch test name if one is provided and the test only flag was set.
+ if t, ok := specutils.EnvVar(args.Spec.Process.Env, conf.TestOnlyTestNameEnv); ok {
+ test = t
+ }
+ }
+
+ debugLogFile, err := specutils.DebugLogFile(conf.DebugLog, "boot", test)
if err != nil {
return fmt.Errorf("opening debug log file in %q: %v", conf.DebugLog, err)
}
diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go
index df435f88d..cb9e58dfb 100644
--- a/runsc/specutils/specutils.go
+++ b/runsc/specutils/specutils.go
@@ -399,13 +399,15 @@ func WaitForReady(pid int, timeout time.Duration, ready func() (bool, error)) er
// - %TIMESTAMP%: is replaced with a timestamp using the following format:
// <yyyymmdd-hhmmss.uuuuuu>
// - %COMMAND%: is replaced with 'command'
-func DebugLogFile(logPattern, command string) (*os.File, error) {
+// - %TEST%: is replaced with 'test' (omitted by default)
+func DebugLogFile(logPattern, command, test string) (*os.File, error) {
if strings.HasSuffix(logPattern, "/") {
// Default format: <debug-log>/runsc.log.<yyyymmdd-hhmmss.uuuuuu>.<command>
logPattern += "runsc.log.%TIMESTAMP%.%COMMAND%"
}
logPattern = strings.Replace(logPattern, "%TIMESTAMP%", time.Now().Format("20060102-150405.000000"), -1)
logPattern = strings.Replace(logPattern, "%COMMAND%", command, -1)
+ logPattern = strings.Replace(logPattern, "%TEST%", test, -1)
dir := filepath.Dir(logPattern)
if err := os.MkdirAll(dir, 0775); err != nil {
@@ -542,3 +544,15 @@ func GetParentPid(pid int) (int, error) {
return ppid, nil
}
+
+// EnvVar looks for a varible value in the env slice assuming the following
+// format: "NAME=VALUE".
+func EnvVar(env []string, name string) (string, bool) {
+ prefix := name + "="
+ for _, e := range env {
+ if strings.HasPrefix(e, prefix) {
+ return strings.TrimPrefix(e, prefix), true
+ }
+ }
+ return "", false
+}