dockershim: implement ContainerStatus()

This commit is contained in:
Yu-Ju Hong
2016-07-25 14:39:31 -07:00
parent 7aa592bfa3
commit 03971d3992
5 changed files with 137 additions and 9 deletions

View File

@@ -19,12 +19,15 @@ package dockershim
import (
"fmt"
"io"
"time"
dockertypes "github.com/docker/engine-api/types"
dockercontainer "github.com/docker/engine-api/types/container"
dockerfilters "github.com/docker/engine-api/types/filters"
dockerstrslice "github.com/docker/engine-api/types/strslice"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
"k8s.io/kubernetes/pkg/kubelet/dockertools"
)
// ListContainers lists all containers matching the filter.
@@ -190,14 +193,112 @@ func (ds *dockerService) RemoveContainer(rawContainerID string) error {
return ds.client.RemoveContainer(rawContainerID, dockertypes.ContainerRemoveOptions{RemoveVolumes: true})
}
func getContainerTimestamps(r *dockertypes.ContainerJSON) (time.Time, time.Time, time.Time, error) {
var createdAt, startedAt, finishedAt time.Time
var err error
createdAt, err = dockertools.ParseDockerTimestamp(r.Created)
if err != nil {
return createdAt, startedAt, finishedAt, err
}
startedAt, err = dockertools.ParseDockerTimestamp(r.State.StartedAt)
if err != nil {
return createdAt, startedAt, finishedAt, err
}
finishedAt, err = dockertools.ParseDockerTimestamp(r.State.FinishedAt)
if err != nil {
return createdAt, startedAt, finishedAt, err
}
return createdAt, startedAt, finishedAt, nil
}
// ContainerStatus returns the container status.
// TODO: Implement the function.
func (ds *dockerService) ContainerStatus(rawContainerID string) (*runtimeApi.ContainerStatus, error) {
return nil, fmt.Errorf("not implemented")
r, err := ds.client.InspectContainer(rawContainerID)
if err != nil {
return nil, err
}
// Parse the timstamps.
createdAt, startedAt, finishedAt, err := getContainerTimestamps(r)
if err != nil {
return nil, fmt.Errorf("failed to parse timestamp for container %q: %v", rawContainerID, err)
}
// Convert the mounts.
mounts := []*runtimeApi.Mount{}
for _, m := range r.Mounts {
readonly := !m.RW
mounts = append(mounts, &runtimeApi.Mount{
Name: &m.Name,
HostPath: &m.Source,
ContainerPath: &m.Destination,
Readonly: &readonly,
// Note: Can't set SeLinuxRelabel
})
}
// Interpret container states.
var state runtimeApi.ContainerState
var reason string
if r.State.Running {
// Container is running.
state = runtimeApi.ContainerState_RUNNING
} else {
// Container is *not* running. We need to get more details.
// * Case 1: container has run and exited with non-zero finishedAt
// time.
// * Case 2: container has failed to start; it has a zero finishedAt
// time, but a non-zero exit code.
// * Case 3: container has been created, but not started (yet).
if !finishedAt.IsZero() { // Case 1
state = runtimeApi.ContainerState_EXITED
switch {
case r.State.OOMKilled:
// TODO: consider exposing OOMKilled via the runtimeAPI.
// Note: if an application handles OOMKilled gracefully, the
// exit code could be zero.
reason = "OOMKilled"
case r.State.ExitCode == 0:
reason = "Completed"
default:
reason = fmt.Sprintf("Error: %s", r.State.Error)
}
} else if !finishedAt.IsZero() && r.State.ExitCode != 0 { // Case 2
state = runtimeApi.ContainerState_EXITED
// Adjust finshedAt and startedAt time to createdAt time to avoid
// the confusion.
finishedAt, startedAt = createdAt, createdAt
reason = "ContainerCannotRun"
} else { // Case 3
state = runtimeApi.ContainerState_CREATED
}
}
// Convert to unix timestamps.
ct, st, ft := createdAt.Unix(), startedAt.Unix(), finishedAt.Unix()
exitCode := int32(r.State.ExitCode)
return &runtimeApi.ContainerStatus{
Id: &r.ID,
Name: &r.Name,
Image: &runtimeApi.ImageSpec{Image: &r.Config.Image},
ImageRef: &r.Image,
Mounts: mounts,
ExitCode: &exitCode,
State: &state,
CreatedAt: &ct,
StartedAt: &st,
FinishedAt: &ft,
Reason: &reason,
// TODO: We write annotations as labels on the docker containers. All
// these annotations will be read back as labels. Need to fix this.
Labels: r.Config.Labels,
}, nil
}
// Exec execute a command in the container.
// TODO: Implement the function.
// TODO: Need to handle terminal resizing before implementing this function.
// https://github.com/kubernetes/kubernetes/issues/29579.
func (ds *dockerService) Exec(rawContainerID string, cmd []string, tty bool, stdin io.Reader, stdout, stderr io.WriteCloser) error {
return fmt.Errorf("not implemented")
}