Commit 73776995 authored by Yu-Ju Hong's avatar Yu-Ju Hong

CRI: add Message in ContainerStatus

Kubernetes expects a brief CamelCase string as "Reason" and a human-readable string as "Message" in the conatiner status. It is difficult for kubelet to derive the other one if the runtime only provides one of the two fields. Augment the API by adding the "Message" field.
parent 501f2647
...@@ -571,14 +571,17 @@ message ContainerStatus { ...@@ -571,14 +571,17 @@ message ContainerStatus {
// Reference to the image in use. For most runtimes, this should be an // Reference to the image in use. For most runtimes, this should be an
// image ID // image ID
optional string image_ref = 9; optional string image_ref = 9;
// A string explains why container is in such a status. // A brief CamelCase string explains why container is in such a status.
optional string reason = 10; optional string reason = 10;
// A human-readable message indication details about why container is in
// this state.
optional string message = 11;
// Labels are key value pairs that may be used to scope and select individual resources. // Labels are key value pairs that may be used to scope and select individual resources.
map<string,string> labels = 11; map<string,string> labels = 12;
// Annotations is an unstructured key value map. // Annotations is an unstructured key value map.
map<string,string> annotations = 12; map<string,string> annotations = 13;
// Mounts specifies mounts for the container // Mounts specifies mounts for the container
repeated Mount mounts = 13; repeated Mount mounts = 14;
} }
message ContainerStatusResponse { message ContainerStatusResponse {
......
...@@ -239,7 +239,7 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai ...@@ -239,7 +239,7 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai
} }
// Interpret container states. // Interpret container states.
var state runtimeApi.ContainerState var state runtimeApi.ContainerState
var reason string var reason, message string
if r.State.Running { if r.State.Running {
// Container is running. // Container is running.
state = runtimeApi.ContainerState_RUNNING state = runtimeApi.ContainerState_RUNNING
...@@ -261,9 +261,9 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai ...@@ -261,9 +261,9 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai
case r.State.ExitCode == 0: case r.State.ExitCode == 0:
reason = "Completed" reason = "Completed"
default: default:
reason = fmt.Sprintf("Error: %s", r.State.Error) reason = "Error"
} }
} else if !finishedAt.IsZero() && r.State.ExitCode != 0 { // Case 2 } else if r.State.ExitCode != 0 { // Case 2
state = runtimeApi.ContainerState_EXITED state = runtimeApi.ContainerState_EXITED
// Adjust finshedAt and startedAt time to createdAt time to avoid // Adjust finshedAt and startedAt time to createdAt time to avoid
// the confusion. // the confusion.
...@@ -272,6 +272,7 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai ...@@ -272,6 +272,7 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai
} else { // Case 3 } else { // Case 3
state = runtimeApi.ContainerState_CREATED state = runtimeApi.ContainerState_CREATED
} }
message = r.State.Error
} }
// Convert to unix timestamps. // Convert to unix timestamps.
...@@ -296,6 +297,7 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai ...@@ -296,6 +297,7 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai
StartedAt: &st, StartedAt: &st,
FinishedAt: &ft, FinishedAt: &ft,
Reason: &reason, Reason: &reason,
Message: &message,
Labels: labels, Labels: labels,
Annotations: annotations, Annotations: annotations,
}, nil }, nil
......
...@@ -104,7 +104,7 @@ func TestContainerStatus(t *testing.T) { ...@@ -104,7 +104,7 @@ func TestContainerStatus(t *testing.T) {
// The following variables are not set in FakeDockerClient. // The following variables are not set in FakeDockerClient.
imageRef := "" imageRef := ""
exitCode := int32(0) exitCode := int32(0)
reason := "" var reason, message string
expected := &runtimeApi.ContainerStatus{ expected := &runtimeApi.ContainerStatus{
State: &state, State: &state,
...@@ -116,6 +116,7 @@ func TestContainerStatus(t *testing.T) { ...@@ -116,6 +116,7 @@ func TestContainerStatus(t *testing.T) {
ImageRef: &imageRef, ImageRef: &imageRef,
ExitCode: &exitCode, ExitCode: &exitCode,
Reason: &reason, Reason: &reason,
Message: &message,
Mounts: []*runtimeApi.Mount{}, Mounts: []*runtimeApi.Mount{},
Labels: config.Labels, Labels: config.Labels,
Annotations: config.Annotations, Annotations: config.Annotations,
......
...@@ -377,11 +377,16 @@ func (m *kubeGenericRuntimeManager) getKubeletContainerStatuses(podSandboxID str ...@@ -377,11 +377,16 @@ func (m *kubeGenericRuntimeManager) getKubeletContainerStatuses(podSandboxID str
cStatus.StartedAt = time.Unix(status.GetStartedAt(), 0) cStatus.StartedAt = time.Unix(status.GetStartedAt(), 0)
} else { } else {
cStatus.Reason = status.GetReason() cStatus.Reason = status.GetReason()
cStatus.Message = status.GetMessage()
cStatus.ExitCode = int(status.GetExitCode()) cStatus.ExitCode = int(status.GetExitCode())
cStatus.FinishedAt = time.Unix(status.GetFinishedAt(), 0) cStatus.FinishedAt = time.Unix(status.GetFinishedAt(), 0)
} }
cStatus.Message = getTerminationMessage(status, cStatus, annotatedInfo.TerminationMessagePath) tMessage := getTerminationMessage(status, cStatus, annotatedInfo.TerminationMessagePath)
// Use the termination message written by the application is not empty
if len(tMessage) != 0 {
cStatus.Message = tMessage
}
statuses[i] = cStatus statuses[i] = cStatus
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment