in agent/engine/daemonmanager/daemon_manager.go [67:179]
func (dm *daemonManager) CreateDaemonTask() (*apitask.Task, error) {
imageName := dm.managedDaemon.GetImageName()
// create daemon-specific host mounts
if err := dm.initDaemonDirectoryMounts(imageName); err != nil {
logger.Error("initDaemonDirectory failure",
logger.Fields{
field.Error: err,
})
return nil, err
}
loadedImageRef := dm.managedDaemon.GetLoadedDaemonImageRef()
containerRunning := apicontainerstatus.ContainerRunning
stringCaps := []string{}
if dm.managedDaemon.GetLinuxParameters() != nil {
caps := dm.managedDaemon.GetLinuxParameters().Capabilities.Add
for _, cap := range caps {
stringCaps = append(stringCaps, *cap)
}
}
dockerHostConfig := dockercontainer.HostConfig{
Mounts: []dockermount.Mount{},
NetworkMode: apitask.HostNetworkMode,
// the default value of 0 for MaximumRetryCount means retry indefinitely
RestartPolicy: dockercontainer.RestartPolicy{
Name: "on-failure",
MaximumRetryCount: 0,
},
Privileged: dm.managedDaemon.GetPrivileged(),
CapAdd: stringCaps,
}
if !dm.managedDaemon.IsValidManagedDaemon() {
return nil, fmt.Errorf("%s is an invalid managed daemon", imageName)
}
for _, mp := range dm.managedDaemon.GetMountPoints() {
if err := mkdirAllAndChown(mp.SourceVolumeHostPath, daemonMountPermission, daemonUID, os.Getegid()); err != nil {
return nil, err
}
var bindOptions = dockermount.BindOptions{}
if mp.PropagationShared {
// https://github.com/moby/moby/blob/master/api/types/mount/mount.go#L52
bindOptions = dockermount.BindOptions{Propagation: dockermount.PropagationShared}
}
logger.Info(fmt.Sprintf("bindMount Propagation: %s", bindOptions.Propagation),
logger.Fields{
field.Image: loadedImageRef,
})
typeBind := dockermount.TypeBind
mountPoint := dockermount.Mount{}
if mp.SourceVolumeType == "npipe" {
typeBind = dockermount.TypeNamedPipe
mountPoint = dockermount.Mount{
Type: typeBind,
Source: mp.SourceVolumeHostPath,
Target: mp.ContainerPath,
}
} else {
mountPoint = dockermount.Mount{
Type: typeBind,
Source: mp.SourceVolumeHostPath,
Target: mp.ContainerPath,
BindOptions: &bindOptions,
}
}
dockerHostConfig.Mounts = append(dockerHostConfig.Mounts, mountPoint)
}
rawHostConfig, err := json.Marshal(&dockerHostConfig)
if err != nil {
return nil, err
}
healthConfig := dm.managedDaemon.GetDockerHealthConfig()
var rawConfig = ""
rawHealthConfig, err := json.Marshal(&healthConfig)
if err != nil {
return nil, err
}
// The raw host config needs to be created this way - if we marshal the entire config object
// directly, and the object only contains healthcheck, all other fields will be written as empty/nil
// in the result string. This will override the configurations that comes with the container image
// (CMD for example)
// TODO update User in raw config to use either runAs user or runAsRoot from managed daemon config
rawConfig = fmt.Sprintf(rawContainerConfigurationTemplate, string(rawHealthConfig))
daemonTask := &apitask.Task{
Arn: fmt.Sprintf("arn:::::/%s-%s", dm.managedDaemon.GetImageName(), uuid.NewUUID()),
DesiredStatusUnsafe: apitaskstatus.TaskRunning,
Containers: []*apicontainer.Container{{
// name must be unique among running containers
// We should only have a single managed daemon of each type per instance
Name: fmt.Sprintf("ecs-managed-%s", dm.managedDaemon.GetImageName()),
Image: loadedImageRef,
ContainerArn: fmt.Sprintf("arn:::::/instance-%s", imageName),
Type: apicontainer.ContainerManagedDaemon,
Command: dm.managedDaemon.GetCommand(),
TransitionDependenciesMap: make(map[apicontainerstatus.ContainerStatus]apicontainer.TransitionDependencySet),
Essential: true,
SteadyStateStatusUnsafe: &containerRunning,
DockerConfig: apicontainer.DockerConfig{
Config: aws.String(rawConfig),
HostConfig: aws.String(string(rawHostConfig)),
},
HealthCheckType: "DOCKER",
}},
LaunchType: "EC2",
NetworkMode: apitask.HostNetworkMode,
ResourcesMapUnsafe: make(map[string][]taskresource.TaskResource),
IsInternal: true,
}
// add managed daemon environment to daemon task container
daemonTask.Containers[0].MergeEnvironmentVariables(dm.managedDaemon.GetEnvironment())
return daemonTask, nil
}