func TestSubmitContainerStateChangeLongReason(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() client, _, mockSubmitStateClient := NewMockClient(mockCtrl, ec2.NewBlackholeEC2MetadataClient()) exitCode := 20 trimmedReason := strings.Repeat("a", api.EcsMaxReasonLength) reason := strings.Repeat("a", api.EcsMaxReasonLength+1) mockSubmitStateClient.EXPECT().SubmitContainerStateChange(&containerSubmitInputMatcher{ ecs.SubmitContainerStateChangeInput{ Cluster: strptr(configuredCluster), Task: strptr("arn"), ContainerName: strptr("cont"), Status: strptr("STOPPED"), ExitCode: int64ptr(&exitCode), Reason: strptr(trimmedReason), NetworkBindings: []*ecs.NetworkBinding{}, }, }) err := client.SubmitContainerStateChange(api.ContainerStateChange{ TaskArn: "arn", ContainerName: "cont", Status: api.ContainerStopped, ExitCode: &exitCode, Reason: reason, }) if err != nil { t.Errorf("Unable to submit container state change: %v", err) } }
func TestTrimWhitespace(t *testing.T) { os.Setenv("ECS_CLUSTER", "default \r") os.Setenv("ECS_ENGINE_AUTH_TYPE", "dockercfg\r") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if cfg.Cluster != "default" { t.Error("Wrong cluster: " + cfg.Cluster) } if cfg.EngineAuthType != "dockercfg" { t.Error("Wrong auth type: " + cfg.EngineAuthType) } cfg = &Config{ Cluster: " asdf ", AWSRegion: " us-east-1\r\t", DataDir: "/trailing/space/directory ", } cfg.trimWhitespace() if !reflect.DeepEqual(cfg, &Config{Cluster: "asdf", AWSRegion: "us-east-1", DataDir: "/trailing/space/directory "}) { t.Error("Did not match expected", *cfg) } }
func TestConfigDefault(t *testing.T) { os.Unsetenv("ECS_DISABLE_METRICS") os.Unsetenv("ECS_RESERVED_PORTS") os.Unsetenv("ECS_RESERVED_MEMORY") os.Unsetenv("ECS_DISABLE_PRIVILEGED") os.Unsetenv("ECS_AVAILABLE_LOGGING_DRIVERS") os.Unsetenv("ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION") os.Unsetenv("ECS_ENABLE_TASK_IAM_ROLE") os.Unsetenv("ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST") os.Unsetenv("ECS_CONTAINER_STOP_TIMEOUT") os.Unsetenv("ECS_AUDIT_LOGFILE") os.Unsetenv("ECS_AUDIT_LOGFILE_DISABLED") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if cfg.DockerEndpoint != "unix:///var/run/docker.sock" { t.Error("Default docker endpoint set incorrectly") } if cfg.DataDir != "/data/" { t.Error("Default datadir set incorrectly") } if cfg.DisableMetrics { t.Errorf("Default disablemetrics set incorrectly: %v", cfg.DisableMetrics) } if len(cfg.ReservedPorts) != 5 { t.Error("Default resered ports set incorrectly") } if cfg.ReservedMemory != 0 { t.Errorf("Default reserved memory set incorrectly: %v", cfg.ReservedMemory) } expectedTimeout, _ := time.ParseDuration("30s") if cfg.DockerStopTimeout != expectedTimeout { t.Error("Default docker stop container timeout set incorrectly", cfg.DockerStopTimeout) } if cfg.PrivilegedDisabled { t.Errorf("Default PrivilegedDisabled set incorrectly: %v", cfg.PrivilegedDisabled) } if !reflect.DeepEqual(cfg.AvailableLoggingDrivers, []dockerclient.LoggingDriver{dockerclient.JsonFileDriver}) { t.Errorf("Default logging drivers set incorrectly: %v", cfg.AvailableLoggingDrivers) } if cfg.TaskCleanupWaitDuration != 3*time.Hour { t.Errorf("Defualt task cleanup wait duration set incorrectly: %v", cfg.TaskCleanupWaitDuration) } if cfg.TaskIAMRoleEnabled { t.Error("TaskIAMRoleEnabled set incorrectly") } if cfg.TaskIAMRoleEnabledForNetworkHost { t.Error("TaskIAMRoleEnabledForNetworkHost set incorrectly") } if cfg.CredentialsAuditLogDisabled { t.Error("CredentialsAuditLogDisabled set incorrectly") } if cfg.CredentialsAuditLogFile != defaultCredentialsAuditLogFile { t.Error("CredentialsAuditLogFile default is set incorrectly") } }
func TestConfigBoolean(t *testing.T) { os.Setenv("ECS_DISABLE_METRICS", "true") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if !cfg.DisableMetrics { t.Error("DisableMetrics not set to true") } }
func TestDiscoverNilTelemetryEndpoint(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() client, mc, _ := NewMockClient(mockCtrl, ec2.NewBlackholeEC2MetadataClient()) pollEndpoint := "http://127.0.0.1" mc.EXPECT().DiscoverPollEndpoint(gomock.Any()).Return(&ecs.DiscoverPollEndpointOutput{Endpoint: &pollEndpoint}, nil) _, err := client.DiscoverTelemetryEndpoint("containerInstance") if err == nil { t.Error("Expected error getting telemetry endpoint with old response") } }
func TestTaskIAMRoleEnabled(t *testing.T) { os.Setenv("ECS_ENABLE_TASK_IAM_ROLE", "true") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if !cfg.TaskIAMRoleEnabled { t.Errorf("Wrong value for TaskIAMRoleEnabled: %v", cfg.TaskIAMRoleEnabled) } }
func TestCredentialsAuditLogDisabled(t *testing.T) { os.Setenv("ECS_AUDIT_LOGFILE_DISABLED", "true") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if !cfg.CredentialsAuditLogDisabled { t.Errorf("Wrong value for CredentialsAuditLogDisabled: %v", cfg.CredentialsAuditLogDisabled) } }
func TestImageCleanupMinimumInterval(t *testing.T) { os.Setenv("ECS_IMAGE_CLEANUP_INTERVAL", "1m") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if cfg.ImageCleanupInterval != DefaultImageCleanupTimeInterval { t.Errorf("Wrong value for ImageCleanupInterval: %v", cfg.ImageCleanupInterval) } }
func TestImageCleanupMinimumNumImagesToDeletePerCycle(t *testing.T) { os.Setenv("ECS_NUM_IMAGES_DELETE_PER_CYCLE", "-1") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if cfg.NumImagesToDeletePerCycle != DefaultNumImagesToDeletePerCycle { t.Errorf("Wrong value for NumImagesToDeletePerCycle: %v", cfg.NumImagesToDeletePerCycle) } }
func TestTaskIAMRoleForHostNetworkEnabled(t *testing.T) { os.Setenv("ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST", "true") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if !cfg.TaskIAMRoleEnabledForNetworkHost { t.Errorf("Wrong value for TaskIAMRoleEnabledForNetworkHost: %v", cfg.TaskIAMRoleEnabledForNetworkHost) } }
func TestCredentialsAuditLogFile(t *testing.T) { dummyLocation := "/foo/bar.log" os.Setenv("ECS_AUDIT_LOGFILE", dummyLocation) cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if cfg.CredentialsAuditLogFile != dummyLocation { t.Errorf("Wrong value for CredentialsAuditLogFile: %v", cfg.CredentialsAuditLogFile) } }
func TestReservedMemory(t *testing.T) { os.Setenv("ECS_RESERVED_MEMORY", "1") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } // If an invalid value is set, the config should pick up the default value for // reserved memory, which is 0. if cfg.ReservedMemory != 1 { t.Errorf("Wrong value for ReservedMemory. Expected %d, got %d", 1, cfg.ReservedMemory) } }
func TestTaskCleanupTimeout(t *testing.T) { os.Setenv("ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION", "10m") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } // If an invalid value is set, the config should pick up the default value for // cleaning up the task. if cfg.TaskCleanupWaitDuration != 10*time.Minute { t.Errorf("Task cleanup wait duration set incorrectly. Expected %v, got %v", 10*time.Minute, cfg.TaskCleanupWaitDuration) } }
func TestInvalidTaskCleanupTimeout(t *testing.T) { os.Setenv("ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION", "1s") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } // If an invalid value is set, the config should pick up the default value for // cleaning up the task. if cfg.TaskCleanupWaitDuration != 3*time.Hour { t.Error("Defualt task cleanup wait duration set incorrectly") } }
func TestSubmitContainerStateChange(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() client, _, mockSubmitStateClient := NewMockClient(mockCtrl, ec2.NewBlackholeEC2MetadataClient()) mockSubmitStateClient.EXPECT().SubmitContainerStateChange(&containerSubmitInputMatcher{ ecs.SubmitContainerStateChangeInput{ Cluster: strptr(configuredCluster), Task: strptr("arn"), ContainerName: strptr("cont"), Status: strptr("RUNNING"), NetworkBindings: []*ecs.NetworkBinding{ &ecs.NetworkBinding{ BindIP: strptr("1.2.3.4"), ContainerPort: int64ptr(intptr(1)), HostPort: int64ptr(intptr(2)), Protocol: strptr("tcp"), }, &ecs.NetworkBinding{ BindIP: strptr("2.2.3.4"), ContainerPort: int64ptr(intptr(3)), HostPort: int64ptr(intptr(4)), Protocol: strptr("udp"), }, }, }, }) err := client.SubmitContainerStateChange(api.ContainerStateChange{ TaskArn: "arn", ContainerName: "cont", Status: api.ContainerRunning, PortBindings: []api.PortBinding{ api.PortBinding{ BindIp: "1.2.3.4", ContainerPort: 1, HostPort: 2, }, api.PortBinding{ BindIp: "2.2.3.4", ContainerPort: 3, HostPort: 4, Protocol: api.TransportProtocolUDP, }, }, }) if err != nil { t.Errorf("Unable to submit container state change: %v", err) } }
func TestDiscoverTelemetryEndpoint(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() client, mc, _ := NewMockClient(mockCtrl, ec2.NewBlackholeEC2MetadataClient()) expectedEndpoint := "http://127.0.0.1" mc.EXPECT().DiscoverPollEndpoint(gomock.Any()).Return(&ecs.DiscoverPollEndpointOutput{TelemetryEndpoint: &expectedEndpoint}, nil) endpoint, err := client.DiscoverTelemetryEndpoint("containerInstance") if err != nil { t.Error("Error getting telemetry endpoint: ", err) } if expectedEndpoint != endpoint { t.Errorf("Expected telemetry endpoint(%s) != endpoint(%s)", expectedEndpoint, endpoint) } mc.EXPECT().DiscoverPollEndpoint(gomock.Any()).Return(nil, fmt.Errorf("Error getting endpoint")) endpoint, err = client.DiscoverTelemetryEndpoint("containerInstance") if err == nil { t.Error("Expected error getting telemetry endpoint, didn't get any") } }
func TestSubmitContainerStateChangeFull(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() client, _, mockSubmitStateClient := NewMockClient(mockCtrl, ec2.NewBlackholeEC2MetadataClient()) exitCode := 20 reason := "I exited" mockSubmitStateClient.EXPECT().SubmitContainerStateChange(&containerSubmitInputMatcher{ ecs.SubmitContainerStateChangeInput{ Cluster: strptr(configuredCluster), Task: strptr("arn"), ContainerName: strptr("cont"), Status: strptr("STOPPED"), ExitCode: int64ptr(&exitCode), Reason: strptr(reason), NetworkBindings: []*ecs.NetworkBinding{ &ecs.NetworkBinding{ BindIP: strptr(""), ContainerPort: int64ptr(intptr(0)), HostPort: int64ptr(intptr(0)), Protocol: strptr("tcp"), }, }, }, }) err := client.SubmitContainerStateChange(api.ContainerStateChange{ TaskArn: "arn", ContainerName: "cont", Status: api.ContainerStopped, ExitCode: &exitCode, Reason: reason, PortBindings: []api.PortBinding{ api.PortBinding{}, }, }) if err != nil { t.Errorf("Unable to submit container state change: %v", err) } }
func TestConfigDefault(t *testing.T) { os.Unsetenv("ECS_DISABLE_METRICS") os.Unsetenv("ECS_RESERVED_PORTS") os.Unsetenv("ECS_RESERVED_MEMORY") os.Unsetenv("ECS_DISABLE_PRIVILEGED") os.Unsetenv("ECS_AVAILABLE_LOGGING_DRIVERS") os.Unsetenv("ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION") cfg, err := NewConfig(ec2.NewBlackholeEC2MetadataClient()) if err != nil { t.Fatal(err) } if cfg.DockerEndpoint != "unix:///var/run/docker.sock" { t.Error("Default docker endpoint set incorrectly") } if cfg.DataDir != "/data/" { t.Error("Default datadir set incorrectly") } if cfg.DisableMetrics { t.Errorf("Default disablemetrics set incorrectly: %v", cfg.DisableMetrics) } if len(cfg.ReservedPorts) != 4 { t.Error("Default resered ports set incorrectly") } if cfg.DockerGraphPath != "/var/lib/docker" { t.Error("Default docker graph path set incorrectly") } if cfg.ReservedMemory != 0 { t.Errorf("Default reserved memory set incorrectly: %v", cfg.ReservedMemory) } if cfg.PrivilegedDisabled { t.Errorf("Default PrivilegedDisabled set incorrectly: %v", cfg.PrivilegedDisabled) } if !reflect.DeepEqual(cfg.AvailableLoggingDrivers, []dockerclient.LoggingDriver{dockerclient.JsonFileDriver}) { t.Errorf("Default logging drivers set incorrectly: %v", cfg.AvailableLoggingDrivers) } if cfg.TaskCleanupWaitDuration != 3*time.Hour { t.Errorf("Defualt task cleanup wait duration set incorrectly: %v", cfg.TaskCleanupWaitDuration) } }
func defaultTestConfig() *config.Config { cfg, _ := config.NewConfig(ec2.NewBlackholeEC2MetadataClient()) return cfg }
func init() { cfg, _ = config.NewConfig(ec2.NewBlackholeEC2MetadataClient()) }
func _main() int { defer log.Flush() flagset := flag.NewFlagSet("Amazon ECS Agent", flag.ContinueOnError) versionFlag := flagset.Bool("version", false, "Print the agent version information and exit") logLevel := flagset.String("loglevel", "", "Loglevel: [<crit>|<error>|<warn>|<info>|<debug>]") acceptInsecureCert := flagset.Bool("k", false, "Disable SSL certificate verification. We do not recommend setting this option.") licenseFlag := flagset.Bool("license", false, "Print the LICENSE and NOTICE files and exit") blackholeEc2Metadata := flagset.Bool("blackhole-ec2-metadata", false, "Blackhole the EC2 Metadata requests. Setting this option can cause the ECS Agent to fail to work properly. We do not recommend setting this option") err := flagset.Parse(os.Args[1:]) if err != nil { return exitcodes.ExitTerminal } if *licenseFlag { license := utils.NewLicenseProvider() text, err := license.GetText() if err != nil { fmt.Fprintln(os.Stderr, err) return exitcodes.ExitError } fmt.Println(text) return exitcodes.ExitSuccess } logger.SetLevel(*logLevel) ec2MetadataClient := ec2.DefaultClient if *blackholeEc2Metadata { ec2MetadataClient = ec2.NewBlackholeEC2MetadataClient() } log.Infof("Starting Agent: %s", version.String()) if *acceptInsecureCert { log.Warn("SSL certificate verification disabled. This is not recommended.") } log.Info("Loading configuration") cfg, cfgErr := config.NewConfig(ec2MetadataClient) // Load cfg and create Docker client before doing 'versionFlag' so that it has the DOCKER_HOST variable loaded if needed clientFactory := dockerclient.NewFactory(cfg.DockerEndpoint) dockerClient, err := engine.NewDockerGoClient(clientFactory, *acceptInsecureCert, cfg) if err != nil { log.Criticalf("Error creating Docker client: %v", err) return exitcodes.ExitError } ctx := context.Background() // Create the DockerContainerChange event stream for tcs containerChangeEventStream := eventstream.NewEventStream(ContainerChangeEventStream, ctx) containerChangeEventStream.StartListening() // Create credentials manager. This will be used by the task engine and // the credentials handler credentialsManager := credentials.NewManager() // Create image manager. This will be used by the task engine for saving image states state := dockerstate.NewDockerTaskEngineState() imageManager := engine.NewImageManager(cfg, dockerClient, state) if *versionFlag { versionableEngine := engine.NewTaskEngine(cfg, dockerClient, credentialsManager, containerChangeEventStream, imageManager, state) version.PrintVersion(versionableEngine) return exitcodes.ExitSuccess } sighandlers.StartDebugHandler() if cfgErr != nil { log.Criticalf("Error loading config: %v", err) // All required config values can be inferred from EC2 Metadata, so this error could be transient. return exitcodes.ExitError } log.Debug("Loaded config: " + cfg.String()) var currentEc2InstanceID, containerInstanceArn string var taskEngine engine.TaskEngine if cfg.Checkpoint { log.Info("Checkpointing is enabled. Attempting to load state") var previousCluster, previousEc2InstanceID, previousContainerInstanceArn string previousTaskEngine := engine.NewTaskEngine(cfg, dockerClient, credentialsManager, containerChangeEventStream, imageManager, state) // previousState is used to verify that our current runtime configuration is // compatible with our past configuration as reflected by our state-file previousState, err := initializeStateManager(cfg, previousTaskEngine, &previousCluster, &previousContainerInstanceArn, &previousEc2InstanceID) if err != nil { log.Criticalf("Error creating state manager: %v", err) return exitcodes.ExitTerminal } err = previousState.Load() if err != nil { log.Criticalf("Error loading previously saved state: %v", err) return exitcodes.ExitTerminal } if previousCluster != "" { // TODO Handle default cluster in a sane and unified way across the codebase configuredCluster := cfg.Cluster if configuredCluster == "" { log.Debug("Setting cluster to default; none configured") configuredCluster = config.DefaultClusterName } if previousCluster != configuredCluster { log.Criticalf("Data mismatch; saved cluster '%v' does not match configured cluster '%v'. Perhaps you want to delete the configured checkpoint file?", previousCluster, configuredCluster) return exitcodes.ExitTerminal } cfg.Cluster = previousCluster log.Infof("Restored cluster '%v'", cfg.Cluster) } if instanceIdentityDoc, err := ec2MetadataClient.InstanceIdentityDocument(); err == nil { currentEc2InstanceID = instanceIdentityDoc.InstanceId } else { log.Criticalf("Unable to access EC2 Metadata service to determine EC2 ID: %v", err) } if previousEc2InstanceID != "" && previousEc2InstanceID != currentEc2InstanceID { log.Warnf("Data mismatch; saved InstanceID '%s' does not match current InstanceID '%s'. Overwriting old datafile", previousEc2InstanceID, currentEc2InstanceID) // Reset taskEngine; all the other values are still default taskEngine = engine.NewTaskEngine(cfg, dockerClient, credentialsManager, containerChangeEventStream, imageManager, state) } else { // Use the values we loaded if there's no issue containerInstanceArn = previousContainerInstanceArn taskEngine = previousTaskEngine } } else { log.Info("Checkpointing not enabled; a new container instance will be created each time the agent is run") taskEngine = engine.NewTaskEngine(cfg, dockerClient, credentialsManager, containerChangeEventStream, imageManager, state) } stateManager, err := initializeStateManager(cfg, taskEngine, &cfg.Cluster, &containerInstanceArn, ¤tEc2InstanceID) if err != nil { log.Criticalf("Error creating state manager: %v", err) return exitcodes.ExitTerminal } capabilities := taskEngine.Capabilities() // We instantiate our own credentialProvider for use in acs/tcs. This tries // to mimic roughly the way it's instantiated by the SDK for a default // session. credentialProvider := defaults.CredChain(defaults.Config(), defaults.Handlers()) // Preflight request to make sure they're good if preflightCreds, err := credentialProvider.Get(); err != nil || preflightCreds.AccessKeyID == "" { log.Warnf("Error getting valid credentials (AKID %s): %v", preflightCreds.AccessKeyID, err) } client := api.NewECSClient(credentialProvider, cfg, httpclient.New(api.RoundtripTimeout, *acceptInsecureCert), ec2MetadataClient) if containerInstanceArn == "" { log.Info("Registering Instance with ECS") containerInstanceArn, err = client.RegisterContainerInstance("", capabilities) if err != nil { log.Errorf("Error registering: %v", err) if retriable, ok := err.(utils.Retriable); ok && !retriable.Retry() { return exitcodes.ExitTerminal } return exitcodes.ExitError } log.Infof("Registration completed successfully. I am running as '%s' in cluster '%s'", containerInstanceArn, cfg.Cluster) // Save our shiny new containerInstanceArn stateManager.Save() } else { log.Infof("Restored from checkpoint file. I am running as '%s' in cluster '%s'", containerInstanceArn, cfg.Cluster) _, err = client.RegisterContainerInstance(containerInstanceArn, capabilities) if err != nil { log.Errorf("Error re-registering: %v", err) if awserr, ok := err.(awserr.Error); ok && api.IsInstanceTypeChangedError(awserr) { log.Criticalf("The current instance type does not match the registered instance type. Please revert the instance type change, or alternatively launch a new instance. Error: %v", err) return exitcodes.ExitTerminal } return exitcodes.ExitError } } // Begin listening to the docker daemon and saving changes taskEngine.SetSaver(stateManager) imageManager.SetSaver(stateManager) taskEngine.MustInit() // start of the periodic image cleanup process if !cfg.ImageCleanupDisabled { go imageManager.StartImageCleanupProcess(ctx) } go sighandlers.StartTerminationHandler(stateManager, taskEngine) // Agent introspection api go handlers.ServeHttp(&containerInstanceArn, taskEngine, cfg) // Start serving the endpoint to fetch IAM Role credentials go credentialshandler.ServeHttp(credentialsManager, containerInstanceArn, cfg) // Start sending events to the backend go eventhandler.HandleEngineEvents(taskEngine, client, stateManager) deregisterInstanceEventStream := eventstream.NewEventStream(DeregisterContainerInstanceEventStream, ctx) deregisterInstanceEventStream.StartListening() telemetrySessionParams := tcshandler.TelemetrySessionParams{ ContainerInstanceArn: containerInstanceArn, CredentialProvider: credentialProvider, Cfg: cfg, DeregisterInstanceEventStream: deregisterInstanceEventStream, ContainerChangeEventStream: containerChangeEventStream, DockerClient: dockerClient, AcceptInvalidCert: *acceptInsecureCert, EcsClient: client, TaskEngine: taskEngine, } // Start metrics session in a go routine go tcshandler.StartMetricsSession(telemetrySessionParams) log.Info("Beginning Polling for updates") err = acshandler.StartSession(ctx, acshandler.StartSessionArguments{ AcceptInvalidCert: *acceptInsecureCert, Config: cfg, DeregisterInstanceEventStream: deregisterInstanceEventStream, ContainerInstanceArn: containerInstanceArn, CredentialProvider: credentialProvider, ECSClient: client, StateManager: stateManager, TaskEngine: taskEngine, CredentialsManager: credentialsManager, }) if err != nil { log.Criticalf("Unretriable error starting communicating with ACS: %v", err) return exitcodes.ExitTerminal } log.Critical("ACS Session handler should never exit") return exitcodes.ExitError }
func init() { cfg, _ = config.NewConfig(ec2.NewBlackholeEC2MetadataClient()) taskEngine = NewDockerTaskEngine(cfg) }