mirror of
https://github.com/actions/actions-runner-controller.git
synced 2025-12-10 11:41:27 +00:00
Compare commits
94 Commits
actions-ru
...
actions-ru
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
360957cfbc | ||
|
|
e1fcd63f92 | ||
|
|
461c016b98 | ||
|
|
2e406e3aef | ||
|
|
044c8ad4d5 | ||
|
|
eaa451df32 | ||
|
|
ab04a2b616 | ||
|
|
d32319be50 | ||
|
|
057b04763f | ||
|
|
bc4f4fee12 | ||
|
|
a6c4d84234 | ||
|
|
e71c64683b | ||
|
|
4aadc7d128 | ||
|
|
45ebcb1c0a | ||
|
|
3ede9b5a01 | ||
|
|
84104de74b | ||
|
|
aa6dab5a9a | ||
|
|
086f9fd2d6 | ||
|
|
2407e4f6c6 | ||
|
|
fc23b7d08e | ||
|
|
85ec00a5a5 | ||
|
|
03d4784518 | ||
|
|
dcfacf4f1e | ||
|
|
02d84575e2 | ||
|
|
3021be73c7 | ||
|
|
adb5bc9f66 | ||
|
|
466be710ee | ||
|
|
acbce4b70a | ||
|
|
418f719bdf | ||
|
|
300e93c59d | ||
|
|
0285da1a32 | ||
|
|
b8e5185fef | ||
|
|
187479f08c | ||
|
|
31244dd61b | ||
|
|
a8417ec67e | ||
|
|
775dc60c94 | ||
|
|
ecd7531917 | ||
|
|
ad1989072e | ||
|
|
fe05987eea | ||
|
|
bd392c3665 | ||
|
|
58d80a7c12 | ||
|
|
212b9daec3 | ||
|
|
28ea8d4e7b | ||
|
|
c1fb793773 | ||
|
|
63d2cbfdaa | ||
|
|
18077a1e83 | ||
|
|
3ae9f09532 | ||
|
|
96a930bfd9 | ||
|
|
877c93c5c3 | ||
|
|
95c324b550 | ||
|
|
5e8f576f65 | ||
|
|
cc15ff0119 | ||
|
|
8318523627 | ||
|
|
fcb65b046b | ||
|
|
87f566e1e6 | ||
|
|
a786dae450 | ||
|
|
666ce8f917 | ||
|
|
9ba4b6b96a | ||
|
|
ae86b1a011 | ||
|
|
154fcde7d0 | ||
|
|
86d7893d61 | ||
|
|
8f374d561f | ||
|
|
40eec3c783 | ||
|
|
0c4798b773 | ||
|
|
7680cfd371 | ||
|
|
3b1771385f | ||
|
|
cb288fc99b | ||
|
|
7c81c2eec1 | ||
|
|
0908715786 | ||
|
|
186c98cf36 | ||
|
|
d328c61fc3 | ||
|
|
61d1235d2a | ||
|
|
3b36a81db6 | ||
|
|
fbdfe0df8c | ||
|
|
63e8f32281 | ||
|
|
2ac48038c6 | ||
|
|
23c8fe4a8b | ||
|
|
8505c95719 | ||
|
|
3de8085b87 | ||
|
|
828d51baf2 | ||
|
|
0b0219b88f | ||
|
|
362b6c10a3 | ||
|
|
2110fa5122 | ||
|
|
9eae9ac75f | ||
|
|
9bb416084b | ||
|
|
fdb049ba1e | ||
|
|
5f27548a73 | ||
|
|
f7fb1490dc | ||
|
|
9d48c791f5 | ||
|
|
371eff09ce | ||
|
|
cfad7a9b08 | ||
|
|
6234c568bd | ||
|
|
3ae3811944 | ||
|
|
c74ad6195f |
10
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
10
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Bug Report
|
||||
description: File a bug report
|
||||
title: "<Please write what didn't work for you here>"
|
||||
labels: ["bug"]
|
||||
labels: ["bug", "needs triage"]
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: read-troubleshooting-guide
|
||||
@@ -9,7 +9,7 @@ body:
|
||||
label: Checks
|
||||
description: Please check all the boxes below before submitting
|
||||
options:
|
||||
- label: I've already read https://github.com/actions-runner-controller/actions-runner-controller/blob/master/TROUBLESHOOTING.md and I'm sure my issue is not covered in the troubleshooting guide.
|
||||
- label: I've already read https://github.com/actions/actions-runner-controller/blob/master/TROUBLESHOOTING.md and I'm sure my issue is not covered in the troubleshooting guide.
|
||||
required: true
|
||||
- label: I'm not using a custom entrypoint in my runner image
|
||||
required: true
|
||||
@@ -51,7 +51,7 @@ body:
|
||||
label: cert-manager installation
|
||||
description: Confirm that you've installed cert-manager correctly by answering a few questions
|
||||
placeholder: |
|
||||
- Did you follow https://github.com/actions-runner-controller/actions-runner-controller#installation? If not, describe the installation process so that we can reproduce your environment.
|
||||
- Did you follow https://github.com/actions/actions-runner-controller#installation? If not, describe the installation process so that we can reproduce your environment.
|
||||
- Are you sure you've installed cert-manager from an official source?
|
||||
(Note that we won't provide user support for cert-manager itself. Make sure cert-manager is fully working before testing ARC or reporting a bug
|
||||
validations:
|
||||
@@ -62,9 +62,9 @@ body:
|
||||
label: Checks
|
||||
description: Please check all the boxes below before submitting
|
||||
options:
|
||||
- label: This isn't a question or user support case (For Q&A and community support, go to [Discussions](https://github.com/actions-runner-controller/actions-runner-controller/discussions). It might also be a good idea to contract with any of contributors and maintainers if your business is so critical and therefore you need priority support
|
||||
- label: This isn't a question or user support case (For Q&A and community support, go to [Discussions](https://github.com/actions/actions-runner-controller/discussions). It might also be a good idea to contract with any of contributors and maintainers if your business is so critical and therefore you need priority support
|
||||
required: true
|
||||
- label: I've read [releasenotes](https://github.com/actions-runner-controller/actions-runner-controller/tree/master/docs/releasenotes) before submitting this issue and I'm sure it's not due to any recently-introduced backward-incompatible changes
|
||||
- label: I've read [releasenotes](https://github.com/actions/actions-runner-controller/tree/master/docs/releasenotes) before submitting this issue and I'm sure it's not due to any recently-introduced backward-incompatible changes
|
||||
required: true
|
||||
- label: My actions-runner-controller version (v0.x.y) does support the feature
|
||||
required: true
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
8
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -2,13 +2,13 @@ blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Sponsor ARC Maintainers
|
||||
about: If your business relies on the continued maintainance of actions-runner-controller, please consider sponsoring the project and the maintainers.
|
||||
url: https://github.com/actions-runner-controller/actions-runner-controller/tree/master/CODEOWNERS
|
||||
url: https://github.com/actions/actions-runner-controller/tree/master/CODEOWNERS
|
||||
- name: Ideas and Feature Requests
|
||||
about: Wanna request a feature? Create a discussion and collect :+1:s first.
|
||||
url: https://github.com/actions-runner-controller/actions-runner-controller/discussions/new?category=ideas
|
||||
url: https://github.com/actions/actions-runner-controller/discussions/new?category=ideas
|
||||
- name: Questions and User Support
|
||||
about: Need support using ARC? We use Discussions as the place to provide community support.
|
||||
url: https://github.com/actions-runner-controller/actions-runner-controller/discussions/new?category=questions
|
||||
url: https://github.com/actions/actions-runner-controller/discussions/new?category=questions
|
||||
- name: Need Paid Support?
|
||||
about: Consider contracting with any of the actions-runner-controller maintainers and contributors.
|
||||
url: https://github.com/actions-runner-controller/actions-runner-controller/tree/master/CODEOWNERS
|
||||
url: https://github.com/actions/actions-runner-controller/tree/master/CODEOWNERS
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
labels: enhancement
|
||||
labels: ["enhancement", "needs triage"]
|
||||
title: ''
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
@@ -14,18 +14,13 @@ inputs:
|
||||
description: "GHCR password. Usually set from the secrets.GITHUB_TOKEN variable"
|
||||
required: true
|
||||
|
||||
outputs:
|
||||
sha_short:
|
||||
description: "The short SHA used for image builds"
|
||||
value: ${{ steps.vars.outputs.sha_short }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Get Short SHA
|
||||
id: vars
|
||||
run: |
|
||||
echo ::set-output name=sha_short::${GITHUB_SHA::7}
|
||||
echo "sha_short=${GITHUB_SHA::7}" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
|
||||
- name: Set up QEMU
|
||||
@@ -37,14 +32,14 @@ runs:
|
||||
version: latest
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: ${{ github.event_name == 'release' || github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
if: ${{ github.event_name == 'release' || github.event_name == 'push' && github.ref == 'refs/heads/master' && inputs.password != '' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ inputs.username }}
|
||||
password: ${{ inputs.password }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: ${{ github.event_name == 'release' || github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
if: ${{ github.event_name == 'release' || github.event_name == 'push' && github.ref == 'refs/heads/master' && inputs.ghcr_password != '' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
|
||||
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gomod" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
7
.github/renovate.json5
vendored
7
.github/renovate.json5
vendored
@@ -30,9 +30,10 @@
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"runner/actions-runner.dockerfile",
|
||||
"runner/actions-runner-dind.dockerfile",
|
||||
"runner/actions-runner-dind-rootless.dockerfile"
|
||||
"runner/actions-runner.ubuntu-20.04.dockerfile",
|
||||
"runner/actions-runner.ubuntu-22.04.dockerfile",
|
||||
"runner/actions-runner-dind.ubuntu-20.04.dockerfile",
|
||||
"runner/actions-runner-dind-rootless.ubuntu-20.04.dockerfile"
|
||||
],
|
||||
"matchStrings": ["RUNNER_VERSION=+(?<currentValue>.*?)\\n"],
|
||||
"depNameTemplate": "actions/runner",
|
||||
|
||||
86
.github/workflows/publish-arc.yaml
vendored
86
.github/workflows/publish-arc.yaml
vendored
@@ -1,21 +1,34 @@
|
||||
name: Publish ARC
|
||||
|
||||
# Revert to https://github.com/actions-runner-controller/releases#releases
|
||||
# for details on why we use this approach
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_tag_name:
|
||||
description: 'Tag name of the release to publish'
|
||||
required: true
|
||||
push_to_registries:
|
||||
description: 'Push images to registries'
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
# https://docs.github.com/en/rest/overview/permissions-required-for-github-apps
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
env:
|
||||
TARGET_ORG: actions-runner-controller
|
||||
TARGET_REPO: actions-runner-controller
|
||||
|
||||
jobs:
|
||||
release-controller:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USER }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -35,8 +48,14 @@ jobs:
|
||||
tar zxvf ghr_v0.13.0_linux_amd64.tar.gz
|
||||
sudo mv ghr_v0.13.0_linux_amd64/ghr /usr/local/bin
|
||||
|
||||
- name: Set version
|
||||
run: echo "VERSION=$(cat ${GITHUB_EVENT_PATH} | jq -r '.release.tag_name')" >> $GITHUB_ENV
|
||||
- name: Set version env variable
|
||||
run: |
|
||||
# Define the release tag name based on the event type
|
||||
if [[ "${{ github.event_name }}" == "release" ]]; then
|
||||
echo "VERSION=$(cat ${GITHUB_EVENT_PATH} | jq -r '.release.tag_name')" >> $GITHUB_ENV
|
||||
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
echo "VERSION=${{ inputs.release_tag_name }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Upload artifacts
|
||||
env:
|
||||
@@ -44,28 +63,39 @@ jobs:
|
||||
run: |
|
||||
make github-release
|
||||
|
||||
- name: Setup Docker Environment
|
||||
id: vars
|
||||
uses: ./.github/actions/setup-docker-environment
|
||||
- name: Get Token
|
||||
id: get_workflow_token
|
||||
uses: peter-murray/workflow-application-token-action@8e1ba3bf1619726336414f1014e37f17fbadf1db
|
||||
with:
|
||||
username: ${{ env.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
ghcr_username: ${{ github.actor }}
|
||||
ghcr_password: ${{ secrets.GITHUB_TOKEN }}
|
||||
application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }}
|
||||
application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }}
|
||||
organization: ${{ env.TARGET_ORG }}
|
||||
|
||||
- name: Build and Push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
file: Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
build-args: VERSION=${{ env.VERSION }}
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.DOCKERHUB_USERNAME }}/actions-runner-controller:latest
|
||||
${{ env.DOCKERHUB_USERNAME }}/actions-runner-controller:${{ env.VERSION }}
|
||||
${{ env.DOCKERHUB_USERNAME }}/actions-runner-controller:${{ env.VERSION }}-${{ steps.vars.outputs.sha_short }}
|
||||
ghcr.io/actions-runner-controller/actions-runner-controller:latest
|
||||
ghcr.io/actions-runner-controller/actions-runner-controller:${{ env.VERSION }}
|
||||
ghcr.io/actions-runner-controller/actions-runner-controller:${{ env.VERSION }}-${{ steps.vars.outputs.sha_short }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
- name: Resolve push to registries
|
||||
run: |
|
||||
# Define the push to registries based on the event type
|
||||
if [[ "${{ github.event_name }}" == "release" ]]; then
|
||||
echo "PUSH_TO_REGISTRIES=true" >> $GITHUB_ENV
|
||||
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
echo "PUSH_TO_REGISTRIES=${{ inputs.push_to_registries }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Trigger Build And Push Images To Registries
|
||||
run: |
|
||||
# Authenticate
|
||||
gh auth login --with-token <<< ${{ steps.get_workflow_token.outputs.token }}
|
||||
|
||||
# Trigger the workflow run
|
||||
jq -n '{"event_type": "arc", "client_payload": {"release_tag_name": "${{ env.VERSION }}", "push_to_registries": "${{ env.PUSH_TO_REGISTRIES }}" }}' \
|
||||
| gh api -X POST /repos/actions-runner-controller/releases/dispatches --input -
|
||||
|
||||
- name: Job summary
|
||||
run: |
|
||||
echo "The [publish-arc](https://github.com/actions-runner-controller/releases/blob/main/.github/workflows/publish-arc.yaml) workflow has been triggered!" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Parameters:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Release tag: ${{ env.VERSION }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Push to registries: ${{ env.PUSH_TO_REGISTRIES }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Status:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[https://github.com/actions-runner-controller/releases/actions/workflows/publish-arc.yaml](https://github.com/actions-runner-controller/releases/actions/workflows/publish-arc.yaml)" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
57
.github/workflows/publish-canary.yaml
vendored
57
.github/workflows/publish-canary.yaml
vendored
@@ -1,5 +1,7 @@
|
||||
name: Publish Canary Image
|
||||
|
||||
# Revert to https://github.com/actions-runner-controller/releases#releases
|
||||
# for details on why we use this approach
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -19,41 +21,50 @@ on:
|
||||
- 'LICENSE'
|
||||
- 'Makefile'
|
||||
|
||||
env:
|
||||
# Safeguard to prevent pushing images to registeries after build
|
||||
PUSH_TO_REGISTRIES: true
|
||||
TARGET_ORG: actions-runner-controller
|
||||
TARGET_REPO: actions-runner-controller
|
||||
|
||||
# https://docs.github.com/en/rest/overview/permissions-required-for-github-apps
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
canary-build:
|
||||
name: Build and Publish Canary Image
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USER }}
|
||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Docker Environment
|
||||
id: vars
|
||||
uses: ./.github/actions/setup-docker-environment
|
||||
- name: Get Token
|
||||
id: get_workflow_token
|
||||
uses: peter-murray/workflow-application-token-action@8e1ba3bf1619726336414f1014e37f17fbadf1db
|
||||
with:
|
||||
username: ${{ env.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
ghcr_username: ${{ github.actor }}
|
||||
ghcr_password: ${{ secrets.GITHUB_TOKEN }}
|
||||
application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }}
|
||||
application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }}
|
||||
organization: ${{ env.TARGET_ORG }}
|
||||
|
||||
# Considered unstable builds
|
||||
# See Issue #285, PR #286, and PR #323 for more information
|
||||
- name: Build and Push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
file: Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
build-args: VERSION=canary-${{ github.sha }}
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.DOCKERHUB_USERNAME }}/actions-runner-controller:canary
|
||||
ghcr.io/${{ github.repository }}:canary
|
||||
cache-from: type=gha,scope=arc-canary
|
||||
cache-to: type=gha,mode=max,scope=arc-canary
|
||||
- name: Trigger Build And Push Images To Registries
|
||||
run: |
|
||||
# Authenticate
|
||||
gh auth login --with-token <<< ${{ steps.get_workflow_token.outputs.token }}
|
||||
|
||||
# Trigger the workflow run
|
||||
jq -n '{"event_type": "canary", "client_payload": {"sha": "${{ github.sha }}", "push_to_registries": ${{ env.PUSH_TO_REGISTRIES }}}}' \
|
||||
| gh api -X POST /repos/actions-runner-controller/releases/dispatches --input -
|
||||
|
||||
- name: Job summary
|
||||
run: |
|
||||
echo "The [publish-canary](https://github.com/actions-runner-controller/releases/blob/main/.github/workflows/publish-canary.yaml) workflow has been triggered!" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Parameters:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- sha: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Push to registries: ${{ env.PUSH_TO_REGISTRIES }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Status:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[https://github.com/actions-runner-controller/releases/actions/workflows/publish-canary.yaml](https://github.com/actions-runner-controller/releases/actions/workflows/publish-canary.yaml)" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
100
.github/workflows/publish-chart.yaml
vendored
100
.github/workflows/publish-chart.yaml
vendored
@@ -1,5 +1,7 @@
|
||||
name: Publish Helm Chart
|
||||
|
||||
# Revert to https://github.com/actions-runner-controller/releases#releases
|
||||
# for details on why we use this approach
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -31,7 +33,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v3.3
|
||||
uses: azure/setup-helm@v3.4
|
||||
with:
|
||||
version: ${{ env.HELM_VERSION }}
|
||||
|
||||
@@ -86,20 +88,31 @@ jobs:
|
||||
if: steps.list-changed.outputs.changed == 'true'
|
||||
run: ct install --config charts/.ci/ct-config.yaml
|
||||
|
||||
# WARNING: This relies on the latest release being inat the top of the JSON from GitHub and a clean chart.yaml
|
||||
# WARNING: This relies on the latest release being at the top of the JSON from GitHub and a clean chart.yaml
|
||||
- name: Check if Chart Publish is Needed
|
||||
id: publish-chart-step
|
||||
run: |
|
||||
CHART_TEXT=$(curl -fs https://raw.githubusercontent.com/actions-runner-controller/actions-runner-controller/master/charts/actions-runner-controller/Chart.yaml)
|
||||
CHART_TEXT=$(curl -fs https://raw.githubusercontent.com/${{ github.repository }}/master/charts/actions-runner-controller/Chart.yaml)
|
||||
NEW_CHART_VERSION=$(echo "$CHART_TEXT" | grep version: | cut -d ' ' -f 2)
|
||||
RELEASE_LIST=$(curl -fs https://api.github.com/repos/actions-runner-controller/actions-runner-controller/releases | jq .[].tag_name | grep actions-runner-controller | cut -d '"' -f 2 | cut -d '-' -f 4)
|
||||
RELEASE_LIST=$(curl -fs https://api.github.com/repos/${{ github.repository }}/releases | jq .[].tag_name | grep actions-runner-controller | cut -d '"' -f 2 | cut -d '-' -f 4)
|
||||
LATEST_RELEASED_CHART_VERSION=$(echo $RELEASE_LIST | cut -d ' ' -f 1)
|
||||
echo "Chart version in master : $NEW_CHART_VERSION"
|
||||
echo "Latest release chart version : $LATEST_RELEASED_CHART_VERSION"
|
||||
echo "CHART_VERSION_IN_MASTER=$NEW_CHART_VERSION" >> $GITHUB_ENV
|
||||
echo "LATEST_CHART_VERSION=$LATEST_RELEASED_CHART_VERSION" >> $GITHUB_ENV
|
||||
if [[ $NEW_CHART_VERSION != $LATEST_RELEASED_CHART_VERSION ]]; then
|
||||
echo "::set-output name=publish::true"
|
||||
echo "publish=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "publish=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Job summary
|
||||
run: |
|
||||
echo "Chart linting has been completed." >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Status:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- chart version in master: ${{ env.CHART_VERSION_IN_MASTER }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- latest chart version: ${{ env.LATEST_CHART_VERSION }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- publish new chart: ${{ steps.publish-chart-step.outputs.publish }}" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
publish-chart:
|
||||
if: needs.lint-chart.outputs.publish-chart == 'true'
|
||||
needs: lint-chart
|
||||
@@ -107,7 +120,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # for helm/chart-releaser-action to push chart release and create a release
|
||||
|
||||
env:
|
||||
CHART_TARGET_ORG: actions-runner-controller
|
||||
CHART_TARGET_REPO: actions-runner-controller.github.io
|
||||
CHART_TARGET_BRANCH: main
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -120,8 +136,68 @@ jobs:
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
|
||||
- name: Run chart-releaser
|
||||
uses: helm/chart-releaser-action@v1.4.1
|
||||
env:
|
||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: Get Token
|
||||
id: get_workflow_token
|
||||
uses: peter-murray/workflow-application-token-action@8e1ba3bf1619726336414f1014e37f17fbadf1db
|
||||
with:
|
||||
application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }}
|
||||
application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }}
|
||||
organization: ${{ env.CHART_TARGET_ORG }}
|
||||
|
||||
- name: Install chart-releaser
|
||||
uses: helm/chart-releaser-action@v1.4.1
|
||||
with:
|
||||
install_only: true
|
||||
install_dir: ${{ github.workspace }}/bin
|
||||
|
||||
- name: Package and upload release assets
|
||||
run: |
|
||||
cr package \
|
||||
${{ github.workspace }}/charts/actions-runner-controller/ \
|
||||
--package-path .cr-release-packages
|
||||
|
||||
cr upload \
|
||||
--owner "$(echo ${{ github.repository }} | cut -d '/' -f 1)" \
|
||||
--git-repo "$(echo ${{ github.repository }} | cut -d '/' -f 2)" \
|
||||
--package-path .cr-release-packages \
|
||||
--token ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Generate updated index.yaml
|
||||
run: |
|
||||
cr index \
|
||||
--owner "$(echo ${{ github.repository }} | cut -d '/' -f 1)" \
|
||||
--git-repo "$(echo ${{ github.repository }} | cut -d '/' -f 2)" \
|
||||
--index-path ${{ github.workspace }}/index.yaml \
|
||||
--pages-branch 'gh-pages' \
|
||||
--pages-index-path 'index.yaml'
|
||||
|
||||
# Chart Release was never intended to publish to a different repo
|
||||
# this workaround is intended to move the index.yaml to the target repo
|
||||
# where the github pages are hosted
|
||||
- name: Checkout pages repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ${{ env.CHART_TARGET_ORG }}/${{ env.CHART_TARGET_REPO }}
|
||||
path: ${{ env.CHART_TARGET_REPO }}
|
||||
ref: ${{ env.CHART_TARGET_BRANCH }}
|
||||
token: ${{ steps.get_workflow_token.outputs.token }}
|
||||
|
||||
- name: Copy index.yaml
|
||||
run: |
|
||||
cp ${{ github.workspace }}/index.yaml ${{ env.CHART_TARGET_REPO }}/actions-runner-controller/index.yaml
|
||||
|
||||
- name: Commit and push
|
||||
run: |
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
git add .
|
||||
git commit -m "Update index.yaml"
|
||||
git push
|
||||
working-directory: ${{ github.workspace }}/${{ env.CHART_TARGET_REPO }}
|
||||
|
||||
- name: Job summary
|
||||
run: |
|
||||
echo "New helm chart has been published" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Status:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- New [index.yaml](https://github.com/${{ env.CHART_TARGET_ORG }}/${{ env.CHART_TARGET_REPO }}/tree/main/actions-runner-controller) pushed" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
64
.github/workflows/release-runners.yaml
vendored
Normal file
64
.github/workflows/release-runners.yaml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
name: Runners
|
||||
|
||||
# Revert to https://github.com/actions-runner-controller/releases#releases
|
||||
# for details on why we use this approach
|
||||
on:
|
||||
# We must do a trigger on a push: instead of a types: closed so GitHub Secrets
|
||||
# are available to the workflow run
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
paths:
|
||||
- 'runner/**'
|
||||
- '!runner/Makefile'
|
||||
- '.github/workflows/runners.yaml'
|
||||
- '!**.md'
|
||||
|
||||
env:
|
||||
# Safeguard to prevent pushing images to registeries after build
|
||||
PUSH_TO_REGISTRIES: true
|
||||
TARGET_ORG: actions-runner-controller
|
||||
TARGET_WORKFLOW: release-runners.yaml
|
||||
RUNNER_VERSION: 2.300.2
|
||||
DOCKER_VERSION: 20.10.21
|
||||
RUNNER_CONTAINER_HOOKS_VERSION: 0.2.0
|
||||
|
||||
jobs:
|
||||
build-runners:
|
||||
name: Trigger Build and Push of Runner Images
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get Token
|
||||
id: get_workflow_token
|
||||
uses: peter-murray/workflow-application-token-action@8e1ba3bf1619726336414f1014e37f17fbadf1db
|
||||
with:
|
||||
application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }}
|
||||
application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }}
|
||||
organization: ${{ env.TARGET_ORG }}
|
||||
|
||||
- name: Trigger Build And Push Runner Images To Registries
|
||||
run: |
|
||||
# Authenticate
|
||||
gh auth login --with-token <<< ${{ steps.get_workflow_token.outputs.token }}
|
||||
|
||||
# Trigger the workflow run
|
||||
gh workflow run ${{ env.TARGET_WORKFLOW }} -R ${{ env.TARGET_ORG }}/releases \
|
||||
-f runner_version=${{ env.RUNNER_VERSION }} \
|
||||
-f docker_version=${{ env.DOCKER_VERSION }} \
|
||||
-f runner_container_hooks_version=${{ env.RUNNER_CONTAINER_HOOKS_VERSION }} \
|
||||
-f sha='${{ github.sha }}' \
|
||||
-f push_to_registries=${{ env.PUSH_TO_REGISTRIES }}
|
||||
|
||||
- name: Job summary
|
||||
run: |
|
||||
echo "The [release-runners.yaml](https://github.com/actions-runner-controller/releases/blob/main/.github/workflows/release-runners.yaml) workflow has been triggered!" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Parameters:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- runner_version: ${{ env.RUNNER_VERSION }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- docker_version: ${{ env.DOCKER_VERSION }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- runner_container_hooks_version: ${{ env.RUNNER_CONTAINER_HOOKS_VERSION }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- sha: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- push_to_registries: ${{ env.PUSH_TO_REGISTRIES }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Status:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[https://github.com/actions-runner-controller/releases/actions/workflows/release-runners.yaml](https://github.com/actions-runner-controller/releases/actions/workflows/release-runners.yaml)" >> $GITHUB_STEP_SUMMARY
|
||||
6
.github/workflows/run-first-interaction.yaml
vendored
6
.github/workflows/run-first-interaction.yaml
vendored
@@ -20,10 +20,10 @@ jobs:
|
||||
|
||||
The maintainers will triage your issue shortly.
|
||||
|
||||
In the meantime, please take a look at the [troubleshooting guide](https://github.com/actions-runner-controller/actions-runner-controller/blob/master/TROUBLESHOOTING.md) for bug reports.
|
||||
In the meantime, please take a look at the [troubleshooting guide](https://github.com/actions/actions-runner-controller/blob/master/TROUBLESHOOTING.md) for bug reports.
|
||||
|
||||
If this is a feature request, please review our [contribution guidelines](https://github.com/actions-runner-controller/actions-runner-controller/blob/master/CONTRIBUTING.md).
|
||||
If this is a feature request, please review our [contribution guidelines](https://github.com/actions/actions-runner-controller/blob/master/CONTRIBUTING.md).
|
||||
pr-message: |
|
||||
Hello! Thank you for your contribution.
|
||||
|
||||
Please review our [contribution guidelines](https://github.com/actions-runner-controller/actions-runner-controller/blob/master/CONTRIBUTING.md) to understand the project's testing and code conventions.
|
||||
Please review our [contribution guidelines](https://github.com/actions/actions-runner-controller/blob/master/CONTRIBUTING.md) to understand the project's testing and code conventions.
|
||||
|
||||
86
.github/workflows/runners.yaml
vendored
86
.github/workflows/runners.yaml
vendored
@@ -1,86 +0,0 @@
|
||||
name: Runners
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
branches:
|
||||
- 'master'
|
||||
paths:
|
||||
- 'runner/**'
|
||||
- '!runner/Makefile'
|
||||
- '.github/workflows/runners.yaml'
|
||||
- '!**.md'
|
||||
# We must do a trigger on a push: instead of a types: closed so GitHub Secrets
|
||||
# are available to the workflow run
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
paths:
|
||||
- 'runner/**'
|
||||
- '!runner/Makefile'
|
||||
- '.github/workflows/runners.yaml'
|
||||
- '!**.md'
|
||||
|
||||
env:
|
||||
RUNNER_VERSION: 2.298.2
|
||||
DOCKER_VERSION: 20.10.12
|
||||
RUNNER_CONTAINER_HOOKS_VERSION: 0.1.2
|
||||
DOCKERHUB_USERNAME: summerwind
|
||||
|
||||
jobs:
|
||||
build-runners:
|
||||
name: Build ${{ matrix.name }}-${{ matrix.os-name }}-${{ matrix.os-version }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: actions-runner
|
||||
os-name: ubuntu
|
||||
os-version: 20.04
|
||||
- name: actions-runner-dind
|
||||
os-name: ubuntu
|
||||
os-version: 20.04
|
||||
- name: actions-runner-dind-rootless
|
||||
os-name: ubuntu
|
||||
os-version: 20.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Docker Environment
|
||||
id: vars
|
||||
uses: ./.github/actions/setup-docker-environment
|
||||
with:
|
||||
username: ${{ env.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
ghcr_username: ${{ github.actor }}
|
||||
ghcr_password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and Push Versioned Tags
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ./runner
|
||||
file: ./runner/${{ matrix.name }}.dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
build-args: |
|
||||
RUNNER_VERSION=${{ env.RUNNER_VERSION }}
|
||||
DOCKER_VERSION=${{ env.DOCKER_VERSION }}
|
||||
RUNNER_CONTAINER_HOOKS_VERSION=${{ env.RUNNER_CONTAINER_HOOKS_VERSION }}
|
||||
tags: |
|
||||
${{ env.DOCKERHUB_USERNAME }}/${{ matrix.name }}:v${{ env.RUNNER_VERSION }}-${{ matrix.os-name }}-${{ matrix.os-version }}
|
||||
${{ env.DOCKERHUB_USERNAME }}/${{ matrix.name }}:v${{ env.RUNNER_VERSION }}-${{ matrix.os-name }}-${{ matrix.os-version }}-${{ steps.vars.outputs.sha_short }}
|
||||
${{ env.DOCKERHUB_USERNAME }}/${{ matrix.name }}:latest
|
||||
ghcr.io/${{ github.repository }}/${{ matrix.name }}:latest
|
||||
ghcr.io/${{ github.repository }}/${{ matrix.name }}:v${{ env.RUNNER_VERSION }}-${{ matrix.os-name }}-${{ matrix.os-version }}
|
||||
ghcr.io/${{ github.repository }}/${{ matrix.name }}:v${{ env.RUNNER_VERSION }}-${{ matrix.os-name }}-${{ matrix.os-version }}-${{ steps.vars.outputs.sha_short }}
|
||||
cache-from: type=gha,scope=build-${{ matrix.name }}
|
||||
cache-to: type=gha,mode=max,scope=build-${{ matrix.name }}
|
||||
2
.github/workflows/validate-chart.yaml
vendored
2
.github/workflows/validate-chart.yaml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v3.3
|
||||
uses: azure/setup-helm@v3.4
|
||||
with:
|
||||
version: ${{ env.HELM_VERSION }}
|
||||
|
||||
|
||||
6
.github/workflows/validate-runners.yaml
vendored
6
.github/workflows/validate-runners.yaml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
- '**'
|
||||
paths:
|
||||
- 'runner/**'
|
||||
- 'test/entrypoint/**'
|
||||
- 'test/startup/**'
|
||||
- '!**.md'
|
||||
|
||||
permissions:
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
name: runner / shellcheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
- name: shellcheck
|
||||
uses: reviewdog/action-shellcheck@v1
|
||||
with:
|
||||
@@ -42,4 +42,4 @@ jobs:
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
make acceptance/runner/entrypoint
|
||||
make acceptance/runner/startup
|
||||
|
||||
@@ -7,8 +7,8 @@ linters-settings:
|
||||
exclude-functions:
|
||||
- (net/http.ResponseWriter).Write
|
||||
- (*net/http.Server).Shutdown
|
||||
- (*github.com/actions-runner-controller/actions-runner-controller/simulator.VisibleRunnerGroups).Add
|
||||
- (*github.com/actions-runner-controller/actions-runner-controller/testing.Kind).Stop
|
||||
- (*github.com/actions/actions-runner-controller/simulator.VisibleRunnerGroups).Add
|
||||
- (*github.com/actions/actions-runner-controller/testing.Kind).Stop
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: controllers/suite_test.go
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# actions-runner-controller maintainers
|
||||
* @mumoshu @toast-gear
|
||||
* @mumoshu @toast-gear @actions/actions-runtime
|
||||
|
||||
74
CODE_OF_CONDUCT.md
Normal file
74
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at opensource@github.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
@@ -19,7 +19,7 @@
|
||||
## Welcome
|
||||
|
||||
This document is the single source of truth for how to contribute to the code base.
|
||||
Feel free to browse the [open issues](https://github.com/actions-runner-controller/actions-runner-controller/issues) or file a new one, all feedback is welcome!
|
||||
Feel free to browse the [open issues](https://github.com/actions/actions-runner-controller/issues) or file a new one, all feedback is welcome!
|
||||
By reading this guide, we hope to give you all of the information you need to be able to pick up issues, contribute new features, and get your work
|
||||
reviewed and merged.
|
||||
|
||||
@@ -111,7 +111,7 @@ That's the directory in which controller-runtime's `envtest` framework locates t
|
||||
sudo mkdir -p /usr/local/kubebuilder/bin
|
||||
make kube-apiserver etcd
|
||||
sudo mv test-assets/{etcd,kube-apiserver} /usr/local/kubebuilder/bin/
|
||||
go test -v -run TestAPIs github.com/actions-runner-controller/actions-runner-controller/controllers
|
||||
go test -v -run TestAPIs github.com/actions/actions-runner-controller/controllers/actions.summerwind.net
|
||||
```
|
||||
|
||||
To run Ginkgo tests selectively, set the pattern of target test names to `GINKGO_FOCUS`.
|
||||
@@ -119,7 +119,7 @@ All the Ginkgo test that matches `GINKGO_FOCUS` will be run.
|
||||
|
||||
```shell
|
||||
GINKGO_FOCUS='[It] should create a new Runner resource from the specified template, add a another Runner on replicas increased, and removes all the replicas when set to 0' \
|
||||
go test -v -run TestAPIs github.com/actions-runner-controller/actions-runner-controller/controllers
|
||||
go test -v -run TestAPIs github.com/actions/actions-runner-controller/controllers/actions.summerwind.net
|
||||
```
|
||||
|
||||
### Running End to End Tests
|
||||
@@ -201,7 +201,7 @@ The maintainers will manage releases and publishing new charts.
|
||||
|
||||
We always appreciate your help in testing open pull requests by deploying custom builds of actions-runner-controller onto your own environment, so that we are extra sure we didn't break anything.
|
||||
|
||||
It is especially true when the pull request is about GitHub Enterprise, both GHEC and GHES, as [maintainers don't have GitHub Enterprise environments for testing](docs/detailed-docs.md#github-enterprise-support).
|
||||
It is especially true when the pull request is about GitHub Enterprise, both GHEC and GHES, as [maintainers don't have GitHub Enterprise environments for testing](docs/about-arc.md#github-enterprise-support).
|
||||
|
||||
The process would look like the below:
|
||||
|
||||
@@ -211,3 +211,9 @@ The process would look like the below:
|
||||
- Update your actions-runner-controller's controller-manager deployment to use the new image, `$DOCKER_USER/actions-runner-controller:canary`
|
||||
|
||||
Please also note that you need to replace `$DOCKER_USER` with your own DockerHub account name.
|
||||
|
||||
## Release process
|
||||
|
||||
Only the maintainers can release a new version of actions-runner-controller, publish a new version of the helm charts, and runner images.
|
||||
|
||||
All release workflows have been moved to [actions-runner-controller/releases](https://github.com/actions-runner-controller/releases) since the packages are owned by the former organization.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Build the manager binary
|
||||
FROM --platform=$BUILDPLATFORM golang:1.19.2 as builder
|
||||
FROM --platform=$BUILDPLATFORM golang:1.19.4 as builder
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
@@ -36,8 +36,9 @@ ENV GOCACHE /build/${TARGETPLATFORM}/root/.cache/go-build
|
||||
RUN --mount=target=. \
|
||||
--mount=type=cache,mode=0777,target=${GOCACHE} \
|
||||
export GOOS=${TARGETOS} GOARCH=${TARGETARCH} GOARM=${TARGETVARIANT#v} && \
|
||||
go build -trimpath -ldflags="-s -w -X 'github.com/actions-runner-controller/actions-runner-controller/build.Version=${VERSION}'" -o /out/manager main.go && \
|
||||
go build -trimpath -ldflags="-s -w" -o /out/github-webhook-server ./cmd/githubwebhookserver
|
||||
go build -trimpath -ldflags="-s -w -X 'github.com/actions/actions-runner-controller/build.Version=${VERSION}'" -o /out/manager main.go && \
|
||||
go build -trimpath -ldflags="-s -w" -o /out/github-webhook-server ./cmd/githubwebhookserver && \
|
||||
go build -trimpath -ldflags="-s -w" -o /out/actions-metrics-server ./cmd/actionsmetricsserver
|
||||
|
||||
# Use distroless as minimal base image to package the manager binary
|
||||
# Refer to https://github.com/GoogleContainerTools/distroless for more details
|
||||
@@ -47,6 +48,7 @@ WORKDIR /
|
||||
|
||||
COPY --from=builder /out/manager .
|
||||
COPY --from=builder /out/github-webhook-server .
|
||||
COPY --from=builder /out/actions-metrics-server .
|
||||
|
||||
USER 65532:65532
|
||||
|
||||
|
||||
41
Makefile
41
Makefile
@@ -5,7 +5,7 @@ else
|
||||
endif
|
||||
DOCKER_USER ?= $(shell echo ${NAME} | cut -d / -f1)
|
||||
VERSION ?= dev
|
||||
RUNNER_VERSION ?= 2.298.2
|
||||
RUNNER_VERSION ?= 2.300.2
|
||||
TARGETPLATFORM ?= $(shell arch)
|
||||
RUNNER_NAME ?= ${DOCKER_USER}/actions-runner
|
||||
RUNNER_TAG ?= ${VERSION}
|
||||
@@ -34,6 +34,19 @@ endif
|
||||
TEST_ASSETS=$(PWD)/test-assets
|
||||
TOOLS_PATH=$(PWD)/.tools
|
||||
|
||||
OS_NAME := $(shell uname -s | tr A-Z a-z)
|
||||
|
||||
# The etcd packages that coreos maintain use different extensions for each *nix OS on their github release page.
|
||||
# ETCD_EXTENSION: the storage format file extension listed on the release page.
|
||||
# EXTRACT_COMMAND: the appropriate CLI command for extracting this file format.
|
||||
ifeq ($(OS_NAME), darwin)
|
||||
ETCD_EXTENSION:=zip
|
||||
EXTRACT_COMMAND:=unzip
|
||||
else
|
||||
ETCD_EXTENSION:=tar.gz
|
||||
EXTRACT_COMMAND:=tar -xzf
|
||||
endif
|
||||
|
||||
# default list of platforms for which multiarch image is built
|
||||
ifeq (${PLATFORMS}, )
|
||||
export PLATFORMS="linux/amd64,linux/arm64"
|
||||
@@ -61,7 +74,7 @@ GO_TEST_ARGS ?= -short
|
||||
# Run tests
|
||||
test: generate fmt vet manifests shellcheck
|
||||
go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
|
||||
go test -fuzz=Fuzz -fuzztime=10s -run=Fuzz* ./controllers
|
||||
go test -fuzz=Fuzz -fuzztime=10s -run=Fuzz* ./controllers/actions.summerwind.net
|
||||
|
||||
test-with-deps: kube-apiserver etcd kubectl
|
||||
# See https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest#pkg-constants
|
||||
@@ -117,7 +130,7 @@ generate: controller-gen
|
||||
|
||||
# Run shellcheck on runner scripts
|
||||
shellcheck: shellcheck-install
|
||||
$(TOOLS_PATH)/shellcheck --shell bash --source-path runner runner/*.bash runner/*.sh
|
||||
$(TOOLS_PATH)/shellcheck --shell bash --source-path runner runner/*.sh
|
||||
|
||||
docker-buildx:
|
||||
export DOCKER_CLI_EXPERIMENTAL=enabled ;\
|
||||
@@ -203,8 +216,8 @@ acceptance/deploy:
|
||||
acceptance/tests:
|
||||
acceptance/checks.sh
|
||||
|
||||
acceptance/runner/entrypoint:
|
||||
cd test/entrypoint/ && bash test.sh
|
||||
acceptance/runner/startup:
|
||||
cd test/startup/ && bash test.sh
|
||||
|
||||
# We use -count=1 instead of `go clean -testcache`
|
||||
# See https://terratest.gruntwork.io/docs/testing-best-practices/avoid-test-caching/
|
||||
@@ -267,8 +280,8 @@ ifeq (, $(wildcard $(TOOLS_PATH)/shellcheck))
|
||||
set -e ;\
|
||||
SHELLCHECK_TMP_DIR=$$(mktemp -d) ;\
|
||||
cd $$SHELLCHECK_TMP_DIR ;\
|
||||
curl -LO https://github.com/koalaman/shellcheck/releases/download/v$(SHELLCHECK_VERSION)/shellcheck-v$(SHELLCHECK_VERSION).linux.x86_64.tar.xz ;\
|
||||
tar Jxvf shellcheck-v$(SHELLCHECK_VERSION).linux.x86_64.tar.xz ;\
|
||||
curl -LO https://github.com/koalaman/shellcheck/releases/download/v$(SHELLCHECK_VERSION)/shellcheck-v$(SHELLCHECK_VERSION).$(OS_NAME).x86_64.tar.xz ;\
|
||||
tar Jxvf shellcheck-v$(SHELLCHECK_VERSION).$(OS_NAME).x86_64.tar.xz ;\
|
||||
cd $(CURDIR) ;\
|
||||
mkdir -p $(TOOLS_PATH) ;\
|
||||
mv $$SHELLCHECK_TMP_DIR/shellcheck-v$(SHELLCHECK_VERSION)/shellcheck $(TOOLS_PATH)/ ;\
|
||||
@@ -277,8 +290,6 @@ ifeq (, $(wildcard $(TOOLS_PATH)/shellcheck))
|
||||
endif
|
||||
SHELLCHECK=$(TOOLS_PATH)/shellcheck
|
||||
|
||||
OS_NAME := $(shell uname -s | tr A-Z a-z)
|
||||
|
||||
# find or download etcd
|
||||
etcd:
|
||||
ifeq (, $(shell which etcd))
|
||||
@@ -287,12 +298,10 @@ ifeq (, $(wildcard $(TEST_ASSETS)/etcd))
|
||||
set -xe ;\
|
||||
INSTALL_TMP_DIR=$$(mktemp -d) ;\
|
||||
cd $$INSTALL_TMP_DIR ;\
|
||||
wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.3.2/kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
|
||||
wget https://github.com/coreos/etcd/releases/download/v3.4.22/etcd-v3.4.22-$(OS_NAME)-amd64.$(ETCD_EXTENSION);\
|
||||
mkdir -p $(TEST_ASSETS) ;\
|
||||
tar zxvf kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/etcd $(TEST_ASSETS)/etcd ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/kube-apiserver $(TEST_ASSETS)/kube-apiserver ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/kubectl $(TEST_ASSETS)/kubectl ;\
|
||||
$(EXTRACT_COMMAND) etcd-v3.4.22-$(OS_NAME)-amd64.$(ETCD_EXTENSION) ;\
|
||||
mv etcd-v3.4.22-$(OS_NAME)-amd64/etcd $(TEST_ASSETS)/etcd ;\
|
||||
rm -rf $$INSTALL_TMP_DIR ;\
|
||||
}
|
||||
ETCD_BIN=$(TEST_ASSETS)/etcd
|
||||
@@ -314,9 +323,7 @@ ifeq (, $(wildcard $(TEST_ASSETS)/kube-apiserver))
|
||||
wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.3.2/kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
|
||||
mkdir -p $(TEST_ASSETS) ;\
|
||||
tar zxvf kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/etcd $(TEST_ASSETS)/etcd ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/kube-apiserver $(TEST_ASSETS)/kube-apiserver ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/kubectl $(TEST_ASSETS)/kubectl ;\
|
||||
rm -rf $$INSTALL_TMP_DIR ;\
|
||||
}
|
||||
KUBE_APISERVER_BIN=$(TEST_ASSETS)/kube-apiserver
|
||||
@@ -338,8 +345,6 @@ ifeq (, $(wildcard $(TEST_ASSETS)/kubectl))
|
||||
wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.3.2/kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
|
||||
mkdir -p $(TEST_ASSETS) ;\
|
||||
tar zxvf kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/etcd $(TEST_ASSETS)/etcd ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/kube-apiserver $(TEST_ASSETS)/kube-apiserver ;\
|
||||
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/kubectl $(TEST_ASSETS)/kubectl ;\
|
||||
rm -rf $$INSTALL_TMP_DIR ;\
|
||||
}
|
||||
|
||||
2
PROJECT
2
PROJECT
@@ -1,5 +1,5 @@
|
||||
domain: summerwind.dev
|
||||
repo: github.com/actions-runner-controller/actions-runner-controller
|
||||
repo: github.com/actions/actions-runner-controller
|
||||
resources:
|
||||
- group: actions
|
||||
kind: Runner
|
||||
|
||||
174
README.md
174
README.md
@@ -1,158 +1,66 @@
|
||||
|
||||
# Actions Runner Controller (ARC)
|
||||
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/6061)
|
||||
[](https://github.com/jonico/awesome-runners)
|
||||
[](https://artifacthub.io/packages/search?repo=actions-runner-controller)
|
||||
|
||||
GitHub Actions automates the deployment of code to different environments, including production. The environments contain the `GitHub Runner` software which executes the automation. `GitHub Runner` can be run in GitHub-hosted cloud or self-hosted environments. Self-hosted environments offer more control of hardware, operating system, and software tools. They can be run on physical machines, virtual machines, or in a container. Containerized environments are lightweight, loosely coupled, highly efficient and can be managed centrally. However, they are not straightforward to use.
|
||||
## People
|
||||
|
||||
`Actions Runner Controller (ARC)` makes it simpler to run self hosted environments on Kubernetes(K8s) cluster.
|
||||
`actions-runner-controller` is an open-source project currently developed and maintained in collaboration with maintainers @mumoshu and @toast-gear, various [contributors](https://github.com/actions/actions-runner-controller/graphs/contributors), and the [awesome community](https://github.com/actions/actions-runner-controller/discussions), mostly in their spare time.
|
||||
|
||||
With ARC you can :
|
||||
If you think the project is awesome and it's becoming a basis for your important business, consider [sponsoring us](https://github.com/sponsors/actions-runner-controller)!
|
||||
|
||||
- **Deploy self hosted runners on Kubernetes cluster** with a simple set of commands.
|
||||
- **Auto scale runners** based on demand.
|
||||
- **Setup across GitHub editions** including GitHub Enterprise editions and GitHub Enterprise Cloud.
|
||||
In case you are already the employer of one of contributors, sponsoring via GitHub Sponsors might not be an option. Just support them in other means!
|
||||
|
||||
## Overview
|
||||
We don't currently have [any sponsors dedicated to this project yet](https://github.com/sponsors/actions-runner-controller).
|
||||
|
||||
For an overview of ARC, please refer to "[ARC Overview](https://github.com/actions-runner-controller/actions-runner-controller/blob/master/docs/Actions-Runner-Controller-Overview.md)."
|
||||
However, [HelloFresh](https://www.hellofreshgroup.com/en/) has recently started sponsoring @mumoshu for this project along with his other works. A part of their sponsorship will enable @mumoshu to add an E2E test to keep ARC even more reliable on AWS. Thank you for your sponsorship!
|
||||
|
||||
[<img src="https://user-images.githubusercontent.com/22009/170898715-07f02941-35ec-418b-8cd4-251b422fa9ac.png" width="219" height="71" />](https://careers.hellofresh.com/)
|
||||
|
||||
## Status
|
||||
|
||||
Even though actions-runner-controller is used in production environments, it is still in its early stage of development, hence versioned 0.x.
|
||||
|
||||
actions-runner-controller complies to Semantic Versioning 2.0.0 in which v0.x means that there could be backward-incompatible changes for every release.
|
||||
|
||||
The documentation is kept inline with master@HEAD, we do our best to highlight any features that require a specific ARC version or higher however this is not always easily done due to there being many moving parts. Additionally, we actively do not retain compatibly with every GitHub Enterprise Server version nor every Kubernetes version so you will need to ensure you stay current within a reasonable timespan.
|
||||
|
||||
## About
|
||||
|
||||
[GitHub Actions](https://github.com/features/actions) is a very useful tool for automating development. GitHub Actions jobs are run in the cloud by default, but you may want to run your jobs in your environment. [Self-hosted runner](https://github.com/actions/runner) can be used for such use cases, but requires the provisioning and configuration of a virtual machine instance. Instead if you already have a Kubernetes cluster, it makes more sense to run the self-hosted runner on top of it.
|
||||
|
||||
**actions-runner-controller** makes that possible. Just create a *Runner* resource on your Kubernetes, and it will run and operate the self-hosted runner for the specified repository. Combined with Kubernetes RBAC, you can also build simple Self-hosted runners as a Service.
|
||||
|
||||
## Getting Started
|
||||
To give ARC a try with just a handful of commands, Please refer to the [Quickstart guide](/docs/quickstart.md).
|
||||
|
||||
ARC can be setup with just a few steps.
|
||||
For an overview of ARC, please refer to [About ARC](https://github.com/actions/actions-runner-controller/blob/master/docs/about-arc.md)
|
||||
|
||||
In this section we will setup prerequisites, deploy ARC into a K8s cluster, and then run GitHub Action workflows on that cluster.
|
||||
For more information, please refer to detailed documentation below!
|
||||
|
||||
### Prerequisites
|
||||
## Documentation
|
||||
|
||||
<details><summary><sub>Create a K8s cluster, if not available.</sub></summary>
|
||||
<sub>
|
||||
If you don't have a K8s cluster, you can install a local environment using minikube. For more information, see <a href="https://minikube.sigs.k8s.io/docs/start/">"Installing minikube."</a>
|
||||
</sub>
|
||||
</details>
|
||||
|
||||
:one: Install cert-manager in your cluster. For more information, see "[cert-manager](https://cert-manager.io/docs/installation/)."
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.2/cert-manager.yaml
|
||||
```
|
||||
|
||||
<sub> *note:- This command uses v1.8.2. Please replace with a later version, if available.</sub>
|
||||
|
||||
>You may also install cert-manager using Helm. For instructions, see "[Installing with Helm](https://cert-manager.io/docs/installation/helm/#installing-with-helm)."
|
||||
|
||||
:two: Next, Generate a Personal Access Token (PAT) for ARC to authenticate with GitHub.
|
||||
|
||||
- Login to your GitHub account and Navigate to "[Create new Token](https://github.com/settings/tokens/new)."
|
||||
- Select **repo**.
|
||||
- Click **Generate Token** and then copy the token locally ( we’ll need it later).
|
||||
|
||||
### Deploy and Configure ARC
|
||||
|
||||
1️⃣ Deploy and configure ARC on your K8s cluster. You may use Helm or Kubectl.
|
||||
|
||||
<details><summary>Helm deployment</summary>
|
||||
|
||||
##### Add repository
|
||||
|
||||
```shell
|
||||
helm repo add actions-runner-controller https://actions-runner-controller.github.io/actions-runner-controller
|
||||
```
|
||||
|
||||
##### Install Helm chart
|
||||
|
||||
```shell
|
||||
helm upgrade --install --namespace actions-runner-system --create-namespace\
|
||||
--set=authSecret.create=true\
|
||||
--set=authSecret.github_token="REPLACE_YOUR_TOKEN_HERE"\
|
||||
--wait actions-runner-controller actions-runner-controller/actions-runner-controller
|
||||
```
|
||||
|
||||
<sub> *note:- Replace REPLACE_YOUR_TOKEN_HERE with your PAT that was generated previously. </sub>
|
||||
</details>
|
||||
|
||||
<details><summary>Kubectl deployment</summary>
|
||||
|
||||
##### Deploy ARC
|
||||
|
||||
```shell
|
||||
kubectl apply -f \
|
||||
https://github.com/actions-runner-controller/actions-runner-controller/\
|
||||
releases/download/v0.22.0/actions-runner-controller.yaml
|
||||
```
|
||||
|
||||
<sub> *note:- Replace "v0.22.0" with the version you wish to deploy </sub>
|
||||
|
||||
##### Configure Personal Access Token
|
||||
|
||||
```shell
|
||||
kubectl create secret generic controller-manager \
|
||||
-n actions-runner-system \
|
||||
--from-literal=github_token=REPLACE_YOUR_TOKEN_HERE
|
||||
````
|
||||
|
||||
<sub> *note:- Replace REPLACE_YOUR_TOKEN_HERE with your PAT that was generated previously.</sub>
|
||||
|
||||
</details>
|
||||
|
||||
2️⃣ Create the GitHub self hosted runners and configure to run against your repository.
|
||||
|
||||
Create a `runnerdeployment.yaml` file and copy the following YAML contents into it:
|
||||
|
||||
```yaml
|
||||
apiVersion: actions.summerwind.dev/v1alpha1
|
||||
kind: RunnerDeployment
|
||||
metadata:
|
||||
name: example-runnerdeploy
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
spec:
|
||||
repository: mumoshu/actions-runner-controller-ci
|
||||
````
|
||||
<sub> *note:- Replace "mumoshu/actions-runner-controller-ci" with your repository name. </sub>
|
||||
|
||||
Apply this file to your K8s cluster.
|
||||
```shell
|
||||
kubectl apply -f runnerdeployment.yaml
|
||||
````
|
||||
|
||||
*🎉 We are done - now we should have self hosted runners running in K8s configured to your repository. 🎉*
|
||||
|
||||
Next - lets verify our setup and execute some workflows.
|
||||
|
||||
### Verify and Execute Workflows
|
||||
|
||||
:one: Verify that your setup is successful:
|
||||
```shell
|
||||
|
||||
$ kubectl get runners
|
||||
NAME REPOSITORY STATUS
|
||||
example-runnerdeploy2475h595fr mumoshu/actions-runner-controller-ci Running
|
||||
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
example-runnerdeploy2475ht2qbr 2/2 Running 0 1m
|
||||
````
|
||||
|
||||
Also, this runner has been registered directly to the specified repository, you can see it in repository settings. For more information, see "[Checking the status of a self-hosted runner - GitHub Docs](https://docs.github.com/en/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners#checking-the-status-of-a-self-hosted-runner)."
|
||||
|
||||
:two: You are ready to execute workflows against this self-hosted runner. For more information, see "[Using self-hosted runners in a workflow - GitHub Docs](https://docs.github.com/en/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow#using-self-hosted-runners-in-a-workflow)."
|
||||
|
||||
There is also a quick start guide to get started on Actions, For more information, please refer to "[Quick start Guide to GitHub Actions](https://docs.github.com/en/actions/quickstart)."
|
||||
|
||||
## Learn more
|
||||
|
||||
For more detailed documentation, please refer to "[Detailed Documentation](https://github.com/actions-runner-controller/actions-runner-controller/blob/master/docs/detailed-docs.md)."
|
||||
- [Quickstart guide](/docs/quickstart.md)
|
||||
- [About ARC](/docs/about-arc.md)
|
||||
- [Installing ARC](/docs/installing-arc.md)
|
||||
- [Authenticating to the GitHub API](/docs/authenticating-to-the-github-api.md)
|
||||
- [Deploying ARC runners](/docs/deploying-arc-runners.md)
|
||||
- [Adding ARC runners to a repository, organization, or enterprise](/docs/choosing-runner-destination.md)
|
||||
- [Automatically scaling runners](/docs/automatically-scaling-runners.md)
|
||||
- [Using custom volumes](/docs/using-custom-volumes.md)
|
||||
- [Using ARC runners in a workflow](/docs/using-arc-runners-in-a-workflow.md)
|
||||
- [Managing access with runner groups](/docs/managing-access-with-runner-groups.md)
|
||||
- [Configuring Windows runners](/docs/configuring-windows-runners.md)
|
||||
- [Using ARC across organizations](/docs/using-arc-across-organizations.md)
|
||||
- [Using entrypoint features](/docs/using-entrypoint-features.md)
|
||||
- [Deploying alternative runners](/docs/deploying-alternative-runners.md)
|
||||
- [Monitoring and troubleshooting](/docs/monitoring-and-troubleshooting.md)
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions from the community. For more details on contributing to the project (including requirements), please refer to "[Getting Started with Contributing](https://github.com/actions-runner-controller/actions-runner-controller/blob/master/CONTRIBUTING.md)."
|
||||
We welcome contributions from the community. For more details on contributing to the project (including requirements), please refer to "[Getting Started with Contributing](https://github.com/actions/actions-runner-controller/blob/master/CONTRIBUTING.md)."
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
We are very happy to help you with any issues you have. Please refer to the "[Troubleshooting](https://github.com/actions-runner-controller/actions-runner-controller/blob/master/TROUBLESHOOTING.md)" section for common issues.
|
||||
We are very happy to help you with any issues you have. Please refer to the "[Troubleshooting](https://github.com/actions/actions-runner-controller/blob/master/TROUBLESHOOTING.md)" section for common issues.
|
||||
|
||||
35
SECURITY.md
35
SECURITY.md
@@ -1,22 +1,31 @@
|
||||
# Security Policy
|
||||
Thanks for helping make GitHub safe for everyone.
|
||||
|
||||
## Sponsoring the project
|
||||
## Security
|
||||
|
||||
This project is maintained by a small team of two and therefore lacks the resource to provide security fixes in a timely manner.
|
||||
GitHub takes the security of our software products and services seriously, including all of the open source code repositories managed through our GitHub organizations, such as [GitHub](https://github.com/GitHub).
|
||||
|
||||
If you have important business(es) that relies on this project, please consider sponsoring the project so that the maintainer(s) can commit to providing such service.
|
||||
Even though [open source repositories are outside of the scope of our bug bounty program](https://bounty.github.com/index.html#scope) and therefore not eligible for bounty rewards, we will ensure that your finding gets passed along to the appropriate maintainers for remediation.
|
||||
|
||||
Please refer to https://github.com/sponsors/actions-runner-controller for available tiers.
|
||||
## Reporting Security Issues
|
||||
|
||||
## Supported Versions
|
||||
If you believe you have found a security vulnerability in any GitHub-owned repository, please report it to us through coordinated disclosure.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.23.0 | :white_check_mark: |
|
||||
| < 0.23.0| :x: |
|
||||
**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**
|
||||
|
||||
## Reporting a Vulnerability
|
||||
Instead, please send an email to opensource-security[@]github.com.
|
||||
|
||||
To report a security issue, please email ykuoka+arcsecurity(at)gmail.com with a description of the issue, the steps you took to create the issue, affected versions, and, if known, mitigations for the issue.
|
||||
Please include as much of the information listed below as you can to help us better understand and resolve the issue:
|
||||
|
||||
A maintainer will try to respond within 5 working days. If the issue is confirmed as a vulnerability, a Security Advisory will be opened. This project tries to follow a 90 day disclosure timeline.
|
||||
* The type of issue (e.g., buffer overflow, SQL injection, or cross-site scripting)
|
||||
* Full paths of source file(s) related to the manifestation of the issue
|
||||
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||
* Any special configuration required to reproduce the issue
|
||||
* Step-by-step instructions to reproduce the issue
|
||||
* Proof-of-concept or exploit code (if possible)
|
||||
* Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
## Policy
|
||||
|
||||
See [GitHub's Safe Harbor Policy](https://docs.github.com/en/github/site-policy/github-bug-bounty-program-legal-safe-harbor#1-safe-harbor-terms)
|
||||
@@ -11,6 +11,7 @@
|
||||
* [Runner coming up before network available](#runner-coming-up-before-network-available)
|
||||
* [Outgoing network action hangs indefinitely](#outgoing-network-action-hangs-indefinitely)
|
||||
* [Unable to scale to zero with TotalNumberOfQueuedAndInProgressWorkflowRuns](#unable-to-scale-to-zero-with-totalnumberofqueuedandinprogressworkflowruns)
|
||||
* [Slow / failure to boot dind sidecar (default runner)](#slow--failure-to-boot-dind-sidecar-default-runner)
|
||||
|
||||
## Tools
|
||||
|
||||
@@ -62,9 +63,9 @@ To fix this, you may either:
|
||||
|
||||
```sh
|
||||
# With helm, you'd set `webhookPort` to the port number of your choice
|
||||
# See https://github.com/actions-runner-controller/actions-runner-controller/pull/1410/files for more information
|
||||
# See https://github.com/actions/actions-runner-controller/pull/1410/files for more information
|
||||
helm upgrade --install --namespace actions-runner-system --create-namespace \
|
||||
--wait actions-runner-controller actions-runner-controller/actions-runner-controller \
|
||||
--wait actions-runner-controller actions/actions-runner-controller \
|
||||
--set webhookPort=10250
|
||||
```
|
||||
|
||||
@@ -167,7 +168,7 @@ are in a namespace not shared with anything else_
|
||||
|
||||
**Problem**
|
||||
|
||||
ARC isn't involved in jobs actually getting allocated to a runner. ARC is responsible for orchestrating runners and the runner lifecycle. Why some people see large delays in job allocation is not clear however it has been confirmed https://github.com/actions-runner-controller/actions-runner-controller/issues/1387#issuecomment-1122593984 that this is caused from the self-update process somehow.
|
||||
ARC isn't involved in jobs actually getting allocated to a runner. ARC is responsible for orchestrating runners and the runner lifecycle. Why some people see large delays in job allocation is not clear however it has been confirmed https://github.com/actions/actions-runner-controller/issues/1387#issuecomment-1122593984 that this is caused from the self-update process somehow.
|
||||
|
||||
**Solution**
|
||||
|
||||
@@ -213,7 +214,7 @@ More broadly, there are many other circumstances where the runner pod coming up
|
||||
|
||||
> Added originally to help users with older istio instances.
|
||||
> Newer Istio instances can use Istio's `holdApplicationUntilProxyStarts` attribute ([istio/istio#11130](https://github.com/istio/istio/issues/11130)) to avoid having to delay starting up the runner.
|
||||
> Please read the discussion in [#592](https://github.com/actions-runner-controller/actions-runner-controller/pull/592) for more information.
|
||||
> Please read the discussion in [#592](https://github.com/actions/actions-runner-controller/pull/592) for more information.
|
||||
|
||||
You can add a delay to the runner's entrypoint script by setting the `STARTUP_DELAY_IN_SECONDS` environment variable for the runner pod. This will cause the script to sleep X seconds, this works with any runner kind.
|
||||
|
||||
@@ -277,7 +278,7 @@ spec:
|
||||
```
|
||||
|
||||
You can read the discussion regarding this issue in
|
||||
(#1406)[https://github.com/actions-runner-controller/actions-runner-controller/issues/1046].
|
||||
(#1406)[https://github.com/actions/actions-runner-controller/issues/1046].
|
||||
|
||||
## Unable to scale to zero with TotalNumberOfQueuedAndInProgressWorkflowRuns
|
||||
|
||||
@@ -287,6 +288,16 @@ HRA doesn't scale the RunnerDeployment to zero, even though you did configure HR
|
||||
|
||||
**Solution**
|
||||
|
||||
You very likely have some dangling workflow jobs stuck in `queued` or `in_progress` as seen in [#1057](https://github.com/actions-runner-controller/actions-runner-controller/issues/1057#issuecomment-1133439061).
|
||||
You very likely have some dangling workflow jobs stuck in `queued` or `in_progress` as seen in [#1057](https://github.com/actions/actions-runner-controller/issues/1057#issuecomment-1133439061).
|
||||
|
||||
Manually call [the "list workflow runs" API](https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository), and [remove the dangling workflow job(s)](https://docs.github.com/en/rest/actions/workflow-runs#delete-a-workflow-run).
|
||||
|
||||
## Slow / failure to boot dind sidecar (default runner)
|
||||
|
||||
**Problem**
|
||||
|
||||
If you noticed that it takes several minutes for sidecar dind container to be created or it exits with with error just after being created it might indicate that you are experiencing disk performance issue. You might see message `failed to reserve container name` when scaling up multiple runners at once. When you ssh on kubernetes node that problematic pods were scheduled on you can use tools like `atop`, `htop` or `iotop` to check IO usage and cpu time percentage used on iowait. If you see that disk usage is high (80-100%) and iowaits are taking a significant chunk of you cpu time (normally it should not be higher than 10%) it means that performance is being bottlenecked by slow disk.
|
||||
|
||||
**Solution**
|
||||
|
||||
The solution is to switch to using faster storage, if you are experiencing this issue you are probably using hdd, switch to ssh fixed the problem in my case. Most cloud providers have a list of storage options to use just pick something faster that your current disk, for on prem clusters you will need to invest in some ssds.
|
||||
|
||||
@@ -88,6 +88,9 @@ data:
|
||||
no-autoupdate: true
|
||||
ingress:
|
||||
# The first rule proxies traffic to the httpbin sample Service defined in app.yaml
|
||||
- hostname: ${TUNNEL_HOSTNAME}
|
||||
service: http://actions-runner-controller-actions-metrics-server.actions-runner-system:80
|
||||
path: /metrics$
|
||||
- hostname: ${TUNNEL_HOSTNAME}
|
||||
service: http://actions-runner-controller-github-webhook-server.actions-runner-system:80
|
||||
# This rule matches any traffic which didn't match a previous rule, and responds with HTTP 404.
|
||||
|
||||
@@ -35,6 +35,16 @@ else
|
||||
echo 'Skipped deploying secret "github-webhook-server". Set WEBHOOK_GITHUB_TOKEN to deploy.' 1>&2
|
||||
fi
|
||||
|
||||
if [ -n "${WEBHOOK_GITHUB_TOKEN}" ]; then
|
||||
kubectl -n actions-runner-system delete secret \
|
||||
actions-metrics-server || :
|
||||
kubectl -n actions-runner-system create secret generic \
|
||||
actions-metrics-server \
|
||||
--from-literal=github_token=${WEBHOOK_GITHUB_TOKEN:?WEBHOOK_GITHUB_TOKEN must not be empty}
|
||||
else
|
||||
echo 'Skipped deploying secret "actions-metrics-server". Set WEBHOOK_GITHUB_TOKEN to deploy.' 1>&2
|
||||
fi
|
||||
|
||||
tool=${ACCEPTANCE_TEST_DEPLOYMENT_TOOL}
|
||||
|
||||
TEST_ID=${TEST_ID:-default}
|
||||
@@ -49,10 +59,16 @@ if [ "${tool}" == "helm" ]; then
|
||||
flags+=( --set imagePullSecrets[0].name=${IMAGE_PULL_SECRET})
|
||||
flags+=( --set image.actionsRunnerImagePullSecrets[0].name=${IMAGE_PULL_SECRET})
|
||||
flags+=( --set githubWebhookServer.imagePullSecrets[0].name=${IMAGE_PULL_SECRET})
|
||||
flags+=( --set actionsMetricsServer.imagePullSecrets[0].name=${IMAGE_PULL_SECRET})
|
||||
fi
|
||||
if [ "${CHART_VERSION}" != "" ]; then
|
||||
flags+=( --version ${CHART_VERSION})
|
||||
fi
|
||||
if [ "${LOG_FORMAT}" != "" ]; then
|
||||
flags+=( --set logFormat=${LOG_FORMAT})
|
||||
flags+=( --set githubWebhookServer.logFormat=${LOG_FORMAT})
|
||||
flags+=( --set actionsMetricsServer.logFormat=${LOG_FORMAT})
|
||||
fi
|
||||
|
||||
set -vx
|
||||
|
||||
@@ -66,6 +82,7 @@ if [ "${tool}" == "helm" ]; then
|
||||
--set image.tag=${VERSION} \
|
||||
--set podAnnotations.test-id=${TEST_ID} \
|
||||
--set githubWebhookServer.podAnnotations.test-id=${TEST_ID} \
|
||||
--set actionsMetricsServer.podAnnotations.test-id=${TEST_ID} \
|
||||
${flags[@]} --set image.imagePullPolicy=${IMAGE_PULL_POLICY} \
|
||||
-f ${VALUES_FILE}
|
||||
set +v
|
||||
|
||||
52
acceptance/testdata/runnerdeploy.envsubst.yaml
vendored
52
acceptance/testdata/runnerdeploy.envsubst.yaml
vendored
@@ -8,6 +8,16 @@ provisioner: rancher.io/local-path
|
||||
reclaimPolicy: Delete
|
||||
volumeBindingMode: WaitForFirstConsumer
|
||||
---
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: ${NAME}-rootless-dind-work-dir
|
||||
labels:
|
||||
content: ${NAME}-rootless-dind-work-dir
|
||||
provisioner: rancher.io/local-path
|
||||
reclaimPolicy: Delete
|
||||
volumeBindingMode: WaitForFirstConsumer
|
||||
---
|
||||
apiVersion: actions.summerwind.dev/v1alpha1
|
||||
kind: RunnerDeployment
|
||||
metadata:
|
||||
@@ -49,13 +59,52 @@ spec:
|
||||
labels:
|
||||
- "${RUNNER_LABEL}"
|
||||
|
||||
serviceAccountName: ${RUNNER_SERVICE_ACCOUNT_NAME}
|
||||
terminationGracePeriodSeconds: ${RUNNER_TERMINATION_GRACE_PERIOD_SECONDS}
|
||||
|
||||
env:
|
||||
- name: RUNNER_GRACEFUL_STOP_TIMEOUT
|
||||
value: "${RUNNER_GRACEFUL_STOP_TIMEOUT}"
|
||||
- name: ROLLING_UPDATE_PHASE
|
||||
value: "${ROLLING_UPDATE_PHASE}"
|
||||
- name: ARC_DOCKER_MTU_PROPAGATION
|
||||
value: "true"
|
||||
# https://github.com/docker/docs/issues/8663
|
||||
- name: DOCKER_DEFAULT_ADDRESS_POOL_BASE
|
||||
value: "172.17.0.0/12"
|
||||
- name: DOCKER_DEFAULT_ADDRESS_POOL_SIZE
|
||||
value: "24"
|
||||
- name: WAIT_FOR_DOCKER_SECONDS
|
||||
value: "3"
|
||||
|
||||
dockerMTU: 1400
|
||||
dockerEnv:
|
||||
- name: RUNNER_GRACEFUL_STOP_TIMEOUT
|
||||
value: "${RUNNER_GRACEFUL_STOP_TIMEOUT}"
|
||||
|
||||
# Fix the following no space left errors with rootless-dind runners that can happen while running buildx build:
|
||||
# ------
|
||||
# > [4/5] RUN go mod download:
|
||||
# ------
|
||||
# ERROR: failed to solve: failed to prepare yxsw8lv9hqnuafzlfta244l0z: mkdir /home/runner/.local/share/docker/vfs/dir/yxsw8lv9hqnuafzlfta244l0z/usr/local/go/src/cmd/compile/internal/types2/testdata: no space left on device
|
||||
# Error: Process completed with exit code 1.
|
||||
#
|
||||
volumeMounts:
|
||||
- name: rootless-dind-work-dir
|
||||
# Omit the /share/docker part of the /home/runner/.local/share/docker as
|
||||
# that part is created by dockerd.
|
||||
mountPath: /home/runner/.local
|
||||
readOnly: false
|
||||
volumes:
|
||||
- name: rootless-dind-work-dir
|
||||
ephemeral:
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
storageClassName: "${NAME}-rootless-dind-work-dir"
|
||||
resources:
|
||||
requests:
|
||||
storage: 3Gi
|
||||
|
||||
#
|
||||
# Non-standard working directory
|
||||
@@ -63,7 +112,7 @@ spec:
|
||||
# workDir: "/"
|
||||
|
||||
# # Uncomment the below to enable the kubernetes container mode
|
||||
# # See https://github.com/actions-runner-controller/actions-runner-controller#runner-with-k8s-jobs
|
||||
# # See https://github.com/actions/actions-runner-controller#runner-with-k8s-jobs
|
||||
containerMode: ${RUNNER_CONTAINER_MODE}
|
||||
workVolumeClaimTemplate:
|
||||
accessModes:
|
||||
@@ -72,7 +121,6 @@ spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
serviceAccountName: ${RUNNER_SERVICE_ACCOUNT_NAME}
|
||||
---
|
||||
apiVersion: actions.summerwind.dev/v1alpha1
|
||||
kind: HorizontalRunnerAutoscaler
|
||||
|
||||
46
acceptance/testdata/runnerset.envsubst.yaml
vendored
46
acceptance/testdata/runnerset.envsubst.yaml
vendored
@@ -54,6 +54,16 @@ provisioner: rancher.io/local-path
|
||||
reclaimPolicy: Retain
|
||||
volumeBindingMode: WaitForFirstConsumer
|
||||
---
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: ${NAME}-rootless-dind-work-dir
|
||||
labels:
|
||||
content: ${NAME}-rootless-dind-work-dir
|
||||
provisioner: rancher.io/local-path
|
||||
reclaimPolicy: Delete
|
||||
volumeBindingMode: WaitForFirstConsumer
|
||||
---
|
||||
apiVersion: actions.summerwind.dev/v1alpha1
|
||||
kind: RunnerSet
|
||||
metadata:
|
||||
@@ -113,10 +123,20 @@ spec:
|
||||
app: ${NAME}
|
||||
spec:
|
||||
serviceAccountName: ${RUNNER_SERVICE_ACCOUNT_NAME}
|
||||
terminationGracePeriodSeconds: ${RUNNER_TERMINATION_GRACE_PERIOD_SECONDS}
|
||||
containers:
|
||||
# # Uncomment only when non-dind-runner / you're using docker sidecar
|
||||
# - name: docker
|
||||
# # Image is required for the dind sidecar definition within RunnerSet spec
|
||||
# image: "docker:dind"
|
||||
# env:
|
||||
# - name: RUNNER_GRACEFUL_STOP_TIMEOUT
|
||||
# value: "${RUNNER_GRACEFUL_STOP_TIMEOUT}"
|
||||
- name: runner
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: RUNNER_GRACEFUL_STOP_TIMEOUT
|
||||
value: "${RUNNER_GRACEFUL_STOP_TIMEOUT}"
|
||||
- name: RUNNER_FEATURE_FLAG_EPHEMERAL
|
||||
value: "${RUNNER_FEATURE_FLAG_EPHEMERAL}"
|
||||
- name: GOMODCACHE
|
||||
@@ -168,6 +188,14 @@ spec:
|
||||
# # For buildx cache
|
||||
# - name: cache
|
||||
# mountPath: "/home/runner/.cache"
|
||||
|
||||
# For fixing no space left error on rootless dind runner
|
||||
- name: rootless-dind-work-dir
|
||||
# Omit the /share/docker part of the /home/runner/.local/share/docker as
|
||||
# that part is created by dockerd.
|
||||
mountPath: /home/runner/.local
|
||||
readOnly: false
|
||||
|
||||
# Comment out the ephemeral work volume if you're going to test the kubernetes container mode
|
||||
# volumes:
|
||||
# - name: work
|
||||
@@ -180,6 +208,24 @@ spec:
|
||||
# resources:
|
||||
# requests:
|
||||
# storage: 10Gi
|
||||
|
||||
# Fix the following no space left errors with rootless-dind runners that can happen while running buildx build:
|
||||
# ------
|
||||
# > [4/5] RUN go mod download:
|
||||
# ------
|
||||
# ERROR: failed to solve: failed to prepare yxsw8lv9hqnuafzlfta244l0z: mkdir /home/runner/.local/share/docker/vfs/dir/yxsw8lv9hqnuafzlfta244l0z/usr/local/go/src/cmd/compile/internal/types2/testdata: no space left on device
|
||||
# Error: Process completed with exit code 1.
|
||||
#
|
||||
volumes:
|
||||
- name: rootless-dind-work-dir
|
||||
ephemeral:
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
storageClassName: "${NAME}-rootless-dind-work-dir"
|
||||
resources:
|
||||
requests:
|
||||
storage: 3Gi
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: vol1
|
||||
|
||||
@@ -33,3 +33,23 @@ githubWebhookServer:
|
||||
protocol: TCP
|
||||
name: http
|
||||
nodePort: 31000
|
||||
actionsMetricsServer:
|
||||
imagePullSecrets: []
|
||||
logLevel: "-4"
|
||||
enabled: true
|
||||
labels: {}
|
||||
replicaCount: 1
|
||||
secret:
|
||||
enabled: true
|
||||
# create: true
|
||||
name: "actions-metrics-server"
|
||||
### GitHub Webhook Configuration
|
||||
#github_webhook_secret_token: ""
|
||||
service:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
nodePort: 31001
|
||||
|
||||
0
apis/actions.github.com/v1beta1/.keep
Normal file
0
apis/actions.github.com/v1beta1/.keep
Normal file
@@ -15,15 +15,15 @@ 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.21.1
|
||||
version: 0.22.0
|
||||
|
||||
# Used as the default manager tag value when no tag property is provided in the values.yaml
|
||||
appVersion: 0.26.0
|
||||
appVersion: 0.27.0
|
||||
|
||||
home: https://github.com/actions-runner-controller/actions-runner-controller
|
||||
home: https://github.com/actions/actions-runner-controller
|
||||
|
||||
sources:
|
||||
- https://github.com/actions-runner-controller/actions-runner-controller
|
||||
- https://github.com/actions/actions-runner-controller
|
||||
|
||||
maintainers:
|
||||
- name: actions-runner-controller
|
||||
|
||||
@@ -4,12 +4,12 @@ All additional docs are kept in the `docs/` folder, this README is solely for do
|
||||
|
||||
## Values
|
||||
|
||||
**_The values are documented as of HEAD, to review the configuration options for your chart version ensure you view this file at the relevant [tag](https://github.com/actions-runner-controller/actions-runner-controller/tags)_**
|
||||
**_The values are documented as of HEAD, to review the configuration options for your chart version ensure you view this file at the relevant [tag](https://github.com/actions/actions-runner-controller/tags)_**
|
||||
|
||||
> _Default values are the defaults set in the charts `values.yaml`, some properties have default configurations in the code for when the property is omitted or invalid_
|
||||
|
||||
| Key | Description | Default |
|
||||
|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|
|
||||
|----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|
|
||||
| `labels` | Set labels to apply to all resources in the chart | |
|
||||
| `replicaCount` | Set the number of controller pods | 1 |
|
||||
| `webhookPort` | Set the containerPort for the webhook Pod | 9443 |
|
||||
@@ -21,6 +21,7 @@ All additional docs are kept in the `docs/` folder, this README is solely for do
|
||||
| `githubUploadURL` | Override GitHub Upload URL to be used for GitHub API calls | |
|
||||
| `runnerGithubURL` | Override GitHub URL to be used by runners during registration | |
|
||||
| `logLevel` | Set the log level of the controller container | |
|
||||
| `logFormat` | Set the log format of the controller. Valid options are "text" and "json" | text |
|
||||
| `additionalVolumes` | Set additional volumes to add to the manager container | |
|
||||
| `additionalVolumeMounts` | Set additional volume mounts to add to the manager container | |
|
||||
| `authSecret.create` | Deploy the controller auth secret | false |
|
||||
@@ -76,8 +77,9 @@ All additional docs are kept in the `docs/` folder, this README is solely for do
|
||||
| `runner.statusUpdateHook.enabled` | Use custom RBAC for runners (role, role binding and service account), this will enable reporting runner statuses | false |
|
||||
| `admissionWebHooks.caBundle` | Base64-encoded PEM bundle containing the CA that signed the webhook's serving certificate | |
|
||||
| `githubWebhookServer.logLevel` | Set the log level of the githubWebhookServer container | |
|
||||
| `githubWebhookServer.logFormat` | Set the log format of the githubWebhookServer controller. Valid options are "text" and "json" | text |
|
||||
| `githubWebhookServer.replicaCount` | Set the number of webhook server pods | 1 |
|
||||
| `githubWebhookServer.useRunnerGroupsVisibility` | Enable supporting runner groups with custom visibility. This will incur in extra API calls and may blow up your budget. Currently, you also need to set `githubWebhookServer.secret.enabled` to enable this feature. | false |
|
||||
| `githubWebhookServer.useRunnerGroupsVisibility` | Enable supporting runner groups with custom visibility, you also need to set `githubWebhookServer.secret.enabled` to enable this feature. | false |
|
||||
| `githubWebhookServer.enabled` | Deploy the webhook server pod | false |
|
||||
| `githubWebhookServer.queueLimit` | Set the queue size limit in the githubWebhookServer | |
|
||||
| `githubWebhookServer.secret.enabled` | Passes the webhook hook secret to the github-webhook-server | false |
|
||||
@@ -110,3 +112,40 @@ All additional docs are kept in the `docs/` folder, this README is solely for do
|
||||
| `githubWebhookServer.podDisruptionBudget.enabled` | Enables a PDB to ensure HA of githubwebhook pods | false |
|
||||
| `githubWebhookServer.podDisruptionBudget.minAvailable` | Minimum number of pods that must be available after eviction | |
|
||||
| `githubWebhookServer.podDisruptionBudget.maxUnavailable` | Maximum number of pods that can be unavailable after eviction. Kubernetes 1.7+ required. | |
|
||||
| `actionsMetricsServer.logLevel` | Set the log level of the actionsMetricsServer container | |
|
||||
| `actionsMetricsServer.logFormat` | Set the log format of the actionsMetricsServer controller. Valid options are "text" and "json" | text |
|
||||
| `actionsMetricsServer.enabled` | Deploy the actions metrics server pod | false |
|
||||
| `actionsMetricsServer.secret.enabled` | Passes the webhook hook secret to the github-webhook-server | false |
|
||||
| `actionsMetricsServer.secret.create` | Deploy the webhook hook secret | false |
|
||||
| `actionsMetricsServer.secret.name` | Set the name of the webhook hook secret | github-webhook-server |
|
||||
| `actionsMetricsServer.secret.github_webhook_secret_token` | Set the webhook secret token value | |
|
||||
| `actionsMetricsServer.imagePullSecrets` | Specifies the secret to be used when pulling the actionsMetricsServer pod containers | |
|
||||
| `actionsMetricsServer.nameOverride` | Override the resource name prefix | |
|
||||
| `actionsMetricsServer.fullnameOverride` | Override the full resource names | |
|
||||
| `actionsMetricsServer.serviceAccount.create` | Deploy the actionsMetricsServer under a service account | true |
|
||||
| `actionsMetricsServer.serviceAccount.annotations` | Set annotations for the service account | |
|
||||
| `actionsMetricsServer.serviceAccount.name` | Set the service account name | |
|
||||
| `actionsMetricsServer.podAnnotations` | Set annotations for the actionsMetricsServer pod | |
|
||||
| `actionsMetricsServer.podLabels` | Set labels for the actionsMetricsServer pod | |
|
||||
| `actionsMetricsServer.podSecurityContext` | Set the security context to actionsMetricsServer pod | |
|
||||
| `actionsMetricsServer.securityContext` | Set the security context for each container in the actionsMetricsServer pod | |
|
||||
| `actionsMetricsServer.resources` | Set the actionsMetricsServer pod resources | |
|
||||
| `actionsMetricsServer.topologySpreadConstraints` | Set the actionsMetricsServer pod topologySpreadConstraints | |
|
||||
| `actionsMetricsServer.nodeSelector` | Set the actionsMetricsServer pod nodeSelector | |
|
||||
| `actionsMetricsServer.tolerations` | Set the actionsMetricsServer pod tolerations | |
|
||||
| `actionsMetricsServer.affinity` | Set the actionsMetricsServer pod affinity rules | |
|
||||
| `actionsMetricsServer.priorityClassName` | Set the actionsMetricsServer pod priorityClassName | |
|
||||
| `actionsMetricsServer.service.type` | Set actionsMetricsServer service type | |
|
||||
| `actionsMetricsServer.service.ports` | Set actionsMetricsServer service ports | `[{"port":80, "targetPort:"http", "protocol":"TCP", "name":"http"}]` |
|
||||
| `actionsMetricsServer.ingress.enabled` | Deploy an ingress kind for the actionsMetricsServer | false |
|
||||
| `actionsMetricsServer.ingress.annotations` | Set annotations for the ingress kind | |
|
||||
| `actionsMetricsServer.ingress.hosts` | Set hosts configuration for ingress | `[{"host": "chart-example.local", "paths": []}]` |
|
||||
| `actionsMetricsServer.ingress.tls` | Set tls configuration for ingress | |
|
||||
| `actionsMetricsServer.ingress.ingressClassName` | Set ingress class name | |
|
||||
| `actionsMetrics.serviceMonitor` | Deploy serviceMonitor kind for for use with prometheus-operator CRDs | false |
|
||||
| `actionsMetrics.serviceAnnotations` | Set annotations for the provisioned actions metrics service resource | |
|
||||
| `actionsMetrics.port` | Set port of actions metrics service | 8443 |
|
||||
| `actionsMetrics.proxy.enabled` | Deploy kube-rbac-proxy container in controller pod | true |
|
||||
| `actionsMetrics.proxy.image.repository` | The "repository/image" of the kube-proxy container | quay.io/brancz/kube-rbac-proxy |
|
||||
| `actionsMetrics.proxy.image.tag` | The tag of the kube-proxy image to use when pulling the container | v0.10.0 |
|
||||
| `actionsMetrics.serviceMonitorLabels` | Set labels to apply to ServiceMonitor resources | |
|
||||
|
||||
@@ -24,7 +24,7 @@ Due to the above you can't just do a `helm upgrade` to release the latest versio
|
||||
# REMEMBER TO UPDATE THE CHART_VERSION TO RELEVANT CHART VERISON!!!!
|
||||
CHART_VERSION=0.18.0
|
||||
|
||||
curl -L https://github.com/actions-runner-controller/actions-runner-controller/releases/download/actions-runner-controller-${CHART_VERSION}/actions-runner-controller-${CHART_VERSION}.tgz | tar zxv --strip 1 actions-runner-controller/crds
|
||||
curl -L https://github.com/actions/actions-runner-controller/releases/download/actions-runner-controller-${CHART_VERSION}/actions-runner-controller-${CHART_VERSION}.tgz | tar zxv --strip 1 actions-runner-controller/crds
|
||||
|
||||
kubectl replace -f crds/
|
||||
```
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "actions-runner-controller-actions-metrics-server.name" -}}
|
||||
{{- default .Chart.Name .Values.actionsMetricsServer.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "actions-runner-controller-actions-metrics-server.instance" -}}
|
||||
{{- printf "%s-%s" .Release.Name "actions-metrics-server" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "actions-runner-controller-actions-metrics-server.fullname" -}}
|
||||
{{- if .Values.actionsMetricsServer.fullnameOverride }}
|
||||
{{- .Values.actionsMetricsServer.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.actionsMetricsServer.nameOverride }}
|
||||
{{- $instance := include "actions-runner-controller-actions-metrics-server.instance" . }}
|
||||
{{- if contains $name $instance }}
|
||||
{{- $instance | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s-%s" .Release.Name $name "actions-metrics-server" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "actions-runner-controller-actions-metrics-server.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "actions-runner-controller-actions-metrics-server.name" . }}
|
||||
app.kubernetes.io/instance: {{ include "actions-runner-controller-actions-metrics-server.instance" . }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "actions-runner-controller-actions-metrics-server.serviceAccountName" -}}
|
||||
{{- if .Values.actionsMetricsServer.serviceAccount.create }}
|
||||
{{- default (include "actions-runner-controller-actions-metrics-server.fullname" .) .Values.actionsMetricsServer.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.actionsMetricsServer.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "actions-runner-controller-actions-metrics-server.secretName" -}}
|
||||
{{- default (include "actions-runner-controller-actions-metrics-server.fullname" .) .Values.actionsMetricsServer.secret.name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "actions-runner-controller-actions-metrics-server.roleName" -}}
|
||||
{{- include "actions-runner-controller-actions-metrics-server.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "actions-runner-controller-actions-metrics-server.serviceMonitorName" -}}
|
||||
{{- include "actions-runner-controller-actions-metrics-server.fullname" . | trunc 47 }}-service-monitor
|
||||
{{- end }}
|
||||
@@ -0,0 +1,162 @@
|
||||
{{- if .Values.actionsMetricsServer.enabled }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "actions-runner-controller-actions-metrics-server.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "actions-runner-controller.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.actionsMetricsServer.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.actionsMetricsServer.podAnnotations }}
|
||||
annotations:
|
||||
kubectl.kubernetes.io/default-logs-container: "github-webhook-server"
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 8 }}
|
||||
{{- with .Values.actionsMetricsServer.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.actionsMetricsServer.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "actions-runner-controller-actions-metrics-server.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.actionsMetricsServer.podSecurityContext | nindent 8 }}
|
||||
{{- with .Values.actionsMetricsServer.priorityClassName }}
|
||||
priorityClassName: "{{ . }}"
|
||||
{{- end }}
|
||||
containers:
|
||||
- args:
|
||||
{{- $metricsHost := .Values.metrics.proxy.enabled | ternary "127.0.0.1" "0.0.0.0" }}
|
||||
{{- $metricsPort := .Values.metrics.proxy.enabled | ternary "8080" .Values.metrics.port }}
|
||||
- "--metrics-addr={{ $metricsHost }}:{{ $metricsPort }}"
|
||||
{{- if .Values.actionsMetricsServer.logLevel }}
|
||||
- "--log-level={{ .Values.actionsMetricsServer.logLevel }}"
|
||||
{{- end }}
|
||||
{{- if .Values.runnerGithubURL }}
|
||||
- "--runner-github-url={{ .Values.runnerGithubURL }}"
|
||||
{{- end }}
|
||||
{{- if .Values.actionsMetricsServer.logFormat }}
|
||||
- "--log-format={{ .Values.actionsMetricsServer.logFormat }}"
|
||||
{{- end }}
|
||||
command:
|
||||
- "/actions-metrics-server"
|
||||
env:
|
||||
- name: GITHUB_WEBHOOK_SECRET_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: github_webhook_secret_token
|
||||
name: {{ include "actions-runner-controller-actions-metrics-server.secretName" . }}
|
||||
optional: true
|
||||
{{- if .Values.githubEnterpriseServerURL }}
|
||||
- name: GITHUB_ENTERPRISE_URL
|
||||
value: {{ .Values.githubEnterpriseServerURL }}
|
||||
{{- end }}
|
||||
{{- if .Values.githubURL }}
|
||||
- name: GITHUB_URL
|
||||
value: {{ .Values.githubURL }}
|
||||
{{- end }}
|
||||
{{- if .Values.githubUploadURL }}
|
||||
- name: GITHUB_UPLOAD_URL
|
||||
value: {{ .Values.githubUploadURL }}
|
||||
{{- end }}
|
||||
{{- if .Values.actionsMetricsServer.secret.enabled }}
|
||||
- name: GITHUB_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: github_token
|
||||
name: {{ include "actions-runner-controller.githubWebhookServerSecretName" . }}
|
||||
optional: true
|
||||
- name: GITHUB_APP_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: github_app_id
|
||||
name: {{ include "actions-runner-controller.githubWebhookServerSecretName" . }}
|
||||
optional: true
|
||||
- name: GITHUB_APP_INSTALLATION_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: github_app_installation_id
|
||||
name: {{ include "actions-runner-controller.githubWebhookServerSecretName" . }}
|
||||
optional: true
|
||||
- name: GITHUB_APP_PRIVATE_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: github_app_private_key
|
||||
name: {{ include "actions-runner-controller.githubWebhookServerSecretName" . }}
|
||||
optional: true
|
||||
{{- if .Values.authSecret.github_basicauth_username }}
|
||||
- name: GITHUB_BASICAUTH_USERNAME
|
||||
value: {{ .Values.authSecret.github_basicauth_username }}
|
||||
{{- end }}
|
||||
- name: GITHUB_BASICAUTH_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: github_basicauth_password
|
||||
name: {{ include "actions-runner-controller.secretName" . }}
|
||||
optional: true
|
||||
{{- end }}
|
||||
{{- range $key, $val := .Values.actionsMetricsServer.env }}
|
||||
- name: {{ $key }}
|
||||
value: {{ $val | quote }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (cat "v" .Chart.AppVersion | replace " " "") }}"
|
||||
name: actions-metrics-server
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
name: http
|
||||
protocol: TCP
|
||||
{{- if not .Values.metrics.proxy.enabled }}
|
||||
- containerPort: {{ .Values.metrics.port }}
|
||||
name: metrics-port
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.actionsMetricsServer.resources | nindent 12 }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.actionsMetricsServer.securityContext | nindent 12 }}
|
||||
{{- if .Values.metrics.proxy.enabled }}
|
||||
- args:
|
||||
- "--secure-listen-address=0.0.0.0:{{ .Values.metrics.port }}"
|
||||
- "--upstream=http://127.0.0.1:8080/"
|
||||
- "--logtostderr=true"
|
||||
- "--v=10"
|
||||
image: "{{ .Values.metrics.proxy.image.repository }}:{{ .Values.metrics.proxy.image.tag }}"
|
||||
name: kube-rbac-proxy
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.metrics.port }}
|
||||
name: metrics-port
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
terminationGracePeriodSeconds: 10
|
||||
{{- with .Values.actionsMetricsServer.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.actionsMetricsServer.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.actionsMetricsServer.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.actionsMetricsServer.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,47 @@
|
||||
{{- if .Values.actionsMetricsServer.ingress.enabled -}}
|
||||
{{- $fullName := include "actions-runner-controller-actions-metrics-server.fullname" . -}}
|
||||
{{- $svcPort := (index .Values.actionsMetricsServer.service.ports 0).port -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "actions-runner-controller.labels" . | nindent 4 }}
|
||||
{{- with .Values.actionsMetricsServer.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.actionsMetricsServer.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.actionsMetricsServer.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.actionsMetricsServer.ingress.ingressClassName }}
|
||||
ingressClassName: {{ . }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.actionsMetricsServer.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- if .extraPaths }}
|
||||
{{- toYaml .extraPaths | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,26 @@
|
||||
{{- if .Values.actionsMetricsServer.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "actions-runner-controller-actions-metrics-server.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "actions-runner-controller.labels" . | nindent 4 }}
|
||||
{{- if .Values.actionsMetricsServer.service.annotations }}
|
||||
annotations:
|
||||
{{ toYaml .Values.actionsMetricsServer.service.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.actionsMetricsServer.service.type }}
|
||||
ports:
|
||||
{{ range $_, $port := .Values.actionsMetricsServer.service.ports -}}
|
||||
- {{ $port | toYaml | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- if .Values.metrics.serviceMonitor }}
|
||||
- name: metrics-port
|
||||
port: {{ .Values.metrics.port }}
|
||||
targetPort: metrics-port
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
{{- if .Values.actionsMetricsServer.enabled -}}
|
||||
{{- if .Values.actionsMetricsServer.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "actions-runner-controller-actions-metrics-server.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "actions-runner-controller.labels" . | nindent 4 }}
|
||||
{{- with .Values.actionsMetricsServer.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,25 @@
|
||||
{{- if and .Values.actionsMetricsServer.enabled .Values.actionsMetrics.serviceMonitor }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "actions-runner-controller.labels" . | nindent 4 }}
|
||||
{{- with .Values.actionsMetricsServer.serviceMonitorLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
name: {{ include "actions-runner-controller-actions-metrics-server.serviceMonitorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
endpoints:
|
||||
- path: /metrics
|
||||
port: metrics-port
|
||||
{{- if .Values.actionsMetrics.proxy.enabled }}
|
||||
bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
scheme: https
|
||||
tlsConfig:
|
||||
insecureSkipVerify: true
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 6 }}
|
||||
{{- end }}
|
||||
@@ -67,6 +67,9 @@ spec:
|
||||
{{- if .Values.runner.statusUpdateHook.enabled }}
|
||||
- "--runner-status-update-hook"
|
||||
{{- end }}
|
||||
{{- if .Values.logFormat }}
|
||||
- "--log-format={{ .Values.logFormat }}"
|
||||
{{- end }}
|
||||
command:
|
||||
- "/manager"
|
||||
env:
|
||||
|
||||
@@ -51,6 +51,9 @@ spec:
|
||||
{{- if .Values.githubWebhookServer.queueLimit }}
|
||||
- "--queue-limit={{ .Values.githubWebhookServer.queueLimit }}"
|
||||
{{- end }}
|
||||
{{- if .Values.githubWebhookServer.logFormat }}
|
||||
- "--log-format={{ .Values.githubWebhookServer.logFormat }}"
|
||||
{{- end }}
|
||||
command:
|
||||
- "/github-webhook-server"
|
||||
env:
|
||||
|
||||
@@ -286,7 +286,7 @@ rules:
|
||||
{{- end }}
|
||||
{{- if .Values.rbac.allowGrantingKubernetesContainerModePermissions }}
|
||||
{{/* These permissions are required by ARC to create RBAC resources for the runner pod to use the kubernetes container mode. */}}
|
||||
{{/* See https://github.com/actions-runner-controller/actions-runner-controller/pull/1268/files#r917331632 */}}
|
||||
{{/* See https://github.com/actions/actions-runner-controller/pull/1268/files#r917331632 */}}
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
|
||||
@@ -53,7 +53,7 @@ webhooks:
|
||||
{{- end }}
|
||||
clientConfig:
|
||||
{{- if .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ quote .Values.admissionWebHooks.caBundle }}
|
||||
{{- else if not .Values.certManagerEnabled }}
|
||||
caBundle: {{ $ca.Cert | b64enc | quote }}
|
||||
{{- end }}
|
||||
@@ -83,7 +83,7 @@ webhooks:
|
||||
{{- end }}
|
||||
clientConfig:
|
||||
{{- if .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ quote .Values.admissionWebHooks.caBundle }}
|
||||
{{- else if not .Values.certManagerEnabled }}
|
||||
caBundle: {{ $ca.Cert | b64enc | quote }}
|
||||
{{- end }}
|
||||
@@ -113,7 +113,7 @@ webhooks:
|
||||
{{- end }}
|
||||
clientConfig:
|
||||
{{- if .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ quote .Values.admissionWebHooks.caBundle }}
|
||||
{{- else if not .Values.certManagerEnabled }}
|
||||
caBundle: {{ $ca.Cert | b64enc | quote }}
|
||||
{{- end }}
|
||||
@@ -156,7 +156,7 @@ webhooks:
|
||||
{{- end }}
|
||||
clientConfig:
|
||||
{{- if .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ quote .Values.admissionWebHooks.caBundle }}
|
||||
{{- else if not .Values.certManagerEnabled }}
|
||||
caBundle: {{ $ca.Cert | b64enc | quote }}
|
||||
{{- end }}
|
||||
@@ -186,7 +186,7 @@ webhooks:
|
||||
{{- end }}
|
||||
clientConfig:
|
||||
{{- if .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ quote .Values.admissionWebHooks.caBundle }}
|
||||
{{- else if not .Values.certManagerEnabled }}
|
||||
caBundle: {{ $ca.Cert | b64enc | quote }}
|
||||
{{- end }}
|
||||
@@ -216,7 +216,7 @@ webhooks:
|
||||
{{- end }}
|
||||
clientConfig:
|
||||
{{- if .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ .Values.admissionWebHooks.caBundle }}
|
||||
caBundle: {{ quote .Values.admissionWebHooks.caBundle }}
|
||||
{{- else if not .Values.certManagerEnabled }}
|
||||
caBundle: {{ $ca.Cert | b64enc | quote }}
|
||||
{{- end }}
|
||||
@@ -237,7 +237,7 @@ webhooks:
|
||||
resources:
|
||||
- runnerreplicasets
|
||||
sideEffects: None
|
||||
{{ if not (or .Values.admissionWebHooks.caBundle .Values.certManagerEnabled) }}
|
||||
{{ if not (or (hasKey .Values.admissionWebHooks "caBundle") .Values.certManagerEnabled) }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
|
||||
@@ -30,7 +30,7 @@ enableLeaderElection: true
|
||||
#
|
||||
# Do set authSecret.enabled=false and set env if you want full control over
|
||||
# the GitHub authn related envvars of the container.
|
||||
# See https://github.com/actions-runner-controller/actions-runner-controller/pull/937 for more details.
|
||||
# See https://github.com/actions/actions-runner-controller/pull/937 for more details.
|
||||
authSecret:
|
||||
enabled: true
|
||||
create: false
|
||||
@@ -70,7 +70,7 @@ rbac:
|
||||
# # This allows ARC to dynamically create a ServiceAccount and a Role for each Runner pod that uses "kubernetes" container mode,
|
||||
# # by extending ARC's manager role to have the same permissions required by the pod runs the runner agent in "kubernetes" container mode.
|
||||
# # Without this, Kubernetes blocks ARC to create the role to prevent a priviledge escalation.
|
||||
# # See https://github.com/actions-runner-controller/actions-runner-controller/pull/1268/files#r917327010
|
||||
# # See https://github.com/actions/actions-runner-controller/pull/1268/files#r917327010
|
||||
# allowGrantingKubernetesContainerModePermissions: true
|
||||
|
||||
serviceAccount:
|
||||
@@ -185,13 +185,18 @@ admissionWebHooks:
|
||||
#caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle containing the CA that signed the webhook's serving certificate>...tLS0K"
|
||||
|
||||
# There may be alternatives to setting `hostNetwork: true`, see
|
||||
# https://github.com/actions-runner-controller/actions-runner-controller/issues/1005#issuecomment-993097155
|
||||
# https://github.com/actions/actions-runner-controller/issues/1005#issuecomment-993097155
|
||||
#hostNetwork: true
|
||||
|
||||
## specify log format for actions runner controller. Valid options are "text" and "json"
|
||||
logFormat: text
|
||||
|
||||
githubWebhookServer:
|
||||
enabled: false
|
||||
replicaCount: 1
|
||||
useRunnerGroupsVisibility: false
|
||||
## specify log format for github webhook controller. Valid options are "text" and "json"
|
||||
logFormat: text
|
||||
secret:
|
||||
enabled: false
|
||||
create: false
|
||||
@@ -271,3 +276,100 @@ githubWebhookServer:
|
||||
# minAvailable: 1
|
||||
# maxUnavailable: 3
|
||||
# queueLimit: 100
|
||||
|
||||
actionsMetrics:
|
||||
serviceAnnotations: {}
|
||||
# Set serviceMonitor=true to create a service monitor
|
||||
# as a part of the helm release.
|
||||
# Do note that you also need actionsMetricsServer.enabled=true
|
||||
# to deploy the actions-metrics-server whose k8s service is referenced by the service monitor.
|
||||
serviceMonitor: false
|
||||
serviceMonitorLabels: {}
|
||||
port: 8443
|
||||
proxy:
|
||||
enabled: true
|
||||
image:
|
||||
repository: quay.io/brancz/kube-rbac-proxy
|
||||
tag: v0.13.1
|
||||
|
||||
actionsMetricsServer:
|
||||
enabled: false
|
||||
# DO NOT CHANGE THIS!
|
||||
# See the thread below for more context.
|
||||
# https://github.com/actions/actions-runner-controller/pull/1814#discussion_r974758924
|
||||
replicaCount: 1
|
||||
## specify log format for github webhook controller. Valid options are "text" and "json"
|
||||
logFormat: text
|
||||
secret:
|
||||
enabled: false
|
||||
create: false
|
||||
name: "actions-metrics-server"
|
||||
### GitHub Webhook Configuration
|
||||
github_webhook_secret_token: ""
|
||||
### GitHub Apps Configuration
|
||||
## NOTE: IDs MUST be strings, use quotes
|
||||
#github_app_id: ""
|
||||
#github_app_installation_id: ""
|
||||
#github_app_private_key: |
|
||||
### GitHub PAT Configuration
|
||||
#github_token: ""
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
securityContext: {}
|
||||
resources: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
priorityClassName: ""
|
||||
service:
|
||||
type: ClusterIP
|
||||
annotations: {}
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
#nodePort: someFixedPortForUseWithTerraformCdkCfnEtc
|
||||
ingress:
|
||||
enabled: false
|
||||
ingressClassName: ""
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths: []
|
||||
# - path: /*
|
||||
# pathType: ImplementationSpecific
|
||||
# Extra paths that are not automatically connected to the server. This is useful when working with annotation based services.
|
||||
extraPaths: []
|
||||
# - path: /*
|
||||
# backend:
|
||||
# serviceName: ssl-redirect
|
||||
# servicePort: use-annotation
|
||||
## for Kubernetes >=1.19 (when "networking.k8s.io/v1" is used)
|
||||
# - path: /*
|
||||
# pathType: Prefix
|
||||
# backend:
|
||||
# service:
|
||||
# name: ssl-redirect
|
||||
# port:
|
||||
# name: use-annotation
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
|
||||
226
cmd/actionsmetricsserver/main.go
Normal file
226
cmd/actionsmetricsserver/main.go
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
Copyright 2022 The actions-runner-controller authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
actionsv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/github"
|
||||
"github.com/actions/actions-runner-controller/logging"
|
||||
"github.com/actions/actions-runner-controller/pkg/actionsmetrics"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"sigs.k8s.io/controller-runtime/pkg/metrics"
|
||||
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/exec"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
var (
|
||||
scheme = runtime.NewScheme()
|
||||
)
|
||||
|
||||
const (
|
||||
webhookSecretTokenEnvName = "GITHUB_WEBHOOK_SECRET_TOKEN"
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
|
||||
_ = actionsv1alpha1.AddToScheme(scheme)
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
func main() {
|
||||
var (
|
||||
err error
|
||||
|
||||
webhookAddr string
|
||||
metricsAddr string
|
||||
|
||||
// The secret token of the GitHub Webhook. See https://docs.github.com/en/developers/webhooks-and-events/securing-your-webhooks
|
||||
webhookSecretToken string
|
||||
webhookSecretTokenEnv string
|
||||
|
||||
logLevel string
|
||||
logFormat string
|
||||
|
||||
ghClient *github.Client
|
||||
)
|
||||
|
||||
var c github.Config
|
||||
err = envconfig.Process("github", &c)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: processing environment variables: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
webhookSecretTokenEnv = os.Getenv(webhookSecretTokenEnvName)
|
||||
|
||||
flag.StringVar(&webhookAddr, "webhook-addr", ":8000", "The address the metric endpoint binds to.")
|
||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||
flag.StringVar(&logLevel, "log-level", logging.LogLevelDebug, `The verbosity of the logging. Valid values are "debug", "info", "warn", "error". Defaults to "debug".`)
|
||||
flag.StringVar(&webhookSecretToken, "github-webhook-secret-token", "", "The personal access token of GitHub.")
|
||||
flag.StringVar(&c.Token, "github-token", c.Token, "The personal access token of GitHub.")
|
||||
flag.Int64Var(&c.AppID, "github-app-id", c.AppID, "The application ID of GitHub App.")
|
||||
flag.Int64Var(&c.AppInstallationID, "github-app-installation-id", c.AppInstallationID, "The installation ID of GitHub App.")
|
||||
flag.StringVar(&c.AppPrivateKey, "github-app-private-key", c.AppPrivateKey, "The path of a private key file to authenticate as a GitHub App")
|
||||
flag.StringVar(&c.URL, "github-url", c.URL, "GitHub URL to be used for GitHub API calls")
|
||||
flag.StringVar(&c.UploadURL, "github-upload-url", c.UploadURL, "GitHub Upload URL to be used for GitHub API calls")
|
||||
flag.StringVar(&c.BasicauthUsername, "github-basicauth-username", c.BasicauthUsername, "Username for GitHub basic auth to use instead of PAT or GitHub APP in case it's running behind a proxy API")
|
||||
flag.StringVar(&c.BasicauthPassword, "github-basicauth-password", c.BasicauthPassword, "Password for GitHub basic auth to use instead of PAT or GitHub APP in case it's running behind a proxy API")
|
||||
flag.StringVar(&c.RunnerGitHubURL, "runner-github-url", c.RunnerGitHubURL, "GitHub URL to be used by runners during registration")
|
||||
flag.StringVar(&logFormat, "log-format", "text", `The log format. Valid options are "text" and "json". Defaults to "text"`)
|
||||
|
||||
flag.Parse()
|
||||
|
||||
logger, err := logging.NewLogger(logLevel, logFormat)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: creating logger: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
logger.WithName("setup")
|
||||
|
||||
if webhookSecretToken == "" && webhookSecretTokenEnv != "" {
|
||||
logger.Info(fmt.Sprintf("Using the value from %s for -github-webhook-secret-token", webhookSecretTokenEnvName))
|
||||
webhookSecretToken = webhookSecretTokenEnv
|
||||
}
|
||||
|
||||
if webhookSecretToken == "" {
|
||||
logger.Info(fmt.Sprintf("-github-webhook-secret-token and %s are missing or empty. Create one following https://docs.github.com/en/developers/webhooks-and-events/securing-your-webhooks and specify it via the flag or the envvar", webhookSecretTokenEnvName))
|
||||
}
|
||||
|
||||
ctrl.SetLogger(logger)
|
||||
|
||||
// Valid GitHub API credentials is required to call get workflow job logs
|
||||
if len(c.Token) > 0 || (c.AppID > 0 && c.AppInstallationID > 0 && c.AppPrivateKey != "") || (len(c.BasicauthUsername) > 0 && len(c.BasicauthPassword) > 0) {
|
||||
c.Log = &logger
|
||||
|
||||
ghClient, err = c.NewClient()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error: Client creation failed.", err)
|
||||
logger.Error(err, "unable to create controller", "controller", "Runner")
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
logger.Info("GitHub client is not initialized. Runner groups with custom visibility are not supported. If needed, please provide GitHub authentication. This will incur in extra GitHub API calls")
|
||||
}
|
||||
|
||||
eventReader := &actionsmetrics.EventReader{
|
||||
Log: ctrl.Log.WithName("workflowjobmetrics-eventreader"),
|
||||
GitHubClient: ghClient,
|
||||
Events: make(chan interface{}, 1024*1024),
|
||||
}
|
||||
|
||||
webhookServer := &actionsmetrics.WebhookServer{
|
||||
Log: ctrl.Log.WithName("workflowjobmetrics-webhookserver"),
|
||||
SecretKeyBytes: []byte(webhookSecretToken),
|
||||
GitHubClient: ghClient,
|
||||
EventHooks: []actionsmetrics.EventHook{eventReader.HandleWorkflowJobEvent},
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer cancel()
|
||||
defer wg.Done()
|
||||
eventReader.ProcessWorkflowJobEvents(ctx)
|
||||
}()
|
||||
|
||||
// Metrics Server
|
||||
|
||||
metricsHandler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{
|
||||
ErrorHandling: promhttp.HTTPErrorOnError,
|
||||
})
|
||||
|
||||
metricsMux := http.NewServeMux()
|
||||
metricsMux.HandleFunc("/", metricsHandler.ServeHTTP)
|
||||
|
||||
metricsSrv := http.Server{
|
||||
Addr: metricsAddr,
|
||||
Handler: metricsMux,
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer cancel()
|
||||
defer wg.Done()
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
|
||||
metricsSrv.Shutdown(context.Background())
|
||||
}()
|
||||
|
||||
if err := metricsSrv.ListenAndServe(); err != nil {
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
logger.Error(err, "problem running metrics server")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Webhook Server
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", webhookServer.Handle)
|
||||
|
||||
srv := http.Server{
|
||||
Addr: webhookAddr,
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer cancel()
|
||||
defer wg.Done()
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
|
||||
srv.Shutdown(context.Background())
|
||||
}()
|
||||
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
logger.Error(err, "problem running http server")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
<-ctrl.SetupSignalHandler().Done()
|
||||
cancel()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
@@ -26,11 +26,13 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
actionsv1alpha1 "github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/controllers"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/github"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/logging"
|
||||
actionsv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
actionssummerwindnet "github.com/actions/actions-runner-controller/controllers/actions.summerwind.net"
|
||||
"github.com/actions/actions-runner-controller/github"
|
||||
"github.com/actions/actions-runner-controller/logging"
|
||||
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/exec"
|
||||
@@ -42,7 +44,6 @@ import (
|
||||
|
||||
var (
|
||||
scheme = runtime.NewScheme()
|
||||
setupLog = ctrl.Log.WithName("setup")
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -71,6 +72,7 @@ func main() {
|
||||
|
||||
logLevel string
|
||||
queueLimit int
|
||||
logFormat string
|
||||
|
||||
ghClient *github.Client
|
||||
)
|
||||
@@ -88,7 +90,7 @@ func main() {
|
||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||
flag.StringVar(&watchNamespace, "watch-namespace", "", "The namespace to watch for HorizontalRunnerAutoscaler's to scale on Webhook. Set to empty for letting it watch for all namespaces.")
|
||||
flag.StringVar(&logLevel, "log-level", logging.LogLevelDebug, `The verbosity of the logging. Valid values are "debug", "info", "warn", "error". Defaults to "debug".`)
|
||||
flag.IntVar(&queueLimit, "queue-limit", controllers.DefaultQueueLimit, `The maximum length of the scale operation queue. The scale opration is enqueued per every matching webhook event, and the server returns a 500 HTTP status when the queue was already full on enqueue attempt.`)
|
||||
flag.IntVar(&queueLimit, "queue-limit", actionssummerwindnet.DefaultQueueLimit, `The maximum length of the scale operation queue. The scale opration is enqueued per every matching webhook event, and the server returns a 500 HTTP status when the queue was already full on enqueue attempt.`)
|
||||
flag.StringVar(&webhookSecretToken, "github-webhook-secret-token", "", "The personal access token of GitHub.")
|
||||
flag.StringVar(&c.Token, "github-token", c.Token, "The personal access token of GitHub.")
|
||||
flag.Int64Var(&c.AppID, "github-app-id", c.AppID, "The application ID of GitHub App.")
|
||||
@@ -99,26 +101,32 @@ func main() {
|
||||
flag.StringVar(&c.BasicauthUsername, "github-basicauth-username", c.BasicauthUsername, "Username for GitHub basic auth to use instead of PAT or GitHub APP in case it's running behind a proxy API")
|
||||
flag.StringVar(&c.BasicauthPassword, "github-basicauth-password", c.BasicauthPassword, "Password for GitHub basic auth to use instead of PAT or GitHub APP in case it's running behind a proxy API")
|
||||
flag.StringVar(&c.RunnerGitHubURL, "runner-github-url", c.RunnerGitHubURL, "GitHub URL to be used by runners during registration")
|
||||
flag.StringVar(&logFormat, "log-format", "text", `The log format. Valid options are "text" and "json". Defaults to "text"`)
|
||||
|
||||
flag.Parse()
|
||||
|
||||
logger, err := logging.NewLogger(logLevel, logFormat)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: creating logger: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
logger.WithName("setup")
|
||||
|
||||
if webhookSecretToken == "" && webhookSecretTokenEnv != "" {
|
||||
setupLog.Info(fmt.Sprintf("Using the value from %s for -github-webhook-secret-token", webhookSecretTokenEnvName))
|
||||
logger.Info(fmt.Sprintf("Using the value from %s for -github-webhook-secret-token", webhookSecretTokenEnvName))
|
||||
webhookSecretToken = webhookSecretTokenEnv
|
||||
}
|
||||
|
||||
if webhookSecretToken == "" {
|
||||
setupLog.Info(fmt.Sprintf("-github-webhook-secret-token and %s are missing or empty. Create one following https://docs.github.com/en/developers/webhooks-and-events/securing-your-webhooks and specify it via the flag or the envvar", webhookSecretTokenEnvName))
|
||||
logger.Info(fmt.Sprintf("-github-webhook-secret-token and %s are missing or empty. Create one following https://docs.github.com/en/developers/webhooks-and-events/securing-your-webhooks and specify it via the flag or the envvar", webhookSecretTokenEnvName))
|
||||
}
|
||||
|
||||
if watchNamespace == "" {
|
||||
setupLog.Info("-watch-namespace is empty. HorizontalRunnerAutoscalers in all the namespaces are watched, cached, and considered as scale targets.")
|
||||
logger.Info("-watch-namespace is empty. HorizontalRunnerAutoscalers in all the namespaces are watched, cached, and considered as scale targets.")
|
||||
} else {
|
||||
setupLog.Info("-watch-namespace is %q. Only HorizontalRunnerAutoscalers in %q are watched, cached, and considered as scale targets.")
|
||||
logger.Info("-watch-namespace is %q. Only HorizontalRunnerAutoscalers in %q are watched, cached, and considered as scale targets.")
|
||||
}
|
||||
|
||||
logger := logging.NewLogger(logLevel)
|
||||
|
||||
ctrl.SetLogger(logger)
|
||||
|
||||
// In order to support runner groups with custom visibility (selected repositories), we need to perform some GitHub API calls.
|
||||
@@ -132,11 +140,11 @@ func main() {
|
||||
ghClient, err = c.NewClient()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error: Client creation failed.", err)
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Runner")
|
||||
logger.Error(err, "unable to create controller", "controller", "Runner")
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
setupLog.Info("GitHub client is not initialized. Runner groups with custom visibility are not supported. If needed, please provide GitHub authentication. This will incur in extra GitHub API calls")
|
||||
logger.Info("GitHub client is not initialized. Runner groups with custom visibility are not supported. If needed, please provide GitHub authentication. This will incur in extra GitHub API calls")
|
||||
}
|
||||
|
||||
syncPeriod := 10 * time.Minute
|
||||
@@ -148,11 +156,11 @@ func main() {
|
||||
Port: 9443,
|
||||
})
|
||||
if err != nil {
|
||||
setupLog.Error(err, "unable to start manager")
|
||||
logger.Error(err, "unable to start manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
hraGitHubWebhook := &controllers.HorizontalRunnerAutoscalerGitHubWebhook{
|
||||
hraGitHubWebhook := &actionssummerwindnet.HorizontalRunnerAutoscalerGitHubWebhook{
|
||||
Name: "webhookbasedautoscaler",
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("webhookbasedautoscaler"),
|
||||
@@ -165,7 +173,7 @@ func main() {
|
||||
}
|
||||
|
||||
if err = hraGitHubWebhook.SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "webhookbasedautoscaler")
|
||||
logger.Error(err, "unable to create controller", "controller", "webhookbasedautoscaler")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -178,9 +186,9 @@ func main() {
|
||||
defer cancel()
|
||||
defer wg.Done()
|
||||
|
||||
setupLog.Info("starting webhook server")
|
||||
logger.Info("starting webhook server")
|
||||
if err := mgr.Start(ctx); err != nil {
|
||||
setupLog.Error(err, "problem running manager")
|
||||
logger.Error(err, "problem running manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
@@ -206,7 +214,7 @@ func main() {
|
||||
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
if !errors.Is(err, http.ErrServerClosed) {
|
||||
setupLog.Error(err, "problem running http server")
|
||||
logger.Error(err, "problem running http server")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -4,5 +4,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
images:
|
||||
- name: controller
|
||||
newName: summerwind/actions-runner-controller
|
||||
newTag: latest
|
||||
newName: jokicnikola07/actions-runner-controller
|
||||
newTag: dev
|
||||
|
||||
@@ -3,4 +3,4 @@ kind: Runner
|
||||
metadata:
|
||||
name: summerwind-actions-runner-controller
|
||||
spec:
|
||||
repository: actions-runner-controller/actions-runner-controller
|
||||
repository: actions/actions-runner-controller
|
||||
|
||||
@@ -6,4 +6,4 @@ spec:
|
||||
replicas: 2
|
||||
template:
|
||||
spec:
|
||||
repository: actions-runner-controller/actions-runner-controller
|
||||
repository: actions/actions-runner-controller
|
||||
|
||||
@@ -6,4 +6,4 @@ spec:
|
||||
replicas: 2
|
||||
template:
|
||||
spec:
|
||||
repository: actions-runner-controller/actions-runner-controller
|
||||
repository: actions/actions-runner-controller
|
||||
|
||||
@@ -3,4 +3,4 @@ The `contrib` directory is the place for sharing various example code for deploy
|
||||
Anything contained in this directory is provided as-is. The maintainers of `actions-runner-controller` is not yet commited to provide
|
||||
full support for using, fixing, and enhancing it. However, they will do their best effort to collect feedbacks from early adopters and advanced users like you, and may eventually consider graduating any of the examples as an official addition to the project.
|
||||
|
||||
See https://github.com/actions-runner-controller/actions-runner-controller/pull/1375#issuecomment-1258816470 and https://github.com/actions-runner-controller/actions-runner-controller/pull/1559#issuecomment-1258827496 for more context.
|
||||
See https://github.com/actions/actions-runner-controller/pull/1375#issuecomment-1258816470 and https://github.com/actions/actions-runner-controller/pull/1559#issuecomment-1258827496 for more context.
|
||||
|
||||
@@ -5,6 +5,6 @@ type: application
|
||||
version: 0.0.1
|
||||
appVersion: 2.290.1
|
||||
|
||||
home: https://github.com/actions-runner-controller/actions-runner-controller/tree/master/runner
|
||||
home: https://github.com/actions/actions-runner-controller/tree/master/runner
|
||||
sources:
|
||||
- https://github.com/actions-runner-controller/actions-runner-controller/tree/master/runner
|
||||
- https://github.com/actions/actions-runner-controller/tree/master/runner
|
||||
|
||||
@@ -4,7 +4,7 @@ All additional docs are kept in the `docs/` folder, this README is solely for do
|
||||
|
||||
## Values
|
||||
|
||||
**_The values are documented as of HEAD, to review the configuration options for your chart version ensure you view this file at the relevent [tag](https://github.com/actions-runner-controller/actions-runner-controller/tags)_**
|
||||
**_The values are documented as of HEAD, to review the configuration options for your chart version ensure you view this file at the relevent [tag](https://github.com/actions/actions-runner-controller/tags)_**
|
||||
|
||||
> _Default values are the defaults set in the charts values.yaml, some properties have default configurations in the code for when the property is omitted or invalid_
|
||||
|
||||
@@ -31,6 +31,6 @@ All additional docs are kept in the `docs/` folder, this README is solely for do
|
||||
| `autoscaler.enabled` | Enable the HorizontalRunnerAutoscaler, if its enabled then replica count will not be used | true |
|
||||
| `autoscaler.minReplicas` | Minimum no of replicas | 1 |
|
||||
| `autoscaler.maxReplicas` | Maximum no of replicas | 5 |
|
||||
| `autoscaler.scaleDownDelaySecondsAfterScaleOut` | [Anti-Flapping Configuration](https://github.com/actions-runner-controller/actions-runner-controller#anti-flapping-configuration) | 120 |
|
||||
| `autoscaler.metrics` | [Pull driven scaling](https://github.com/actions-runner-controller/actions-runner-controller#pull-driven-scaling) | default |
|
||||
| `autoscaler.scaleUpTriggers` | [Webhook driven scaling](https://github.com/actions-runner-controller/actions-runner-controller#webhook-driven-scaling) | |
|
||||
| `autoscaler.scaleDownDelaySecondsAfterScaleOut` | [Anti-Flapping Configuration](https://github.com/actions/actions-runner-controller#anti-flapping-configuration) | 120 |
|
||||
| `autoscaler.metrics` | [Pull driven scaling](https://github.com/actions/actions-runner-controller#pull-driven-scaling) | default |
|
||||
| `autoscaler.scaleUpTriggers` | [Webhook driven scaling](https://github.com/actions/actions-runner-controller#webhook-driven-scaling) | |
|
||||
|
||||
@@ -26,8 +26,8 @@ autoscaler:
|
||||
maxReplicas: 5
|
||||
scaleDownDelaySecondsAfterScaleOut: 120
|
||||
# metrics (pull method) / scaleUpTriggers (push method)
|
||||
# https://github.com/actions-runner-controller/actions-runner-controller#pull-driven-scaling
|
||||
# https://github.com/actions-runner-controller/actions-runner-controller#webhook-driven-scaling
|
||||
# https://github.com/actions/actions-runner-controller#pull-driven-scaling
|
||||
# https://github.com/actions/actions-runner-controller#webhook-driven-scaling
|
||||
metrics:
|
||||
- type: PercentageRunnersBusy
|
||||
scaleUpThreshold: '0.75'
|
||||
|
||||
0
controllers/actions.github.com/.keep
Normal file
0
controllers/actions.github.com/.keep
Normal file
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
prometheus_metrics "github.com/actions-runner-controller/actions-runner-controller/controllers/metrics"
|
||||
arcgithub "github.com/actions-runner-controller/actions-runner-controller/github"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
prometheus_metrics "github.com/actions/actions-runner-controller/controllers/actions.summerwind.net/metrics"
|
||||
arcgithub "github.com/actions/actions-runner-controller/github"
|
||||
"github.com/google/go-github/v47/github"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -34,7 +34,7 @@ func (r *HorizontalRunnerAutoscalerReconciler) suggestDesiredReplicas(ghc *arcgi
|
||||
numMetrics := len(metrics)
|
||||
if numMetrics == 0 {
|
||||
// We don't default to anything since ARC 0.23.0
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/issues/728
|
||||
// See https://github.com/actions/actions-runner-controller/issues/728
|
||||
return nil, nil
|
||||
} else if numMetrics > 2 {
|
||||
return nil, fmt.Errorf("too many autoscaling metrics configured: It must be 0 to 2, but got %d", numMetrics)
|
||||
@@ -99,7 +99,7 @@ func (r *HorizontalRunnerAutoscalerReconciler) suggestReplicasByQueuedAndInProgr
|
||||
|
||||
// In case it's an organizational runners deployment without any scaling metrics defined,
|
||||
// we assume that the desired replicas should always be `minReplicas + capacityReservedThroughWebhook`.
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/issues/377#issuecomment-793372693
|
||||
// See https://github.com/actions/actions-runner-controller/issues/377#issuecomment-793372693
|
||||
if metrics == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/github"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/github/fake"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/github"
|
||||
"github.com/actions/actions-runner-controller/github/fake"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import "time"
|
||||
|
||||
@@ -61,7 +61,7 @@ const (
|
||||
// In case it actually took more than DefaultRunnerPodRecreationDelayAfterWebhookScale for the workflow_job completion event to arrive,
|
||||
// ARC will recreate the completed runner(s), assuming something went wrong in either GitHub, your K8s cluster, or ARC, so ARC needs to resync anyway.
|
||||
//
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/pull/1180
|
||||
// See https://github.com/actions/actions-runner-controller/pull/1180
|
||||
DefaultRunnerPodRecreationDelayAfterWebhookScale = 10 * time.Minute
|
||||
|
||||
EnvVarRunnerName = "RUNNER_NAME"
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/go-logr/logr"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -190,7 +190,7 @@ func (s *batchScaler) batchScale(ctx context.Context, batch batchScaleOperation)
|
||||
after := len(copy.Spec.CapacityReservations)
|
||||
|
||||
s.Log.V(1).Info(
|
||||
fmt.Sprintf("Updating hra %s for capacityReservations update", hra.Name),
|
||||
fmt.Sprintf("Patching hra %s for capacityReservations update", hra.Name),
|
||||
"before", before,
|
||||
"expired", expired,
|
||||
"added", added,
|
||||
@@ -198,8 +198,8 @@ func (s *batchScaler) batchScale(ctx context.Context, batch batchScaleOperation)
|
||||
"after", after,
|
||||
)
|
||||
|
||||
if err := s.Client.Update(ctx, copy); err != nil {
|
||||
return fmt.Errorf("updating horizontalrunnerautoscaler to add capacity reservation: %w", err)
|
||||
if err := s.Client.Patch(ctx, copy, client.MergeFrom(&hra)); err != nil {
|
||||
return fmt.Errorf("patching horizontalrunnerautoscaler to add capacity reservation: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -36,9 +35,9 @@ import (
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/github"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/simulator"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/github"
|
||||
"github.com/actions/actions-runner-controller/simulator"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -175,56 +174,6 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||
enterpriseSlug := enterpriseEvent.Enterprise.Slug
|
||||
|
||||
switch e := event.(type) {
|
||||
case *gogithub.PushEvent:
|
||||
target, err = autoscaler.getScaleUpTarget(
|
||||
context.TODO(),
|
||||
log,
|
||||
e.Repo.GetName(),
|
||||
e.Repo.Owner.GetLogin(),
|
||||
e.Repo.Owner.GetType(),
|
||||
// Most go-github Event types don't seem to contain Enteprirse(.Slug) fields
|
||||
// we need, so we parse it by ourselves.
|
||||
enterpriseSlug,
|
||||
autoscaler.MatchPushEvent(e),
|
||||
)
|
||||
case *gogithub.PullRequestEvent:
|
||||
target, err = autoscaler.getScaleUpTarget(
|
||||
context.TODO(),
|
||||
log,
|
||||
e.Repo.GetName(),
|
||||
e.Repo.Owner.GetLogin(),
|
||||
e.Repo.Owner.GetType(),
|
||||
// Most go-github Event types don't seem to contain Enteprirse(.Slug) fields
|
||||
// we need, so we parse it by ourselves.
|
||||
enterpriseSlug,
|
||||
autoscaler.MatchPullRequestEvent(e),
|
||||
)
|
||||
|
||||
if pullRequest := e.PullRequest; pullRequest != nil {
|
||||
log = log.WithValues(
|
||||
"pullRequest.base.ref", e.PullRequest.Base.GetRef(),
|
||||
"action", e.GetAction(),
|
||||
)
|
||||
}
|
||||
case *gogithub.CheckRunEvent:
|
||||
target, err = autoscaler.getScaleUpTarget(
|
||||
context.TODO(),
|
||||
log,
|
||||
e.Repo.GetName(),
|
||||
e.Repo.Owner.GetLogin(),
|
||||
e.Repo.Owner.GetType(),
|
||||
// Most go-github Event types don't seem to contain Enteprirse(.Slug) fields
|
||||
// we need, so we parse it by ourselves.
|
||||
enterpriseSlug,
|
||||
autoscaler.MatchCheckRunEvent(e),
|
||||
)
|
||||
|
||||
if checkRun := e.GetCheckRun(); checkRun != nil {
|
||||
log = log.WithValues(
|
||||
"checkRun.status", checkRun.GetStatus(),
|
||||
"action", e.GetAction(),
|
||||
)
|
||||
}
|
||||
case *gogithub.WorkflowJobEvent:
|
||||
if workflowJob := e.GetWorkflowJob(); workflowJob != nil {
|
||||
log = log.WithValues(
|
||||
@@ -235,6 +184,8 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||
"repository.owner.type", e.Repo.Owner.GetType(),
|
||||
"enterprise.slug", enterpriseSlug,
|
||||
"action", e.GetAction(),
|
||||
"workflowJob.runID", e.WorkflowJob.GetRunID(),
|
||||
"workflowJob.ID", e.WorkflowJob.GetID(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -305,7 +256,7 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||
|
||||
if target == nil {
|
||||
log.V(1).Info(
|
||||
"Scale target not found. If this is unexpected, ensure that there is exactly one repository-wide or organizational runner deployment that matches this webhook event",
|
||||
"Scale target not found. If this is unexpected, ensure that there is exactly one repository-wide or organizational runner deployment that matches this webhook event. If --watch-namespace is set ensure this is configured correctly.",
|
||||
)
|
||||
|
||||
msg := "no horizontalrunnerautoscaler to scale for this github event"
|
||||
@@ -343,7 +294,7 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||
|
||||
msg := fmt.Sprintf("scaled %s by %d", target.Name, target.Amount)
|
||||
|
||||
autoscaler.Log.Info(msg)
|
||||
log.Info(msg)
|
||||
|
||||
if written, err := w.Write([]byte(msg)); err != nil {
|
||||
log.Error(err, "failed writing http response", "msg", msg, "written", written)
|
||||
@@ -381,24 +332,6 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) findHRAsByKey(ctx con
|
||||
return hras, nil
|
||||
}
|
||||
|
||||
func matchTriggerConditionAgainstEvent(types []string, eventAction *string) bool {
|
||||
if len(types) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
if eventAction == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, tpe := range types {
|
||||
if tpe == *eventAction {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type ScaleTarget struct {
|
||||
v1alpha1.HorizontalRunnerAutoscaler
|
||||
v1alpha1.ScaleUpTrigger
|
||||
@@ -406,72 +339,6 @@ type ScaleTarget struct {
|
||||
log *logr.Logger
|
||||
}
|
||||
|
||||
func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) searchScaleTargets(hras []v1alpha1.HorizontalRunnerAutoscaler, f func(v1alpha1.ScaleUpTrigger) bool) []ScaleTarget {
|
||||
var matched []ScaleTarget
|
||||
|
||||
for _, hra := range hras {
|
||||
if !hra.ObjectMeta.DeletionTimestamp.IsZero() {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, scaleUpTrigger := range hra.Spec.ScaleUpTriggers {
|
||||
if !f(scaleUpTrigger) {
|
||||
continue
|
||||
}
|
||||
|
||||
matched = append(matched, ScaleTarget{
|
||||
HorizontalRunnerAutoscaler: hra,
|
||||
ScaleUpTrigger: scaleUpTrigger,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return matched
|
||||
}
|
||||
|
||||
func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getScaleTarget(ctx context.Context, name string, f func(v1alpha1.ScaleUpTrigger) bool) (*ScaleTarget, error) {
|
||||
hras, err := autoscaler.findHRAsByKey(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
autoscaler.Log.V(1).Info(fmt.Sprintf("Found %d HRAs by key", len(hras)), "key", name)
|
||||
|
||||
targets := autoscaler.searchScaleTargets(hras, f)
|
||||
|
||||
n := len(targets)
|
||||
|
||||
if n == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if n > 1 {
|
||||
var scaleTargetIDs []string
|
||||
|
||||
for _, t := range targets {
|
||||
scaleTargetIDs = append(scaleTargetIDs, t.HorizontalRunnerAutoscaler.Name)
|
||||
}
|
||||
|
||||
autoscaler.Log.Info(
|
||||
"Found too many scale targets: "+
|
||||
"It must be exactly one to avoid ambiguity. "+
|
||||
"Either set Namespace for the webhook-based autoscaler to let it only find HRAs in the namespace, "+
|
||||
"or update Repository, Organization, or Enterprise fields in your RunnerDeployment resources to fix the ambiguity.",
|
||||
"scaleTargets", strings.Join(scaleTargetIDs, ","))
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &targets[0], nil
|
||||
}
|
||||
|
||||
func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getScaleUpTarget(ctx context.Context, log logr.Logger, repo, owner, ownerType, enterprise string, f func(v1alpha1.ScaleUpTrigger) bool) (*ScaleTarget, error) {
|
||||
scaleTarget := func(value string) (*ScaleTarget, error) {
|
||||
return autoscaler.getScaleTarget(ctx, value, f)
|
||||
}
|
||||
return autoscaler.getScaleUpTargetWithFunction(ctx, log, repo, owner, ownerType, enterprise, scaleTarget)
|
||||
}
|
||||
|
||||
func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getJobScaleUpTargetForRepoOrOrg(
|
||||
ctx context.Context, log logr.Logger, repo, owner, ownerType, enterprise string, labels []string,
|
||||
) (*ScaleTarget, error) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
actionsv1alpha1 "github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
actionsv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/google/go-github/v47/github"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -30,78 +30,6 @@ func init() {
|
||||
_ = actionsv1alpha1.AddToScheme(sc)
|
||||
}
|
||||
|
||||
func TestOrgWebhookCheckRun(t *testing.T) {
|
||||
f, err := os.Open("testdata/org_webhook_check_run_payload.json")
|
||||
if err != nil {
|
||||
t.Fatalf("could not open the fixture: %s", err)
|
||||
}
|
||||
defer f.Close()
|
||||
var e github.CheckRunEvent
|
||||
if err := json.NewDecoder(f).Decode(&e); err != nil {
|
||||
t.Fatalf("invalid json: %s", err)
|
||||
}
|
||||
testServer(t,
|
||||
"check_run",
|
||||
&e,
|
||||
200,
|
||||
"no horizontalrunnerautoscaler to scale for this github event",
|
||||
)
|
||||
}
|
||||
|
||||
func TestRepoWebhookCheckRun(t *testing.T) {
|
||||
f, err := os.Open("testdata/repo_webhook_check_run_payload.json")
|
||||
if err != nil {
|
||||
t.Fatalf("could not open the fixture: %s", err)
|
||||
}
|
||||
defer f.Close()
|
||||
var e github.CheckRunEvent
|
||||
if err := json.NewDecoder(f).Decode(&e); err != nil {
|
||||
t.Fatalf("invalid json: %s", err)
|
||||
}
|
||||
testServer(t,
|
||||
"check_run",
|
||||
&e,
|
||||
200,
|
||||
"no horizontalrunnerautoscaler to scale for this github event",
|
||||
)
|
||||
}
|
||||
|
||||
func TestWebhookPullRequest(t *testing.T) {
|
||||
testServer(t,
|
||||
"pull_request",
|
||||
&github.PullRequestEvent{
|
||||
PullRequest: &github.PullRequest{
|
||||
Base: &github.PullRequestBranch{
|
||||
Ref: github.String("main"),
|
||||
},
|
||||
},
|
||||
Repo: &github.Repository{
|
||||
Name: github.String("myorg/myrepo"),
|
||||
Organization: &github.Organization{
|
||||
Name: github.String("myorg"),
|
||||
},
|
||||
},
|
||||
Action: github.String("created"),
|
||||
},
|
||||
200,
|
||||
"no horizontalrunnerautoscaler to scale for this github event",
|
||||
)
|
||||
}
|
||||
|
||||
func TestWebhookPush(t *testing.T) {
|
||||
testServer(t,
|
||||
"push",
|
||||
&github.PushEvent{
|
||||
Repo: &github.PushEventRepository{
|
||||
Name: github.String("myrepo"),
|
||||
Organization: github.String("myorg"),
|
||||
},
|
||||
},
|
||||
200,
|
||||
"no horizontalrunnerautoscaler to scale for this github event",
|
||||
)
|
||||
}
|
||||
|
||||
func TestWebhookPing(t *testing.T) {
|
||||
testServer(t,
|
||||
"ping",
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -35,9 +35,9 @@ import (
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/controllers/metrics"
|
||||
arcgithub "github.com/actions-runner-controller/actions-runner-controller/github"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/controllers/actions.summerwind.net/metrics"
|
||||
arcgithub "github.com/actions/actions-runner-controller/github"
|
||||
)
|
||||
|
||||
const (
|
||||
629
controllers/actions.summerwind.net/integration_test.go
Normal file
629
controllers/actions.summerwind.net/integration_test.go
Normal file
@@ -0,0 +1,629 @@
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"time"
|
||||
|
||||
github2 "github.com/actions/actions-runner-controller/github"
|
||||
"github.com/google/go-github/v47/github"
|
||||
|
||||
"github.com/actions/actions-runner-controller/github/fake"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
actionsv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
)
|
||||
|
||||
type testEnvironment struct {
|
||||
Namespace *corev1.Namespace
|
||||
Responses *fake.FixedResponses
|
||||
|
||||
webhookServer *httptest.Server
|
||||
ghClient *github2.Client
|
||||
fakeRunnerList *fake.RunnersList
|
||||
fakeGithubServer *httptest.Server
|
||||
}
|
||||
|
||||
var (
|
||||
workflowRunsFor3Replicas = `{"total_count": 5, "workflow_runs":[{"status":"queued"}, {"status":"queued"}, {"status":"in_progress"}, {"status":"in_progress"}, {"status":"completed"}]}"`
|
||||
workflowRunsFor3Replicas_queued = `{"total_count": 2, "workflow_runs":[{"status":"queued"}, {"status":"queued"}]}"`
|
||||
workflowRunsFor3Replicas_in_progress = `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"`
|
||||
)
|
||||
|
||||
// SetupIntegrationTest will set up a testing environment.
|
||||
// This includes:
|
||||
// * creating a Namespace to be used during the test
|
||||
// * starting all the reconcilers
|
||||
// * stopping all the reconcilers after the test ends
|
||||
// Call this function at the start of each of your tests.
|
||||
func SetupIntegrationTest(ctx2 context.Context) *testEnvironment {
|
||||
var ctx context.Context
|
||||
var cancel func()
|
||||
ns := &corev1.Namespace{}
|
||||
|
||||
env := &testEnvironment{
|
||||
Namespace: ns,
|
||||
webhookServer: nil,
|
||||
ghClient: nil,
|
||||
}
|
||||
|
||||
BeforeEach(func() {
|
||||
ctx, cancel = context.WithCancel(ctx2)
|
||||
*ns = corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "testns-" + randStringRunes(5)},
|
||||
}
|
||||
|
||||
err := k8sClient.Create(ctx, ns)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
|
||||
|
||||
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
|
||||
Namespace: ns.Name,
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to create manager")
|
||||
|
||||
responses := &fake.FixedResponses{}
|
||||
responses.ListRunners = fake.DefaultListRunnersHandler()
|
||||
responses.ListRepositoryWorkflowRuns = &fake.Handler{
|
||||
Status: 200,
|
||||
Body: workflowRunsFor3Replicas,
|
||||
Statuses: map[string]string{
|
||||
"queued": workflowRunsFor3Replicas_queued,
|
||||
"in_progress": workflowRunsFor3Replicas_in_progress,
|
||||
},
|
||||
}
|
||||
fakeRunnerList := fake.NewRunnersList()
|
||||
responses.ListRunners = fakeRunnerList.HandleList()
|
||||
fakeGithubServer := fake.NewServer(fake.WithFixedResponses(responses))
|
||||
|
||||
env.Responses = responses
|
||||
env.fakeRunnerList = fakeRunnerList
|
||||
env.fakeGithubServer = fakeGithubServer
|
||||
env.ghClient = newGithubClient(fakeGithubServer)
|
||||
|
||||
controllerName := func(name string) string {
|
||||
return fmt.Sprintf("%s%s", ns.Name, name)
|
||||
}
|
||||
|
||||
multiClient := NewMultiGitHubClient(mgr.GetClient(), env.ghClient)
|
||||
|
||||
runnerController := &RunnerReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: scheme.Scheme,
|
||||
Log: logf.Log,
|
||||
Recorder: mgr.GetEventRecorderFor("runnerreplicaset-controller"),
|
||||
GitHubClient: multiClient,
|
||||
RunnerImage: "example/runner:test",
|
||||
DockerImage: "example/docker:test",
|
||||
Name: controllerName("runner"),
|
||||
RegistrationRecheckInterval: time.Millisecond * 100,
|
||||
RegistrationRecheckJitter: time.Millisecond * 10,
|
||||
UnregistrationRetryDelay: 1 * time.Second,
|
||||
}
|
||||
err = runnerController.SetupWithManager(mgr)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to setup runner controller")
|
||||
|
||||
replicasetController := &RunnerReplicaSetReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: scheme.Scheme,
|
||||
Log: logf.Log,
|
||||
Recorder: mgr.GetEventRecorderFor("runnerreplicaset-controller"),
|
||||
Name: controllerName("runnerreplicaset"),
|
||||
}
|
||||
err = replicasetController.SetupWithManager(mgr)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to setup runnerreplicaset controller")
|
||||
|
||||
deploymentsController := &RunnerDeploymentReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: scheme.Scheme,
|
||||
Log: logf.Log,
|
||||
Recorder: mgr.GetEventRecorderFor("runnerdeployment-controller"),
|
||||
Name: controllerName("runnnerdeployment"),
|
||||
}
|
||||
err = deploymentsController.SetupWithManager(mgr)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to setup runnerdeployment controller")
|
||||
|
||||
autoscalerController := &HorizontalRunnerAutoscalerReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: scheme.Scheme,
|
||||
Log: logf.Log,
|
||||
GitHubClient: multiClient,
|
||||
Recorder: mgr.GetEventRecorderFor("horizontalrunnerautoscaler-controller"),
|
||||
Name: controllerName("horizontalrunnerautoscaler"),
|
||||
}
|
||||
err = autoscalerController.SetupWithManager(mgr)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to setup autoscaler controller")
|
||||
|
||||
autoscalerWebhook := &HorizontalRunnerAutoscalerGitHubWebhook{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: scheme.Scheme,
|
||||
Log: logf.Log,
|
||||
Recorder: mgr.GetEventRecorderFor("horizontalrunnerautoscaler-controller"),
|
||||
Name: controllerName("horizontalrunnerautoscalergithubwebhook"),
|
||||
Namespace: ns.Name,
|
||||
}
|
||||
err = autoscalerWebhook.SetupWithManager(mgr)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to setup autoscaler webhook")
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", autoscalerWebhook.Handle)
|
||||
|
||||
env.webhookServer = httptest.NewServer(mux)
|
||||
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
|
||||
err := mgr.Start(ctx)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to start manager")
|
||||
}()
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
defer cancel()
|
||||
|
||||
env.fakeGithubServer.Close()
|
||||
env.webhookServer.Close()
|
||||
|
||||
err := k8sClient.Delete(ctx, ns)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to delete test namespace")
|
||||
})
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
var _ = Context("INTEGRATION: Inside of a new namespace", func() {
|
||||
ctx := context.TODO()
|
||||
env := SetupIntegrationTest(ctx)
|
||||
ns := env.Namespace
|
||||
|
||||
Describe("when no existing resources exist", func() {
|
||||
|
||||
It("should create and scale organization's repository runners on workflow_job event", func() {
|
||||
name := "example-runnerdeploy"
|
||||
|
||||
{
|
||||
rd := &actionsv1alpha1.RunnerDeployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns.Name,
|
||||
},
|
||||
Spec: actionsv1alpha1.RunnerDeploymentSpec{
|
||||
Replicas: intPtr(1),
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Template: actionsv1alpha1.RunnerTemplate{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Spec: actionsv1alpha1.RunnerSpec{
|
||||
RunnerConfig: actionsv1alpha1.RunnerConfig{
|
||||
Repository: "test/valid",
|
||||
Image: "bar",
|
||||
Group: "baz",
|
||||
},
|
||||
RunnerPodSpec: actionsv1alpha1.RunnerPodSpec{
|
||||
Env: []corev1.EnvVar{
|
||||
{Name: "FOO", Value: "FOOVALUE"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ExpectCreate(ctx, rd, "test RunnerDeployment")
|
||||
ExpectRunnerSetsCountEventuallyEquals(ctx, ns.Name, 1)
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 1)
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(1, "count of fake list runners")
|
||||
}
|
||||
|
||||
// Scale-up to 1 replica via ScaleUpTriggers.GitHubEvent.WorkflowJob based scaling
|
||||
{
|
||||
hra := &actionsv1alpha1.HorizontalRunnerAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns.Name,
|
||||
},
|
||||
Spec: actionsv1alpha1.HorizontalRunnerAutoscalerSpec{
|
||||
ScaleTargetRef: actionsv1alpha1.ScaleTargetRef{
|
||||
Name: name,
|
||||
},
|
||||
MinReplicas: intPtr(1),
|
||||
MaxReplicas: intPtr(5),
|
||||
ScaleDownDelaySecondsAfterScaleUp: intPtr(1),
|
||||
ScaleUpTriggers: []actionsv1alpha1.ScaleUpTrigger{
|
||||
{
|
||||
GitHubEvent: &actionsv1alpha1.GitHubEventScaleUpTriggerSpec{
|
||||
WorkflowJob: &actionsv1alpha1.WorkflowJobSpec{},
|
||||
},
|
||||
Amount: 1,
|
||||
Duration: metav1.Duration{Duration: time.Minute},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ExpectCreate(ctx, hra, "test HorizontalRunnerAutoscaler")
|
||||
|
||||
ExpectRunnerSetsCountEventuallyEquals(ctx, ns.Name, 1)
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 1)
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(1, "count of fake list runners")
|
||||
}
|
||||
|
||||
// Scale-up to 2 replicas on first workflow_job.queued webhook event
|
||||
{
|
||||
env.SendWorkflowJobEvent("test", "valid", "queued", []string{"self-hosted"}, int64(1234), int64(4321))
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 2, "runners after first webhook event")
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(2, "count of fake list runners")
|
||||
}
|
||||
|
||||
// Scale-up to 3 replicas on second workflow_job.queued webhook event
|
||||
{
|
||||
env.SendWorkflowJobEvent("test", "valid", "queued", []string{"self-hosted"}, int64(1234), int64(4321))
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 3, "runners after second webhook event")
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(3, "count of fake list runners")
|
||||
}
|
||||
|
||||
// Do not scale-up on third workflow_job.queued webhook event
|
||||
// repo "example" doesn't match our Spec
|
||||
{
|
||||
env.SendWorkflowJobEvent("test", "example", "queued", []string{"self-hosted"}, int64(1234), int64(4321))
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 3, "runners after third webhook event")
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(3, "count of fake list runners")
|
||||
}
|
||||
})
|
||||
|
||||
It("should be able to scale visible organization runner group with default labels", func() {
|
||||
name := "example-runnerdeploy"
|
||||
|
||||
{
|
||||
rd := &actionsv1alpha1.RunnerDeployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns.Name,
|
||||
},
|
||||
Spec: actionsv1alpha1.RunnerDeploymentSpec{
|
||||
Replicas: intPtr(1),
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Template: actionsv1alpha1.RunnerTemplate{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Spec: actionsv1alpha1.RunnerSpec{
|
||||
RunnerConfig: actionsv1alpha1.RunnerConfig{
|
||||
Repository: "test/valid",
|
||||
Image: "bar",
|
||||
Group: "baz",
|
||||
},
|
||||
RunnerPodSpec: actionsv1alpha1.RunnerPodSpec{
|
||||
Env: []corev1.EnvVar{
|
||||
{Name: "FOO", Value: "FOOVALUE"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ExpectCreate(ctx, rd, "test RunnerDeployment")
|
||||
|
||||
hra := &actionsv1alpha1.HorizontalRunnerAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns.Name,
|
||||
},
|
||||
Spec: actionsv1alpha1.HorizontalRunnerAutoscalerSpec{
|
||||
ScaleTargetRef: actionsv1alpha1.ScaleTargetRef{
|
||||
Name: name,
|
||||
},
|
||||
MinReplicas: intPtr(1),
|
||||
MaxReplicas: intPtr(5),
|
||||
ScaleDownDelaySecondsAfterScaleUp: intPtr(1),
|
||||
ScaleUpTriggers: []actionsv1alpha1.ScaleUpTrigger{
|
||||
{
|
||||
GitHubEvent: &actionsv1alpha1.GitHubEventScaleUpTriggerSpec{
|
||||
WorkflowJob: &actionsv1alpha1.WorkflowJobSpec{},
|
||||
},
|
||||
Amount: 1,
|
||||
Duration: metav1.Duration{Duration: time.Minute},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ExpectCreate(ctx, hra, "test HorizontalRunnerAutoscaler")
|
||||
|
||||
ExpectRunnerSetsCountEventuallyEquals(ctx, ns.Name, 1)
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 1)
|
||||
}
|
||||
|
||||
{
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(1, "count of fake list runners")
|
||||
}
|
||||
|
||||
// Scale-up to 2 replicas on first workflow_job webhook event
|
||||
{
|
||||
env.SendWorkflowJobEvent("test", "valid", "queued", []string{"self-hosted"}, int64(1234), int64(4321))
|
||||
ExpectRunnerSetsCountEventuallyEquals(ctx, ns.Name, 1, "runner sets after webhook")
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 2, "runners after first webhook event")
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(2, "count of fake list runners")
|
||||
}
|
||||
})
|
||||
|
||||
It("should be able to scale visible organization runner group with custom labels", func() {
|
||||
name := "example-runnerdeploy"
|
||||
|
||||
{
|
||||
rd := &actionsv1alpha1.RunnerDeployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns.Name,
|
||||
},
|
||||
Spec: actionsv1alpha1.RunnerDeploymentSpec{
|
||||
Replicas: intPtr(1),
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Template: actionsv1alpha1.RunnerTemplate{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Spec: actionsv1alpha1.RunnerSpec{
|
||||
RunnerConfig: actionsv1alpha1.RunnerConfig{
|
||||
Repository: "test/valid",
|
||||
Image: "bar",
|
||||
Group: "baz",
|
||||
Labels: []string{"custom-label"},
|
||||
},
|
||||
RunnerPodSpec: actionsv1alpha1.RunnerPodSpec{
|
||||
Env: []corev1.EnvVar{
|
||||
{Name: "FOO", Value: "FOOVALUE"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ExpectCreate(ctx, rd, "test RunnerDeployment")
|
||||
|
||||
hra := &actionsv1alpha1.HorizontalRunnerAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns.Name,
|
||||
},
|
||||
Spec: actionsv1alpha1.HorizontalRunnerAutoscalerSpec{
|
||||
ScaleTargetRef: actionsv1alpha1.ScaleTargetRef{
|
||||
Name: name,
|
||||
},
|
||||
MinReplicas: intPtr(1),
|
||||
MaxReplicas: intPtr(5),
|
||||
ScaleDownDelaySecondsAfterScaleUp: intPtr(1),
|
||||
ScaleUpTriggers: []actionsv1alpha1.ScaleUpTrigger{
|
||||
{
|
||||
GitHubEvent: &actionsv1alpha1.GitHubEventScaleUpTriggerSpec{
|
||||
WorkflowJob: &actionsv1alpha1.WorkflowJobSpec{},
|
||||
},
|
||||
Amount: 1,
|
||||
Duration: metav1.Duration{Duration: time.Minute},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ExpectCreate(ctx, hra, "test HorizontalRunnerAutoscaler")
|
||||
|
||||
ExpectRunnerSetsCountEventuallyEquals(ctx, ns.Name, 1)
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 1)
|
||||
}
|
||||
|
||||
{
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(1, "count of fake list runners")
|
||||
}
|
||||
|
||||
// Scale-up to 2 replicas on first workflow_job webhook event
|
||||
{
|
||||
env.SendWorkflowJobEvent("test", "valid", "queued", []string{"custom-label"}, int64(1234), int64(4321))
|
||||
ExpectRunnerSetsCountEventuallyEquals(ctx, ns.Name, 1, "runner sets after webhook")
|
||||
ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx, ns.Name, 2, "runners after first webhook event")
|
||||
env.ExpectRegisteredNumberCountEventuallyEquals(2, "count of fake list runners")
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
func ExpectHRADesiredReplicasEquals(ctx context.Context, ns, name string, desired int, optionalDescriptions ...interface{}) {
|
||||
var rd actionsv1alpha1.HorizontalRunnerAutoscaler
|
||||
|
||||
err := k8sClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, &rd)
|
||||
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to get test HRA resource")
|
||||
|
||||
replicas := rd.Status.DesiredReplicas
|
||||
|
||||
ExpectWithOffset(1, *replicas).To(Equal(desired), optionalDescriptions...)
|
||||
}
|
||||
|
||||
func (env *testEnvironment) ExpectRegisteredNumberCountEventuallyEquals(want int, optionalDescriptions ...interface{}) {
|
||||
EventuallyWithOffset(
|
||||
1,
|
||||
func() int {
|
||||
env.SyncRunnerRegistrations()
|
||||
|
||||
rs, err := env.ghClient.ListRunners(context.Background(), "", "", "test/valid")
|
||||
Expect(err).NotTo(HaveOccurred(), "verifying list fake runners response")
|
||||
|
||||
return len(rs)
|
||||
},
|
||||
time.Second*10, time.Millisecond*500).Should(Equal(want), optionalDescriptions...)
|
||||
}
|
||||
|
||||
func (env *testEnvironment) SendWorkflowJobEvent(org, repo, statusAndAction string, labels []string, runID int64, ID int64) {
|
||||
resp, err := sendWebhook(env.webhookServer, "workflow_job", &github.WorkflowJobEvent{
|
||||
WorkflowJob: &github.WorkflowJob{
|
||||
ID: &ID,
|
||||
RunID: &runID,
|
||||
Status: &statusAndAction,
|
||||
Labels: labels,
|
||||
},
|
||||
Org: &github.Organization{
|
||||
Login: github.String(org),
|
||||
},
|
||||
Repo: &github.Repository{
|
||||
Name: github.String(repo),
|
||||
Owner: &github.User{
|
||||
Login: github.String(org),
|
||||
Type: github.String("Organization"),
|
||||
},
|
||||
},
|
||||
Action: github.String(statusAndAction),
|
||||
})
|
||||
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to send workflow_job event")
|
||||
|
||||
ExpectWithOffset(1, resp.StatusCode).To(Equal(200))
|
||||
}
|
||||
|
||||
func (env *testEnvironment) SyncRunnerRegistrations() {
|
||||
var runnerList actionsv1alpha1.RunnerList
|
||||
|
||||
err := k8sClient.List(context.TODO(), &runnerList, client.InNamespace(env.Namespace.Name))
|
||||
if err != nil {
|
||||
logf.Log.Error(err, "list runners")
|
||||
}
|
||||
|
||||
env.fakeRunnerList.Sync(runnerList.Items)
|
||||
}
|
||||
|
||||
func ExpectCreate(ctx context.Context, rd client.Object, s string) {
|
||||
err := k8sClient.Create(ctx, rd)
|
||||
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred(), fmt.Sprintf("failed to create %s resource", s))
|
||||
}
|
||||
|
||||
func ExpectRunnerDeploymentEventuallyUpdates(ctx context.Context, ns string, name string, f func(rd *actionsv1alpha1.RunnerDeployment)) {
|
||||
// We wrap the update in the Eventually block to avoid the below error that occurs due to concurrent modification
|
||||
// made by the controller to update .Status.AvailableReplicas and .Status.ReadyReplicas
|
||||
// Operation cannot be fulfilled on runnersets.actions.summerwind.dev "example-runnerset": the object has been modified; please apply your changes to the latest version and try again
|
||||
EventuallyWithOffset(
|
||||
1,
|
||||
func() error {
|
||||
var rd actionsv1alpha1.RunnerDeployment
|
||||
|
||||
err := k8sClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, &rd)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to get test RunnerDeployment resource")
|
||||
|
||||
f(&rd)
|
||||
|
||||
return k8sClient.Update(ctx, &rd)
|
||||
},
|
||||
time.Second*1, time.Millisecond*500).Should(BeNil())
|
||||
}
|
||||
|
||||
func ExpectRunnerSetsCountEventuallyEquals(ctx context.Context, ns string, count int, optionalDescription ...interface{}) {
|
||||
runnerSets := actionsv1alpha1.RunnerReplicaSetList{Items: []actionsv1alpha1.RunnerReplicaSet{}}
|
||||
|
||||
EventuallyWithOffset(
|
||||
1,
|
||||
func() int {
|
||||
err := k8sClient.List(ctx, &runnerSets, client.InNamespace(ns))
|
||||
if err != nil {
|
||||
logf.Log.Error(err, "list runner sets")
|
||||
}
|
||||
|
||||
return len(runnerSets.Items)
|
||||
},
|
||||
time.Second*10, time.Millisecond*500).Should(BeEquivalentTo(count), optionalDescription...)
|
||||
}
|
||||
|
||||
func ExpectRunnerCountEventuallyEquals(ctx context.Context, ns string, count int, optionalDescription ...interface{}) {
|
||||
runners := actionsv1alpha1.RunnerList{Items: []actionsv1alpha1.Runner{}}
|
||||
|
||||
EventuallyWithOffset(
|
||||
1,
|
||||
func() int {
|
||||
err := k8sClient.List(ctx, &runners, client.InNamespace(ns))
|
||||
if err != nil {
|
||||
logf.Log.Error(err, "list runner sets")
|
||||
}
|
||||
|
||||
var running int
|
||||
|
||||
for _, r := range runners.Items {
|
||||
if r.Status.Phase == string(corev1.PodRunning) {
|
||||
running++
|
||||
} else {
|
||||
var pod corev1.Pod
|
||||
if err := k8sClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: r.Name}, &pod); err != nil {
|
||||
logf.Log.Error(err, "simulating pod controller")
|
||||
continue
|
||||
}
|
||||
|
||||
copy := pod.DeepCopy()
|
||||
copy.Status.Phase = corev1.PodRunning
|
||||
|
||||
if err := k8sClient.Status().Patch(ctx, copy, client.MergeFrom(&pod)); err != nil {
|
||||
logf.Log.Error(err, "simulating pod controller")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return running
|
||||
},
|
||||
time.Second*10, time.Millisecond*500).Should(BeEquivalentTo(count), optionalDescription...)
|
||||
}
|
||||
|
||||
func ExpectRunnerSetsManagedReplicasCountEventuallyEquals(ctx context.Context, ns string, count int, optionalDescription ...interface{}) {
|
||||
runnerSets := actionsv1alpha1.RunnerReplicaSetList{Items: []actionsv1alpha1.RunnerReplicaSet{}}
|
||||
|
||||
EventuallyWithOffset(
|
||||
1,
|
||||
func() int {
|
||||
err := k8sClient.List(ctx, &runnerSets, client.InNamespace(ns))
|
||||
if err != nil {
|
||||
logf.Log.Error(err, "list runner sets")
|
||||
}
|
||||
|
||||
if len(runnerSets.Items) == 0 {
|
||||
logf.Log.Info("No runnerreplicasets exist yet")
|
||||
return -1
|
||||
}
|
||||
|
||||
if len(runnerSets.Items) != 1 {
|
||||
logf.Log.Info("Too many runnerreplicasets exist", "runnerSets", runnerSets)
|
||||
return -1
|
||||
}
|
||||
|
||||
return *runnerSets.Items[0].Spec.Replicas
|
||||
},
|
||||
time.Second*5, time.Millisecond*500).Should(BeEquivalentTo(count), optionalDescription...)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/github"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/github"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -1,10 +1,10 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
arcv1alpha1 "github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/github"
|
||||
arcv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/github"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
@@ -131,6 +131,10 @@ func TestNewRunnerPod(t *testing.T) {
|
||||
Name: "RUNNER_STATUS_UPDATE_HOOK",
|
||||
Value: "false",
|
||||
},
|
||||
{
|
||||
Name: "GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT",
|
||||
Value: "actions-runner-controller/NA",
|
||||
},
|
||||
{
|
||||
Name: "DOCKER_HOST",
|
||||
Value: "tcp://localhost:2376",
|
||||
@@ -160,9 +164,7 @@ func TestNewRunnerPod(t *testing.T) {
|
||||
},
|
||||
},
|
||||
ImagePullPolicy: corev1.PullAlways,
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Privileged: func() *bool { v := false; return &v }(),
|
||||
},
|
||||
SecurityContext: &corev1.SecurityContext{},
|
||||
},
|
||||
{
|
||||
Name: "docker",
|
||||
@@ -190,6 +192,17 @@ func TestNewRunnerPod(t *testing.T) {
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Privileged: func(b bool) *bool { return &b }(true),
|
||||
},
|
||||
Lifecycle: &corev1.Lifecycle{
|
||||
PreStop: &corev1.LifecycleHandler{
|
||||
Exec: &corev1.ExecAction{
|
||||
Command: []string{
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"timeout \"${RUNNER_GRACEFUL_STOP_TIMEOUT:-15}\" /bin/sh -c \"echo 'Prestop hook started'; while [ -f /runner/.runner ]; do sleep 1; done; echo 'Waiting for dockerd to start'; while ! pgrep -x dockerd; do sleep 1; done; echo 'Prestop hook stopped'\" >/proc/1/fd/1 2>&1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: corev1.RestartPolicyNever,
|
||||
@@ -265,6 +278,10 @@ func TestNewRunnerPod(t *testing.T) {
|
||||
Name: "RUNNER_STATUS_UPDATE_HOOK",
|
||||
Value: "false",
|
||||
},
|
||||
{
|
||||
Name: "GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT",
|
||||
Value: "actions-runner-controller/NA",
|
||||
},
|
||||
},
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{
|
||||
@@ -347,6 +364,10 @@ func TestNewRunnerPod(t *testing.T) {
|
||||
Name: "RUNNER_STATUS_UPDATE_HOOK",
|
||||
Value: "false",
|
||||
},
|
||||
{
|
||||
Name: "GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT",
|
||||
Value: "actions-runner-controller/NA",
|
||||
},
|
||||
},
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{
|
||||
@@ -355,9 +376,7 @@ func TestNewRunnerPod(t *testing.T) {
|
||||
},
|
||||
},
|
||||
ImagePullPolicy: corev1.PullAlways,
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Privileged: boolPtr(false),
|
||||
},
|
||||
SecurityContext: &corev1.SecurityContext{},
|
||||
},
|
||||
},
|
||||
RestartPolicy: corev1.RestartPolicyNever,
|
||||
@@ -642,6 +661,10 @@ func TestNewRunnerPodFromRunnerController(t *testing.T) {
|
||||
Name: "RUNNER_STATUS_UPDATE_HOOK",
|
||||
Value: "false",
|
||||
},
|
||||
{
|
||||
Name: "GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT",
|
||||
Value: "actions-runner-controller/NA",
|
||||
},
|
||||
{
|
||||
Name: "DOCKER_HOST",
|
||||
Value: "tcp://localhost:2376",
|
||||
@@ -679,9 +702,7 @@ func TestNewRunnerPodFromRunnerController(t *testing.T) {
|
||||
},
|
||||
},
|
||||
ImagePullPolicy: corev1.PullAlways,
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Privileged: func() *bool { v := false; return &v }(),
|
||||
},
|
||||
SecurityContext: &corev1.SecurityContext{},
|
||||
},
|
||||
{
|
||||
Name: "docker",
|
||||
@@ -709,6 +730,17 @@ func TestNewRunnerPodFromRunnerController(t *testing.T) {
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Privileged: func(b bool) *bool { return &b }(true),
|
||||
},
|
||||
Lifecycle: &corev1.Lifecycle{
|
||||
PreStop: &corev1.LifecycleHandler{
|
||||
Exec: &corev1.ExecAction{
|
||||
Command: []string{
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"timeout \"${RUNNER_GRACEFUL_STOP_TIMEOUT:-15}\" /bin/sh -c \"echo 'Prestop hook started'; while [ -f /runner/.runner ]; do sleep 1; done; echo 'Waiting for dockerd to start'; while ! pgrep -x dockerd; do sleep 1; done; echo 'Prestop hook stopped'\" >/proc/1/fd/1 2>&1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: corev1.RestartPolicyNever,
|
||||
@@ -791,6 +823,10 @@ func TestNewRunnerPodFromRunnerController(t *testing.T) {
|
||||
Name: "RUNNER_STATUS_UPDATE_HOOK",
|
||||
Value: "false",
|
||||
},
|
||||
{
|
||||
Name: "GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT",
|
||||
Value: "actions-runner-controller/NA",
|
||||
},
|
||||
{
|
||||
Name: "RUNNER_NAME",
|
||||
Value: "runner",
|
||||
@@ -892,6 +928,10 @@ func TestNewRunnerPodFromRunnerController(t *testing.T) {
|
||||
Name: "RUNNER_STATUS_UPDATE_HOOK",
|
||||
Value: "false",
|
||||
},
|
||||
{
|
||||
Name: "GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT",
|
||||
Value: "actions-runner-controller/NA",
|
||||
},
|
||||
{
|
||||
Name: "RUNNER_NAME",
|
||||
Value: "runner",
|
||||
@@ -908,9 +948,7 @@ func TestNewRunnerPodFromRunnerController(t *testing.T) {
|
||||
},
|
||||
},
|
||||
ImagePullPolicy: corev1.PullAlways,
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Privileged: boolPtr(false),
|
||||
},
|
||||
SecurityContext: &corev1.SecurityContext{},
|
||||
},
|
||||
},
|
||||
RestartPolicy: corev1.RestartPolicyNever,
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -25,7 +25,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/hash"
|
||||
"github.com/actions/actions-runner-controller/build"
|
||||
"github.com/actions/actions-runner-controller/hash"
|
||||
"github.com/go-logr/logr"
|
||||
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -39,7 +40,7 @@ import (
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -207,9 +208,35 @@ func runnerPodOrContainerIsStopped(pod *corev1.Pod) bool {
|
||||
|
||||
if status.State.Terminated != nil {
|
||||
stopped = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if pod.DeletionTimestamp != nil && !pod.DeletionTimestamp.IsZero() && len(pod.Status.ContainerStatuses) == 0 {
|
||||
// This falls into cases where the pod is stuck with pod status like the below:
|
||||
//
|
||||
// status:
|
||||
// conditions:
|
||||
// - lastProbeTime: null
|
||||
// lastTransitionTime: "2022-11-20T07:58:05Z"
|
||||
// message: 'binding rejected: running Bind plugin "DefaultBinder": Operation cannot
|
||||
// be fulfilled on pods/binding "org-runnerdeploy-l579v-qx5p2": pod org-runnerdeploy-l579v-qx5p2
|
||||
// is being deleted, cannot be assigned to a host'
|
||||
// reason: SchedulerError
|
||||
// status: "False"
|
||||
// type: PodScheduled
|
||||
// phase: Pending
|
||||
// qosClass: BestEffort
|
||||
//
|
||||
// ARC usually waits for the registration timeout to elapse when the pod is terminated before getting scheduled onto a node,
|
||||
// assuming there can be a race condition between ARC and Kubernetes where Kubernetes schedules the pod while ARC is deleting the pod,
|
||||
// which may end up with non-gracefully terminating the runner.
|
||||
//
|
||||
// However, Kubernetes seems to not schedule the pod after observing status like the above.
|
||||
// This if-block is therefore needed to prevent ARC from unnecessarily waiting for the registration timeout to happen.
|
||||
stopped = true
|
||||
}
|
||||
}
|
||||
|
||||
return stopped
|
||||
@@ -472,7 +499,7 @@ func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) {
|
||||
// A registered runner's session and the a registration token seem to have two different and independent
|
||||
// lifecycles.
|
||||
//
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/issues/143 for more context.
|
||||
// See https://github.com/actions/actions-runner-controller/issues/143 for more context.
|
||||
labels[LabelKeyPodTemplateHash] = hash.FNVHashStringObjects(
|
||||
filterLabels(runner.ObjectMeta.Labels, LabelKeyRunnerTemplateHash),
|
||||
runner.ObjectMeta.Annotations,
|
||||
@@ -809,6 +836,10 @@ func newRunnerPodWithContainerMode(containerMode string, template corev1.Pod, ru
|
||||
Name: "RUNNER_STATUS_UPDATE_HOOK",
|
||||
Value: fmt.Sprintf("%v", useRunnerStatusUpdateHook),
|
||||
},
|
||||
{
|
||||
Name: "GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT",
|
||||
Value: fmt.Sprintf("actions-runner-controller/%s", build.Version),
|
||||
},
|
||||
}
|
||||
|
||||
var seLinuxOptions *corev1.SELinuxOptions
|
||||
@@ -849,10 +880,6 @@ func newRunnerPodWithContainerMode(containerMode string, template corev1.Pod, ru
|
||||
runnerContainerIndex = -1
|
||||
runnerContainer = &corev1.Container{
|
||||
Name: containerName,
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
// Runner need to run privileged if it contains DinD
|
||||
Privileged: &dockerdInRunnerPrivileged,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,8 +914,10 @@ func newRunnerPodWithContainerMode(containerMode string, template corev1.Pod, ru
|
||||
runnerContainer.SecurityContext = &corev1.SecurityContext{}
|
||||
}
|
||||
|
||||
if runnerContainer.SecurityContext.Privileged == nil {
|
||||
// Runner need to run privileged if it contains DinD
|
||||
// Runner need to run privileged if it contains DinD.
|
||||
// Do not explicitly set SecurityContext.Privileged to false which is default,
|
||||
// otherwise Windows pods don't get admitted on GKE.
|
||||
if dockerdInRunnerPrivileged {
|
||||
runnerContainer.SecurityContext.Privileged = &dockerdInRunnerPrivileged
|
||||
}
|
||||
|
||||
@@ -1025,7 +1054,7 @@ func newRunnerPodWithContainerMode(containerMode string, template corev1.Pod, ru
|
||||
}...)
|
||||
|
||||
// Determine the volume mounts assigned to the docker sidecar. In case extra mounts are included in the RunnerSpec, append them to the standard
|
||||
// set of mounts. See https://github.com/actions-runner-controller/actions-runner-controller/issues/435 for context.
|
||||
// set of mounts. See https://github.com/actions/actions-runner-controller/issues/435 for context.
|
||||
dockerVolumeMounts := []corev1.VolumeMount{
|
||||
{
|
||||
Name: runnerVolumeName,
|
||||
@@ -1102,7 +1131,7 @@ func newRunnerPodWithContainerMode(containerMode string, template corev1.Pod, ru
|
||||
//
|
||||
// br-c5bf6c172bd7 is the interface that corresponds to the docker network created with docker-create-network.
|
||||
// We have another ARC feature to inherit the host's MTU to the docker networks:
|
||||
// https://github.com/actions-runner-controller/actions-runner-controller/pull/1201
|
||||
// https://github.com/actions/actions-runner-controller/pull/1201
|
||||
//
|
||||
// docker's MTU is updated to the specified MTU once any container is created.
|
||||
// You can verity that by running a random container from within the runner or dockerd containers:
|
||||
@@ -1151,6 +1180,27 @@ func newRunnerPodWithContainerMode(containerMode string, template corev1.Pod, ru
|
||||
fmt.Sprintf("--registry-mirror=%s", dockerRegistryMirror),
|
||||
)
|
||||
}
|
||||
|
||||
dockerdContainer.Lifecycle = &corev1.Lifecycle{
|
||||
PreStop: &corev1.LifecycleHandler{
|
||||
Exec: &corev1.ExecAction{
|
||||
Command: []string{
|
||||
"/bin/sh", "-c",
|
||||
// A prestop hook can start before the dockerd start up, for example, when the docker init is still provisioning
|
||||
// the TLS key and the cert to be used by dockerd.
|
||||
//
|
||||
// The author of this prestop script encountered issues where the prestophung for ten or more minutes on his cluster.
|
||||
// He realized that the hang happened when a prestop hook is executed while the docker init is provioning the key and cert.
|
||||
// Assuming it's due to that the SIGTERM sent by K8s after the prestop hook was ignored by the docker init at that time,
|
||||
// and it needed to wait until terminationGracePeriodSeconds to elapse before finally killing the container,
|
||||
// he wrote this script so that it tries to delay SIGTERM until dockerd starts and becomes ready for processing the signal.
|
||||
//
|
||||
// Also note that we don't need to run `pkill dockerd` at the end of the prehook script, as SIGTERM is sent by K8s after the prestop had completed.
|
||||
`timeout "${RUNNER_GRACEFUL_STOP_TIMEOUT:-15}" /bin/sh -c "echo 'Prestop hook started'; while [ -f /runner/.runner ]; do sleep 1; done; echo 'Waiting for dockerd to start'; while ! pgrep -x dockerd; do sleep 1; done; echo 'Prestop hook stopped'" >/proc/1/fd/1 2>&1`,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if runnerContainerIndex == -1 {
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/github"
|
||||
"github.com/actions/actions-runner-controller/github"
|
||||
"github.com/go-logr/logr"
|
||||
gogithub "github.com/google/go-github/v47/github"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -98,12 +98,41 @@ func ensureRunnerUnregistration(ctx context.Context, retryDelay time.Duration, l
|
||||
// If it's already unregistered in the previous reconcilation loop,
|
||||
// you can safely assume that it won't get registered again so it's safe to delete the runner pod.
|
||||
log.Info("Runner pod is marked as already unregistered.")
|
||||
} else if runnerID == nil && !runnerPodOrContainerIsStopped(pod) && !podConditionTransitionTimeAfter(pod, corev1.PodReady, registrationTimeout) {
|
||||
} else if runnerID == nil && !runnerPodOrContainerIsStopped(pod) && !podConditionTransitionTimeAfter(pod, corev1.PodReady, registrationTimeout) &&
|
||||
!podIsPending(pod) {
|
||||
|
||||
log.Info(
|
||||
"Unregistration started before runner obtains ID. Waiting for the regisration timeout to elapse, or the runner to obtain ID, or the runner pod to stop",
|
||||
"Unregistration started before runner obtains ID. Waiting for the registration timeout to elapse, or the runner to obtain ID, or the runner pod to stop",
|
||||
"registrationTimeout", registrationTimeout,
|
||||
)
|
||||
return &ctrl.Result{RequeueAfter: retryDelay}, nil
|
||||
} else if runnerID == nil && podIsPending(pod) {
|
||||
// Note: This logic is here to prevent a dead-lock between ARC and the PV provider.
|
||||
//
|
||||
// The author of this logic thinks that some (or all?) of CSI plugins and PV providers
|
||||
// do not support provisioning dynamic PVs for a pod that is already marked for deletion.
|
||||
// If we didn't handle this case here, ARC would end up with waiting forever until the
|
||||
// PV provider(s) provision PVs for the pod, which seems to never happen.
|
||||
//
|
||||
// For reference, the below is an eaxmple of pod.status that you might see when it happened:
|
||||
// status:
|
||||
// conditions:
|
||||
// - lastProbeTime: null
|
||||
// lastTransitionTime: "2022-11-04T00:04:05Z"
|
||||
// message: 'binding rejected: running Bind plugin "DefaultBinder": Operation cannot
|
||||
// be fulfilled on pods/binding "org-runnerdeploy-xv2lg-pm6t2": pod org-runnerdeploy-xv2lg-pm6t2
|
||||
// is being deleted, cannot be assigned to a host'
|
||||
// reason: SchedulerError
|
||||
// status: "False"
|
||||
// type: PodScheduled
|
||||
// phase: Pending
|
||||
// qosClass: BestEffort
|
||||
log.Info(
|
||||
"Unregistration started before runner pod gets scheduled onto a node. "+
|
||||
"Perhaps the runner is taking a long time due to e.g. slow CSI slugin not giving us a PV in a timely manner, or your Kubernetes cluster is overloaded? "+
|
||||
"Marking unregistration as completed anyway because there's nothing ARC can do.",
|
||||
"registrationTimeout", registrationTimeout,
|
||||
)
|
||||
} else if runnerID == nil && runnerPodOrContainerIsStopped(pod) {
|
||||
log.Info(
|
||||
"Unregistration started before runner ID is assigned and the runner stopped before obtaining ID within registration timeout. "+
|
||||
@@ -144,7 +173,7 @@ func ensureRunnerUnregistration(ctx context.Context, retryDelay time.Duration, l
|
||||
}
|
||||
|
||||
// Prevent runner pod from stucking in Terminating.
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/issues/1369
|
||||
// See https://github.com/actions/actions-runner-controller/issues/1369
|
||||
log.Info("Deleting runner pod anyway because it has stopped prematurely. This may leave a dangling runner resource in GitHub Actions",
|
||||
"lastState.exitCode", lts.ExitCode,
|
||||
"lastState.message", lts.Message,
|
||||
@@ -229,7 +258,7 @@ func ensureRunnerUnregistration(ctx context.Context, retryDelay time.Duration, l
|
||||
log.V(2).Info("Retrying runner unregistration because the static runner is still busy")
|
||||
// Otherwise we may end up spamming 422 errors,
|
||||
// each call consuming GitHub API rate limit
|
||||
// https://github.com/actions-runner-controller/actions-runner-controller/pull/1167#issuecomment-1064213271
|
||||
// https://github.com/actions/actions-runner-controller/pull/1167#issuecomment-1064213271
|
||||
return &ctrl.Result{RequeueAfter: retryDelay}, nil
|
||||
}
|
||||
|
||||
@@ -327,6 +356,10 @@ func podConditionTransitionTimeAfter(pod *corev1.Pod, tpe corev1.PodConditionTyp
|
||||
return c.Add(d).Before(time.Now())
|
||||
}
|
||||
|
||||
func podIsPending(pod *corev1.Pod) bool {
|
||||
return pod.Status.Phase == corev1.PodPending
|
||||
}
|
||||
|
||||
func podRunnerID(pod *corev1.Pod) string {
|
||||
id, _ := getAnnotation(pod, AnnotationKeyRunnerID)
|
||||
return id
|
||||
@@ -411,7 +444,7 @@ func unregisterRunner(ctx context.Context, client *github.Client, enterprise, or
|
||||
// # NOTES
|
||||
//
|
||||
// - It can be "status=offline" at the same time but that's another story.
|
||||
// - After https://github.com/actions-runner-controller/actions-runner-controller/pull/1127, ListRunners responses that are used to
|
||||
// - After https://github.com/actions/actions-runner-controller/pull/1127, ListRunners responses that are used to
|
||||
// determine if the runner is busy can be more outdated than before, as those responeses are now cached for 60 seconds.
|
||||
// - Note that 60 seconds is controlled by the Cache-Control response header provided by GitHub so we don't have a strict control on it but we assume it won't
|
||||
// change from 60 seconds.
|
||||
@@ -1,9 +1,9 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import corev1 "k8s.io/api/core/v1"
|
||||
|
||||
// Force the runner pod managed by either RunnerDeployment and RunnerSet to have restartPolicy=Never.
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/issues/1369 for more context.
|
||||
// See https://github.com/actions/actions-runner-controller/issues/1369 for more context.
|
||||
//
|
||||
// This is to prevent runner pods from stucking in Terminating when a K8s node disappeared along with the runnr pod and the runner container within it.
|
||||
//
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
arcv1alpha1 "github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
arcv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/go-logr/logr"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -179,7 +179,7 @@ func getPodsForOwner(ctx context.Context, c client.Client, log logr.Logger, o cl
|
||||
"Runner failed to register itself to GitHub in timely manner. "+
|
||||
"Recreating the pod to see if it resolves the issue. "+
|
||||
"CAUTION: If you see this a lot, you should investigate the root cause. "+
|
||||
"See https://github.com/actions-runner-controller/actions-runner-controller/issues/288",
|
||||
"See https://github.com/actions/actions-runner-controller/issues/288",
|
||||
"creationTimestamp", pod.CreationTimestamp,
|
||||
"readyTransitionTime", podConditionTransitionTime(&pod, corev1.PodReady, corev1.ConditionTrue),
|
||||
"configuredRegistrationTimeout", registrationTimeout,
|
||||
@@ -488,7 +488,7 @@ func collectPodsForOwners(ctx context.Context, c client.Client, log logr.Logger,
|
||||
// lastSyncTime becomes non-nil only when there are one or more owner(s) hence there are same number of runner pods.
|
||||
// It's used to prevent runnerset-controller from recreating "completed ephemeral runners".
|
||||
// This is needed to prevent runners from being terminated prematurely.
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/issues/911 for more context.
|
||||
// See https://github.com/actions/actions-runner-controller/issues/911 for more context.
|
||||
//
|
||||
// This becomes nil when there are zero statefulset(s). That's fine because then there should be zero stateful(s) to be recreated either hence
|
||||
// we don't need to guard with lastSyncTime.
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -37,8 +37,8 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/controllers/metrics"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/controllers/actions.summerwind.net/metrics"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -158,7 +158,7 @@ func (r *RunnerDeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Req
|
||||
// A selector update change doesn't trigger replicaset replacement,
|
||||
// but we still need to update the existing replicaset with it.
|
||||
// Otherwise selector-based runner query will never work on replicasets created before the controller v0.17.0
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/pull/355#discussion_r585379259
|
||||
// See https://github.com/actions/actions-runner-controller/pull/355#discussion_r585379259
|
||||
if err := r.Client.Update(ctx, updateSet); err != nil {
|
||||
log.Error(err, "Failed to update runnerreplicaset resource")
|
||||
|
||||
@@ -183,7 +183,7 @@ func (r *RunnerDeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Req
|
||||
// Please add more conditions that we can in-place update the newest runnerreplicaset without disruption
|
||||
//
|
||||
// If we missed taking the EffectiveTime diff into account, you might end up experiencing scale-ups being delayed scale-down.
|
||||
// See https://github.com/actions-runner-controller/actions-runner-controller/pull/1477#issuecomment-1164154496
|
||||
// See https://github.com/actions/actions-runner-controller/pull/1477#issuecomment-1164154496
|
||||
var et1, et2 time.Time
|
||||
if newestSet.Spec.EffectiveTime != nil {
|
||||
et1 = newestSet.Spec.EffectiveTime.Time
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
actionsv1alpha1 "github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
actionsv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
)
|
||||
|
||||
func TestNewRunnerReplicaSet(t *testing.T) {
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
)
|
||||
|
||||
// RunnerReplicaSetReconciler reconciles a Runner object
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -16,8 +16,8 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
actionsv1alpha1 "github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/github/fake"
|
||||
actionsv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/github/fake"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -31,8 +31,8 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions-runner-controller/actions-runner-controller/controllers/metrics"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/controllers/actions.summerwind.net/metrics"
|
||||
"github.com/go-logr/logr"
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
actionsv1alpha1 "github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
actionsv1alpha1 "github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -57,19 +57,16 @@ func TestAPIs(t *testing.T) {
|
||||
var _ = BeforeSuite(func(done Done) {
|
||||
logf.SetLogger(zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)))
|
||||
|
||||
var apiServerFlags []string
|
||||
|
||||
apiServerFlags = append(apiServerFlags, envtest.DefaultKubeAPIServerFlags...)
|
||||
// Avoids the following error:
|
||||
// 2021-03-19T15:14:11.673+0900 ERROR controller-runtime.controller Reconciler error {"controller": "testns-tvjzjrunner", "request": "testns-gdnyx/example-runnerdeploy-zps4z-j5562", "error": "Pod \"example-runnerdeploy-zps4z-j5562\" is invalid: [spec.containers[1].image: Required value, spec.containers[1].securityContext.privileged: Forbidden: disallowed by cluster policy]"}
|
||||
apiServerFlags = append(apiServerFlags, "--allow-privileged=true")
|
||||
|
||||
By("bootstrapping test environment")
|
||||
testEnv = &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
|
||||
KubeAPIServerFlags: apiServerFlags,
|
||||
CRDDirectoryPaths: []string{filepath.Join("../..", "config", "crd", "bases")},
|
||||
}
|
||||
|
||||
// Avoids the following error:
|
||||
// 2021-03-19T15:14:11.673+0900 ERROR controller-runtime.controller Reconciler error {"controller": "testns-tvjzjrunner", "request": "testns-gdnyx/example-runnerdeploy-zps4z-j5562", "error": "Pod \"example-runnerdeploy-zps4z-j5562\" is invalid: [spec.containers[1].image: Required value, spec.containers[1].securityContext.privileged: Forbidden: disallowed by cluster policy]"}
|
||||
testEnv.ControlPlane.GetAPIServer().Configure().
|
||||
Append("allow-privileged", "true")
|
||||
|
||||
var err error
|
||||
cfg, err = testEnv.Start()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
@@ -1,11 +1,11 @@
|
||||
package controllers
|
||||
package actionssummerwindnet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
|
||||
"github.com/go-logr/logr"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user