// build +linux
package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"strings"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/integration-cli/checker"
	"github.com/docker/docker/integration-cli/cli"
	"github.com/go-check/check"
	"golang.org/x/net/context"
)

/* testIpcCheckDevExists checks whether a given mount (identified by its
 * major:minor pair from /proc/self/mountinfo) exists on the host system.
 *
 * The format of /proc/self/mountinfo is like:
 *
 * 29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw
 *       ^^^^\
 *            - this is the minor:major we look for
 */
func testIpcCheckDevExists(mm string) (bool, error) {
	f, err := os.Open("/proc/self/mountinfo")
	if err != nil {
		return false, err
	}
	defer f.Close()

	s := bufio.NewScanner(f)
	for s.Scan() {
		fields := strings.Fields(s.Text())
		if len(fields) < 7 {
			continue
		}
		if fields[2] == mm {
			return true, nil
		}
	}

	return false, s.Err()
}

// testIpcNonePrivateShareable is a helper function to test "none",
// "private" and "shareable" modes.
func testIpcNonePrivateShareable(c *check.C, mode string, mustBeMounted bool, mustBeShared bool) {
	cfg := container.Config{
		Image: "busybox",
		Cmd:   []string{"top"},
	}
	hostCfg := container.HostConfig{
		IpcMode: container.IpcMode(mode),
	}
	ctx := context.Background()

	client := testEnv.APIClient()

	resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
	c.Assert(err, checker.IsNil)
	c.Assert(len(resp.Warnings), checker.Equals, 0)

	err = client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
	c.Assert(err, checker.IsNil)

	// get major:minor pair for /dev/shm from container's /proc/self/mountinfo
	cmd := "awk '($5 == \"/dev/shm\") {printf $3}' /proc/self/mountinfo"
	mm := cli.DockerCmd(c, "exec", "-i", resp.ID, "sh", "-c", cmd).Combined()
	if !mustBeMounted {
		c.Assert(mm, checker.Equals, "")
		// no more checks to perform
		return
	}
	c.Assert(mm, checker.Matches, "^[0-9]+:[0-9]+$")

	shared, err := testIpcCheckDevExists(mm)
	c.Assert(err, checker.IsNil)
	c.Logf("[testIpcPrivateShareable] ipcmode: %v, ipcdev: %v, shared: %v, mustBeShared: %v\n", mode, mm, shared, mustBeShared)
	c.Assert(shared, checker.Equals, mustBeShared)
}

/* TestAPIIpcModeNone checks the container "none" IPC mode
 * (--ipc none) works as expected. It makes sure there is no
 * /dev/shm mount inside the container.
 */
func (s *DockerSuite) TestAPIIpcModeNone(c *check.C) {
	testRequires(c, DaemonIsLinux)
	testIpcNonePrivateShareable(c, "none", false, false)
}

/* TestAPIIpcModePrivate checks the container private IPC mode
 * (--ipc private) works as expected. It gets the minor:major pair
 * of /dev/shm mount from the container, and makes sure there is no
 * such pair on the host.
 */
func (s *DockerSuite) TestAPIIpcModePrivate(c *check.C) {
	testRequires(c, DaemonIsLinux, SameHostDaemon)
	testIpcNonePrivateShareable(c, "private", true, false)
}

/* TestAPIIpcModeShareable checks the container shareable IPC mode
 * (--ipc shareable) works as expected. It gets the minor:major pair
 * of /dev/shm mount from the container, and makes sure such pair
 * also exists on the host.
 */
func (s *DockerSuite) TestAPIIpcModeShareable(c *check.C) {
	testRequires(c, DaemonIsLinux, SameHostDaemon)
	testIpcNonePrivateShareable(c, "shareable", true, true)
}

// testIpcContainer is a helper function to test --ipc container:NNN mode in various scenarios
func testIpcContainer(s *DockerSuite, c *check.C, donorMode string, mustWork bool) {
	cfg := container.Config{
		Image: "busybox",
		Cmd:   []string{"top"},
	}
	hostCfg := container.HostConfig{
		IpcMode: container.IpcMode(donorMode),
	}
	ctx := context.Background()

	client := testEnv.APIClient()

	// create and start the "donor" container
	resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
	c.Assert(err, checker.IsNil)
	c.Assert(len(resp.Warnings), checker.Equals, 0)
	name1 := resp.ID

	err = client.ContainerStart(ctx, name1, types.ContainerStartOptions{})
	c.Assert(err, checker.IsNil)

	// create and start the second container
	hostCfg.IpcMode = container.IpcMode("container:" + name1)
	resp, err = client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
	c.Assert(err, checker.IsNil)
	c.Assert(len(resp.Warnings), checker.Equals, 0)
	name2 := resp.ID

	err = client.ContainerStart(ctx, name2, types.ContainerStartOptions{})
	if !mustWork {
		// start should fail with a specific error
		c.Assert(err, checker.NotNil)
		c.Assert(fmt.Sprintf("%v", err), checker.Contains, "non-shareable IPC")
		// no more checks to perform here
		return
	}

	// start should succeed
	c.Assert(err, checker.IsNil)

	// check that IPC is shared
	// 1. create a file in the first container
	cli.DockerCmd(c, "exec", name1, "sh", "-c", "printf covfefe > /dev/shm/bar")
	// 2. check it's the same file in the second one
	out := cli.DockerCmd(c, "exec", "-i", name2, "cat", "/dev/shm/bar").Combined()
	c.Assert(out, checker.Matches, "^covfefe$")
}

/* TestAPIIpcModeShareableAndContainer checks that a container created with
 * --ipc container:ID can use IPC of another shareable container.
 */
func (s *DockerSuite) TestAPIIpcModeShareableAndContainer(c *check.C) {
	testRequires(c, DaemonIsLinux)
	testIpcContainer(s, c, "shareable", true)
}

/* TestAPIIpcModePrivateAndContainer checks that a container created with
 * --ipc container:ID can NOT use IPC of another private container.
 */
func (s *DockerSuite) TestAPIIpcModePrivateAndContainer(c *check.C) {
	testRequires(c, DaemonIsLinux)
	testIpcContainer(s, c, "private", false)
}

/* TestAPIIpcModeHost checks that a container created with --ipc host
 * can use IPC of the host system.
 */
func (s *DockerSuite) TestAPIIpcModeHost(c *check.C) {
	testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace)

	cfg := container.Config{
		Image: "busybox",
		Cmd:   []string{"top"},
	}
	hostCfg := container.HostConfig{
		IpcMode: container.IpcMode("host"),
	}
	ctx := context.Background()

	client := testEnv.APIClient()
	resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
	c.Assert(err, checker.IsNil)
	c.Assert(len(resp.Warnings), checker.Equals, 0)
	name := resp.ID

	err = client.ContainerStart(ctx, name, types.ContainerStartOptions{})
	c.Assert(err, checker.IsNil)

	// check that IPC is shared
	// 1. create a file inside container
	cli.DockerCmd(c, "exec", name, "sh", "-c", "printf covfefe > /dev/shm/."+name)
	// 2. check it's the same on the host
	bytes, err := ioutil.ReadFile("/dev/shm/." + name)
	c.Assert(err, checker.IsNil)
	c.Assert(string(bytes), checker.Matches, "^covfefe$")
	// 3. clean up
	cli.DockerCmd(c, "exec", name, "rm", "-f", "/dev/shm/."+name)
}
