diff --git a/.github/actionlint.yml b/.github/actionlint.yml index 9e95094b4..0e0a4c33d 100644 --- a/.github/actionlint.yml +++ b/.github/actionlint.yml @@ -8,3 +8,5 @@ self-hosted-runner: - windows-2019-16core - custom-linux-xxl-nomad-20.04 - custom-linux-xl-nomad-22.04 + - custom-ubuntu-22.04-xl + - custom-ubuntu-22.04-arm64-xl diff --git a/.github/workflows/test-core.yaml b/.github/workflows/test-core.yaml index e79456a78..a7a14e230 100644 --- a/.github/workflows/test-core.yaml +++ b/.github/workflows/test-core.yaml @@ -104,7 +104,6 @@ jobs: sudo -E env "PATH=$PATH" make test-nomad-module tests-groups: needs: [checks] - runs-on: custom-linux-xl-nomad-22.04 timeout-minutes: 30 strategy: fail-fast: false @@ -115,6 +114,11 @@ jobs: - command - drivers - quick + runners: + - custom-ubuntu-22.04-xl + - custom-ubuntu-22.04-arm64-xl + runs-on: ${{matrix.runners}} + name: tests-groups (${{matrix.groups}}, ${{ contains(matrix.runners, '-arm64') && ' linux_arm64 )' || ' linux_amd64 )' }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 @@ -122,9 +126,12 @@ jobs: cache: ${{ contains(runner.name, 'Github Actions') }} go-version-file: .go-version cache-dependency-path: '**/go.sum' - - name: Install optional dependencies + - name: Install "driver" group dependencies if: ${{ matrix.groups == 'drivers' }} run: sudo apt update && sudo apt install qemu-system + - name: Install "command" group dependencies + if: ${{ matrix.groups == 'command' }} + run: sudo apt update && sudo apt install xdg-utils - name: Run Matrix Tests env: GOTEST_GROUP: ${{matrix.groups}} diff --git a/client/fingerprint/cpu_default_test.go b/client/fingerprint/cpu_default_test.go index c756305e9..258dba157 100644 --- a/client/fingerprint/cpu_default_test.go +++ b/client/fingerprint/cpu_default_test.go @@ -1,11 +1,12 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: BUSL-1.1 -//go:build !darwin || !arm64 || !cgo +//go:build !darwin package fingerprint import ( + "runtime" "strconv" "testing" @@ -38,12 +39,17 @@ func TestCPUFingerprint_Classic(t *testing.T) { attributes := response.Attributes must.NotNil(t, attributes) must.MapContainsKey(t, attributes, "cpu.numcores") - must.MapContainsKey(t, attributes, "cpu.modelname") must.MapContainsKey(t, attributes, "cpu.totalcompute") must.Positive(t, response.NodeResources.Processors.Topology.UsableCompute()) must.Positive(t, response.NodeResources.Processors.Topology.NumCores()) must.NotEmpty(t, response.NodeResources.Processors.Topology.UsableCores()) + // The library we use does not populate arm64 CPU model names and I don't + // believe this is easily possible anyway. + if runtime.GOARCH == "amd64" { + must.MapContainsKey(t, attributes, "cpu.modelname") + } + _, frequencyPresent := attributes["cpu.frequency"] _, performancePresent := attributes["cpu.frequency.performance"] _, efficiencyPresent := attributes["cpu.frequency.efficiency"] diff --git a/drivers/docker/driver_test.go b/drivers/docker/driver_test.go index 2ac114766..a04f8870d 100644 --- a/drivers/docker/driver_test.go +++ b/drivers/docker/driver_test.go @@ -160,7 +160,7 @@ func dockerSetup(t *testing.T, task *drivers.TaskConfig, driverCfg map[string]in driver := dockerDriverHarness(t, driverCfg) cleanup := driver.MkAllocDir(task, loggingIsEnabled(&DriverConfig{}, task)) - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), fmt.Sprintf("busybox_linux_%s.tar", runtime.GOARCH)) _, _, err := driver.StartTask(task) must.NoError(t, err) @@ -270,7 +270,7 @@ func TestDockerDriver_Start_Wait(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -304,7 +304,7 @@ func TestDockerDriver_Start_WaitFinish(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -345,7 +345,7 @@ func TestDockerDriver_Start_StoppedContainer(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) client := newTestDockerClient(t) @@ -410,7 +410,7 @@ func TestDockerDriver_ContainerAlreadyExists(t *testing.T) { driver := dockerDriverHarness(t, nil) cleanup := driver.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) d, ok := driver.Impl().(*Driver) must.True(t, ok) @@ -460,7 +460,7 @@ func TestDockerDriver_Start_LoadImage(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -585,7 +585,7 @@ func TestDockerDriver_Start_Wait_AllocDir(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -633,7 +633,7 @@ func TestDockerDriver_Start_Kill_Wait(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -684,7 +684,7 @@ func TestDockerDriver_Start_KillTimeout(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -720,7 +720,7 @@ func TestDockerDriver_StartN(t *testing.T) { } testutil.DockerCompatible(t) - task1, _, _ := dockerTask(t) + task1, taskCfg, _ := dockerTask(t) task2, _, _ := dockerTask(t) task3, _, _ := dockerTask(t) @@ -733,7 +733,7 @@ func TestDockerDriver_StartN(t *testing.T) { for _, task := range taskList { cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -763,8 +763,8 @@ func TestDockerDriver_StartN(t *testing.T) { func TestDockerDriver_StartNVersions(t *testing.T) { ci.Parallel(t) - if runtime.GOOS == "windows" { - t.Skip("Skipped on windows, we don't have image variants available") + if runtime.GOOS == "windows" || runtime.GOARCH == "arm64" { + t.Skip("Skipped on windows or arm64, we don't have image variants available") } testutil.DockerCompatible(t) @@ -798,7 +798,7 @@ func TestDockerDriver_StartNVersions(t *testing.T) { for _, task := range taskList { cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), "busybox_linux_amd64.tar") copyImage(t, task.TaskDir(), "busybox_musl.tar") copyImage(t, task.TaskDir(), "busybox_glibc.tar") _, _, err := d.StartTask(task) @@ -997,7 +997,6 @@ func TestDockerDriver_ForcePull_RepoDigest(t *testing.T) { cfg.LoadImage = "" cfg.Image = "library/busybox@sha256:58ac43b2cc92c687a32c8be6278e50a063579655fe3090125dcb2af0ff9e1a64" - localDigest := "sha256:8ac48589692a53a9b8c2d1ceaa6b402665aa7fe667ba51ccc03002300856d8c7" cfg.ForcePull = true cfg.Command = busyboxLongRunningCmd[0] cfg.Args = busyboxLongRunningCmd[1:] @@ -1009,7 +1008,15 @@ func TestDockerDriver_ForcePull_RepoDigest(t *testing.T) { container, err := client.ContainerInspect(context.Background(), handle.containerID) must.NoError(t, err) - must.Eq(t, localDigest, container.Image) + + switch runtime.GOARCH { + case "amd64": + must.Eq(t, "sha256:8ac48589692a53a9b8c2d1ceaa6b402665aa7fe667ba51ccc03002300856d8c7", container.Image) + case "arm64": + must.Eq(t, "sha256:ba3a78826904c625e65a2eed1f247bbab59898f043490e7113e88907bf7c6b3b", container.Image) + default: + t.Fatalf("unsupported test architecture: %s", runtime.GOARCH) + } } func TestDockerDriver_SecurityOptUnconfined(t *testing.T) { @@ -1599,7 +1606,7 @@ func TestDockerDriver_Capabilities(t *testing.T) { cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) _, _, err := d.StartTask(task) defer d.DestroyTask(task.ID, true) @@ -2029,7 +2036,7 @@ func TestDockerDriver_EnableImageGC(t *testing.T) { cleanSlate(client, cfg.Image) - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) _, _, err := driver.StartTask(task) must.NoError(t, err) @@ -2097,7 +2104,7 @@ func TestDockerDriver_DisableImageGC(t *testing.T) { cleanSlate(client, cfg.Image) - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) _, _, err := driver.StartTask(task) must.NoError(t, err) @@ -2162,7 +2169,7 @@ func TestDockerDriver_MissingContainer_Cleanup(t *testing.T) { cleanSlate(client, cfg.Image) - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) _, _, err := driver.StartTask(task) must.NoError(t, err) @@ -2282,7 +2289,7 @@ func setupDockerVolumes(t *testing.T, cfg map[string]interface{}, hostpath strin d := dockerDriverHarness(t, cfg) cleanup := d.MkAllocDir(task, true) - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) return task, d, &taskCfg, hostfile, cleanup } @@ -2449,7 +2456,7 @@ func TestDockerDriver_Mounts(t *testing.T) { cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) _, _, err := d.StartTask(task) defer d.DestroyTask(task.ID, true) @@ -2593,7 +2600,7 @@ func TestDockerDriver_OOMKilled(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -2647,7 +2654,7 @@ func TestDockerDriver_Devices_IsInvalidConfig(t *testing.T) { must.NoError(t, task.EncodeConcreteDriverConfig(cfg)) d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) defer cleanup() _, _, err := d.StartTask(task) @@ -2823,7 +2830,7 @@ func TestDockerDriver_AdvertiseIPv6Address(t *testing.T) { driver := dockerDriverHarness(t, nil) cleanup := driver.MkAllocDir(task, true) - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) defer cleanup() _, network, err := driver.StartTask(task) @@ -2902,7 +2909,7 @@ func TestDockerDriver_CreationIdempotent(t *testing.T) { cleanup := driver.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), cfg.LoadImage) d, ok := driver.Impl().(*Driver) must.True(t, ok) @@ -3085,8 +3092,8 @@ func TestDockerDriver_parseSignal(t *testing.T) { func TestDockerDriver_StopSignal(t *testing.T) { ci.Parallel(t) testutil.DockerCompatible(t) - if runtime.GOOS == "windows" { - t.Skip("Skipped on windows, we don't have image variants available") + if runtime.GOOS == "windows" || runtime.GOARCH == "arm64" { + t.Skip("Skipped on windows or arm64, we don't have image variants available") } cases := []struct { @@ -3141,7 +3148,7 @@ func TestDockerDriver_StopSignal(t *testing.T) { if c.variant == "stopsignal" { copyImage(t, task.TaskDir(), "busybox_stopsignal.tar") // Default busybox image with STOPSIGNAL 19 added } else { - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) } client := newTestDockerClient(t) @@ -3232,7 +3239,7 @@ func TestDockerDriver_CollectStats(t *testing.T) { cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), taskCfg.LoadImage) _, _, err := d.StartTask(task) must.NoError(t, err) diff --git a/drivers/docker/driver_unix_test.go b/drivers/docker/driver_unix_test.go index 751d36a92..2d98c9d5b 100644 --- a/drivers/docker/driver_unix_test.go +++ b/drivers/docker/driver_unix_test.go @@ -46,7 +46,7 @@ func TestDockerDriver_User(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), fmt.Sprintf("busybox_linux_%s.tar", runtime.GOARCH)) _, _, err := d.StartTask(task) if err == nil { @@ -91,7 +91,7 @@ func TestDockerDriver_NetworkAliases_Bridge(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), fmt.Sprintf("busybox_linux_%s.tar", runtime.GOARCH)) _, _, err = d.StartTask(task) must.NoError(t, err) @@ -127,7 +127,7 @@ func TestDockerDriver_NetworkMode_Host(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), fmt.Sprintf("busybox_linux_%s.tar", runtime.GOARCH)) _, _, err := d.StartTask(task) must.NoError(t, err) @@ -258,7 +258,7 @@ func TestDockerDriver_Sysctl_Ulimit_Errors(t *testing.T) { d := dockerDriverHarness(t, nil) cleanup := d.MkAllocDir(task, true) t.Cleanup(cleanup) - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), fmt.Sprintf("busybox_linux_%s.tar", runtime.GOARCH)) _, _, err := d.StartTask(task) must.ErrorContains(t, err, tc.err.Error()) @@ -743,11 +743,20 @@ func TestDockerDriver_Start_Image_HTTPS(t *testing.T) { } func newTaskConfig(variant string, command []string) TaskConfig { - // busyboxImageID is the ID stored in busybox.tar - busyboxImageID := "busybox:1.29.3" + + var busyboxImageID, loadImage string + + switch runtime.GOARCH { + case "arm64": + busyboxImageID = "busybox:1.37.0" + loadImage = "busybox_linux_arm64.tar" + default: + busyboxImageID = "busybox:1.29.3" + loadImage = "busybox_linux_amd64.tar" + } image := busyboxImageID - loadImage := "busybox.tar" + if variant != "" { image = fmt.Sprintf("%s-%s", busyboxImageID, variant) loadImage = fmt.Sprintf("busybox_%s.tar", variant) @@ -807,7 +816,7 @@ func TestDocker_ExecTaskStreaming(t *testing.T) { harness := dockerDriverHarness(t, nil) cleanup := harness.MkAllocDir(task, true) defer cleanup() - copyImage(t, task.TaskDir(), "busybox.tar") + copyImage(t, task.TaskDir(), fmt.Sprintf("busybox_linux_%s.tar", runtime.GOARCH)) _, _, err := harness.StartTask(task) must.NoError(t, err) diff --git a/drivers/docker/test-resources/docker/busybox.tar b/drivers/docker/test-resources/docker/busybox_linux_amd64.tar similarity index 100% rename from drivers/docker/test-resources/docker/busybox.tar rename to drivers/docker/test-resources/docker/busybox_linux_amd64.tar diff --git a/drivers/docker/test-resources/docker/busybox_linux_arm64.tar b/drivers/docker/test-resources/docker/busybox_linux_arm64.tar new file mode 100644 index 000000000..c88f4215d Binary files /dev/null and b/drivers/docker/test-resources/docker/busybox_linux_arm64.tar differ diff --git a/drivers/shared/executor/executor_linux_test.go b/drivers/shared/executor/executor_linux_test.go index 4899894c8..aabbd4a86 100644 --- a/drivers/shared/executor/executor_linux_test.go +++ b/drivers/shared/executor/executor_linux_test.go @@ -10,6 +10,7 @@ import ( "os/exec" "path/filepath" "regexp" + "runtime" "strconv" "strings" "syscall" @@ -37,7 +38,11 @@ import ( ) func init() { - executorFactories["LibcontainerExecutor"] = libcontainerFactory + // There are no busybox arm64 images to download. These tests will need to + // be reworked, or a custom build performed. + if runtime.GOARCH == "amd64" { + executorFactories["LibcontainerExecutor"] = libcontainerFactory + } } var libcontainerFactory = executorFactory{