diff --git a/.github/workflows/arc-publish-chart.yaml b/.github/workflows/arc-publish-chart.yaml index 5cada00e..dd47350c 100644 --- a/.github/workflows/arc-publish-chart.yaml +++ b/.github/workflows/arc-publish-chart.yaml @@ -45,8 +45,7 @@ jobs: fetch-depth: 0 - name: Set up Helm - # Using https://github.com/Azure/setup-helm/releases/tag/v4.2.0 - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 + uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 with: version: ${{ env.HELM_VERSION }} @@ -64,7 +63,6 @@ jobs: python-version: "3.11" - name: Set up chart-testing - # https://github.com/helm/chart-testing-action/releases/tag/v2.7.0 uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b - name: Run chart-testing (list-changed) @@ -81,7 +79,6 @@ jobs: - name: Create kind cluster if: steps.list-changed.outputs.changed == 'true' - # https://github.com/helm/kind-action/releases/tag/v1.12.0 uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # We need cert-manager already installed in the cluster because we assume the CRDs exist @@ -148,8 +145,7 @@ jobs: - name: Get Token id: get_workflow_token - # https://github.com/peter-murray/workflow-application-token-action/releases/tag/v3.0.0 - uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343 with: application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }} application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }} diff --git a/.github/workflows/arc-publish.yaml b/.github/workflows/arc-publish.yaml index 1a9328ca..9eba867d 100644 --- a/.github/workflows/arc-publish.yaml +++ b/.github/workflows/arc-publish.yaml @@ -73,8 +73,7 @@ jobs: - name: Get Token id: get_workflow_token - # https://github.com/peter-murray/workflow-application-token-action/releases/tag/v3.0.0 - uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343 with: application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }} application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }} diff --git a/.github/workflows/arc-release-runners.yaml b/.github/workflows/arc-release-runners.yaml index da1fbf54..306b3ced 100644 --- a/.github/workflows/arc-release-runners.yaml +++ b/.github/workflows/arc-release-runners.yaml @@ -39,8 +39,7 @@ jobs: - name: Get Token id: get_workflow_token - # https://github.com/peter-murray/workflow-application-token-action/releases/tag/v3.0.0 - uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343 with: application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }} application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }} diff --git a/.github/workflows/arc-validate-chart.yaml b/.github/workflows/arc-validate-chart.yaml index d93fa27f..771690db 100644 --- a/.github/workflows/arc-validate-chart.yaml +++ b/.github/workflows/arc-validate-chart.yaml @@ -45,8 +45,7 @@ jobs: fetch-depth: 0 - name: Set up Helm - # Using https://github.com/Azure/setup-helm/releases/tag/v4.2.0 - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 + uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 with: version: ${{ env.HELM_VERSION }} @@ -56,7 +55,6 @@ jobs: python-version: "3.11" - name: Set up chart-testing - # https://github.com/helm/chart-testing-action/releases/tag/v2.7.0 uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b - name: Run chart-testing (list-changed) @@ -72,7 +70,6 @@ jobs: ct lint --config charts/.ci/ct-config.yaml - name: Create kind cluster - # https://github.com/helm/kind-action/releases/tag/v1.12.0 uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 if: steps.list-changed.outputs.changed == 'true' diff --git a/.github/workflows/gha-e2e-tests.yaml b/.github/workflows/gha-e2e-tests.yaml index aaed23bd..61541cd5 100644 --- a/.github/workflows/gha-e2e-tests.yaml +++ b/.github/workflows/gha-e2e-tests.yaml @@ -16,7 +16,7 @@ env: TARGET_ORG: actions-runner-controller TARGET_REPO: arc_e2e_test_dummy IMAGE_NAME: "arc-test-image" - IMAGE_VERSION: "0.12.0" + IMAGE_VERSION: "0.12.1" concurrency: # This will make sure we only apply the concurrency limits on pull requests diff --git a/.github/workflows/gha-publish-chart.yaml b/.github/workflows/gha-publish-chart.yaml index c6e6e8b5..6a0ad653 100644 --- a/.github/workflows/gha-publish-chart.yaml +++ b/.github/workflows/gha-publish-chart.yaml @@ -72,11 +72,10 @@ jobs: echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT - name: Set up QEMU - # https://github.com/docker/setup-qemu-action/releases/tag/v3.6.0 uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 with: # Pinning v0.9.1 for Buildx and BuildKit v0.10.6 # BuildKit v0.11 which has a bug causing intermittent @@ -85,7 +84,6 @@ jobs: driver-opts: image=moby/buildkit:v0.10.6 - name: Login to GitHub Container Registry - # https://github.com/docker/login-action/releases/tag/v3.4.0 uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: registry: ghcr.io @@ -93,7 +91,6 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build & push controller image - # https://github.com/docker/build-push-action/releases/tag/v6.18.0 uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 with: file: Dockerfile @@ -141,8 +138,7 @@ jobs: echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT - name: Set up Helm - # Using https://github.com/Azure/setup-helm/releases/tag/v4.2.0 - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 + uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 with: version: ${{ env.HELM_VERSION }} @@ -189,8 +185,7 @@ jobs: echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT - name: Set up Helm - # Using https://github.com/Azure/setup-helm/releases/tag/v4.2.0 - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 + uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 with: version: ${{ env.HELM_VERSION }} diff --git a/.github/workflows/gha-validate-chart.yaml b/.github/workflows/gha-validate-chart.yaml index 3e249867..07d5cc24 100644 --- a/.github/workflows/gha-validate-chart.yaml +++ b/.github/workflows/gha-validate-chart.yaml @@ -41,8 +41,7 @@ jobs: fetch-depth: 0 - name: Set up Helm - # Using https://github.com/Azure/setup-helm/releases/tag/v4.2.0 - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 + uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 with: version: ${{ env.HELM_VERSION }} @@ -52,7 +51,6 @@ jobs: python-version: "3.11" - name: Set up chart-testing - # https://github.com/helm/chart-testing-action/releases/tag/v2.7.0 uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b - name: Run chart-testing (list-changed) @@ -69,13 +67,12 @@ jobs: ct lint --config charts/.ci/ct-config-gha.yaml - name: Set up docker buildx - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 if: steps.list-changed.outputs.changed == 'true' with: version: latest - name: Build controller image - # https://github.com/docker/build-push-action/releases/tag/v6.18.0 uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 if: steps.list-changed.outputs.changed == 'true' with: @@ -91,7 +88,6 @@ jobs: cache-to: type=gha,mode=max - name: Create kind cluster - # https://github.com/helm/kind-action/releases/tag/v1.12.0 uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 if: steps.list-changed.outputs.changed == 'true' with: diff --git a/.github/workflows/global-publish-canary.yaml b/.github/workflows/global-publish-canary.yaml index ed649f5c..2f0a2fbd 100644 --- a/.github/workflows/global-publish-canary.yaml +++ b/.github/workflows/global-publish-canary.yaml @@ -59,8 +59,7 @@ jobs: - name: Get Token id: get_workflow_token - # https://github.com/peter-murray/workflow-application-token-action/releases/tag/v3.0.0 - uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343 with: application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }} application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }} @@ -94,7 +93,6 @@ jobs: uses: actions/checkout@v4 - name: Login to GitHub Container Registry - # https://github.com/docker/login-action/releases/tag/v3.4.0 uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: registry: ghcr.io @@ -112,18 +110,15 @@ jobs: echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT - name: Set up QEMU - # https://github.com/docker/setup-qemu-action/releases/tag/v3.6.0 uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 - name: Set up Docker Buildx - # https://github.com/docker/setup-buildx-action/releases/tag/v3.10.0 - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 with: version: latest # Unstable builds - run at your own risk - name: Build and Push - # https://github.com/docker/build-push-action/releases/tag/v6.18.0 uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 with: context: . diff --git a/.github/workflows/global-run-codeql.yaml b/.github/workflows/global-run-codeql.yaml index 99692156..db262624 100644 --- a/.github/workflows/global-run-codeql.yaml +++ b/.github/workflows/global-run-codeql.yaml @@ -33,12 +33,12 @@ jobs: go-version-file: go.mod - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: go - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/global-run-stale.yaml b/.github/workflows/global-run-stale.yaml index a84af45b..52464196 100644 --- a/.github/workflows/global-run-stale.yaml +++ b/.github/workflows/global-run-stale.yaml @@ -14,7 +14,7 @@ jobs: issues: write # for actions/stale to close stale issues pull-requests: write # for actions/stale to close stale PRs steps: - - uses: actions/stale@v6 + - uses: actions/stale@v9 with: stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' # turn off stale for both issues and PRs diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 703b56a5..800c49cc 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -48,8 +48,7 @@ jobs: go-version-file: "go.mod" cache: false - name: golangci-lint - # https://github.com/golangci/golangci-lint-action/releases/tag/v7.0.0 - uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd + uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 with: only-new-issues: true version: v2.1.2 diff --git a/charts/gha-runner-scale-set-controller/Chart.yaml b/charts/gha-runner-scale-set-controller/Chart.yaml index b89143cb..c529bc6b 100644 --- a/charts/gha-runner-scale-set-controller/Chart.yaml +++ b/charts/gha-runner-scale-set-controller/Chart.yaml @@ -15,13 +15,13 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.12.0 +version: 0.12.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.12.0" +appVersion: "0.12.1" home: https://github.com/actions/actions-runner-controller diff --git a/charts/gha-runner-scale-set-controller/templates/_helpers.tpl b/charts/gha-runner-scale-set-controller/templates/_helpers.tpl index 65c5315e..8ac86c06 100644 --- a/charts/gha-runner-scale-set-controller/templates/_helpers.tpl +++ b/charts/gha-runner-scale-set-controller/templates/_helpers.tpl @@ -129,11 +129,3 @@ Create the name of the service account to use {{- define "gha-runner-scale-set-controller.leaderElectionRoleBinding" -}} {{- include "gha-runner-scale-set-controller.fullname" . }}-leader-election {{- end }} - -{{- define "gha-runner-scale-set-controller.imagePullSecretsNames" -}} -{{- $names := list }} -{{- range $k, $v := . }} - {{- $names = append $names $v.name }} -{{- end }} -{{- $names | join ","}} -{{- end }} diff --git a/charts/gha-runner-scale-set-controller/templates/deployment.yaml b/charts/gha-runner-scale-set-controller/templates/deployment.yaml index 5aa5c6f5..200cbe0f 100644 --- a/charts/gha-runner-scale-set-controller/templates/deployment.yaml +++ b/charts/gha-runner-scale-set-controller/templates/deployment.yaml @@ -54,7 +54,9 @@ spec: - "--leader-election-id={{ include "gha-runner-scale-set-controller.fullname" . }}" {{- end }} {{- with .Values.imagePullSecrets }} - - "--auto-scaler-image-pull-secrets={{ include "gha-runner-scale-set-controller.imagePullSecretsNames" . }}" + {{- range . }} + - "--auto-scaler-image-pull-secrets={{- .name -}}" + {{- end }} {{- end }} {{- with .Values.flags.logLevel }} - "--log-level={{ . }}" diff --git a/charts/gha-runner-scale-set-controller/tests/template_test.go b/charts/gha-runner-scale-set-controller/tests/template_test.go index a8623f2e..c39cceee 100644 --- a/charts/gha-runner-scale-set-controller/tests/template_test.go +++ b/charts/gha-runner-scale-set-controller/tests/template_test.go @@ -683,7 +683,8 @@ func TestTemplate_ControllerDeployment_ForwardImagePullSecrets(t *testing.T) { expectedArgs := []string{ "--auto-scaling-runner-set-only", - "--auto-scaler-image-pull-secrets=dockerhub,ghcr", + "--auto-scaler-image-pull-secrets=dockerhub", + "--auto-scaler-image-pull-secrets=ghcr", "--log-level=debug", "--log-format=text", "--update-strategy=immediate", @@ -1079,6 +1080,7 @@ func TestDeployment_excludeLabelPropagationPrefixes(t *testing.T) { assert.Contains(t, container.Args, "--exclude-label-propagation-prefix=prefix.com/") assert.Contains(t, container.Args, "--exclude-label-propagation-prefix=complete.io/label") } + func TestNamespaceOverride(t *testing.T) { t.Parallel() diff --git a/charts/gha-runner-scale-set/Chart.yaml b/charts/gha-runner-scale-set/Chart.yaml index c2dcf121..237b5cfb 100644 --- a/charts/gha-runner-scale-set/Chart.yaml +++ b/charts/gha-runner-scale-set/Chart.yaml @@ -15,13 +15,13 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.12.0 +version: 0.12.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.12.0" +appVersion: "0.12.1" home: https://github.com/actions/actions-runner-controller diff --git a/cmd/ghalistener/metrics/metrics.go b/cmd/ghalistener/metrics/metrics.go index 71a657cd..2aed6fb8 100644 --- a/cmd/ghalistener/metrics/metrics.go +++ b/cmd/ghalistener/metrics/metrics.go @@ -468,7 +468,7 @@ func (e *exporter) PublishStatistics(stats *actions.RunnerScaleSetStatistic) { e.setGauge(MetricAssignedJobs, e.scaleSetLabels, float64(stats.TotalAssignedJobs)) e.setGauge(MetricRunningJobs, e.scaleSetLabels, float64(stats.TotalRunningJobs)) e.setGauge(MetricRegisteredRunners, e.scaleSetLabels, float64(stats.TotalRegisteredRunners)) - e.setGauge(MetricBusyRunners, e.scaleSetLabels, float64(float64(stats.TotalBusyRunners))) + e.setGauge(MetricBusyRunners, e.scaleSetLabels, float64(stats.TotalBusyRunners)) e.setGauge(MetricIdleRunners, e.scaleSetLabels, float64(stats.TotalIdleRunners)) } diff --git a/controllers/actions.github.com/ephemeralrunner_controller.go b/controllers/actions.github.com/ephemeralrunner_controller.go index 9ca3f52e..74138fc7 100644 --- a/controllers/actions.github.com/ephemeralrunner_controller.go +++ b/controllers/actions.github.com/ephemeralrunner_controller.go @@ -201,12 +201,16 @@ func (r *EphemeralRunnerReconciler) Reconcile(ctx context.Context, req ctrl.Requ backoffDuration := failedRunnerBackoff[len(ephemeralRunner.Status.Failures)] nextReconciliation := lastFailure.Add(backoffDuration) if !lastFailure.IsZero() && now.Before(&metav1.Time{Time: nextReconciliation}) { + requeueAfter := nextReconciliation.Sub(now.Time) log.Info("Backing off the next reconciliation due to failure", "lastFailure", lastFailure, "nextReconciliation", nextReconciliation, - "requeueAfter", nextReconciliation.Sub(now.Time), + "requeueAfter", requeueAfter, ) - return ctrl.Result{RequeueAfter: now.Sub(nextReconciliation)}, nil + return ctrl.Result{ + Requeue: true, + RequeueAfter: requeueAfter, + }, nil } secret := new(corev1.Secret) @@ -293,28 +297,10 @@ func (r *EphemeralRunnerReconciler) Reconcile(ctx context.Context, req ctrl.Requ } return ctrl.Result{}, nil - default: - // pod succeeded. We double-check with the service if the runner exists. - // The reason is that image can potentially finish with status 0, but not pick up the job. - existsInService, err := r.runnerRegisteredWithService(ctx, ephemeralRunner.DeepCopy(), log) - if err != nil { - log.Error(err, "Failed to check if runner is registered with the service") - return ctrl.Result{}, err - } - if !existsInService { - // the runner does not exist in the service, so it must be done - log.Info("Ephemeral runner has finished since it does not exist in the service anymore") - if err := r.markAsFinished(ctx, ephemeralRunner, log); err != nil { - log.Error(err, "Failed to mark ephemeral runner as finished") - return ctrl.Result{}, err - } - return ctrl.Result{}, nil - } - - // The runner still exists. This can happen if the pod exited with 0 but fails to start - log.Info("Ephemeral runner pod has finished, but the runner still exists in the service. Deleting the pod to restart it.") - if err := r.deletePodAsFailed(ctx, ephemeralRunner, pod, log); err != nil { - log.Error(err, "failed to delete a pod that still exists in the service") + default: // succeeded + log.Info("Ephemeral runner has finished successfully") + if err := r.markAsFinished(ctx, ephemeralRunner, log); err != nil { + log.Error(err, "Failed to mark ephemeral runner as finished") return ctrl.Result{}, err } return ctrl.Result{}, nil @@ -752,35 +738,6 @@ func (r *EphemeralRunnerReconciler) updateRunStatusFromPod(ctx context.Context, return nil } -// runnerRegisteredWithService checks if the runner is still registered with the service -// Returns found=false and err=nil if ephemeral runner does not exist in GitHub service and should be deleted -func (r EphemeralRunnerReconciler) runnerRegisteredWithService(ctx context.Context, runner *v1alpha1.EphemeralRunner, log logr.Logger) (found bool, err error) { - actionsClient, err := r.GetActionsService(ctx, runner) - if err != nil { - return false, fmt.Errorf("failed to get Actions client for ScaleSet: %w", err) - } - - log.Info("Checking if runner exists in GitHub service", "runnerId", runner.Status.RunnerId) - _, err = actionsClient.GetRunner(ctx, int64(runner.Status.RunnerId)) - if err != nil { - actionsError := &actions.ActionsError{} - if !errors.As(err, &actionsError) { - return false, err - } - - if actionsError.StatusCode != http.StatusNotFound || - !actionsError.IsException("AgentNotFoundException") { - return false, fmt.Errorf("failed to check if runner exists in GitHub service: %w", err) - } - - log.Info("Runner does not exist in GitHub service", "runnerId", runner.Status.RunnerId) - return false, nil - } - - log.Info("Runner exists in GitHub service", "runnerId", runner.Status.RunnerId) - return true, nil -} - func (r *EphemeralRunnerReconciler) deleteRunnerFromService(ctx context.Context, ephemeralRunner *v1alpha1.EphemeralRunner, log logr.Logger) error { client, err := r.GetActionsService(ctx, ephemeralRunner) if err != nil { diff --git a/controllers/actions.github.com/ephemeralrunner_controller_test.go b/controllers/actions.github.com/ephemeralrunner_controller_test.go index 26d66814..3aa6a8ea 100644 --- a/controllers/actions.github.com/ephemeralrunner_controller_test.go +++ b/controllers/actions.github.com/ephemeralrunner_controller_test.go @@ -675,53 +675,6 @@ var _ = Describe("EphemeralRunner", func() { ).Should(BeEquivalentTo(true)) }) - It("It should re-create pod on exit status 0, but runner exists within the service", func() { - pod := new(corev1.Pod) - Eventually( - func() (bool, error) { - if err := k8sClient.Get(ctx, client.ObjectKey{Name: ephemeralRunner.Name, Namespace: ephemeralRunner.Namespace}, pod); err != nil { - return false, err - } - return true, nil - }, - ephemeralRunnerTimeout, - ephemeralRunnerInterval, - ).Should(BeEquivalentTo(true)) - - pod.Status.ContainerStatuses = append(pod.Status.ContainerStatuses, corev1.ContainerStatus{ - Name: v1alpha1.EphemeralRunnerContainerName, - State: corev1.ContainerState{ - Terminated: &corev1.ContainerStateTerminated{ - ExitCode: 0, - }, - }, - }) - err := k8sClient.Status().Update(ctx, pod) - Expect(err).To(BeNil(), "failed to update pod status") - - updated := new(v1alpha1.EphemeralRunner) - Eventually(func() (bool, error) { - err := k8sClient.Get(ctx, client.ObjectKey{Name: ephemeralRunner.Name, Namespace: ephemeralRunner.Namespace}, updated) - if err != nil { - return false, err - } - return len(updated.Status.Failures) == 1, nil - }, ephemeralRunnerTimeout, ephemeralRunnerInterval).Should(BeEquivalentTo(true)) - - // should re-create after failure - Eventually( - func() (bool, error) { - pod := new(corev1.Pod) - if err := k8sClient.Get(ctx, client.ObjectKey{Name: ephemeralRunner.Name, Namespace: ephemeralRunner.Namespace}, pod); err != nil { - return false, err - } - return true, nil - }, - ephemeralRunnerTimeout, - ephemeralRunnerInterval, - ).Should(BeEquivalentTo(true)) - }) - It("It should not set the phase to succeeded without pod termination status", func() { pod := new(corev1.Pod) Eventually( diff --git a/controllers/actions.summerwind.net/runner_controller.go b/controllers/actions.summerwind.net/runner_controller.go index 714fb7c0..78fc7229 100644 --- a/controllers/actions.summerwind.net/runner_controller.go +++ b/controllers/actions.summerwind.net/runner_controller.go @@ -1046,12 +1046,12 @@ func newRunnerPodWithContainerMode(containerMode string, template corev1.Pod, ru // overridden if ok, _ := envVarPresent("DOCKER_GROUP_GID", dockerdContainer.Env); !ok { gid := d.DockerGID - // We default to gid 121 for Ubuntu 22.04 images + // We default to gid 121 for Ubuntu 22.04 and 24.04 images // See below for more details // - https://github.com/actions/actions-runner-controller/issues/2490#issuecomment-1501561923 // - https://github.com/actions/actions-runner-controller/blob/8869ad28bb5a1daaedefe0e988571fe1fb36addd/runner/actions-runner.ubuntu-20.04.dockerfile#L14 // - https://github.com/actions/actions-runner-controller/blob/8869ad28bb5a1daaedefe0e988571fe1fb36addd/runner/actions-runner.ubuntu-22.04.dockerfile#L12 - if strings.Contains(runnerContainer.Image, "22.04") { + if strings.Contains(runnerContainer.Image, "22.04") || strings.Contains(runnerContainer.Image, "24.04") { gid = "121" } else if strings.Contains(runnerContainer.Image, "20.04") { gid = "1001" diff --git a/docs/authenticating-to-the-github-api.md b/docs/authenticating-to-the-github-api.md index 669e94d1..392c1f25 100644 --- a/docs/authenticating-to-the-github-api.md +++ b/docs/authenticating-to-the-github-api.md @@ -188,7 +188,7 @@ Create one using e.g. `eksctl`. You can refer to [the EKS documentation](https:/ Once you set up the service account, all you need is to add `serviceAccountName` and `fsGroup` to any pods that use the IAM-role enabled service account. -`fsGroup` needs to be set to the UID of the `runner` Linux user that runs the runner agent (and dockerd in case you use dind-runner). For anyone using an Ubuntu 20.04 runner image it's `1000` and for Ubuntu 22.04 one it's `1001`. +`fsGroup` needs to be set to the UID of the `runner` Linux user that runs the runner agent (and dockerd in case you use dind-runner). For anyone using an Ubuntu 20.04 runner image it's `1000` and for Ubuntu 22.04 and 24.04 one it's `1001`. For `RunnerDeployment`, you can set those two fields under the runner spec at `RunnerDeployment.Spec.Template`: @@ -205,7 +205,7 @@ spec: securityContext: # For Ubuntu 20.04 runner fsGroup: 1000 - # Use 1001 for Ubuntu 22.04 runner + # Use 1001 for Ubuntu 22.04 and 24.04 runner #fsGroup: 1001 ``` diff --git a/docs/gha-runner-scale-set-controller/README.md b/docs/gha-runner-scale-set-controller/README.md index 42b363a1..27f1b76b 100644 --- a/docs/gha-runner-scale-set-controller/README.md +++ b/docs/gha-runner-scale-set-controller/README.md @@ -43,6 +43,14 @@ You can follow [this troubleshooting guide](https://docs.github.com/en/actions/h ## Changelog +### 0.12.1 + +1. Fix indentation of startupProbe attributes in dind sidecar [#4126](https://github.com/actions/actions-runner-controller/pull/4126) +1. Remove duplicate float64 call [#4139](https://github.com/actions/actions-runner-controller/pull/4139) +1. Fix dind sidecar template [#4128](https://github.com/actions/actions-runner-controller/pull/4128) +1. Remove check if runner exists after exit code 0 [#4142](https://github.com/actions/actions-runner-controller/pull/4142) +1. Explicitly requeue during backoff ephemeral runner [#4152](https://github.com/actions/actions-runner-controller/pull/4152) + ### 0.12.0 1. Allow use of client id as an app id [#4057](https://github.com/actions/actions-runner-controller/pull/4057) diff --git a/main.go b/main.go index 8f0025f9..d649d4ae 100644 --- a/main.go +++ b/main.go @@ -124,7 +124,7 @@ func main() { flag.StringVar(&leaderElectionId, "leader-election-id", "actions-runner-controller", "Controller id for leader election.") flag.StringVar(&runnerPodDefaults.RunnerImage, "runner-image", defaultRunnerImage, "The image name of self-hosted runner container to use by default if one isn't defined in yaml.") flag.StringVar(&runnerPodDefaults.DockerImage, "docker-image", defaultDockerImage, "The image name of docker sidecar container to use by default if one isn't defined in yaml.") - flag.StringVar(&runnerPodDefaults.DockerGID, "docker-gid", defaultDockerGID, "The default GID of docker group in the docker sidecar container. Use 1001 for dockerd sidecars of Ubuntu 20.04 runners 121 for Ubuntu 22.04.") + flag.StringVar(&runnerPodDefaults.DockerGID, "docker-gid", defaultDockerGID, "The default GID of docker group in the docker sidecar container. Use 1001 for dockerd sidecars of Ubuntu 20.04 runners 121 for Ubuntu 22.04 and 24.04.") flag.Var(&runnerImagePullSecrets, "runner-image-pull-secret", "The default image-pull secret name for self-hosted runner container.") flag.StringVar(&runnerPodDefaults.DockerRegistryMirror, "docker-registry-mirror", "", "The default Docker Registry Mirror used by runners.") flag.StringVar(&c.Token, "github-token", c.Token, "The personal access token of GitHub.") diff --git a/runner/actions-runner-dind-rootless.ubuntu-24.04.dockerfile b/runner/actions-runner-dind-rootless.ubuntu-24.04.dockerfile new file mode 100644 index 00000000..ea3d56ca --- /dev/null +++ b/runner/actions-runner-dind-rootless.ubuntu-24.04.dockerfile @@ -0,0 +1,135 @@ +FROM ubuntu:24.04 + +ARG TARGETPLATFORM +ARG RUNNER_VERSION +ARG RUNNER_CONTAINER_HOOKS_VERSION +# Docker and Docker Compose arguments +ENV CHANNEL=stable +ARG DOCKER_COMPOSE_VERSION=v2.23.0 +ARG DUMB_INIT_VERSION=1.2.5 +ARG RUNNER_USER_UID=1001 + +# Other arguments +ARG DEBUG=false + +RUN test -n "$TARGETPLATFORM" || (echo "TARGETPLATFORM must be set" && false) + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update -y \ + && apt-get install -y software-properties-common \ + && add-apt-repository -y ppa:git-core/ppa \ + && apt-get update -y \ + && apt-get install -y --no-install-recommends \ + curl \ + ca-certificates \ + git \ + iproute2 \ + iptables \ + jq \ + sudo \ + uidmap \ + unzip \ + zip \ + fuse-overlayfs \ + && rm -rf /var/lib/apt/lists/* + +# Download latest git-lfs version +RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && \ + apt-get install -y --no-install-recommends git-lfs + +# Runner user +RUN adduser --disabled-password --gecos "" --uid $RUNNER_USER_UID runner + +ENV HOME=/home/runner + +# Set-up subuid and subgid so that "--userns-remap=default" works +RUN set -eux; \ + addgroup --system dockremap; \ + adduser --system --ingroup dockremap dockremap; \ + echo 'dockremap:165536:65536' >> /etc/subuid; \ + echo 'dockremap:165536:65536' >> /etc/subgid + +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \ + && curl -fLo /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_${ARCH} \ + && chmod +x /usr/bin/dumb-init + +ENV RUNNER_ASSETS_DIR=/runnertmp +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x64 ; fi \ + && mkdir -p "$RUNNER_ASSETS_DIR" \ + && cd "$RUNNER_ASSETS_DIR" \ + && curl -fLo runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz \ + && tar xzf ./runner.tar.gz \ + && rm runner.tar.gz \ + && ./bin/installdependencies.sh \ + && mv ./externals ./externalstmp \ + # libyaml-dev is required for ruby/setup-ruby action. + # It is installed after installdependencies.sh and before removing /var/lib/apt/lists + # to avoid rerunning apt-update on its own. + && apt-get install -y libyaml-dev \ + && rm -rf /var/lib/apt/lists/* + +ENV RUNNER_TOOL_CACHE=/opt/hostedtoolcache +RUN mkdir /opt/hostedtoolcache \ + && chgrp runner /opt/hostedtoolcache \ + && chmod g+rwx /opt/hostedtoolcache + +RUN cd "$RUNNER_ASSETS_DIR" \ + && curl -fLo runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \ + && unzip ./runner-container-hooks.zip -d ./k8s \ + && rm -f runner-container-hooks.zip + +# Make the rootless runner directory executable +RUN mkdir /run/user/1000 \ + && chown runner:runner /run/user/1000 \ + && chmod a+x /run/user/1000 + +# We place the scripts in `/usr/bin` so that users who extend this image can +# override them with scripts of the same name placed in `/usr/local/bin`. +COPY entrypoint-dind-rootless.sh startup.sh logger.sh graceful-stop.sh update-status /usr/bin/ +RUN chmod +x /usr/bin/entrypoint-dind-rootless.sh /usr/bin/startup.sh + +# Copy the docker shim which propagates the docker MTU to underlying networks +# to replace the docker binary in the PATH. +COPY docker-shim.sh /usr/local/bin/docker + +# Configure hooks folder structure. +COPY hooks /etc/arc/hooks/ + +# Add the Python "User Script Directory" to the PATH +ENV PATH="${PATH}:${HOME}/.local/bin:/home/runner/bin" +ENV ImageOS=ubuntu22 +ENV DOCKER_HOST=unix:///run/user/1000/docker.sock +ENV XDG_RUNTIME_DIR=/run/user/1000 + +RUN echo "PATH=${PATH}" > /etc/environment \ + && echo "ImageOS=${ImageOS}" >> /etc/environment \ + && echo "DOCKER_HOST=${DOCKER_HOST}" >> /etc/environment \ + && echo "XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}" >> /etc/environment + +# No group definition, as that makes it harder to run docker. +USER runner + +# This will install docker under $HOME/bin according to the content of the script +RUN export SKIP_IPTABLES=1 \ + && curl -fsSL https://get.docker.com/rootless | sh \ + && /home/runner/bin/docker -v + +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \ + && mkdir -p /home/runner/.docker/cli-plugins \ + && curl -fLo /home/runner/.docker/cli-plugins/docker-compose https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-${ARCH} \ + && chmod +x /home/runner/.docker/cli-plugins/docker-compose \ + && ln -s /home/runner/.docker/cli-plugins/docker-compose /home/runner/bin/docker-compose \ + && which docker-compose \ + && docker compose version + +# Create folder structure here to avoid permission issues +# when mounting the daemon.json file from a configmap. +RUN mkdir -p /home/runner/.config/docker + +ENTRYPOINT ["/bin/bash", "-c"] +CMD ["entrypoint-dind-rootless.sh"] diff --git a/runner/actions-runner-dind.ubuntu-24.04.dockerfile b/runner/actions-runner-dind.ubuntu-24.04.dockerfile new file mode 100644 index 00000000..de4bf852 --- /dev/null +++ b/runner/actions-runner-dind.ubuntu-24.04.dockerfile @@ -0,0 +1,120 @@ +FROM ubuntu:24.04 + +ARG TARGETPLATFORM +ARG RUNNER_VERSION +ARG RUNNER_CONTAINER_HOOKS_VERSION +# Docker and Docker Compose arguments +ARG CHANNEL=stable +ARG DOCKER_VERSION=24.0.7 +ARG DOCKER_COMPOSE_VERSION=v2.23.0 +ARG DUMB_INIT_VERSION=1.2.5 +ARG RUNNER_USER_UID=1001 +ARG DOCKER_GROUP_GID=121 + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update -y \ + && apt-get install -y software-properties-common \ + && add-apt-repository -y ppa:git-core/ppa \ + && apt-get update -y \ + && apt-get install -y --no-install-recommends \ + curl \ + ca-certificates \ + git \ + iptables \ + jq \ + software-properties-common \ + sudo \ + unzip \ + zip \ + && rm -rf /var/lib/apt/lists/* + +# Download latest git-lfs version +RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && \ + apt-get install -y --no-install-recommends git-lfs + +# Runner user +RUN adduser --disabled-password --gecos "" --uid $RUNNER_USER_UID runner \ + && groupadd docker --gid $DOCKER_GROUP_GID \ + && usermod -aG sudo runner \ + && usermod -aG docker runner \ + && echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers \ + && echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >> /etc/sudoers + +ENV HOME=/home/runner + +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \ + && curl -fLo /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_${ARCH} \ + && chmod +x /usr/bin/dumb-init + +ENV RUNNER_ASSETS_DIR=/runnertmp +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x64 ; fi \ + && mkdir -p "$RUNNER_ASSETS_DIR" \ + && cd "$RUNNER_ASSETS_DIR" \ + && curl -fLo runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz \ + && tar xzf ./runner.tar.gz \ + && rm -f runner.tar.gz \ + && ./bin/installdependencies.sh \ + # libyaml-dev is required for ruby/setup-ruby action. + # It is installed after installdependencies.sh and before removing /var/lib/apt/lists + # to avoid rerunning apt-update on its own. + && apt-get install -y libyaml-dev \ + && rm -rf /var/lib/apt/lists/* + +ENV RUNNER_TOOL_CACHE=/opt/hostedtoolcache +RUN mkdir /opt/hostedtoolcache \ + && chgrp docker /opt/hostedtoolcache \ + && chmod g+rwx /opt/hostedtoolcache + +RUN cd "$RUNNER_ASSETS_DIR" \ + && curl -fLo runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \ + && unzip ./runner-container-hooks.zip -d ./k8s \ + && rm -f runner-container-hooks.zip + +RUN set -vx; \ + export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \ + && curl -fLo docker.tgz https://download.docker.com/linux/static/${CHANNEL}/${ARCH}/docker-${DOCKER_VERSION}.tgz \ + && tar zxvf docker.tgz \ + && install -o root -g root -m 755 docker/* /usr/bin/ \ + && rm -rf docker docker.tgz + +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \ + && mkdir -p /usr/libexec/docker/cli-plugins \ + && curl -fLo /usr/libexec/docker/cli-plugins/docker-compose https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-${ARCH} \ + && chmod +x /usr/libexec/docker/cli-plugins/docker-compose \ + && ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/bin/docker-compose \ + && which docker-compose \ + && docker compose version + +# We place the scripts in `/usr/bin` so that users who extend this image can +# override them with scripts of the same name placed in `/usr/local/bin`. +COPY entrypoint-dind.sh startup.sh logger.sh wait.sh graceful-stop.sh update-status /usr/bin/ +RUN chmod +x /usr/bin/entrypoint-dind.sh /usr/bin/startup.sh + +# Copy the docker shim which propagates the docker MTU to underlying networks +# to replace the docker binary in the PATH. +COPY docker-shim.sh /usr/local/bin/docker + +# Configure hooks folder structure. +COPY hooks /etc/arc/hooks/ + +VOLUME /var/lib/docker + +# Add the Python "User Script Directory" to the PATH +ENV PATH="${PATH}:${HOME}/.local/bin" +ENV ImageOS=ubuntu24 + +RUN echo "PATH=${PATH}" > /etc/environment \ + && echo "ImageOS=${ImageOS}" >> /etc/environment + +# No group definition, as that makes it harder to run docker. +USER runner + +ENTRYPOINT ["/bin/bash", "-c"] +CMD ["entrypoint-dind.sh"] diff --git a/runner/actions-runner.ubuntu-24.04.dockerfile b/runner/actions-runner.ubuntu-24.04.dockerfile new file mode 100644 index 00000000..a905590d --- /dev/null +++ b/runner/actions-runner.ubuntu-24.04.dockerfile @@ -0,0 +1,114 @@ +FROM ubuntu:24.04 + +ARG TARGETPLATFORM +ARG RUNNER_VERSION +ARG RUNNER_CONTAINER_HOOKS_VERSION +# Docker and Docker Compose arguments +ARG CHANNEL=stable +ARG DOCKER_VERSION=24.0.7 +ARG DOCKER_COMPOSE_VERSION=v2.23.0 +ARG DUMB_INIT_VERSION=1.2.5 +ARG RUNNER_USER_UID=1001 +ARG DOCKER_GROUP_GID=121 + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update -y \ + && apt-get install -y software-properties-common \ + && add-apt-repository -y ppa:git-core/ppa \ + && apt-get update -y \ + && apt-get install -y --no-install-recommends \ + curl \ + ca-certificates \ + git \ + jq \ + sudo \ + unzip \ + zip \ + && rm -rf /var/lib/apt/lists/* + +# Download latest git-lfs version +RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && \ + apt-get install -y --no-install-recommends git-lfs + +RUN adduser --disabled-password --gecos "" --uid $RUNNER_USER_UID runner \ + && groupadd docker --gid $DOCKER_GROUP_GID \ + && usermod -aG sudo runner \ + && usermod -aG docker runner \ + && echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers \ + && echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >> /etc/sudoers + +ENV HOME=/home/runner + +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \ + && curl -fLo /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_${ARCH} \ + && chmod +x /usr/bin/dumb-init + +ENV RUNNER_ASSETS_DIR=/runnertmp +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x64 ; fi \ + && mkdir -p "$RUNNER_ASSETS_DIR" \ + && cd "$RUNNER_ASSETS_DIR" \ + && curl -fLo runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz \ + && tar xzf ./runner.tar.gz \ + && rm runner.tar.gz \ + && ./bin/installdependencies.sh \ + && mv ./externals ./externalstmp \ + # libyaml-dev is required for ruby/setup-ruby action. + # It is installed after installdependencies.sh and before removing /var/lib/apt/lists + # to avoid rerunning apt-update on its own. + && apt-get install -y libyaml-dev \ + && rm -rf /var/lib/apt/lists/* + +ENV RUNNER_TOOL_CACHE=/opt/hostedtoolcache +RUN mkdir /opt/hostedtoolcache \ + && chgrp docker /opt/hostedtoolcache \ + && chmod g+rwx /opt/hostedtoolcache + +RUN cd "$RUNNER_ASSETS_DIR" \ + && curl -fLo runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \ + && unzip ./runner-container-hooks.zip -d ./k8s \ + && rm -f runner-container-hooks.zip + +RUN set -vx; \ + export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \ + && curl -fLo docker.tgz https://download.docker.com/linux/static/${CHANNEL}/${ARCH}/docker-${DOCKER_VERSION}.tgz \ + && tar zxvf docker.tgz \ + && install -o root -g root -m 755 docker/docker /usr/bin/docker \ + && rm -rf docker docker.tgz + +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \ + && mkdir -p /usr/libexec/docker/cli-plugins \ + && curl -fLo /usr/libexec/docker/cli-plugins/docker-compose https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-${ARCH} \ + && chmod +x /usr/libexec/docker/cli-plugins/docker-compose \ + && ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/bin/docker-compose \ + && which docker-compose \ + && docker compose version + +# We place the scripts in `/usr/bin` so that users who extend this image can +# override them with scripts of the same name placed in `/usr/local/bin`. +COPY entrypoint.sh startup.sh logger.sh graceful-stop.sh update-status /usr/bin/ + +# Copy the docker shim which propagates the docker MTU to underlying networks +# to replace the docker binary in the PATH. +COPY docker-shim.sh /usr/local/bin/docker + +# Configure hooks folder structure. +COPY hooks /etc/arc/hooks/ + +# Add the Python "User Script Directory" to the PATH +ENV PATH="${PATH}:${HOME}/.local/bin/" +ENV ImageOS=ubuntu24 + +RUN echo "PATH=${PATH}" > /etc/environment \ + && echo "ImageOS=${ImageOS}" >> /etc/environment + +USER runner + +ENTRYPOINT ["/bin/bash", "-c"] +CMD ["entrypoint.sh"]