diff --git a/Makefile b/Makefile index a35e2fac1..f6091e654 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,7 @@ DOC_FILES := \ bundle.md \ runtime.md \ runtime-linux.md \ + command-line-interface.md \ config.md \ config-linux.md \ config-solaris.md \ diff --git a/README.md b/README.md index 21bac043e..b5216c5e8 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Table of Contents - Runtime and Lifecycle - [General Runtime and Lifecycle](runtime.md) - [Linux-specific Runtime and Lifecycle](runtime-linux.md) + - [Runtime Command Line Interface](command-line-interface.md) - Configuration - [General Configuration](config.md) - [Linux-specific Configuration](config-linux.md) diff --git a/command-line-interface.md b/command-line-interface.md new file mode 100644 index 000000000..10cfaf76c --- /dev/null +++ b/command-line-interface.md @@ -0,0 +1,189 @@ +# Operations + +A conformant [runtime][] MUST provide an executable (called `funC` in the following examples). +That executable MUST support commands with the following template: + +```sh +$ funC [global-options] [command-specific-options] +``` + +## Global options + +None are required, but the runtime MAY support options that start with at least one hyphen. +Global options MAY take positional arguments (e.g. `--log-level debug`). +Command names MUST NOT start with hyphens. +The option parsing MUST be such that `funC ` is unambiguously an invocation of `` (even for commands not specified in this document). +If the runtime is invoked with an unrecognized command, it MUST exit with a nonzero exit code and MAY log a warning to stderr. +Beyond the above rules, the behavior of the runtime in the presence of commands and options not specified in this document is unspecified. + +## Character encodings + +This API specification does not cover character encodings, but runtimes SHOULD conform to their native operating system. +For example, POSIX systems define [`LANG` and related environment variables][posix-lang] for [declaring][posix-locale-encoding] [locale-specific character encodings][posix-encoding], so a runtime in an `en_US.UTF-8` locale SHOULD write its [state](#state) to stdout in [UTF-8][]. + +## Commands + +### create + +[Create][create] a container from a [bundle directory][bundle]. + +* *Arguments* + * *``* Set the container ID to create. +* *Options* + * *`--bundle `* Override the path to the [bundle directory][bundle] (defaults to the current working directory). + * *`--pid-file `* The runtime MUST write the container PID to this path. +* *Standard streams:* + * *stdin:* The runtime MUST attach its stdin directly to the container process without reading from it. + * *stdout:* The runtime MUST attach its stdout directly to the container process without writing to it. + * *stderr:* The runtime MUST attach its stderr to the container process, and MUST not write to it unless it exits with a non-zero code. +* *Environment variables* + * *`LISTEN_FDS`:* The number of file descriptors passed. + For example, `LISTEN_FDS=2` would mean that the runtime MUST pass file descriptors 3 and 4 to the container process (in addition to the standard streams) to support [socket activation][systemd-listen-fds]. +* *Exit code:* Zero if the container was successfully created and non-zero on errors. + +Callers MAY block on this command's successful exit to trigger post-create activity. + +#### Example + +``` +# in a bundle directory with a process that echos "hello" and exits 42 +$ test -t 1 && echo 'stdout is a terminal' +stdout is a terminal +$ funC create hello-1 +$ echo $? +0 +$ funC start hello-1 +hello +$ echo $? +0 +$ block-on-exit-and-collect-exit-code hello-1 +$ echo $? +42 +$ funC delete hello-1 +$ echo $? +0 +``` + +`hello` shows up in the terminal after `start`, because `start` happens to be called from the same shell session (using the same terminal) as `create`, and the container process inherited its standard streams from `create`. +If you call `start` from a shell using a separate terminal, the container output would still have appeared in the `create` terminal. + +#### Container process exit + +The [example's](#example) `block-on-exit-and-collect-exit-code` is platform-specific magic that is not specified in this document. +On Linux, it might involve an ancestor process which had set [`PR_SET_CHILD_SUBREAPER`][prctl.2] and collected the container PID [from the state][state], or a process that was [ptracing][ptrace.2] the container process for [`exit_group`][exit_group.2], although both of those race against the container process exiting before the watcher is monitoring. + +### start + +[Start][start] the user-specified code from [`process`][process]. + +* *Arguments* + * *``* Set the container ID to start. +* *Standard streams:* + * *stdin:* The runtime MUST NOT attempt to read from its stdin. + * *stdout:* The handling of stdout is unspecified. + * *stderr:* The runtime MAY print diagnostic messages to stderr, and the format for those lines is not specified in this document. +* *Exit code:* Zero if the container was successfully started and non-zero on errors. + +Callers MAY block on this command's successful exit to trigger post-start activity. + +See [create](#example) for an example. + +### state + +[Request][state-request] the container [state][state]. + +* *Arguments* + * *``* The container whose state is being requested. +* *Standard streams:* + * *stdin:* The runtime MUST NOT attempt to read from its stdin. + * *stdout:* The runtime MUST print the [state JSON][state] to its stdout. + * *stderr:* The runtime MAY print diagnostic messages to stderr, and the format for those lines is not specified in this document. +* *Exit code:* Zero if the state was successfully written to stdout and non-zero on errors. + +#### Example + +``` +# in a bundle directory with a process that sleeps for several seconds +$ funC start --id sleeper-1 & +$ funC state sleeper-1 +{ + "ociVersion": "1.0.0-rc1", + "id": "sleeper-1", + "status": "running", + "pid": 4422, + "bundlePath": "/containers/sleeper", + "annotations" { + "myKey": "myValue" + } +} +$ echo $? +0 +``` + +### kill + +[Send a signal][kill] to the container process. + +* *Arguments* + * *``* The container being signaled. +* *Options* + * *`--signal `* The signal to send (defaults to `TERM`). + The runtime MUST support `TERM` and `KILL` signals with [the POSIX semantics][posix-signals]. + The runtime MAY support additional signal names. + On platforms that support [POSIX signals][posix-signals], the runtime MUST implement this command using POSIX signals. + On platforms that do not support POSIX signals, the runtime MAY implement this command with alternative technology as long as `TERM` and `KILL` retain their POSIX semantics. + Runtime authors on non-POSIX platforms SHOULD submit documentation for their TERM implementation to this specificiation, so runtime callers can configure the container process to gracefully handle the signals. +* *Standard streams:* + * *stdin:* The runtime MUST NOT attempt to read from its stdin. + * *stdout:* The runtime MAY print diagnostic messaged to stdout, and the format for those lines is not specified in this document. + * *stderr:* The runtime MAY print diagnostic messages to stderr, and the format for those lines is not specified in this document. +* *Exit code:* Zero if the signal was successfully sent to the container process and non-zero on errors. + Successfully sent does not mean that the signal was successfully received or handled by the container process. + +#### Example + +``` +# in a bundle directory with a process ignores TERM +$ funC start --id sleeper-1 & +$ funC kill sleeper-1 +$ echo $? +0 +$ funC kill --signal KILL sleeper-1 +$ echo $? +0 +``` + +### delete + +[Release](#delete) container resources after the container process has exited. + +* *Arguments* + * *``* Set the container ID to delete. +* *Standard streams:* + * *stdin:* The runtime MUST NOT attempt to read from its stdin. + * *stdout:* The handling of stdout is unspecified. + * *stderr:* The runtime MAY print diagnostic messages to stderr, and the format for those lines is not specified in this document. +* *Exit code:* Zero if the container was successfully deleted and non-zero on errors. + +See [create](#example) for an example. + +[bundle]: bundle.md +[create]: runtime.md#create +[delete]: runtime.md#delete +[exit_group.2]: http://man7.org/linux/man-pages/man2/exit_group.2.html +[kill]: runtime.md#kill +[kill.2]: http://man7.org/linux/man-pages/man2/kill.2.html +[process]: config.md#process-configuration +[posix-encoding]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap06.html#tag_06_02 +[posix-lang]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_02 +[posix-locale-encoding]: http://www.unicode.org/reports/tr35/#Bundle_vs_Item_Lookup +[posix-signals]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html#tag_13_42_03 +[prctl.2]: http://man7.org/linux/man-pages/man2/prctl.2.html +[ptrace.2]: http://man7.org/linux/man-pages/man2/ptrace.2.html +[runtime]: glossary.md#runtime +[standard-streams]: https://github.com/opencontainers/specs/blob/v0.1.1/runtime-linux.md#file-descriptors +[start]: runtime.md#start +[state]: runtime.md#state +[state-request]: runtime.md#query-state +[systemd-listen-fds]: http://www.freedesktop.org/software/systemd/man/sd_listen_fds.html +[UTF-8]: http://www.unicode.org/versions/Unicode8.0.0/ch03.pdf diff --git a/runtime-linux.md b/runtime-linux.md index 388df30a7..e4ba33e35 100644 --- a/runtime-linux.md +++ b/runtime-linux.md @@ -1,11 +1,5 @@ # Linux Runtime -## File descriptors - -By default, only the `stdin`, `stdout` and `stderr` file descriptors are kept open for the application by the runtime. -The runtime MAY pass additional file descriptors to the application to support features such as [socket activation](http://0pointer.de/blog/projects/socket-activated-containers.html). -Some of the file descriptors MAY be redirected to `/dev/null` even though they are open. - ## Dev symbolic links After the container has `/proc` mounted, the following standard symlinks MUST be setup within `/dev/` for the io.