fix: refactor into python script
This commit is contained in:
committed by
Gabriel Nützi
parent
57665ba763
commit
f8dc4e3c29
+20
-114
@@ -126,7 +126,7 @@ in
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
let
|
||||
auth = pkgs.writeText "auth.json" (
|
||||
authPayload = pkgs.writeText "auth.json" (
|
||||
builtins.toJSON {
|
||||
grant_type = "password";
|
||||
username = "root";
|
||||
@@ -134,129 +134,35 @@ in
|
||||
}
|
||||
);
|
||||
|
||||
runnerTokenTmpl = pkgs.writeText "runner-token.env" ''
|
||||
runnerTokenEnv = pkgs.writeText "runner-token.env" ''
|
||||
CI_SERVER_URL=http://gitlab
|
||||
CI_SERVER_TOKEN=$token
|
||||
'';
|
||||
|
||||
createRunner = pkgs.writeText "create-runner.json" (
|
||||
createRunnerPayload = pkgs.writeText "create-runner.json" (
|
||||
builtins.toJSON {
|
||||
runner_type = "instance_type";
|
||||
}
|
||||
);
|
||||
|
||||
# Wait for all GitLab services to be fully started.
|
||||
waitForServices = ''
|
||||
gitlab.wait_for_unit("gitaly.service")
|
||||
gitlab.wait_for_unit("gitlab-workhorse.service")
|
||||
gitlab.wait_for_unit("gitlab.service")
|
||||
gitlab.wait_for_unit("gitlab-sidekiq.service")
|
||||
gitlab.wait_for_file("${nodes.gitlab.services.gitlab.statePath}/tmp/sockets/gitlab.socket")
|
||||
gitlab.wait_until_succeeds("curl -sSf http://gitlab/users/sign_in")
|
||||
'';
|
||||
|
||||
testSetup =
|
||||
# python
|
||||
''
|
||||
import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
from string import Template
|
||||
from dataclasses import dataclass
|
||||
|
||||
print("==> Getting secrets and headers.")
|
||||
gitlab.succeed("cp /var/gitlab/state/config/secrets.yml /root/gitlab-secrets.yml")
|
||||
|
||||
gitlab.succeed(
|
||||
"echo \"Authorization: Bearer $(curl -X POST -H 'Content-Type: application/json' -d @${auth} http://gitlab/oauth/token | ${pkgs.jq}/bin/jq -r '.access_token')\" >/tmp/headers"
|
||||
)
|
||||
|
||||
gitlab.copy_from_vm("/tmp/headers")
|
||||
out_dir = os.environ.get("out", os.getcwd())
|
||||
gitlab_runner.copy_from_host(str(Path(out_dir, "headers")), "/tmp/headers")
|
||||
|
||||
print("==> Testing connection.")
|
||||
gitlab_runner.succeed("curl -v -H @/tmp/headers http://gitlab/api/v4/version")
|
||||
|
||||
# Runner config data.
|
||||
@dataclass
|
||||
class Runner:
|
||||
name: str
|
||||
desc: str
|
||||
tokenFile: str
|
||||
|
||||
id: str
|
||||
token: str
|
||||
|
||||
runnerConfigs: dict[str, Runner] = {}
|
||||
'';
|
||||
|
||||
testRegisterRunner =
|
||||
runnerConfig:
|
||||
# python
|
||||
''
|
||||
r = Runner(name="${runnerConfig.name}",
|
||||
desc="${runnerConfig.desc}",
|
||||
tokenFile="${runnerConfig.tokenFile}",
|
||||
token="",
|
||||
id="")
|
||||
runnerConfigs[r.name] = r
|
||||
|
||||
print(f"==> Create Runner '{r.name}'")
|
||||
resp = gitlab.execute("""
|
||||
curl -s -X POST \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H @/tmp/headers \
|
||||
-d @${createRunner} \
|
||||
http://gitlab/api/v4/user/runners
|
||||
""")[1]
|
||||
obj = json.loads(resp)
|
||||
r.id = obj["id"]
|
||||
r.token = obj["token"]
|
||||
|
||||
# Push the token to the runner machine.
|
||||
print("==> Push runner token to machine.")
|
||||
tokenF = Path(out_dir, f"token-{r.name}.env")
|
||||
with open("${runnerTokenTmpl}", "r") as f:
|
||||
tokenData = Template(f.read()).substitute({"token": token})
|
||||
with open(tokenF, "w") as w:
|
||||
w.write(tokenData)
|
||||
gitlab_runner.copy_from_host(str(tokenF), r.tokenFile)
|
||||
'';
|
||||
|
||||
restartRunnerService =
|
||||
# python
|
||||
''
|
||||
print("==> Restart Gitlab Runner")
|
||||
gitlab_runner.systemctl("restart gitlab-runner.service")
|
||||
gitlab_runner.wait_for_unit("gitlab-runner.service")
|
||||
'';
|
||||
|
||||
testRunnerConnected =
|
||||
runnerConfig:
|
||||
# python
|
||||
''
|
||||
r = runnerConfigs["${runnerConfig.name}"]
|
||||
|
||||
resp = gitlab.execute(f"""
|
||||
curl -s -X GET \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H @/tmp/headers \
|
||||
http://gitlab/api/v4/runners/{r.id}
|
||||
""")[1]
|
||||
runnerStatus = json.loads(resp)
|
||||
|
||||
if not runnerStatus["active"]:
|
||||
raise Exception(f"Runner '{r.name}' [id: '{r.id}'] status is not active: {resp}")
|
||||
'';
|
||||
in
|
||||
# python
|
||||
''
|
||||
# Define some globals for the python script below.
|
||||
JQ_BINARY="${pkgs.jq}/bin/jq"
|
||||
GITLAB_STATE_PATH="${nodes.gitlab.services.gitlab.statePath}"
|
||||
RUNNER_TOKEN_ENV_FILE="${runnerTokenEnv}"
|
||||
AUTH_PAYLOAD_FILE="${authPayload}"
|
||||
CREATE_RUNNER_PAYLOAD_FILE="${createRunnerPayload}"
|
||||
|
||||
${lib.readFile ./runner_test.py}
|
||||
|
||||
start_all()
|
||||
''
|
||||
+ waitForServices
|
||||
+ testSetup
|
||||
+ (testRegisterRunner runnerConfigs.shell)
|
||||
+ restartRunnerService
|
||||
+ (testRunnerConnected runnerConfigs.shell);
|
||||
wait_for_services()
|
||||
|
||||
# Run all tests.
|
||||
test_connection()
|
||||
test_register_runner(name="shell", tokenFile="${runnerConfigs.shell.tokenFile}")
|
||||
restart_gitlab_runner_service()
|
||||
test_runner_registered(runnerConfigs["shell"])
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
import json
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from string import Template
|
||||
from typing import Any
|
||||
|
||||
|
||||
@dataclass
|
||||
class Runner:
|
||||
name: str
|
||||
tokenFile: str
|
||||
|
||||
id: str
|
||||
token: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Machines:
|
||||
gitlab: Any
|
||||
gitlab_runner: Any
|
||||
|
||||
|
||||
@dataclass
|
||||
class Nix:
|
||||
jq: str
|
||||
gitlab_state_path: str
|
||||
create_runner_payload_file: str
|
||||
auth_payload_file: str
|
||||
runner_token_env_file: str
|
||||
|
||||
|
||||
# Some global variables to work in the tests.
|
||||
out_dir = os.environ.get("out", os.getcwd())
|
||||
nix = Nix(
|
||||
jq=JQ_BINARY,
|
||||
gitlab_state_path=GITLAB_STATE_PATH,
|
||||
auth_payload_file=AUTH_PAYLOAD_FILE,
|
||||
create_runner_payload_file=CREATE_RUNNER_PAYLOAD_FILE,
|
||||
runner_token_env_file=RUNNER_TOKEN_ENV_FILE,
|
||||
)
|
||||
vms = Machines(gitlab, gitlab_runner)
|
||||
runnerConfigs: dict[str, Runner] = {}
|
||||
|
||||
|
||||
def wait_for_services():
|
||||
vms.gitlab.wait_for_unit("gitaly.service")
|
||||
vms.gitlab.wait_for_unit("gitlab-workhorse.service")
|
||||
vms.gitlab.wait_for_unit("gitlab.service")
|
||||
vms.gitlab.wait_for_unit("gitlab-sidekiq.service")
|
||||
vms.gitlab.wait_for_file(f"{nix.gitlab_state_path}/tmp/sockets/gitlab.socket")
|
||||
vms.gitlab.wait_until_succeeds("curl -sSf http://gitlab/users/sign_in")
|
||||
|
||||
|
||||
def test_connection():
|
||||
"""
|
||||
Test the connection to Gitlab and check if it is reachable from the runner VM.
|
||||
"""
|
||||
|
||||
print("==> Getting secrets and headers.")
|
||||
vms.gitlab.succeed(
|
||||
"cp /var/gitlab/state/config/secrets.yml /root/gitlab-secrets.yml"
|
||||
)
|
||||
|
||||
vms.gitlab.succeed(
|
||||
f"echo \"Authorization: Bearer $(curl -X POST -H 'Content-Type: application/json' -d @{nix.auth_payload_file} http://gitlab/oauth/token | {nix.jq} -r '.access_token')\" >/tmp/headers"
|
||||
)
|
||||
|
||||
vms.gitlab.copy_from_vm("/tmp/headers")
|
||||
out_dir = os.environ.get("out", os.getcwd())
|
||||
vms.gitlab_runner.copy_from_host(str(Path(out_dir, "headers")), "/tmp/headers")
|
||||
|
||||
print("==> Testing connection.")
|
||||
vms.gitlab_runner.succeed("curl -v -H @/tmp/headers http://gitlab/api/v4/version")
|
||||
|
||||
|
||||
def test_register_runner(name: str, tokenFile: str):
|
||||
"""
|
||||
Register the runner in Gitlab and write the token file to be picked up by
|
||||
the gitlab-runner service on the other VM.
|
||||
"""
|
||||
|
||||
r = Runner(
|
||||
name=name,
|
||||
tokenFile=tokenFile,
|
||||
token="",
|
||||
id="",
|
||||
)
|
||||
runnerConfigs[r.name] = r
|
||||
|
||||
print(f"==> Create Runner '{r.name}'")
|
||||
resp = vms.gitlab.execute(
|
||||
f"""
|
||||
curl -s -X POST \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H @/tmp/headers \
|
||||
-d @{nix.create_runner_payload_file} \
|
||||
http://gitlab/api/v4/user/runners
|
||||
"""
|
||||
)[1]
|
||||
obj = json.loads(resp)
|
||||
r.id = obj["id"]
|
||||
r.token = obj["token"]
|
||||
|
||||
# Push the token to the runner machine.
|
||||
print("==> Push runner token to machine.")
|
||||
tokenF = Path(out_dir, f"token-{r.name}.env")
|
||||
with open("${runnerTokenTmpl}", "r") as f:
|
||||
tokenData = Template(f.read()).substitute({"token": r.token})
|
||||
with open(tokenF, "w") as w:
|
||||
w.write(tokenData)
|
||||
vms.gitlab_runner.copy_from_host(str(tokenF), r.tokenFile)
|
||||
|
||||
|
||||
def restart_gitlab_runner_service():
|
||||
print("==> Restart Gitlab Runner")
|
||||
vms.gitlab_runner.systemctl("restart gitlab-runner.service")
|
||||
vms.gitlab_runner.wait_for_unit("gitlab-runner.service")
|
||||
|
||||
|
||||
def test_runner_registered(r: Runner):
|
||||
"""
|
||||
Test that the runner `r` is registered in Gitlab and its status is active.
|
||||
"""
|
||||
|
||||
print("==> Check that runner '{r.name}' is registered.")
|
||||
|
||||
resp = vms.gitlab.execute(
|
||||
f"""
|
||||
curl -s -X GET \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H @/tmp/headers \
|
||||
http://gitlab/api/v4/runners/{r.id}"""
|
||||
)[1]
|
||||
runnerStatus = json.loads(resp)
|
||||
|
||||
if not runnerStatus["active"]:
|
||||
raise Exception(
|
||||
f"Runner '{r.name}' [id: '{r.id}'] status is not active: {resp}"
|
||||
)
|
||||
Reference in New Issue
Block a user