Manage mount lifecycle and remove cached state

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu
2018-10-10 17:20:40 -07:00
parent 36893c3ec9
commit c1740d8291
10 changed files with 267 additions and 167 deletions

View File

@@ -353,7 +353,7 @@ func checkSelinuxLevel(level string) (bool, error) {
matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}((.c\d{1,4})?,c\d{1,4})*(.c\d{1,4})?(,c\d{1,4}(.c\d{1,4})?)*)?$`, level)
if err != nil || !matched {
return false, fmt.Errorf("the format of 'level' %q is not correct: %v", level, err)
return false, errors.Wrapf(err, "the format of 'level' %q is not correct", level)
}
return true, nil
}

View File

@@ -34,6 +34,7 @@ import (
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
"github.com/containerd/cri/pkg/netns"
cio "github.com/containerd/cri/pkg/server/io"
containerstore "github.com/containerd/cri/pkg/store/container"
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
@@ -394,14 +395,7 @@ func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.S
// Don't need to load netns for host network sandbox.
return sandbox, nil
}
netNS, err := sandboxstore.LoadNetNS(meta.NetNSPath)
if err != nil {
if err != sandboxstore.ErrClosedNetNS {
return sandbox, errors.Wrapf(err, "failed to load netns %q", meta.NetNSPath)
}
netNS = nil
}
sandbox.NetNS = netNS
sandbox.NetNS = netns.LoadNetNS(meta.NetNSPath)
// It doesn't matter whether task is running or not. If it is running, sandbox
// status will be `READY`; if it is not running, sandbox status will be `NOT_READY`,

View File

@@ -59,10 +59,12 @@ func (c *criService) portForward(id string, port int32, stream io.ReadWriteClose
securityContext := s.Config.GetLinux().GetSecurityContext()
hostNet := securityContext.GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
if !hostNet {
if s.NetNS == nil || s.NetNS.Closed() {
if closed, err := s.NetNS.Closed(); err != nil {
return errors.Wrapf(err, "failed to check netwok namespace closed for sandbox %q", id)
} else if closed {
return errors.Errorf("network namespace for sandbox %q is closed", id)
}
netNSDo = s.NetNS.GetNs().Do
netNSDo = s.NetNS.Do
netNSPath = s.NetNS.GetPath()
} else {
// Run the function directly for host network.

View File

@@ -52,8 +52,13 @@ func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodS
}
// Return error if sandbox network namespace is not closed yet.
if sandbox.NetNS != nil && !sandbox.NetNS.Closed() {
return nil, errors.Errorf("sandbox network namespace %q is not fully closed", sandbox.NetNS.GetPath())
if sandbox.NetNS != nil {
nsPath := sandbox.NetNS.GetPath()
if closed, err := sandbox.NetNS.Closed(); err != nil {
return nil, errors.Wrapf(err, "failed to check sandbox network namespace %q closed", nsPath)
} else if !closed {
return nil, errors.Errorf("sandbox network namespace %q is not fully closed", nsPath)
}
}
// Remove all containers inside the sandbox.

View File

@@ -41,6 +41,7 @@ import (
customopts "github.com/containerd/cri/pkg/containerd/opts"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
"github.com/containerd/cri/pkg/log"
"github.com/containerd/cri/pkg/netns"
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
"github.com/containerd/cri/pkg/util"
)
@@ -104,7 +105,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
// handle. NetNSPath in sandbox metadata and NetNS is non empty only for non host network
// namespaces. If the pod is in host network namespace then both are empty and should not
// be used.
sandbox.NetNS, err = sandboxstore.NewNetNS()
sandbox.NetNS, err = netns.NewNetNS()
if err != nil {
return nil, errors.Wrapf(err, "failed to create network namespace for sandbox %q", id)
}

View File

@@ -36,7 +36,10 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox
return nil, errors.Wrap(err, "an error occurred when try to find sandbox")
}
ip := c.getIP(sandbox)
ip, err := c.getIP(sandbox)
if err != nil {
return nil, errors.Wrap(err, "failed to get sandbox ip")
}
status := toCRISandboxStatus(sandbox.Metadata, sandbox.Status.Get(), ip)
if !r.GetVerbose() {
return &runtime.PodSandboxStatusResponse{Status: status}, nil
@@ -54,21 +57,22 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox
}, nil
}
func (c *criService) getIP(sandbox sandboxstore.Sandbox) string {
func (c *criService) getIP(sandbox sandboxstore.Sandbox) (string, error) {
config := sandbox.Config
if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
// For sandboxes using the node network we are not
// responsible for reporting the IP.
return ""
return "", nil
}
// The network namespace has been closed.
if sandbox.NetNS == nil || sandbox.NetNS.Closed() {
return ""
if closed, err := sandbox.NetNS.Closed(); err != nil {
return "", errors.Wrap(err, "check network namespace closed")
} else if closed {
return "", nil
}
return sandbox.IP
return sandbox.IP, nil
}
// toCRISandboxStatus converts sandbox metadata into CRI pod sandbox status.
@@ -146,9 +150,13 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st
si.Status = "deleted"
}
if sandbox.NetNSPath != "" {
if sandbox.NetNS != nil {
// Add network closed information if sandbox is not using host network.
si.NetNSClosed = (sandbox.NetNS == nil || sandbox.NetNS.Closed())
closed, err := sandbox.NetNS.Closed()
if err != nil {
return nil, errors.Wrap(err, "failed to check network namespace closed")
}
si.NetNSClosed = closed
}
spec, err := container.Spec(ctx)

View File

@@ -59,21 +59,20 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
}
// Teardown network for sandbox.
if sandbox.NetNSPath != "" {
if sandbox.NetNS != nil {
netNSPath := sandbox.NetNSPath
if sandbox.NetNS == nil || sandbox.NetNS.Closed() {
// Use empty netns path if netns is not available. This is defined in:
// https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md
// Use empty netns path if netns is not available. This is defined in:
// https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md
if closed, err := sandbox.NetNS.Closed(); err != nil {
return nil, errors.Wrap(err, "failed to check network namespace closed")
} else if closed {
netNSPath = ""
}
if err := c.teardownPod(id, netNSPath, sandbox.Config); err != nil {
return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id)
}
// Close the sandbox network namespace if it was created
if sandbox.NetNS != nil {
if err = sandbox.NetNS.Remove(); err != nil {
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
}
if err = sandbox.NetNS.Remove(); err != nil {
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
}
}