mirror of
https://github.com/actions/actions-runner-controller.git
synced 2025-12-11 20:21:02 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfffd3fb62 | ||
|
|
f710a54110 | ||
|
|
85c29a95f5 | ||
|
|
a2b335ad6a | ||
|
|
56c57cbf71 | ||
|
|
837563c976 | ||
|
|
df99f394b4 | ||
|
|
be25715e1e | ||
|
|
4ca825eef0 |
56
.github/workflows/build-runner.yml
vendored
56
.github/workflows/build-runner.yml
vendored
@@ -27,46 +27,38 @@ jobs:
|
|||||||
- name: actions-runner-dind
|
- name: actions-runner-dind
|
||||||
dockerfile: dindrunner.Dockerfile
|
dockerfile: dindrunner.Dockerfile
|
||||||
env:
|
env:
|
||||||
RUNNER_VERSION: 2.274.1
|
RUNNER_VERSION: 2.274.2
|
||||||
DOCKER_VERSION: 19.03.12
|
DOCKER_VERSION: 19.03.12
|
||||||
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
uses: docker/setup-buildx-action@v1
|
||||||
uses: crazy-max/ghaction-docker-buildx@v1
|
|
||||||
with:
|
with:
|
||||||
buildx-version: latest
|
version: latest
|
||||||
|
|
||||||
- name: Build Container Image
|
- name: Login to DockerHub
|
||||||
working-directory: runner
|
uses: docker/login-action@v1
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
run: |
|
|
||||||
docker buildx build \
|
|
||||||
--build-arg RUNNER_VERSION=${RUNNER_VERSION} \
|
|
||||||
--build-arg DOCKER_VERSION=${DOCKER_VERSION} \
|
|
||||||
--platform linux/amd64,linux/arm64 \
|
|
||||||
--tag ${DOCKERHUB_USERNAME}/${{ matrix.name }}:v${RUNNER_VERSION} \
|
|
||||||
--tag ${DOCKERHUB_USERNAME}/${{ matrix.name }}:latest \
|
|
||||||
-f ${{ matrix.dockerfile }} .
|
|
||||||
|
|
||||||
- name: Login to GitHub Docker Registry
|
|
||||||
run: echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin
|
|
||||||
if: ${{ github.event_name == 'push' }}
|
if: ${{ github.event_name == 'push' }}
|
||||||
env:
|
with:
|
||||||
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||||
|
|
||||||
- name: Build and Push Container Image
|
- name: Build [and Push]
|
||||||
working-directory: runner
|
uses: docker/build-push-action@v2
|
||||||
if: ${{ github.event_name == 'push' }}
|
with:
|
||||||
run: |
|
context: ./runner
|
||||||
docker buildx build \
|
file: ./runner/${{ matrix.dockerfile }}
|
||||||
--build-arg RUNNER_VERSION=${RUNNER_VERSION} \
|
platforms: linux/amd64,linux/arm64
|
||||||
--build-arg DOCKER_VERSION=${DOCKER_VERSION} \
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
--platform linux/amd64,linux/arm64 \
|
build-args: |
|
||||||
--tag ${DOCKERHUB_USERNAME}/${{ matrix.name }}:v${RUNNER_VERSION} \
|
RUNNER_VERSION=${{ env.RUNNER_VERSION }}
|
||||||
--tag ${DOCKERHUB_USERNAME}/${{ matrix.name }}:latest \
|
DOCKER_VERSION=${{ env.DOCKER_VERSION }}
|
||||||
-f ${{ matrix.dockerfile }} . --push
|
tags: |
|
||||||
|
${{ env.DOCKERHUB_USERNAME }}/${{ matrix.name }}:v${{ env.RUNNER_VERSION }}
|
||||||
|
${{ env.DOCKERHUB_USERNAME }}/${{ matrix.name }}:latest
|
||||||
|
|||||||
35
.github/workflows/release.yml
vendored
35
.github/workflows/release.yml
vendored
@@ -6,6 +6,8 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Release
|
name: Release
|
||||||
|
env:
|
||||||
|
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@@ -29,23 +31,26 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: make github-release
|
run: make github-release
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: crazy-max/ghaction-docker-buildx@v1
|
uses: docker/setup-buildx-action@v1
|
||||||
with:
|
with:
|
||||||
buildx-version: latest
|
version: latest
|
||||||
|
|
||||||
- name: Login to GitHub Docker Registry
|
- name: Login to DockerHub
|
||||||
run: echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin
|
uses: docker/login-action@v1
|
||||||
env:
|
with:
|
||||||
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and Push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
file: Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: ${{ env.DOCKERHUB_USERNAME }}/actions-runner-controller:${{ env.VERSION }}
|
||||||
|
|
||||||
- name: Build Container Image
|
|
||||||
env:
|
|
||||||
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
|
||||||
run: |
|
|
||||||
docker buildx build \
|
|
||||||
--platform linux/amd64,linux/arm64 \
|
|
||||||
--tag ${DOCKERHUB_USERNAME}/actions-runner-controller:${{ env.VERSION }} \
|
|
||||||
-f Dockerfile . --push
|
|
||||||
|
|||||||
35
.github/workflows/wip.yml
vendored
35
.github/workflows/wip.yml
vendored
@@ -9,27 +9,32 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: release-latest
|
name: release-latest
|
||||||
|
env:
|
||||||
|
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: crazy-max/ghaction-docker-buildx@v1
|
uses: docker/setup-buildx-action@v1
|
||||||
with:
|
with:
|
||||||
buildx-version: latest
|
version: latest
|
||||||
|
|
||||||
- name: Login to GitHub Docker Registry
|
- name: Login to DockerHub
|
||||||
run: echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin
|
uses: docker/login-action@v1
|
||||||
env:
|
with:
|
||||||
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and Push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
file: Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: ${{ env.DOCKERHUB_USERNAME }}/actions-runner-controller:latest
|
||||||
|
|
||||||
- name: Build Container Image
|
|
||||||
env:
|
|
||||||
DOCKERHUB_USERNAME: ${{ github.repository_owner }}
|
|
||||||
run: |
|
|
||||||
docker buildx build \
|
|
||||||
--platform linux/amd64,linux/arm64 \
|
|
||||||
--tag ${DOCKERHUB_USERNAME}/actions-runner-controller:latest \
|
|
||||||
-f Dockerfile . --push
|
|
||||||
|
|||||||
22
Makefile
22
Makefile
@@ -121,21 +121,27 @@ release: manifests
|
|||||||
mkdir -p release
|
mkdir -p release
|
||||||
kustomize build config/default > release/actions-runner-controller.yaml
|
kustomize build config/default > release/actions-runner-controller.yaml
|
||||||
|
|
||||||
.PHONY: acceptance
|
.PHONY: release/clean
|
||||||
acceptance: release
|
release/clean:
|
||||||
ACCEPTANCE_TEST_SECRET_TYPE=token make acceptance/setup acceptance/tests acceptance/teardown
|
rm -rf release
|
||||||
ACCEPTANCE_TEST_SECRET_TYPE=app make acceptance/setup acceptance/tests acceptance/teardown
|
|
||||||
ACCEPTANCE_TEST_DEPLOYMENT_TOOL=helm ACCEPTANCE_TEST_SECRET_TYPE=token make acceptance/setup acceptance/tests acceptance/teardown
|
|
||||||
ACCEPTANCE_TEST_DEPLOYMENT_TOOL=helm ACCEPTANCE_TEST_SECRET_TYPE=app make acceptance/setup acceptance/tests acceptance/teardown
|
|
||||||
|
|
||||||
acceptance/setup:
|
.PHONY: acceptance
|
||||||
|
acceptance: release/clean docker-build docker-push release
|
||||||
|
ACCEPTANCE_TEST_SECRET_TYPE=token make acceptance/kind acceptance/setup acceptance/tests acceptance/teardown
|
||||||
|
ACCEPTANCE_TEST_SECRET_TYPE=app make acceptance/kind acceptance/setup acceptance/tests acceptance/teardown
|
||||||
|
ACCEPTANCE_TEST_DEPLOYMENT_TOOL=helm ACCEPTANCE_TEST_SECRET_TYPE=token make acceptance/kind acceptance/setup acceptance/tests acceptance/teardown
|
||||||
|
ACCEPTANCE_TEST_DEPLOYMENT_TOOL=helm ACCEPTANCE_TEST_SECRET_TYPE=app make acceptance/kind acceptance/setup acceptance/tests acceptance/teardown
|
||||||
|
|
||||||
|
acceptance/kind:
|
||||||
kind create cluster --name acceptance
|
kind create cluster --name acceptance
|
||||||
kubectl cluster-info --context kind-acceptance
|
kubectl cluster-info --context kind-acceptance
|
||||||
|
|
||||||
|
acceptance/setup:
|
||||||
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.4/cert-manager.yaml #kubectl create namespace actions-runner-system
|
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.4/cert-manager.yaml #kubectl create namespace actions-runner-system
|
||||||
kubectl -n cert-manager wait deploy/cert-manager-cainjector --for condition=available --timeout 60s
|
kubectl -n cert-manager wait deploy/cert-manager-cainjector --for condition=available --timeout 60s
|
||||||
kubectl -n cert-manager wait deploy/cert-manager-webhook --for condition=available --timeout 60s
|
kubectl -n cert-manager wait deploy/cert-manager-webhook --for condition=available --timeout 60s
|
||||||
kubectl -n cert-manager wait deploy/cert-manager --for condition=available --timeout 60s
|
kubectl -n cert-manager wait deploy/cert-manager --for condition=available --timeout 60s
|
||||||
kubectl create namespace actions-runner-system
|
kubectl create namespace actions-runner-system || true
|
||||||
# Adhocly wait for some time until cert-manager's admission webhook gets ready
|
# Adhocly wait for some time until cert-manager's admission webhook gets ready
|
||||||
sleep 5
|
sleep 5
|
||||||
|
|
||||||
|
|||||||
44
README.md
44
README.md
@@ -404,6 +404,32 @@ spec:
|
|||||||
group: NewGroup
|
group: NewGroup
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Using EKS IAM role for service accounts
|
||||||
|
|
||||||
|
`actions-runner-controller` v0.15.0 or later has support for EKS IAM role for service accounts.
|
||||||
|
|
||||||
|
As similar as for regular pods and deployments, you firstly need an existing service account with the IAM role associated.
|
||||||
|
Create one using e.g. `eksctl`. You can refer to [the EKS documentation](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) for more details.
|
||||||
|
|
||||||
|
Once you set up the service account, all you need is to add `serviceAccountName` and `fsGroup` to any pods that uses
|
||||||
|
the IAM-role enabled service account.
|
||||||
|
|
||||||
|
For `RunnerDeployment`, you can set those two fields under the runner spec at `RunnerDeployment.Spec.Template`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: actions.summerwind.dev/v1alpha1
|
||||||
|
kind: RunnerDeployment
|
||||||
|
metadata:
|
||||||
|
name: example-runnerdeploy
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
repository: USER/REO
|
||||||
|
serviceAccountName: my-service-account
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 1447
|
||||||
|
```
|
||||||
|
|
||||||
## Software installed in the runner image
|
## Software installed in the runner image
|
||||||
|
|
||||||
The GitHub hosted runners include a large amount of pre-installed software packages. For Ubuntu 18.04, this list can be found at <https://github.com/actions/virtual-environments/blob/master/images/linux/Ubuntu1804-README.md>
|
The GitHub hosted runners include a large amount of pre-installed software packages. For Ubuntu 18.04, this list can be found at <https://github.com/actions/virtual-environments/blob/master/images/linux/Ubuntu1804-README.md>
|
||||||
@@ -458,7 +484,10 @@ If you'd like to modify the controller to fork or contribute, I'd suggest using
|
|||||||
the acceptance test:
|
the acceptance test:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
NAME=$DOCKER_USER/actions-runner-controller VERSION=dev \
|
# This sets `VERSION` envvar to some appropriate value
|
||||||
|
. hack/make-env.sh
|
||||||
|
|
||||||
|
NAME=$DOCKER_USER/actions-runner-controller \
|
||||||
GITHUB_TOKEN=*** \
|
GITHUB_TOKEN=*** \
|
||||||
APP_ID=*** \
|
APP_ID=*** \
|
||||||
PRIVATE_KEY_FILE_PATH=path/to/pem/file \
|
PRIVATE_KEY_FILE_PATH=path/to/pem/file \
|
||||||
@@ -474,6 +503,19 @@ The test creates a one-off `kind` cluster, deploys `cert-manager` and `actions-r
|
|||||||
creates a `RunnerDeployment` custom resource for a public Git repository to confirm that the
|
creates a `RunnerDeployment` custom resource for a public Git repository to confirm that the
|
||||||
controller is able to bring up a runner pod with the actions runner registration token installed.
|
controller is able to bring up a runner pod with the actions runner registration token installed.
|
||||||
|
|
||||||
|
If you prefer to test in a non-kind cluster, you can instead run:
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
KUBECONFIG=path/to/kubeconfig \
|
||||||
|
NAME=$DOCKER_USER/actions-runner-controller \
|
||||||
|
GITHUB_TOKEN=*** \
|
||||||
|
APP_ID=*** \
|
||||||
|
PRIVATE_KEY_FILE_PATH=path/to/pem/file \
|
||||||
|
INSTALLATION_ID=*** \
|
||||||
|
ACCEPTANCE_TEST_SECRET_TYPE=token \
|
||||||
|
make docker-build docker-push \
|
||||||
|
acceptance/setup acceptance/tests
|
||||||
|
```
|
||||||
# Alternatives
|
# Alternatives
|
||||||
|
|
||||||
The following is a list of alternative solutions that may better fit you depending on your use-case:
|
The following is a list of alternative solutions that may better fit you depending on your use-case:
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ echo Found pod ${pod_name}.
|
|||||||
|
|
||||||
echo Waiting for pod ${runner_name} to become ready... 1>&2
|
echo Waiting for pod ${runner_name} to become ready... 1>&2
|
||||||
|
|
||||||
kubectl wait pod/${runner_name} --for condition=ready --timeout 120s
|
kubectl wait pod/${runner_name} --for condition=ready --timeout 180s
|
||||||
|
|
||||||
echo All tests passed. 1>&2
|
echo All tests passed. 1>&2
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ else
|
|||||||
kubectl apply \
|
kubectl apply \
|
||||||
-n actions-runner-system \
|
-n actions-runner-system \
|
||||||
-f release/actions-runner-controller.yaml
|
-f release/actions-runner-controller.yaml
|
||||||
kubectl -n actions-runner-system wait deploy/controller-manager --for condition=available
|
kubectl -n actions-runner-system wait deploy/controller-manager --for condition=available --timeout 60s
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Adhocly wait for some time until actions-runner-controller's admission webhook gets ready
|
# Adhocly wait for some time until actions-runner-controller's admission webhook gets ready
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ spec:
|
|||||||
serviceAccountName: {{ include "actions-runner-controller.serviceAccountName" . }}
|
serviceAccountName: {{ include "actions-runner-controller.serviceAccountName" . }}
|
||||||
securityContext:
|
securityContext:
|
||||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
{{- with .Values.priorityClassName }}
|
||||||
|
priorityClassName: "{{ . }}"
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
- args:
|
- args:
|
||||||
- "--metrics-addr=127.0.0.1:8080"
|
- "--metrics-addr=127.0.0.1:8080"
|
||||||
|
|||||||
@@ -79,3 +79,8 @@ nodeSelector: {}
|
|||||||
tolerations: []
|
tolerations: []
|
||||||
|
|
||||||
affinity: {}
|
affinity: {}
|
||||||
|
|
||||||
|
# Leverage a PriorityClass to ensure your pods survive resource shortages
|
||||||
|
# ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
|
||||||
|
# PriorityClass: system-cluster-critical
|
||||||
|
priorityClassName: ""
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"github.com/summerwind/actions-runner-controller/hash"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
@@ -39,6 +39,8 @@ import (
|
|||||||
const (
|
const (
|
||||||
containerName = "runner"
|
containerName = "runner"
|
||||||
finalizerName = "runner.actions.summerwind.dev"
|
finalizerName = "runner.actions.summerwind.dev"
|
||||||
|
|
||||||
|
LabelKeyPodTemplateHash = "pod-template-hash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunnerReconciler reconciles a Runner object
|
// RunnerReconciler reconciles a Runner object
|
||||||
@@ -198,14 +200,21 @@ func (r *RunnerReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !runnerBusy && (!reflect.DeepEqual(pod.Spec.Containers[0].Env, newPod.Spec.Containers[0].Env) || pod.Spec.Containers[0].Image != newPod.Spec.Containers[0].Image) {
|
// See the `newPod` function called above for more information
|
||||||
|
// about when this hash changes.
|
||||||
|
curHash := pod.Labels[LabelKeyPodTemplateHash]
|
||||||
|
newHash := newPod.Labels[LabelKeyPodTemplateHash]
|
||||||
|
|
||||||
|
if !runnerBusy && curHash != newHash {
|
||||||
restart = true
|
restart = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't do anything if there's no need to restart the runner
|
||||||
if !restart {
|
if !restart {
|
||||||
return ctrl.Result{}, err
|
return ctrl.Result{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete current pod if recreation is needed
|
||||||
if err := r.Delete(ctx, &pod); err != nil {
|
if err := r.Delete(ctx, &pod); err != nil {
|
||||||
log.Error(err, "Failed to delete pod resource")
|
log.Error(err, "Failed to delete pod resource")
|
||||||
return ctrl.Result{}, err
|
return ctrl.Result{}, err
|
||||||
@@ -357,11 +366,44 @@ func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
env = append(env, runner.Spec.Env...)
|
env = append(env, runner.Spec.Env...)
|
||||||
|
|
||||||
|
labels := map[string]string{}
|
||||||
|
|
||||||
|
for k, v := range runner.Labels {
|
||||||
|
labels[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// This implies that...
|
||||||
|
//
|
||||||
|
// (1) We recreate the runner pod whenever the runner has changes in:
|
||||||
|
// - metadata.labels (excluding "runner-template-hash" added by the parent RunnerReplicaSet
|
||||||
|
// - metadata.annotations
|
||||||
|
// - metadata.spec (including image, env, organization, repository, group, and so on)
|
||||||
|
// - GithubBaseURL setting of the controller (can be configured via GITHUB_ENTERPRISE_URL)
|
||||||
|
//
|
||||||
|
// (2) We don't recreate the runner pod when there are changes in:
|
||||||
|
// - runner.status.registration.token
|
||||||
|
// - This token expires and changes hourly, but you don't need to recreate the pod due to that.
|
||||||
|
// It's the opposite.
|
||||||
|
// An unexpired token is required only when the runner agent is registering itself on launch.
|
||||||
|
//
|
||||||
|
// In other words, the registered runner doesn't get invalidated on registration token expiration.
|
||||||
|
// A registered runner's session and the a registration token seem to have two different and independent
|
||||||
|
// lifecycles.
|
||||||
|
//
|
||||||
|
// See https://github.com/summerwind/actions-runner-controller/issues/143 for more context.
|
||||||
|
labels[LabelKeyPodTemplateHash] = hash.FNVHashStringObjects(
|
||||||
|
filterLabels(runner.Labels, LabelKeyRunnerTemplateHash),
|
||||||
|
runner.Annotations,
|
||||||
|
runner.Spec,
|
||||||
|
r.GitHubClient.GithubBaseURL,
|
||||||
|
)
|
||||||
|
|
||||||
pod := corev1.Pod{
|
pod := corev1.Pod{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: runner.Name,
|
Name: runner.Name,
|
||||||
Namespace: runner.Namespace,
|
Namespace: runner.Namespace,
|
||||||
Labels: runner.Labels,
|
Labels: labels,
|
||||||
Annotations: runner.Annotations,
|
Annotations: runner.Annotations,
|
||||||
},
|
},
|
||||||
Spec: corev1.PodSpec{
|
Spec: corev1.PodSpec{
|
||||||
@@ -397,6 +439,12 @@ func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) {
|
|||||||
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "certs-client",
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
pod.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{
|
pod.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{
|
||||||
{
|
{
|
||||||
@@ -407,11 +455,26 @@ func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) {
|
|||||||
Name: "externals",
|
Name: "externals",
|
||||||
MountPath: "/runner/externals",
|
MountPath: "/runner/externals",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "certs-client",
|
||||||
|
MountPath: "/certs/client",
|
||||||
|
ReadOnly: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, corev1.EnvVar{
|
pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, []corev1.EnvVar{
|
||||||
|
{
|
||||||
Name: "DOCKER_HOST",
|
Name: "DOCKER_HOST",
|
||||||
Value: "tcp://localhost:2375",
|
Value: "tcp://localhost:2376",
|
||||||
})
|
},
|
||||||
|
{
|
||||||
|
Name: "DOCKER_TLS_VERIFY",
|
||||||
|
Value: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "DOCKER_CERT_PATH",
|
||||||
|
Value: "/certs/client",
|
||||||
|
},
|
||||||
|
}...)
|
||||||
pod.Spec.Containers = append(pod.Spec.Containers, corev1.Container{
|
pod.Spec.Containers = append(pod.Spec.Containers, corev1.Container{
|
||||||
Name: "docker",
|
Name: "docker",
|
||||||
Image: r.DockerImage,
|
Image: r.DockerImage,
|
||||||
@@ -424,11 +487,15 @@ func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) {
|
|||||||
Name: "externals",
|
Name: "externals",
|
||||||
MountPath: "/runner/externals",
|
MountPath: "/runner/externals",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "certs-client",
|
||||||
|
MountPath: "/certs/client",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Env: []corev1.EnvVar{
|
Env: []corev1.EnvVar{
|
||||||
{
|
{
|
||||||
Name: "DOCKER_TLS_CERTDIR",
|
Name: "DOCKER_TLS_CERTDIR",
|
||||||
Value: "",
|
Value: "/certs",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
SecurityContext: &corev1.SecurityContext{
|
SecurityContext: &corev1.SecurityContext{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-github/v32/github"
|
"github.com/google/go-github/v33/github"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
|
|||||||
13
controllers/utils.go
Normal file
13
controllers/utils.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
func filterLabels(labels map[string]string, filter string) map[string]string {
|
||||||
|
filtered := map[string]string{}
|
||||||
|
|
||||||
|
for k, v := range labels {
|
||||||
|
if k != filter {
|
||||||
|
filtered[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered
|
||||||
|
}
|
||||||
34
controllers/utils_test.go
Normal file
34
controllers/utils_test.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_filterLabels(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
labels map[string]string
|
||||||
|
filter string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want map[string]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ok",
|
||||||
|
args: args{
|
||||||
|
labels: map[string]string{LabelKeyRunnerTemplateHash: "abc", LabelKeyPodTemplateHash: "def"},
|
||||||
|
filter: LabelKeyRunnerTemplateHash,
|
||||||
|
},
|
||||||
|
want: map[string]string{LabelKeyPodTemplateHash: "def"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := filterLabels(tt.args.labels, tt.args.filter); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("filterLabels() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/google/go-github/v32/github"
|
"github.com/google/go-github/v33/github"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bradleyfalzon/ghinstallation"
|
"github.com/bradleyfalzon/ghinstallation"
|
||||||
"github.com/google/go-github/v32/github"
|
"github.com/google/go-github/v33/github"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,6 +32,7 @@ type Client struct {
|
|||||||
GithubBaseURL string
|
GithubBaseURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewClient creates a Github Client
|
||||||
func (c *Config) NewClient() (*Client, error) {
|
func (c *Config) NewClient() (*Client, error) {
|
||||||
var (
|
var (
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
@@ -84,7 +85,7 @@ func (c *Client) GetRegistrationToken(ctx context.Context, org, repo, name strin
|
|||||||
key := getRegistrationKey(org, repo)
|
key := getRegistrationKey(org, repo)
|
||||||
rt, ok := c.regTokens[key]
|
rt, ok := c.regTokens[key]
|
||||||
|
|
||||||
if ok && rt.GetExpiresAt().After(time.Now().Add(-10*time.Minute)) {
|
if ok && rt.GetExpiresAt().After(time.Now()) {
|
||||||
return rt, nil
|
return rt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,25 +180,25 @@ func (c *Client) cleanup() {
|
|||||||
func (c *Client) createRegistrationToken(ctx context.Context, owner, repo string) (*github.RegistrationToken, *github.Response, error) {
|
func (c *Client) createRegistrationToken(ctx context.Context, owner, repo string) (*github.RegistrationToken, *github.Response, error) {
|
||||||
if len(repo) > 0 {
|
if len(repo) > 0 {
|
||||||
return c.Client.Actions.CreateRegistrationToken(ctx, owner, repo)
|
return c.Client.Actions.CreateRegistrationToken(ctx, owner, repo)
|
||||||
} else {
|
|
||||||
return CreateOrganizationRegistrationToken(ctx, c, owner)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CreateOrganizationRegistrationToken(ctx, c, owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) removeRunner(ctx context.Context, owner, repo string, runnerID int64) (*github.Response, error) {
|
func (c *Client) removeRunner(ctx context.Context, owner, repo string, runnerID int64) (*github.Response, error) {
|
||||||
if len(repo) > 0 {
|
if len(repo) > 0 {
|
||||||
return c.Client.Actions.RemoveRunner(ctx, owner, repo, runnerID)
|
return c.Client.Actions.RemoveRunner(ctx, owner, repo, runnerID)
|
||||||
} else {
|
|
||||||
return RemoveOrganizationRunner(ctx, c, owner, runnerID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return RemoveOrganizationRunner(ctx, c, owner, runnerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) listRunners(ctx context.Context, owner, repo string, opts *github.ListOptions) (*github.Runners, *github.Response, error) {
|
func (c *Client) listRunners(ctx context.Context, owner, repo string, opts *github.ListOptions) (*github.Runners, *github.Response, error) {
|
||||||
if len(repo) > 0 {
|
if len(repo) > 0 {
|
||||||
return c.Client.Actions.ListRunners(ctx, owner, repo, opts)
|
return c.Client.Actions.ListRunners(ctx, owner, repo, opts)
|
||||||
} else {
|
|
||||||
return ListOrganizationRunners(ctx, c, owner, opts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ListOrganizationRunners(ctx, c, owner, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validates owner and repo arguments. Both are optional, but at least one should be specified
|
// Validates owner and repo arguments. Both are optional, but at least one should be specified
|
||||||
@@ -214,9 +215,8 @@ func getOwnerAndRepo(org, repo string) (string, string, error) {
|
|||||||
func getRegistrationKey(org, repo string) string {
|
func getRegistrationKey(org, repo string) string {
|
||||||
if len(org) > 0 {
|
if len(org) > 0 {
|
||||||
return org
|
return org
|
||||||
} else {
|
|
||||||
return repo
|
|
||||||
}
|
}
|
||||||
|
return repo
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitOwnerAndRepo(repo string) (string, string, error) {
|
func splitOwnerAndRepo(repo string) (string, string, error) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/google/go-github/v32/github"
|
"github.com/google/go-github/v33/github"
|
||||||
"github.com/google/go-querystring/query"
|
"github.com/google/go-querystring/query"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-github/v32/github"
|
"github.com/google/go-github/v33/github"
|
||||||
"github.com/summerwind/actions-runner-controller/github/fake"
|
"github.com/summerwind/actions-runner-controller/github/fake"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -6,7 +6,9 @@ require (
|
|||||||
github.com/bradleyfalzon/ghinstallation v1.1.1
|
github.com/bradleyfalzon/ghinstallation v1.1.1
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/go-logr/logr v0.1.0
|
github.com/go-logr/logr v0.1.0
|
||||||
|
github.com/google/go-github v17.0.0+incompatible // indirect
|
||||||
github.com/google/go-github/v32 v32.1.1-0.20200822031813-d57a3a84ba04
|
github.com/google/go-github/v32 v32.1.1-0.20200822031813-d57a3a84ba04
|
||||||
|
github.com/google/go-github/v33 v33.0.0
|
||||||
github.com/google/go-querystring v1.0.0
|
github.com/google/go-querystring v1.0.0
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/kelseyhightower/envconfig v1.4.0
|
github.com/kelseyhightower/envconfig v1.4.0
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -116,10 +116,14 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
|||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||||
|
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||||
github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU8N8Pts=
|
github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU8N8Pts=
|
||||||
github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
|
github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
|
||||||
github.com/google/go-github/v32 v32.1.1-0.20200822031813-d57a3a84ba04 h1:wEYk2h/GwOhImcVjiTIceP88WxVbXw2F+ARYUQMEsfg=
|
github.com/google/go-github/v32 v32.1.1-0.20200822031813-d57a3a84ba04 h1:wEYk2h/GwOhImcVjiTIceP88WxVbXw2F+ARYUQMEsfg=
|
||||||
github.com/google/go-github/v32 v32.1.1-0.20200822031813-d57a3a84ba04/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
github.com/google/go-github/v32 v32.1.1-0.20200822031813-d57a3a84ba04/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||||
|
github.com/google/go-github/v33 v33.0.0 h1:qAf9yP0qc54ufQxzwv+u9H0tiVOnPJxo0lI/JXqw3ZM=
|
||||||
|
github.com/google/go-github/v33 v33.0.0/go.mod h1:GMdDnVZY/2TsWgp/lkYnpSAh6TrzhANBBwm6k6TTEXg=
|
||||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||||
|
|||||||
19
hack/make-env.sh
Executable file
19
hack/make-env.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
COMMIT=$(git rev-parse HEAD)
|
||||||
|
TAG=$(git describe --exact-match --abbrev=0 --tags "${COMMIT}" 2> /dev/null || true)
|
||||||
|
BRANCH=$(git branch | grep \* | cut -d ' ' -f2 | sed -e 's/[^a-zA-Z0-9+=._:/-]*//g' || true)
|
||||||
|
VERSION=""
|
||||||
|
|
||||||
|
if [ -z "$TAG" ]; then
|
||||||
|
[[ -n "$BRANCH" ]] && VERSION="${BRANCH}-"
|
||||||
|
VERSION="${VERSION}${COMMIT:0:8}"
|
||||||
|
else
|
||||||
|
VERSION=$TAG
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$(git diff --shortstat 2> /dev/null | tail -n1)" ]; then
|
||||||
|
VERSION="${VERSION}-dirty"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export VERSION
|
||||||
17
hash/fnv.go
Normal file
17
hash/fnv.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package hash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
|
"k8s.io/apimachinery/pkg/util/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FNVHashStringObjects(objs ...interface{}) string {
|
||||||
|
hash := fnv.New32a()
|
||||||
|
|
||||||
|
for _, obj := range objs {
|
||||||
|
DeepHashObject(hash, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rand.SafeEncodeString(fmt.Sprint(hash.Sum32()))
|
||||||
|
}
|
||||||
25
hash/hash.go
Normal file
25
hash/hash.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2015 The Kubernetes Authors.
|
||||||
|
// hash.go is copied from kubernetes's pkg/util/hash.go
|
||||||
|
// See https://github.com/kubernetes/kubernetes/blob/e1c617a88ec286f5f6cb2589d6ac562d095e1068/pkg/util/hash/hash.go#L25-L37
|
||||||
|
|
||||||
|
package hash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeepHashObject writes specified object to hash using the spew library
|
||||||
|
// which follows pointers and prints actual values of the nested objects
|
||||||
|
// ensuring the hash does not change when a pointer changes.
|
||||||
|
func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) {
|
||||||
|
hasher.Reset()
|
||||||
|
printer := spew.ConfigState{
|
||||||
|
Indent: " ",
|
||||||
|
SortKeys: true,
|
||||||
|
DisableMethods: true,
|
||||||
|
SpewKeys: true,
|
||||||
|
}
|
||||||
|
printer.Fprintf(hasher, "%#v", objectToWrite)
|
||||||
|
}
|
||||||
@@ -56,6 +56,10 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
|||||||
&& echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers
|
&& echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers
|
||||||
|
|
||||||
# Runner download supports amd64 as x64. Externalstmp is needed for making mount points work inside DinD.
|
# Runner download supports amd64 as x64. Externalstmp is needed for making mount points work inside DinD.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
||||||
&& if [ "$ARCH" = "amd64" ]; then export ARCH=x64 ; fi \
|
&& if [ "$ARCH" = "amd64" ]; then export ARCH=x64 ; fi \
|
||||||
&& mkdir -p /runner \
|
&& mkdir -p /runner \
|
||||||
@@ -65,8 +69,14 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
|||||||
&& rm runner.tar.gz \
|
&& rm runner.tar.gz \
|
||||||
&& ./bin/installdependencies.sh \
|
&& ./bin/installdependencies.sh \
|
||||||
&& mv ./externals ./externalstmp \
|
&& mv ./externals ./externalstmp \
|
||||||
|
&& apt-get install -y libyaml-dev \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN echo AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache > /runner.env \
|
||||||
|
&& mkdir /opt/hostedtoolcache \
|
||||||
|
&& chgrp runner /opt/hostedtoolcache \
|
||||||
|
&& chmod g+rwx /opt/hostedtoolcache
|
||||||
|
|
||||||
COPY entrypoint.sh /runner
|
COPY entrypoint.sh /runner
|
||||||
COPY patched /runner/patched
|
COPY patched /runner/patched
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
|||||||
docker --version
|
docker --version
|
||||||
|
|
||||||
# Runner download supports amd64 as x64
|
# Runner download supports amd64 as x64
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
||||||
&& if [ "$ARCH" = "amd64" ]; then export ARCH=x64 ; fi \
|
&& if [ "$ARCH" = "amd64" ]; then export ARCH=x64 ; fi \
|
||||||
&& mkdir -p /runner \
|
&& mkdir -p /runner \
|
||||||
@@ -75,8 +79,13 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
|||||||
&& tar xzf ./runner.tar.gz \
|
&& tar xzf ./runner.tar.gz \
|
||||||
&& rm runner.tar.gz \
|
&& rm runner.tar.gz \
|
||||||
&& ./bin/installdependencies.sh \
|
&& ./bin/installdependencies.sh \
|
||||||
|
&& apt-get install -y libyaml-dev \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN echo AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache > /runner.env \
|
||||||
|
&& mkdir /opt/hostedtoolcache \
|
||||||
|
&& chgrp runner /opt/hostedtoolcache \
|
||||||
|
&& chmod g+rwx /opt/hostedtoolcache
|
||||||
|
|
||||||
COPY modprobe startup.sh /usr/local/bin/
|
COPY modprobe startup.sh /usr/local/bin/
|
||||||
COPY supervisor/ /etc/supervisor/conf.d/
|
COPY supervisor/ /etc/supervisor/conf.d/
|
||||||
|
|||||||
Reference in New Issue
Block a user