Skip to content

Commit

Permalink
Add new setting in system configuration file to set Elastic Agent ima…
Browse files Browse the repository at this point in the history
…ge type (#2044)

Added support to check the new setting in the system test
configuration file to set the Elastic Agent base image to be used
during tests.
  • Loading branch information
mrodm authored Aug 29, 2024
1 parent 3131065 commit 0d3c215
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 53 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,11 @@ There are available some environment variables that could be used to change some
- `ELASTIC_PACKAGE_SERVERLESS_PIPELINE_TEST_DISABLE_COMPARE_RESULTS`: If set to `true`, the results from pipeline tests are not compared to avoid errors from GeoIP.
- `ELASTIC_PACKAGE_DISABLE_ELASTIC_AGENT_WOLFI`: If set to `true`, the Elastic Agent image used for running agents will be using the Ubuntu docker images
(e.g. `docker.elastic.co/elastic-agent/elastic-agent-complete`). If set to `false`, the Elastic Agent image used for the running agents will be based on the wolfi
<<<<<<< HEAD
images (e.g. `docker.elastic.co/elastic-agent/elastic-agent-wolfi`). Default: `true`.
=======
images (e.g. `docker.elastic.co/elastic-agent/elastic-agent-wolfi`). Default: `false`.
>>>>>>> upstream/main
- To configure the Elastic stack to be used by `elastic-package`:
- `ELASTIC_PACKAGE_ELASTICSEARCH_HOST`: Host of the elasticsearch (e.g. https://127.0.0.1:9200)
Expand Down
20 changes: 15 additions & 5 deletions internal/agentdeployer/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (d *DockerComposeAgentDeployer) SetUp(ctx context.Context, agentInfo AgentI
logger.Debug("setting up agent using Docker Compose agent deployer")
d.agentRunID = agentInfo.Test.RunID

appConfig, err := install.Configuration()
appConfig, err := install.Configuration(install.OptionWithStackVersion(d.stackVersion))
if err != nil {
return nil, fmt.Errorf("can't read application configuration: %w", err)
}
Expand All @@ -112,7 +112,7 @@ func (d *DockerComposeAgentDeployer) SetUp(ctx context.Context, agentInfo AgentI
}

env := append(
appConfig.StackImageRefs(d.stackVersion).AsEnv(),
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),
Expand Down Expand Up @@ -264,14 +264,14 @@ func (d *DockerComposeAgentDeployer) installDockerCompose(agentInfo AgentInfo) (
stackVersion = config.Parameters[stack.ParamServerlessLocalStackVersion]
}

appConfig, err := install.Configuration()
agentImage, err := selectElasticAgentImage(stackVersion, agentInfo.Agent.BaseImage)
if err != nil {
return "", fmt.Errorf("can't read application configuration: %w", err)
return "", nil
}

resourceManager := resource.NewManager()
resourceManager.AddFacter(resource.StaticFacter{
"agent_image": appConfig.StackImageRefs(stackVersion).ElasticAgent,
"agent_image": agentImage,
"user": agentInfo.Agent.User,
"capabilities": strings.Join(agentInfo.Agent.LinuxCapabilities, ","),
"runtime": agentInfo.Agent.Runtime,
Expand Down Expand Up @@ -303,6 +303,16 @@ func (d *DockerComposeAgentDeployer) installDockerCompose(agentInfo AgentInfo) (
return customAgentDir, nil
}

func selectElasticAgentImage(stackVersion, agentBaseImage string) (string, error) {
appConfig, err := install.Configuration(install.OptionWithAgentBaseImage(agentBaseImage), install.OptionWithStackVersion(stackVersion))
if err != nil {
return "", fmt.Errorf("can't read application configuration: %w", err)
}

agentImage := appConfig.StackImageRefs().ElasticAgent
return agentImage, nil
}

func (d *DockerComposeAgentDeployer) installDockerfileResources(agentSettings AgentSettings, folder string) error {
agentResources := []resource.Resource{
&resource.File{
Expand Down
2 changes: 2 additions & 0 deletions internal/agentdeployer/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type AgentScript struct {
type AgentSettings struct {
// User user to run Elastic Agent process
User string `config:"user"`
// BaseImage elastic-agent base image to be used for testing
BaseImage string `config:"base_image"`
// PidMode selects the host PID mode
// (From docker-compose docs) Turns on sharing between container and the host
// operating system the PID address space
Expand Down
4 changes: 2 additions & 2 deletions internal/agentdeployer/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ var elasticAgentManagedYamlTmpl string
func getElasticAgentYAML(profile *profile.Profile, stackVersion, policyName, agentName string) ([]byte, error) {
logger.Debugf("Prepare YAML definition for Elastic Agent running in stack v%s", stackVersion)

appConfig, err := install.Configuration()
appConfig, err := install.Configuration(install.OptionWithStackVersion(stackVersion))
if err != nil {
return nil, fmt.Errorf("can't read application configuration: %w", err)
}
Expand All @@ -196,7 +196,7 @@ func getElasticAgentYAML(profile *profile.Profile, stackVersion, policyName, age
"fleetURL": "https://fleet-server:8220",
"kibanaURL": "https://kibana:5601",
"caCertPem": caCert,
"elasticAgentImage": appConfig.StackImageRefs(stackVersion).ElasticAgent,
"elasticAgentImage": appConfig.StackImageRefs().ElasticAgent,
"elasticAgentTokenPolicyName": getTokenPolicyName(stackVersion, policyName),
"agentName": agentName,
})
Expand Down
68 changes: 50 additions & 18 deletions internal/install/application_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ func DefaultConfiguration() *ApplicationConfiguration {

// ApplicationConfiguration represents the configuration of the elastic-package.
type ApplicationConfiguration struct {
c configFile
c configFile
agentBaseImage string
stackVersion string
}

type configFile struct {
Expand Down Expand Up @@ -119,12 +121,12 @@ func (ir ImageRefs) AsEnv() []string {
}

// StackImageRefs function selects the appropriate set of Docker image references for the given stack version.
func (ac *ApplicationConfiguration) StackImageRefs(version string) ImageRefs {
refs := ac.c.Stack.ImageRefOverridesForVersion(version)
refs.ElasticAgent = stringOrDefault(refs.ElasticAgent, fmt.Sprintf("%s:%s", selectElasticAgentImageName(version), version))
refs.Elasticsearch = stringOrDefault(refs.Elasticsearch, fmt.Sprintf("%s:%s", elasticsearchImageName, version))
refs.Kibana = stringOrDefault(refs.Kibana, fmt.Sprintf("%s:%s", kibanaImageName, version))
refs.Logstash = stringOrDefault(refs.Logstash, fmt.Sprintf("%s:%s", logstashImageName, version))
func (ac *ApplicationConfiguration) StackImageRefs() ImageRefs {
refs := ac.c.Stack.ImageRefOverridesForVersion(ac.stackVersion)
refs.ElasticAgent = stringOrDefault(refs.ElasticAgent, fmt.Sprintf("%s:%s", selectElasticAgentImageName(ac.stackVersion, ac.agentBaseImage), ac.stackVersion))
refs.Elasticsearch = stringOrDefault(refs.Elasticsearch, fmt.Sprintf("%s:%s", elasticsearchImageName, ac.stackVersion))
refs.Kibana = stringOrDefault(refs.Kibana, fmt.Sprintf("%s:%s", kibanaImageName, ac.stackVersion))
refs.Logstash = stringOrDefault(refs.Logstash, fmt.Sprintf("%s:%s", logstashImageName, ac.stackVersion))
return refs
}

Expand All @@ -148,7 +150,7 @@ func (ac *ApplicationConfiguration) SetCurrentProfile(name string) {

// selectElasticAgentImageName function returns the appropriate image name for Elastic-Agent depending on the stack version.
// This is mandatory as "elastic-agent-complete" is available since 7.15.0-SNAPSHOT.
func selectElasticAgentImageName(version string) string {
func selectElasticAgentImageName(version, agentBaseImage string) string {
if version == "" { // as version is optional and can be empty
return elasticAgentImageName
}
Expand All @@ -164,20 +166,41 @@ func selectElasticAgentImageName(version string) string {
if ok && strings.ToLower(valueEnv) != "false" {
disableWolfiImages = true
}
if !disableWolfiImages && !v.LessThan(elasticAgentWolfiVersion) {
switch {
case !disableWolfiImages && !v.LessThan(elasticAgentWolfiVersion) && agentBaseImage != "complete":
return elasticAgentWolfiImageName
}
if !v.LessThan(elasticAgentCompleteOwnNamespaceVersion) {
case !v.LessThan(elasticAgentCompleteOwnNamespaceVersion):
return elasticAgentCompleteImageName
}
if !v.LessThan(elasticAgentCompleteFirstSupportedVersion) {
case !v.LessThan(elasticAgentCompleteFirstSupportedVersion):
return elasticAgentCompleteLegacyImageName
default:
return elasticAgentImageName
}
}

type configurationOptions struct {
agentBaseImage string
stackVersion string
}

type ConfigurationOption func(*configurationOptions)

// OptionWithAgentBaseImage sets the agent image type to be used.
func OptionWithAgentBaseImage(agentBaseImage string) ConfigurationOption {
return func(opts *configurationOptions) {
opts.agentBaseImage = agentBaseImage
}
}

// OptionWithStackVersion sets the Elastic Stack version to be used.
func OptionWithStackVersion(stackVersion string) ConfigurationOption {
return func(opts *configurationOptions) {
opts.stackVersion = stackVersion
}
return elasticAgentImageName
}

// Configuration function returns the elastic-package configuration.
func Configuration() (*ApplicationConfiguration, error) {
func Configuration(options ...ConfigurationOption) (*ApplicationConfiguration, error) {
configPath, err := locations.NewLocationManager()
if err != nil {
return nil, fmt.Errorf("can't read configuration directory: %w", err)
Expand All @@ -197,9 +220,18 @@ func Configuration() (*ApplicationConfiguration, error) {
return nil, fmt.Errorf("can't unmarshal configuration file: %w", err)
}

return &ApplicationConfiguration{
c: c,
}, nil
configOptions := configurationOptions{}
for _, option := range options {
option(&configOptions)
}

configuration := ApplicationConfiguration{
c: c,
agentBaseImage: configOptions.agentBaseImage,
stackVersion: configOptions.stackVersion,
}

return &configuration, nil
}

func stringOrDefault(value string, defaultValue string) string {
Expand Down
31 changes: 21 additions & 10 deletions internal/install/application_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,72 @@ import (

func TestSelectElasticAgentImageName_NoVersion(t *testing.T) {
var version string
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentImageName)
}

func TestSelectElasticAgentImageName_OlderStack(t *testing.T) {
version := "7.14.99-SNAPSHOT"
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentImageName)
}

func TestSelectElasticAgentImageName_FirstStackWithCompleteAgent(t *testing.T) {
version := stackVersion715
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentCompleteLegacyImageName)
}

func TestSelectElasticAgentImageName_NextStackWithAgentComplete(t *testing.T) {
version := "7.16.0-SNAPSHOT"
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentCompleteLegacyImageName)
}

func TestSelectElasticAgentImageName_OwnNamespace(t *testing.T) {
version := "8.2.0-SNAPSHOT"
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentCompleteImageName)
}

func TestSelectElasticAgentImageName_OwnNamespace_Release(t *testing.T) {
version := "8.2.0"
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentCompleteImageName)
}

func TestSelectElasticAgentImageName_NextStackInOwnNamespace(t *testing.T) {
version := "8.4.0-SNAPSHOT"
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentCompleteImageName)
}

func TestSelectElasticAgentImageName_WolfiImage(t *testing.T) {
version := "8.16.0-SNAPSHOT"
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentWolfiImageName)
}

func TestSelectElasticAgentImageName_DisableWolfiImageEnvVar(t *testing.T) {
version := "8.16.0-SNAPSHOT"
t.Setenv(disableElasticAgentWolfiEnvVar, "true")
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentCompleteImageName)
}
func TestSelectElasticAgentImageName_EnableWolfiImageEnvVar(t *testing.T) {
version := "8.16.0-SNAPSHOT"
t.Setenv(disableElasticAgentWolfiEnvVar, "false")
selected := selectElasticAgentImageName(version)
selected := selectElasticAgentImageName(version, "")
assert.Equal(t, selected, elasticAgentWolfiImageName)
}

func TestSelectCompleteElasticAgentImageName_ForceCompleteImage(t *testing.T) {
version := "8.16.0-SNAPSHOT"
selected := selectElasticAgentImageName(version, "complete")
assert.Equal(t, selected, elasticAgentCompleteImageName)
}
func TestSelectCompleteElasticAgentImageName_ForceDefaultImage(t *testing.T) {
version := "8.16.0-SNAPSHOT"
selected := selectElasticAgentImageName(version, "default")
assert.Equal(t, selected, elasticAgentWolfiImageName)
}
4 changes: 2 additions & 2 deletions internal/servicedeployer/custom_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func NewCustomAgentDeployer(options CustomAgentDeployerOptions) (*CustomAgentDep
func (d *CustomAgentDeployer) SetUp(ctx context.Context, svcInfo ServiceInfo) (DeployedService, error) {
logger.Warn("DEPRECATED - setting up service using Docker Compose service deployer")

appConfig, err := install.Configuration()
appConfig, err := install.Configuration(install.OptionWithStackVersion(d.stackVersion))
if err != nil {
return nil, fmt.Errorf("can't read application configuration: %w", err)
}
Expand All @@ -90,7 +90,7 @@ func (d *CustomAgentDeployer) SetUp(ctx context.Context, svcInfo ServiceInfo) (D
svcInfo.Hostname = dockerCustomAgentName

env := append(
appConfig.StackImageRefs(d.stackVersion).AsEnv(),
appConfig.StackImageRefs().AsEnv(),
fmt.Sprintf("%s=%s", serviceLogsDirEnv, svcInfo.Logs.Folder.Local),
fmt.Sprintf("%s=%s", localCACertEnv, caCertPath),
fmt.Sprintf("%s=%s", fleetPolicyEnv, d.policyName),
Expand Down
4 changes: 2 additions & 2 deletions internal/servicedeployer/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ var elasticAgentManagedYamlTmpl string
func getElasticAgentYAML(profile *profile.Profile, stackVersion, policyName string) ([]byte, error) {
logger.Debugf("Prepare YAML definition for Elastic Agent running in stack v%s", stackVersion)

appConfig, err := install.Configuration()
appConfig, err := install.Configuration(install.OptionWithStackVersion(stackVersion))
if err != nil {
return nil, fmt.Errorf("can't read application configuration: %w", err)
}
Expand All @@ -246,7 +246,7 @@ func getElasticAgentYAML(profile *profile.Profile, stackVersion, policyName stri
"fleetURL": "https://fleet-server:8220",
"kibanaURL": "https://kibana:5601",
"caCertPem": caCert,
"elasticAgentImage": appConfig.StackImageRefs(stackVersion).ElasticAgent,
"elasticAgentImage": appConfig.StackImageRefs().ElasticAgent,
"elasticAgentTokenPolicyName": getTokenPolicyName(stackVersion, policyName),
})
if err != nil {
Expand Down
16 changes: 8 additions & 8 deletions internal/stack/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ func dockerComposeBuild(ctx context.Context, options Options) error {
return fmt.Errorf("could not create docker compose project: %w", err)
}

appConfig, err := install.Configuration()
appConfig, err := install.Configuration(install.OptionWithStackVersion(options.StackVersion))
if err != nil {
return fmt.Errorf("can't read application configuration: %w", err)
}

opts := compose.CommandOptions{
Env: newEnvBuilder().
withEnvs(appConfig.StackImageRefs(options.StackVersion).AsEnv()).
withEnvs(appConfig.StackImageRefs().AsEnv()).
withEnv(stackVariantAsEnv(options.StackVersion)).
withEnvs(options.Profile.ComposeEnvVars()).
build(),
Expand All @@ -82,14 +82,14 @@ func dockerComposePull(ctx context.Context, options Options) error {
return fmt.Errorf("could not create docker compose project: %w", err)
}

appConfig, err := install.Configuration()
appConfig, err := install.Configuration(install.OptionWithStackVersion(options.StackVersion))
if err != nil {
return fmt.Errorf("can't read application configuration: %w", err)
}

opts := compose.CommandOptions{
Env: newEnvBuilder().
withEnvs(appConfig.StackImageRefs(options.StackVersion).AsEnv()).
withEnvs(appConfig.StackImageRefs().AsEnv()).
withEnv(stackVariantAsEnv(options.StackVersion)).
withEnvs(options.Profile.ComposeEnvVars()).
build(),
Expand All @@ -113,14 +113,14 @@ func dockerComposeUp(ctx context.Context, options Options) error {
args = append(args, "-d")
}

appConfig, err := install.Configuration()
appConfig, err := install.Configuration(install.OptionWithStackVersion(options.StackVersion))
if err != nil {
return fmt.Errorf("can't read application configuration: %w", err)
}

opts := compose.CommandOptions{
Env: newEnvBuilder().
withEnvs(appConfig.StackImageRefs(options.StackVersion).AsEnv()).
withEnvs(appConfig.StackImageRefs().AsEnv()).
withEnv(stackVariantAsEnv(options.StackVersion)).
withEnvs(options.Profile.ComposeEnvVars()).
build(),
Expand All @@ -140,14 +140,14 @@ func dockerComposeDown(ctx context.Context, options Options) error {
return fmt.Errorf("could not create docker compose project: %w", err)
}

appConfig, err := install.Configuration()
appConfig, err := install.Configuration(install.OptionWithStackVersion(options.StackVersion))
if err != nil {
return fmt.Errorf("can't read application configuration: %w", err)
}

downOptions := compose.CommandOptions{
Env: newEnvBuilder().
withEnvs(appConfig.StackImageRefs(options.StackVersion).AsEnv()).
withEnvs(appConfig.StackImageRefs().AsEnv()).
withEnv(stackVariantAsEnv(options.StackVersion)).
withEnvs(options.Profile.ComposeEnvVars()).
build(),
Expand Down
Loading

0 comments on commit 0d3c215

Please sign in to comment.