Merge pull request #1351 from Random-Liu/better-unknown-state-handling

Better handle unknown state.
This commit is contained in:
Lantao Liu 2019-12-09 10:34:57 -08:00 committed by GitHub
commit 78708b20c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 1 deletions

View File

@ -333,6 +333,12 @@ func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr conta
status.Pid = 0 status.Pid = 0
status.FinishedAt = e.ExitedAt.UnixNano() status.FinishedAt = e.ExitedAt.UnixNano()
status.ExitCode = int32(e.ExitStatus) status.ExitCode = int32(e.ExitStatus)
// Unknown state can only transit to EXITED state, so we need
// to handle unknown state here.
if status.Unknown {
logrus.Debugf("Container %q transited from UNKNOWN to EXITED", cntr.ID)
status.Unknown = false
}
return status, nil return status, nil
}) })
if err != nil { if err != nil {

View File

@ -359,6 +359,7 @@ func unknownContainerStatus() containerstore.Status {
FinishedAt: 0, FinishedAt: 0,
ExitCode: unknownExitCode, ExitCode: unknownExitCode,
Reason: unknownExitReason, Reason: unknownExitReason,
Unknown: true,
} }
} }

View File

@ -308,7 +308,9 @@ func (c *criService) loadContainer(ctx context.Context, cntr containerd.Containe
}() }()
if err != nil { if err != nil {
log.G(ctx).WithError(err).Errorf("Failed to load container status for %q", id) log.G(ctx).WithError(err).Errorf("Failed to load container status for %q", id)
status = unknownContainerStatus() // Only set the unknown field in this case, because other fields may
// contain useful information loaded from the checkpoint.
status.Unknown = true
} }
opts := []containerstore.Opts{ opts := []containerstore.Opts{
containerstore.WithStatus(status, containerDir), containerstore.WithStatus(status, containerDir),

View File

@ -94,10 +94,16 @@ type Status struct {
// Removing indicates that the container is in removing state. // Removing indicates that the container is in removing state.
// This field doesn't need to be checkpointed. // This field doesn't need to be checkpointed.
Removing bool `json:"-"` Removing bool `json:"-"`
// Unknown indicates that the container status is not fully loaded.
// This field doesn't need to be checkpointed.
Unknown bool `json:"-"`
} }
// State returns current state of the container based on the container status. // State returns current state of the container based on the container status.
func (s Status) State() runtime.ContainerState { func (s Status) State() runtime.ContainerState {
if s.Unknown {
return runtime.ContainerState_CONTAINER_UNKNOWN
}
if s.FinishedAt != 0 { if s.FinishedAt != 0 {
return runtime.ContainerState_CONTAINER_EXITED return runtime.ContainerState_CONTAINER_EXITED
} }

View File

@ -36,6 +36,12 @@ func TestContainerState(t *testing.T) {
state runtime.ContainerState state runtime.ContainerState
}{ }{
"unknown state": { "unknown state": {
status: Status{
Unknown: true,
},
state: runtime.ContainerState_CONTAINER_UNKNOWN,
},
"unknown state because there is no timestamp set": {
status: Status{}, status: Status{},
state: runtime.ContainerState_CONTAINER_UNKNOWN, state: runtime.ContainerState_CONTAINER_UNKNOWN,
}, },
@ -76,6 +82,7 @@ func TestStatusEncodeDecode(t *testing.T) {
Message: "test-message", Message: "test-message",
Removing: true, Removing: true,
Starting: true, Starting: true,
Unknown: true,
} }
assert := assertlib.New(t) assert := assertlib.New(t)
data, err := s.encode() data, err := s.encode()
@ -84,6 +91,7 @@ func TestStatusEncodeDecode(t *testing.T) {
assert.NoError(newS.decode(data)) assert.NoError(newS.decode(data))
s.Removing = false // Removing should not be encoded. s.Removing = false // Removing should not be encoded.
s.Starting = false // Starting should not be encoded. s.Starting = false // Starting should not be encoded.
s.Unknown = false // Unknown should not be encoded.
assert.Equal(s, newS) assert.Equal(s, newS)
unsupported, err := json.Marshal(&versionedStatus{ unsupported, err := json.Marshal(&versionedStatus{