Job Specification Fields
This chapter specifies all of the possible fields for a job specification. Most, but not all, of these fields have an obvious mapping to job-spec fields.
image
This field must be an object as described below. It specifies the
image
field of the job spec.
The field can either be a string or an object. If it's a string, then it specifies the URI of the image to use, as documented here.
If it's an object, then it must have a string name
field and it may have an
optional use
field. The name
field specifies the URI of the image to use,
as documented here.
The use
fields must be a list of strings specifying what parts of the
container image to use for the job spec. It must contain a non-empty subset of:
layers
: This sets theuse_layers
field in the job spec's image value. This is incompatible with thelayers
field: useadded_layers
instead.environment
: This sets theuse_environment
field in the job spec's image value. This is incompatible with theenvironment
field specified using implicit mode: use explicit mode instead.working_directory
: This sets theuse_working_directory
field in the job spec's image value. This is incompatible with theworking_directory
field.
If no use
field is provided, or if the first form is used where only a URI is
specified, then the image will use the layers and environment from the image.
For example, the following three are identical job specifications:
{
"image": {
"name": "docker://ubuntu",
"use": [ "layers", "environment" ]
},
"program": "echo",
"arguments": [ "hello", "world" ]
}
{
"image": { "name": "docker://ubuntu" },
"program": "echo",
"arguments": [ "hello", "world" ]
}
{
"image": "docker://ubuntu",
"program": "echo",
"arguments": [ "hello", "world" ]
}
program
This field must be a string, and it specifies the program to be run. It sets
the program
field of the job spec. It must be provided.
arguments
This field must be a list of strings, and it specifies the program's arguments.
It sets the arguments
field of the job spec. If not
provided, the job spec will have an empty arguments vector.
environment
This field sets the environment
field of the job
spec. If not provided, the job spec will have an empty environment vectors.
This field can be specified in one of two ways: implicit mode and explicit mode.
Implicit Mode
In this mode, a JSON map from string to string is expected. The job spec will have a single element in it, with the provided map. This is usually what you want.
% BAR=bar maelstrom-run --one
{
"image": {
"name": "docker://ubuntu",
"use": [ "layers" ]
},
"program": "/usr/bin/env",
"environment": {
"FOO": "foo",
"BAR": "$env{BAR}"
}
}
BAR=bar
FOO=foo
%
This mode is incompatible with a use
of environment
in the image
. It's
ambiguous whether the desired environment is the one provided with environment
or the
one from the image:
% maelstrom-run --one
{
"image": {
"name": "docker://ubuntu",
"use": [ "layers", "environment" ]
},
"program": "/usr/bin/env",
"environment": {
"FOO": "foo",
"BAR": "bar"
}
}
Error: field `environment` must provide `extend` flags if [`image` with a `use`
of `environment`](#image-use-environment) is also set at line 11 column 1
%
Explicit Mode
In this mode, a list of EnvironmentSpec
is
provided, and they are used verbatim in the job spec.
For example:
% BAR=bar maelstrom-run --one
{
"image": {
"name": "docker://ubuntu",
"use": [ "layers", "environment" ]
},
"program": "/usr/bin/env",
"environment": [
{ "vars": { "PATH": "$prev{PATH}", "FOO": "foo" }, "extend": false },
{ "vars": { "BAR": "$env{BAR}" }, "extend": true }
]
}
BAR=bar
FOO=foo
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
%
layers
This field sets the layers
field of the job
spec. Either this field, or an image
with a use
of layers
must be
provided, but not both.
To add additional layers beyond those provided by an image, use
added_layers
.
Here is an example of specifying layers:
% wget -O busybox https://busybox.net/downloads/binaries/1.35.0-x86_64-linux-musl/busybox
...
% chmod +x ./busybox
% maelstrom-run --one
{
"layers": [
{ "paths": [ "busybox" ] },
{ "symlinks": [{ "link": "/ls", "target": "/busybox" }] }
],
"program": "/ls"
}
busybox
ls
%
added_layers
This is just like layers
, except is can only be used with an
image
that has a use
of layers
. The provided layers
will be append to the layers provided by the image when creating the job spec.
Here's an example:
% maelstrom-run --one
{
"image": "docker://ubuntu",
"added_layers": [
{ "stubs": [ "/foo/{bar,baz}" ] }
],
"program": "/bin/ls",
"arguments": [ "/foo" ]
}
bar
baz
%
mounts
This field sets the mounts
field of the job spec.
If this field isn't specified, an empty mounts
will be set in the job spec.
The field must be a list of objects, where the format is the direct JSON translation of the corresponding job-spec type.
For example:
% maelstrom-run
{
"image": "docker://ubuntu",
"added_layers": [
{ "stubs": [ "/dev/{null,zero}" ] }
],
"mounts": [
{ "type": "proc", "mount_point": "/proc" },
{ "type": "tmp", "mount_point": "/tmp" },
{ "type": "devices", "devices": [ "null", "zero" ] }
],
"program": "mount"
}
Maelstrom LayerFS on / type fuse (ro,nosuid,nodev,relatime,user_id=0,group_id=0)
none on /proc type proc (rw,relatime)
none on /tmp type tmpfs (rw,relatime,uid=1000,gid=1000,inode64)
udev on /dev/null type devtmpfs (rw,nosuid,relatime,size=8087700k,nr_inodes=2021925,mode=755,inode64)
udev on /dev/zero type devtmpfs (rw,nosuid,relatime,size=8087700k,nr_inodes=2021925,mode=755,inode64)
%
Bind mounts can be used to transfer data out of the job:
% touch output
% cat output
% maelstrom-run --one
{
"image": "docker://ubuntu",
"added_layers": [
{ "stubs": [ "/output" ] }
],
"mounts": [
{
"type": "bind",
"mount_point": "/output",
"local_path": "output",
"read_only": false
}
],
"program": "bash",
"arguments": [ "-c", "echo foo >output" ]
}
% cat output
foo
%
network
This field must be a string with a value of one: "disabled"
, "loopback"
,
"local"
. It sets the network
field of the job spec to
the provided value. If this field isn't provided, the default of "disabled"
is used.
enable_writable_file_system
This field must be a boolean value. If it's true
, it sets the
root_overlay
field of the job spec to Tmp
. If
it's not specified, or is set to false
, the [root_overlay
] field will be
None
.
working_directory
This field must be a string, and it specifies the working directory of the
program be run. It sets the working_directory
field of the job spec. If not provided, /
will be used.
This field is incompatible with an image
that has a use
of
working_directory
.
For example:
% maelstrom-run --one
{
"image": "docker://ubuntu",
"program": "pwd"
}
/
% maelstrom-run --one
{
"image": "docker://ubuntu",
"program": "pwd",
"working_directory": "/root"
}
/root
%
user
This field must be an integer, and it specifies the UID of the program to be run.
It sets the user
field of the job spec. If not provided,
0
will be used.
For example:
% maelstrom-run --one
{
"image": "docker://ubuntu",
"program": "id"
}
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
% maelstrom-run --one
{
"image": "docker://ubuntu",
"program": "id",
"user": 1234
}
uid=1234 gid=0(root) groups=0(root),65534(nogroup)
%
group
This field must be an integer, and it specifies the UID of the program to be
run. It sets the group
field of the job spec. If not
provided, 0
will be used.
For example:
% maelstrom-run --one
{
"image": "docker://ubuntu",
"program": "id"
}
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
% maelstrom-run --one
{
"image": "docker://ubuntu",
"program": "id",
"group": 4321
}
uid=0(root) gid=4321 groups=4321,65534(nogroup)
%
timeout
This field must be an integers, and it specifies a timeout for the job in
seconds. It sets the timeout
field of the job spec. If
not provided, the job will have no timeout.
For example:
% maelstrom-run --one
{
"image": "docker://ubuntu",
"program": "sleep",
"arguments": [ "1d" ],
"timeout": 1
}
timed out
%