diff --git a/agent/acs/update_handler/updater_test.go b/agent/acs/update_handler/updater_test.go index b93a2d74cf..739a7674b9 100644 --- a/agent/acs/update_handler/updater_test.go +++ b/agent/acs/update_handler/updater_test.go @@ -128,7 +128,7 @@ func TestPerformUpdateWithUpdatesDisabled(t *testing.T) { Reason: ptr("Updates are disabled").(*string), }}) - taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) msg := &ecsacs.PerformUpdateMessage{ ClusterArn: ptr("cluster").(*string), ContainerInstanceArn: ptr("containerInstance").(*string), @@ -182,7 +182,7 @@ func TestFullUpdateFlow(t *testing.T) { require.Equal(t, "update-tar-data", writtenFile.String(), "incorrect data written") - taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) msg := &ecsacs.PerformUpdateMessage{ ClusterArn: ptr("cluster").(*string), ContainerInstanceArn: ptr("containerInstance").(*string), @@ -250,7 +250,7 @@ func TestUndownloadedUpdate(t *testing.T) { MessageId: ptr("mid").(*string), }}) - taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) msg := &ecsacs.PerformUpdateMessage{ ClusterArn: ptr("cluster").(*string), ContainerInstanceArn: ptr("containerInstance").(*string), @@ -308,7 +308,7 @@ func TestDuplicateUpdateMessagesWithSuccess(t *testing.T) { require.Equal(t, "update-tar-data", writtenFile.String(), "incorrect data written") - taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) msg := &ecsacs.PerformUpdateMessage{ ClusterArn: ptr("cluster").(*string), ContainerInstanceArn: ptr("containerInstance").(*string), @@ -377,7 +377,7 @@ func TestDuplicateUpdateMessagesWithFailure(t *testing.T) { require.Equal(t, "update-tar-data", writtenFile.String(), "incorrect data written") - taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) msg := &ecsacs.PerformUpdateMessage{ ClusterArn: ptr("cluster").(*string), ContainerInstanceArn: ptr("containerInstance").(*string), @@ -448,7 +448,7 @@ func TestNewerUpdateMessages(t *testing.T) { require.Equal(t, "newer-update-tar-data", writtenFile.String(), "incorrect data written") - taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) msg := &ecsacs.PerformUpdateMessage{ ClusterArn: ptr("cluster").(*string), ContainerInstanceArn: ptr("containerInstance").(*string), diff --git a/agent/api/ecsclient/client.go b/agent/api/ecsclient/client.go index dc808ef756..71d970f86e 100644 --- a/agent/api/ecsclient/client.go +++ b/agent/api/ecsclient/client.go @@ -306,6 +306,20 @@ func (client *APIECSClient) getResources() ([]*ecs.Resource, error) { return []*ecs.Resource{&cpuResource, &memResource, &portResource, &udpPortResource}, nil } +// GetHostResources calling getHostResources to get a list of CPU, MEMORY, PORTS and PORTS_UPD resources +// and return a resourceMap that map the resource name to each resource +func (client *APIECSClient) GetHostResources() (map[string]*ecs.Resource, error) { + resources, err := client.getResources() + if err != nil { + return nil, err + } + resourceMap := make(map[string]*ecs.Resource) + for _, resource := range resources { + resourceMap[*resource.Name] = resource + } + return resourceMap, nil +} + func getCpuAndMemory() (int64, int64) { memInfo, err := system.ReadMemInfo() mem := int64(0) diff --git a/agent/api/interface.go b/agent/api/interface.go index 6b39e1e92c..8455d48083 100644 --- a/agent/api/interface.go +++ b/agent/api/interface.go @@ -57,6 +57,8 @@ type ECSClient interface { // UpdateContainerInstancesState updates the given container Instance ID with // the given status. Only valid statuses are ACTIVE and DRAINING. UpdateContainerInstancesState(instanceARN, status string) error + // GetHostResources retrieves a map that map the resource name to the corresponding resource + GetHostResources() (map[string]*ecs.Resource, error) } // ECSSDK is an interface that specifies the subset of the AWS Go SDK's ECS diff --git a/agent/api/mocks/api_mocks.go b/agent/api/mocks/api_mocks.go index 9d80f92e00..851e1ee439 100644 --- a/agent/api/mocks/api_mocks.go +++ b/agent/api/mocks/api_mocks.go @@ -263,6 +263,21 @@ func (mr *MockECSClientMockRecorder) DiscoverTelemetryEndpoint(arg0 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DiscoverTelemetryEndpoint", reflect.TypeOf((*MockECSClient)(nil).DiscoverTelemetryEndpoint), arg0) } +// GetHostResources mocks base method. +func (m *MockECSClient) GetHostResources() (map[string]*ecs.Resource, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetHostResources") + ret0, _ := ret[0].(map[string]*ecs.Resource) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetHostResources indicates an expected call of GetHostResources. +func (mr *MockECSClientMockRecorder) GetHostResources() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHostResources", reflect.TypeOf((*MockECSClient)(nil).GetHostResources)) +} + // GetResourceTags mocks base method. func (m *MockECSClient) GetResourceTags(arg0 string) ([]*ecs.Tag, error) { m.ctrl.T.Helper() diff --git a/agent/app/agent.go b/agent/app/agent.go index fa6d73c1c6..2311d8f57d 100644 --- a/agent/app/agent.go +++ b/agent/app/agent.go @@ -306,17 +306,36 @@ func (agent *ecsAgent) doStart(containerChangeEventStream *eventstream.EventStre return exitcodes.ExitTerminal } } + hostResources, err := client.GetHostResources() + if err != nil { + seelog.Critical("Unable to fetch host resources") + return exitcodes.ExitError + } + numGPUs := int64(0) if agent.cfg.GPUSupportEnabled { err := agent.initializeGPUManager() if err != nil { seelog.Criticalf("Could not initialize Nvidia GPU Manager: %v", err) return exitcodes.ExitError } + // Find number of GPUs instance has + platformDevices := agent.getPlatformDevices() + for _, device := range platformDevices { + if *device.Type == ecs.PlatformDeviceTypeGpu { + numGPUs++ + } + } + } + + hostResources["GPU"] = &ecs.Resource{ + Name: utils.Strptr("GPU"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &numGPUs, } // Create the task engine taskEngine, currentEC2InstanceID, err := agent.newTaskEngine( - containerChangeEventStream, credentialsManager, state, imageManager, execCmdMgr, agent.serviceconnectManager) + containerChangeEventStream, credentialsManager, state, imageManager, hostResources, execCmdMgr, agent.serviceconnectManager) if err != nil { seelog.Criticalf("Unable to initialize new task engine: %v", err) return exitcodes.ExitTerminal @@ -523,6 +542,7 @@ func (agent *ecsAgent) newTaskEngine(containerChangeEventStream *eventstream.Eve credentialsManager credentials.Manager, state dockerstate.TaskEngineState, imageManager engine.ImageManager, + hostResources map[string]*ecs.Resource, execCmdMgr execcmd.Manager, serviceConnectManager engineserviceconnect.Manager) (engine.TaskEngine, string, error) { @@ -531,11 +551,11 @@ func (agent *ecsAgent) newTaskEngine(containerChangeEventStream *eventstream.Eve if !agent.cfg.Checkpoint.Enabled() { seelog.Info("Checkpointing not enabled; a new container instance will be created each time the agent is run") return engine.NewTaskEngine(agent.cfg, agent.dockerClient, credentialsManager, - containerChangeEventStream, imageManager, state, + containerChangeEventStream, imageManager, hostResources, state, agent.metadataManager, agent.resourceFields, execCmdMgr, serviceConnectManager), "", nil } - savedData, err := agent.loadData(containerChangeEventStream, credentialsManager, state, imageManager, execCmdMgr, serviceConnectManager) + savedData, err := agent.loadData(containerChangeEventStream, credentialsManager, state, imageManager, hostResources, execCmdMgr, serviceConnectManager) if err != nil { seelog.Criticalf("Error loading previously saved state: %v", err) return nil, "", err @@ -560,7 +580,7 @@ func (agent *ecsAgent) newTaskEngine(containerChangeEventStream *eventstream.Eve state.Reset() // Reset taskEngine; all the other values are still default return engine.NewTaskEngine(agent.cfg, agent.dockerClient, credentialsManager, - containerChangeEventStream, imageManager, state, agent.metadataManager, + containerChangeEventStream, imageManager, hostResources, state, agent.metadataManager, agent.resourceFields, execCmdMgr, serviceConnectManager), currentEC2InstanceID, nil } diff --git a/agent/app/agent_compatibility_linux_test.go b/agent/app/agent_compatibility_linux_test.go index b7833d0a16..6b45034214 100644 --- a/agent/app/agent_compatibility_linux_test.go +++ b/agent/app/agent_compatibility_linux_test.go @@ -65,7 +65,8 @@ func TestCompatibilityEnabledSuccess(t *testing.T) { defer cancel() containerChangeEventStream := eventstream.NewEventStream("events", ctx) - _, _, err := agent.newTaskEngine(containerChangeEventStream, creds, dockerstate.NewTaskEngineState(), images, execCmdMgr, serviceConnectManager) + hostResources := getTestHostResources() + _, _, err := agent.newTaskEngine(containerChangeEventStream, creds, dockerstate.NewTaskEngineState(), images, hostResources, execCmdMgr, serviceConnectManager) assert.NoError(t, err) assert.True(t, cfg.TaskCPUMemLimit.Enabled()) @@ -106,7 +107,8 @@ func TestCompatibilityNotSetFail(t *testing.T) { defer cancel() containerChangeEventStream := eventstream.NewEventStream("events", ctx) - _, _, err := agent.newTaskEngine(containerChangeEventStream, creds, dockerstate.NewTaskEngineState(), images, execCmdMgr, serviceConnectManager) + hostResources := getTestHostResources() + _, _, err := agent.newTaskEngine(containerChangeEventStream, creds, dockerstate.NewTaskEngineState(), images, hostResources, execCmdMgr, serviceConnectManager) assert.NoError(t, err) assert.False(t, cfg.TaskCPUMemLimit.Enabled()) @@ -146,7 +148,8 @@ func TestCompatibilityExplicitlyEnabledFail(t *testing.T) { defer cancel() containerChangeEventStream := eventstream.NewEventStream("events", ctx) - _, _, err := agent.newTaskEngine(containerChangeEventStream, creds, dockerstate.NewTaskEngineState(), images, execCmdMgr, serviceConnectManager) + hostResources := getTestHostResources() + _, _, err := agent.newTaskEngine(containerChangeEventStream, creds, dockerstate.NewTaskEngineState(), images, hostResources, execCmdMgr, serviceConnectManager) assert.Error(t, err) } diff --git a/agent/app/agent_test.go b/agent/app/agent_test.go index 7f2ffd50f8..a7fec4d4a5 100644 --- a/agent/app/agent_test.go +++ b/agent/app/agent_test.go @@ -44,6 +44,7 @@ import ( "github.com/aws/amazon-ecs-agent/agent/sighandlers/exitcodes" "github.com/aws/amazon-ecs-agent/agent/statemanager" mock_statemanager "github.com/aws/amazon-ecs-agent/agent/statemanager/mocks" + "github.com/aws/amazon-ecs-agent/agent/utils" mock_loader "github.com/aws/amazon-ecs-agent/agent/utils/loader/mocks" mock_mobypkgwrapper "github.com/aws/amazon-ecs-agent/agent/utils/mobypkgwrapper/mocks" "github.com/aws/amazon-ecs-agent/agent/version" @@ -78,6 +79,20 @@ var apiVersions = []dockerclient.DockerVersion{ dockerclient.Version_1_22, dockerclient.Version_1_23} var capabilities []*ecs.Attribute +var testHostCPU = int64(1024) +var testHostMEMORY = int64(1024) +var testHostResource = map[string]*ecs.Resource{ + "CPU": &ecs.Resource{ + Name: utils.Strptr("CPU"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &testHostCPU, + }, + "MEMORY": &ecs.Resource{ + Name: utils.Strptr("MEMORY"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &testHostMEMORY, + }, +} func setup(t *testing.T) (*gomock.Controller, *mock_credentials.MockManager, @@ -169,6 +184,7 @@ func TestDoStartNewTaskEngineError(t *testing.T) { ec2MetadataClient := mock_ec2.NewMockEC2MetadataClient(ctrl) gomock.InOrder( dockerClient.EXPECT().SupportedVersions().Return(apiVersions), + client.EXPECT().GetHostResources().Return(testHostResource, nil), saveableOptionFactory.EXPECT().AddSaveable("TaskEngine", gomock.Any()).Return(nil), saveableOptionFactory.EXPECT().AddSaveable("ContainerInstanceArn", gomock.Any()).Return(nil), saveableOptionFactory.EXPECT().AddSaveable("Cluster", gomock.Any()).Return(nil), @@ -225,6 +241,7 @@ func TestDoStartRegisterContainerInstanceErrorTerminal(t *testing.T) { mockServiceConnectManager.EXPECT().SetECSClient(gomock.Any(), gomock.Any()).AnyTimes() gomock.InOrder( dockerClient.EXPECT().SupportedVersions().Return(apiVersions), + client.EXPECT().GetHostResources().Return(testHostResource, nil), mockCredentialsProvider.EXPECT().Retrieve().Return(aws_credentials.Value{}, nil), dockerClient.EXPECT().SupportedVersions().Return(nil), dockerClient.EXPECT().KnownVersions().Return(nil), @@ -281,6 +298,7 @@ func TestDoStartRegisterContainerInstanceErrorNonTerminal(t *testing.T) { mockServiceConnectManager.EXPECT().SetECSClient(gomock.Any(), gomock.Any()).AnyTimes() gomock.InOrder( dockerClient.EXPECT().SupportedVersions().Return(apiVersions), + client.EXPECT().GetHostResources().Return(testHostResource, nil), mockCredentialsProvider.EXPECT().Retrieve().Return(aws_credentials.Value{}, nil), dockerClient.EXPECT().SupportedVersions().Return(nil), dockerClient.EXPECT().KnownVersions().Return(nil), @@ -322,6 +340,7 @@ func TestDoStartWarmPoolsError(t *testing.T) { mockEC2Metadata := mock_ec2.NewMockEC2MetadataClient(ctrl) gomock.InOrder( dockerClient.EXPECT().SupportedVersions().Return(apiVersions), + client.EXPECT().GetHostResources().Return(testHostResource, nil), ) cfg := getTestConfig() @@ -441,6 +460,7 @@ func testDoStartHappyPathWithConditions(t *testing.T, blackholed bool, warmPools gomock.InOrder( dockerClient.EXPECT().SupportedVersions().Return(apiVersions), + client.EXPECT().GetHostResources().Return(testHostResource, nil), mockCredentialsProvider.EXPECT().Retrieve().Return(aws_credentials.Value{}, nil), dockerClient.EXPECT().SupportedVersions().Return(nil), dockerClient.EXPECT().KnownVersions().Return(nil), @@ -562,8 +582,10 @@ func TestNewTaskEngineRestoreFromCheckpointNoEC2InstanceIDToLoadHappyPath(t *tes saveableOptionFactory: saveableOptionFactory, } + hostResources := getTestHostResources() + _, instanceID, err := agent.newTaskEngine(eventstream.NewEventStream("events", ctx), - credentialsManager, dockerstate.NewTaskEngineState(), imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, dockerstate.NewTaskEngineState(), imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.NoError(t, err) assert.Equal(t, expectedInstanceID, instanceID) assert.Equal(t, "prev-container-inst", agent.containerInstanceARN) @@ -624,9 +646,10 @@ func TestNewTaskEngineRestoreFromCheckpointPreviousEC2InstanceIDLoadedHappyPath( ec2MetadataClient: ec2MetadataClient, saveableOptionFactory: saveableOptionFactory, } + hostResources := getTestHostResources() _, instanceID, err := agent.newTaskEngine(eventstream.NewEventStream("events", ctx), - credentialsManager, dockerstate.NewTaskEngineState(), imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, dockerstate.NewTaskEngineState(), imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.NoError(t, err) assert.Equal(t, expectedInstanceID, instanceID) assert.NotEqual(t, "prev-container-inst", agent.containerInstanceARN) @@ -686,8 +709,10 @@ func TestNewTaskEngineRestoreFromCheckpointClusterIDMismatch(t *testing.T) { saveableOptionFactory: saveableOptionFactory, } + hostResources := getTestHostResources() + _, _, err := agent.newTaskEngine(eventstream.NewEventStream("events", ctx), - credentialsManager, dockerstate.NewTaskEngineState(), imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, dockerstate.NewTaskEngineState(), imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.Error(t, err) assert.IsType(t, clusterMismatchError{}, err) } @@ -731,8 +756,10 @@ func TestNewTaskEngineRestoreFromCheckpointNewStateManagerError(t *testing.T) { saveableOptionFactory: saveableOptionFactory, } + hostResources := getTestHostResources() + _, _, err := agent.newTaskEngine(eventstream.NewEventStream("events", ctx), - credentialsManager, dockerstate.NewTaskEngineState(), imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, dockerstate.NewTaskEngineState(), imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.Error(t, err) assert.False(t, isTransient(err)) } @@ -777,8 +804,10 @@ func TestNewTaskEngineRestoreFromCheckpointStateLoadError(t *testing.T) { saveableOptionFactory: saveableOptionFactory, } + hostResources := getTestHostResources() + _, _, err := agent.newTaskEngine(eventstream.NewEventStream("events", ctx), - credentialsManager, dockerstate.NewTaskEngineState(), imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, dockerstate.NewTaskEngineState(), imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.Error(t, err) assert.False(t, isTransient(err)) } @@ -816,8 +845,10 @@ func TestNewTaskEngineRestoreFromCheckpoint(t *testing.T) { } state := dockerstate.NewTaskEngineState() + hostResources := getTestHostResources() + _, instanceID, err := agent.newTaskEngine(eventstream.NewEventStream("events", ctx), - credentialsManager, state, imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, state, imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.NoError(t, err) assert.Equal(t, testEC2InstanceID, instanceID) @@ -1346,6 +1377,7 @@ func TestRegisterContainerInstanceInvalidParameterTerminalError(t *testing.T) { mockServiceConnectManager.EXPECT().SetECSClient(gomock.Any(), gomock.Any()).AnyTimes() gomock.InOrder( dockerClient.EXPECT().SupportedVersions().Return(apiVersions), + client.EXPECT().GetHostResources().Return(testHostResource, nil), mockCredentialsProvider.EXPECT().Retrieve().Return(aws_credentials.Value{}, nil), dockerClient.EXPECT().SupportedVersions().Return(nil), dockerClient.EXPECT().KnownVersions().Return(nil), @@ -1637,6 +1669,46 @@ func getTestConfig() config.Config { return cfg } +func getTestHostResources() map[string]*ecs.Resource { + hostResources := make(map[string]*ecs.Resource) + CPUs := int64(1024) + hostResources["CPU"] = &ecs.Resource{ + Name: utils.Strptr("CPU"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &CPUs, + } + //MEMORY + memory := int64(1024) + hostResources["MEMORY"] = &ecs.Resource{ + Name: utils.Strptr("MEMORY"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &memory, + } + //PORTS + ports_tcp := []*string{} + hostResources["PORTS_TCP"] = &ecs.Resource{ + Name: utils.Strptr("PORTS_TCP"), + Type: utils.Strptr("STRINGSET"), + StringSetValue: ports_tcp, + } + + //PORTS_UDP + ports_udp := []*string{} + hostResources["PORTS_UDP"] = &ecs.Resource{ + Name: utils.Strptr("PORTS_UDP"), + Type: utils.Strptr("STRINGSET"), + StringSetValue: ports_udp, + } + //GPUs + numGPUs := int64(3) + hostResources["GPU"] = &ecs.Resource{ + Name: utils.Strptr("GPU"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &numGPUs, + } + return hostResources +} + func newTestDataClient(t *testing.T) data.Client { testDir := t.TempDir() diff --git a/agent/app/agent_unix_test.go b/agent/app/agent_unix_test.go index 543f3e4a65..89d4f94433 100644 --- a/agent/app/agent_unix_test.go +++ b/agent/app/agent_unix_test.go @@ -116,6 +116,7 @@ func TestDoStartTaskENIHappyPath(t *testing.T) { mockServiceConnectManager.EXPECT().GetLoadedImageName().Return("service_connect_agent:v1").AnyTimes() imageManager.EXPECT().AddImageToCleanUpExclusionList(gomock.Eq("service_connect_agent:v1")).Times(1) mockUdevMonitor.EXPECT().Monitor(gomock.Any()).Return(monitoShutdownEvents).AnyTimes() + client.EXPECT().GetHostResources().Return(testHostResource, nil).Times(1) gomock.InOrder( mockMetadata.EXPECT().PrimaryENIMAC().Return(mac, nil), @@ -460,6 +461,7 @@ func TestDoStartCgroupInitHappyPath(t *testing.T) { mockServiceConnectManager.EXPECT().GetAppnetContainerTarballDir().AnyTimes() mockServiceConnectManager.EXPECT().GetLoadedImageName().Return("service_connect_agent:v1").AnyTimes() imageManager.EXPECT().AddImageToCleanUpExclusionList(gomock.Eq("service_connect_agent:v1")).Times(1) + client.EXPECT().GetHostResources().Return(testHostResource, nil).Times(1) gomock.InOrder( mockControl.EXPECT().Init().Return(nil), @@ -624,6 +626,8 @@ func TestDoStartGPUManagerHappyPath(t *testing.T) { mockServiceConnectManager.EXPECT().GetAppnetContainerTarballDir().AnyTimes() mockServiceConnectManager.EXPECT().GetLoadedImageName().Return("service_connect_agent:v1").AnyTimes() imageManager.EXPECT().AddImageToCleanUpExclusionList(gomock.Eq("service_connect_agent:v1")).Times(1) + client.EXPECT().GetHostResources().Return(testHostResource, nil).Times(1) + mockGPUManager.EXPECT().GetDevices().Return(devices).AnyTimes() gomock.InOrder( mockGPUManager.EXPECT().Initialize().Return(nil), @@ -634,7 +638,7 @@ func TestDoStartGPUManagerHappyPath(t *testing.T) { dockerClient.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]string{}, nil), mockGPUManager.EXPECT().GetDriverVersion().Return("396.44"), - mockGPUManager.EXPECT().GetDevices().Return(devices), + mockGPUManager.EXPECT().GetDevices().Return(devices).AnyTimes(), client.EXPECT().RegisterContainerInstance(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), devices, gomock.Any()).Return("arn", "", nil), imageManager.EXPECT().SetDataClient(gomock.Any()), @@ -717,6 +721,7 @@ func TestDoStartGPUManagerInitError(t *testing.T) { mockServiceConnectManager.EXPECT().GetLoadedAppnetVersion().AnyTimes() mockServiceConnectManager.EXPECT().GetCapabilitiesForAppnetInterfaceVersion("").AnyTimes() mockServiceConnectManager.EXPECT().SetECSClient(gomock.Any(), gomock.Any()).AnyTimes() + client.EXPECT().GetHostResources().Return(testHostResource, nil).Times(1) cfg := getTestConfig() cfg.GPUSupportEnabled = true @@ -766,6 +771,7 @@ func TestDoStartTaskENIPauseError(t *testing.T) { dockerapi.ListContainersResponse{}).AnyTimes() imageManager.EXPECT().StartImageCleanupProcess(gomock.Any()).MaxTimes(1) mockPauseLoader.EXPECT().LoadImage(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")).AnyTimes() + client.EXPECT().GetHostResources().Return(testHostResource, nil).Times(1) cfg := getTestConfig() cfg.TaskENIEnabled = config.BooleanDefaultFalse{Value: config.ExplicitlyEnabled} diff --git a/agent/app/data.go b/agent/app/data.go index 77dcafe94a..e4bd1ab5e2 100644 --- a/agent/app/data.go +++ b/agent/app/data.go @@ -18,6 +18,7 @@ import ( "strings" "github.com/aws/amazon-ecs-agent/agent/data" + "github.com/aws/amazon-ecs-agent/agent/ecs_client/model/ecs" "github.com/aws/amazon-ecs-agent/agent/engine" "github.com/aws/amazon-ecs-agent/agent/engine/dockerstate" "github.com/aws/amazon-ecs-agent/agent/engine/execcmd" @@ -65,11 +66,13 @@ func (agent *ecsAgent) loadData(containerChangeEventStream *eventstream.EventStr credentialsManager credentials.Manager, state dockerstate.TaskEngineState, imageManager engine.ImageManager, + hostResources map[string]*ecs.Resource, execCmdMgr execcmd.Manager, serviceConnectManager serviceconnect.Manager) (*savedData, error) { + s := &savedData{ taskEngine: engine.NewTaskEngine(agent.cfg, agent.dockerClient, credentialsManager, - containerChangeEventStream, imageManager, state, + containerChangeEventStream, imageManager, hostResources, state, agent.metadataManager, agent.resourceFields, execCmdMgr, serviceConnectManager), } s.taskEngine.SetDataClient(agent.dataClient) diff --git a/agent/app/data_test.go b/agent/app/data_test.go index cad597134f..5adcaff690 100644 --- a/agent/app/data_test.go +++ b/agent/app/data_test.go @@ -112,9 +112,10 @@ func TestLoadDataNoPreviousState(t *testing.T) { stateManagerFactory: stateManagerFactory, saveableOptionFactory: factory.NewSaveableOption(), } + hostResources := getTestHostResources() _, err := agent.loadData(eventstream.NewEventStream("events", ctx), - credentialsManager, dockerstate.NewTaskEngineState(), imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, dockerstate.NewTaskEngineState(), imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.NoError(t, err) } @@ -143,8 +144,9 @@ func TestLoadDataLoadFromBoltDB(t *testing.T) { } state := dockerstate.NewTaskEngineState() + hostResources := getTestHostResources() s, err := agent.loadData(eventstream.NewEventStream("events", ctx), - credentialsManager, state, imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, state, imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.NoError(t, err) checkLoadedData(state, s, t) } @@ -181,8 +183,9 @@ func TestLoadDataLoadFromStateFile(t *testing.T) { } state := dockerstate.NewTaskEngineState() + hostResources := getTestHostResources() s, err := agent.loadData(eventstream.NewEventStream("events", ctx), - credentialsManager, state, imageManager, execCmdMgr, serviceConnectManager) + credentialsManager, state, imageManager, hostResources, execCmdMgr, serviceConnectManager) assert.NoError(t, err) checkLoadedData(state, s, t) diff --git a/agent/engine/common_integ_test.go b/agent/engine/common_integ_test.go index eb15a1ab2f..8486cbf2da 100644 --- a/agent/engine/common_integ_test.go +++ b/agent/engine/common_integ_test.go @@ -111,9 +111,11 @@ func setupGMSALinux(cfg *config.Config, state dockerstate.TaskEngineState, t *te }, DockerClient: dockerClient, } + hostResources := getTestHostResources() + hostResourceManager := NewHostResourceManager(hostResources) taskEngine := NewDockerTaskEngine(cfg, dockerClient, credentialsManager, - eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, state, metadataManager, + eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, &hostResourceManager, state, metadataManager, resourceFields, execcmd.NewManager(), engineserviceconnect.NewManager()) taskEngine.MustInit(context.TODO()) return taskEngine, func() { @@ -202,9 +204,11 @@ func setup(cfg *config.Config, state dockerstate.TaskEngineState, t *testing.T) imageManager := NewImageManager(cfg, dockerClient, state) imageManager.SetDataClient(data.NewNoopClient()) metadataManager := containermetadata.NewManager(dockerClient, cfg) + hostResources := getTestHostResources() + hostResourceManager := NewHostResourceManager(hostResources) taskEngine := NewDockerTaskEngine(cfg, dockerClient, credentialsManager, - eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, state, metadataManager, + eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, &hostResourceManager, state, metadataManager, nil, execcmd.NewManager(), engineserviceconnect.NewManager()) taskEngine.MustInit(context.TODO()) return taskEngine, func() { diff --git a/agent/engine/common_test.go b/agent/engine/common_test.go index ca0c5a16d6..2ddda13a9e 100644 --- a/agent/engine/common_test.go +++ b/agent/engine/common_test.go @@ -32,11 +32,13 @@ import ( "github.com/aws/amazon-ecs-agent/agent/dockerclient" "github.com/aws/amazon-ecs-agent/agent/dockerclient/dockerapi" mock_dockerapi "github.com/aws/amazon-ecs-agent/agent/dockerclient/dockerapi/mocks" + "github.com/aws/amazon-ecs-agent/agent/ecs_client/model/ecs" "github.com/aws/amazon-ecs-agent/agent/engine/execcmd" mock_engine "github.com/aws/amazon-ecs-agent/agent/engine/mocks" "github.com/aws/amazon-ecs-agent/agent/statechange" "github.com/aws/amazon-ecs-agent/ecs-agent/credentials" mock_ttime "github.com/aws/amazon-ecs-agent/ecs-agent/utils/ttime/mocks" + "github.com/aws/amazon-ecs-agent/agent/utils" "github.com/cihub/seelog" dockercontainer "github.com/docker/docker/api/types/container" "github.com/golang/mock/gomock" @@ -365,3 +367,43 @@ func enableExecCommandAgentForContainer(container *apicontainer.Container, state }, } } + +func getTestHostResources() map[string]*ecs.Resource { + hostResources := make(map[string]*ecs.Resource) + CPUs := int64(1024) + hostResources["CPU"] = &ecs.Resource{ + Name: utils.Strptr("CPU"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &CPUs, + } + //MEMORY + memory := int64(1024) + hostResources["MEMORY"] = &ecs.Resource{ + Name: utils.Strptr("MEMORY"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &memory, + } + //PORTS + ports_tcp := []*string{} + hostResources["PORTS_TCP"] = &ecs.Resource{ + Name: utils.Strptr("PORTS_TCP"), + Type: utils.Strptr("STRINGSET"), + StringSetValue: ports_tcp, + } + + //PORTS_UDP + ports_udp := []*string{} + hostResources["PORTS_UDP"] = &ecs.Resource{ + Name: utils.Strptr("PORTS_UDP"), + Type: utils.Strptr("STRINGSET"), + StringSetValue: ports_udp, + } + //GPUs + numGPUs := int64(3) + hostResources["GPU"] = &ecs.Resource{ + Name: utils.Strptr("GPU"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &numGPUs, + } + return hostResources +} diff --git a/agent/engine/default.go b/agent/engine/default.go index d83c53a89c..cb91e521c9 100644 --- a/agent/engine/default.go +++ b/agent/engine/default.go @@ -19,6 +19,7 @@ import ( "github.com/aws/amazon-ecs-agent/agent/config" "github.com/aws/amazon-ecs-agent/agent/containermetadata" "github.com/aws/amazon-ecs-agent/agent/dockerclient/dockerapi" + "github.com/aws/amazon-ecs-agent/agent/ecs_client/model/ecs" "github.com/aws/amazon-ecs-agent/agent/engine/dockerstate" "github.com/aws/amazon-ecs-agent/agent/engine/execcmd" "github.com/aws/amazon-ecs-agent/agent/engine/serviceconnect" @@ -31,14 +32,15 @@ import ( func NewTaskEngine(cfg *config.Config, client dockerapi.DockerClient, credentialsManager credentials.Manager, containerChangeEventStream *eventstream.EventStream, - imageManager ImageManager, state dockerstate.TaskEngineState, + imageManager ImageManager, hostResources map[string]*ecs.Resource, state dockerstate.TaskEngineState, metadataManager containermetadata.Manager, resourceFields *taskresource.ResourceFields, execCmdMgr execcmd.Manager, serviceConnectManager serviceconnect.Manager) TaskEngine { + hostResourceManager := NewHostResourceManager(hostResources) taskEngine := NewDockerTaskEngine(cfg, client, credentialsManager, - containerChangeEventStream, imageManager, + containerChangeEventStream, imageManager, &hostResourceManager, state, metadataManager, resourceFields, execCmdMgr, serviceConnectManager) return taskEngine diff --git a/agent/engine/docker_task_engine.go b/agent/engine/docker_task_engine.go index 0ed71d7d80..f2b15ae92c 100644 --- a/agent/engine/docker_task_engine.go +++ b/agent/engine/docker_task_engine.go @@ -162,6 +162,7 @@ type DockerTaskEngine struct { containerStatusToTransitionFunction map[apicontainerstatus.ContainerStatus]transitionApplyFunc metadataManager containermetadata.Manager serviceconnectManager serviceconnect.Manager + hostResourceManager *HostResourceManager serviceconnectRelay *apitask.Task // taskSteadyStatePollInterval is the duration that a managed task waits @@ -195,6 +196,7 @@ func NewDockerTaskEngine(cfg *config.Config, credentialsManager credentials.Manager, containerChangeEventStream *eventstream.EventStream, imageManager ImageManager, + hostResourceManager *HostResourceManager, state dockerstate.TaskEngineState, metadataManager containermetadata.Manager, resourceFields *taskresource.ResourceFields, @@ -214,6 +216,7 @@ func NewDockerTaskEngine(cfg *config.Config, containerChangeEventStream: containerChangeEventStream, imageManager: imageManager, + hostResourceManager: hostResourceManager, cniClient: ecscni.NewClient(cfg.CNIPluginsPath), appnetClient: appnet.Client(), diff --git a/agent/engine/docker_task_engine_test.go b/agent/engine/docker_task_engine_test.go index 49733eb745..c248745ac5 100644 --- a/agent/engine/docker_task_engine_test.go +++ b/agent/engine/docker_task_engine_test.go @@ -179,9 +179,10 @@ func mocks(t *testing.T, ctx context.Context, cfg *config.Config) (*gomock.Contr imageManager := mock_engine.NewMockImageManager(ctrl) metadataManager := mock_containermetadata.NewMockManager(ctrl) execCmdMgr := mock_execcmdagent.NewMockManager(ctrl) + hostResources := getTestHostResources() taskEngine := NewTaskEngine(cfg, client, credentialsManager, containerChangeEventStream, - imageManager, dockerstate.NewTaskEngineState(), metadataManager, nil, execCmdMgr, nil) + imageManager, hostResources, dockerstate.NewTaskEngineState(), metadataManager, nil, execCmdMgr, nil) taskEngine.(*DockerTaskEngine)._time = mockTime taskEngine.(*DockerTaskEngine).ctx = ctx taskEngine.(*DockerTaskEngine).stopContainerBackoffMin = time.Millisecond diff --git a/agent/engine/engine_sudo_linux_integ_test.go b/agent/engine/engine_sudo_linux_integ_test.go index 2ddd9a47b0..9160cec66f 100644 --- a/agent/engine/engine_sudo_linux_integ_test.go +++ b/agent/engine/engine_sudo_linux_integ_test.go @@ -584,9 +584,11 @@ func setupEngineForExecCommandAgent(t *testing.T, hostBinDir string) (TaskEngine imageManager.SetDataClient(data.NewNoopClient()) metadataManager := containermetadata.NewManager(dockerClient, cfg) execCmdMgr := execcmd.NewManagerWithBinDir(hostBinDir) + hostResources := getTestHostResources() + hostResourceManager := NewHostResourceManager(hostResources) taskEngine := NewDockerTaskEngine(cfg, dockerClient, credentialsManager, - eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, state, metadataManager, + eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, &hostResourceManager, state, metadataManager, nil, execCmdMgr, engineserviceconnect.NewManager()) taskEngine.monitorExecAgentsInterval = time.Second taskEngine.MustInit(context.TODO()) diff --git a/agent/engine/engine_windows_integ_test.go b/agent/engine/engine_windows_integ_test.go index b244ade6fc..68ad150b2d 100644 --- a/agent/engine/engine_windows_integ_test.go +++ b/agent/engine/engine_windows_integ_test.go @@ -552,9 +552,11 @@ func setupGMSA(cfg *config.Config, state dockerstate.TaskEngineState, t *testing }, DockerClient: dockerClient, } + hostResources := getTestHostResources() + hostResourceManager := NewHostResourceManager(hostResources) taskEngine := NewDockerTaskEngine(cfg, dockerClient, credentialsManager, - eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, state, metadataManager, + eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, &hostResourceManager, state, metadataManager, resourceFields, execcmd.NewManager(), engineserviceconnect.NewManager()) taskEngine.MustInit(context.TODO()) return taskEngine, func() { @@ -794,9 +796,11 @@ func setupEngineForExecCommandAgent(t *testing.T, hostBinDir string) (TaskEngine imageManager.SetDataClient(data.NewNoopClient()) metadataManager := containermetadata.NewManager(dockerClient, cfg) execCmdMgr := execcmd.NewManagerWithBinDir(hostBinDir) + hostResources := getTestHostResources() + hostResourceManager := NewHostResourceManager(hostResources) taskEngine := NewDockerTaskEngine(cfg, dockerClient, credentialsManager, - eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, state, metadataManager, + eventstream.NewEventStream("ENGINEINTEGTEST", context.Background()), imageManager, &hostResourceManager, state, metadataManager, nil, execCmdMgr, engineserviceconnect.NewManager()) taskEngine.monitorExecAgentsInterval = time.Second taskEngine.MustInit(context.TODO()) diff --git a/agent/engine/host_resource_manager.go b/agent/engine/host_resource_manager.go new file mode 100644 index 0000000000..21aa9733be --- /dev/null +++ b/agent/engine/host_resource_manager.go @@ -0,0 +1,92 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +// Package engine contains the core logic for managing tasks + +package engine + +import ( + "github.com/aws/amazon-ecs-agent/agent/ecs_client/model/ecs" + "github.com/aws/amazon-ecs-agent/agent/utils" + "github.com/aws/amazon-ecs-agent/ecs-agent/logger" +) + +// initialHostResource keeps account of each task in +type HostResourceManager struct { + initialHostResource map[string]*ecs.Resource + consumedResource map[string]*ecs.Resource + + //task.arn to boolean whether host resources consumed or not + taskConsumed map[string]bool +} + +// NewHostResourceManager initialize host resource manager with available host resource values +func NewHostResourceManager(resourceMap map[string]*ecs.Resource) HostResourceManager { + // for resources in resourceMap, some are "available resources" like CPU, mem, while + // some others are "reserved/consumed resources" like ports + consumedResourceMap := make(map[string]*ecs.Resource) + taskConsumed := make(map[string]bool) + // assigns CPU, MEMORY, PORTS_TCP, PORTS_UDP from host + //CPU + CPUs := int64(0) + consumedResourceMap["CPU"] = &ecs.Resource{ + Name: utils.Strptr("CPU"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &CPUs, + } + //MEMORY + memory := int64(0) + consumedResourceMap["MEMORY"] = &ecs.Resource{ + Name: utils.Strptr("MEMORY"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &memory, + } + //PORTS_TCP + //Copying ports from host resources as consumed ports for initializing + portsTcp := []*string{} + if resourceMap != nil && resourceMap["PORTS_TCP"] != nil { + portsTcp = resourceMap["PORTS_TCP"].StringSetValue + } + consumedResourceMap["PORTS_TCP"] = &ecs.Resource{ + Name: utils.Strptr("PORTS_TCP"), + Type: utils.Strptr("STRINGSET"), + StringSetValue: portsTcp, + } + + //PORTS_UDP + portsUdp := []*string{} + if resourceMap != nil && resourceMap["PORTS_UDP"] != nil { + portsUdp = resourceMap["PORTS_UDP"].StringSetValue + } + consumedResourceMap["PORTS_UDP"] = &ecs.Resource{ + Name: utils.Strptr("PORTS_UDP"), + Type: utils.Strptr("STRINGSET"), + StringSetValue: portsUdp, + } + + //GPUs + numGPUs := int64(0) + consumedResourceMap["GPU"] = &ecs.Resource{ + Name: utils.Strptr("GPU"), + Type: utils.Strptr("INTEGER"), + IntegerValue: &numGPUs, + } + + logger.Info("Initializing host resource manager, initialHostResource", logger.Fields{"initialHostResource": resourceMap}) + logger.Info("Initializing host resource manager, consumed resource", logger.Fields{"consumedResource": consumedResourceMap}) + return HostResourceManager{ + initialHostResource: resourceMap, + consumedResource: consumedResourceMap, + taskConsumed: taskConsumed, + } +} diff --git a/agent/sighandlers/termination_handler_test.go b/agent/sighandlers/termination_handler_test.go index d0e21b5e94..a282ee6aaf 100644 --- a/agent/sighandlers/termination_handler_test.go +++ b/agent/sighandlers/termination_handler_test.go @@ -44,7 +44,7 @@ func TestFinalSave(t *testing.T) { state := dockerstate.NewTaskEngineState() taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, - nil, nil, state, nil, nil, nil, nil) + nil, nil, nil, state, nil, nil, nil, nil) task := &apitask.Task{ Arn: taskARN, diff --git a/agent/statemanager/state_manager_test.go b/agent/statemanager/state_manager_test.go index 41815dcf55..069ee8b142 100644 --- a/agent/statemanager/state_manager_test.go +++ b/agent/statemanager/state_manager_test.go @@ -44,7 +44,7 @@ func TestLoadsV1DataCorrectly(t *testing.T) { defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v1", "1")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 @@ -90,7 +90,7 @@ func TestLoadsV13DataCorrectly(t *testing.T) { defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v13", "1")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 @@ -138,7 +138,7 @@ func TestLoadsDataForContainerHealthCheckTask(t *testing.T) { defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v10", "container-health-check")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 @@ -180,7 +180,7 @@ func TestLoadsDataForPrivateRegistryTask(t *testing.T) { defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v14", "private-registry")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 @@ -226,7 +226,7 @@ func TestLoadsDataForSecretsTask(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v17", "secrets")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -264,7 +264,7 @@ func TestLoadsDataForAddingAvailabilityZoneInTask(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v18", "availabilityZone")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID, availabilityZone string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -295,7 +295,7 @@ func TestLoadsDataForASMSecretsTask(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v18", "secrets")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -334,7 +334,7 @@ func TestLoadsDataForContainerOrdering(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v20", "containerOrdering")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -369,7 +369,7 @@ func TestLoadsDataForPerContainerTimeouts(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v20", "perContainerTimeouts")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -404,7 +404,7 @@ func TestLoadsDataForContainerRuntimeID(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v23", "perContainerRuntimeID")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -435,7 +435,7 @@ func TestLoadsDataForContainerImageDigest(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v24", "perContainerImageDigest")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -466,7 +466,7 @@ func TestLoadsDataSeqTaskManifest(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v25", "seqNumTaskManifest")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber, seqNumTaskManifest int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -493,7 +493,7 @@ func TestLoadsDataForEnvFiles(t *testing.T) { require.Nil(t, err, "Failed to set up test") defer cleanup() cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v28", "environmentFiles")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, diff --git a/agent/statemanager/state_manager_unix_test.go b/agent/statemanager/state_manager_unix_test.go index 8b735eea20..e97e4891b7 100644 --- a/agent/statemanager/state_manager_unix_test.go +++ b/agent/statemanager/state_manager_unix_test.go @@ -46,7 +46,7 @@ func TestStateManager(t *testing.T) { // Now let's make some state to save containerInstanceArn := "" - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) manager, err = statemanager.NewStateManager(cfg, statemanager.AddSaveable("TaskEngine", taskEngine), @@ -64,7 +64,7 @@ func TestStateManager(t *testing.T) { assertFileMode(t, filepath.Join(tmpDir, "ecs_agent_data.json")) // Now make sure we can load that state sanely - loadedTaskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), + loadedTaskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var loadedContainerInstanceArn string @@ -110,7 +110,7 @@ func TestLoadsDataForAWSVPCTask(t *testing.T) { t.Run(tc.name, func(t *testing.T) { cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v11", tc.dir)} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string stateManager, err := statemanager.NewStateManager(cfg, @@ -149,7 +149,7 @@ func TestLoadsDataForAWSVPCTask(t *testing.T) { // verify that the state manager correctly loads gpu related fields in state file func TestLoadsDataForGPU(t *testing.T) { cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v18", "gpu")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -194,7 +194,7 @@ func TestLoadsDataForGPU(t *testing.T) { func TestLoadsDataForFirelensTask(t *testing.T) { cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v23", "firelens")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -242,7 +242,7 @@ func TestLoadsDataForFirelensTask(t *testing.T) { func TestLoadsDataForFirelensTaskWithExternalConfig(t *testing.T) { cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v24", "firelens")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -296,7 +296,7 @@ func TestLoadsDataForFirelensTaskWithExternalConfig(t *testing.T) { func TestLoadsDataForEFSGATask(t *testing.T) { cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v27", "efs")} - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 stateManager, err := statemanager.NewStateManager(cfg, @@ -333,7 +333,7 @@ func TestLoadsDataForEFSGATask(t *testing.T) { func TestLoadsDataForGMSATask(t *testing.T) { cfg := &config.Config{DataDir: filepath.Join(".", "testdata", "v31", "gmsalinux")} taskEngineState := dockerstate.NewTaskEngineState() - taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, taskEngineState, nil, nil, nil, nil) + taskEngine := engine.NewTaskEngine(&config.Config{}, nil, nil, nil, nil, nil, taskEngineState, nil, nil, nil, nil) var containerInstanceArn, cluster, savedInstanceID string var sequenceNumber int64 diff --git a/agent/stats/engine_integ_test.go b/agent/stats/engine_integ_test.go index 65878661b1..ab951ce6ea 100644 --- a/agent/stats/engine_integ_test.go +++ b/agent/stats/engine_integ_test.go @@ -83,7 +83,7 @@ func TestStatsEngineWithExistingContainersWithoutHealth(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithExistingContainersWithoutHealth") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) testTask := createRunningTask("default") // Populate Tasks and Container map in the engine. dockerTaskEngine := taskEngine.(*ecsengine.DockerTaskEngine) @@ -142,7 +142,7 @@ func TestStatsEngineWithNewContainersWithoutHealth(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithNewContainers") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) testTask := createRunningTask("default") // Populate Tasks and Container map in the engine. dockerTaskEngine := taskEngine.(*ecsengine.DockerTaskEngine) @@ -220,7 +220,7 @@ func TestStatsEngineWithExistingContainers(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithExistingContainers") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) testTask := createRunningTask("bridge") // enable container health check for this container testTask.Containers[0].HealthCheckType = "docker" @@ -287,7 +287,7 @@ func TestStatsEngineWithNewContainers(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithNewContainers") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) testTask := createRunningTask("bridge") // enable health check of the container @@ -369,7 +369,7 @@ func TestStatsEngineWithNewContainersWithPolling(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithNewContainers") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) testTask := createRunningTask("bridge") // enable health check of the container @@ -434,7 +434,7 @@ func TestStatsEngineWithNewContainersWithPolling(t *testing.T) { func TestStatsEngineWithDockerTaskEngine(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithDockerTaskEngine") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) container, err := createHealthContainer(client) require.NoError(t, err, "creating container failed") ctx, cancel := context.WithCancel(context.TODO()) @@ -518,7 +518,7 @@ func TestStatsEngineWithDockerTaskEngine(t *testing.T) { func TestStatsEngineWithDockerTaskEngineMissingRemoveEvent(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithDockerTaskEngineMissingRemoveEvent") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) ctx, cancel := context.WithCancel(context.TODO()) defer cancel() @@ -606,7 +606,7 @@ func testNetworkModeStatsInteg(t *testing.T, networkMode string, statsEmpty bool containerChangeEventStream := eventStream("TestStatsEngineWithNetworkStats") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) testTask := createRunningTask(networkMode) // Populate Tasks and Container map in the engine. @@ -687,7 +687,7 @@ func TestStorageStats(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithStorageStats") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) testTask := createRunningTask("bridge") // Populate Tasks and Container map in the engine. diff --git a/agent/stats/engine_unix_integ_test.go b/agent/stats/engine_unix_integ_test.go index b7a0309100..764b8c0172 100644 --- a/agent/stats/engine_unix_integ_test.go +++ b/agent/stats/engine_unix_integ_test.go @@ -110,7 +110,7 @@ func TestStatsEngineWithServiceConnectMetrics(t *testing.T) { containerChangeEventStream := eventStream("TestStatsEngineWithServiceConnectMetrics") taskEngine := ecsengine.NewTaskEngine(&config.Config{}, nil, nil, containerChangeEventStream, - nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) + nil, nil, dockerstate.NewTaskEngineState(), nil, nil, nil, nil) testTask := createRunningTask("bridge") testTask.ServiceConnectConfig = &serviceconnect.Config{ ContainerName: serviceConnectContainerName,