Skip to content
SHC Docs

Job module

Source: modules/job/.

CLIshc job
Subcommands6
HTTP endpointssee the route reference
Events emittedsee the event reference
Error codessee the error code reference
Service classesJobLoader, JobExecutor, JobService
Cross-module depsapp, network, node, stack
modules/job/
├── command.go
├── errors.go
├── events.go
├── models.go
├── registration.go
├── router.go
├── service.go
├── tasks.go
├── types.go
├── utils.go
├── commands/
└── contexts/

Routes are listed in the generated route reference; request/response notes live in the API reference.

Typed errors are catalogued in the error code reference with HTTP statuses and message templates.

The job module owns user-defined jobs — short-lived, named operations that an app exposes alongside its stack. Jobs live in *.job.yaml files inside an app directory and can be invoked manually (shc job run), on a cron (shc schedule add), or from lifecycle hooks (pre_install, post_install, etc.).

The module has three collaborating types in service.go:

  • JobLoader — reads *.job.yaml files from a stack’s app directory and parses them into JobDefinition Go structs. One JobLoader per (tenant, stack, environment). Errors: X400010INVJOB, X400011JOBMNG, X404001JOBNFD.
  • JobExecutor — takes a JobDefinition, resolves secrets via ref+vault://... references (vars.ResolveSecretReferences), renders the job’s templated command with Go templating (sharing filters with the app template machinery), dispatches to the correct context executor (container, host, remote, etc. — see contexts/), and returns a structured result.
  • JobService — the public API. Lists, runs, and tracks jobs through JobModel / JobRunModel tables. Each invocation creates a JobRunModel row with status, start/end time, stdout/stderr, and the POSIX exit code.

What the job module does not own: scheduling (that is schedule, which inserts rows into ScheduleModel that reference a job by name), queueing for async execution (that is the task module), or the shell/container primitives themselves (those live in the per-context executors, modules/job/context_*.go).

A job run’s lifecycle: JobService.run → creates JobRunModel → delegates to JobExecutor.execute → dispatches to a context executor → captures exit/stdout → updates the run row → emits audit event.