Esempio n. 1
0
func (d *Driver) createNetwork(container *configs.Config, c *execdriver.Command, hooks execdriver.Hooks) error {
	if c.Network == nil {
		return nil
	}
	if c.Network.ContainerID != "" {
		d.Lock()
		active := d.activeContainers[c.Network.ContainerID]
		d.Unlock()

		if active == nil {
			return fmt.Errorf("%s is not a valid running container to join", c.Network.ContainerID)
		}

		state, err := active.State()
		if err != nil {
			return err
		}

		container.Namespaces.Add(configs.NEWNET, state.NamespacePaths[configs.NEWNET])
		return nil
	}

	if c.Network.NamespacePath != "" {
		container.Namespaces.Add(configs.NEWNET, c.Network.NamespacePath)
		return nil
	}
	// only set up prestart hook if the namespace path is not set (this should be
	// all cases *except* for --net=host shared networking)
	container.Hooks = &configs.Hooks{
		Prestart: []configs.Hook{
			configs.NewFunctionHook(func(s configs.HookState) error {
				if len(hooks.PreStart) > 0 {
					for _, fnHook := range hooks.PreStart {
						// A closed channel for OOM is returned here as it will be
						// non-blocking and return the correct result when read.
						chOOM := make(chan struct{})
						close(chOOM)
						if err := fnHook(&c.ProcessConfig, s.Pid, chOOM); err != nil {
							return err
						}
					}
				}
				return nil
			}),
		},
	}
	return nil
}
Esempio n. 2
0
func TestFuncHookRun(t *testing.T) {
	state := configs.HookState{
		Version: "1",
		ID:      "1",
		Pid:     1,
		Root:    "root",
	}

	fHook := configs.NewFunctionHook(func(s configs.HookState) error {
		if !reflect.DeepEqual(state, s) {
			t.Errorf("Expected state %+v to equal %+v", state, s)
		}
		return nil
	})

	fHook.Run(state)
}
Esempio n. 3
0
func TestMarshalHooksWithUnexpectedType(t *testing.T) {
	fHook := configs.NewFunctionHook(func(configs.HookState) error {
		return nil
	})
	hook := configs.Hooks{
		Prestart: []configs.Hook{fHook},
	}
	hooks, err := hook.MarshalJSON()
	if err != nil {
		t.Fatal(err)
	}

	h := `{"poststart":null,"poststop":null,"prestart":null}`
	if string(hooks) != h {
		t.Errorf("Expected hooks %s to equal %s", string(hooks), h)
	}
}
Esempio n. 4
0
func TestHook(t *testing.T) {
	if testing.Short() {
		return
	}
	root, err := newTestRoot()
	ok(t, err)
	defer os.RemoveAll(root)

	rootfs, err := newRootfs()
	ok(t, err)
	defer remove(rootfs)

	config := newTemplateConfig(rootfs)
	config.Hooks = &configs.Hooks{
		Prestart: []configs.Hook{
			configs.NewFunctionHook(func(s configs.HookState) error {
				f, err := os.Create(filepath.Join(s.Root, "test"))
				if err != nil {
					return err
				}
				return f.Close()
			}),
		},
		Poststop: []configs.Hook{
			configs.NewFunctionHook(func(s configs.HookState) error {
				return os.RemoveAll(filepath.Join(s.Root, "test"))
			}),
		},
	}
	container, err := factory.Create("test", config)
	ok(t, err)

	var stdout bytes.Buffer
	pconfig := libcontainer.Process{
		Args:   []string{"sh", "-c", "ls /test"},
		Env:    standardEnvironment,
		Stdin:  nil,
		Stdout: &stdout,
	}
	err = container.Start(&pconfig)
	ok(t, err)

	// Wait for process
	waitProcess(&pconfig, t)

	outputLs := string(stdout.Bytes())

	// Check that the ls output has the expected file touched by the prestart hook
	if !strings.Contains(outputLs, "/test") {
		container.Destroy()
		t.Fatalf("ls output doesn't have the expected file: %s", outputLs)
	}

	if err := container.Destroy(); err != nil {
		t.Fatalf("container destory %s", err)
	}
	fi, err := os.Stat(filepath.Join(rootfs, "test"))
	if err == nil || !os.IsNotExist(err) {
		t.Fatalf("expected file to not exist, got %s", fi.Name())
	}
}
Esempio n. 5
0
func TestHook(t *testing.T) {
	if testing.Short() {
		return
	}
	root, err := newTestRoot()
	ok(t, err)
	defer os.RemoveAll(root)

	rootfs, err := newRootfs()
	ok(t, err)
	defer remove(rootfs)

	config := newTemplateConfig(rootfs)
	expectedBundlePath := "/path/to/bundle/path"
	config.Labels = append(config.Labels, fmt.Sprintf("bundle=%s", expectedBundlePath))
	config.Hooks = &configs.Hooks{
		Prestart: []configs.Hook{
			configs.NewFunctionHook(func(s configs.HookState) error {
				if s.BundlePath != expectedBundlePath {
					t.Fatalf("Expected prestart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
				}

				f, err := os.Create(filepath.Join(s.Root, "test"))
				if err != nil {
					return err
				}
				return f.Close()
			}),
		},
		Poststart: []configs.Hook{
			configs.NewFunctionHook(func(s configs.HookState) error {
				if s.BundlePath != expectedBundlePath {
					t.Fatalf("Expected poststart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
				}

				return ioutil.WriteFile(filepath.Join(s.Root, "test"), []byte("hello world"), 0755)
			}),
		},
		Poststop: []configs.Hook{
			configs.NewFunctionHook(func(s configs.HookState) error {
				if s.BundlePath != expectedBundlePath {
					t.Fatalf("Expected poststop hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
				}

				return os.RemoveAll(filepath.Join(s.Root, "test"))
			}),
		},
	}
	container, err := factory.Create("test", config)
	ok(t, err)

	var stdout bytes.Buffer
	pconfig := libcontainer.Process{
		Cwd:    "/",
		Args:   []string{"sh", "-c", "ls /test"},
		Env:    standardEnvironment,
		Stdin:  nil,
		Stdout: &stdout,
	}
	err = container.Run(&pconfig)
	ok(t, err)

	// Wait for process
	waitProcess(&pconfig, t)

	outputLs := string(stdout.Bytes())

	// Check that the ls output has the expected file touched by the prestart hook
	if !strings.Contains(outputLs, "/test") {
		container.Destroy()
		t.Fatalf("ls output doesn't have the expected file: %s", outputLs)
	}

	// Check that the file is written by the poststart hook
	testFilePath := filepath.Join(rootfs, "test")
	contents, err := ioutil.ReadFile(testFilePath)
	if err != nil {
		t.Fatalf("cannot read file '%s': %s", testFilePath, err)
	}
	if string(contents) != "hello world" {
		t.Fatalf("Expected test file to contain 'hello world'; got '%s'", string(contents))
	}

	if err := container.Destroy(); err != nil {
		t.Fatalf("container destroy %s", err)
	}
	fi, err := os.Stat(filepath.Join(rootfs, "test"))
	if err == nil || !os.IsNotExist(err) {
		t.Fatalf("expected file to not exist, got %s", fi.Name())
	}
}