Пример #1
0
// TestProcFSRestrictions checks that access to sensitive paths under
// /proc and /sys is correctly restricted:
// https://github.com/coreos/rkt/issues/2484
func TestProcFSRestrictions(t *testing.T) {
	// check access to read-only paths
	roEntry := "/proc/sysrq-trigger"
	testContent := "h"
	roImage := patchTestACI("rkt-inspect-write-procfs.aci", fmt.Sprintf("--exec=/inspect --write-file --file-name %s --content %s", roEntry, testContent))
	defer os.Remove(roImage)

	roCtx := testutils.NewRktRunCtx()
	defer roCtx.Cleanup()

	roCmd := fmt.Sprintf("%s --insecure-options=image run %s", roCtx.Cmd(), roImage)

	roExpectedLine := fmt.Sprintf("Cannot write to file \"%s\"", roEntry)
	runRktAndCheckOutput(t, roCmd, roExpectedLine, true)

	// check access to inaccessible paths
	hiddenEntry := "/sys/firmware/"
	hiddenImage := patchTestACI("rkt-inspect-stat-procfs.aci", fmt.Sprintf("--exec=/inspect --stat-file --file-name %s", hiddenEntry))
	defer os.Remove(hiddenImage)

	hiddenCtx := testutils.NewRktRunCtx()
	defer hiddenCtx.Cleanup()

	hiddenCmd := fmt.Sprintf("%s --insecure-options=image run %s", hiddenCtx.Cmd(), hiddenImage)

	hiddenExpectedLine := fmt.Sprintf("%s: mode: d---------", hiddenEntry)
	runRktAndCheckOutput(t, hiddenCmd, hiddenExpectedLine, false)
}
Пример #2
0
func testFetchNoStore(t *testing.T, args string, image string, imageArgs string, finalURL string) {
	remoteFetchMsgTpl := `remote fetching from URL %q`
	remoteFetchMsg := fmt.Sprintf(remoteFetchMsgTpl, finalURL)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	if _, err := importImageAndFetchHash(t, ctx, "", image); err != nil {
		t.Skip(fmt.Sprintf("%v, probably a network failure. Skipping...", err))
	}

	cmd := fmt.Sprintf("%s --no-store %s %s %s", ctx.Cmd(), args, image, imageArgs)

	// 1. Run cmd with the image available in the store, should get $remoteFetchMsg.
	err := runRktAndCheckRegexOutput(t, cmd, remoteFetchMsg)
	status, _ := common.GetExitStatus(err)
	if status != 0 {
		t.Logf("%v", err)
		t.Skip("remote fetching failed, probably a network failure. Skipping...")
	}

	if err != nil {
		t.Fatalf("%q should be found: %v", remoteFetchMsg, err)
	}
}
Пример #3
0
func testFetchDefault(t *testing.T, arg string, image string, imageArgs string, finalURL string) {
	remoteFetchMsgTpl := `remote fetching from URL %q`
	storeMsgTpl := `using image from local store for .* %s`
	if finalURL == "" {
		finalURL = image
	}
	remoteFetchMsg := fmt.Sprintf(remoteFetchMsgTpl, finalURL)
	storeMsg := fmt.Sprintf(storeMsgTpl, image)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	cmd := fmt.Sprintf("%s %s %s %s", ctx.Cmd(), arg, image, imageArgs)

	// 1. Run cmd with the image not available in the store, should get $remoteFetchMsg.
	err := runRktAndCheckRegexOutput(t, cmd, remoteFetchMsg)
	status, _ := common.GetExitStatus(err)
	if status != 0 {
		t.Logf("%v", err)
		t.Skip("remote fetching failed, probably a network failure. Skipping...")
	}

	// 2. Run cmd with the image available in the store, should get $storeMsg.
	runRktAndCheckRegexOutput(t, cmd, storeMsg)
}
Пример #4
0
// Check that "enter" is able to wait for the ppid file to be created
func TestPidFileDelayedStart(t *testing.T) {
	sleepImage := patchTestACI("rkt-inspect-sleep.aci", "--exec=/inspect --read-stdin")
	defer os.Remove(sleepImage)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	runChild, enterChild, pidFileName, pidFileNameBackup := preparePidFileRace(t, ctx, sleepImage)

	// Restore ppid file so the "enter" command can find it
	if err := os.Rename(pidFileNameBackup, pidFileName); err != nil {
		t.Fatalf("Cannot restore ppid file: %v", err)
	}

	// Now the "enter" command works and can complete
	if err := expectWithOutput(enterChild, "RktEnterWorksFine"); err != nil {
		t.Fatalf("Waited for enter to works but failed: %v", err)
	}
	if err := enterChild.Wait(); err != nil {
		t.Fatalf("rkt enter didn't terminate correctly: %v", err)
	}

	// Terminate the pod
	if err := runChild.SendLine("Bye"); err != nil {
		t.Fatalf("rkt couldn't write to the container: %v", err)
	}
	if err := expectWithOutput(runChild, "Received text: Bye"); err != nil {
		t.Fatalf("Expected Bye but not found: %v", err)
	}
	if err := runChild.Wait(); err != nil {
		t.Fatalf("rkt didn't terminate correctly: %v", err)
	}
}
Пример #5
0
// Check that "enter" doesn't wait forever for the ppid file when the pod is terminated
func TestPidFileAbortedStart(t *testing.T) {
	sleepImage := patchTestACI("rkt-inspect-sleep.aci", "--exec=/inspect --read-stdin")
	defer os.Remove(sleepImage)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	runChild, enterChild, _, _ := preparePidFileRace(t, ctx, sleepImage)

	// Terminate the pod with the escape sequence: ^]^]^]
	if err := runChild.SendLine("\035\035\035"); err != nil {
		t.Fatalf("Failed to terminate the pod: %v", err)
	}
	waitOrFail(t, runChild, 1)

	// Now the "enter" command terminates quickly
	before := time.Now()
	if err := enterChild.Wait(); err.Error() != "exit status 1" {
		t.Fatalf("rkt enter didn't terminate as expected: %v", err)
	}
	delay := time.Now().Sub(before)
	t.Logf("rkt enter terminated %v after the pod was terminated", delay)
	if delay > time.Second { // 1 second shall be enough: it takes less than 50ms on my computer
		t.Fatalf("rkt enter didn't terminate quickly enough: %v", delay)
	}

}
Пример #6
0
func TestAceValidator(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	if err := ctx.LaunchMDS(); err != nil {
		t.Fatalf("Cannot launch metadata service: %v", err)
	}

	aceMain := os.Getenv("RKT_ACE_MAIN_IMAGE")
	if aceMain == "" {
		panic("empty RKT_ACE_MAIN_IMAGE env var")
	}
	aceSidekick := os.Getenv("RKT_ACE_SIDEKICK_IMAGE")
	if aceSidekick == "" {
		panic("empty RKT_ACE_SIDEKICK_IMAGE env var")
	}

	rktArgs := fmt.Sprintf("--debug --insecure-skip-verify run --mds-register --volume database,kind=empty %s %s",
		aceMain, aceSidekick)
	rktCmd := fmt.Sprintf("%s %s", ctx.Cmd(), rktArgs)

	child := spawnOrFail(t, rktCmd)
	defer waitOrFail(t, child, true)

	for _, e := range expectedResults {
		if err := expectWithOutput(child, e); err != nil {
			t.Fatalf("Expected %q but not found: %v", e, err)
		}
	}
}
Пример #7
0
func TestAPIServiceGetInfo(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	svc := startAPIService(t, ctx)
	defer stopAPIService(t, svc)

	c, conn := newAPIClientOrFail(t, "localhost:15441")
	defer conn.Close()

	resp, err := c.GetInfo(context.Background(), &v1alpha.GetInfoRequest{})
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	expectedAPIVersion := "1.0.0-alpha"
	if resp.Info.ApiVersion != expectedAPIVersion {
		t.Errorf("Expected api version to be %q, but saw %q", expectedAPIVersion, resp.Info.ApiVersion)
	}

	expectedGlobalFlags := &v1alpha.GlobalFlags{
		Dir:             ctx.DataDir(),
		SystemConfigDir: ctx.SystemDir(),
		LocalConfigDir:  ctx.LocalDir(),
		UserConfigDir:   ctx.UserDir(),
		InsecureFlags:   "none",
	}
	if !reflect.DeepEqual(resp.Info.GlobalFlags, expectedGlobalFlags) {
		t.Errorf("Expected global flags to be %v, but saw %v", expectedGlobalFlags, resp.Info.GlobalFlags)
	}
}
Пример #8
0
func TestAuthSanity(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()
	server := runServer(t, taas.None)
	defer server.Close()
	expectedRunRkt(ctx, t, server.URL, "sanity", authSuccessfulDownload)
}
Пример #9
0
// TestHostname test that the --hostname option works.
func TestHostname(t *testing.T) {
	imageFile := patchTestACI("rkt-inspect-hostname.aci", "--exec=/inspect --print-hostname")
	defer os.Remove(imageFile)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	tests := []struct {
		hostname string
	}{
		{
			"test-hostname",
		},
		{
			"",
		},
	}

	for _, tt := range tests {
		rktCmd := fmt.Sprintf("%s prepare --insecure-options=image %s", ctx.Cmd(), imageFile)
		uuid := runRktAndGetUUID(t, rktCmd)

		expectedHostname := "rkt-" + uuid
		hostnameParam := ""
		if tt.hostname != "" {
			expectedHostname = tt.hostname
			hostnameParam = fmt.Sprintf("--hostname=%s", tt.hostname)
		}

		rktCmd = fmt.Sprintf("%s run-prepared %s %s", ctx.Cmd(), hostnameParam, uuid)
		expected := fmt.Sprintf("Hostname: %s", expectedHostname)
		runRktAndCheckOutput(t, rktCmd, expected, false)
	}
}
Пример #10
0
func TestAuthOverride(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()
	server, image := runAuthServer(t, taas.AuthOauth)
	defer authCleanup(server, image)
	hash := "sha512-" + getHashOrPanic(image)
	tests := []struct {
		systemConfig         string
		localConfig          string
		name                 string
		resultBeforeOverride string
		resultAfterOverride  string
	}{
		{server.Conf, getInvalidOAuthConfig(server.Conf), "valid-system-invalid-local", authSuccessfulDownload, authFailedDownload},
		{getInvalidOAuthConfig(server.Conf), server.Conf, "invalid-system-valid-local", authFailedDownload, authSuccessfulDownload},
	}
	for _, tt := range tests {
		writeConfig(t, authDir(ctx.SystemDir()), "test.json", tt.systemConfig)
		expectedRunRkt(ctx, t, server.URL, tt.name+"-1", tt.resultBeforeOverride)
		if tt.resultBeforeOverride == authSuccessfulDownload {
			// Remove the image from the store since it was fetched in the
			// previous run and the test aci-server returns a
			// Cache-Control max-age header
			removeFromCas(t, ctx, hash)
		}
		writeConfig(t, authDir(ctx.LocalDir()), "test.json", tt.localConfig)
		expectedRunRkt(ctx, t, server.URL, tt.name+"-2", tt.resultAfterOverride)
		ctx.Reset()
	}
}
Пример #11
0
// TestPathsStat checks that access to inaccessible paths under
// /proc or /sys is correctly restricted:
// https://github.com/coreos/rkt/issues/2484
func TestPathsStat(t *testing.T) {
	tests := []struct {
		Path         string
		ExpectedMode string
	}{
		{
			Path:         "/sys/firmware",
			ExpectedMode: "d---------",
		},
		{
			Path:         "/proc/kcore",
			ExpectedMode: "----------",
		},
	}

	for _, tt := range tests {
		hiddenImage := patchTestACI("rkt-inspect-stat-procfs.aci", fmt.Sprintf("--exec=/inspect --stat-file --file-name %s", tt.Path))
		defer os.Remove(hiddenImage)

		hiddenCtx := testutils.NewRktRunCtx()
		defer hiddenCtx.Cleanup()

		//run
		hiddenCmd := fmt.Sprintf("%s --debug --insecure-options=image run %s", hiddenCtx.Cmd(), hiddenImage)
		hiddenExpectedLine := fmt.Sprintf("%s: mode: %s", tt.Path, tt.ExpectedMode)
		runRktAndCheckOutput(t, hiddenCmd, hiddenExpectedLine, false)
		// run-prepared
		hiddenCmd = fmt.Sprintf(`%s --insecure-options=image prepare %s`, hiddenCtx.Cmd(), hiddenImage)
		uuid := runRktAndGetUUID(t, hiddenCmd)
		hiddenCmd = fmt.Sprintf("%s --debug run-prepared --mds-register=false %s", hiddenCtx.Cmd(), uuid)
		runRktAndCheckOutput(t, hiddenCmd, hiddenExpectedLine, false)
	}
}
Пример #12
0
// TestHostDNS checks that --dns=host reflects the host's /etc/resolv.conf
func TestDNSHost(t *testing.T) {
	dat, err := ioutil.ReadFile("/etc/resolv.conf")
	if err != nil {
		t.Fatal("Could not read host's resolv.conf", err)
	}

	sum := fmt.Sprintf("%x", sha1.Sum(dat))
	t.Log("Expecting sum", sum)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	appCmd := "--exec=/inspect -- --hash-file"
	rktCmd := fmt.Sprintf("%s --insecure-options=image run --dns=host --set-env=FILE=/etc/resolv.conf %s %s",
		ctx.Cmd(), getInspectImagePath(), appCmd)

	child := spawnOrFail(t, rktCmd)
	ctx.RegisterChild(child)
	defer waitOrFail(t, child, 0)

	expectedRegex := `sha1sum: ([0-9a-f]+)`
	result, out, err := expectRegexTimeoutWithOutput(child, expectedRegex, 30*time.Second)
	if err != nil {
		t.Fatalf("Error: %v\nOutput: %v", err, out)
	}

	if result[1] != sum {
		t.Fatalf("container's /etc/host has sha1sum %s expected %s", result[1], sum)
	}
}
Пример #13
0
func testFetchNoStore(t *testing.T, args string, image string, imageArgs string, finalURL string) {
	remoteFetchMsgTpl := `remote fetching from URL %q`
	remoteFetchMsg := fmt.Sprintf(remoteFetchMsgTpl, finalURL)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	if _, err := importImageAndFetchHash(t, ctx, "", image); err != nil {
		t.Skip(fmt.Sprintf("%v, probably a network failure. Skipping...", err))
	}

	cmd := fmt.Sprintf("%s --no-store %s %s %s", ctx.Cmd(), args, image, imageArgs)

	// 1. Run cmd with the image available in the store, should get $remoteFetchMsg.
	child := spawnOrFail(t, cmd)
	if err := expectWithOutput(child, remoteFetchMsg); err != nil {
		t.Fatalf("%q should be found: %v", remoteFetchMsg, err)
	}
	err := child.Wait()
	status := getExitStatus(err)
	if status != 0 {
		t.Logf("rkt terminated with unexpected status %d, expected %d\nOutput:\n%s", status, 0, child.Collect())
		t.Skip("remote fetching failed, probably a network failure. Skipping...")
	}
}
Пример #14
0
func TestRmCgroup(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	imagePath := getInspectImagePath()
	cmd := fmt.Sprintf("%s --insecure-options=image prepare %s", ctx.Cmd(), imagePath)
	uuid := runRktAndGetUUID(t, cmd)
	shortUUID := strings.Split(uuid, "-")[0]

	cmd = fmt.Sprintf("%s run-prepared %s", ctx.Cmd(), shortUUID)
	runRktAndCheckOutput(t, cmd, "", false)

	cgs, err := getPodCgroups(shortUUID)
	if err != nil {
		t.Fatalf("error getting pod cgroups: %v", err)
	}
	if len(cgs) == 0 {
		t.Fatalf("expected pod cgroup directories after run, but found none")
	}

	rmCmd := fmt.Sprintf("%s rm %s", ctx.Cmd(), shortUUID)
	spawnAndWaitOrFail(t, rmCmd, 0)

	cgs, err = getPodCgroups(shortUUID)
	if err != nil {
		t.Fatalf("error getting pod cgroups: %v", err)
	}
	if len(cgs) > 0 {
		t.Fatalf(fmt.Sprintf("expected no pod cgroup directories after GC, but found %d: %v", len(cgs), cgs))
	}
}
Пример #15
0
func TestAppIsolatorMemory(t *testing.T) {
	ok, err := cgroup.IsIsolatorSupported("memory")
	if err != nil {
		t.Fatalf("Error checking memory isolator support: %v", err)
	}
	if !ok {
		t.Skip("Memory isolator not supported.")
	}

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	t.Logf("Running test: %v", memoryTest.testName)

	aciFileName := patchTestACI("rkt-inspect-isolators.aci", memoryTest.aciBuildArgs...)
	defer os.Remove(aciFileName)

	rktCmd := fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s", ctx.Cmd(), aciFileName)
	expectedLine := "Memory Limit: " + strconv.Itoa(maxMemoryUsage)
	runRktAndCheckOutput(t, rktCmd, expectedLine, false)

	rktCmd = fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s --memory 42Mi", ctx.Cmd(), aciFileName)
	expectedLine = "Memory Limit: " + strconv.Itoa(42*1024*1024)
	runRktAndCheckOutput(t, rktCmd, expectedLine, false)
}
Пример #16
0
func testFetchDefault(t *testing.T, arg string, image string, imageArgs string, finalURL string) {
	remoteFetchMsgTpl := `remote fetching from URL %q`
	storeMsgTpl := `using image from local store for .* %s`
	if finalURL == "" {
		finalURL = image
	}
	remoteFetchMsg := fmt.Sprintf(remoteFetchMsgTpl, finalURL)
	storeMsg := fmt.Sprintf(storeMsgTpl, image)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	cmd := fmt.Sprintf("%s %s %s %s", ctx.Cmd(), arg, image, imageArgs)

	// 1. Run cmd with the image not available in the store, should get $remoteFetchMsg.
	child := spawnOrFail(t, cmd)
	err := expectWithOutput(child, remoteFetchMsg)
	if exitErr := checkExitStatus(child); exitErr != nil {
		t.Logf("%v", exitErr)
		t.Skip("remote fetching failed, probably a network failure. Skipping...")
	}
	if err != nil {
		t.Fatalf("%q should be found: %v", remoteFetchMsg, err)
	}

	// 2. Run cmd with the image available in the store, should get $storeMsg.
	runRktAndCheckRegexOutput(t, cmd, storeMsg)
}
Пример #17
0
func TestAppIsolatorCPU(t *testing.T) {
	isUnified, err := cgroup.IsCgroupUnified("/")
	if err != nil {
		t.Fatalf("Error determining the cgroup version: %v", err)
	}

	if isUnified {
		// TODO: for now kernel does not support cpu isolator in cgroup2.
		// Write a test when it does.
		t.Skip("kernel does not support cpu isolator in cgroup2.")
	}
	ok, err := cgroup.IsIsolatorSupported("cpu")
	if err != nil {
		t.Fatalf("Error checking cpu isolator support: %v", err)
	}
	if !ok {
		t.Skip("CPU isolator not supported.")
	}

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	t.Logf("Running test: %v", cpuTest.testName)

	aciFileName := patchTestACI("rkt-inspect-isolators.aci", cpuTest.aciBuildArgs...)
	defer os.Remove(aciFileName)

	rktCmd := fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s", ctx.Cmd(), aciFileName)
	expectedLine := "CPU Quota: " + strconv.Itoa(CPUQuota)
	runRktAndCheckOutput(t, rktCmd, expectedLine, false)

	rktCmd = fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s --cpu 900m", ctx.Cmd(), aciFileName)
	expectedLine = "CPU Quota: " + strconv.Itoa(900)
	runRktAndCheckOutput(t, rktCmd, expectedLine, false)
}
Пример #18
0
func TestAuthSanity(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()
	server, image := runAuthServer(t, taas.AuthNone)
	defer authCleanup(server, image)
	expectedRunRkt(ctx, t, server.URL, "sanity", authSuccessfulDownload)
}
Пример #19
0
func TestGC(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	imagePath := getInspectImagePath()
	// Finished pods.
	importImageAndRun(imagePath, t, ctx)

	// Prepared pods.
	importImageAndPrepare(imagePath, t, ctx)

	// Abort prepare.
	cmd := fmt.Sprintf("%s --insecure-options=image prepare %s %s", ctx.Cmd(), imagePath, imagePath)
	spawnAndWaitOrFail(t, cmd, 254)

	gcCmd := fmt.Sprintf("%s gc --mark-only=true --expire-prepared=0 --grace-period=0", ctx.Cmd())
	spawnAndWaitOrFail(t, gcCmd, 0)

	pods := podsRemaining(t, ctx)
	if len(pods) == 0 {
		t.Fatalf("pods should still be present in rkt's data directory")
	}

	gcCmd = fmt.Sprintf("%s gc --mark-only=false --expire-prepared=0 --grace-period=0", ctx.Cmd())
	spawnAndWaitOrFail(t, gcCmd, 0)

	pods = podsRemaining(t, ctx)
	if len(pods) != 0 {
		t.Fatalf("no pods should exist rkt's data directory, but found: %v", pods)
	}
}
Пример #20
0
func TestCapsNonRoot(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	for i, tt := range capsTests {
		args := []string{"--exec=/inspect --print-caps-pid=0 --print-user", "--user=9000", "--group=9000"}
		if tt.capIsolator != "" {
			args = append(args, "--capability="+tt.capIsolator)
		}
		fileName := patchTestACI("rkt-inspect-print-caps-nonroot.aci", args...)
		defer os.Remove(fileName)

		t.Logf("Running test #%v: %v [non-root]", i, tt.testName)

		cmd := fmt.Sprintf("%s --debug --insecure-options=image run --mds-register=false --set-env=CAPABILITY=%d %s", ctx.Cmd(), int(tt.capa), fileName)
		child := spawnOrFail(t, cmd)

		expectedLine := tt.capa.String()
		if tt.nonrootCapExpected {
			expectedLine += "=enabled"
		} else {
			expectedLine += "=disabled"
		}
		if err := expectWithOutput(child, expectedLine); err != nil {
			t.Fatalf("Expected %q but not found: %v", expectedLine, err)
		}

		if err := expectWithOutput(child, "User: uid=9000 euid=9000 gid=9000 egid=9000"); err != nil {
			t.Fatalf("Expected user 9000 but not found: %v", err)
		}

		waitOrFail(t, child, 0)
		ctx.Reset()
	}
}
Пример #21
0
func TestJournalLink(t *testing.T) {
	if !sd_util.IsRunningSystemd() {
		t.Skip("Systemd is not running on the host.")
	}

	if _, err := os.Stat(journalDir); os.IsNotExist(err) {
		t.Skip("Persistent journaling disabled.")
	}

	image := getInspectImagePath()

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	rktCmd := fmt.Sprintf("%s prepare --insecure-options=image %s", ctx.Cmd(), image)
	uuid := runRktAndGetUUID(t, rktCmd)

	rktCmd = fmt.Sprintf("%s run-prepared %s", ctx.Cmd(), uuid)
	spawnAndWaitOrFail(t, rktCmd, 0)

	machineID := strings.Replace(uuid, "-", "", -1)
	journalPath := filepath.Join("/var/log/journal", machineID)

	link, err := os.Readlink(journalPath)
	if err != nil {
		t.Fatalf("failed to read journal link %q", journalPath)
	}

	podJournal := filepath.Join(ctx.DataDir(), "pods/run", uuid, "stage1/rootfs/var/log/journal/", machineID)
	if link != podJournal {
		t.Fatalf("unexpected target of journal link: %q. Expected %q", link, podJournal)
	}
}
Пример #22
0
func TestFlyNetns(t *testing.T) {
	testImageArgs := []string{"--exec=/inspect --print-netns"}
	testImage := patchTestACI("rkt-inspect-stage1-fly.aci", testImageArgs...)
	defer os.Remove(testImage)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	cmd := fmt.Sprintf("%s --debug --insecure-options=image run %s", ctx.Cmd(), testImage)
	child := spawnOrFail(t, cmd)
	ctx.RegisterChild(child)
	defer waitOrFail(t, child, 0)

	expectedRegex := `NetNS: (net:\[\d+\])`
	result, out, err := expectRegexWithOutput(child, expectedRegex)
	if err != nil {
		t.Fatalf("Error: %v\nOutput: %v", err, out)
	}

	ns, err := os.Readlink("/proc/self/ns/net")
	if err != nil {
		t.Fatalf("Cannot evaluate NetNS symlink: %v", err)
	}

	if nsChanged := ns != result[1]; nsChanged {
		t.Fatalf("container left host netns")
	}
}
Пример #23
0
func TestCapsSeveralAppWithPatches(t *testing.T) {
	// All the following images are launched together in the same pod

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	for i, tt := range appCapsTests {
		patches := []string{
			fmt.Sprintf("--name=%s", tt.testName),
			fmt.Sprintf("--exec=/inspect --print-caps-pid=0 --suffix-msg=%s", tt.testName),
		}
		if tt.capRetainSet != "x" {
			patches = append(patches, "--capability="+tt.capRetainSet)
		}
		if tt.capRemoveSet != "x" {
			patches = append(patches, "--revoke-capability="+tt.capRemoveSet)
		}
		imageFile := patchTestACI(tt.testName+".aci", patches...)
		defer os.Remove(imageFile)
		appCapsTests[i].imageFile = imageFile
		t.Logf("Built image %q", imageFile)
	}

	// Generate the rkt arguments to launch all the apps in the same pod
	rktArgs := ""
	for _, tt := range appCapsTests {
		rktArgs += " " + tt.imageFile
	}
	cmd := fmt.Sprintf("%s --insecure-options=image run %s", ctx.Cmd(), rktArgs)

	capsSeveralAppsRunAndCheckOutput(t, ctx, cmd)
}
Пример #24
0
func TestImageRunRmDuplicate(t *testing.T) {
	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
	defer os.Remove(imageFile)
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	cmd := fmt.Sprintf("%s --insecure-options=image fetch %s", ctx.Cmd(), imageFile)
	t.Logf("Fetching %s", imageFile)
	spawnAndWaitOrFail(t, cmd, true)

	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
	cmd = fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s", ctx.Cmd(), referencedACI)
	t.Logf("Running %s", referencedACI)
	spawnAndWaitOrFail(t, cmd, true)

	t.Logf("Retrieving %s image ID", referencedApp)
	referencedImageID, err := getImageID(ctx, referencedApp)
	if err != nil {
		t.Fatalf("rkt didn't terminate correctly: %v", err)
	}

	t.Logf("Retrieving %s image ID", unreferencedApp)
	unreferencedImageID, err := getImageID(ctx, unreferencedApp)
	if err != nil {
		t.Fatalf("rkt didn't terminate correctly: %v", err)
	}

	t.Logf("Removing image for app %s (should work)", referencedApp)
	removeImage(t, ctx, referencedApp, referencedImageID)

	t.Logf("Removing image for app %s (should work)", unreferencedApp)
	removeImage(t, ctx, unreferencedImageID, unreferencedApp)
}
Пример #25
0
func TestImageRunRmName(t *testing.T) {
	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
	defer os.Remove(imageFile)
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	cmd := fmt.Sprintf("%s --insecure-options=image fetch %s", ctx.Cmd(), imageFile)
	spawnAndWaitOrFail(t, cmd, true)

	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
	cmd = fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s", ctx.Cmd(), referencedACI)
	spawnAndWaitOrFail(t, cmd, true)

	t.Logf("Retrieving stage1 image name")
	stage1ImageName := getImageName(t, ctx, stage1App)

	t.Logf("Removing stage1 image (should work)")
	removeImage(t, ctx, stage1ImageName)

	t.Logf("Removing image for app %s (should work)", referencedApp)
	removeImage(t, ctx, referencedApp)

	t.Logf("Removing image for app %s (should work)", unreferencedApp)
	removeImage(t, ctx, unreferencedApp)
}
Пример #26
0
func TestInteractive(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	for i, tt := range interactiveTests {
		t.Logf("Running test #%v: %v", i, tt.testName)

		aciFileName := patchTestACI("rkt-inspect-interactive.aci", tt.aciBuildArgs...)
		defer os.Remove(aciFileName)

		rktCmd := fmt.Sprintf("%s %s", ctx.Cmd(), tt.rktArgs)
		rktCmd = strings.Replace(rktCmd, "^INTERACTIVE^", aciFileName, -1)
		child := spawnOrFail(t, rktCmd)
		if tt.say != "" {
			if err := expectTimeoutWithOutput(child, "Enter text:", time.Minute); err != nil {
				t.Fatalf("Waited for the prompt but not found #%v: %v", i, err)
			}

			if err := child.SendLine(tt.say); err != nil {
				t.Fatalf("Failed to send %q on the prompt #%v: %v", tt.say, i, err)
			}
		}

		if err := expectTimeoutWithOutput(child, tt.expect, time.Minute); err != nil {
			t.Fatalf("Expected %q but not found #%v: %v", tt.expect, i, err)
		}

		if err := child.Wait(); err != nil {
			t.Fatalf("rkt didn't terminate correctly: %v", err)
		}
	}
}
Пример #27
0
/*
 * Default net
 * ---
 * Container must be in a separate network namespace
 */
func NewTestNetDefaultNetNS() testutils.Test {
	return testutils.TestFunc(func(t *testing.T) {
		testImageArgs := []string{"--exec=/inspect --print-netns"}
		testImage := patchTestACI("rkt-inspect-networking.aci", testImageArgs...)
		defer os.Remove(testImage)

		ctx := testutils.NewRktRunCtx()
		defer ctx.Cleanup()

		f := func(argument string) {
			cmd := fmt.Sprintf("%s --debug --insecure-options=image run %s --mds-register=false %s", ctx.Cmd(), argument, testImage)
			child := spawnOrFail(t, cmd)
			defer waitOrFail(t, child, 0)

			expectedRegex := `NetNS: (net:\[\d+\])`
			result, out, err := expectRegexWithOutput(child, expectedRegex)
			if err != nil {
				t.Fatalf("Error: %v\nOutput: %v", err, out)
			}

			ns, err := os.Readlink("/proc/self/ns/net")
			if err != nil {
				t.Fatalf("Cannot evaluate NetNS symlink: %v", err)
			}

			if nsChanged := ns != result[1]; !nsChanged {
				t.Fatalf("container did not leave host netns")
			}

		}
		f("--net=default")
		f("")
	})
}
Пример #28
0
/*
 * NewNetDefaultGWTest checks if default gateway is correct if only configured network is one provided by flannel.
 */
func NewNetDefaultGWTest() testutils.Test {
	return testutils.TestFunc(func(t *testing.T) {
		ctx := testutils.NewRktRunCtx()
		defer ctx.Cleanup()

		_, ntFlannel, err := mockFlannelNetwork(t, ctx)
		if err != nil {
			t.Errorf("Can't mock flannel network: %v", err)
		}

		defer os.Remove(ntFlannel.SubnetFile)

		testImageArgs := []string{"--exec=/inspect --print-defaultgwv4"}
		testImage := patchTestACI("rkt-inspect-networking.aci", testImageArgs...)
		defer os.Remove(testImage)

		cmd := fmt.Sprintf("%s --debug --insecure-options=image run --net=%s --mds-register=false %s", ctx.Cmd(), ntFlannel.Name, testImage)
		child := spawnOrFail(t, cmd)
		defer waitOrFail(t, child, 0)

		expectedRegex := `DefaultGWv4: (\d+\.\d+\.\d+\.\d+)`
		if _, out, err := expectRegexTimeoutWithOutput(child, expectedRegex, time.Minute); err != nil {
			t.Fatalf("No default gateway!\nError: %v\nOutput: %v", err, out)
		}
	})
}
Пример #29
0
/*
 * Pass the IP arg to the default networks, ensure it works
 */
func NewNetDefaultIPArgTest() testutils.Test {
	doTest := func(netArg, expectedIP string, t *testing.T) {
		ctx := testutils.NewRktRunCtx()
		defer ctx.Cleanup()

		appCmd := "--exec=/inspect -- --print-ipv4=eth0"
		cmd := fmt.Sprintf("%s --debug --insecure-options=image run --net=\"%s\" --mds-register=false %s %s",
			ctx.Cmd(), netArg, getInspectImagePath(), appCmd)
		child := spawnOrFail(t, cmd)
		defer waitOrFail(t, child, 0)

		expectedRegex := `IPv4: (\d+\.\d+\.\d+\.\d+)`
		result, out, err := expectRegexTimeoutWithOutput(child, expectedRegex, 30*time.Second)
		if err != nil {
			t.Fatalf("Error: %v\nOutput: %v", err, out)
			return
		}

		containerIP := result[1]
		if expectedIP != containerIP {
			t.Fatalf("--net=%s setting IP failed: Got %q but expected %q", netArg, containerIP, expectedIP)
		}
	}
	return testutils.TestFunc(func(t *testing.T) {
		doTest("default:IP=172.16.28.123", "172.16.28.123", t)
		doTest("default-restricted:IP=172.17.42.42", "172.17.42.42", t)
	})
}
Пример #30
0
func TestAPIServiceListInspectImages(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	svc := startAPIService(t, ctx)
	defer stopAPIService(t, svc)

	c, conn := newAPIClientOrFail(t, "localhost:15441")
	defer conn.Close()

	resp, err := c.ListImages(context.Background(), &v1alpha.ListImagesRequest{})
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	if len(resp.Images) != 0 {
		t.Errorf("Unexpected result: %v, should see zero images", resp.Images)
	}

	_, err = patchImportAndFetchHash("rkt-inspect-sleep.aci", []string{"--exec=/inspect"}, t, ctx)
	if err != nil {
		t.Fatalf("%v", err)
	}

	// ListImages(detail=false).
	resp, err = c.ListImages(context.Background(), &v1alpha.ListImagesRequest{})
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	if len(resp.Images) == 0 {
		t.Errorf("Unexpected result: %v, should see non-zero images", resp.Images)
	}

	for _, m := range resp.Images {
		checkImageBasics(t, ctx, m)

		// Test InspectImage().
		inspectResp, err := c.InspectImage(context.Background(), &v1alpha.InspectImageRequest{Id: m.Id})
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}
		checkImageDetails(t, ctx, inspectResp.Image)
	}

	// ListImages(detail=true).
	resp, err = c.ListImages(context.Background(), &v1alpha.ListImagesRequest{Detail: true})
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	if len(resp.Images) == 0 {
		t.Errorf("Unexpected result: %v, should see non-zero images", resp.Images)
	}

	for _, m := range resp.Images {
		checkImageDetails(t, ctx, m)
	}
}