cri-o/server/container_status.go
Nalin Dahyabhai f3b7065bd8 Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.

In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.

In Server.ListImages(), be sure to only return tagged names in the
RepoTags field.  In Server.ImageStatus(), also return canonical
references in the RepoDigests field.

In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:52 -05:00

105 lines
2.9 KiB
Go

package server
import (
"time"
"github.com/containers/image/types"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
)
const (
oomKilledReason = "OOMKilled"
completedReason = "Completed"
errorReason = "Error"
)
// ContainerStatus returns status of the container.
func (s *Server) ContainerStatus(ctx context.Context, req *pb.ContainerStatusRequest) (resp *pb.ContainerStatusResponse, err error) {
const operation = "container_status"
defer func() {
recordOperation(operation, time.Now())
recordError(operation, err)
}()
logrus.Debugf("ContainerStatusRequest %+v", req)
c, err := s.GetContainerFromRequest(req.ContainerId)
if err != nil {
return nil, err
}
containerID := c.ID()
resp = &pb.ContainerStatusResponse{
Status: &pb.ContainerStatus{
Id: containerID,
Metadata: c.Metadata(),
Labels: c.Labels(),
Annotations: c.Annotations(),
ImageRef: c.ImageRef(),
},
}
resp.Status.Image = &pb.ImageSpec{Image: c.Image()}
if status, err := s.StorageImageServer().ImageStatus(&types.SystemContext{}, c.ImageRef()); err == nil {
resp.Status.Image.Image = status.Name
}
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
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.
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
created := cState.Created.UnixNano()
resp.Status.CreatedAt = created
case oci.ContainerStateRunning:
rStatus = pb.ContainerState_CONTAINER_RUNNING
created := cState.Created.UnixNano()
resp.Status.CreatedAt = created
started := cState.Started.UnixNano()
resp.Status.StartedAt = started
case oci.ContainerStateStopped:
rStatus = pb.ContainerState_CONTAINER_EXITED
created := cState.Created.UnixNano()
resp.Status.CreatedAt = created
started := cState.Started.UnixNano()
resp.Status.StartedAt = started
finished := cState.Finished.UnixNano()
resp.Status.FinishedAt = finished
resp.Status.ExitCode = cState.ExitCode
switch {
case cState.OOMKilled:
resp.Status.Reason = oomKilledReason
case cState.ExitCode == 0:
resp.Status.Reason = completedReason
default:
resp.Status.Reason = errorReason
resp.Status.Message = cState.Error
}
}
resp.Status.State = rStatus
logrus.Debugf("ContainerStatusResponse: %+v", resp)
return resp, nil
}