in agent/engine/task_manager.go [433:526]
func (mtask *managedTask) handleContainerChange(containerChange dockerContainerChange) {
// locate the container
container := containerChange.container
runtimeID := container.GetRuntimeID()
event := containerChange.event
containerKnownStatus := container.GetKnownStatus()
if event.Status != containerKnownStatus {
logger.Info("Handling container change event", logger.Fields{
field.TaskARN: mtask.Arn,
field.Container: container.Name,
field.RuntimeID: runtimeID,
field.Status: event.Status.String(),
})
}
found := mtask.isContainerFound(container)
if !found {
logger.Critical("State error; invoked with another task's container!", logger.Fields{
field.TaskARN: mtask.Arn,
field.Container: container.Name,
field.RuntimeID: runtimeID,
field.Status: event.Status.String(),
})
return
}
// If this is a backwards transition stopped->running, the first time set it
// to be known running so it will be stopped. Subsequently ignore these backward transitions
mtask.handleStoppedToRunningContainerTransition(event.Status, container)
if event.Status <= containerKnownStatus {
logger.Debug("Container change is redundant", logger.Fields{
field.TaskARN: mtask.Arn,
field.Container: container.Name,
field.RuntimeID: runtimeID,
field.Status: event.Status.String(),
field.KnownStatus: containerKnownStatus.String(),
})
// Only update container metadata when status stays RUNNING
if event.Status == containerKnownStatus && event.Status == apicontainerstatus.ContainerRunning {
updateContainerMetadata(&event.DockerContainerMetadata, container, mtask.Task)
}
return
}
// Container has progressed its status if we reach here. Make sure to save it to database.
defer mtask.engine.saveContainerData(container)
// Update the container to be known
currentKnownStatus := containerKnownStatus
container.SetKnownStatus(event.Status)
updateContainerMetadata(&event.DockerContainerMetadata, container, mtask.Task)
if event.Error != nil {
proceedAnyway := mtask.handleEventError(containerChange, currentKnownStatus)
if !proceedAnyway {
return
}
}
if execcmd.IsExecEnabledContainer(container) && container.GetKnownStatus() == apicontainerstatus.ContainerStopped {
// if this is an execute-command-enabled container STOPPED event, we should emit a corresponding managedAgent event
mtask.handleManagedAgentStoppedTransition(container, execcmd.ExecuteCommandAgentName)
}
mtask.RecordExecutionStoppedAt(container)
logger.Debug("Sending container change event to tcs", logger.Fields{
field.TaskARN: mtask.Arn,
field.Container: container.Name,
field.RuntimeID: runtimeID,
field.Status: event.Status.String(),
})
err := mtask.containerChangeEventStream.WriteToEventStream(event)
if err != nil {
logger.Warn("Failed to write container change event to tcs event stream",
logger.Fields{
field.TaskARN: mtask.Arn,
field.Container: container.Name,
field.RuntimeID: runtimeID,
field.Error: err,
})
}
mtask.emitContainerEvent(mtask.Task, container, "")
if mtask.UpdateStatus() {
// If knownStatus changed, let it be known
var taskStateChangeReason string
if mtask.GetKnownStatus().Terminal() {
taskStateChangeReason = mtask.Task.GetTerminalReason()
}
mtask.emitTaskEvent(mtask.Task, taskStateChangeReason)
// Save the new task status to database.
mtask.engine.saveTaskData(mtask.Task)
}
}