doos 0.1.0: user-level overlayfs containers with slirp networking
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user