Example #1
0
// EnvironmentConfig reads the given configs from the environment and attempts
// to convert them to the given type
func EnvironmentConfig() Config {
	endpoint := os.Getenv("ECS_BACKEND_HOST")

	clusterRef := os.Getenv("ECS_CLUSTER")
	awsRegion := os.Getenv("AWS_DEFAULT_REGION")

	dockerEndpoint := os.Getenv("DOCKER_HOST")
	engineAuthType := os.Getenv("ECS_ENGINE_AUTH_TYPE")
	engineAuthData := os.Getenv("ECS_ENGINE_AUTH_DATA")

	var checkpoint bool
	dataDir := os.Getenv("ECS_DATADIR")
	if dataDir != "" {
		// if we have a directory to checkpoint to, default it to be on
		checkpoint = utils.ParseBool(os.Getenv("ECS_CHECKPOINT"), true)
	} else {
		// if the directory is not set, default to checkpointing off for
		// backwards compatibility
		checkpoint = utils.ParseBool(os.Getenv("ECS_CHECKPOINT"), false)
	}

	// Format: json array, e.g. [1,2,3]
	reservedPortEnv := os.Getenv("ECS_RESERVED_PORTS")
	portDecoder := json.NewDecoder(strings.NewReader(reservedPortEnv))
	var reservedPorts []uint16
	err := portDecoder.Decode(&reservedPorts)
	// EOF means the string was blank as opposed to UnexepctedEof which means an
	// invalid parse
	// Blank is not a warning; we have sane defaults
	if err != io.EOF && err != nil {
		log.Warn("Invalid format for \"ECS_RESERVED_PORTS\" environment variable; expected a JSON array like [1,2,3].", "err", err)
	}

	reservedPortUDPEnv := os.Getenv("ECS_RESERVED_PORTS_UDP")
	portDecoderUDP := json.NewDecoder(strings.NewReader(reservedPortUDPEnv))
	var reservedPortsUDP []uint16
	err = portDecoderUDP.Decode(&reservedPortsUDP)
	// EOF means the string was blank as opposed to UnexepctedEof which means an
	// invalid parse
	// Blank is not a warning; we have sane defaults
	if err != io.EOF && err != nil {
		log.Warn("Invalid format for \"ECS_RESERVED_PORTS_UDP\" environment variable; expected a JSON array like [1,2,3].", "err", err)
	}

	updateDownloadDir := os.Getenv("ECS_UPDATE_DOWNLOAD_DIR")
	updatesEnabled := utils.ParseBool(os.Getenv("ECS_UPDATES_ENABLED"), false)

	disableMetrics := utils.ParseBool(os.Getenv("ECS_DISABLE_METRICS"), false)
	dockerGraphPath := os.Getenv("ECS_DOCKER_GRAPHPATH")

	reservedMemoryEnv := os.Getenv("ECS_RESERVED_MEMORY")
	var reservedMemory64 uint64
	var reservedMemory uint16
	if reservedMemoryEnv == "" {
		reservedMemory = 0
	} else {
		reservedMemory64, err = strconv.ParseUint(reservedMemoryEnv, 10, 16)
		if err != nil {
			log.Warn("Invalid format for \"ECS_RESERVED_MEMORY\" environment variable; expected unsigned integer.", "err", err)
			reservedMemory = 0
		} else {
			reservedMemory = uint16(reservedMemory64)
		}
	}

	availableLoggingDriversEnv := os.Getenv("ECS_AVAILABLE_LOGGING_DRIVERS")
	loggingDriverDecoder := json.NewDecoder(strings.NewReader(availableLoggingDriversEnv))
	var availableLoggingDrivers []dockerclient.LoggingDriver
	err = loggingDriverDecoder.Decode(&availableLoggingDrivers)
	// EOF means the string was blank as opposed to UnexepctedEof which means an
	// invalid parse
	// Blank is not a warning; we have sane defaults
	if err != io.EOF && err != nil {
		log.Warn("Invalid format for \"ECS_AVAILABLE_LOGGING_DRIVERS\" environment variable; expected a JSON array like [\"json-file\",\"syslog\"].", "err", err)
	}

	privilegedDisabled := utils.ParseBool(os.Getenv("ECS_DISABLE_PRIVILEGED"), false)
	seLinuxCapable := utils.ParseBool(os.Getenv("ECS_SELINUX_CAPABLE"), false)
	appArmorCapable := utils.ParseBool(os.Getenv("ECS_APPARMOR_CAPABLE"), false)

	return Config{
		Cluster:                 clusterRef,
		APIEndpoint:             endpoint,
		AWSRegion:               awsRegion,
		DockerEndpoint:          dockerEndpoint,
		ReservedPorts:           reservedPorts,
		ReservedPortsUDP:        reservedPortsUDP,
		DataDir:                 dataDir,
		Checkpoint:              checkpoint,
		EngineAuthType:          engineAuthType,
		EngineAuthData:          NewSensitiveRawMessage([]byte(engineAuthData)),
		UpdatesEnabled:          updatesEnabled,
		UpdateDownloadDir:       updateDownloadDir,
		DisableMetrics:          disableMetrics,
		DockerGraphPath:         dockerGraphPath,
		ReservedMemory:          reservedMemory,
		AvailableLoggingDrivers: availableLoggingDrivers,
		PrivilegedDisabled:      privilegedDisabled,
		SELinuxCapable:          seLinuxCapable,
		AppArmorCapable:         appArmorCapable,
	}
}
// environmentConfig reads the given configs from the environment and attempts
// to convert them to the given type
func environmentConfig() Config {
	endpoint := os.Getenv("ECS_BACKEND_HOST")

	clusterRef := os.Getenv("ECS_CLUSTER")
	awsRegion := os.Getenv("AWS_DEFAULT_REGION")

	dockerEndpoint := os.Getenv("DOCKER_HOST")
	engineAuthType := os.Getenv("ECS_ENGINE_AUTH_TYPE")
	engineAuthData := os.Getenv("ECS_ENGINE_AUTH_DATA")

	var checkpoint bool
	dataDir := os.Getenv("ECS_DATADIR")
	if dataDir != "" {
		// if we have a directory to checkpoint to, default it to be on
		checkpoint = utils.ParseBool(os.Getenv("ECS_CHECKPOINT"), true)
	} else {
		// if the directory is not set, default to checkpointing off for
		// backwards compatibility
		checkpoint = utils.ParseBool(os.Getenv("ECS_CHECKPOINT"), false)
	}

	// Format: json array, e.g. [1,2,3]
	reservedPortEnv := os.Getenv("ECS_RESERVED_PORTS")
	portDecoder := json.NewDecoder(strings.NewReader(reservedPortEnv))
	var reservedPorts []uint16
	err := portDecoder.Decode(&reservedPorts)
	// EOF means the string was blank as opposed to UnexepctedEof which means an
	// invalid parse
	// Blank is not a warning; we have sane defaults
	if err != io.EOF && err != nil {
		seelog.Warnf("Invalid format for \"ECS_RESERVED_PORTS\" environment variable; expected a JSON array like [1,2,3]. err %v", err)
	}

	reservedPortUDPEnv := os.Getenv("ECS_RESERVED_PORTS_UDP")
	portDecoderUDP := json.NewDecoder(strings.NewReader(reservedPortUDPEnv))
	var reservedPortsUDP []uint16
	err = portDecoderUDP.Decode(&reservedPortsUDP)
	// EOF means the string was blank as opposed to UnexepctedEof which means an
	// invalid parse
	// Blank is not a warning; we have sane defaults
	if err != io.EOF && err != nil {
		seelog.Warnf("Invalid format for \"ECS_RESERVED_PORTS_UDP\" environment variable; expected a JSON array like [1,2,3]. err %v", err)
	}

	updateDownloadDir := os.Getenv("ECS_UPDATE_DOWNLOAD_DIR")
	updatesEnabled := utils.ParseBool(os.Getenv("ECS_UPDATES_ENABLED"), false)

	disableMetrics := utils.ParseBool(os.Getenv("ECS_DISABLE_METRICS"), false)

	reservedMemory := parseEnvVariableUint16("ECS_RESERVED_MEMORY")

	var dockerStopTimeout time.Duration
	parsedStopTimeout := parseEnvVariableDuration("ECS_CONTAINER_STOP_TIMEOUT")
	if parsedStopTimeout >= minimumDockerStopTimeout {
		dockerStopTimeout = parsedStopTimeout
	} else if parsedStopTimeout != 0 {
		seelog.Warnf("Discarded invalid value for docker stop timeout, parsed as: %v", parsedStopTimeout)
	}

	taskCleanupWaitDuration := parseEnvVariableDuration("ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION")
	availableLoggingDriversEnv := os.Getenv("ECS_AVAILABLE_LOGGING_DRIVERS")
	loggingDriverDecoder := json.NewDecoder(strings.NewReader(availableLoggingDriversEnv))
	var availableLoggingDrivers []dockerclient.LoggingDriver
	err = loggingDriverDecoder.Decode(&availableLoggingDrivers)
	// EOF means the string was blank as opposed to UnexepctedEof which means an
	// invalid parse
	// Blank is not a warning; we have sane defaults
	if err != io.EOF && err != nil {
		seelog.Warnf("Invalid format for \"ECS_AVAILABLE_LOGGING_DRIVERS\" environment variable; expected a JSON array like [\"json-file\",\"syslog\"]. err %v", err)
	}

	privilegedDisabled := utils.ParseBool(os.Getenv("ECS_DISABLE_PRIVILEGED"), false)
	seLinuxCapable := utils.ParseBool(os.Getenv("ECS_SELINUX_CAPABLE"), false)
	appArmorCapable := utils.ParseBool(os.Getenv("ECS_APPARMOR_CAPABLE"), false)
	taskIAMRoleEnabled := utils.ParseBool(os.Getenv("ECS_ENABLE_TASK_IAM_ROLE"), false)
	taskIAMRoleEnabledForNetworkHost := utils.ParseBool(os.Getenv("ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST"), false)

	credentialsAuditLogFile := os.Getenv("ECS_AUDIT_LOGFILE")
	credentialsAuditLogDisabled := utils.ParseBool(os.Getenv("ECS_AUDIT_LOGFILE_DISABLED"), false)

	imageCleanupDisabled := utils.ParseBool(os.Getenv("ECS_DISABLE_IMAGE_CLEANUP"), false)
	minimumImageDeletionAge := parseEnvVariableDuration("ECS_IMAGE_MINIMUM_CLEANUP_AGE")
	imageCleanupInterval := parseEnvVariableDuration("ECS_IMAGE_CLEANUP_INTERVAL")
	numImagesToDeletePerCycle, err := strconv.Atoi(os.Getenv("ECS_NUM_IMAGES_DELETE_PER_CYCLE"))
	if err != nil {
		seelog.Warnf("Invalid format for \"ECS_NUM_IMAGES_DELETE_PER_CYCLE\", expected an integer. err %v", err)
	}

	return Config{
		Cluster:                          clusterRef,
		APIEndpoint:                      endpoint,
		AWSRegion:                        awsRegion,
		DockerEndpoint:                   dockerEndpoint,
		ReservedPorts:                    reservedPorts,
		ReservedPortsUDP:                 reservedPortsUDP,
		DataDir:                          dataDir,
		Checkpoint:                       checkpoint,
		EngineAuthType:                   engineAuthType,
		EngineAuthData:                   NewSensitiveRawMessage([]byte(engineAuthData)),
		UpdatesEnabled:                   updatesEnabled,
		UpdateDownloadDir:                updateDownloadDir,
		DisableMetrics:                   disableMetrics,
		ReservedMemory:                   reservedMemory,
		AvailableLoggingDrivers:          availableLoggingDrivers,
		PrivilegedDisabled:               privilegedDisabled,
		SELinuxCapable:                   seLinuxCapable,
		AppArmorCapable:                  appArmorCapable,
		TaskCleanupWaitDuration:          taskCleanupWaitDuration,
		TaskIAMRoleEnabled:               taskIAMRoleEnabled,
		DockerStopTimeout:                dockerStopTimeout,
		CredentialsAuditLogFile:          credentialsAuditLogFile,
		CredentialsAuditLogDisabled:      credentialsAuditLogDisabled,
		TaskIAMRoleEnabledForNetworkHost: taskIAMRoleEnabledForNetworkHost,
		ImageCleanupDisabled:             imageCleanupDisabled,
		MinimumImageDeletionAge:          minimumImageDeletionAge,
		ImageCleanupInterval:             imageCleanupInterval,
		NumImagesToDeletePerCycle:        numImagesToDeletePerCycle,
	}
}