Terminology

The following terms have specific meanings within the job framework:

Job

A job is a set of one or more of the following:

Jobs are defined in manifests.

Manifest

A manifest is a document that contains all of the information about a job. Manifests are written in JSON format.

Here is a simple "hello world" manifest for a job:

{
    "Label": "hello.world",
    "Program": ["/bin/echo", "Hello world!"],
    "StandardOutPath": "/tmp/job.log",
}

When this job runs, it will write the words "Hello world!" to a file named */tmp/job.log*

Method

A job can define custom methods in their manifest . A method is a public API for the job, and can be thought of in similar terms to methods in object-oriented programs.

Here is a simple manifest for a job that runs a daemon and offers a "status" method to display the current status:

{
    "Label": "com.example.my-daemon",
    "Program": "/usr/local/sbin/my-daemon",
    "Methods": {
        "status": ["/bin/echo", "Here is my status output"],
    },
}				
				

This method can be invoked by *jobctl(1)* like this:

# jobctl my-daemon status
				

The effect of running the above command is that the phrase "Here is my status output" will be printed to the standard output.

For more detail about methods, see the [specification](../wiki/Functional-Specification#methods).

Program

The program is the argument vector that is passed to [execve(2)](https://www.freebsd.org/cgi/man.cgi?query=execve&apropos=0&sektion=0&manpath=FreeBSD+10.3-RELEASE&arch=default&format=html) when a job is launched. Jobs may also define methods and hooks that run immediately before or after the program is executed; these are also programs specified in the same way.

Here is an example of how a program is written out in JSON:

["/bin/echo", "Hello world!"]
				
Property

A manifest may contain one or more properties of the job. A property is a simple key/value pair of strings. These properties may be substituted as variables in various places throughout the manifest, and may be retrieved or set by the *jobcfg(1)* command.

Here is an example manifest for a job that exposes a "greeting" property:

{
    "Label": "hello.world",
    "Program": ["/bin/echo", "${greeting}"],
    "Properties": {
         "greeting": "This is the default value",
    },
    "StandardOutPath": "/tmp/hello.log",
}				
				

When this job runs, it will write the words "This is the default value" to a file named */tmp/job.log*

An administrator can override the default value of a property by using the jobcfg. Example:

# jobcfg hello.world set greeting="This is the overridden value"				
				

The next time the job is executed, it will write the words "This is the overridden value" to a file named */tmp/job.log*

Label

A label uniquely identifies each job. Labels are written using reverse domain name notation . The label for each job is specified in the manifest.

Labels should be written in snake-case, to have a consistent style. For example, use 'com.example.nginx_web_server' to describe a job for running the NGINX web server.

For more about labels, see the [specification](../wiki/Functional-Specification#labels).

Execution Context

Jobs are executed when the jobd daemon calls fork(2) to create a child process. This child process eventually becomes the job.

The execution context refers to changes to the child process that take place prior to calling execve(2) to start the program. Examples include:

  • setting environment variables

  • calling setuid(2) and setgid(2)

  • calling chdir(2) to change the working directory

  • calling chroot(2) to change the root directory

  • calling setrlimit(2) to adjust resource limits

  • calling jail_attach(2) to enter a FreeBSD jail

Resource

A resource is a generic term for external things to be acquired on behalf of a job. The resources are owned by the job, and may be automatically destroyed when the job terminates.

Examples include:

  • creating sockets and binding them to ports

  • mounting filesystems

  • creating network interfaces

  • assigning IP addresses to network interfaces

  • installing packages

  • cloning ZFS datasets

  • creating jail(2) jails, chroot(2) jails, or Linux control groups

Resources are acquired at the time when the job is scheduled to run. If the job is transient , its resources will be destroyed when the job terminates; otherwise, the resources will be re-used the next time the job runs. When the job is unloaded, its resources will be destroyed.

Dependency

A dependency is a generic term for things that determine whether or not a job can be executed.

Examples include:

  • the status of other jobs,

  • one or more on-demand conditions,

  • the current system load average,

  • the amount of time the system has been idle,

  • special cases, such as when the computer is starting up or shutting down

Jobs will be executed as soon as all of their dependencies are met.

Scheduler

A job scheduler manages the lifecycle of zero or more jobs. The job lifecycle covers the following steps:

  1. Loading the job into memory, i.e. parsing the manifest

  2. Checking the dependencies to determine when the job can be executed

  3. Acquiring resources when the job is ready to run

  4. Forking a child process and executing the job's program

  5. Waiting for the child process to exit

  6. Restarting the child process automatically, if the manifest requires it

  7. Updating the history of the job to record the exit status

  8. Unloading the job from memory

Depending on the settings in the manifest, jobs may be launched immediately, or on-demand when specific conditions are met.

On-Demand Scheduling

Jobs may be scheduled to run on-demand based on one or more conditions, such as:

  • periodic interval timers

  • calendar scheduling, like cron(8)

  • incoming socket connections

  • files being created within a spool directory

Transient

A job can be designated as transient in its manifest. This has the following effect:

When the program exits, all resources will be automatically destroyed. If the exit code is zero, the job will be automatically be unloaded from the scheduler. Otherwise, if the exit code is non-zero, the job will not be unloaded and remain in the scheduler to alert the administrator that there is a failed job.