Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gitea support #323

Open
hulto opened this issue Dec 24, 2024 · 6 comments
Open

Gitea support #323

hulto opened this issue Dec 24, 2024 · 6 comments

Comments

@hulto
Copy link

hulto commented Dec 24, 2024

Hey!
I just started playing with Garm and I'm really enjoying it!
I'd like to use it with my gitea server as well as some GitHub repos.

Are there plans to add support for Gitea? If not is that something I can contribute?

@gabriel-samfira
Copy link
Member

Hi @hulto!

As long as Gitea/Forgejo supports:

  • ephemeral runners
  • registration tokens/JIT runners
  • can send webhooks with job runs so we can schedule runners to a pool
  • Has a way to allow us to list compatible agent downloads for linux/windows/mac/etc

It should be possible. However, I think there is an inherent danger in trying to support 2 different forges in the same project, as they may deviate significantly in the future and it may become cumbersome or downright impossible to consolidate. It may be wise to attempt to rearchitect parts of GARM and split off the bits that deal with the interaction between GARM and the forge. Similar to how providers work. But that would be a huge undertaking.

In the short term, if gitea has the above mentioned features, an attempt could be made to support it, if you have the time. Up to this point the focus has been to support GitHub and GHES. So the code mostly revolves around that assumption. But I think some thin abstractions could make gitea fit.

My experience with gitea is limited, so I am not sure how much I could help, but if I can, I will. If you want to tackle this, I suggest creating a proof of concept, hacked with an axe, just to see if it's feasible. Something that won't take months of your time, just to find that we can't merge it.

If having the two forges coexist does not seem possible, another option would be to fork GARM, yank out github and replace it with gitea. The we can merge back if/when the architecture of GARM permits pluggable forges, as we could then separately maintain plugins for gitea, github, etc.

So, plenty of options 😊.

@ChristopherHX
Copy link

I got so far with gitea + garm that the jobs are listed. By patching random stuff on both gitea and garm.

~/garm/garm-src$ ./bin/garm-cli job list
+----+------+-----------+------------+-------------+------------+------------------+-----------+
| ID | NAME | STATUS    | CONCLUSION | RUNNER NAME | REPOSITORY | REQUESTED LABELS | LOCKED BY |
+----+------+-----------+------------+-------------+------------+------------------+-----------+
|  5 | _    | queued    |            |             | test/test  | ubuntu           |           |
+----+------+-----------+------------+-------------+------------+------------------+-----------+
|  6 | _    | completed | cancelled  |             | test/test  | ubuntu           |           |
+----+------+-----------+------------+-------------+------------+------------------+-----------+

My problems are dropped error messages due to security.

  • Gitea Webhooks don't send any webhook installation level information e.g. repository, organization (user and global) (enterprise not available)

Does garm only try to create runners if it could fetch runner installation packages?

  • runner package download is 404 due to
    • not beeing implemented in gitea
    • go-github is configured via WithEnterpriseURLs this leads to weirdness of that method
      • GET http://rpi2server.fritz.box:3044/api/v1/api/v3/repos/test/test/actions/runners/downloads: 404, manually setting these exported fields is needed for gitea

@gabriel-samfira
Copy link
Member

Hi @ChristopherHX

Adding Gitea will be a bit more involved. There are a few assumptions in GARM that are related to GitHub. Each entity (Repo, Org, Enterprise) has a "pool manager" (needs to be reworked). That pool manager makes sure that the runners in each pool are properly created, deleted, etc. To ensure that GARM itselt has valid credentials to manage resources inside an entity, we periodically fetch the tools. We need them anyway, and in some cases, tools have a bearer token we need to ass to be able to download them (GHES). So checking for tools has a dual purpose:

  • Validate credentials
  • keep the tools object in cache for the entity

For Gitea we don't have enterprises, which is fine. But if Gitea doesn't have "organizations", only repos and global, we need to create a new entity type.

We also need to determine how webhooks work in Gitea. For example, in GitHub we can have an enterprise which has multiple orgs which in turn have multiple repos. I can install GARM at all 3 levels. If we have repo "testrepo" in org "testorg" which is part of "testenterprise" and I have GARM installed on all 3 levels, then whenever "testrepo" triggers a workflow, all 3 will send a webhook to GARM for the same job.

Does Gitea have a similar behavior? If so, we need a way to determine who triggered that webhook, so we know which pools are entitled to react and create a runner.

To get this to work we will need to:

  • Abstract the forge specific code that deals with webhooks
  • After determining the forge type, we need to:
    • Determine which entity types are available for this implementation
    • Save the job in the db and associate it with the entity
  • Create a new credentials type for the new forge type. Github has apps and PATs. Something similar needs to exist in Gitea.
  • Determine if JIT runners is officially supported, if not, this bit will be hidden away in the pool manager implementaion.
  • Abstract away the pool manager to consume jobs and create runners associated with a specific pool
    • Based on the origin forge, we need to generate proper userdata that sets up the runner and registers it in the forge

There are probably more points to consider, but if we are to add Gitea support, I need to cleanup the code a bit and remove some assumptions that are tightly coupled to GitHub. I would like to do this anyway, because I want us to be able to support Gitea as well as Forgejo. Porentially others in the future.

It might take a while though. In the meantime if you'd like to create a PoC, do not let me discourage you 🙂 .

@ChristopherHX
Copy link

ChristopherHX commented Feb 25, 2025

Gitea has

  • System/Global Runners (/admin/runners/registration-token) Gitea Only (replacement of enterprise)
  • User Runners (/user/actions/runners/registration-token) Gitea Only
  • Organization Runners (/orgs/{org}/actions/runners/registration-token) GitHub Compatible
  • Repo Runners (/repos/{owner}/{repo}/actions/runners/registration-token) GitHub Compatible <<<--- I tried this in the POC.

Abstract the forge specific code that deals with webhooks

For me this is only now this missing header then Gitea is able to use the GitHub code of garm

hookType := r.Header.Get("X-Github-Hook-Installation-Target-Type")

X-Github-Hook-Installation-Target-Type, Gitea send the other X-Github headers already.

I hardcoded repository in the POC.

Create a new credentials type for the new forge type. Github has apps and PATs. Something similar needs to exist in Gitea.

Not needed at first, I used PAT like GitHub. Gitea does it very good to behave like the GitHub Rest Api. Oidc etc. are enhancements.

e.g. the runner registration token retrieval is 100% the same if the GHES config does not append /api/v3 to a /api/v1 path.

Image

Determine if JIT runners is officially supported, if not, this bit will be hidden away in the pool manager implementaion.

Currently no.

At first I just thought this is straight forward (by just needed to provide a custom runner setup template), but yes this is sightly more complex, I come back to this topic in March.

This seems to be a used endpoint as well
failed to fetch github runners: fetching runners: GET http://rpi2server.fritz.box:3044/api/v1/repos/test/test/actions/runners?per_page=100

DeleteRunner not available as well

@ChristopherHX
Copy link

ChristopherHX commented Feb 28, 2025

So checking for tools has a dual purpose:

  • Validate credentials
  • keep the tools object in cache for the entity

Yes it really blocked progress, so the lxd pluginhas created runners for me by just returning the json from GitHub docs from Gitea for runner downloads. (at least until this feature is replicated, could also be skipped in a garm POC).

  • repository github api ok for my gitea test branch and patched garm to work with /api/v1 instead of /api/v3
  • get registration token ok (auto fallback, because jit tokens not supported, can take a while for me to add that stuff have some pending PRs to Gitea at this time)
  • start lxd container ok
  • track job status in garm ok
  • authentication via PAT ok

I omited the code I used, so ping me if you want the information. Added Gitea as repository level GHES instance.

Now I'am at step adding an extra spec to download and setup act_runner instead of GitHub's runner (while I have a way to proxy GitHub runners to gitea e.g. binary compatible, this is not my goal right now)

For arm64 systems only.... due to act_runner url

garm-cli pool update --extra-specs='{"enable_boot_debug": true,"runner_install_template":"IyEvYmluL2Jhc2gKCnNldCAtZQpzZXQgLW8gcGlwZWZhaWwKCnt7LSBpZiAuRW5hYmxlQm9vdERlYnVnIH19CnNldCAteAp7ey0gZW5kIH19CgpDQUxMQkFDS19VUkw9Int7IC5DYWxsYmFja1VSTCB9fSIKTUVUQURBVEFfVVJMPSJ7eyAuTWV0YWRhdGFVUkwgfX0iCkJFQVJFUl9UT0tFTj0ie3sgLkNhbGxiYWNrVG9rZW4gfX0iCgpSVU5fSE9NRT0iL2hvbWUve3sgLlJ1bm5lclVzZXJuYW1lIH19L2FjdGlvbnMtcnVubmVyIgoKaWYgWyAteiAiJE1FVEFEQVRBX1VSTCIgXTt0aGVuCgllY2hvICJubyB0b2tlbiBpcyBhdmFpbGFibGUgYW5kIE1FVEFEQVRBX1VSTCBpcyBub3Qgc2V0IgoJZXhpdCAxCmZpCgpmdW5jdGlvbiBjYWxsKCkgewoJUEFZTE9BRD0iJDEiCglbWyAkQ0FMTEJBQ0tfVVJMID1+IF4oLiopL3N0YXR1cygvKT8kIF1dIHx8IENBTExCQUNLX1VSTD0iJHtDQUxMQkFDS19VUkx9L3N0YXR1cyIKCWN1cmwgLS1yZXRyeSA1IC0tcmV0cnktZGVsYXkgNSAtLXJldHJ5LWNvbm5yZWZ1c2VkIC0tZmFpbCAtcyAtWCBQT1NUIC1kICIke1BBWUxPQUR9IiAtSCAnQWNjZXB0OiBhcHBsaWNhdGlvbi9qc29uJyAtSCAiQXV0aG9yaXphdGlvbjogQmVhcmVyICR7QkVBUkVSX1RPS0VOfSIgIiR7Q0FMTEJBQ0tfVVJMfSIgfHwgZWNobyAiZmFpbGVkIHRvIGNhbGwgaG9tZTogZXhpdCBjb2RlICgkPykiCn0KCmZ1bmN0aW9uIHN5c3RlbUluZm8oKSB7CglpZiBbIC1mICIvZXRjL29zLXJlbGVhc2UiIF07dGhlbgoJCS4gL2V0Yy9vcy1yZWxlYXNlCglmaQoJT1NfTkFNRT0ke05BTUU6LSIifQoJT1NfVkVSU0lPTj0ke1ZFUlNJT05fSUQ6LSIifQoJQUdFTlRfSUQ9JHsxOi1udWxsfQoJIyBzdHJpcCBzdGF0dXMgZnJvbSB0aGUgY2FsbGJhY2sgdXJsCglbWyAkQ0FMTEJBQ0tfVVJMID1+IF4oLiopL3N0YXR1cygvKT8kIF1dICYmIENBTExCQUNLX1VSTD0iJHtCQVNIX1JFTUFUQ0hbMV19IiB8fCB0cnVlCglTWVNJTkZPX1VSTD0iJHtDQUxMQkFDS19VUkx9L3N5c3RlbS1pbmZvLyIKCVBBWUxPQUQ9IntcIm9zX25hbWVcIjogXCIkT1NfTkFNRVwiLCBcIm9zX3ZlcnNpb25cIjogXCIkT1NfVkVSU0lPTlwiLCBcImFnZW50X2lkXCI6ICRBR0VOVF9JRH0iCgljdXJsIC0tcmV0cnkgNSAtLXJldHJ5LWRlbGF5IDUgLS1yZXRyeS1jb25ucmVmdXNlZCAtLWZhaWwgLXMgLVggUE9TVCAtZCAiJHtQQVlMT0FEfSIgLUggJ0FjY2VwdDogYXBwbGljYXRpb24vanNvbicgLUggIkF1dGhvcml6YXRpb246IEJlYXJlciAke0JFQVJFUl9UT0tFTn0iICIke1NZU0lORk9fVVJMfSIgfHwgdHJ1ZQp9CgpmdW5jdGlvbiBzZW5kU3RhdHVzKCkgewoJTVNHPSIkMSIKCWNhbGwgIntcInN0YXR1c1wiOiBcImluc3RhbGxpbmdcIiwgXCJtZXNzYWdlXCI6IFwiJE1TR1wifSIKfQoKZnVuY3Rpb24gc3VjY2VzcygpIHsKCU1TRz0iJDEiCglJRD0kezI6LW51bGx9CgljYWxsICJ7XCJzdGF0dXNcIjogXCJpZGxlXCIsIFwibWVzc2FnZVwiOiBcIiRNU0dcIiwgXCJhZ2VudF9pZFwiOiAkSUR9Igp9CgpmdW5jdGlvbiBmYWlsKCkgewoJTVNHPSIkMSIKCWNhbGwgIntcInN0YXR1c1wiOiBcImZhaWxlZFwiLCBcIm1lc3NhZ2VcIjogXCIkTVNHXCJ9IgoJZXhpdCAxCn0KCmZ1bmN0aW9uIGRvd25sb2FkQW5kRXh0cmFjdFJ1bm5lcigpIHsKCXNlbmRTdGF0dXMgImRvd25sb2FkaW5nIHRvb2xzIGZyb20gaHR0cHM6Ly9kbC5naXRlYS5jb20vYWN0X3J1bm5lci8wLjIuMTEvYWN0X3J1bm5lci0wLjIuMTEtbGludXgtYXJtNjQiCglta2RpciAtcCAiJFJVTl9IT01FIiB8fCBmYWlsICJmYWlsZWQgdG8gY3JlYXRlIGFjdGlvbnMtcnVubmVyIGZvbGRlciIKCWN1cmwgLS1yZXRyeSA1IC0tcmV0cnktZGVsYXkgNSAtLXJldHJ5LWNvbm5yZWZ1c2VkIC0tZmFpbCAtTCAtbyAiJFJVTl9IT01FL2FjdF9ydW5uZXIiICJodHRwczovL2RsLmdpdGVhLmNvbS9hY3RfcnVubmVyLzAuMi4xMS9hY3RfcnVubmVyLTAuMi4xMS1saW51eC1hcm02NCIgfHwgZmFpbCAiZmFpbGVkIHRvIGRvd25sb2FkIHRvb2xzIgogICAgc3VkbyBjaG93biB7eyAuUnVubmVyVXNlcm5hbWUgfX06e3sgLlJ1bm5lckdyb3VwIH19IC1SIC9ob21lL3t7IC5SdW5uZXJVc2VybmFtZSB9fSB8fCBmYWlsICJmYWlsZWQgdG8gY2hhbmdlIG93bmVyIgogICAgc3VkbyBjaG1vZCAreCAiJFJVTl9IT01FL2FjdF9ydW5uZXIiIHx8IGZhaWwgImZhaWxlZCB0byBjaGFuZ2UgcGVybWlzc2lvbnMiCiAgICBzdWRvIHRlZSAiJFJVTl9IT01FL2FjdF9ydW5uZXIuc2VydmljZSIgPDxFT0YKW1VuaXRdCkRlc2NyaXB0aW9uPWFjdF9ydW5uZXIKQWZ0ZXI9bmV0d29yay50YXJnZXQKCltTZXJ2aWNlXQpVc2VyPXt7IC5SdW5uZXJVc2VybmFtZSB9fQpFbnZpcm9ubWVudD1IT01FPS9ob21lL3t7IC5SdW5uZXJVc2VybmFtZSB9fQpFeGVjU3RhcnQ9JFJVTl9IT01FL2FjdF9ydW5uZXIgZGFlbW9uCldvcmtpbmdEaXJlY3Rvcnk9JFJVTl9IT01FCktpbGxNb2RlPXByb2Nlc3MKS2lsbFNpZ25hbD1TSUdJTlQKVGltZW91dFN0b3BTZWM9NW1pbgoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CkVPRgogICAgc3VkbyBzeXN0ZW1jdGwgZW5hYmxlICRSVU5fSE9NRS9hY3RfcnVubmVyLnNlcnZpY2UKfQoKaWYgWyAhIC1kICIkUlVOX0hPTUUiIF07dGhlbgoJZG93bmxvYWRBbmRFeHRyYWN0UnVubmVyCgljZCAiJFJVTl9IT01FIgplbHNlCglzZW5kU3RhdHVzICJ1c2luZyBjYWNoZWQgcnVubmVyIGZvdW5kIGluICRSVU5fSE9NRSIKCWNkICIkUlVOX0hPTUUiCmZpCgoKc2VuZFN0YXR1cyAiY29uZmlndXJpbmcgcnVubmVyIgp7ey0gaWYgLlVzZUpJVENvbmZpZyB9fQp7ey0gZWxzZX19CgpHSVRIVUJfVE9LRU49JChjdXJsIC0tcmV0cnkgNSAtLXJldHJ5LWRlbGF5IDUgLS1yZXRyeS1jb25ucmVmdXNlZCAtLWZhaWwgLXMgLVggR0VUIC1IICdBY2NlcHQ6IGFwcGxpY2F0aW9uL2pzb24nIC1IICJBdXRob3JpemF0aW9uOiBCZWFyZXIgJHtCRUFSRVJfVE9LRU59IiAiJHtNRVRBREFUQV9VUkx9L3J1bm5lci1yZWdpc3RyYXRpb24tdG9rZW4vIikKCnNldCArZQphdHRlbXB0PTEKd2hpbGUgdHJ1ZTsgZG8KCUVSUk9VVD0kKG1rdGVtcCkKCXt7LSBpZiAuR2l0SHViUnVubmVyR3JvdXAgfX0KCXt7LSBlbHNlfX0KCiAgICAjIC0tZXBoZW1lcmFsIG9uY2Ugc3VwcG9ydGVkCiAgICAjICJ7eyAuUnVubmVyTGFiZWxzIH19IgogICAgLi9hY3RfcnVubmVyIHJlZ2lzdGVyIC0tbm8taW50ZXJhY3RpdmUgLS1pbnN0YW5jZSAiJChlY2hvICJ7eyAuUmVwb1VSTCB9fSIgfCBjdXQgLWQnLycgLWYxLTMpIiAtLXRva2VuICIkR0lUSFVCX1RPS0VOIiAtLW5hbWUgInt7IC5SdW5uZXJOYW1lIH19IiAtLWxhYmVscyAidWJ1bnR1LGdlbmVyaWMiIDI+JEVSUk9VVAoJe3stIGVuZH19CglpZiBbICQ/IC1lcSAwIF07IHRoZW4KCQlybSAkRVJST1VUIHx8IHRydWUKCQlzZW5kU3RhdHVzICJydW5uZXIgc3VjY2Vzc2Z1bGx5IGNvbmZpZ3VyZWQgYWZ0ZXIgJGF0dGVtcHQgYXR0ZW1wdChzKSIKCQlicmVhawoJZmkKCUxBU1RfRVJSPSQoY2F0ICRFUlJPVVQpCgllY2hvICIkTEFTVF9FUlIiCgoJaWYgWyAkYXR0ZW1wdCAtZ3QgNSBdO3RoZW4KCQlybSAkRVJST1VUIHx8IHRydWUKCQlmYWlsICJmYWlsZWQgdG8gY29uZmlndXJlIHJ1bm5lcjogJExBU1RfRVJSIgoJZmkKCglzZW5kU3RhdHVzICJmYWlsZWQgdG8gY29uZmlndXJlIHJ1bm5lciAoYXR0ZW1wdCAkYXR0ZW1wdCk6ICRMQVNUX0VSUiAocmV0cnlpbmcgaW4gNSBzZWNvbmRzKSIKCWF0dGVtcHQ9JCgoYXR0ZW1wdCsxKSkKCXJtICRFUlJPVVQgfHwgdHJ1ZQoJc2xlZXAgNQpkb25lCnNldCAtZQp7ey0gZW5kfX0KCmlmIFsgLWUgIi9zeXMvZnMvc2VsaW51eCIgXTt0aGVuCglzdWRvIGNoY29uIC1SIC1oIHVzZXJfdTpvYmplY3RfcjpiaW5fdDpzMCAvaG9tZS9ydW5uZXIvIHx8IGZhaWwgImZhaWxlZCB0byBjaGFuZ2Ugc2VsaW51eCBjb250ZXh0IgpmaQoKQUdFTlRfSUQ9IiIKe3stIGlmIC5Vc2VKSVRDb25maWcgfX0Ke3stIGVsc2V9fQpzdWRvIHN5c3RlbWN0bCBzdGFydCBhY3RfcnVubmVyIHx8IGZhaWwgImZhaWxlZCB0byBzdGFydCBzZXJ2aWNlIgp7ey0gZW5kfX0Kc3lzdGVtSW5mbyAkQUdFTlRfSUQKc3VjY2VzcyAicnVubmVyIHN1Y2Nlc3NmdWxseSBpbnN0YWxsZWQiICRBR0VOVF9JRAo="}'  <POOL_ID>

Debugging tips for the runner setup of the lxd garm backend would help me a lot.

runnerinstalltemplate gitea prototype label ubuntu,generic hardcoded in POC (the label using : cause register to fail with exit code 0 :( )

For arm64 systems only.... due to act_runner url

#!/bin/bash

set -e
set -o pipefail

{{- if .EnableBootDebug }}
set -x
{{- end }}

CALLBACK_URL="{{ .CallbackURL }}"
METADATA_URL="{{ .MetadataURL }}"
BEARER_TOKEN="{{ .CallbackToken }}"

RUN_HOME="/home/{{ .RunnerUsername }}/actions-runner"

if [ -z "$METADATA_URL" ];then
	echo "no token is available and METADATA_URL is not set"
	exit 1
fi

function call() {
	PAYLOAD="$1"
	[[ $CALLBACK_URL =~ ^(.*)/status(/)?$ ]] || CALLBACK_URL="${CALLBACK_URL}/status"
	curl --retry 5 --retry-delay 5 --retry-connrefused --fail -s -X POST -d "${PAYLOAD}" -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "${CALLBACK_URL}" || echo "failed to call home: exit code ($?)"
}

function systemInfo() {
	if [ -f "/etc/os-release" ];then
		. /etc/os-release
	fi
	OS_NAME=${NAME:-""}
	OS_VERSION=${VERSION_ID:-""}
	AGENT_ID=${1:-null}
	# strip status from the callback url
	[[ $CALLBACK_URL =~ ^(.*)/status(/)?$ ]] && CALLBACK_URL="${BASH_REMATCH[1]}" || true
	SYSINFO_URL="${CALLBACK_URL}/system-info/"
	PAYLOAD="{\"os_name\": \"$OS_NAME\", \"os_version\": \"$OS_VERSION\", \"agent_id\": $AGENT_ID}"
	curl --retry 5 --retry-delay 5 --retry-connrefused --fail -s -X POST -d "${PAYLOAD}" -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "${SYSINFO_URL}" || true
}

function sendStatus() {
	MSG="$1"
	call "{\"status\": \"installing\", \"message\": \"$MSG\"}"
}

function success() {
	MSG="$1"
	ID=${2:-null}
	call "{\"status\": \"idle\", \"message\": \"$MSG\", \"agent_id\": $ID}"
}

function fail() {
	MSG="$1"
	call "{\"status\": \"failed\", \"message\": \"$MSG\"}"
	exit 1
}

function downloadAndExtractRunner() {
	sendStatus "downloading tools from https://dl.gitea.com/act_runner/0.2.11/act_runner-0.2.11-linux-arm64"
	mkdir -p "$RUN_HOME" || fail "failed to create actions-runner folder"
	curl --retry 5 --retry-delay 5 --retry-connrefused --fail -L -o "$RUN_HOME/act_runner" "https://dl.gitea.com/act_runner/0.2.11/act_runner-0.2.11-linux-arm64" || fail "failed to download tools"
    sudo chown {{ .RunnerUsername }}:{{ .RunnerGroup }} -R /home/{{ .RunnerUsername }} || fail "failed to change owner"
    sudo chmod +x "$RUN_HOME/act_runner" || fail "failed to change permissions"
    sudo tee "$RUN_HOME/act_runner.service" <<EOF
[Unit]
Description=act_runner
After=network.target

[Service]
User={{ .RunnerUsername }}
Environment=HOME=/home/{{ .RunnerUsername }}
ExecStart=$RUN_HOME/act_runner daemon
WorkingDirectory=$RUN_HOME
KillMode=process
KillSignal=SIGINT
TimeoutStopSec=5min

[Install]
WantedBy=multi-user.target
EOF
    sudo systemctl enable $RUN_HOME/act_runner.service
}

if [ ! -d "$RUN_HOME" ];then
	downloadAndExtractRunner
	cd "$RUN_HOME"
else
	sendStatus "using cached runner found in $RUN_HOME"
	cd "$RUN_HOME"
fi


sendStatus "configuring runner"
{{- if .UseJITConfig }}
{{- else}}

GITHUB_TOKEN=$(curl --retry 5 --retry-delay 5 --retry-connrefused --fail -s -X GET -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "${METADATA_URL}/runner-registration-token/")

set +e
attempt=1
while true; do
	ERROUT=$(mktemp)
	{{- if .GitHubRunnerGroup }}
	{{- else}}

    # --ephemeral once supported
    # "{{ .RunnerLabels }}" once `:` supported
    ./act_runner register --no-interactive --instance "$(echo "{{ .RepoURL }}" | cut -d'/' -f1-3)" --token "$GITHUB_TOKEN" --name "{{ .RunnerName }}" --labels "ubuntu,generic" 2>$ERROUT
	{{- end}}
	if [ $? -eq 0 ]; then
		rm $ERROUT || true
		sendStatus "runner successfully configured after $attempt attempt(s)"
		break
	fi
	LAST_ERR=$(cat $ERROUT)
	echo "$LAST_ERR"

	if [ $attempt -gt 5 ];then
		rm $ERROUT || true
		fail "failed to configure runner: $LAST_ERR"
	fi

	sendStatus "failed to configure runner (attempt $attempt): $LAST_ERR (retrying in 5 seconds)"
	attempt=$((attempt+1))
	rm $ERROUT || true
	sleep 5
done
set -e
{{- end}}

if [ -e "/sys/fs/selinux" ];then
	sudo chcon -R -h user_u:object_r:bin_t:s0 /home/runner/ || fail "failed to change selinux context"
fi

AGENT_ID=""
{{- if .UseJITConfig }}
{{- else}}
sudo systemctl start act_runner || fail "failed to start service"
{{- end}}
systemInfo $AGENT_ID
success "runner successfully installed" $AGENT_ID

This branch of Gitea used by the POC: https://github.com/ChristopherHX/gitea/tree/workflow_job_webhook PRs pending for non stub parts

  • runner download stub (only included here)
  • runner register token POST method (only included here right now, idk why it uses GET)

Version of GARM that can configure go-github for gitea: https://github.com/actions-oss/gitea-garm-poc, otherwise didn't need edits if my version of gitea is used.

The --ephemeral flag act_runner can be found here: https://gitea.com/gitea/act_runner/pulls/649
Then the runner_setup_template needs to be updated with a new download url + the cli flag, then the runners that pick a task get removed from the webui automatically.

Open Bugs

@gabriel-samfira
Copy link
Member

Hi @ChristopherHX

Amazing progress! I am currently fighting off a flu or something. Will have some input for you as soon as my brain works again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants