diff --git a/agent/api/task/task.go b/agent/api/task/task.go index dc2f4dfda55..7703df90236 100644 --- a/agent/api/task/task.go +++ b/agent/api/task/task.go @@ -1946,6 +1946,15 @@ func (task *Task) dockerHostConfig(container *apicontainer.Container, dockerCont // overrideContainerRuntime overrides the runtime for the container in host config if needed. func (task *Task) overrideContainerRuntime(container *apicontainer.Container, hostCfg *dockercontainer.HostConfig, cfg *config.Config) *apierrors.HostConfigError { + if cfg.Runtime != "" { + logger.Debug("Setting runtime for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + "runTime": cfg.Runtime, + }) + hostCfg.Runtime = cfg.Runtime + } + if task.isGPUEnabled() && task.shouldRequireNvidiaRuntime(container) { if !cfg.External.Enabled() { if task.NvidiaRuntime == "" { diff --git a/agent/api/task/task_test.go b/agent/api/task/task_test.go index fa7eacbec79..639024de7a1 100644 --- a/agent/api/task/task_test.go +++ b/agent/api/task/task_test.go @@ -3542,6 +3542,22 @@ func TestDockerHostConfigNvidiaRuntime(t *testing.T) { assert.Equal(t, testTask.NvidiaRuntime, dockerHostConfig.Runtime) } +func TestDockerHostConfigCustomRuntime(t *testing.T) { + testTask := &Task{ + Arn: "test", + Containers: []*apicontainer.Container{ + { + Name: "myName1", + Image: "image:tag", + }, + }, + } + + dockerHostConfig, _ := testTask.DockerHostConfig(testTask.Containers[0], dockerMap(testTask), defaultDockerClientAPIVersion, + &config.Config{Runtime: "custom-runtime"}) + assert.Equal(t, "custom-runtime", dockerHostConfig.Runtime) +} + func TestDockerHostConfigRuntimeWithoutGPU(t *testing.T) { testTask := &Task{ Arn: "test", diff --git a/agent/config/config.go b/agent/config/config.go index 9350c04909f..58a49b22bc0 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -597,6 +597,7 @@ func environmentConfig() (Config, error) { WarmPoolsSupport: parseBooleanDefaultFalseConfig("ECS_WARM_POOLS_CHECK"), DynamicHostPortRange: parseDynamicHostPortRange("ECS_DYNAMIC_HOST_PORT_RANGE"), TaskPidsLimit: parseTaskPidsLimit(), + Runtime: os.Getenv("ECS_DOCKER_RUNTIME"), }, err } diff --git a/agent/config/config_test.go b/agent/config/config_test.go index 7b1c08c6679..6048326c88b 100644 --- a/agent/config/config_test.go +++ b/agent/config/config_test.go @@ -162,6 +162,7 @@ func TestEnvironmentConfig(t *testing.T) { defer setTestEnv("ECS_EXCLUDE_IPV6_PORTBINDING", "true")() defer setTestEnv("ECS_WARM_POOLS_CHECK", "false")() defer setTestEnv("ECS_DYNAMIC_HOST_PORT_RANGE", "200-300")() + defer setTestEnv("ECS_DOCKER_RUNTIME", "custom-runtime")() additionalLocalRoutesJSON := `["1.2.3.4/22","5.6.7.8/32"]` setTestEnv("ECS_AWSVPC_ADDITIONAL_LOCAL_ROUTES", additionalLocalRoutesJSON) setTestEnv("ECS_ENABLE_CONTAINER_METADATA", "true") @@ -222,6 +223,7 @@ func TestEnvironmentConfig(t *testing.T) { assert.True(t, conf.ShouldExcludeIPv6PortBinding.Enabled(), "Wrong value for ShouldExcludeIPv6PortBinding") assert.False(t, conf.WarmPoolsSupport.Enabled(), "Wrong value for WarmPoolsSupport") assert.Equal(t, "200-300", conf.DynamicHostPortRange) + assert.Equal(t, "custom-runtime", conf.Runtime) } func TestTrimWhitespaceWhenCreating(t *testing.T) { diff --git a/agent/config/types.go b/agent/config/types.go index ced906727c5..178730e7b13 100644 --- a/agent/config/types.go +++ b/agent/config/types.go @@ -376,4 +376,7 @@ type Config struct { // cgroup setting at the ECS task level. // see https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#pid TaskPidsLimit int + + // Runtime specifies a custom docker runtime to be used when launching tasks. + Runtime string }