Files
doos/SPEC.md
T

64 lines
2.7 KiB
Markdown

# doos specification
Authoritative description of behavior and limits. Code constants live in `src/spec.hpp`; change both together.
## CLI
| Command | Behavior |
|---|---|
| `doos list` | Table of NAME, STATE (running/stopped), NET, AGE. |
| `doos get_or_create [--net M] NAME` | Creates the container if missing. Prints `created NAME` or `exists NAME`. |
| `doos attach [--net M] NAME [-- CMD...]` | get_or_create, then run CMD (default `/bin/bash`, else `/bin/sh`). Starts the container if stopped, joins it if running. Exit code is the command's. |
| `doos delete [--yes] NAME` | Dry run unless `--yes`. Refuses a running container. |
`get-or-create` is accepted as an alias. Network mode `M` is fixed at creation: `slirp` (default), `host`, `none`.
## Limits (hard caps)
| Item | Cap |
|---|---|
| Containers | 64 |
| Name | `[a-z0-9][a-z0-9_-]{0,31}` |
| Command arguments | 256 |
| Open files inside | 4096 |
| `/tmp`, `/run`, `/dev/shm` | 256m, 64m, 64m (tmpfs) |
| slirp4netns ready wait | 5 s |
| Lock wait | 5 s |
| Delete recursion depth | 256 |
## State layout
`$DOOS_HOME`, else `$XDG_DATA_HOME/doos`, else `~/.local/share/doos`. Path must not contain `,` or `:`.
```
containers/NAME/{meta,pid,lock,rootfs/,layers/<dir>/{upper,work},private/{root,var}}
```
## Container filesystem
| Path | Source |
|---|---|
| `/usr /etc /opt` (and `/bin /sbin /lib /lib32 /lib64` when real dirs) | overlayfs, lower = host dir, upper = `layers/<dir>/upper` |
| `/bin /sbin /lib...` when host symlinks | same symlink recreated |
| `/root /var` | persistent private dirs, no host data |
| `/tmp /run /dev/shm` | tmpfs |
| `/dev` | tmpfs + bound null zero full random urandom tty, new devpts instance |
| `/proc` | own pid namespace; `sys sysrq-trigger irq bus fs` read-only; `kcore keys timer_list` masked |
| `/sys`, `/home`, everything else on host | absent |
## Isolation
User, mount, pid, uts, ipc namespaces always; network namespace unless `host`. Single-entry id map (container root = invoking user). `no_new_privs`, core dumps off. pid 1 is a reaping init that forwards SIGTERM/SIGINT/SIGHUP/SIGQUIT and kills the container when the command exits. Container lifetime = the first `attach` command; later attaches join via setns.
## Networking
- `slirp`: private netns, `slirp4netns --configure --disable-host-loopback`, DNS 10.0.2.3, outbound only, host 127.0.0.1 unreachable.
- `none`: private netns with loopback only.
- `host`: shares the host network namespace (no isolation, explicit opt-in).
## Safety rules
- `delete` is dry-run by default, scoped to `containers/NAME`, refuses running containers, never follows symlinks.
- Invalid names, bad state paths and missing slirp4netns fail loudly.
- A failed start kills the half-built container (no orphans).