Skip to content

Commit 4a5ca7c

Browse files
committed
Add ContainerManifestPulled and TaskManifestPulled states
1 parent 22af4f2 commit 4a5ca7c

File tree

20 files changed

+575
-101
lines changed

20 files changed

+575
-101
lines changed

agent/api/container/container_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ func TestIsKnownSteadyState(t *testing.T) {
9696
func TestGetNextStateProgression(t *testing.T) {
9797
// This creates a container with `iota` ContainerStatus (NONE)
9898
container := &Container{}
99-
// NONE should transition to PULLED
99+
// NONE should transition to MANIFEST_PULLED
100+
assert.Equal(t, container.GetNextKnownStateProgression(), apicontainerstatus.ContainerManifestPulled)
101+
container.SetKnownStatus(apicontainerstatus.ContainerManifestPulled)
102+
// MANIFEST_PULLED should transition to PULLED
100103
assert.Equal(t, container.GetNextKnownStateProgression(), apicontainerstatus.ContainerPulled)
101104
container.SetKnownStatus(apicontainerstatus.ContainerPulled)
102105
// PULLED should transition to CREATED

agent/api/task/task.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ func (task *Task) initializeASMAuthResource(credentialsManager credentials.Manag
10521052
if container.ShouldPullWithASMAuth() {
10531053
container.BuildResourceDependency(asmAuthResource.GetName(),
10541054
resourcestatus.ResourceStatus(asmauth.ASMAuthStatusCreated),
1055-
apicontainerstatus.ContainerPulled)
1055+
apicontainerstatus.ContainerManifestPulled)
10561056
}
10571057
}
10581058
}

agent/api/task/task_test.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -2842,8 +2842,18 @@ func TestPostUnmarshalTaskASMDockerAuth(t *testing.T) {
28422842
},
28432843
}
28442844

2845+
resourceDep := apicontainer.ResourceDependency{
2846+
Name: asmauth.ResourceName,
2847+
RequiredStatus: resourcestatus.ResourceStatus(asmauth.ASMAuthStatusCreated),
2848+
}
2849+
28452850
err := task.PostUnmarshalTask(cfg, credentialsManager, resFields, nil, nil)
2846-
assert.NoError(t, err)
2851+
require.NoError(t, err)
2852+
assert.Equal(t,
2853+
resourceDep,
2854+
task.Containers[0].
2855+
TransitionDependenciesMap[apicontainerstatus.ContainerManifestPulled].
2856+
ResourceDependencies[0])
28472857
}
28482858

28492859
func TestPostUnmarshalTaskSecret(t *testing.T) {

agent/engine/dependencygraph/graph.go

+6
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,12 @@ func containerOrderingDependenciesIsResolved(target *apicontainer.Container,
415415
targetContainerKnownStatus := target.GetKnownStatus()
416416
dependsOnContainerKnownStatus := dependsOnContainer.GetKnownStatus()
417417

418+
// Containers are allowed to transition to MANIFEST_PULLED irrespective of any container
419+
// ordering dependencies.
420+
if targetContainerKnownStatus < apicontainerstatus.ContainerManifestPulled {
421+
return true
422+
}
423+
418424
// The 'target' container desires to be moved to 'Created' or the 'steady' state.
419425
// Allow this only if the environment variable ECS_PULL_DEPENDENT_CONTAINERS_UPFRONT is enabled and
420426
// known status of the `target` container state has not reached to 'Pulled' state;

agent/engine/dependencygraph/graph_test.go

+239-20
Large diffs are not rendered by default.

agent/engine/dependencygraph/graph_unix_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ func TestVerifyCgroupDependenciesResolved(t *testing.T) {
4444
DependencyKnown: resourcestatus.ResourceStatus(cgroup.CgroupStatusNone),
4545
RequiredStatus: resourcestatus.ResourceStatus(cgroup.CgroupCreated),
4646

47+
ExpectedResolved: true,
48+
},
49+
{
50+
Name: "resource none,container pull depends on resource created",
51+
TargetKnown: apicontainerstatus.ContainerManifestPulled,
52+
TargetDep: apicontainerstatus.ContainerPulled,
53+
DependencyKnown: resourcestatus.ResourceStatus(cgroup.CgroupStatusNone),
54+
RequiredStatus: resourcestatus.ResourceStatus(cgroup.CgroupCreated),
4755
ExpectedResolved: false,
4856
},
4957
{

agent/engine/docker_task_engine.go

+14
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ func (engine *DockerTaskEngine) reconcileHostResources() {
289289

290290
func (engine *DockerTaskEngine) initializeContainerStatusToTransitionFunction() {
291291
containerStatusToTransitionFunction := map[apicontainerstatus.ContainerStatus]transitionApplyFunc{
292+
apicontainerstatus.ContainerManifestPulled: engine.pullContainerManifest,
292293
apicontainerstatus.ContainerPulled: engine.pullContainer,
293294
apicontainerstatus.ContainerCreated: engine.createContainer,
294295
apicontainerstatus.ContainerRunning: engine.startContainer,
@@ -1231,6 +1232,19 @@ func (engine *DockerTaskEngine) GetDaemonManagers() map[string]dm.DaemonManager
12311232
return engine.daemonManagers
12321233
}
12331234

1235+
// Pulls the manifest of the container image.
1236+
func (engine *DockerTaskEngine) pullContainerManifest(
1237+
task *apitask.Task, container *apicontainer.Container,
1238+
) dockerapi.DockerContainerMetadata {
1239+
// Currently a no-op
1240+
logger.Debug("Manifest pull is currently a no-op", logger.Fields{
1241+
field.TaskID: task.GetID(),
1242+
field.Container: container.Name,
1243+
field.Image: container.Image,
1244+
})
1245+
return dockerapi.DockerContainerMetadata{}
1246+
}
1247+
12341248
func (engine *DockerTaskEngine) pullContainer(task *apitask.Task, container *apicontainer.Container) dockerapi.DockerContainerMetadata {
12351249
switch container.Type {
12361250
case apicontainer.ContainerCNIPause, apicontainer.ContainerNamespacePause, apicontainer.ContainerServiceConnectRelay, apicontainer.ContainerManagedDaemon:

agent/engine/task_manager.go

+10-7
Original file line numberDiff line numberDiff line change
@@ -620,8 +620,9 @@ func (mtask *managedTask) emitTaskEvent(task *apitask.Task, reason string) {
620620
}
621621
if !taskKnownStatus.BackendRecognized() {
622622
logger.Debug("Skipping event emission for task", logger.Fields{
623-
field.TaskID: mtask.GetID(),
624-
field.Error: "status not recognized by ECS",
623+
field.TaskID: mtask.GetID(),
624+
field.Error: "status not recognized by ECS",
625+
field.KnownStatus: taskKnownStatus.String(),
625626
})
626627
return
627628
}
@@ -862,34 +863,36 @@ func (mtask *managedTask) handleEventError(containerChange dockerContainerChange
862863
switch event.Status {
863864
// event.Status is the desired container transition from container's known status
864865
// (* -> event.Status)
865-
case apicontainerstatus.ContainerPulled:
866+
case apicontainerstatus.ContainerManifestPulled, apicontainerstatus.ContainerPulled:
866867
// If the agent pull behavior is always or once, we receive the error because
867-
// the image pull fails, the task should fail. If we don't fail task here,
868+
// the image or manifest pull fails, the task should fail. If we don't fail task here,
868869
// then the cached image will probably be used for creating container, and we
869870
// don't want to use cached image for both cases.
870871
if mtask.cfg.ImagePullBehavior == config.ImagePullAlwaysBehavior ||
871872
mtask.cfg.ImagePullBehavior == config.ImagePullOnceBehavior {
872-
logger.Error("Error while pulling image; moving task to STOPPED", logger.Fields{
873+
logger.Error("Error while pulling image or its manifest; moving task to STOPPED", logger.Fields{
873874
field.TaskID: mtask.GetID(),
874875
field.Image: container.Image,
875876
field.Container: container.Name,
876877
field.Error: event.Error,
878+
field.Status: event.Status,
877879
})
878880
// The task should be stopped regardless of whether this container is
879881
// essential or non-essential.
880882
mtask.SetDesiredStatus(apitaskstatus.TaskStopped)
881883
return false
882884
}
883885
// If the agent pull behavior is prefer-cached, we receive the error because
884-
// the image pull fails and there is no cached image in local, we don't make
886+
// the image or manifest pull fails and there is no cached image in local, we don't make
885887
// the task fail here, will let create container handle it instead.
886888
// If the agent pull behavior is default, use local image cache directly,
887889
// assuming it exists.
888-
logger.Error("Error while pulling image; will try to run anyway", logger.Fields{
890+
logger.Error("Error while pulling image or its manifest; will try to run anyway", logger.Fields{
889891
field.TaskID: mtask.GetID(),
890892
field.Image: container.Image,
891893
field.Container: container.Name,
892894
field.Error: event.Error,
895+
field.Status: event.Status,
893896
})
894897
// proceed anyway
895898
return true

0 commit comments

Comments
 (0)