in internal/agentdeployer/agent.go [100:220]
func (d *DockerComposeAgentDeployer) SetUp(ctx context.Context, agentInfo AgentInfo) (DeployedAgent, error) {
logger.Debug("setting up agent using Docker Compose agent deployer")
d.agentRunID = agentInfo.Test.RunID
appConfig, err := install.Configuration(install.OptionWithStackVersion(d.stackVersion))
if err != nil {
return nil, fmt.Errorf("can't read application configuration: %w", err)
}
caCertPath, err := stack.FindCACertificate(d.profile)
if err != nil {
return nil, fmt.Errorf("can't locate CA certificate: %w", err)
}
env := append(
appConfig.StackImageRefs().AsEnv(),
fmt.Sprintf("%s=%s", serviceLogsDirEnv, agentInfo.Logs.Folder.Local),
fmt.Sprintf("%s=%s", localCACertEnv, caCertPath),
fmt.Sprintf("%s=%s", fleetPolicyEnv, d.policyName),
fmt.Sprintf("%s=%s", agentHostnameEnv, d.agentHostname()),
)
configDir, err := d.installDockerCompose(ctx, agentInfo)
if err != nil {
return nil, fmt.Errorf("could not create resources for custom agent: %w", err)
}
composeProjectName := fmt.Sprintf("elastic-package-agent-%s-%s", d.agentName(), agentInfo.Test.RunID)
agent := dockerComposeDeployedAgent{
ymlPaths: []string{filepath.Join(configDir, dockerTestAgentDockerCompose)},
project: composeProjectName,
env: env,
configDir: configDir,
}
agentInfo.NetworkName = fmt.Sprintf("%s_default", composeProjectName)
p, err := compose.NewProject(agent.project, agent.ymlPaths...)
if err != nil {
return nil, fmt.Errorf("could not create Docker Compose project for agent: %w", err)
}
// Verify the Elastic stack network
err = stack.EnsureStackNetworkUp(d.profile)
if err != nil {
return nil, fmt.Errorf("stack network is not ready: %w", err)
}
// Clean service logs
if d.runTestsOnly {
// service logs folder must no be deleted to avoid breaking log files written
// by the service. If this is required, those files should be rotated or truncated
// so the service can still write to them.
logger.Debugf("Skipping removing service logs folder %s", agentInfo.Logs.Folder.Local)
} else {
err = files.RemoveContent(agentInfo.Logs.Folder.Local)
if err != nil {
return nil, fmt.Errorf("removing service logs failed: %w", err)
}
}
// Service name defined in the docker-compose file
agentInfo.Name = dockerTestAgentServiceName
agentName := agentInfo.Name
opts := compose.CommandOptions{
Env: env,
ExtraArgs: []string{"--build", "-d"},
}
if d.runTestsOnly || d.runTearDown {
logger.Debug("Skipping bringing up docker-compose project and connect container to network (non setup steps)")
} else {
err = p.Up(ctx, opts)
if err != nil {
return nil, fmt.Errorf("could not boot up agent using Docker Compose: %w", err)
}
// Connect service network with stack network (for the purpose of metrics collection)
err = docker.ConnectToNetwork(p.ContainerName(agentName), stack.Network(d.profile))
if err != nil {
return nil, fmt.Errorf("can't attach agent container to the stack network: %w", err)
}
}
// requires to be connected the service to the stack network
err = p.WaitForHealthy(ctx, opts)
if err != nil {
processAgentContainerLogs(ctx, p, compose.CommandOptions{
Env: opts.Env,
}, agentName)
return nil, fmt.Errorf("service is unhealthy: %w", err)
}
// Build agent container name
// For those packages that require to do requests to agent ports in their tests (e.g. ti_anomali),
// using the ContainerName of the agent (p.ContainerName(agentName)) as in servicedeployer does not work,
// probably because it is in another compose project in case of ti_anomali?.
agentInfo.Hostname = d.agentHostname()
logger.Debugf("adding service container %s internal ports to context", p.ContainerName(agentName))
serviceComposeConfig, err := p.Config(ctx, compose.CommandOptions{Env: env})
if err != nil {
return nil, fmt.Errorf("could not get Docker Compose configuration for service: %w", err)
}
s := serviceComposeConfig.Services[agentName]
agentInfo.Ports = make([]int, len(s.Ports))
for idx, port := range s.Ports {
agentInfo.Ports[idx] = port.InternalPort
}
// Shortcut to first port for convenience
if len(agentInfo.Ports) > 0 {
agentInfo.Port = agentInfo.Ports[0]
}
agentInfo.Agent.Host.NamePrefix = agentInfo.Name
agent.agentInfo = agentInfo
return &agent, nil
}