Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4a8726a6f | ||
|
|
08828e44a9 | ||
|
|
418f6b1f31 | ||
|
|
77ca94e97f | ||
|
|
eb29a1af8c |
@@ -4,6 +4,8 @@ on:
|
||||
paths:
|
||||
- Dockerfile.base
|
||||
- .github/workflows/base.yml
|
||||
- tests/**
|
||||
- go.*
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
@@ -11,8 +13,110 @@ on:
|
||||
- cron: '0 22 * * *'
|
||||
|
||||
jobs:
|
||||
ubuntu_base_tests:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
release: [jammy, focal, noble]
|
||||
platform: [linux/amd64, linux/arm64]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Copy Repo Files
|
||||
uses: actions/checkout@master
|
||||
- name: Get GitHub organization or user
|
||||
run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Copy Dockerfile
|
||||
run: cp Dockerfile.base Dockerfile.base.ubuntu-${{ matrix.release }}; sed -i.bak 's/FROM.*/FROM ubuntu:${{ matrix.release }}/' Dockerfile.base.ubuntu-${{ matrix.release }}
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.22'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
go get github.com/testcontainers/testcontainers-go@v0.33.0
|
||||
- name: Get current Git SHA
|
||||
id: vars
|
||||
run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
- name: set testable image environment variable
|
||||
id: testvars
|
||||
run: echo "GH_RUNNER_IMAGE=ubuntu-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.base.ubuntu-${{ matrix.release }}
|
||||
pull: true
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ env.ORG }}/github-runner-base:ubuntu-${{ matrix.release }},${{ env.GH_RUNNER_IMAGE }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
- name: Run go tests
|
||||
run: go test -run ^TestIntegrationGHRunnerBase$ tests/base_test.go
|
||||
|
||||
debian_base_tests:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
release: [bookworm, sid]
|
||||
platform: [linux/amd64, linux/arm64]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Copy Repo Files
|
||||
uses: actions/checkout@master
|
||||
- name: Get GitHub organization or user
|
||||
run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Copy Dockerfile
|
||||
run: cp Dockerfile.base Dockerfile.base.debian-${{ matrix.release }}; sed -i.bak 's/FROM.*/FROM debian:${{ matrix.release }}/' Dockerfile.base.debian-${{ matrix.release }}
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.22'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
go get github.com/testcontainers/testcontainers-go@v0.33.0
|
||||
- name: Get current Git SHA
|
||||
id: vars
|
||||
run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
- name: set testable image environment variable
|
||||
id: testvars
|
||||
run: echo "GH_RUNNER_IMAGE=debian-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.base.debian-${{ matrix.release }}
|
||||
pull: true
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ env.ORG }}/github-runner-base:debian-${{ matrix.release }},${{ env.GH_RUNNER_IMAGE }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
- name: Run go tests
|
||||
run: go test -run ^TestIntegrationGHRunnerBase$ tests/base_test.go
|
||||
ubuntu_base_latest_deploy:
|
||||
runs-on: ubuntu-latest
|
||||
needs: ubuntu_base_tests
|
||||
steps:
|
||||
- name: Copy Repo Files
|
||||
uses: actions/checkout@master
|
||||
@@ -41,6 +145,7 @@ jobs:
|
||||
|
||||
ubuntu_base_deploy:
|
||||
runs-on: ubuntu-latest
|
||||
needs: ubuntu_base_tests
|
||||
strategy:
|
||||
matrix:
|
||||
release: [jammy, focal, noble]
|
||||
@@ -75,6 +180,7 @@ jobs:
|
||||
|
||||
debian_base_deploy:
|
||||
runs-on: ubuntu-latest
|
||||
needs: debian_base_tests
|
||||
strategy:
|
||||
matrix:
|
||||
release: [bookworm, sid]
|
||||
|
||||
@@ -4,6 +4,8 @@ on:
|
||||
paths-ignore:
|
||||
- Dockerfile.base
|
||||
- README.md
|
||||
- tests/**
|
||||
- go.*
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
@@ -13,3 +13,115 @@ jobs:
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
|
||||
ubuntu_tests:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
release: [jammy, focal, noble]
|
||||
platform: [amd64, arm64]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Copy Repo Files
|
||||
uses: actions/checkout@master
|
||||
- name: Get GitHub organization or user
|
||||
run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.22'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
go get github.com/testcontainers/testcontainers-go@v0.33.0
|
||||
- name: Get current Git SHA
|
||||
id: vars
|
||||
run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
- name: set testable image environment variable
|
||||
id: testvars
|
||||
run: echo "GH_RUNNER_IMAGE=ubuntu-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV
|
||||
- name: Combine Dockerfile
|
||||
run: |
|
||||
cp Dockerfile.base Dockerfile.final.ubuntu-${{ matrix.release }};
|
||||
sed -i.bak 's/FROM.*/FROM ubuntu:${{ matrix.release }}/' Dockerfile.final.ubuntu-${{ matrix.release }}
|
||||
|
||||
# Combine the dockerfiles
|
||||
cp Dockerfile Dockerfile.ubuntu-${{ matrix.release }}
|
||||
cat Dockerfile.ubuntu-${{ matrix.release }} | sed "s/^FROM.*//" >>Dockerfile.final.ubuntu-${{ matrix.release }}
|
||||
|
||||
# Sanity check
|
||||
grep FROM Dockerfile.final.ubuntu-${{ matrix.release }}
|
||||
- name: Build final image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.final.ubuntu-${{ matrix.release }}
|
||||
pull: true
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ env.GH_RUNNER_IMAGE }}
|
||||
platforms: linux/${{ matrix.platform }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
# Tests will run against the final `${GH_RUNNER_IMAGE}` laid on top of `base-${GH_RUNNER_IMAGE}`
|
||||
- name: Run go tests
|
||||
run: go test ./tests/...
|
||||
|
||||
debian_tests:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
release: [bookworm, sid]
|
||||
platform: [amd64, arm64]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Copy Repo Files
|
||||
uses: actions/checkout@master
|
||||
- name: Get GitHub organization or user
|
||||
run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.22'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
go get github.com/testcontainers/testcontainers-go@v0.33.0
|
||||
- name: Get current Git SHA
|
||||
id: vars
|
||||
run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
- name: set testable image environment variable
|
||||
id: testvars
|
||||
run: echo "GH_RUNNER_IMAGE=debian-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV
|
||||
- name: Combine Dockerfile
|
||||
run: |
|
||||
cp Dockerfile.base Dockerfile.final.debian-${{ matrix.release }}
|
||||
sed -i.bak 's/FROM.*/FROM debian:${{ matrix.release }}/' Dockerfile.final.debian-${{ matrix.release }}
|
||||
|
||||
# Combine the dockerfiles
|
||||
cp Dockerfile Dockerfile.debian-${{ matrix.release }}
|
||||
cat Dockerfile.debian-${{ matrix.release }} | sed "s/^FROM.*//" >>Dockerfile.final.debian-${{ matrix.release }}
|
||||
|
||||
# Sanity check
|
||||
grep FROM Dockerfile.final.debian-${{ matrix.release }}
|
||||
- name: Build final image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.final.debian-${{ matrix.release }}
|
||||
pull: true
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ env.GH_RUNNER_IMAGE }}
|
||||
platforms: linux/${{ matrix.platform }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
# Tests will run against the final `${GH_RUNNER_IMAGE}` laid on top of `base-${GH_RUNNER_IMAGE}`
|
||||
- name: Run go tests
|
||||
run: go test ./tests/...
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
*.bak
|
||||
.idea/
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ LABEL maintainer="myoung34@my.apsu.edu"
|
||||
ENV AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache
|
||||
RUN mkdir -p /opt/hostedtoolcache
|
||||
|
||||
ARG GH_RUNNER_VERSION="2.319.0"
|
||||
ARG GH_RUNNER_VERSION="2.319.1"
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
|
||||
@@ -71,3 +71,20 @@ These containers are built via Github actions that [copy the dockerfile](https:/
|
||||
| `DISABLE_AUTO_UPDATE` | Optional environment variable to [disable auto updates](https://github.blog/changelog/2022-02-01-github-actions-self-hosted-runners-can-now-disable-automatic-updates/). Auto updates are enabled by default to preserve past behavior. Any value is considered truthy and will disable them. |
|
||||
| `START_DOCKER_SERVICE` | Optional flag which automatically starts the docker service if set to `true`. Useful when using [sysbox](https://github.com/nestybox/sysbox). Defaults to `false`. |
|
||||
| `NO_DEFAULT_LABELS` | Optional environment variable to disable adding the default self-hosted, platform, and architecture labels to the runner. Any value is considered truthy and will disable them. |
|
||||
| `DEBUG_ONLY` | Optional boolean to print debug output but not run any actual registration or runner commands. Used in CI and testing. Default: false |
|
||||
| `DEBUG_OUTPUT` | Optional boolean to print additional debug output. Default: false |
|
||||
|
||||
|
||||
## Tests ##
|
||||
|
||||
Tests are written in [testcontainers-go](https://testcontainers.org/) for general assertions.
|
||||
It's expected that all pull-requests have relevant assertions in order to be merged.
|
||||
|
||||
The test file expects the image to test as an environment variable `GH_RUNNER_IMAGE` to assist in CI
|
||||
|
||||
To test:
|
||||
```
|
||||
$ go get github.com/testcontainers/testcontainers-go@v0.33.0`
|
||||
$ docker build -t my-image-test -f Dockerfile.base .
|
||||
$ GH_RUNNER_IMAGE="my-image-test" go test -v ./tests/...
|
||||
```
|
||||
|
||||
+53
-7
@@ -14,6 +14,7 @@ export -n APP_PRIVATE_KEY
|
||||
trap_with_arg() {
|
||||
func="$1" ; shift
|
||||
for sig ; do
|
||||
# shellcheck disable=SC2064
|
||||
trap "$func $sig" "$sig"
|
||||
done
|
||||
}
|
||||
@@ -28,6 +29,8 @@ deregister_runner() {
|
||||
exit
|
||||
}
|
||||
|
||||
_DEBUG_ONLY=${DEBUG_ONLY:-false}
|
||||
_DEBUG_OUTPUT=${DEBUG_OUTPUT:-false}
|
||||
_DISABLE_AUTOMATIC_DEREGISTRATION=${DISABLE_AUTOMATIC_DEREGISTRATION:-false}
|
||||
|
||||
_RANDOM_RUNNER_SUFFIX=${RANDOM_RUNNER_SUFFIX:="true"}
|
||||
@@ -162,11 +165,16 @@ if [[ -n "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then
|
||||
if [ -f "/actions-runner/.runner" ]; then
|
||||
echo "The runner has already been configured"
|
||||
else
|
||||
configure_runner
|
||||
|
||||
if [[ ${_DEBUG_ONLY} == "false" ]]; then
|
||||
configure_runner
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Runner reusage is disabled"
|
||||
configure_runner
|
||||
if [[ ${_DEBUG_ONLY} == "false" ]]; then
|
||||
configure_runner
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then
|
||||
@@ -178,7 +186,9 @@ fi
|
||||
|
||||
|
||||
if [[ ${_DISABLE_AUTOMATIC_DEREGISTRATION} == "false" ]]; then
|
||||
trap_with_arg deregister_runner SIGINT SIGQUIT SIGTERM INT TERM QUIT
|
||||
if [[ ${_DEBUG_ONLY} == "false" ]]; then
|
||||
trap_with_arg deregister_runner SIGINT SIGQUIT SIGTERM INT TERM QUIT
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start docker service if needed (e.g. for docker-in-docker)
|
||||
@@ -186,15 +196,39 @@ if [[ ${_START_DOCKER_SERVICE} == "true" ]]; then
|
||||
echo "Starting docker service"
|
||||
_PREFIX=""
|
||||
[[ ${_RUN_AS_ROOT} != "true" ]] && _PREFIX="sudo"
|
||||
${_PREFIX} service docker start
|
||||
|
||||
if [[ ${_DEBUG_ONLY} == "true" ]]; then
|
||||
echo ${_PREFIX} service docker start
|
||||
else
|
||||
${_PREFIX} service docker start
|
||||
fi
|
||||
fi
|
||||
|
||||
# Container's command (CMD) execution as runner user
|
||||
|
||||
|
||||
if [[ ${_DEBUG_ONLY} == "true" ]] || [[ ${_DEBUG_OUTPUT} == "true" ]] ; then
|
||||
echo ""
|
||||
echo "Disable automatic registration: ${_DISABLE_AUTOMATIC_DEREGISTRATION}"
|
||||
echo "Random runner suffix: ${_RANDOM_RUNNER_SUFFIX}"
|
||||
echo "Runner name: ${_RUNNER_NAME}"
|
||||
echo "Runner workdir: ${_RUNNER_WORKDIR}"
|
||||
echo "Labels: ${_LABELS}"
|
||||
echo "Runner Group: ${_RUNNER_GROUP}"
|
||||
echo "Github Host: ${_GITHUB_HOST}"
|
||||
echo "Run as root:${_RUN_AS_ROOT}"
|
||||
echo "Start docker: ${_START_DOCKER_SERVICE}"
|
||||
fi
|
||||
|
||||
if [[ ${_RUN_AS_ROOT} == "true" ]]; then
|
||||
if [[ $(id -u) -eq 0 ]]; then
|
||||
"$@"
|
||||
if [[ ${_DEBUG_ONLY} == "true" ]] || [[ ${_DEBUG_OUTPUT} == "true" ]] ; then
|
||||
# shellcheck disable=SC2145
|
||||
echo "Running $@"
|
||||
fi
|
||||
if [[ ${_DEBUG_ONLY} == "false" ]]; then
|
||||
"$@"
|
||||
fi
|
||||
else
|
||||
echo "ERROR: RUN_AS_ROOT env var is set to true but the user has been overridden and is not running as root, but UID '$(id -u)'"
|
||||
exit 1
|
||||
@@ -205,8 +239,20 @@ else
|
||||
chown -R runner "${_RUNNER_WORKDIR}" /actions-runner
|
||||
# The toolcache is not recursively chowned to avoid recursing over prepulated tooling in derived docker images
|
||||
chown runner /opt/hostedtoolcache/
|
||||
/usr/sbin/gosu runner "$@"
|
||||
if [[ ${_DEBUG_ONLY} == "true" ]] || [[ ${_DEBUG_OUTPUT} == "true" ]] ; then
|
||||
# shellcheck disable=SC2145
|
||||
echo "Running /usr/sbin/gosu runner $@"
|
||||
fi
|
||||
if [[ ${_DEBUG_ONLY} == "false" ]]; then
|
||||
/usr/sbin/gosu runner "$@"
|
||||
fi
|
||||
else
|
||||
"$@"
|
||||
if [[ ${_DEBUG_ONLY} == "true" ]] || [[ ${_DEBUG_OUTPUT} == "true" ]] ; then
|
||||
# shellcheck disable=SC2145
|
||||
echo "Running $@"
|
||||
fi
|
||||
if [[ ${_DEBUG_ONLY} == "false" ]]; then
|
||||
"$@"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
module docker-github-actions-runner
|
||||
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/containerd/containerd v1.7.18 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/docker v27.1.1+incompatible // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.4 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/user v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/testcontainers/testcontainers-go v0.33.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
)
|
||||
@@ -0,0 +1,142 @@
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao=
|
||||
github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
|
||||
github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
|
||||
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
|
||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
|
||||
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
|
||||
github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,167 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIntegrationGHRunnerBase(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
ghaRunner, err := setupGHRunner(ctx, map[string]string{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Clean up the container after the test is complete
|
||||
t.Cleanup(func() {
|
||||
if err := ghaRunner.Terminate(ctx); err != nil {
|
||||
t.Fatalf("failed to terminate container: %s", err)
|
||||
}
|
||||
})
|
||||
|
||||
for _, theProgram := range []string{
|
||||
"curl",
|
||||
"docker",
|
||||
"docker-compose",
|
||||
"dumb-init",
|
||||
"gh",
|
||||
"git",
|
||||
"git-lfs",
|
||||
"gosu",
|
||||
"jq",
|
||||
"lsb_release",
|
||||
"make",
|
||||
"nodejs",
|
||||
"pwsh",
|
||||
"python3",
|
||||
"rsync",
|
||||
"ssh",
|
||||
"sudo",
|
||||
"tar",
|
||||
"unzip",
|
||||
"wget",
|
||||
"yq",
|
||||
"zip",
|
||||
} {
|
||||
|
||||
t.Run(fmt.Sprintf("%sExists", theProgram), func(t *testing.T) {
|
||||
|
||||
exitCode, _, err := ghaRunner.Exec(ctx, []string{"which", theProgram})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if exitCode != 0 {
|
||||
t.Fatalf("expected %s to be installed", theProgram)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
theTests := []outputTest{
|
||||
{
|
||||
name: "ulimit set",
|
||||
cmd: []string{"grep", "^\\s*# ulimit -Hn", "/etc/init.d/docker"},
|
||||
expectation: "expected ulimit to be set in /etc/init.d/docker\"",
|
||||
output: []string{""},
|
||||
statusCode: 0,
|
||||
},
|
||||
{
|
||||
name: "runner user id",
|
||||
cmd: []string{"id", "-u", "runner"},
|
||||
expectation: "expected runner to exist with uid 1001",
|
||||
output: []string{"1001"},
|
||||
statusCode: 0,
|
||||
},
|
||||
{
|
||||
name: "runner group id",
|
||||
cmd: []string{"id", "-g", "runner"},
|
||||
expectation: "expected runner to exist with gid 121",
|
||||
output: []string{"121"},
|
||||
statusCode: 0,
|
||||
},
|
||||
{
|
||||
name: "runner groups",
|
||||
cmd: []string{"id", "-Gn", "runner"},
|
||||
expectation: "expected runner to exist with group names runner sudo docker",
|
||||
output: []string{"runner sudo docker"},
|
||||
statusCode: 0,
|
||||
},
|
||||
{
|
||||
name: "sudo no password for runner",
|
||||
cmd: []string{"tail", "-n", "1", "/etc/sudoers"},
|
||||
expectation: "expected runner to have NOPASSWD line in sudoers",
|
||||
output: []string{"%sudo ALL=(ALL) NOPASSWD: ALL"},
|
||||
statusCode: 0,
|
||||
},
|
||||
{
|
||||
name: "suders defaults",
|
||||
cmd: []string{"grep", "Defaults env_keep = \"HTTP_PROXY HTTPS_PROXY NO_PROXY FTP_PROXY http_proxy https_proxy no_proxy ftp_proxy\"", "/etc/sudoers"},
|
||||
expectation: "expected sudoers to have updated Defaults env_keep",
|
||||
output: []string{""},
|
||||
statusCode: 0,
|
||||
},
|
||||
{
|
||||
name: "locale set",
|
||||
cmd: []string{"grep", "-v", "^#", "/etc/locale.gen"},
|
||||
expectation: "expected locale to be set in /etc/locale.gen",
|
||||
output: []string{"en_US.UTF-8 UTF-8"},
|
||||
statusCode: 0,
|
||||
},
|
||||
}
|
||||
t.Logf("%v", theTests)
|
||||
|
||||
for _, theT := range theTests {
|
||||
|
||||
t.Run(theT.name, func(t *testing.T) {
|
||||
|
||||
if theT.output[0] != "" {
|
||||
output, err := runAndReturnOutput(ghaRunner, ctx, theT.cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if output[0] != theT.output[0] {
|
||||
t.Fatalf("expected %s, got %s", theT.output, output[0])
|
||||
}
|
||||
}
|
||||
|
||||
cmdExitCode, _, _ := ghaRunner.Exec(ctx, theT.cmd)
|
||||
if cmdExitCode != 0 {
|
||||
t.Fatalf(theT.expectation)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// os specific tests
|
||||
osDistro, err := runAndReturnOutput(ghaRunner, ctx, []string{"/usr/bin/awk", "-F=", "/^VERSION_CODENAME=/ {print $2}", "/etc/os-release"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// focal is the only one that does not have skopeo buildah podman
|
||||
if osDistro[0] != "focal" {
|
||||
for _, theProgram := range []string{
|
||||
"skopeo",
|
||||
"buildah",
|
||||
"podman",
|
||||
} {
|
||||
t.Run(fmt.Sprintf("%sExists", theProgram), func(t *testing.T) {
|
||||
|
||||
exitCode, _, err := ghaRunner.Exec(ctx, []string{"which", theProgram})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if exitCode != 0 {
|
||||
t.Fatalf("expected %s to be installed", theProgram)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type ghaRunnerontainer struct {
|
||||
testcontainers.Container
|
||||
}
|
||||
|
||||
// Helper function to read from an io.Reader and return a slice of strings (one per line)
|
||||
func readLines(reader io.Reader) ([]string, error) {
|
||||
var lines []string
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return lines, nil
|
||||
}
|
||||
|
||||
func cleanString(b []byte) string {
|
||||
s := string(b)
|
||||
return strings.Map(func(r rune) rune {
|
||||
if unicode.IsPrint(r) {
|
||||
return r
|
||||
}
|
||||
return -1
|
||||
}, s)
|
||||
}
|
||||
|
||||
func runAndReturnOutput(ctr testcontainers.Container, ctx context.Context, cmd []string) ([]string, error) {
|
||||
_, reader, err := ctr.Exec(ctx, cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lines, err := readLines(reader)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading lines:", err)
|
||||
}
|
||||
|
||||
fixedOutput := make([]string, len(lines))
|
||||
for i, line := range lines {
|
||||
fixedOutput[i] = cleanString([]byte(line))
|
||||
}
|
||||
return fixedOutput, nil
|
||||
|
||||
}
|
||||
|
||||
func setupGHRunner(ctx context.Context, envVars map[string]string) (*ghaRunnerontainer, error) {
|
||||
if os.Getenv("GH_RUNNER_IMAGE") == "" {
|
||||
return nil, fmt.Errorf("GH_RUNNER_IMAGE is not set")
|
||||
}
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: os.Getenv("GH_RUNNER_IMAGE"),
|
||||
ExposedPorts: []string{},
|
||||
Entrypoint: []string{"/usr/bin/sleep"},
|
||||
Cmd: []string{"60"},
|
||||
Env: envVars,
|
||||
}
|
||||
|
||||
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ghaRunnerontainer{Container: container}, nil
|
||||
}
|
||||
|
||||
type outputTest struct {
|
||||
name string
|
||||
cmd []string
|
||||
output []string
|
||||
statusCode int
|
||||
expectation string
|
||||
envVars map[string]string
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIntegrationGHRunner(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
theTests := []outputTest{
|
||||
{
|
||||
name: "default behavior",
|
||||
envVars: map[string]string{
|
||||
"DEBUG_ONLY": "true",
|
||||
"RUNNER_NAME": "test",
|
||||
},
|
||||
cmd: []string{"/entrypoint.sh", "something"},
|
||||
expectation: "The default behavior should be set correctly",
|
||||
output: []string{
|
||||
"REPO_URL required for repo runners",
|
||||
"Runner reusage is disabled",
|
||||
"",
|
||||
"Disable automatic registration: false",
|
||||
"Random runner suffix: true",
|
||||
"Runner name: test",
|
||||
"Runner workdir: /_work/test",
|
||||
"Labels: default",
|
||||
"Runner Group: Default",
|
||||
"Github Host: github.com",
|
||||
"Run as root:true",
|
||||
"Start docker: false",
|
||||
"Running something",
|
||||
},
|
||||
statusCode: 0,
|
||||
},
|
||||
{
|
||||
name: "non default behavior",
|
||||
envVars: map[string]string{
|
||||
"DEBUG_ONLY": "true",
|
||||
"RUNNER_NAME": "huzzah",
|
||||
"REPO_URL": "https://github.com/myoung34/docker-github-actions-runner",
|
||||
"RUN_AS_ROOT": "true",
|
||||
"RUNNER_NAME_PREFIX": "asdf",
|
||||
"ACCESS_TOKEN": "1234",
|
||||
"APP_ID": "5678",
|
||||
"APP_PRIVATE_KEY": "2345",
|
||||
"APP_LOGIN": "SOMETHING",
|
||||
"RUNNER_SCOPE": "org",
|
||||
"ORG_NAME": "myoung34",
|
||||
"ENTERPRISE_NAME": "emyoung34",
|
||||
"LABELS": "blue,green",
|
||||
"RUNNER_TOKEN": "3456",
|
||||
"RUNNER_WORKDIR": "/tmp/a",
|
||||
"RUNNER_GROUP": "wat",
|
||||
"GITHUB_HOST": "github.example.com",
|
||||
"DISABLE_AUTOMATIC_DEREGISTRATION": "true",
|
||||
"EPHEMERAL": "true",
|
||||
"DISABLE_AUTO_UPDATE": "true",
|
||||
},
|
||||
cmd: []string{"/entrypoint.sh", "something"},
|
||||
expectation: "The non default behavior should be set correctly",
|
||||
output: []string{
|
||||
"Runner reusage is disabled",
|
||||
"",
|
||||
"Disable automatic registration: true",
|
||||
"Random runner suffix: true",
|
||||
"Runner name: huzzah",
|
||||
"Runner workdir: /tmp/a",
|
||||
"Labels: blue,green",
|
||||
"Runner Group: wat",
|
||||
"Github Host: github.example.com",
|
||||
"Run as root:true",
|
||||
"Start docker: false",
|
||||
"Running something",
|
||||
},
|
||||
statusCode: 0,
|
||||
},
|
||||
{
|
||||
name: "gha softwrae installed",
|
||||
cmd: []string{"ls", "./bin/Runner.Listener"},
|
||||
expectation: "The GHA software should be installed in the container",
|
||||
output: []string{
|
||||
"./bin/Runner.Listener",
|
||||
},
|
||||
statusCode: 0,
|
||||
},
|
||||
}
|
||||
t.Logf("%v", theTests)
|
||||
|
||||
for _, theT := range theTests {
|
||||
|
||||
t.Run(theT.name, func(t *testing.T) {
|
||||
ghaRunner, err := setupGHRunner(ctx, theT.envVars)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Clean up the container after the test is complete
|
||||
t.Cleanup(func() {
|
||||
if err := ghaRunner.Terminate(ctx); err != nil {
|
||||
t.Fatalf("failed to terminate container: %s", err)
|
||||
}
|
||||
})
|
||||
|
||||
output, err := runAndReturnOutput(ghaRunner, ctx, theT.cmd)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// loop through output and compare to test output
|
||||
for i, line := range output {
|
||||
// skip if theT.output[i] is empty
|
||||
if theT.output[i] == "" {
|
||||
continue
|
||||
}
|
||||
if line != theT.output[i] {
|
||||
// try it again but without the first character in the line because of dumb unicode
|
||||
if line[1:] != theT.output[i] {
|
||||
if line != theT.output[i][1:] {
|
||||
if line[1:] != theT.output[i][1:] {
|
||||
t.Errorf("Expected %s, got %s", theT.output[i], line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user