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

run user-defined functionality in job_started and job_completed hooks #649

Merged
merged 11 commits into from
Jul 19, 2024
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
Loading