Merge pull request #766 from mrunalp/ctr_status_fixes
Container status fixes
This commit is contained in:
commit
959aab4fd5
15 changed files with 204 additions and 148 deletions
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"github.com/kubernetes-incubator/cri-o/libkpod"
|
||||
|
@ -39,22 +40,23 @@ const (
|
|||
seccompLocalhostPrefix = "localhost/"
|
||||
)
|
||||
|
||||
func addOCIBindMounts(sb *sandbox.Sandbox, containerConfig *pb.ContainerConfig, specgen *generate.Generator) error {
|
||||
func addOCIBindMounts(sb *sandbox.Sandbox, containerConfig *pb.ContainerConfig, specgen *generate.Generator) ([]oci.ContainerVolume, error) {
|
||||
volumes := []oci.ContainerVolume{}
|
||||
mounts := containerConfig.GetMounts()
|
||||
for _, mount := range mounts {
|
||||
dest := mount.ContainerPath
|
||||
if dest == "" {
|
||||
return fmt.Errorf("Mount.ContainerPath is empty")
|
||||
return nil, fmt.Errorf("Mount.ContainerPath is empty")
|
||||
}
|
||||
|
||||
src := mount.HostPath
|
||||
if src == "" {
|
||||
return fmt.Errorf("Mount.HostPath is empty")
|
||||
return nil, fmt.Errorf("Mount.HostPath is empty")
|
||||
}
|
||||
|
||||
if _, err := os.Stat(src); err != nil && os.IsNotExist(err) {
|
||||
if err1 := os.MkdirAll(src, 0644); err1 != nil {
|
||||
return fmt.Errorf("Failed to mkdir %s: %s", src, err)
|
||||
return nil, fmt.Errorf("Failed to mkdir %s: %s", src, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,14 +69,20 @@ func addOCIBindMounts(sb *sandbox.Sandbox, containerConfig *pb.ContainerConfig,
|
|||
if mount.SelinuxRelabel {
|
||||
// Need a way in kubernetes to determine if the volume is shared or private
|
||||
if err := label.Relabel(src, sb.MountLabel(), true); err != nil && err != unix.ENOTSUP {
|
||||
return fmt.Errorf("relabel failed %s: %v", src, err)
|
||||
return nil, fmt.Errorf("relabel failed %s: %v", src, err)
|
||||
}
|
||||
}
|
||||
|
||||
volumes = append(volumes, oci.ContainerVolume{
|
||||
ContainerPath: dest,
|
||||
HostPath: src,
|
||||
Readonly: mount.Readonly,
|
||||
})
|
||||
|
||||
specgen.AddBindMount(src, dest, options)
|
||||
}
|
||||
|
||||
return nil
|
||||
return volumes, nil
|
||||
}
|
||||
|
||||
func addImageVolumes(rootfs string, s *Server, containerInfo *storage.ContainerInfo, specgen *generate.Generator, mountLabel string) error {
|
||||
|
@ -326,10 +334,6 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err = s.Runtime().UpdateStatus(container); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.addContainer(container)
|
||||
|
||||
if err = s.CtrIDIndex().Add(containerID); err != nil {
|
||||
|
@ -360,10 +364,17 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
|
|||
specgen.HostSpecific = true
|
||||
specgen.ClearProcessRlimits()
|
||||
|
||||
if err := addOCIBindMounts(sb, containerConfig, &specgen); err != nil {
|
||||
containerVolumes, err := addOCIBindMounts(sb, containerConfig, &specgen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
volumesJSON, err := json.Marshal(containerVolumes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specgen.AddAnnotation(annotations.Volumes, string(volumesJSON))
|
||||
|
||||
// Add cgroup mount so container process can introspect its own limits
|
||||
specgen.AddCgroupsMount("ro")
|
||||
|
||||
|
@ -565,6 +576,41 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
|
|||
}
|
||||
image = images[0]
|
||||
|
||||
// Get imageName and imageRef that are requested in container status
|
||||
imageName := image
|
||||
status, err := s.StorageImageServer().ImageStatus(s.ImageContext(), image)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
imageRef := status.ID
|
||||
//
|
||||
// TODO: https://github.com/kubernetes-incubator/cri-o/issues/531
|
||||
//
|
||||
//for _, n := range status.Names {
|
||||
//r, err := reference.ParseNormalizedNamed(n)
|
||||
//if err != nil {
|
||||
//return nil, fmt.Errorf("failed to normalize image name for ImageRef: %v", err)
|
||||
//}
|
||||
//if digested, isDigested := r.(reference.Canonical); isDigested {
|
||||
//imageRef = reference.FamiliarString(digested)
|
||||
//break
|
||||
//}
|
||||
//}
|
||||
for _, n := range status.Names {
|
||||
r, err := reference.ParseNormalizedNamed(n)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to normalize image name for Image: %v", err)
|
||||
}
|
||||
if tagged, isTagged := r.(reference.Tagged); isTagged {
|
||||
imageName = reference.FamiliarString(tagged)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
specgen.AddAnnotation(annotations.ImageName, imageName)
|
||||
specgen.AddAnnotation(annotations.ImageRef, imageRef)
|
||||
|
||||
// bind mount the pod shm
|
||||
specgen.AddBindMount(sb.ShmPath(), "/dev/shm", []string{"rw"})
|
||||
|
||||
|
@ -727,11 +773,15 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
container, err := oci.NewContainer(containerID, containerName, containerInfo.RunDir, logPath, sb.NetNs(), labels, kubeAnnotations, image, metadata, sb.ID(), containerConfig.Tty, containerConfig.Stdin, containerConfig.StdinOnce, sb.Privileged(), sb.Trusted(), containerInfo.Dir, created, containerImageConfig.Config.StopSignal)
|
||||
container, err := oci.NewContainer(containerID, containerName, containerInfo.RunDir, logPath, sb.NetNs(), labels, kubeAnnotations, image, imageName, imageRef, metadata, sb.ID(), containerConfig.Tty, containerConfig.Stdin, containerConfig.StdinOnce, sb.Privileged(), sb.Trusted(), containerInfo.Dir, created, containerImageConfig.Config.StopSignal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, cv := range containerVolumes {
|
||||
container.AddVolume(cv)
|
||||
}
|
||||
|
||||
return container, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,6 @@ func (s *Server) RemoveContainer(ctx context.Context, req *pb.RemoveContainerReq
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.Runtime().UpdateStatus(c); err != nil {
|
||||
return nil, fmt.Errorf("failed to update container state: %v", err)
|
||||
}
|
||||
|
||||
cState := s.Runtime().ContainerStatus(c)
|
||||
if cState.Status == oci.ContainerStateCreated || cState.Status == oci.ContainerStateRunning {
|
||||
if err := s.Runtime().StopContainer(c, -1); err != nil {
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/kubernetes-incubator/cri-o/oci"
|
||||
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
||||
|
@ -26,11 +21,6 @@ func (s *Server) ContainerStatus(ctx context.Context, req *pb.ContainerStatusReq
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err = s.Runtime().UpdateStatus(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.ContainerStateToDisk(c)
|
||||
|
||||
containerID := c.ID()
|
||||
resp := &pb.ContainerStatusResponse{
|
||||
Status: &pb.ContainerStatus{
|
||||
|
@ -38,52 +28,35 @@ func (s *Server) ContainerStatus(ctx context.Context, req *pb.ContainerStatusReq
|
|||
Metadata: c.Metadata(),
|
||||
Labels: c.Labels(),
|
||||
Annotations: c.Annotations(),
|
||||
ImageRef: c.ImageRef(),
|
||||
},
|
||||
}
|
||||
resp.Status.Image = &pb.ImageSpec{Image: c.ImageName()}
|
||||
|
||||
mounts, err := s.getMounts(containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
mounts := []*pb.Mount{}
|
||||
for _, cv := range c.Volumes() {
|
||||
mounts = append(mounts, &pb.Mount{
|
||||
ContainerPath: cv.ContainerPath,
|
||||
HostPath: cv.HostPath,
|
||||
Readonly: cv.Readonly,
|
||||
})
|
||||
}
|
||||
resp.Status.Mounts = mounts
|
||||
|
||||
imageName := c.Image()
|
||||
status, err := s.StorageImageServer().ImageStatus(s.ImageContext(), imageName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
imageRef := status.ID
|
||||
//
|
||||
// TODO: https://github.com/kubernetes-incubator/cri-o/issues/531
|
||||
//
|
||||
//for _, n := range status.Names {
|
||||
//r, err := reference.ParseNormalizedNamed(n)
|
||||
//if err != nil {
|
||||
//return nil, fmt.Errorf("failed to normalize image name for ImageRef: %v", err)
|
||||
//}
|
||||
//if digested, isDigested := r.(reference.Canonical); isDigested {
|
||||
//imageRef = reference.FamiliarString(digested)
|
||||
//break
|
||||
//}
|
||||
//}
|
||||
resp.Status.ImageRef = imageRef
|
||||
|
||||
for _, n := range status.Names {
|
||||
r, err := reference.ParseNormalizedNamed(n)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to normalize image name for Image: %v", err)
|
||||
}
|
||||
if tagged, isTagged := r.(reference.Tagged); isTagged {
|
||||
imageName = reference.FamiliarString(tagged)
|
||||
break
|
||||
}
|
||||
}
|
||||
resp.Status.Image = &pb.ImageSpec{Image: imageName}
|
||||
|
||||
cState := s.Runtime().ContainerStatus(c)
|
||||
rStatus := pb.ContainerState_CONTAINER_UNKNOWN
|
||||
|
||||
// If we defaulted to exit code -1 earlier then we attempt to
|
||||
// get the exit code from the exit file again.
|
||||
// TODO: We could wait in UpdateStatus for exit file to show up.
|
||||
if cState.ExitCode == -1 {
|
||||
err := s.Runtime().UpdateStatus(c)
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to UpdateStatus of container %s: %v", c.ID(), err)
|
||||
}
|
||||
cState = s.Runtime().ContainerStatus(c)
|
||||
}
|
||||
|
||||
switch cState.Status {
|
||||
case oci.ContainerStateCreated:
|
||||
rStatus = pb.ContainerState_CONTAINER_CREATED
|
||||
|
@ -120,46 +93,3 @@ func (s *Server) ContainerStatus(ctx context.Context, req *pb.ContainerStatusReq
|
|||
logrus.Debugf("ContainerStatusResponse: %+v", resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *Server) getMounts(id string) ([]*pb.Mount, error) {
|
||||
config, err := s.Store().FromContainerDirectory(id, "config.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var m rspec.Spec
|
||||
if err = json.Unmarshal(config, &m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
isRO := func(m rspec.Mount) bool {
|
||||
var ro bool
|
||||
for _, o := range m.Options {
|
||||
if o == "ro" {
|
||||
ro = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return ro
|
||||
}
|
||||
isBind := func(m rspec.Mount) bool {
|
||||
var bind bool
|
||||
for _, o := range m.Options {
|
||||
if o == "bind" || o == "rbind" {
|
||||
bind = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return bind
|
||||
}
|
||||
mounts := []*pb.Mount{}
|
||||
for _, b := range m.Mounts {
|
||||
if !isBind(b) {
|
||||
continue
|
||||
}
|
||||
mounts = append(mounts, &pb.Mount{
|
||||
ContainerPath: b.Destination,
|
||||
HostPath: b.Source,
|
||||
Readonly: isRO(b),
|
||||
})
|
||||
}
|
||||
return mounts, nil
|
||||
}
|
||||
|
|
|
@ -17,9 +17,6 @@ func (s *Server) StopContainer(ctx context.Context, req *pb.StopContainerRequest
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.Runtime().UpdateStatus(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cStatus := s.Runtime().ContainerStatus(c)
|
||||
if cStatus.Status != oci.ContainerStateStopped {
|
||||
if err := s.Runtime().StopContainer(c, req.Timeout); err != nil {
|
||||
|
@ -33,6 +30,6 @@ func (s *Server) StopContainer(ctx context.Context, req *pb.StopContainerRequest
|
|||
s.ContainerStateToDisk(c)
|
||||
|
||||
resp := &pb.StopContainerResponse{}
|
||||
logrus.Debugf("StopContainerResponse: %+v", resp)
|
||||
logrus.Debugf("StopContainerResponse %s: %+v", c.ID(), resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
|
|
@ -60,10 +60,6 @@ func (s *Server) ListPodSandbox(ctx context.Context, req *pb.ListPodSandboxReque
|
|||
// it's better not to panic
|
||||
continue
|
||||
}
|
||||
if err := s.Runtime().UpdateStatus(podInfraContainer); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cState := s.Runtime().ContainerStatus(podInfraContainer)
|
||||
created := cState.Created.UnixNano()
|
||||
rStatus := pb.PodSandboxState_SANDBOX_NOTREADY
|
||||
|
|
|
@ -38,15 +38,13 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR
|
|||
|
||||
// Delete all the containers in the sandbox
|
||||
for _, c := range containers {
|
||||
if err := s.Runtime().UpdateStatus(c); err != nil {
|
||||
return nil, fmt.Errorf("failed to update container state: %v", err)
|
||||
}
|
||||
|
||||
cState := s.Runtime().ContainerStatus(c)
|
||||
if cState.Status == oci.ContainerStateCreated || cState.Status == oci.ContainerStateRunning {
|
||||
if err := s.Runtime().StopContainer(c, -1); err != nil {
|
||||
// Assume container is already stopped
|
||||
logrus.Warnf("failed to stop container %s: %v", c.Name(), err)
|
||||
if !sb.Stopped() {
|
||||
cState := s.Runtime().ContainerStatus(c)
|
||||
if cState.Status == oci.ContainerStateCreated || cState.Status == oci.ContainerStateRunning {
|
||||
if err := s.Runtime().StopContainer(c, -1); err != nil {
|
||||
// Assume container is already stopped
|
||||
logrus.Warnf("failed to stop container %s: %v", c.Name(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,19 +78,9 @@ func (s *Server) runContainer(container *oci.Container, cgroupParent string) err
|
|||
if err := s.Runtime().CreateContainer(container, cgroupParent); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Runtime().UpdateStatus(container); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Runtime().StartContainer(container); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Runtime().UpdateStatus(container); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -461,7 +451,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
|
|||
return nil, fmt.Errorf("failed to write runtime configuration for pod sandbox %s(%s): %v", sb.Name(), id, err)
|
||||
}
|
||||
|
||||
container, err := oci.NewContainer(id, containerName, podContainer.RunDir, logPath, sb.NetNs(), labels, kubeAnnotations, "", nil, id, false, false, false, sb.Privileged(), sb.Trusted(), podContainer.Dir, created, podContainer.Config.Config.StopSignal)
|
||||
container, err := oci.NewContainer(id, containerName, podContainer.RunDir, logPath, sb.NetNs(), labels, kubeAnnotations, "", "", "", nil, id, false, false, false, sb.Privileged(), sb.Trusted(), podContainer.Dir, created, podContainer.Config.Config.StopSignal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -16,11 +16,6 @@ func (s *Server) PodSandboxStatus(ctx context.Context, req *pb.PodSandboxStatusR
|
|||
}
|
||||
|
||||
podInfraContainer := sb.InfraContainer()
|
||||
if err = s.Runtime().UpdateStatus(podInfraContainer); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.ContainerStateToDisk(podInfraContainer)
|
||||
|
||||
cState := s.Runtime().ContainerStatus(podInfraContainer)
|
||||
|
||||
netNsPath, err := podInfraContainer.NetNsPath()
|
||||
|
|
|
@ -34,6 +34,13 @@ func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxReque
|
|||
|
||||
resp := &pb.StopPodSandboxResponse{}
|
||||
logrus.Warnf("could not get sandbox %s, it's probably been stopped already: %v", req.PodSandboxId, err)
|
||||
logrus.Debugf("StopPodSandboxResponse %s: %+v", req.PodSandboxId, resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
if sb.Stopped() {
|
||||
resp := &pb.StopPodSandboxResponse{}
|
||||
logrus.Debugf("StopPodSandboxResponse %s: %+v", sb.ID(), resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
@ -70,9 +77,6 @@ func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxReque
|
|||
containers = append(containers, podInfraContainer)
|
||||
|
||||
for _, c := range containers {
|
||||
if err := s.Runtime().UpdateStatus(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cStatus := s.Runtime().ContainerStatus(c)
|
||||
if cStatus.Status != oci.ContainerStateStopped {
|
||||
if err := s.Runtime().StopContainer(c, -1); err != nil {
|
||||
|
@ -113,8 +117,9 @@ func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxReque
|
|||
logrus.Warnf("failed to stop sandbox container in pod sandbox %s: %v", sb.ID(), err)
|
||||
}
|
||||
|
||||
sb.SetStopped()
|
||||
resp := &pb.StopPodSandboxResponse{}
|
||||
logrus.Debugf("StopPodSandboxResponse: %+v", resp)
|
||||
logrus.Debugf("StopPodSandboxResponse %s: %+v", sb.ID(), resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -313,15 +313,28 @@ func (s *Server) StartExitMonitor() {
|
|||
logrus.Debugf("event: %v", event)
|
||||
if event.Op&fsnotify.Create == fsnotify.Create {
|
||||
containerID := filepath.Base(event.Name)
|
||||
logrus.Debugf("container exited: %v", containerID)
|
||||
logrus.Debugf("container or sandbox exited: %v", containerID)
|
||||
c := s.GetContainer(containerID)
|
||||
if c != nil {
|
||||
logrus.Debugf("container exited and found: %v", containerID)
|
||||
err := s.Runtime().UpdateStatus(c)
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to update container status %s: %v", c, err)
|
||||
} else {
|
||||
s.ContainerStateToDisk(c)
|
||||
}
|
||||
} else {
|
||||
sb := s.GetSandbox(containerID)
|
||||
if sb != nil {
|
||||
c := sb.InfraContainer()
|
||||
logrus.Debugf("sandbox exited and found: %v", containerID)
|
||||
err := s.Runtime().UpdateStatus(c)
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to update sandbox infra container status %s: %v", c, err)
|
||||
} else {
|
||||
s.ContainerStateToDisk(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case err := <-watcher.Errors:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue