diff --git a/.ci/.e2e-tests.yaml b/.ci/.e2e-tests.yaml index f9e1d4caf5..f01c9d6fea 100644 --- a/.ci/.e2e-tests.yaml +++ b/.ci/.e2e-tests.yaml @@ -12,12 +12,15 @@ SUITES: tags: "metricbeat" - suite: "fleet" platforms: + - "arm64" - "ubuntu-18.04" scenarios: - name: "Fleet" pullRequestFilter: " && ~debian" tags: "fleet_mode_agent" - name: "Endpoint Integration" + platforms: + - "ubuntu-18.04" pullRequestFilter: " && ~debian" tags: "agent_endpoint_integration" - name: "Linux Integration" diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 1e1a1aab00..1cc36d3716 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -249,16 +249,23 @@ def checkTestSuite(Map parallelTasks = [:], Map item = [:]) { def suite = item.suite def platforms = item.platforms item.scenarios.each { scenario -> + def name = scenario.name + def platformsValue = platforms + def scenarioPlatforms = scenario.platforms + if (scenarioPlatforms?.size() > 0) { + // scenario platforms take precedence over suite platforms, overriding them + platformsValue = scenarioPlatforms + } def pullRequestFilter = scenario.containsKey('pullRequestFilter') ? scenario.pullRequestFilter : '' def tags = scenario.tags def regexps = [ "^e2e/_suites/${suite}/.*", "^.ci/.*", "^cli/.*", "^e2e/.*\\.go", "^internal/.*\\.go" ] if ("${FORCE_SKIP_GIT_CHECKS}" == "true" || isGitRegionMatch(patterns: regexps, shouldMatchAll: false)) { - platforms.each { platform -> + platformsValue.each { platform -> log(level: 'INFO', text: "Adding ${platform}:${suite}:${tags} test suite to the build execution") - parallelTasks["${platform}_${suite}_${tags}"] = generateFunctionalTestStep(platform: "${platform}", suite: "${suite}", tags: "${tags}", pullRequestFilter: "${pullRequestFilter}") + parallelTasks["${platform}_${suite}_${tags}"] = generateFunctionalTestStep(name: "${name}", platform: "${platform}", suite: "${suite}", tags: "${tags}", pullRequestFilter: "${pullRequestFilter}") } } else { - log(level: 'WARN', text: "The ${suite}:${tags} test suite won't be executed because there are no modified files") + log(level: 'WARN', text: "The ${platform}:${suite}:${tags} test suite won't be executed because there are no modified files") } } } @@ -281,6 +288,7 @@ def doNotifyBuildResult(boolean slackNotify) { } def generateFunctionalTestStep(Map args = [:]){ + def name = args.get('name') def platform = args.get('platform') def suite = args.get('suite') def tags = args.get('tags') @@ -298,7 +306,17 @@ def generateFunctionalTestStep(Map args = [:]){ if (isPR() || isUpstreamTrigger(filter: 'PR-')) { tags += pullRequestFilter } - def workerLabels = "${platform} && immutable && docker" + + def goArch = "amd64" + def workerLabels = "${platform} && immutable" + if (platform == "arm64") { + goArch = "arm64" + // ARM is not ready as immutable workers + workerLabels = "arm" + } + + // Skip scenarios per platform + tags += " && ~@skip:${goArch}" return { withNode(labels: "${workerLabels}", sleepMax: 20, forceWorkspace: true){ @@ -309,10 +327,12 @@ def generateFunctionalTestStep(Map args = [:]){ if(isInstalled(tool: 'docker', flag: '--version')) { dockerLogin(secret: "${DOCKER_ELASTIC_SECRET}", registry: "${DOCKER_REGISTRY}") } - filebeat(output: "docker_logs_${suite}_${tags}.log", workdir: "${env.WORKSPACE}"){ + filebeat(image: 'docker.elastic.co/beats/filebeat:7.13.0-SNAPSHOT', output: "docker_logs_${goArch}_${suite}_${name}.log", workdir: "${env.WORKSPACE}"){ dir("${BASE_DIR}"){ - withSecretVault(secret: "${VAULT_INSTRUMENTATION_SECRET}", user_key: "apmServerToken", user_var_name: "APM_SECRET_TOKEN", pass_key: "apmServerUrl", pass_var_name: "APM_SERVER_URL"){ - sh script: """.ci/scripts/functional-test.sh "${suite}" "${tags}" "${STACK_VERSION}" "${BEAT_VERSION}" """, label: "Run functional tests for ${suite}:${tags}" + withEnv(["GOARCH=${goArch}"]) { + withSecretVault(secret: "${VAULT_INSTRUMENTATION_SECRET}", user_key: "apmServerToken", user_var_name: "APM_SECRET_TOKEN", pass_key: "apmServerUrl", pass_var_name: "APM_SERVER_URL"){ + sh script: """.ci/scripts/functional-test.sh "${suite}" "${tags}" "${STACK_VERSION}" "${BEAT_VERSION}" """, label: "Run functional tests for ${suite}:${tags}" + } } } } diff --git a/.ci/packer_cache.sh b/.ci/packer_cache.sh index 957d43deb8..c999d14011 100755 --- a/.ci/packer_cache.sh +++ b/.ci/packer_cache.sh @@ -5,9 +5,9 @@ source /usr/local/bin/bash_standard_lib.sh readonly GO_VERSION=$(cat .go-version) -DOCKER_IMAGES="centos/systemd:latest -alehaa/debian-systemd:stretch -docker.elastic.co/beats/filebeat:7.10.1 +DOCKER_IMAGES="docker.elastic.co/observability-ci/centos-systemd:latest +docker.elastic.co/observability-ci/debian-systemd:latest +docker.elastic.co/beats/filebeat:7.13.0-SNAPSHOT docker.elastic.co/observability-ci/picklesdoc:2.20.1 golang:${GO_VERSION}-stretch " diff --git a/.ci/scripts/clean-docker.sh b/.ci/scripts/clean-docker.sh index bc3fc0f29c..a49ef696da 100755 --- a/.ci/scripts/clean-docker.sh +++ b/.ci/scripts/clean-docker.sh @@ -12,6 +12,9 @@ set -euxo pipefail readonly VERSION="$(cat $(pwd)/.stack-version)" main() { + # remove running containers + docker container rm -fv $(docker container ls -a --quiet) || true + # refresh docker images cat <.tmp_images docker.elastic.co/beats/elastic-agent:${VERSION} diff --git a/.ci/scripts/functional-test.sh b/.ci/scripts/functional-test.sh index a1ef1f886d..2c51d11c05 100755 --- a/.ci/scripts/functional-test.sh +++ b/.ci/scripts/functional-test.sh @@ -22,6 +22,7 @@ SUITE=${1:-''} TAGS=${2:-''} STACK_VERSION=${3:-"${BASE_VERSION}"} BEAT_VERSION=${4:-"${BASE_VERSION}"} +GOARCH=${GOARCH:-"amd64"} ## Install the required dependencies for the given SUITE .ci/scripts/install-test-dependencies.sh "${SUITE}" @@ -29,6 +30,6 @@ BEAT_VERSION=${4:-"${BASE_VERSION}"} rm -rf outputs || true mkdir -p outputs -REPORT="$(pwd)/outputs/TEST-${SUITE}" +REPORT="$(pwd)/outputs/TEST-${GOARCH}-${SUITE}" -TAGS="${TAGS}" FORMAT=junit:${REPORT}.xml STACK_VERSION=${STACK_VERSION} BEAT_VERSION=${BEAT_VERSION} make --no-print-directory -C e2e/_suites/${SUITE} functional-test +TAGS="${TAGS}" FORMAT=junit:${REPORT}.xml GOARCH=${GOARCH} STACK_VERSION=${STACK_VERSION} BEAT_VERSION=${BEAT_VERSION} make --no-print-directory -C e2e/_suites/${SUITE} functional-test diff --git a/.ci/scripts/install-helm-test-dependencies.sh b/.ci/scripts/install-helm-test-dependencies.sh index f5c054d6ce..e7ba644c79 100755 --- a/.ci/scripts/install-helm-test-dependencies.sh +++ b/.ci/scripts/install-helm-test-dependencies.sh @@ -14,11 +14,12 @@ set -euxo pipefail # - KUBERNETES_VERSION - that's the Kubernetes version which will be installed and enabled. # +GOARCH=${GOARCH:-"amd64"} MSG="parameter missing." HOME=${HOME:?$MSG} HELM_VERSION="${HELM_VERSION:-"3.5.2"}" -HELM_TAR_GZ_FILE="helm-v${HELM_VERSION}-linux-amd64.tar.gz" +HELM_TAR_GZ_FILE="helm-v${HELM_VERSION}-linux-${GOARCH}.tar.gz" KIND_VERSION="v${KIND_VERSION:-"0.10.0"}" KUBERNETES_VERSION="${KUBERNETES_VERSION:-"1.18.2"}" @@ -26,20 +27,20 @@ HELM_CMD="${HOME}/bin/helm" KBC_CMD="${HOME}/bin/kubectl" # Install kind as a Go binary -GO111MODULE="on" go get sigs.k8s.io/kind@${KIND_VERSION} +GOARCH=${GOARCH} GO111MODULE="on" go get sigs.k8s.io/kind@${KIND_VERSION} mkdir -p "${HOME}/bin" "${HOME}/.kube" touch "${HOME}/.kube/config" # Install kubectl -curl -sSLo "${KBC_CMD}" "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl" +curl -sSLo "${KBC_CMD}" "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/${GOARCH}/kubectl" chmod +x "${KBC_CMD}" ${KBC_CMD} version --client # Install Helm curl -o ${HELM_TAR_GZ_FILE} "https://get.helm.sh/${HELM_TAR_GZ_FILE}" tar -xvf ${HELM_TAR_GZ_FILE} -mv linux-amd64/helm ${HELM_CMD} +mv linux-${GOARCH}/helm ${HELM_CMD} chmod +x "${HELM_CMD}" ${HELM_CMD} version --client -rm -fr linux-amd64 ${HELM_TAR_GZ_FILE} +rm -fr linux-${GOARCH} ${HELM_TAR_GZ_FILE} diff --git a/cli/config/compose/profiles/fleet/configurations/kibana.config.yml b/cli/config/compose/profiles/fleet/configurations/kibana.config.yml index aad1ec0a6a..7f109e559e 100644 --- a/cli/config/compose/profiles/fleet/configurations/kibana.config.yml +++ b/cli/config/compose/profiles/fleet/configurations/kibana.config.yml @@ -12,7 +12,7 @@ monitoring.ui.container.elasticsearch.enabled: true xpack.encryptedSavedObjects.encryptionKey: "12345678901234567890123456789012" xpack.fleet.enabled: true -xpack.fleet.registryUrl: http://package-registry:8080 +xpack.fleet.registryUrl: https://epr-staging.elastic.co xpack.fleet.agents.enabled: true xpack.fleet.agents.elasticsearch.host: http://elasticsearch:9200 xpack.fleet.agents.fleet_server.hosts: diff --git a/cli/config/compose/profiles/fleet/docker-compose.yml b/cli/config/compose/profiles/fleet/docker-compose.yml index 20e8a65d25..1dd40074dc 100644 --- a/cli/config/compose/profiles/fleet/docker-compose.yml +++ b/cli/config/compose/profiles/fleet/docker-compose.yml @@ -17,30 +17,23 @@ services: - ELASTIC_USERNAME=elastic - ELASTIC_PASSWORD=changeme image: "docker.elastic.co/elasticsearch/elasticsearch:${stackVersion:-8.0.0-SNAPSHOT}" + platform: ${stackPlatform:-linux/amd64} ports: - "9200:9200" kibana: depends_on: elasticsearch: condition: service_healthy - package-registry: - condition: service_healthy healthcheck: test: "curl -f http://localhost:5601/login | grep kbn-injected-metadata 2>&1 >/dev/null" retries: 600 interval: 1s image: "docker.elastic.co/${kibanaDockerNamespace:-kibana}/kibana:${kibanaVersion:-8.0.0-SNAPSHOT}" + platform: ${stackPlatform:-linux/amd64} ports: - "5601:5601" volumes: - ./configurations/kibana.config.yml:/usr/share/kibana/config/kibana.yml - package-registry: - image: docker.elastic.co/package-registry/distribution:staging - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8080"] - retries: 300 - interval: 1s - fleet-server: image: "docker.elastic.co/beats/elastic-agent:${stackVersion:-8.0.0-SNAPSHOT}" depends_on: diff --git a/cli/config/compose/profiles/metricbeat/docker-compose.yml b/cli/config/compose/profiles/metricbeat/docker-compose.yml index dcb02ffd92..a4ff128f0d 100644 --- a/cli/config/compose/profiles/metricbeat/docker-compose.yml +++ b/cli/config/compose/profiles/metricbeat/docker-compose.yml @@ -10,5 +10,6 @@ services: - ELASTIC_USERNAME=elastic - ELASTIC_PASSWORD=changeme image: "docker.elastic.co/elasticsearch/elasticsearch:${stackVersion:-8.0.0-SNAPSHOT}" + platform: ${stackPlatform:-linux/amd64} ports: - "9200:9200" diff --git a/cli/config/compose/services/elastic-agent/centos/docker-compose.yml b/cli/config/compose/services/elastic-agent/centos/docker-compose.yml index dbe229fc10..21bb17417c 100644 --- a/cli/config/compose/services/elastic-agent/centos/docker-compose.yml +++ b/cli/config/compose/services/elastic-agent/centos/docker-compose.yml @@ -1,7 +1,7 @@ version: '2.4' services: elastic-agent: - image: centos/systemd:${centos_systemdTag:-latest} + image: docker.elastic.co/observability-ci/centos-systemd:latest container_name: ${centos_systemdContainerName} entrypoint: "/usr/sbin/init" platform: ${stackPlatform:-linux/amd64} diff --git a/cli/config/compose/services/elastic-agent/cloud/docker-compose.yml b/cli/config/compose/services/elastic-agent/cloud/docker-compose.yml index e4613f7f0c..a1f62987ee 100644 --- a/cli/config/compose/services/elastic-agent/cloud/docker-compose.yml +++ b/cli/config/compose/services/elastic-agent/cloud/docker-compose.yml @@ -18,6 +18,7 @@ services: - "DATA_PATH=/apm-legacy/data/" - "LOGS_PATH=/apm-legacy/logs/" - "HOME_PATH=/apm-legacy/" + platform: ${stackPlatform:-linux/amd64} volumes: - "${apmVolume}:/apm-legacy" ports: diff --git a/cli/config/compose/services/elastic-agent/debian/docker-compose.yml b/cli/config/compose/services/elastic-agent/debian/docker-compose.yml index 2c39275ce1..0aff8b7b27 100644 --- a/cli/config/compose/services/elastic-agent/debian/docker-compose.yml +++ b/cli/config/compose/services/elastic-agent/debian/docker-compose.yml @@ -1,7 +1,7 @@ version: '2.4' services: elastic-agent: - image: alehaa/debian-systemd:${debian_systemdTag:-stretch} + image: docker.elastic.co/observability-ci/debian-systemd:latest container_name: ${debian_systemdContainerName} entrypoint: "/sbin/init" platform: ${stackPlatform:-linux/amd64} diff --git a/cli/config/compose/services/elastic-agent/docker-compose.yml b/cli/config/compose/services/elastic-agent/docker-compose.yml index 3d493cd0ab..59541349ad 100644 --- a/cli/config/compose/services/elastic-agent/docker-compose.yml +++ b/cli/config/compose/services/elastic-agent/docker-compose.yml @@ -11,6 +11,6 @@ services: environment: - "FLEET_SERVER_ENABLE=${fleetServerMode:-0}" - "FLEET_SERVER_INSECURE_HTTP=${fleetServerMode:-0}" - platform: ${elasticAgentPlatform:-linux/amd64} + platform: ${stackPlatform:-linux/amd64} ports: - "127.0.0.1:8220:8220" diff --git a/cli/config/compose/services/elasticsearch/docker-compose.yml b/cli/config/compose/services/elasticsearch/docker-compose.yml index d3dda9ed9f..3b5e9a9701 100644 --- a/cli/config/compose/services/elasticsearch/docker-compose.yml +++ b/cli/config/compose/services/elasticsearch/docker-compose.yml @@ -10,6 +10,7 @@ services: - ELASTIC_USERNAME=elastic - ELASTIC_PASSWORD=changeme image: "docker.elastic.co/observability-ci/elasticsearch:${elasticsearchTag}" + platform: ${elasticsearchPlatform:-linux/amd64} ports: - "9200:9200" - "9300:9300" diff --git a/cli/config/compose/services/fleet-server-centos/docker-compose.yml b/cli/config/compose/services/fleet-server-centos/docker-compose.yml index 942ad0be4b..d423ce19b9 100644 --- a/cli/config/compose/services/fleet-server-centos/docker-compose.yml +++ b/cli/config/compose/services/fleet-server-centos/docker-compose.yml @@ -1,9 +1,10 @@ version: '2.4' services: fleet-server-centos: - image: centos/systemd:${fleet_server_centosTag:-latest} + image: docker.elastic.co/observability-ci/centos-systemd:latest container_name: ${fleet_server_centosContainerName} entrypoint: "/usr/sbin/init" + platform: ${stackPlatform:-linux/amd64} privileged: true volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro diff --git a/cli/config/compose/services/fleet-server-debian/docker-compose.yml b/cli/config/compose/services/fleet-server-debian/docker-compose.yml index 8b2f3c3d09..694c7abe13 100644 --- a/cli/config/compose/services/fleet-server-debian/docker-compose.yml +++ b/cli/config/compose/services/fleet-server-debian/docker-compose.yml @@ -1,9 +1,10 @@ version: '2.4' services: fleet-server-debian: - image: alehaa/debian-systemd:${fleet_server_debianTag:-stretch} + image: docker.elastic.co/observability-ci/debian-systemd:latest container_name: ${fleet_server_debianContainerName} entrypoint: "/sbin/init" + platform: ${stackPlatform:-linux/amd64} privileged: true volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro diff --git a/cli/config/compose/services/metricbeat/docker-compose.yml b/cli/config/compose/services/metricbeat/docker-compose.yml index 2ae9b403ab..b05d9ee1cd 100644 --- a/cli/config/compose/services/metricbeat/docker-compose.yml +++ b/cli/config/compose/services/metricbeat/docker-compose.yml @@ -17,6 +17,6 @@ services: image: "docker.elastic.co/${metricbeatDockerNamespace:-beats}/metricbeat:${metricbeatTag:-8.0.0-SNAPSHOT}" labels: co.elastic.logs/module: "${serviceName}" - platform: ${metricbeatPlatform:-linux/amd64} + platform: ${stackPlatform:-linux/amd64} volumes: - "${metricbeatConfigFile}:/usr/share/metricbeat/metricbeat.yml" diff --git a/e2e/_suites/fleet/features/agent_endpoint_integration.feature b/e2e/_suites/fleet/features/agent_endpoint_integration.feature index 9dd1986863..57f55a5455 100644 --- a/e2e/_suites/fleet/features/agent_endpoint_integration.feature +++ b/e2e/_suites/fleet/features/agent_endpoint_integration.feature @@ -1,8 +1,8 @@ @agent_endpoint_integration +@skip:arm64 Feature: Agent Endpoint Integration Scenarios for Agent to deploy Endpoint and sending data to Fleet and Elasticsearch. -@deploy-endpoint-with-agent Scenario Outline: Adding the Endpoint Integration to an Agent makes the host to show in Security App Given a "" agent is deployed to Fleet with "tar" installer And the agent is listed in Fleet as "online" @@ -20,7 +20,6 @@ Examples: Debian | os | | debian | -@endpoint-policy-check Scenario Outline: Deploying an Endpoint makes policies to appear in the Security App When an "Endpoint" is successfully deployed with a "" Agent using "tar" installer Then the policy response will be shown in the Security App @@ -35,7 +34,6 @@ Examples: Debian | os | | debian | -@set-policy-and-check-changes Scenario Outline: Changing an Agent policy is reflected in the Security App Given an "Endpoint" is successfully deployed with a "" Agent using "tar" installer When the policy is updated to have "malware" in "detect" mode @@ -51,7 +49,6 @@ Examples: Debian | os | | debian | -@deploy-endpoint-then-unenroll-agent Scenario Outline: Un-enrolling Elastic Agent stops Elastic Endpoint Given an "Endpoint" is successfully deployed with a "" Agent using "tar" installer When the agent is un-enrolled @@ -68,7 +65,6 @@ Examples: Debian | os | | debian | -@deploy-endpoint-then-remove-it-from-policy Scenario Outline: Removing Endpoint from Agent policy stops the connected Endpoint Given an "Endpoint" is successfully deployed with a "" Agent using "tar" installer When the "Endpoint Security" integration is "removed" in the policy diff --git a/e2e/_suites/fleet/ingest_manager_test.go b/e2e/_suites/fleet/ingest_manager_test.go index 6a1a011029..09be9db570 100644 --- a/e2e/_suites/fleet/ingest_manager_test.go +++ b/e2e/_suites/fleet/ingest_manager_test.go @@ -66,8 +66,6 @@ func InitializeIngestManagerTestSuite(ctx *godog.TestSuiteContext) { ctx.BeforeSuite(func() { setUpSuite() - log.Trace("Bootstrapping Fleet Server") - if !shell.GetEnvBool("SKIP_PULL") { images := []string{ "docker.elastic.co/beats/elastic-agent:" + common.BeatVersion, diff --git a/e2e/_suites/fleet/stand-alone.go b/e2e/_suites/fleet/stand-alone.go index 8a44b69eb9..edc521c7bc 100644 --- a/e2e/_suites/fleet/stand-alone.go +++ b/e2e/_suites/fleet/stand-alone.go @@ -112,7 +112,9 @@ func (fts *FleetTestSuite) startStandAloneAgent(image string, flavour string, en agentService := deploy.NewServiceRequest(common.ElasticAgentServiceName) dockerInstaller, _ := installer.Attach(fts.deployer, agentService, "docker") dockerInstaller.Preinstall() - dockerImageTag += "-amd64" + + arch := utils.GetArchitecture() + dockerImageTag += "-" + arch } common.ProfileEnv["elasticAgentDockerImageSuffix"] = "" @@ -125,7 +127,6 @@ func (fts *FleetTestSuite) startStandAloneAgent(image string, flavour string, en containerName := fmt.Sprintf("%s_%s_%d", common.FleetProfileName, common.ElasticAgentServiceName, 1) common.ProfileEnv["elasticAgentContainerName"] = containerName - common.ProfileEnv["elasticAgentPlatform"] = "linux/amd64" common.ProfileEnv["elasticAgentTag"] = dockerImageTag for k, v := range env { diff --git a/e2e/_suites/metricbeat/metricbeat_test.go b/e2e/_suites/metricbeat/metricbeat_test.go index 3900248c11..418c8f3dc4 100644 --- a/e2e/_suites/metricbeat/metricbeat_test.go +++ b/e2e/_suites/metricbeat/metricbeat_test.go @@ -231,7 +231,8 @@ func InitializeMetricbeatTestSuite(ctx *godog.TestSuiteContext) { serviceManager := deploy.NewServiceManager() env := map[string]string{ - "stackVersion": common.StackVersion, + "stackPlatform": "linux/" + utils.GetArchitecture(), + "stackVersion": common.StackVersion, } err := serviceManager.RunCompose( @@ -371,7 +372,8 @@ func (mts *MetricbeatTestSuite) runMetricbeatService() error { useCISnapshots := shell.GetEnvBool("BEATS_USE_CI_SNAPSHOTS") beatsLocalPath := shell.GetEnv("BEATS_LOCAL_PATH", "") if useCISnapshots || beatsLocalPath != "" { - artifactName := utils.BuildArtifactName("metricbeat", mts.Version, common.BeatVersionBase, "linux", "amd64", "tar.gz", true) + arch := utils.GetArchitecture() + artifactName := utils.BuildArtifactName("metricbeat", mts.Version, common.BeatVersionBase, "linux", arch, "tar.gz", true) imagePath, err := utils.FetchBeatsBinary(artifactName, "metricbeat", mts.Version, common.BeatVersionBase, utils.TimeoutFactor, true) if err != nil { @@ -383,7 +385,7 @@ func (mts *MetricbeatTestSuite) runMetricbeatService() error { return err } - mts.Version = mts.Version + "-amd64" + mts.Version = mts.Version + "-" + arch err = deploy.TagImage( "docker.elastic.co/beats/metricbeat:"+common.BeatVersionBase, @@ -411,6 +413,8 @@ func (mts *MetricbeatTestSuite) runMetricbeatService() error { logLevel = log.DebugLevel.String() } + arch := utils.GetArchitecture() + env := map[string]string{ "BEAT_STRICT_PERMS": "false", "indexName": mts.getIndexName(), @@ -423,7 +427,7 @@ func (mts *MetricbeatTestSuite) runMetricbeatService() error { } env["metricbeatDockerNamespace"] = utils.GetDockerNamespaceEnvVar("beats") - env["metricbeatPlatform"] = "linux/amd64" + env["metricbeatPlatform"] = "linux/" + arch err := serviceManager.AddServicesToCompose( testSuite.currentContext, diff --git a/e2e/commons-test.mk b/e2e/commons-test.mk index 8b04a81bac..2423f5299d 100644 --- a/e2e/commons-test.mk +++ b/e2e/commons-test.mk @@ -48,6 +48,8 @@ TAGS_VALUE="~skip" endif endif +GOARCH?=amd64 + .PHONY: install install: go get -v -t ./... @@ -55,7 +57,7 @@ install: .PHONY: install-godog install-godog: export GO111MODULE := on install-godog: - go get -v github.com/cucumber/godog/cmd/godog@v0.11.0 + GOARCH=${GOARCH} go get -v github.com/cucumber/godog/cmd/godog@v0.11.0 .PHONY: functional-test functional-test: install-godog diff --git a/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-aarch64.rpm b/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-aarch64.rpm new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-arm64.deb b/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-arm64.deb new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz b/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-linux-arm64.tar.gz b/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-linux-arm64.tar.gz new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-linux-x86_64.tar.gz b/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-8.0.0-SNAPSHOT-linux-x86_64.tar.gz new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-ubi8-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz b/internal/_testresources/beats/x-pack/elastic-agent/build/distributions/elastic-agent-ubi8-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/deploy/docker.go b/internal/deploy/docker.go index 455fa81be0..80d2b243d5 100644 --- a/internal/deploy/docker.go +++ b/internal/deploy/docker.go @@ -36,6 +36,7 @@ func (c *dockerDeploymentManifest) Bootstrap(waitCB func() error) error { serviceManager := NewServiceManager() common.ProfileEnv = map[string]string{ "kibanaVersion": common.KibanaVersion, + "stackPlatform": "linux/" + utils.GetArchitecture(), "stackVersion": common.StackVersion, } diff --git a/internal/deploy/docker_client.go b/internal/deploy/docker_client.go index 8d0e14c589..7e3596decf 100644 --- a/internal/deploy/docker_client.go +++ b/internal/deploy/docker_client.go @@ -462,9 +462,18 @@ func PullImages(images []string) error { c := getDockerClient() ctx := context.Background() - log.WithField("images", images).Info("Pulling Docker images...") + platform := "linux/" + utils.GetArchitecture() + + log.WithFields(log.Fields{ + "images": images, + "platform": platform, + }).Info("Pulling Docker images...") + options := types.ImagePullOptions{ + Platform: platform, + } + for _, image := range images { - r, err := c.ImagePull(ctx, image, types.ImagePullOptions{}) + r, err := c.ImagePull(ctx, image, options) if err != nil { return err } diff --git a/internal/installer/base_test.go b/internal/installer/base_test.go index f1820715b3..4653f9c5d7 100644 --- a/internal/installer/base_test.go +++ b/internal/installer/base_test.go @@ -27,7 +27,7 @@ func TestDownloadAgentBinary(t *testing.T) { assert.NotNil(t, err) }) - t.Run("Fetching RPM binary from local Beats dir", func(t *testing.T) { + t.Run("Fetching RPM binary (amd64) from local Beats dir", func(t *testing.T) { defer os.Unsetenv("BEATS_LOCAL_PATH") os.Setenv("BEATS_LOCAL_PATH", beatsDir) @@ -38,8 +38,19 @@ func TestDownloadAgentBinary(t *testing.T) { assert.Nil(t, err) assert.Equal(t, downloadedFilePath, expectedFilePath) }) + t.Run("Fetching RPM binary (arm64) from local Beats dir", func(t *testing.T) { + defer os.Unsetenv("BEATS_LOCAL_PATH") + os.Setenv("BEATS_LOCAL_PATH", beatsDir) + + artifactName := "elastic-agent-8.0.0-SNAPSHOT-aarch64.rpm" + expectedFilePath := path.Join(distributionsDir, artifactName) + + downloadedFilePath, err := downloadAgentBinary(artifactName, artifact, version) + assert.Nil(t, err) + assert.Equal(t, downloadedFilePath, expectedFilePath) + }) - t.Run("Fetching DEB binary from local Beats dir", func(t *testing.T) { + t.Run("Fetching DEB binary (amd64) from local Beats dir", func(t *testing.T) { defer os.Unsetenv("BEATS_LOCAL_PATH") os.Setenv("BEATS_LOCAL_PATH", beatsDir) @@ -50,8 +61,19 @@ func TestDownloadAgentBinary(t *testing.T) { assert.Nil(t, err) assert.Equal(t, downloadedFilePath, expectedFilePath) }) + t.Run("Fetching DEB binary (arm64) from local Beats dir", func(t *testing.T) { + defer os.Unsetenv("BEATS_LOCAL_PATH") + os.Setenv("BEATS_LOCAL_PATH", beatsDir) - t.Run("Fetching TAR binary from local Beats dir", func(t *testing.T) { + artifactName := "elastic-agent-8.0.0-SNAPSHOT-arm64.deb" + expectedFilePath := path.Join(distributionsDir, artifactName) + + downloadedFilePath, err := downloadAgentBinary(artifactName, artifact, version) + assert.Nil(t, err) + assert.Equal(t, downloadedFilePath, expectedFilePath) + }) + + t.Run("Fetching TAR binary (amd64) from local Beats dir", func(t *testing.T) { defer os.Unsetenv("BEATS_LOCAL_PATH") os.Setenv("BEATS_LOCAL_PATH", beatsDir) @@ -62,8 +84,30 @@ func TestDownloadAgentBinary(t *testing.T) { assert.Nil(t, err) assert.Equal(t, downloadedFilePath, expectedFilePath) }) + t.Run("Fetching TAR binary (x86_64) from local Beats dir", func(t *testing.T) { + defer os.Unsetenv("BEATS_LOCAL_PATH") + os.Setenv("BEATS_LOCAL_PATH", beatsDir) + + artifactName := "elastic-agent-8.0.0-SNAPSHOT-linux-x86_64.tar.gz" + expectedFilePath := path.Join(distributionsDir, artifactName) + + downloadedFilePath, err := downloadAgentBinary(artifactName, artifact, version) + assert.Nil(t, err) + assert.Equal(t, downloadedFilePath, expectedFilePath) + }) + t.Run("Fetching TAR binary (arm64) from local Beats dir", func(t *testing.T) { + defer os.Unsetenv("BEATS_LOCAL_PATH") + os.Setenv("BEATS_LOCAL_PATH", beatsDir) + + artifactName := "elastic-agent-8.0.0-SNAPSHOT-linux-arm64.tar.gz" + expectedFilePath := path.Join(distributionsDir, artifactName) + + downloadedFilePath, err := downloadAgentBinary(artifactName, artifact, version) + assert.Nil(t, err) + assert.Equal(t, downloadedFilePath, expectedFilePath) + }) - t.Run("Fetching Docker binary from local Beats dir", func(t *testing.T) { + t.Run("Fetching Docker binary (amd64) from local Beats dir", func(t *testing.T) { defer os.Unsetenv("BEATS_LOCAL_PATH") os.Setenv("BEATS_LOCAL_PATH", beatsDir) @@ -74,14 +118,36 @@ func TestDownloadAgentBinary(t *testing.T) { assert.Nil(t, err) assert.Equal(t, downloadedFilePath, expectedFilePath) }) + t.Run("Fetching Docker binary (arm64) from local Beats dir", func(t *testing.T) { + defer os.Unsetenv("BEATS_LOCAL_PATH") + os.Setenv("BEATS_LOCAL_PATH", beatsDir) - t.Run("Fetching ubi8 Docker binary from local Beats dir", func(t *testing.T) { + artifactName := "elastic-agent-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz" + expectedFilePath := path.Join(distributionsDir, artifactName) + + downloadedFilePath, err := downloadAgentBinary(artifactName, artifact, version) + assert.Nil(t, err) + assert.Equal(t, downloadedFilePath, expectedFilePath) + }) + + t.Run("Fetching ubi8 Docker binary (amd64) from local Beats dir", func(t *testing.T) { defer os.Unsetenv("BEATS_LOCAL_PATH") os.Setenv("BEATS_LOCAL_PATH", beatsDir) artifactName := "elastic-agent-ubi8-8.0.0-SNAPSHOT-linux-amd64.docker.tar.gz" expectedFilePath := path.Join(distributionsDir, artifactName) + downloadedFilePath, err := downloadAgentBinary(artifactName, artifact, version) + assert.Nil(t, err) + assert.Equal(t, downloadedFilePath, expectedFilePath) + }) + t.Run("Fetching ubi8 Docker binary (arm64) from local Beats dir", func(t *testing.T) { + defer os.Unsetenv("BEATS_LOCAL_PATH") + os.Setenv("BEATS_LOCAL_PATH", beatsDir) + + artifactName := "elastic-agent-ubi8-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz" + expectedFilePath := path.Join(distributionsDir, artifactName) + downloadedFilePath, err := downloadAgentBinary(artifactName, artifact, version) assert.Nil(t, err) assert.Equal(t, downloadedFilePath, expectedFilePath) diff --git a/internal/installer/elasticagent_deb.go b/internal/installer/elasticagent_deb.go index 165daf8586..fa13847286 100644 --- a/internal/installer/elasticagent_deb.go +++ b/internal/installer/elasticagent_deb.go @@ -103,7 +103,7 @@ func (i *elasticAgentDEBPackage) Postinstall() error { func (i *elasticAgentDEBPackage) Preinstall() error { artifact := "elastic-agent" os := "linux" - arch := "amd64" + arch := utils.GetArchitecture() extension := "deb" binaryName := utils.BuildArtifactName(artifact, common.BeatVersion, common.BeatVersionBase, os, arch, extension, false) diff --git a/internal/installer/elasticagent_docker.go b/internal/installer/elasticagent_docker.go index b08626b1a1..a0cd13db50 100644 --- a/internal/installer/elasticagent_docker.go +++ b/internal/installer/elasticagent_docker.go @@ -75,7 +75,7 @@ func (i *elasticAgentDockerPackage) Postinstall() error { func (i *elasticAgentDockerPackage) Preinstall() error { artifact := "elastic-agent" os := "linux" - arch := "x86_64" + arch := utils.GetArchitecture() extension := "tar.gz" binaryName := utils.BuildArtifactName(artifact, common.BeatVersion, common.BeatVersionBase, os, arch, extension, false) @@ -100,7 +100,7 @@ func (i *elasticAgentDockerPackage) Preinstall() error { // we need to tag the loaded image because its tag relates to the target branch return deploy.TagImage( fmt.Sprintf("docker.elastic.co/beats/%s:%s", artifact, common.BeatVersionBase), - fmt.Sprintf("docker.elastic.co/observability-ci/%s:%s-amd64", artifact, common.BeatVersion), + fmt.Sprintf("docker.elastic.co/observability-ci/%s:%s-%s", artifact, common.BeatVersion, arch), ) } diff --git a/internal/installer/elasticagent_rpm.go b/internal/installer/elasticagent_rpm.go index 1e450bfbc2..0317cacb99 100644 --- a/internal/installer/elasticagent_rpm.go +++ b/internal/installer/elasticagent_rpm.go @@ -105,6 +105,9 @@ func (i *elasticAgentRPMPackage) Preinstall() error { artifact := "elastic-agent" os := "linux" arch := "x86_64" + if utils.GetArchitecture() == "arm64" { + arch = "aarch64" + } extension := "rpm" binaryName := utils.BuildArtifactName(artifact, common.BeatVersion, common.BeatVersionBase, os, arch, extension, false) diff --git a/internal/installer/elasticagent_tar.go b/internal/installer/elasticagent_tar.go index 87234bb255..55558a27a1 100644 --- a/internal/installer/elasticagent_tar.go +++ b/internal/installer/elasticagent_tar.go @@ -89,6 +89,9 @@ func (i *elasticAgentTARPackage) Preinstall() error { artifact := "elastic-agent" os := "linux" arch := "x86_64" + if utils.GetArchitecture() == "arm64" { + arch = "arm64" + } extension := "tar.gz" binaryName := utils.BuildArtifactName(artifact, common.BeatVersion, common.BeatVersionBase, os, arch, extension, false) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index ce942d2ac7..378287112f 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -64,8 +64,8 @@ func BuildArtifactName(artifact string, version string, fallbackVersion string, useCISnapshots := shell.GetEnvBool("BEATS_USE_CI_SNAPSHOTS") // we detected that the docker name on CI is using a different structure - // CI snapshots on GCP: elastic-agent-$VERSION-linux-amd64.docker.tar.gz - // Elastic's snapshots: elastic-agent-$VERSION-docker-image-linux-amd64.tar.gz + // CI snapshots on GCP: elastic-agent-$VERSION-linux-$ARCH.docker.tar.gz + // Elastic's snapshots: elastic-agent-$VERSION-docker-image-linux-$ARCH.tar.gz if !useCISnapshots && isDocker { dockerString = "docker-image" artifactName = fmt.Sprintf("%s-%s-%s-%s-%s.%s", artifact, artifactVersion, dockerString, OS, arch, lowerCaseExtension) @@ -165,6 +165,19 @@ func FetchBeatsBinary(artifactName string, artifact string, version string, fall return handleDownload(downloadURL) } +// GetArchitecture retrieves if the underlying system platform is arm64 or amd64 +func GetArchitecture() string { + arch := "amd64" + + envArch := os.Getenv("GOARCH") + if envArch == "arm64" { + arch = "arm64" + } + + log.Debugf("Golang's architecture is %s (%s)", arch, envArch) + return arch +} + // getGCPBucketCoordinates it calculates the bucket path in GCP func getGCPBucketCoordinates(fileName string, artifact string, version string, fallbackVersion string) (string, string, string) { bucket := "beats-ci-artifacts" @@ -268,9 +281,9 @@ func GetElasticArtifactVersion(version string) (string, error) { // GetElasticArtifactURL returns the URL of a released artifact, which its full name is defined in the first argument, // from Elastic's artifact repository, building the JSON path query based on the full name -// i.e. GetElasticArtifactURL("elastic-agent-$VERSION-amd64.deb", "elastic-agent", "$VERSION") +// i.e. GetElasticArtifactURL("elastic-agent-$VERSION-$ARCH.deb", "elastic-agent", "$VERSION") // i.e. GetElasticArtifactURL("elastic-agent-$VERSION-x86_64.rpm", "elastic-agent","$VERSION") -// i.e. GetElasticArtifactURL("elastic-agent-$VERSION-linux-amd64.tar.gz", "elastic-agent","$VERSION") +// i.e. GetElasticArtifactURL("elastic-agent-$VERSION-linux-$ARCH.tar.gz", "elastic-agent","$VERSION") func GetElasticArtifactURL(artifactName string, artifact string, version string) (string, error) { exp := GetExponentialBackOff(time.Minute) @@ -325,6 +338,14 @@ func GetElasticArtifactURL(artifactName string, artifact string, version string) return "", err } + log.WithFields(log.Fields{ + "retries": retryCount, + "artifact": artifact, + "artifactName": artifactName, + "elapsedTime": exp.GetElapsedTime(), + "version": version, + }).Trace("Artifact found") + packagesObject := jsonParsed.Path("packages") // we need to get keys with dots using Search instead of Path downloadObject := packagesObject.Search(artifactName) diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index 2df96cd062..0580e0e9c8 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -48,7 +48,7 @@ func TestBuildArtifactName(t *testing.T) { OS := "linux" version := "8.0.0-SNAPSHOT" - t.Run("For RPM", func(t *testing.T) { + t.Run("For RPM (amd64)", func(t *testing.T) { arch := "x86_64" extension := "rpm" expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-x86_64.rpm" @@ -59,8 +59,19 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "RPM", false) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For RPM (arm64)", func(t *testing.T) { + arch := "aarch64" + extension := "rpm" + expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-aarch64.rpm" + + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, false) + assert.Equal(t, expectedFileName, artifactName) + + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "RPM", false) + assert.Equal(t, expectedFileName, artifactName) + }) - t.Run("For DEB", func(t *testing.T) { + t.Run("For DEB (amd64)", func(t *testing.T) { arch := "amd64" extension := "deb" expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-amd64.deb" @@ -71,11 +82,22 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "DEB", false) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For DEB (arm64)", func(t *testing.T) { + arch := "arm64" + extension := "deb" + expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-arm64.deb" - t.Run("For TAR", func(t *testing.T) { - arch := "amd64" + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, false) + assert.Equal(t, expectedFileName, artifactName) + + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "DEB", false) + assert.Equal(t, expectedFileName, artifactName) + }) + + t.Run("For TAR (amd64)", func(t *testing.T) { + arch := "x86_64" extension := "tar.gz" - expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-linux-amd64.tar.gz" + expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-linux-x86_64.tar.gz" artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, false) assert.Equal(t, expectedFileName, artifactName) @@ -83,8 +105,19 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", false) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For TAR (arm64)", func(t *testing.T) { + arch := "arm64" + extension := "tar.gz" + expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-linux-arm64.tar.gz" + + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, false) + assert.Equal(t, expectedFileName, artifactName) - t.Run("For Docker from Elastic's repository", func(t *testing.T) { + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", false) + assert.Equal(t, expectedFileName, artifactName) + }) + + t.Run("For Docker from Elastic's repository (amd64)", func(t *testing.T) { defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS") os.Setenv("BEATS_USE_CI_SNAPSHOTS", "false") @@ -99,8 +132,23 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For Docker from Elastic's repository (arm64)", func(t *testing.T) { + defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS") + os.Setenv("BEATS_USE_CI_SNAPSHOTS", "false") + + artifact = "elastic-agent" + arch := "arm64" + extension := "tar.gz" + expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-docker-image-linux-arm64.tar.gz" - t.Run("For Docker UBI8 from Elastic's repository", func(t *testing.T) { + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, true) + assert.Equal(t, expectedFileName, artifactName) + + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) + assert.Equal(t, expectedFileName, artifactName) + }) + + t.Run("For Docker UBI8 from Elastic's repository (amd64)", func(t *testing.T) { defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS") os.Setenv("BEATS_USE_CI_SNAPSHOTS", "false") @@ -115,8 +163,23 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For Docker UBI8 from Elastic's repository (arm64)", func(t *testing.T) { + defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS") + os.Setenv("BEATS_USE_CI_SNAPSHOTS", "false") + + artifact = "elastic-agent-ubi8" + arch := "arm64" + extension := "tar.gz" + expectedFileName := "elastic-agent-ubi8-8.0.0-SNAPSHOT-docker-image-linux-arm64.tar.gz" + + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, true) + assert.Equal(t, expectedFileName, artifactName) + + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) + assert.Equal(t, expectedFileName, artifactName) + }) - t.Run("For Docker from local repository", func(t *testing.T) { + t.Run("For Docker from local repository (amd64)", func(t *testing.T) { defer os.Unsetenv("BEATS_LOCAL_PATH") os.Setenv("BEATS_LOCAL_PATH", "/tmp") @@ -131,8 +194,23 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For Docker from local repository (arm64)", func(t *testing.T) { + defer os.Unsetenv("BEATS_LOCAL_PATH") + os.Setenv("BEATS_LOCAL_PATH", "/tmp") - t.Run("For Docker UBI8 from local repository", func(t *testing.T) { + artifact = "elastic-agent" + arch := "arm64" + extension := "tar.gz" + expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz" + + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, true) + assert.Equal(t, expectedFileName, artifactName) + + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) + assert.Equal(t, expectedFileName, artifactName) + }) + + t.Run("For Docker UBI8 from local repository (amd64)", func(t *testing.T) { defer os.Unsetenv("BEATS_LOCAL_PATH") os.Setenv("BEATS_LOCAL_PATH", "/tmp") @@ -147,8 +225,23 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For Docker UBI8 from local repository (arm64)", func(t *testing.T) { + defer os.Unsetenv("BEATS_LOCAL_PATH") + os.Setenv("BEATS_LOCAL_PATH", "/tmp") + + artifact = "elastic-agent-ubi8" + arch := "arm64" + extension := "tar.gz" + expectedFileName := "elastic-agent-ubi8-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz" - t.Run("For Docker from GCP", func(t *testing.T) { + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, true) + assert.Equal(t, expectedFileName, artifactName) + + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) + assert.Equal(t, expectedFileName, artifactName) + }) + + t.Run("For Docker from GCP (amd64)", func(t *testing.T) { defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS") os.Setenv("BEATS_USE_CI_SNAPSHOTS", "true") @@ -163,8 +256,23 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For Docker from GCP (arm64)", func(t *testing.T) { + defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS") + os.Setenv("BEATS_USE_CI_SNAPSHOTS", "true") + + artifact = "elastic-agent" + arch := "arm64" + extension := "tar.gz" + expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz" + + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, true) + assert.Equal(t, expectedFileName, artifactName) + + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) + assert.Equal(t, expectedFileName, artifactName) + }) - t.Run("For Docker UBI8 from GCP", func(t *testing.T) { + t.Run("For Docker UBI8 from GCP (amd64)", func(t *testing.T) { defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS") os.Setenv("BEATS_USE_CI_SNAPSHOTS", "true") @@ -179,8 +287,23 @@ func TestBuildArtifactName(t *testing.T) { artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) assert.Equal(t, expectedFileName, artifactName) }) + t.Run("For Docker UBI8 from GCP (arm64)", func(t *testing.T) { + defer os.Unsetenv("BEATS_USE_CI_SNAPSHOTS") + os.Setenv("BEATS_USE_CI_SNAPSHOTS", "true") + + artifact = "elastic-agent-ubi8" + arch := "arm64" + extension := "tar.gz" + expectedFileName := "elastic-agent-ubi8-8.0.0-SNAPSHOT-linux-arm64.docker.tar.gz" + + artifactName := BuildArtifactName(artifact, version, version, OS, arch, extension, true) + assert.Equal(t, expectedFileName, artifactName) + + artifactName = BuildArtifactName(artifact, version, version, OS, arch, "TAR.GZ", true) + assert.Equal(t, expectedFileName, artifactName) + }) - t.Run("For Docker for a Pull Request", func(t *testing.T) { + t.Run("For Docker for a Pull Request (amd64)", func(t *testing.T) { defer os.Unsetenv("GITHUB_CHECK_SHA1") os.Setenv("GITHUB_CHECK_SHA1", "0123456789") @@ -193,6 +316,22 @@ func TestBuildArtifactName(t *testing.T) { artifactName := BuildArtifactName(artifact, version, fallbackVersion, OS, arch, extension, true) assert.Equal(t, expectedFileName, artifactName) + artifactName = BuildArtifactName(artifact, version, fallbackVersion, OS, arch, "TAR.GZ", true) + assert.Equal(t, expectedFileName, artifactName) + }) + t.Run("For Docker for a Pull Request (arm64)", func(t *testing.T) { + defer os.Unsetenv("GITHUB_CHECK_SHA1") + os.Setenv("GITHUB_CHECK_SHA1", "0123456789") + + artifact = "elastic-agent" + arch := "arm64" + extension := "tar.gz" + fallbackVersion := "8.0.0-SNAPSHOT" + expectedFileName := "elastic-agent-8.0.0-SNAPSHOT-docker-image-linux-arm64.tar.gz" + + artifactName := BuildArtifactName(artifact, version, fallbackVersion, OS, arch, extension, true) + assert.Equal(t, expectedFileName, artifactName) + artifactName = BuildArtifactName(artifact, version, fallbackVersion, OS, arch, "TAR.GZ", true) assert.Equal(t, expectedFileName, artifactName) }) @@ -223,6 +362,32 @@ func TestDownloadFile(t *testing.T) { assert.True(t, strings.HasSuffix(f, "robots.txt")) } +func TestGetArchitecture(t *testing.T) { + t.Run("Retrieving amd architecture", func(t *testing.T) { + fallbackArch := os.Getenv("GOARCH") + os.Setenv("GOARCH", "amd64") + defer os.Setenv("GOARCH", fallbackArch) + + assert.Equal(t, "amd64", GetArchitecture()) + }) + + t.Run("Retrieving amd architecture as fallback", func(t *testing.T) { + fallbackArch := os.Getenv("GOARCH") + os.Setenv("GOARCH", "arch-not-found") + defer os.Setenv("GOARCH", fallbackArch) + + assert.Equal(t, "amd64", GetArchitecture()) + }) + + t.Run("Retrieving arm architecture", func(t *testing.T) { + fallbackArch := os.Getenv("GOARCH") + os.Setenv("GOARCH", "arm64") + defer os.Setenv("GOARCH", fallbackArch) + + assert.Equal(t, "arm64", GetArchitecture()) + }) +} + func TestGetBucketSearchNextPageParam_HasMorePages(t *testing.T) { expectedParam := "&pageToken=foo"