mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-11-02 03:08:15 +00:00
dockershim: implement ContainerStatus()
This commit is contained in:
@@ -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")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user