Skip to content

Commit

Permalink
run user-defined functionality in job_started and job_completed hooks (
Browse files Browse the repository at this point in the history
…#649)

Adds the ability to inject bash into the job started and job completed
hook through the runner group in the runner-manager.yaml config

Fixes: #577
  • Loading branch information
evawoodbridge authored Jul 19, 2024
1 parent 77cdd70 commit 99a4199
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 0 deletions.
12 changes: 12 additions & 0 deletions runner_manager/bin/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,15 @@ function job_started {
sleep 5
done
fi
# Run bash injected through runner group config
bash /opt/runner/job_started_script.sh
echo "Done"
}

function job_completed {
# This function is called when the job is completed
# Run bash injected through runner group config
bash /opt/runner/job_completed_script.sh
echo "Job completed"

}
Expand Down Expand Up @@ -126,6 +130,14 @@ function setup_runner {
sudo -H -u actions bash -c "nohup /home/actions/actions-runner/run.sh --jitconfig \"${JIT_CONFIG}\" 2>/home/actions/actions-runner/logs &"
fi

cat <<EOF >/opt/runner/job_started_script.sh
${RUNNER_JOB_STARTED_SCRIPT}
EOF

cat <<EOF >/opt/runner/job_completed_script.sh
${RUNNER_JOB_COMPLETED_SCRIPT}
EOF

}

function install_docker {
Expand Down
4 changes: 4 additions & 0 deletions runner_manager/models/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class RunnerEnv(BaseModel):
RUNNER_GROUP: Optional[str] = None
RUNNER_REDHAT_USERNAME: Optional[str] = None
RUNNER_REDHAT_PASSWORD: Optional[str] = None
RUNNER_JOB_STARTED_SCRIPT: Optional[str] = ""
RUNNER_JOB_COMPLETED_SCRIPT: Optional[str] = ""


class InstanceConfig(BaseSettings):
Expand All @@ -63,6 +65,8 @@ def runner_env(self, runner: Runner) -> RunnerEnv:
RUNNER_REDHAT_PASSWORD=(
self.redhat_password if self.redhat_password else None
),
RUNNER_JOB_STARTED_SCRIPT=runner.job_started_script,
RUNNER_JOB_COMPLETED_SCRIPT=runner.job_completed_script,
)

def template_startup(self, runner: Runner) -> str:
Expand Down
2 changes: 2 additions & 0 deletions runner_manager/models/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class Runner(BaseModel):
organization: str = Field(default=None, index=True, description="Organization name")
created_at: Optional[datetime]
started_at: Optional[datetime]
job_started_script: Optional[str] = ""
job_completed_script: Optional[str] = ""

def __str__(self):
return f"{self.name} (status: {self.status}, busy: {self.busy})"
Expand Down
6 changes: 6 additions & 0 deletions runner_manager/models/runner_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class BaseRunnerGroup(PydanticBaseModel):
max: Optional[int] = Field(ge=1, default=20)
min: Optional[int] = Field(ge=0, default=0)
labels: List[str]
job_started_script: Optional[str] = ""
job_completed_script: Optional[str] = ""

backend: Annotated[
Union[BaseBackend, DockerBackend, GCPBackend, AWSBackend, VsphereBackend],
Expand All @@ -62,6 +64,8 @@ class RunnerGroup(BaseModel, BaseRunnerGroup):
queued: int = Field(default=0, ge=0)
os: str = Field(default="linux")
arch: str = Field(default="x64")
job_started_script: Optional[str] = Field(default="")
job_completed_script: Optional[str] = Field(default="")

def __str__(self) -> str:
return (
Expand Down Expand Up @@ -149,6 +153,8 @@ def create_runner(self, github: GitHub) -> Runner | None:
labels=self.runner_labels,
manager=self.manager,
download_url=self.download_url(github),
job_started_script=self.job_started_script,
job_completed_script=self.job_completed_script,
)
runner.save()
runner.generate_jit_config(github)
Expand Down
9 changes: 9 additions & 0 deletions tests/unit/backend/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,12 @@ def test_setup_redhat_credentials(runner, monkeypatch):
template = runner_group.backend.instance_config.template_startup(runner)
assert 'REDHAT_USERNAME="username"' in template
assert 'REDHAT_PASSWORD="password"' in template


def test_job_scripts(runner_group, runner):
runner.job_started_script = 'echo "job started"'
runner.job_completed_script = 'echo "job completed"'
# Ensure that the template is rendered correctly
template = runner_group.backend.instance_config.template_startup(runner)
assert 'echo "job started"' in template
assert 'echo "job completed"' in template
11 changes: 11 additions & 0 deletions tests/unit/models/test_runner_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def test_create_runner_from_group(runner_group: RunnerGroup, github: GitHub):
assert runner.encoded_jit_config is not None
assert runner.created_at is not None
assert runner.created_at.tzinfo == timezone.utc
assert runner.job_started_script == ""
assert runner.job_completed_script == ""


def test_list_runners_from_group(runner_group: RunnerGroup, github: GitHub):
Expand Down Expand Up @@ -163,6 +165,15 @@ def test_runner_group_name():
)


def test_job_scripts(runner_group: RunnerGroup, github: GitHub):
runner_group.job_started_script = "Hello"
runner_group.min = 1
runner_group.save()
runner = runner_group.create_runner(github)
assert runner.job_completed_script == ""
assert runner.job_started_script == runner_group.job_started_script


def test_need_new_runner(runner_group: RunnerGroup, github: GitHub):
runner_group.max = 2
runner_group.min = 1
Expand Down

0 comments on commit 99a4199

Please sign in to comment.