adds volatile state directory to the fs plan for cntrs/pods/fifo

Signed-off-by: Mike Brown <brownwm@us.ibm.com>
This commit is contained in:
Mike Brown 2018-03-22 14:49:21 -05:00 committed by Lantao Liu
parent 7f64f9b85c
commit 94df315de8
15 changed files with 178 additions and 119 deletions

4
cri.go
View File

@ -64,12 +64,10 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
pluginConfig := ic.Config.(*criconfig.PluginConfig)
c := criconfig.Config{
PluginConfig: *pluginConfig,
// This is a hack. We assume that containerd root directory
// is one level above plugin directory.
// TODO(random-liu): Expose containerd config to plugin.
ContainerdRootDir: filepath.Dir(ic.Root),
ContainerdEndpoint: ic.Address,
RootDir: ic.Root,
StateDir: ic.State,
}
log.G(ctx).Infof("Start cri plugin with config %+v", c)

View File

@ -189,7 +189,8 @@ $ crictl info
"statsCollectPeriod": 10,
"containerdRootDir": "/var/lib/containerd",
"containerdEndpoint": "/run/containerd/containerd.sock",
"rootDir": "/var/lib/containerd/io.containerd.grpc.v1.cri"
"rootDir": "/var/lib/containerd/io.containerd.grpc.v1.cri",
"stateDir": "/run/containerd/io.containerd.grpc.v1.cri",
},
"golang": "go1.10"
}

View File

@ -96,6 +96,8 @@ type Config struct {
// RootDir is the root directory path for managing cri plugin files
// (metadata checkpoint etc.)
RootDir string `json:"rootDir"`
// StateDir is the root directory path for managing volatile pod/container data
StateDir string `json:"stateDir"`
}
// DefaultConfig returns default configurations of cri plugin.

View File

@ -134,7 +134,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
logrus.Debugf("Use OCI %+v for container %q", ociRuntime, id)
// Create container root directory.
containerRootDir := getContainerRootDir(c.config.RootDir, id)
containerRootDir := c.getContainerRootDir(id)
if err = c.os.MkdirAll(containerRootDir, 0755); err != nil {
return nil, errors.Wrapf(err, "failed to create container root directory %q",
containerRootDir)
@ -148,12 +148,26 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
}
}
}()
volatileContainerRootDir := c.getVolatileContainerRootDir(id)
if err = c.os.MkdirAll(volatileContainerRootDir, 0755); err != nil {
return nil, errors.Wrapf(err, "failed to create volatile container root directory %q",
volatileContainerRootDir)
}
defer func() {
if retErr != nil {
// Cleanup the volatile container root directory.
if err = c.os.RemoveAll(volatileContainerRootDir); err != nil {
logrus.WithError(err).Errorf("Failed to remove volatile container root directory %q",
volatileContainerRootDir)
}
}
}()
// Create container volumes mounts.
volumeMounts := c.generateVolumeMounts(containerRootDir, config.GetMounts(), &image.ImageSpec.Config)
// Generate container runtime spec.
mounts := c.generateContainerMounts(getSandboxRootDir(c.config.RootDir, sandboxID), config)
mounts := c.generateContainerMounts(sandboxID, config)
spec, err := c.generateContainerSpec(id, sandboxID, sandboxPid, config, sandboxConfig, &image.ImageSpec.Config, append(mounts, volumeMounts...))
if err != nil {
@ -188,7 +202,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
}
containerIO, err := cio.NewContainerIO(id,
cio.WithNewFIFOs(containerRootDir, config.GetTty(), config.GetStdin()))
cio.WithNewFIFOs(volatileContainerRootDir, config.GetTty(), config.GetStdin()))
if err != nil {
return nil, errors.Wrap(err, "failed to create container io")
}
@ -416,13 +430,13 @@ func (c *criService) generateVolumeMounts(containerRootDir string, criMounts []*
// generateContainerMounts sets up necessary container mounts including /dev/shm, /etc/hosts
// and /etc/resolv.conf.
func (c *criService) generateContainerMounts(sandboxRootDir string, config *runtime.ContainerConfig) []*runtime.Mount {
func (c *criService) generateContainerMounts(sandboxID string, config *runtime.ContainerConfig) []*runtime.Mount {
var mounts []*runtime.Mount
securityContext := config.GetLinux().GetSecurityContext()
if !isInCRIMounts(etcHosts, config.GetMounts()) {
mounts = append(mounts, &runtime.Mount{
ContainerPath: etcHosts,
HostPath: getSandboxHosts(sandboxRootDir),
HostPath: c.getSandboxHosts(sandboxID),
Readonly: securityContext.GetReadonlyRootfs(),
})
}
@ -432,13 +446,13 @@ func (c *criService) generateContainerMounts(sandboxRootDir string, config *runt
if !isInCRIMounts(resolvConfPath, config.GetMounts()) {
mounts = append(mounts, &runtime.Mount{
ContainerPath: resolvConfPath,
HostPath: getResolvPath(sandboxRootDir),
HostPath: c.getResolvPath(sandboxID),
Readonly: securityContext.GetReadonlyRootfs(),
})
}
if !isInCRIMounts(devShm, config.GetMounts()) {
sandboxDevShm := getSandboxDevShm(sandboxRootDir)
sandboxDevShm := c.getSandboxDevShm(sandboxID)
if securityContext.GetNamespaceOptions().GetIpc() == runtime.NamespaceMode_NODE {
sandboxDevShm = devShm
}

View File

@ -497,7 +497,7 @@ func TestGenerateVolumeMounts(t *testing.T) {
}
func TestGenerateContainerMounts(t *testing.T) {
testSandboxRootDir := "test-sandbox-root"
const testSandboxID = "test-id"
for desc, test := range map[string]struct {
criMounts []*runtime.Mount
securityContext *runtime.LinuxContainerSecurityContext
@ -510,17 +510,17 @@ func TestGenerateContainerMounts(t *testing.T) {
expectedMounts: []*runtime.Mount{
{
ContainerPath: "/etc/hosts",
HostPath: testSandboxRootDir + "/hosts",
HostPath: filepath.Join(testRootDir, sandboxesDir, testSandboxID, "hosts"),
Readonly: true,
},
{
ContainerPath: resolvConfPath,
HostPath: testSandboxRootDir + "/resolv.conf",
HostPath: filepath.Join(testRootDir, sandboxesDir, testSandboxID, "resolv.conf"),
Readonly: true,
},
{
ContainerPath: "/dev/shm",
HostPath: testSandboxRootDir + "/shm",
HostPath: filepath.Join(testStateDir, sandboxesDir, testSandboxID, "shm"),
Readonly: false,
},
},
@ -530,17 +530,17 @@ func TestGenerateContainerMounts(t *testing.T) {
expectedMounts: []*runtime.Mount{
{
ContainerPath: "/etc/hosts",
HostPath: testSandboxRootDir + "/hosts",
HostPath: filepath.Join(testRootDir, sandboxesDir, testSandboxID, "hosts"),
Readonly: false,
},
{
ContainerPath: resolvConfPath,
HostPath: testSandboxRootDir + "/resolv.conf",
HostPath: filepath.Join(testRootDir, sandboxesDir, testSandboxID, "resolv.conf"),
Readonly: false,
},
{
ContainerPath: "/dev/shm",
HostPath: testSandboxRootDir + "/shm",
HostPath: filepath.Join(testStateDir, sandboxesDir, testSandboxID, "shm"),
Readonly: false,
},
},
@ -552,12 +552,12 @@ func TestGenerateContainerMounts(t *testing.T) {
expectedMounts: []*runtime.Mount{
{
ContainerPath: "/etc/hosts",
HostPath: testSandboxRootDir + "/hosts",
HostPath: filepath.Join(testRootDir, sandboxesDir, testSandboxID, "hosts"),
Readonly: false,
},
{
ContainerPath: resolvConfPath,
HostPath: testSandboxRootDir + "/resolv.conf",
HostPath: filepath.Join(testRootDir, sandboxesDir, testSandboxID, "resolv.conf"),
Readonly: false,
},
{
@ -597,7 +597,7 @@ func TestGenerateContainerMounts(t *testing.T) {
},
}
c := newTestCRIService()
mounts := c.generateContainerMounts(testSandboxRootDir, config)
mounts := c.generateContainerMounts(testSandboxID, config)
assert.Equal(t, test.expectedMounts, mounts, desc)
}
}

View File

@ -116,12 +116,12 @@ func (c *criService) execInContainer(ctx context.Context, id string, opts execOp
}
execID := util.GenerateID()
logrus.Debugf("Generated exec id %q for container %q", execID, id)
rootDir := getContainerRootDir(c.config.RootDir, id)
volatileRootDir := c.getVolatileContainerRootDir(id)
var execIO *cio.ExecIO
process, err := task.Exec(ctx, execID, pspec,
func(id string) (containerdio.IO, error) {
var err error
execIO, err = cio.NewExecIO(id, rootDir, opts.tty, opts.stdin != nil)
execIO, err = cio.NewExecIO(id, volatileRootDir, opts.tty, opts.stdin != nil)
return execIO, err
},
)

View File

@ -76,11 +76,16 @@ func (c *criService) RemoveContainer(ctx context.Context, r *runtime.RemoveConta
return nil, errors.Wrapf(err, "failed to delete container checkpoint for %q", id)
}
containerRootDir := getContainerRootDir(c.config.RootDir, id)
containerRootDir := c.getContainerRootDir(id)
if err := system.EnsureRemoveAll(containerRootDir); err != nil {
return nil, errors.Wrapf(err, "failed to remove container root directory %q",
containerRootDir)
}
volatileContainerRootDir := c.getVolatileContainerRootDir(id)
if err := system.EnsureRemoveAll(volatileContainerRootDir); err != nil {
return nil, errors.Wrapf(err, "failed to remove volatile container root directory %q",
volatileContainerRootDir)
}
c.containerStore.Delete(id)

View File

@ -156,29 +156,42 @@ func getCgroupsPath(cgroupsParent, id string, systemdCgroup bool) string {
}
// getSandboxRootDir returns the root directory for managing sandbox files,
// e.g. named pipes.
func getSandboxRootDir(rootDir, id string) string {
return filepath.Join(rootDir, sandboxesDir, id)
// e.g. hosts files.
func (c *criService) getSandboxRootDir(id string) string {
return filepath.Join(c.config.RootDir, sandboxesDir, id)
}
// getContainerRootDir returns the root directory for managing container files.
func getContainerRootDir(rootDir, id string) string {
return filepath.Join(rootDir, containersDir, id)
// getVolatileSandboxRootDir returns the root directory for managing volatile sandbox files,
// e.g. named pipes.
func (c *criService) getVolatileSandboxRootDir(id string) string {
return filepath.Join(c.config.StateDir, sandboxesDir, id)
}
// getContainerRootDir returns the root directory for managing container files,
// e.g. state checkpoint.
func (c *criService) getContainerRootDir(id string) string {
return filepath.Join(c.config.RootDir, containersDir, id)
}
// getVolatileContainerRootDir returns the root directory for managing volatile container files,
// e.g. named pipes.
func (c *criService) getVolatileContainerRootDir(id string) string {
return filepath.Join(c.config.StateDir, containersDir, id)
}
// getSandboxHosts returns the hosts file path inside the sandbox root directory.
func getSandboxHosts(sandboxRootDir string) string {
return filepath.Join(sandboxRootDir, "hosts")
func (c *criService) getSandboxHosts(id string) string {
return filepath.Join(c.getSandboxRootDir(id), "hosts")
}
// getResolvPath returns resolv.conf filepath for specified sandbox.
func getResolvPath(sandboxRoot string) string {
return filepath.Join(sandboxRoot, "resolv.conf")
func (c *criService) getResolvPath(id string) string {
return filepath.Join(c.getSandboxRootDir(id), "resolv.conf")
}
// getSandboxDevShm returns the shm file path inside the sandbox root directory.
func getSandboxDevShm(sandboxRootDir string) string {
return filepath.Join(sandboxRootDir, "shm")
func (c *criService) getSandboxDevShm(id string) string {
return filepath.Join(c.getVolatileSandboxRootDir(id), "shm")
}
// getNetworkNamespace returns the network namespace of a process.

View File

@ -78,8 +78,9 @@ func (c *criService) recover(ctx context.Context) error {
return errors.Wrap(err, "failed to list containers")
}
for _, container := range containers {
containerDir := getContainerRootDir(c.config.RootDir, container.ID())
cntr, err := loadContainer(ctx, container, containerDir)
containerDir := c.getContainerRootDir(container.ID())
volatileContainerDir := c.getVolatileContainerRootDir(container.ID())
cntr, err := loadContainer(ctx, container, containerDir, volatileContainerDir)
if err != nil {
logrus.WithError(err).Errorf("Failed to load container %q", container.ID())
continue
@ -113,21 +114,42 @@ func (c *criService) recover(ctx context.Context) error {
// we can't even get metadata, we should cleanup orphaned sandbox/container directories
// with best effort.
// Cleanup orphaned sandbox directories without corresponding containerd container.
if err := cleanupOrphanedSandboxDirs(sandboxes, filepath.Join(c.config.RootDir, "sandboxes")); err != nil {
return errors.Wrap(err, "failed to cleanup orphaned sandbox directories")
// Cleanup orphaned sandbox and container directories without corresponding containerd container.
for _, cleanup := range []struct {
cntrs []containerd.Container
base string
errMsg string
}{
{
cntrs: sandboxes,
base: filepath.Join(c.config.RootDir, sandboxesDir),
errMsg: "failed to cleanup orphaned sandbox directories",
},
{
cntrs: sandboxes,
base: filepath.Join(c.config.StateDir, sandboxesDir),
errMsg: "failed to cleanup orphaned volatile sandbox directories",
},
{
cntrs: containers,
base: filepath.Join(c.config.RootDir, containersDir),
errMsg: "failed to cleanup orphaned container directories",
},
{
cntrs: containers,
base: filepath.Join(c.config.StateDir, containersDir),
errMsg: "failed to cleanup orphaned volatile container directories",
},
} {
if err := cleanupOrphanedIDDirs(cleanup.cntrs, cleanup.base); err != nil {
return errors.Wrap(err, cleanup.errMsg)
}
// Cleanup orphaned container directories without corresponding containerd container.
if err := cleanupOrphanedContainerDirs(containers, filepath.Join(c.config.RootDir, "containers")); err != nil {
return errors.Wrap(err, "failed to cleanup orphaned container directories")
}
return nil
}
// loadContainer loads container from containerd and status checkpoint.
func loadContainer(ctx context.Context, cntr containerd.Container, containerDir string) (containerstore.Container, error) {
func loadContainer(ctx context.Context, cntr containerd.Container, containerDir, volatileContainerDir string) (containerstore.Container, error) {
id := cntr.ID()
var container containerstore.Container
// Load container metadata.
@ -197,7 +219,7 @@ func loadContainer(ctx context.Context, cntr containerd.Container, containerDir
// containerd got restarted during that. In that case, we still
// treat the container as `CREATED`.
containerIO, err = cio.NewContainerIO(id,
cio.WithNewFIFOs(containerDir, meta.Config.GetTty(), meta.Config.GetStdin()),
cio.WithNewFIFOs(volatileContainerDir, meta.Config.GetTty(), meta.Config.GetStdin()),
)
if err != nil {
return container, errors.Wrap(err, "failed to create container io")
@ -448,59 +470,30 @@ func loadImages(ctx context.Context, cImages []containerd.Image,
return images, nil
}
func cleanupOrphanedSandboxDirs(cntrs []containerd.Container, sandboxesRoot string) error {
// Cleanup orphaned sandbox directories.
dirs, err := ioutil.ReadDir(sandboxesRoot)
func cleanupOrphanedIDDirs(cntrs []containerd.Container, base string) error {
// Cleanup orphaned id directories.
dirs, err := ioutil.ReadDir(base)
if err != nil && !os.IsNotExist(err) {
return errors.Wrapf(err, "failed to read pod sandboxes directory %q", sandboxesRoot)
return errors.Wrap(err, "failed to read base directory")
}
cntrsMap := make(map[string]containerd.Container)
idsMap := make(map[string]containerd.Container)
for _, cntr := range cntrs {
cntrsMap[cntr.ID()] = cntr
idsMap[cntr.ID()] = cntr
}
for _, d := range dirs {
if !d.IsDir() {
logrus.Warnf("Invalid file %q found in pod sandboxes directory", d.Name())
logrus.Warnf("Invalid file %q found in base directory %q", d.Name(), base)
continue
}
if _, ok := cntrsMap[d.Name()]; ok {
// Do not remove sandbox directory if corresponding container is found.
if _, ok := idsMap[d.Name()]; ok {
// Do not remove id directory if corresponding container is found.
continue
}
sandboxDir := filepath.Join(sandboxesRoot, d.Name())
if err := system.EnsureRemoveAll(sandboxDir); err != nil {
logrus.WithError(err).Warnf("Failed to remove pod sandbox directory %q", sandboxDir)
dir := filepath.Join(base, d.Name())
if err := system.EnsureRemoveAll(dir); err != nil {
logrus.WithError(err).Warnf("Failed to remove id directory %q", dir)
} else {
logrus.Debugf("Cleanup orphaned pod sandbox directory %q", sandboxDir)
}
}
return nil
}
func cleanupOrphanedContainerDirs(cntrs []containerd.Container, containersRoot string) error {
// Cleanup orphaned container directories.
dirs, err := ioutil.ReadDir(containersRoot)
if err != nil && !os.IsNotExist(err) {
return errors.Wrapf(err, "failed to read containers directory %q", containersRoot)
}
cntrsMap := make(map[string]containerd.Container)
for _, cntr := range cntrs {
cntrsMap[cntr.ID()] = cntr
}
for _, d := range dirs {
if !d.IsDir() {
logrus.Warnf("Invalid file %q found in containers directory", d.Name())
continue
}
if _, ok := cntrsMap[d.Name()]; ok {
// Do not remove container directory if corresponding container is found.
continue
}
containerDir := filepath.Join(containersRoot, d.Name())
if err := system.EnsureRemoveAll(containerDir); err != nil {
logrus.WithError(err).Warnf("Failed to remove container directory %q", containerDir)
} else {
logrus.Debugf("Cleanup orphaned container directory %q", containerDir)
logrus.Debugf("Cleanup orphaned id directory %q", dir)
}
}
return nil

View File

@ -72,12 +72,17 @@ func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodS
}
}
// Cleanup the sandbox root directory.
sandboxRootDir := getSandboxRootDir(c.config.RootDir, id)
// Cleanup the sandbox root directories.
sandboxRootDir := c.getSandboxRootDir(id)
if err := system.EnsureRemoveAll(sandboxRootDir); err != nil {
return nil, errors.Wrapf(err, "failed to remove sandbox root directory %q",
sandboxRootDir)
}
volatileSandboxRootDir := c.getVolatileSandboxRootDir(id)
if err := system.EnsureRemoveAll(volatileSandboxRootDir); err != nil {
return nil, errors.Wrapf(err, "failed to remove volatile sandbox root directory %q",
volatileSandboxRootDir)
}
// Delete sandbox container.
if err := sandbox.Container.Delete(ctx, containerd.WithSnapshotCleanup); err != nil {

View File

@ -189,8 +189,8 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
}
}()
// Create sandbox container root directory.
sandboxRootDir := getSandboxRootDir(c.config.RootDir, id)
// Create sandbox container root directories.
sandboxRootDir := c.getSandboxRootDir(id)
if err := c.os.MkdirAll(sandboxRootDir, 0755); err != nil {
return nil, errors.Wrapf(err, "failed to create sandbox root directory %q",
sandboxRootDir)
@ -204,14 +204,28 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
}
}
}()
volatileSandboxRootDir := c.getVolatileSandboxRootDir(id)
if err := c.os.MkdirAll(volatileSandboxRootDir, 0755); err != nil {
return nil, errors.Wrapf(err, "failed to create volatile sandbox root directory %q",
volatileSandboxRootDir)
}
defer func() {
if retErr != nil {
// Cleanup the volatile sandbox root directory.
if err := c.os.RemoveAll(volatileSandboxRootDir); err != nil {
logrus.WithError(err).Errorf("Failed to remove volatile sandbox root directory %q",
volatileSandboxRootDir)
}
}
}()
// Setup sandbox /dev/shm, /etc/hosts and /etc/resolv.conf.
if err = c.setupSandboxFiles(sandboxRootDir, config); err != nil {
if err = c.setupSandboxFiles(id, config); err != nil {
return nil, errors.Wrapf(err, "failed to setup sandbox files")
}
defer func() {
if retErr != nil {
if err = c.unmountSandboxFiles(sandboxRootDir, config); err != nil {
if err = c.unmountSandboxFiles(id, config); err != nil {
logrus.WithError(err).Errorf("Failed to unmount sandbox files in %q",
sandboxRootDir)
}
@ -398,9 +412,9 @@ func (c *criService) generateSandboxContainerSpec(id string, config *runtime.Pod
// setupSandboxFiles sets up necessary sandbox files including /dev/shm, /etc/hosts
// and /etc/resolv.conf.
func (c *criService) setupSandboxFiles(rootDir string, config *runtime.PodSandboxConfig) error {
func (c *criService) setupSandboxFiles(id string, config *runtime.PodSandboxConfig) error {
// TODO(random-liu): Consider whether we should maintain /etc/hosts and /etc/resolv.conf in kubelet.
sandboxEtcHosts := getSandboxHosts(rootDir)
sandboxEtcHosts := c.getSandboxHosts(id)
if err := c.os.CopyFile(etcHosts, sandboxEtcHosts, 0644); err != nil {
return errors.Wrapf(err, "failed to generate sandbox hosts file %q", sandboxEtcHosts)
}
@ -414,7 +428,7 @@ func (c *criService) setupSandboxFiles(rootDir string, config *runtime.PodSandbo
return errors.Wrapf(err, "failed to parse sandbox DNSConfig %+v", dnsConfig)
}
}
resolvPath := getResolvPath(rootDir)
resolvPath := c.getResolvPath(id)
if resolvContent == "" {
// copy host's resolv.conf to resolvPath
err = c.os.CopyFile(resolvConfPath, resolvPath, 0644)
@ -434,7 +448,7 @@ func (c *criService) setupSandboxFiles(rootDir string, config *runtime.PodSandbo
return errors.Wrapf(err, "host %q is not available for host ipc", devShm)
}
} else {
sandboxDevShm := getSandboxDevShm(rootDir)
sandboxDevShm := c.getSandboxDevShm(id)
if err := c.os.MkdirAll(sandboxDevShm, 0700); err != nil {
return errors.Wrap(err, "failed to create sandbox shm")
}
@ -475,9 +489,9 @@ func parseDNSOptions(servers, searches, options []string) (string, error) {
// remove these files. Unmount should *NOT* return error when:
// 1) The mount point is already unmounted.
// 2) The mount point doesn't exist.
func (c *criService) unmountSandboxFiles(rootDir string, config *runtime.PodSandboxConfig) error {
func (c *criService) unmountSandboxFiles(id string, config *runtime.PodSandboxConfig) error {
if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetIpc() != runtime.NamespaceMode_NODE {
if err := c.os.Unmount(getSandboxDevShm(rootDir), unix.MNT_DETACH); err != nil && !os.IsNotExist(err) {
if err := c.os.Unmount(c.getSandboxDevShm(id), unix.MNT_DETACH); err != nil && !os.IsNotExist(err) {
return err
}
}

View File

@ -18,6 +18,7 @@ package server
import (
"os"
"path/filepath"
"testing"
cni "github.com/containerd/go-cni"
@ -177,7 +178,7 @@ func TestGenerateSandboxContainerSpec(t *testing.T) {
}
func TestSetupSandboxFiles(t *testing.T) {
testRootDir := "test-sandbox-root"
const testID = "test-id"
for desc, test := range map[string]struct {
dnsConfig *runtime.DNSConfig
ipcMode runtime.NamespaceMode
@ -189,13 +190,17 @@ func TestSetupSandboxFiles(t *testing.T) {
{
Name: "CopyFile",
Arguments: []interface{}{
"/etc/hosts", testRootDir + "/hosts", os.FileMode(0644),
"/etc/hosts",
filepath.Join(testRootDir, sandboxesDir, testID, "hosts"),
os.FileMode(0644),
},
},
{
Name: "CopyFile",
Arguments: []interface{}{
"/etc/resolv.conf", testRootDir + "/resolv.conf", os.FileMode(0644),
"/etc/resolv.conf",
filepath.Join(testRootDir, sandboxesDir, testID, "resolv.conf"),
os.FileMode(0644),
},
},
{
@ -215,13 +220,16 @@ func TestSetupSandboxFiles(t *testing.T) {
{
Name: "CopyFile",
Arguments: []interface{}{
"/etc/hosts", testRootDir + "/hosts", os.FileMode(0644),
"/etc/hosts",
filepath.Join(testRootDir, sandboxesDir, testID, "hosts"),
os.FileMode(0644),
},
},
{
Name: "WriteFile",
Arguments: []interface{}{
testRootDir + "/resolv.conf", []byte(`search 114.114.114.114
filepath.Join(testRootDir, sandboxesDir, testID, "resolv.conf"),
[]byte(`search 114.114.114.114
nameserver 8.8.8.8
options timeout:1
`), os.FileMode(0644),
@ -239,19 +247,24 @@ options timeout:1
{
Name: "CopyFile",
Arguments: []interface{}{
"/etc/hosts", testRootDir + "/hosts", os.FileMode(0644),
"/etc/hosts",
filepath.Join(testRootDir, sandboxesDir, testID, "hosts"),
os.FileMode(0644),
},
},
{
Name: "CopyFile",
Arguments: []interface{}{
"/etc/resolv.conf", testRootDir + "/resolv.conf", os.FileMode(0644),
"/etc/resolv.conf",
filepath.Join(testRootDir, sandboxesDir, testID, "resolv.conf"),
os.FileMode(0644),
},
},
{
Name: "MkdirAll",
Arguments: []interface{}{
testRootDir + "/shm", os.FileMode(0700),
filepath.Join(testStateDir, sandboxesDir, testID, "shm"),
os.FileMode(0700),
},
},
{
@ -273,7 +286,7 @@ options timeout:1
},
},
}
c.setupSandboxFiles(testRootDir, cfg)
c.setupSandboxFiles(testID, cfg)
calls := c.os.(*ostesting.FakeOS).GetCalls()
assert.Len(t, calls, len(test.expectedCalls))
for i, expected := range test.expectedCalls {

View File

@ -81,9 +81,8 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
logrus.Infof("TearDown network for sandbox %q successfully", id)
sandboxRoot := getSandboxRootDir(c.config.RootDir, id)
if err := c.unmountSandboxFiles(sandboxRoot, sandbox.Config); err != nil {
return nil, errors.Wrapf(err, "failed to unmount sandbox files in %q", sandboxRoot)
if err := c.unmountSandboxFiles(id, sandbox.Config); err != nil {
return nil, errors.Wrap(err, "failed to unmount sandbox files")
}
// Only stop sandbox container when it's running.

View File

@ -28,7 +28,8 @@ import (
)
const (
testRootDir = "/test/rootfs"
testRootDir = "/test/root"
testStateDir = "/test/state"
// Use an image id as test sandbox image to avoid image name resolve.
// TODO(random-liu): Change this to image name after we have complete image
// management unit test framework.
@ -41,6 +42,7 @@ func newTestCRIService() *criService {
return &criService{
config: criconfig.Config{
RootDir: testRootDir,
StateDir: testStateDir,
PluginConfig: criconfig.PluginConfig{
SandboxImage: testSandboxImage,
},