Exemple #1
0
func (s *IntegrationTestSuite) TestLongContainerName(c *chk.C) {
	id, err := containers.NewIdentifier("IntTest006xxxxxxxxxxxxxx")
	c.Assert(err, chk.IsNil)
	s.containerIds = append(s.containerIds, id)

	hostContainerId := fmt.Sprintf("%v/%v", s.daemonURI, id)

	cmd := exec.Command("/usr/bin/gear", "install", TestImage, hostContainerId, "--start", "--ports=8080:4003", "--isolate")
	data, err := cmd.CombinedOutput()
	c.Log(string(data))
	c.Assert(err, chk.IsNil)
	s.assertContainerState(c, id, CONTAINER_STARTED)

	s.assertFilePresent(c, id.UnitPathFor(), 0664, true)
	s.assertFilePresent(c, filepath.Join(id.HomePath(), "container-init.sh"), 0700, false)

	ports, err := containers.GetExistingPorts(id)
	c.Assert(err, chk.IsNil)
	c.Assert(len(ports), chk.Equals, 1)

	t := time.NewTicker(time.Second / 10)
	defer t.Stop()
	select {
	case <-t.C:
		resp, err := http.Get(fmt.Sprintf("http://0.0.0.0:%v", ports[0].External))
		if err == nil {
			c.Assert(resp.StatusCode, chk.Equals, 200)
		}
	case <-time.After(time.Second * 15):
		c.Fail()
	}
}
Exemple #2
0
func (s *IntegrationTestSuite) TestStartStopContainer(c *chk.C) {
	id, err := containers.NewIdentifier("IntTest003")
	c.Assert(err, chk.IsNil)
	s.containerIds = append(s.containerIds, id)

	hostContainerId := fmt.Sprintf("%v/%v", s.daemonURI, id)

	cmd := exec.Command("/usr/bin/gear", "install", TestImage, hostContainerId, "--ports=8080:4001", "--isolate")
	data, err := cmd.CombinedOutput()
	c.Log(string(data))
	c.Assert(err, chk.IsNil)
	s.assertFilePresent(c, id.UnitPathFor(), 0664, true)

	cmd = exec.Command("/usr/bin/gear", "start", hostContainerId)
	data, err = cmd.CombinedOutput()
	c.Log(string(data))
	c.Assert(err, chk.IsNil)
	s.assertContainerState(c, id, CONTAINER_STARTED)
	s.assertFilePresent(c, filepath.Join(id.HomePath(), "container-init.sh"), 0700, false)

	ports, err := containers.GetExistingPorts(id)
	c.Assert(err, chk.IsNil)
	c.Assert(len(ports), chk.Equals, 1)

	resp, err := http.Get(fmt.Sprintf("http://0.0.0.0:%v", ports[0].External))
	c.Assert(err, chk.IsNil)
	c.Assert(resp.StatusCode, chk.Equals, 200)

	cmd = exec.Command("/usr/bin/gear", "stop", hostContainerId)
	data, err = cmd.CombinedOutput()
	c.Log(string(data))
	c.Assert(err, chk.IsNil)
	s.assertContainerState(c, id, CONTAINER_STOPPED)
}
Exemple #3
0
func (s *IntegrationTestSuite) TestSimpleInstallAndStartImage(c *chk.C) {
	id, err := containers.NewIdentifier("IntTest000")
	c.Assert(err, chk.IsNil)
	s.containerIds = append(s.containerIds, id)

	hostContainerId := fmt.Sprintf("%v/%v", s.daemonURI, id)

	cmd := exec.Command("/usr/bin/gear", "install", TestImage, hostContainerId)
	data, err := cmd.CombinedOutput()
	c.Log(string(data))
	c.Assert(err, chk.IsNil)
	s.assertContainerState(c, id, CONTAINER_STOPPED)

	s.assertFilePresent(c, id.UnitPathFor(), 0664, true)
	paths, err := filepath.Glob(id.VersionedUnitPathFor("*"))
	c.Assert(err, chk.IsNil)
	for _, p := range paths {
		s.assertFilePresent(c, p, 0664, true)
	}
	s.assertFileAbsent(c, filepath.Join(id.HomePath(), "container-init.sh"))

	ports, err := containers.GetExistingPorts(id)
	c.Assert(err, chk.IsNil)
	c.Assert(len(ports), chk.Equals, 0)

	cmd = exec.Command("/usr/bin/gear", "status", hostContainerId)
	data, err = cmd.CombinedOutput()
	c.Assert(err, chk.IsNil)
	c.Log(string(data))
	c.Assert(strings.Contains(string(data), "Loaded: loaded (/var/lib/containers/units/In/ctr-IntTest000.service; enabled)"), chk.Equals, true)
	s.assertContainerState(c, id, CONTAINER_STOPPED)
}
Exemple #4
0
func (s *IntegrationTestSuite) TestLongContainerName(c *chk.C) {
	id, err := containers.NewIdentifier("IntTest006xxxxxxxxxxxxxx")
	c.Assert(err, chk.IsNil)
	s.containerIds = append(s.containerIds, id)

	hostContainerId := fmt.Sprintf("%v/%v", s.daemonURI, id)

	cmd := exec.Command("/usr/bin/gear", "install", TestImage, hostContainerId, "--start", "--ports=8080:0", "--isolate")
	data, err := cmd.CombinedOutput()
	c.Log(string(data))
	c.Assert(err, chk.IsNil)
	s.assertContainerStarts(c, id)

	s.assertFilePresent(c, id.UnitPathFor(), 0664, true)
	s.assertFilePresent(c, filepath.Join(id.RunPathFor(), "container-init.sh"), 0700, false)

	ports, err := containers.GetExistingPorts(id)
	c.Assert(err, chk.IsNil)
	c.Assert(len(ports), chk.Equals, 1)

	httpAlive := func() bool {
		resp, err := http.Get(fmt.Sprintf("http://0.0.0.0:%v", ports[0].External))
		if err == nil {
			c.Assert(resp.StatusCode, chk.Equals, 200)
			return true
		}
		return false
	}
	if !until(TimeoutContainerStateChange, IntervalHttpCheck, httpAlive) {
		c.Errorf("Unable to retrieve a 200 status code from port %d", ports[0].External)
		c.FailNow()
	}
}
Exemple #5
0
func (j *ContainerPortsRequest) Execute(resp jobs.Response) {
	portPairs, err := containers.GetExistingPorts(j.Id)
	if err != nil {
		log.Printf("job_container_ports_log: Unable to find unit: %s\n", err.Error())
		resp.Failure(ErrContainerNotFound)
		return
	}

	resp.SuccessWithData(jobs.ResponseAccepted, ContainerPortsResponse{portPairs})
}
Exemple #6
0
func UnidleContainer(id containers.Identifier, hostIp string) {
	portPairs, err := containers.GetExistingPorts(id)
	if err != nil {
		fmt.Printf("UnidleContainer: Error retrieving ports for container: %v\n", id)
		return
	}

	for _, portPair := range portPairs {
		port := portPair.External
		runIptablesRules(false, true, hostIp, port.String(), id)
		runIptablesRules(false, true, localhost, port.String(), id)

		runIptablesRules(false, false, localhost, port.String(), id)
		runIptablesRules(true, false, localhost, port.String(), id)
	}
}
Exemple #7
0
func (idler *Idler) idleContainer(id containers.Identifier) bool {
	portPairs, err := containers.GetExistingPorts(id)
	if err != nil {
		fmt.Printf("idler.idleContainer: Error retrieving ports for container: %v\n", id)
		return false
	}

	iptablePorts, err := iptables.GetIdlerRules(id, false)
	if err != nil {
		fmt.Printf("idler.idleContainer: Error retrieving ports from iptables: %v\n", id)
		return false
	}

	shouldRecreateRules := false
	for _, portPair := range portPairs {
		extPort := strconv.Itoa(int(portPair.External))
		shouldRecreateRules = shouldRecreateRules || !iptablePorts[extPort]
	}

	if !shouldRecreateRules {
		return false
	}

	//TODO: Ask geard to idle container
	f, err := os.Create(id.IdleUnitPathFor())
	if err != nil {
		fmt.Printf("idler.idleContainer: Could not create idle marker for %s: %v", id.UnitNameFor(), err)
		return false
	}
	f.Close()
	if err := systemd.Connection().StopUnitJob(id.UnitNameFor(), "fail"); err != nil {
		fmt.Printf("idler.idleContainer: Could not stop container %s: %v", id.UnitNameFor(), err)
		return false
	}

	iptables.IdleContainer(id, idler.hostIp)
	return true
}
Exemple #8
0
func InitPreStart(dockerSocket string, id containers.Identifier, imageName string) error {
	var (
		err     error
		imgInfo *dc.Image
		d       *docker.DockerClient
	)

	_, socketActivationType, err := containers.GetSocketActivation(id)
	if err != nil {
		fmt.Printf("init_pre_start: Error while parsing unit file: %v\n", err)
		return err
	}

	if _, err = user.Lookup(id.LoginFor()); err != nil {
		if _, ok := err.(user.UnknownUserError); !ok {
			return err
		}
		if err = createUser(id); err != nil {
			return err
		}
	}

	if d, err = docker.GetConnection(dockerSocket); err != nil {
		return err
	}

	if imgInfo, err = d.GetImage(imageName); err != nil {
		return err
	}

	if err := os.MkdirAll(id.HomePath(), 0700); err != nil {
		return err
	}

	u, _ := user.Lookup(id.LoginFor())
	volumes := make([]string, 0, 10)
	for volPath := range imgInfo.Config.Volumes {
		volumes = append(volumes, volPath)
	}

	user := imgInfo.Config.User
	if user == "" {
		user = "******"
	}

	ports, err := containers.GetExistingPorts(id)
	if err != nil {
		fmt.Printf("container init pre-start: Unable to retrieve port mapping\n")
		return err
	}

	containerData := containers.ContainerInitScript{
		imgInfo.Config.User == "",
		user,
		u.Uid,
		u.Gid,
		strings.Join(imgInfo.Config.Cmd, " "),
		len(volumes) > 0,
		strings.Join(volumes, " "),
		ports,
		socketActivationType == "proxied",
	}

	file, _, err := utils.OpenFileExclusive(path.Join(id.RunPathFor(), "container-init.sh"), 0700)
	if err != nil {
		fmt.Printf("container init pre-start: Unable to open script file: %v\n", err)
		return err
	}
	defer file.Close()

	if erre := containers.ContainerInitTemplate.Execute(file, containerData); erre != nil {
		fmt.Printf("container init pre-start: Unable to output template: ", erre)
		return erre
	}
	if err := file.Close(); err != nil {
		return err
	}

	file, _, err = utils.OpenFileExclusive(path.Join(id.RunPathFor(), "container-cmd.sh"), 0705)
	if err != nil {
		fmt.Printf("container init pre-start: Unable to open cmd script file: %v\n", err)
		return err
	}
	defer file.Close()

	if erre := containers.ContainerCmdTemplate.Execute(file, containerData); erre != nil {
		fmt.Printf("container init pre-start: Unable to output cmd template: ", erre)
		return erre
	}
	if err := file.Close(); err != nil {
		return err
	}

	return nil
}
Exemple #9
0
func (j *DeleteContainerRequest) Execute(resp JobResponse) {
	unitName := j.Id.UnitNameFor()
	unitPath := j.Id.UnitPathFor()
	unitDefinitionsPath := j.Id.VersionedUnitsPathFor()
	idleFlagPath := j.Id.IdleUnitPathFor()
	socketUnitPath := j.Id.SocketUnitPathFor()
	homeDirPath := j.Id.BaseHomePath()
	networkLinksPath := j.Id.NetworkLinksPathFor()

	_, err := systemd.Connection().GetUnitProperties(unitName)
	switch {
	case systemd.IsNoSuchUnit(err):
		resp.Success(JobResponseOk)
		return
	case err != nil:
		resp.Failure(ErrDeleteContainerFailed)
		return
	}

	if err := systemd.Connection().StopUnitJob(unitName, "fail"); err != nil {
		log.Printf("delete_container: Unable to queue stop unit job: %v", err)
	}

	ports, err := containers.GetExistingPorts(j.Id)
	if err != nil {
		if !os.IsNotExist(err) {
			log.Printf("delete_container: Unable to read existing port definitions: %v", err)
		}
		ports = port.PortPairs{}
	}

	if err := port.ReleaseExternalPorts(ports); err != nil {
		log.Printf("delete_container: Unable to release ports: %v", err)
	}

	if err := os.Remove(unitPath); err != nil && !os.IsNotExist(err) {
		resp.Failure(ErrDeleteContainerFailed)
		return
	}

	if err := os.Remove(idleFlagPath); err != nil && !os.IsNotExist(err) {
		resp.Failure(ErrDeleteContainerFailed)
		return
	}

	if err := j.Id.SetUnitStartOnBoot(false); err != nil {
		log.Printf("delete_container: Unable to clear unit boot state: %v", err)
	}

	if err := os.Remove(socketUnitPath); err != nil && !os.IsNotExist(err) {
		log.Printf("delete_container: Unable to remove socket unit path: %v", err)
	}

	if err := os.Remove(networkLinksPath); err != nil && !os.IsNotExist(err) {
		log.Printf("delete_container: Unable to remove network links file: %v", err)
	}

	if err := os.RemoveAll(unitDefinitionsPath); err != nil {
		log.Printf("delete_container: Unable to remove definitions for container: %v", err)
	}

	if err := os.RemoveAll(filepath.Dir(homeDirPath)); err != nil {
		log.Printf("delete_container: Unable to remove home directory: %v", err)
	}

	if _, err := systemd.Connection().DisableUnitFiles([]string{unitPath, socketUnitPath}, false); err != nil {
		log.Printf("delete_container: Some units have not been disabled: %v", err)
	}

	if err := systemd.Connection().Reload(); err != nil {
		log.Printf("delete_container: Some units have not been disabled: %v", err)
	}

	resp.Success(JobResponseOk)
}
Exemple #10
0
func (req *InstallContainerRequest) Execute(resp jobs.Response) {
	id := req.Id
	unitName := id.UnitNameFor()
	unitPath := id.UnitPathFor()
	unitVersionPath := id.VersionedUnitPathFor(req.RequestIdentifier.String())

	socketUnitName := id.SocketUnitNameFor()
	socketUnitPath := id.SocketUnitPathFor()
	var socketActivationType string
	if req.SocketActivation {
		socketActivationType = "enabled"
		if !req.SkipSocketProxy {
			socketActivationType = "proxied"
		}
	}

	// attempt to download the environment if it is remote
	env := req.Environment
	if env != nil {
		if err := env.Fetch(100 * 1024); err != nil {
			resp.Failure(ErrContainerCreateFailed)
			return
		}
		if env.Empty() {
			env = nil
		}
	}

	// open and lock the base path (to prevent simultaneous updates)
	state, exists, err := utils.OpenFileExclusive(unitPath, 0664)
	if err != nil {
		log.Print("install_container: Unable to lock unit file: ", err)
		resp.Failure(ErrContainerCreateFailed)
	}
	defer state.Close()

	// write a new file to disk that describes the new service
	unit, err := utils.CreateFileExclusive(unitVersionPath, 0664)
	if err != nil {
		log.Print("install_container: Unable to open unit file definition: ", err)
		resp.Failure(ErrContainerCreateFailed)
		return
	}
	defer unit.Close()

	// if this is an existing container, read the currently reserved ports
	existingPorts := port.PortPairs{}
	if exists {
		existingPorts, err = containers.GetExistingPorts(id)
		if err != nil {
			if _, ok := err.(*os.PathError); !ok {
				log.Print("install_container: Unable to read existing ports from file: ", err)
				resp.Failure(ErrContainerCreateFailed)
				return
			}
		}
	}

	// allocate and reserve ports for this container
	reserved, erra := port.AtomicReserveExternalPorts(unitVersionPath, req.Ports, existingPorts)
	if erra != nil {
		log.Printf("install_container: Unable to reserve external ports: %+v", erra)
		resp.Failure(ErrContainerCreateFailedPortsReserved)
		return
	}
	if len(reserved) > 0 {
		resp.WritePendingSuccess(PendingPortMappingName, reserved)
	}

	var portSpec string
	if req.Simple && len(reserved) == 0 {
		portSpec = "-P"
	} else {
		portSpec = dockerPortSpec(reserved)
	}

	// write the environment to disk
	var environmentPath string
	if env != nil {
		if errw := env.Write(false); errw != nil {
			resp.Failure(ErrContainerCreateFailed)
			return
		}
		environmentPath = env.Id.EnvironmentPathFor()
	}

	// write the network links (if any) to disk
	if req.NetworkLinks != nil {
		if errw := req.NetworkLinks.Write(id.NetworkLinksPathFor(), false); errw != nil {
			resp.Failure(ErrContainerCreateFailed)
			return
		}
	}

	slice := "container-small"

	// write the definition unit file
	args := csystemd.ContainerUnit{
		Id:       id,
		Image:    req.Image,
		PortSpec: portSpec,
		Slice:    slice + ".slice",

		Isolate: req.Isolate,

		ReqId: req.RequestIdentifier.String(),

		HomeDir:         id.HomePath(),
		RunDir:          id.RunPathFor(),
		EnvironmentPath: environmentPath,
		ExecutablePath:  filepath.Join("/", "usr", "bin", "gear"),
		IncludePath:     "",

		PortPairs:            reserved,
		SocketUnitName:       socketUnitName,
		SocketActivationType: socketActivationType,

		DockerFeatures: config.SystemDockerFeatures,
	}

	var templateName string
	switch {
	case req.SocketActivation:
		templateName = "SOCKETACTIVATED"
	case config.SystemDockerFeatures.ForegroundRun:
		templateName = "FOREGROUND"
	default:
		templateName = "SIMPLE"
	}

	if erre := csystemd.ContainerUnitTemplate.ExecuteTemplate(unit, templateName, args); erre != nil {
		log.Printf("install_container: Unable to output template: %+v", erre)
		resp.Failure(ErrContainerCreateFailed)
		defer os.Remove(unitVersionPath)
		return
	}
	if err := unit.Close(); err != nil {
		log.Printf("install_container: Unable to finish writing unit: %+v", err)
		resp.Failure(ErrContainerCreateFailed)
		defer os.Remove(unitVersionPath)
		return
	}

	// swap the new definition with the old one
	if err := utils.AtomicReplaceLink(unitVersionPath, unitPath); err != nil {
		log.Printf("install_container: Failed to activate new unit: %+v", err)
		resp.Failure(ErrContainerCreateFailed)
		return
	}
	state.Close()

	// write whether this container should be started on next boot
	if req.Started {
		if errs := csystemd.SetUnitStartOnBoot(id, true); errs != nil {
			log.Print("install_container: Unable to write container boot link: ", err)
			resp.Failure(ErrContainerCreateFailed)
			return
		}
	}

	// Generate the socket file and ignore failures
	paths := []string{unitPath}
	if req.SocketActivation {
		if err := writeSocketUnit(socketUnitPath, &args); err == nil {
			paths = []string{unitPath, socketUnitPath}
		}
	}

	if err := systemd.EnableAndReloadUnit(systemd.Connection(), unitName, paths...); err != nil {
		log.Printf("install_container: Could not enable container %s (%v): %v", unitName, paths, err)
		resp.Failure(ErrContainerCreateFailed)
		return
	}

	if req.Started {
		if req.SocketActivation {
			// Start the socket file, not the service and ignore failures
			if err := systemd.Connection().StartUnitJob(socketUnitName, "replace"); err != nil {
				log.Printf("install_container: Could not start container socket %s: %v", socketUnitName, err)
				resp.Failure(ErrContainerCreateFailed)
				return
			}
		} else {
			if err := systemd.Connection().StartUnitJob(unitName, "replace"); err != nil {
				log.Printf("install_container: Could not start container %s: %v", unitName, err)
				resp.Failure(ErrContainerCreateFailed)
				return
			}

		}
	}

	w := resp.SuccessWithWrite(jobs.ResponseAccepted, true, false)
	if req.Started {
		fmt.Fprintf(w, "Container %s is starting\n", id)
	} else {
		fmt.Fprintf(w, "Container %s is installed\n", id)
	}
}
// FIXME: Refactor into separate responsibilities for file creation, templating, and disk access
func generateAuthorizedKeys(id containers.Identifier, u *user.User, forceCreate, printToStdOut bool) error {
	var (
		err      error
		sshKeys  []string
		destFile *os.File
		srcFile  *os.File
		w        *bufio.Writer
	)

	var authorizedKeysPortSpec string
	ports, err := containers.GetExistingPorts(id)
	if err != nil {
		fmt.Errorf("container init pre-start: Unable to retrieve port mapping")
		return err
	}

	for _, port := range ports {
		authorizedKeysPortSpec += fmt.Sprintf("permitopen=\"127.0.0.1:%v\",", port.External)
	}

	sshKeys, err = filepath.Glob(path.Join(SshAccessBasePath(id), "*"))

	if !printToStdOut {
		os.MkdirAll(id.HomePath(), 0700)
		os.Mkdir(path.Join(id.HomePath(), ".ssh"), 0700)
		authKeysPath := id.AuthKeysPathFor()
		if _, err = os.Stat(authKeysPath); err != nil {
			if !os.IsNotExist(err) {
				return err
			}
		} else {
			if forceCreate {
				os.Remove(authKeysPath)
			} else {
				return nil
			}
		}

		if destFile, err = os.Create(authKeysPath); err != nil {
			return err
		}
		defer destFile.Close()
		w = bufio.NewWriter(destFile)
	} else {
		w = bufio.NewWriter(os.Stdout)
	}

	for _, keyFile := range sshKeys {
		s, err := os.Stat(keyFile)
		if err != nil {
			continue
		}
		if s.IsDir() {
			continue
		}

		srcFile, err = os.Open(keyFile)
		defer srcFile.Close()
		w.WriteString(fmt.Sprintf("command=\"/usr/bin/switchns\",%vno-agent-forwarding,no-X11-forwarding ", authorizedKeysPortSpec))
		io.Copy(w, srcFile)
		w.WriteString("\n")
	}
	w.Flush()

	if !printToStdOut {
		uid, _ := strconv.Atoi(u.Uid)
		gid, _ := strconv.Atoi(u.Gid)

		for _, path := range []string{
			id.HomePath(),
			filepath.Join(id.HomePath(), ".ssh"),
			filepath.Join(id.HomePath(), ".ssh", "authorized_keys"),
		} {
			if err := os.Chown(path, uid, gid); err != nil {
				return err
			}
		}

		if err := selinux.RestoreCon(id.BaseHomePath(), true); err != nil {
			return err
		}
	}
	return nil
}
Exemple #12
0
func (s *IntegrationTestSuite) TestInstallVolume(c *chk.C) {
	id, err := containers.NewIdentifier("TestInstallVolume")
	c.Assert(err, chk.IsNil)
	s.containerIds = append(s.containerIds, id)

	hostContainerId := fmt.Sprintf("%v/%v", s.daemonURI, id)

	mountPath, err := ioutil.TempDir("/tmp", "bind-rw")
	c.Assert(err, chk.IsNil)

	roMountPath, err := ioutil.TempDir("/tmp", "bind-ro")
	c.Assert(err, chk.IsNil)
	roTestFilePath := path.Join(roMountPath, "ro-test")
	ioutil.WriteFile(roTestFilePath, []byte{}, 0664)

	cmd := exec.Command("/usr/bin/gear", "install", TestImage, hostContainerId,
		fmt.Sprintf("--volumes=/test-volume,%s:/test-bind-ro:ro,%s:/test-bind-rw", roMountPath, mountPath),
		"--ports=8080:0", "--start")
	data, err := cmd.CombinedOutput()
	c.Log(string(data))
	c.Assert(err, chk.IsNil)
	s.assertContainerStarts(c, id)
	oldPid := s.getContainerPid(id)

	ports, err := containers.GetExistingPorts(id)
	c.Assert(err, chk.IsNil)
	c.Assert(len(ports), chk.Equals, 1)

	httpAlive := func() bool {
		resp, err := http.Get(fmt.Sprintf("http://0.0.0.0:%v", ports[0].External))
		if err == nil {
			c.Assert(resp.StatusCode, chk.Equals, 200)
			return true
		}
		return false
	}
	if !until(TimeoutContainerStateChange, IntervalHttpCheck, httpAlive) {
		c.Errorf("Unable to retrieve a 200 status code from port %d", ports[0].External)
		c.FailNow()
	}

	exitCode, err := namespace.RunCommandInContainer(s.dockerClient,
		"TestInstallVolume",
		[]string{"/bin/busybox", "ls", "/test-bind-ro/ro-test"}, []string{})
	c.Assert(err, chk.IsNil)
	c.Assert(exitCode, chk.Equals, 0)

	exitCode, err = namespace.RunCommandInContainer(s.dockerClient,
		"TestInstallVolume",
		[]string{"/bin/busybox", "touch", "/test-bind-ro/rw-test"}, []string{})
	c.Assert(err, chk.IsNil)
	c.Assert(exitCode, chk.Not(chk.Equals), 0)

	exitCode, err = namespace.RunCommandInContainer(s.dockerClient,
		"TestInstallVolume",
		[]string{"/bin/busybox", "touch", "/test-bind-rw/rw-test"}, []string{})
	c.Assert(err, chk.IsNil)
	c.Assert(exitCode, chk.Equals, 0)

	exitCode, err = namespace.RunCommandInContainer(s.dockerClient,
		"TestInstallVolume",
		[]string{"/bin/busybox", "touch", "/test-volume/rw-test"}, []string{})
	c.Assert(err, chk.IsNil)
	c.Assert(exitCode, chk.Equals, 0)

	exitCode, err = namespace.RunCommandInContainer(s.dockerClient,
		"TestInstallVolume",
		[]string{"/bin/busybox", "touch", "/tmp/transient-file"}, []string{})
	c.Assert(err, chk.IsNil)
	c.Assert(exitCode, chk.Equals, 0)

	cmd = exec.Command("/usr/bin/gear", "restart", hostContainerId)
	data, err = cmd.CombinedOutput()
	c.Log(string(data))
	c.Assert(err, chk.IsNil)
	s.assertContainerRestarts(c, id)

	newPid := s.getContainerPid(id)
	c.Assert(oldPid, chk.Not(chk.Equals), newPid)

	exitCode, err = namespace.RunCommandInContainer(s.dockerClient,
		"TestInstallVolume",
		[]string{"/bin/busybox", "ls", "/test-bind-rw/rw-test"}, []string{})
	c.Assert(err, chk.IsNil)
	c.Assert(exitCode, chk.Equals, 0)

	exitCode, err = namespace.RunCommandInContainer(s.dockerClient,
		"TestInstallVolume",
		[]string{"/bin/busybox", "ls", "/test-volume/rw-test"}, []string{})
	c.Assert(err, chk.IsNil)
	c.Assert(exitCode, chk.Equals, 0)

	exitCode, err = namespace.RunCommandInContainer(s.dockerClient,
		"TestInstallVolume",
		[]string{"/bin/busybox", "ls", "/tmp/transient-file"}, []string{})
	c.Assert(err, chk.IsNil)
	c.Assert(exitCode, chk.Not(chk.Equals), 0)
}