Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Let a job budget its whole run

e7aa0785cb69ace8c1338cc0b924113ea52a7abb · Keenan Nemetz · 6d ago · parent 2bc0ae74

Let a job budget its whole run

A step was capped at an hour and a job was not capped at all, so a job of
several slow steps held a runner for as long as they took, with no number saying
what the job was allowed to spend. And one long step — a session, a soak test, a
slow suite — could not be expressed, because the only clock was per step and its
ceiling was an hour.

A job may now declare `timeout: 2h`: a wall clock its steps share, starting with
the first step. A step that declares its own timeout is cut short when the budget
ends first, and a step that declares none runs with whatever is left, so one long
step needs only the job's number. A budget spent before a step starts stops the
job there instead of running the step on its own cap.

The budget is optional, pinned with the run, and spent by a local run the same
way, so nothing changes for a workflow that does not declare one. The step
ceiling rises from one hour to four to make a single long step possible; the
default stays ten minutes. The image build is not charged to the budget — it has
its own cap, so a slow pull cannot eat the time the steps were given.

A step timeout longer than its job's budget is refused at push time: the budget
would end first, so the step could never use what it asked for.

Closes #161.

# Conflicts:
#	ci/agent/agent.go
#	cmd/vole/workflowrun.go
#	docs/reference/workflow-reference.md

server/ssh/runner.go +3

@@ -171,6 +171,8 @@ type runnerJob struct {
171 171 // workflow did not say. The runner applies it to the container it starts, so a job
172 172 // that asks for none gets none even on a machine that could provide a bridge.
173 173 Network string `json:"network,omitempty"`
174 // Timeout is the job's budget as a duration string, or empty when it has none.
175 Timeout string `json:"timeout,omitempty"`
174 176 // Image is a registry reference or "file:<name>". For the latter, ImageDefinition
175 177 // is the pinned recipe and ImageSHA is its digest; the runner builds it locally.
176 178 Image string `json:"image"`
@@ -334,6 +336,7 @@ func (s *Server) serveRunner(ch xssh.Channel, user string) {
334 336 Image: run.Image, ImageFile: run.ImageFile, ImageDefinition: run.ImageDefinition,
335 337 ImageSHA: run.ImageSHA,
336 338 Network: run.Network,
339 Timeout: run.Timeout,
337 340 Env: run.Env,
338 341 Secrets: secrets, Missing: missing,
339 342 Tag: run.Tag, TagAnnotated: run.TagAnnotated, ReleaseArtifacts: run.ReleaseArtifacts,