Skip to content

Commit 8587a9b

Browse files
committed
Make create container timeout configurable
1 parent ef0f5c7 commit 8587a9b

12 files changed

+61
-5
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ additional details on each available environment variable.
150150
| `ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION` | 10m | Time to wait to delete containers for a stopped task. If set to less than 1 minute, the value is ignored. | 3h | 3h |
151151
| `ECS_CONTAINER_STOP_TIMEOUT` | 10m | Instance scoped configuration for time to wait for the container to exit normally before being forcibly killed. | 30s | 30s |
152152
| `ECS_CONTAINER_START_TIMEOUT` | 10m | Timeout before giving up on starting a container. | 3m | 8m |
153+
| `ECS_CONTAINER_CREATE_TIMEOUT` | 10m | Timeout before giving up on creating a container. Minimum value is 1m. If user sets a value below minimum it will be set to min. | 4m | 4m |
153154
| `ECS_ENABLE_TASK_IAM_ROLE` | `true` | Whether to enable IAM Roles for Tasks on the Container Instance | `false` | `false` |
154155
| `ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST` | `true` | Whether to enable IAM Roles for Tasks when launched with `host` network mode on the Container Instance | `false` | `false` |
155156
| `ECS_DISABLE_IMAGE_CLEANUP` | `true` | Whether to disable automated image cleanup for the ECS Agent. | `false` | `false` |

agent/config/config.go

+3
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ func environmentConfig() (Config, error) {
533533
TaskCPUMemLimit: parseBooleanDefaultTrueConfig("ECS_ENABLE_TASK_CPU_MEM_LIMIT"),
534534
DockerStopTimeout: parseDockerStopTimeout(),
535535
ContainerStartTimeout: parseContainerStartTimeout(),
536+
ContainerCreateTimeout: parseContainerCreateTimeout(),
536537
DependentContainersPullUpfront: parseBooleanDefaultFalseConfig("ECS_PULL_DEPENDENT_CONTAINERS_UPFRONT"),
537538
ImagePullInactivityTimeout: parseImagePullInactivityTimeout(),
538539
ImagePullTimeout: parseEnvVariableDuration("ECS_IMAGE_PULL_TIMEOUT"),
@@ -601,6 +602,7 @@ func (cfg *Config) String() string {
601602
"TaskCleanupWaitDuration: %v, "+
602603
"DockerStopTimeout: %v, "+
603604
"ContainerStartTimeout: %v, "+
605+
"ContainerCreateTimeout: %v, "+
604606
"DependentContainersPullUpfront: %v, "+
605607
"TaskCPUMemLimit: %v, "+
606608
"%s",
@@ -617,6 +619,7 @@ func (cfg *Config) String() string {
617619
cfg.TaskCleanupWaitDuration,
618620
cfg.DockerStopTimeout,
619621
cfg.ContainerStartTimeout,
622+
cfg.ContainerCreateTimeout,
620623
cfg.DependentContainersPullUpfront,
621624
cfg.TaskCPUMemLimit,
622625
cfg.platformString(),

agent/config/config_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ func TestEnvironmentConfig(t *testing.T) {
119119
defer setTestEnv("ECS_RESERVED_MEMORY", "20")()
120120
defer setTestEnv("ECS_CONTAINER_STOP_TIMEOUT", "60s")()
121121
defer setTestEnv("ECS_CONTAINER_START_TIMEOUT", "5m")()
122+
defer setTestEnv("ECS_CONTAINER_CREATE_TIMEOUT", "4m")()
122123
defer setTestEnv("ECS_IMAGE_PULL_INACTIVITY_TIMEOUT", "10m")()
123124
defer setTestEnv("ECS_AVAILABLE_LOGGING_DRIVERS", "[\""+string(dockerclient.SyslogDriver)+"\"]")()
124125
defer setTestEnv("ECS_SELINUX_CAPABLE", "true")()
@@ -164,6 +165,8 @@ func TestEnvironmentConfig(t *testing.T) {
164165
assert.Equal(t, expectedDurationDockerStopTimeout, conf.DockerStopTimeout)
165166
expectedDurationContainerStartTimeout, _ := time.ParseDuration("5m")
166167
assert.Equal(t, expectedDurationContainerStartTimeout, conf.ContainerStartTimeout)
168+
expectedDurationContainerCreateTimeout, _ := time.ParseDuration("4m")
169+
assert.Equal(t, expectedDurationContainerCreateTimeout, conf.ContainerCreateTimeout)
167170
assert.Equal(t, []dockerclient.LoggingDriver{dockerclient.SyslogDriver}, conf.AvailableLoggingDrivers)
168171
assert.True(t, conf.PrivilegedDisabled.Enabled())
169172
assert.True(t, conf.SELinuxCapable.Enabled(), "Wrong value for SELinuxCapable")
@@ -322,6 +325,14 @@ func TestInvalidFormatContainerStartTimeout(t *testing.T) {
322325
assert.Equal(t, defaultContainerStartTimeout, conf.ContainerStartTimeout, "Wrong value for ContainerStartTimeout")
323326
}
324327

328+
func TestInvalidFormatContainerCreateTimeout(t *testing.T) {
329+
defer setTestRegion()()
330+
defer setTestEnv("ECS_CONTAINER_CREATE_TIMEOUT", "invalid")()
331+
conf, err := NewConfig(ec2.NewBlackholeEC2MetadataClient())
332+
assert.NoError(t, err)
333+
assert.Equal(t, defaultContainerCreateTimeout, conf.ContainerCreateTimeout, "Wrong value for ContainerCreateTimeout")
334+
}
335+
325336
func TestInvalidFormatDockerInactivityTimeout(t *testing.T) {
326337
defer setTestRegion()()
327338
defer setTestEnv("ECS_IMAGE_PULL_INACTIVITY_TIMEOUT", "invalid")()
@@ -355,6 +366,14 @@ func TestZeroValueContainerStartTimeout(t *testing.T) {
355366
assert.Equal(t, defaultContainerStartTimeout, conf.ContainerStartTimeout, "Wrong value for ContainerStartTimeout")
356367
}
357368

369+
func TestZeroValueContainerCreateTimeout(t *testing.T) {
370+
defer setTestRegion()()
371+
defer setTestEnv("ECS_CONTAINER_CREATE_TIMEOUT", "0s")()
372+
conf, err := NewConfig(ec2.NewBlackholeEC2MetadataClient())
373+
assert.NoError(t, err)
374+
assert.Equal(t, defaultContainerCreateTimeout, conf.ContainerCreateTimeout, "Wrong value for ContainerCreateTimeout")
375+
}
376+
358377
func TestInvalidValueContainerStartTimeout(t *testing.T) {
359378
defer setTestRegion()()
360379
defer setTestEnv("ECS_CONTAINER_START_TIMEOUT", "-10s")()
@@ -363,6 +382,14 @@ func TestInvalidValueContainerStartTimeout(t *testing.T) {
363382
assert.Equal(t, minimumContainerStartTimeout, conf.ContainerStartTimeout, "Wrong value for ContainerStartTimeout")
364383
}
365384

385+
func TestInvalidValueContainerCreateTimeout(t *testing.T) {
386+
defer setTestRegion()()
387+
defer setTestEnv("ECS_CONTAINER_CREATE_TIMEOUT", "-10s")()
388+
conf, err := NewConfig(ec2.NewBlackholeEC2MetadataClient())
389+
assert.NoError(t, err)
390+
assert.Equal(t, minimumContainerCreateTimeout, conf.ContainerCreateTimeout, "Wrong value for ContainerCreataeTimeout")
391+
}
392+
366393
func TestZeroValueDockerPullInactivityTimeout(t *testing.T) {
367394
defer setTestRegion()()
368395
defer setTestEnv("ECS_DOCKER_PULL_INACTIVITY_TIMEOUT", "0s")()

agent/config/config_unix.go

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ const (
3838
defaultContainerStartTimeout = 3 * time.Minute
3939
// minimumContainerStartTimeout specifies the minimum value for starting a container
4040
minimumContainerStartTimeout = 45 * time.Second
41+
// defaultContainerCreateTimeout specifies the value for container create timeout duration
42+
defaultContainerCreateTimeout = 4 * time.Minute
43+
// minimumContainerCreateTimeout specifies the minimum value for creating a container
44+
minimumContainerCreateTimeout = 1 * time.Minute
4145
// default docker inactivity time is extra time needed on container extraction
4246
defaultImagePullInactivityTimeout = 1 * time.Minute
4347
)
@@ -56,6 +60,7 @@ func DefaultConfig() Config {
5660
TaskCleanupWaitDuration: DefaultTaskCleanupWaitDuration,
5761
DockerStopTimeout: defaultDockerStopTimeout,
5862
ContainerStartTimeout: defaultContainerStartTimeout,
63+
ContainerCreateTimeout: defaultContainerCreateTimeout,
5964
DependentContainersPullUpfront: BooleanDefaultFalse{Value: ExplicitlyDisabled},
6065
CredentialsAuditLogFile: defaultCredentialsAuditLogFile,
6166
CredentialsAuditLogDisabled: false,

agent/config/config_unix_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func TestConfigDefault(t *testing.T) {
4343
assert.Equal(t, uint16(0), cfg.ReservedMemory, "Default reserved memory set incorrectly")
4444
assert.Equal(t, 30*time.Second, cfg.DockerStopTimeout, "Default docker stop container timeout set incorrectly")
4545
assert.Equal(t, 3*time.Minute, cfg.ContainerStartTimeout, "Default docker start container timeout set incorrectly")
46+
assert.Equal(t, 4*time.Minute, cfg.ContainerCreateTimeout, "Default docker create container timeout set incorrectly")
4647
assert.False(t, cfg.PrivilegedDisabled.Enabled(), "Default PrivilegedDisabled set incorrectly")
4748
assert.Equal(t, []dockerclient.LoggingDriver{dockerclient.JSONFileDriver, dockerclient.NoneDriver},
4849
cfg.AvailableLoggingDrivers, "Default logging drivers set incorrectly")

agent/config/config_windows.go

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ const (
4848
defaultContainerStartTimeout = 8 * time.Minute
4949
// minimumContainerStartTimeout specifies the minimum value for starting a container
5050
minimumContainerStartTimeout = 2 * time.Minute
51+
// defaultContainerCreateTimeout specifies the value for container create timeout duration
52+
defaultContainerCreateTimeout = 4 * time.Minute
53+
// minimumContainerCreateTimeout specifies the minimum value for creating a container
54+
minimumContainerCreateTimeout = 1 * time.Minute
5155
// default image pull inactivity time is extra time needed on container extraction
5256
defaultImagePullInactivityTimeout = 3 * time.Minute
5357
)
@@ -86,6 +90,7 @@ func DefaultConfig() Config {
8690
TaskCleanupWaitDuration: DefaultTaskCleanupWaitDuration,
8791
DockerStopTimeout: defaultDockerStopTimeout,
8892
ContainerStartTimeout: defaultContainerStartTimeout,
93+
ContainerCreateTimeout: defaultContainerCreateTimeout,
8994
DependentContainersPullUpfront: BooleanDefaultFalse{Value: ExplicitlyDisabled},
9095
ImagePullInactivityTimeout: defaultImagePullInactivityTimeout,
9196
ImagePullTimeout: DefaultImagePullTimeout,

agent/config/config_windows_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func TestConfigDefault(t *testing.T) {
4040
assert.Equal(t, uint16(0), cfg.ReservedMemory, "Default reserved memory set incorrectly")
4141
assert.Equal(t, 30*time.Second, cfg.DockerStopTimeout, "Default docker stop container timeout set incorrectly")
4242
assert.Equal(t, 8*time.Minute, cfg.ContainerStartTimeout, "Default docker start container timeout set incorrectly")
43+
assert.Equal(t, 4*time.Minute, cfg.ContainerCreateTimeout, "Default docker create container timeout set incorrectly")
4344
assert.False(t, cfg.PrivilegedDisabled.Enabled(), "Default PrivilegedDisabled set incorrectly")
4445
assert.Equal(t, []dockerclient.LoggingDriver{dockerclient.JSONFileDriver, dockerclient.NoneDriver, dockerclient.AWSLogsDriver},
4546
cfg.AvailableLoggingDrivers, "Default logging drivers set incorrectly")

agent/config/parse.go

+13
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,19 @@ func parseContainerStartTimeout() time.Duration {
9494
return containerStartTimeout
9595
}
9696

97+
func parseContainerCreateTimeout() time.Duration {
98+
var containerCreateTimeout time.Duration
99+
parsedCreateTimeout := parseEnvVariableDuration("ECS_CONTAINER_CREATE_TIMEOUT")
100+
if parsedCreateTimeout >= minimumContainerCreateTimeout {
101+
containerCreateTimeout = parsedCreateTimeout
102+
// do the parsedCreateTimeout != 0 check for the same reason as in getDockerStopTimeout()
103+
} else if parsedCreateTimeout != 0 {
104+
containerCreateTimeout = minimumContainerCreateTimeout
105+
seelog.Warnf("Discarded invalid value for container create timeout, parsed as: %v", parsedCreateTimeout)
106+
}
107+
return containerCreateTimeout
108+
}
109+
97110
func parseImagePullInactivityTimeout() time.Duration {
98111
var imagePullInactivityTimeout time.Duration
99112
parsedImagePullInactivityTimeout := parseEnvVariableDuration("ECS_IMAGE_PULL_INACTIVITY_TIMEOUT")

agent/config/types.go

+3
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ type Config struct {
112112
// ContainerStartTimeout specifies the amount of time to wait to start a container
113113
ContainerStartTimeout time.Duration
114114

115+
// ContainerCreateTimeout specifies the amount of time to wait to create a container
116+
ContainerCreateTimeout time.Duration
117+
115118
// DependentContainersPullUpfront specifies whether pulling images upfront should be applied to this agent.
116119
// Default false
117120
DependentContainersPullUpfront BooleanDefaultFalse

agent/dockerclient/dockerapi/docker_client_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ func TestCreateContainer(t *testing.T) {
428428
)
429429
ctx, cancel := context.WithCancel(context.TODO())
430430
defer cancel()
431-
metadata := client.CreateContainer(ctx, nil, hostConfig, name, dockerclient.CreateContainerTimeout)
431+
metadata := client.CreateContainer(ctx, nil, hostConfig, name, defaultTestConfig().ContainerCreateTimeout)
432432
assert.NoError(t, metadata.Error)
433433
assert.Equal(t, "id", metadata.DockerID)
434434
assert.Nil(t, metadata.ExitCode, "Expected a created container to not have an exit code")

agent/dockerclient/timeout.go

-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ const (
3131
LoadImageTimeout = 2 * time.Minute
3232
// RemoveImageTimeout is the timeout for the RemoveImage API.
3333
RemoveImageTimeout = 3 * time.Minute
34-
35-
// CreateContainerTimeout is the timeout for the CreateContainer API.
36-
CreateContainerTimeout = 4 * time.Minute
3734
// ListContainersTimeout is the timeout for the ListContainers API.
3835
ListContainersTimeout = 10 * time.Minute
3936
// InspectContainerTimeout is the timeout for the InspectContainer API.

agent/engine/docker_task_engine.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,7 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a
10991099

11001100
createContainerBegin := time.Now()
11011101
metadata := client.CreateContainer(engine.ctx, config, hostConfig,
1102-
dockerContainerName, dockerclient.CreateContainerTimeout)
1102+
dockerContainerName, engine.cfg.ContainerCreateTimeout)
11031103
if metadata.DockerID != "" {
11041104
seelog.Infof("Task engine [%s]: created docker container for task: %s -> %s",
11051105
task.Arn, container.Name, metadata.DockerID)

0 commit comments

Comments
 (0)