Skip to content

Commit d7e5c99

Browse files
authored
Create run_linux.sh
1 parent b5bdd1c commit d7e5c99

File tree

1 file changed

+193
-0
lines changed

1 file changed

+193
-0
lines changed

Github/Runners/run_linux.sh

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#!/bin/env bash
2+
3+
#------------------------------------------------------------------------------------#
4+
#Sanity Checks
5+
if [ -z "${GITHUB_PERSONAL_TOKEN}" ] || \
6+
[ -z "${GITHUB_OWNER}" ] || \
7+
[ -z "${RUNNER_NAME}" ] || \
8+
[ -z "${RUNNER_LABELS}" ]; then
9+
#exit
10+
echo -e "\n[-] FATAL: Required ENV VARS NOT SET\n"
11+
echo -e "GITHUB_PERSONAL_TOKEN=${GITHUB_PERSONAL_TOKEN}"
12+
echo -e "GITHUB_OWNER=${GITHUB_OWNER}"
13+
echo -e "RUNNER_NAME=${RUNNER_NAME}"
14+
echo -e "RUNNER_LABELS=${RUNNER_LABELS}"
15+
exit 1
16+
elif [ -z "${GITHUB_REPOSITORY}" ] && [ -z "${GITHUB_ORG}" ]; then
17+
#exit
18+
echo -e "\n[-] FATAL: At least GITHUB_ORG or GITHUB_REPOSITORY must be specified\n"
19+
echo -e "GITHUB_ORG=${GITHUB_ORG}"
20+
echo -e "GITHUB_REPOSITORY=${GITHUB_REPOSITORY}"
21+
exit 1
22+
fi
23+
#------------------------------------------------------------------------------------#
24+
25+
#------------------------------------------------------------------------------------#
26+
##Start Docker
27+
#Check for kernel modules
28+
sudo systemctl stop docker 2>/dev/null
29+
sudo cp -au "/var/lib/docker" "/var/lib/docker.bk"
30+
sudo modprobe -n -q "fuse"
31+
fuse_overlayfs_status=$?
32+
sudo modprobe -n -q "btrfs"
33+
btrfs_status=$?
34+
if [[ $fuse_overlayfs_status -ne 0 && $btrfs_status -ne 0 ]]; then
35+
sudo modprobe "fuse" ; sudo modprobe "btrfs"
36+
echo -e "\n[+] Configuring Docker to use vfs\n"
37+
sudo rm -rf "/var/lib/docker/"
38+
if [[ ! -f "/etc/docker/daemon.json" ]]; then
39+
sudo mkdir -p "/etc/docker"
40+
echo '{"storage-driver": "vfs"}' | jq . | sudo tee -a "/etc/docker/daemon.json"
41+
else
42+
sudo sed 's/"storage-driver": "fuse-overlayfs"/"storage-driver": "vfs"/' -i "/etc/docker/daemon.json"
43+
sudo sed 's/"storage-driver": "btrfs"/"storage-driver": "vfs"/' -i "/etc/docker/daemon.json"
44+
jq . "/etc/docker/daemon.json"
45+
fi
46+
sudo cp -au "/var/lib/docker.bk/." "/var/lib/docker/" && sudo rm -rf "/var/lib/docker.bk"
47+
elif sudo grep -q 'btrfs' "/proc/filesystems" && sudo modprobe -n -q "btrfs"; then
48+
echo -e "\n[+] Configuring Docker to use btrfs\n"
49+
sudo rm -rf "/var/lib/docker/"
50+
sudo mkfs.btrfs -f "/dev/xvdf" "/dev/xvdg"
51+
sudo mount -t btrfs "/dev/xvdf" "/var/lib/docker"
52+
if [[ ! -f "/etc/docker/daemon.json" ]]; then
53+
echo '{"storage-driver": "btrfs"}' | jq . | sudo tee -a "/etc/docker/daemon.json"
54+
else
55+
sed 's/"storage-driver": "fuse-overlayfs"/"storage-driver": "btrfs"/' -i "/etc/docker/daemon.json"
56+
sed 's/"storage-driver": "vfs"/"storage-driver": "btrfs"/' -i "/etc/docker/daemon.json"
57+
jq . "/etc/docker/daemon.json"
58+
fi
59+
sudo cp -au "/var/lib/docker.bk/." "/var/lib/docker/" && sudo rm -rf "/var/lib/docker.bk"
60+
fi
61+
##Restart Services
62+
if command -v systemctl &>/dev/null && [ -s "/lib/systemd/system/docker.service" ]; then
63+
echo -e "\n[+] Starting supervisor (Docker)\n"
64+
sudo systemctl daemon-reload 2>/dev/null
65+
sudo systemctl enable docker --now 2>/dev/null
66+
sudo systemctl list-unit-files --type=service | grep -i "docker"
67+
if sudo systemctl is-active --quiet docker; then
68+
echo -e "\n[+] Docker is Active\n"
69+
sudo systemctl status "docker.service" --no-pager
70+
else
71+
echo -e "\n[+] Restarting Docker (1/2) ...\n"
72+
sudo service docker restart >/dev/null 2>&1 ; sleep 20
73+
if sudo systemctl is-active --quiet docker; then
74+
echo -e "\n[+] Docker is Active\n"
75+
sudo systemctl status "docker.service" --no-pager
76+
else
77+
echo -e "\n[+] Restarting Docker (2/2) ...\n"
78+
sudo service docker restart >/dev/null 2>&1 ; sleep 20
79+
sudo systemctl status "docker.service" --no-pager
80+
fi
81+
fi
82+
#if ! sudo systemctl is-active --quiet docker; then
83+
if sudo systemctl is-active --quiet docker; then
84+
sudo docker info
85+
else
86+
echo "[-] FATAL: Multiple Attempts to restart Docker Failed\nQuitting..."
87+
sudo systemctl status "docker.service" --no-pager
88+
exit 1
89+
fi
90+
fi
91+
#------------------------------------------------------------------------------------#
92+
93+
#------------------------------------------------------------------------------------#
94+
##Read from --env-file=runner.env & Authenticate
95+
if [ -n "${GITHUB_REPOSITORY}" ]; then
96+
echo -e "[+] Registering Runner For ${GITHUB_OWNER}/${GITHUB_REPOSITORY} [REPO]"
97+
export AUTH_URL="https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPOSITORY}/actions/runners/registration-token"
98+
export REG_URL="https://github.com/${GITHUB_OWNER}/${GITHUB_REPOSITORY}"
99+
elif [ -n "${GITHUB_ORG}" ]; then
100+
echo -e "[+] Registering Runner For ${GITHUB_ORG} [ORG]"
101+
export AUTH_URL="https://api.github.com/orgs/${GITHUB_OWNER}/actions/runners/registration-token"
102+
export REG_URL="https://github.com/${GITHUB_OWNER}"
103+
fi
104+
#------------------------------------------------------------------------------------#
105+
106+
#------------------------------------------------------------------------------------#
107+
##Func to Generate API Tokens
108+
generate_token() {
109+
echo -e "[+] Generating Token..."
110+
API_RESPONSE="$(curl -qfsSL -X 'POST' "${AUTH_URL}" -H "Authorization: Bearer ${GITHUB_PERSONAL_TOKEN}" -H 'Accept: application/vnd.github+json')" && export API_RESPONSE="${API_RESPONSE}"
111+
#Validate Response
112+
if ! echo "${API_RESPONSE}" | jq -e . >/dev/null 2>&1; then
113+
echo "[-] Error: API response is not a valid JSON."
114+
echo "${API_RESPONSE}"
115+
unset RUNNER_TOKEN
116+
exit 1
117+
else
118+
#Fetch Token
119+
RUNNER_TOKEN="$(echo "${API_RESPONSE}" | jq -r '.token' | tr -d '[:space:]')" && export RUNNER_TOKEN="${RUNNER_TOKEN}"
120+
if [ "${RUNNER_TOKEN}" == "null" ]; then
121+
echo "[-] Error: Couldn't fetch Ephemeral AUTH Token."
122+
echo "${API_RESPONSE}" | jq .
123+
unset RUNNER_TOKEN
124+
exit 1
125+
else
126+
echo -e "[+] Ephemeral AUTH Token :: ${RUNNER_TOKEN}"
127+
fi
128+
fi
129+
}
130+
export -f generate_token
131+
#------------------------------------------------------------------------------------#
132+
133+
#------------------------------------------------------------------------------------#
134+
##Register Runner
135+
cd "/runner-init"
136+
RUNNER_ID="${RUNNER_NAME}_$(openssl rand -hex 6 | tr -d '[:space:]')" && export RUNNER_ID="${RUNNER_ID}"
137+
echo "[+] Registering Runner --> ${RUNNER_ID}" && generate_token
138+
if [ -n "${RUNNER_TOKEN}" ]; then
139+
##Configure
140+
echo "[+] Configuring Runner..."
141+
echo "[+] (ID: ${RUNNER_ID})"
142+
echo "[+] (LABELS: ${RUNNER_LABELS})"
143+
echo "[+] (TOKEN: ${RUNNER_TOKEN})"
144+
echo "[+] (URL: ${REG_URL})"
145+
"/runner-init/config.sh" \
146+
--name "${RUNNER_ID}" \
147+
--labels "${RUNNER_LABELS}" \
148+
--token "${RUNNER_TOKEN}" \
149+
--url "${REG_URL}" \
150+
--unattended \
151+
--replace \
152+
--ephemeral
153+
else
154+
echo "[-] Failed to Generate Token..."
155+
echo -e "\n[+] GITHUB_PERSONAL_TOKEN: ${GITHUB_PERSONAL_TOKEN}\n"
156+
curl -fsSL "https://api.github.com/user" -H "Authorization: Bearer ${GITHUB_PERSONAL_TOKEN}" -H 'Accept: application/vnd.github+json'
157+
exit 1
158+
fi
159+
#------------------------------------------------------------------------------------#
160+
161+
#------------------------------------------------------------------------------------#
162+
##Remove Runner Upon Completion
163+
remove_runner() {
164+
generate_token
165+
echo -e "\n[+] Removing Runners ...\n"
166+
#Remove Offline Runners
167+
if [ -n "${GITHUB_REPOSITORY}" ]; then
168+
OFFLINE_RUNNERS="$(curl -qfsSL "https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPOSITORY}/actions/runners?per_page=100" -H "Authorization: Bearer ${GITHUB_PERSONAL_TOKEN}" -H 'Accept: application/vnd.github+json' | jq -r '.runners[] | select(.status == "offline") | .id')" && export OFFLINE_RUNNERS="${OFFLINE_RUNNERS}"
169+
readarray -t OFFLINE_RUNNERS_ID <<< "${OFFLINE_RUNNERS}"
170+
for R_ID in "${OFFLINE_RUNNERS_ID[@]}"; do
171+
curl -qfsSL -X 'DELETE' "https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPOSITORY}/actions/runners/${R_ID}" -H "Authorization: Bearer ${GITHUB_PERSONAL_TOKEN}" -H 'Accept: application/vnd.github+json'
172+
done
173+
elif [ -n "${GITHUB_ORG}" ]; then
174+
OFFLINE_RUNNERS="$(curl -qfsSL "https://api.github.com/orgs/${GITHUB_OWNER}/actions/runners?per_page=100" -H "Authorization: Bearer ${GITHUB_PERSONAL_TOKEN}" -H 'Accept: application/vnd.github+json' | jq -r '.runners[] | select(.status == "offline") | .id')" && export OFFLINE_RUNNERS="${OFFLINE_RUNNERS}"
175+
readarray -t OFFLINE_RUNNERS_ID <<< "${OFFLINE_RUNNERS}"
176+
for R_ID in "${OFFLINE_RUNNERS_ID[@]}"; do
177+
curl -qfsSL -X 'DELETE' "https://api.github.com/orgs/${GITHUB_OWNER}/actions/runners/${R_ID}" -H "Authorization: Bearer ${GITHUB_PERSONAL_TOKEN}" -H 'Accept: application/vnd.github+json'
178+
done
179+
fi
180+
#Remove Self
181+
"/runner-init/config.sh" remove --unattended --token "${RUNNER_TOKEN}"
182+
#Cleanup
183+
unset API_RESPONSE AUTH_URL OFFLINE_RUNNERS_ID REG_URL RUNNERS_ID R_ID RUNNER_ID RUNNER_LABELS RUNNER_TOKEN
184+
}
185+
export -f remove_runner
186+
#exit if ctrl + c
187+
trap 'remove_runner; exit 130' SIGINT
188+
#exit if kill|pkill -9
189+
trap 'remove_runner; exit 143' SIGTERM
190+
#------------------------------------------------------------------------------------#
191+
#Run with Initial ARGs
192+
"/runner-init/run.sh" "$*"
193+
#------------------------------------------------------------------------------------#

0 commit comments

Comments
 (0)