Add a man page, built optionally via scdoc
docs/slocker-lite.1.scd covers the full CLI (grouped like README.md's flag table, including the DEBUGGING section for --mount/--umount/ --cleanup and the reassigned-short-option note), FILES, EXIT STATUS, and SEE ALSO. meson.build builds it into slocker-lite.1 and installs it under man1 only when scdoc is found on the host -- configuration still succeeds without it, matching this project's existing "degrade gracefully when an optional tool is missing" policy. Verified the rendered page with `man --warnings` (clean, no troff warnings) and a DESTDIR install. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
slocker-lite(1)
|
||||
|
||||
# NAME
|
||||
|
||||
slocker-lite - mount and sandbox OCI images without podman, docker, or kernel overlayfs
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
*slocker-lite* -r|--run _image.tar_ [_options_]... [-- _command_ [_args_...]]
|
||||
|
||||
*slocker-lite* -x|--exec _pid_ [-- _command_ [_args_...]]
|
||||
|
||||
*slocker-lite* --kill _pid_
|
||||
|
||||
*slocker-lite* -l|--list-images _directory_
|
||||
|
||||
*slocker-lite* -i|--inspect _image.tar_
|
||||
|
||||
*slocker-lite* -v|--volume _name_ _directory_
|
||||
|
||||
*slocker-lite* --list-volumes
|
||||
|
||||
*slocker-lite* --delete-volume|--delete-volume-full _name_
|
||||
|
||||
*slocker-lite* -n|--network _name_ (--extern|--intern) [_network-options_]...
|
||||
|
||||
*slocker-lite* --list-networks
|
||||
|
||||
*slocker-lite* --delete-network|--delete-network-full _name_
|
||||
|
||||
*slocker-lite* --list-processes
|
||||
|
||||
*slocker-lite* --clean-processes
|
||||
|
||||
*slocker-lite* [-c|--config-file _path_] -w|--write-config
|
||||
|
||||
*slocker-lite* -t|--test [-- _catch-options_]
|
||||
|
||||
*slocker-lite* -u|--up _images-dir_ [_compose-file_]
|
||||
|
||||
*slocker-lite* -d|--down [_compose-file_]
|
||||
|
||||
*slocker-lite* --list-containers
|
||||
|
||||
*slocker-lite* -h|--help
|
||||
|
||||
*slocker-lite* -V|--version
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
*slocker-lite* mounts an OCI Image Layout tar (the format produced by
|
||||
*skopeo*(1), *podman-save*(1) with _--format oci-archive_, or a modern
|
||||
*docker-save*(1)) and runs a sandboxed command against it, without needing
|
||||
*podman*, *docker*, or a kernel that supports overlayfs.
|
||||
|
||||
It targets Android with a stock kernel: neither *podman* nor *docker* run
|
||||
there (missing namespace support), and there is no kernel overlayfs. Image
|
||||
layers are imported into *containers-storage*(1) and mounted with
|
||||
*fuse-overlayfs*(1) (userspace, no kernel overlayfs needed), then the
|
||||
requested command is sandboxed with *bwrap*(1) in "degraded mode" - using
|
||||
only whichever _--unshare-xxx_ namespaces the running kernel actually
|
||||
supports, instead of requiring the full set.
|
||||
|
||||
# OPTIONS
|
||||
|
||||
## RUNNING CONTAINERS
|
||||
|
||||
*-r*, *--run* _image.tar_
|
||||
Mount, run *bwrap*(1) in the foreground, then unmount and clean up on
|
||||
exit. Defaults to the image's own Entrypoint/Cmd (or _/bin/sh_ if
|
||||
neither is set); pass _-- command [args...]_ to override.
|
||||
|
||||
*--no-nsenter*
|
||||
With *--run*, bind the mount directly instead of *nsenter*(1)-ing
|
||||
into *fuse-overlayfs*'s namespace. Automatic when running as root;
|
||||
use this to force it off otherwise.
|
||||
|
||||
*-D*, *--daemonize*
|
||||
With *--run*, fork into the background: detaches from the
|
||||
controlling terminal, ignores SIGHUP, and redirects stdin from
|
||||
_/dev/null_ and stdout/stderr to a log file under
|
||||
_$XDG_STATE_HOME/slocker-lite/logs/_. Prints the session's pid and
|
||||
log path, then returns.
|
||||
|
||||
*--user* _user_
|
||||
With *--run*, run the command as this user (name or numeric uid)
|
||||
instead of the image's own declared user (or root, if it declares
|
||||
none). Resolved against the image's own _/etc/passwd_. Only takes
|
||||
effect when *--run* executes as root.
|
||||
|
||||
*--group* _group_
|
||||
With *--user*, use this group (name or numeric gid) instead of the
|
||||
user's primary group.
|
||||
|
||||
*--hostname* _name_
|
||||
With *--run*, set the sandbox's hostname. Only takes effect if the
|
||||
running kernel supports _--unshare-uts_; ignored with a warning
|
||||
otherwise.
|
||||
|
||||
*--env* _VAR=VALUE_
|
||||
With *--run*, set an environment variable in the sandbox (overrides
|
||||
the default PATH/HOME/PWD/TERM if given the same name). Repeatable;
|
||||
combined with *--env-file* in command-line order, each later one
|
||||
winning over an earlier one for the same name.
|
||||
|
||||
*--env-file* _file_
|
||||
With *--run*, load environment variables from _file_ - one
|
||||
_VAR=VALUE_ per line; blank lines and _#_-comments are skipped.
|
||||
Repeatable.
|
||||
|
||||
*-v*, *--volume* _name-or-dir_ _container-path_
|
||||
With *--run*, mount a volume into the sandbox (repeatable): the
|
||||
first argument is an existing named volume, or, if it contains _/_,
|
||||
a host directory path (created if missing); the second is the
|
||||
absolute path inside the container to mount it at.
|
||||
|
||||
*-n*, *--network* _name_
|
||||
With *--run*, join _name_ to the container as its own _ethN_
|
||||
interface with an address from the network's subnet. Repeatable, no
|
||||
membership limit.
|
||||
|
||||
*-p*, *--port-forward* [_network_:]_host-port_:_container-port_[/tcp|udp]
|
||||
With *--run*, forward a port from the host into the container - TCP
|
||||
by default, or UDP with an explicit _/udp_ suffix. _network_ is
|
||||
optional, defaulting to the container's sole *--extern* network (an
|
||||
error if it joined more than one without specifying). Repeatable,
|
||||
including the same port pair once per protocol. Reachable via the
|
||||
host's real, externally-facing IP; _localhost_/loopback access has a
|
||||
known NAT-hairpinning limitation, for both protocols.
|
||||
|
||||
*--no-dns*
|
||||
With *--run*, skip starting the per-session *dnsmasq*(8) resolver
|
||||
even if it is available. Has no effect if no *-n*/*--network* was
|
||||
given, or if *dnsmasq* is not installed.
|
||||
|
||||
*-x*, *--exec* _pid_
|
||||
Join an already-running *--run* session (_pid_ must be one
|
||||
*--list-processes* shows as running) and run a command inside its
|
||||
container. Pass _-- command [args...]_ to specify it.
|
||||
|
||||
*--kill* _pid_
|
||||
Stop a running *--run* session (_pid_ must be one *--list-processes*
|
||||
shows as running): sends SIGTERM, waits up to 10 seconds, then
|
||||
forces it with SIGKILL. Reaches every process the session started,
|
||||
including daemonized/reparented ones a plain _kill pid_ would leave
|
||||
behind, via a dedicated cgroup when available, or the sandboxed pid
|
||||
namespace's own collapse-on-kill guarantee when not, falling back to
|
||||
signaling the tracked pid alone if neither applies.
|
||||
|
||||
*--list-processes*
|
||||
List running *--run* sessions found by their pid files under
|
||||
_$XDG_STATE_HOME/slocker-lite/run/_, with their pid, container name,
|
||||
and status (running or exited).
|
||||
|
||||
*--clean-processes*
|
||||
Remove stale pid files (see *--list-processes*), and any
|
||||
*-p*/*--port-forward* iptables rules or *-n*/*--network*
|
||||
tap-relay/DNS-resolver processes, left behind by sessions that are
|
||||
no longer running (e.g. after a crash).
|
||||
|
||||
## IMAGES
|
||||
|
||||
*-l*, *--list-images* _directory_
|
||||
List OCI Image Layout tars (\*.tar, \*.tar.\*) found directly in
|
||||
_directory_, with their name:tag.
|
||||
|
||||
*-i*, *--inspect* _image.tar_
|
||||
Print an image's declared user, exposed ports, env, volumes, and
|
||||
default command, without mounting or running it.
|
||||
|
||||
## VOLUMES
|
||||
|
||||
*-v*, *--volume* _name_ _directory_
|
||||
Create a named volume mapped to a host directory (created if
|
||||
missing), recorded in the config file's _volumes_ section. Fails if
|
||||
the name or directory is already used by an existing volume. Volume
|
||||
names cannot contain _/_. (See RUNNING CONTAINERS above for combined
|
||||
use with *--run*.)
|
||||
|
||||
*--list-volumes*
|
||||
List all named volumes with their host directory.
|
||||
|
||||
*--delete-volume* _name_
|
||||
Remove a named volume from the config. The host directory is left
|
||||
untouched.
|
||||
|
||||
*--delete-volume-full* _name_
|
||||
Like *--delete-volume*, but also recursively deletes the volume's
|
||||
host directory.
|
||||
|
||||
## NETWORKS
|
||||
|
||||
*-n*, *--network* _name_ (*--extern*|*--intern*)
|
||||
Create a persistent named network: *--extern* is a bridge in its
|
||||
own dedicated namespace, with an uplink out to the host's real
|
||||
network so containers reach it via IPv4 NAT/forwarding; *--intern*
|
||||
is a bridge inside its own dedicated, routeless namespace, only
|
||||
reachable by other containers on the same network. Root-only. (See
|
||||
RUNNING CONTAINERS above for combined use with *--run*.)
|
||||
|
||||
*--subnet* _cidr_
|
||||
With network creation, override the auto-allocated IPv4 range.
|
||||
|
||||
*--with-ipv6*=_bool_
|
||||
With network creation, enable/disable the auto-allocated IPv6 range.
|
||||
Defaults to the config file's own _global.with-ipv6_.
|
||||
|
||||
*--subnet6* _cidr_
|
||||
With network creation and IPv6 enabled, override the auto-allocated
|
||||
IPv6 range.
|
||||
|
||||
*--with-veth*=_bool_
|
||||
With network creation, _false_ forces the tap+relay join fallback
|
||||
even on a kernel that supports veth (useful for testing that path;
|
||||
otherwise chosen automatically whenever the running kernel lacks
|
||||
veth support). Defaults to the config file's own _global.with-veth_.
|
||||
|
||||
*--list-networks*
|
||||
List all named networks with their kind, IPv4 subnet, bridge name,
|
||||
and IPv6 subnet.
|
||||
|
||||
*--delete-network* _name_
|
||||
Remove a named network from the config. Its live
|
||||
bridge/namespace/iptables state is left untouched.
|
||||
|
||||
*--delete-network-full* _name_
|
||||
Like *--delete-network*, but also tears down its live state, so a
|
||||
network with the same name can be created fresh afterward.
|
||||
|
||||
## CONFIGURATION
|
||||
|
||||
*-c*, *--config-file* _path_
|
||||
Use _path_ instead of the default _config.yaml_ for the *global*
|
||||
section only (log-level, unshare-\*, with-veth, with-ipv6) -
|
||||
volumes/networks always come from the separate, always-fixed
|
||||
_persistent.yaml_. Errors if _path_ does not exist. Combine with
|
||||
*-w* to bootstrap a config file at a custom location. Always
|
||||
available, regardless of command.
|
||||
|
||||
*-w*, *--write-config*
|
||||
Write a complete global config file (creating it, and its parent
|
||||
directory, if missing), filling in every global option's current or
|
||||
default value. Never touches volumes/networks. Prints the file's
|
||||
full path.
|
||||
|
||||
## TESTING
|
||||
|
||||
*-t*, *--test* [-- _catch-options_]
|
||||
Run the built-in Catch2 test suite. A bare *-t* runs everything
|
||||
Catch2 finds; select a category with a tag expression after a
|
||||
literal _--_ (needed since Catch2's own *-r*/*--reporter* would
|
||||
otherwise collide with *slocker-lite*'s own *-r*/*--run*).
|
||||
|
||||
## COMPOSE
|
||||
|
||||
*-u*, *--up* _images-dir_ [_compose-file_]
|
||||
Start a docker-compose.yaml-subset project: mount every service's
|
||||
image (from the OCI tars in _images-dir_), provision its declared
|
||||
networks/volumes, then start each service's container in dependency
|
||||
order, daemonized. _compose-file_ defaults to _compose.yaml_ in the
|
||||
current directory. Root-only if the compose file declares any
|
||||
networks.
|
||||
|
||||
*-d*, *--down* [_compose-file_]
|
||||
Stop every container a matching *--up* run started and tear down
|
||||
any networks it created that are no longer in use by anything else;
|
||||
named volumes are always left in place. _compose-file_ defaults the
|
||||
same way as *--up*.
|
||||
|
||||
*--list-containers*
|
||||
List containers started by *--up*, with their compose file, service
|
||||
name, container name, pid, and status.
|
||||
|
||||
## OTHER
|
||||
|
||||
*--log-level* _level_
|
||||
Set log verbosity: trace, debug, info, warn, error, critical, off.
|
||||
|
||||
*-h*, *--help*
|
||||
Print usage and exit.
|
||||
|
||||
*-V*, *--version*
|
||||
Print version information and exit.
|
||||
|
||||
## DEBUGGING
|
||||
|
||||
These three commands bypass *--run*'s own mount/sandbox/cleanup lifecycle and
|
||||
exist mainly for troubleshooting; they are long-option only. Earlier versions
|
||||
used *-m*, *-u*, and *-c* as short forms for these; those letters have since
|
||||
been reassigned (*-u* to *--up*, *-c* to *--config-file*) since compose
|
||||
orchestration and per-invocation config overrides are both far more commonly
|
||||
used.
|
||||
|
||||
*--mount* _image.tar_
|
||||
Validate and mount an OCI Image Layout tar. See *-r*/*--run* and
|
||||
*-x*/*--exec* above for the normal way to actually use an image.
|
||||
|
||||
*--umount* _layer-id_
|
||||
Unmount a previously mounted layer (the ID printed by
|
||||
*--mount*/*--run*, or from _containers-storage layers_).
|
||||
*-r*/*--run* already unmounts on its own when done.
|
||||
|
||||
*--cleanup* _layer-id_
|
||||
Delete a layer and its ancestor chain from local storage (unmount
|
||||
it first).
|
||||
|
||||
# FILES
|
||||
|
||||
_$XDG_CONFIG_HOME/slocker-lite/config.yaml_ (falling back to
|
||||
_$HOME/.config/slocker-lite/config.yaml_)
|
||||
The *global* section only: log verbosity, bwrap namespace policy,
|
||||
network-creation defaults. What *-c*/*--config-file* can point
|
||||
elsewhere for a single invocation.
|
||||
|
||||
_$XDG_CONFIG_HOME/slocker-lite/persistent.yaml_
|
||||
The _volumes_ and _networks_ sections: real, provisioned host state.
|
||||
Always this one fixed file - *-c*/*--config-file* never affects it.
|
||||
|
||||
_$XDG_STATE_HOME/slocker-lite/run/_
|
||||
Locked pid files for active *--run* sessions (falls back to
|
||||
_$HOME/.local/state/slocker-lite/_).
|
||||
|
||||
_$XDG_STATE_HOME/slocker-lite/logs/_
|
||||
Log files for *-D*/*--daemonize* sessions.
|
||||
|
||||
_$XDG_STATE_HOME/slocker-lite/compose/_
|
||||
State files mapping a compose file to the pids *--up* started, used
|
||||
by *--down* and *--list-containers*.
|
||||
|
||||
# EXIT STATUS
|
||||
|
||||
*0*
|
||||
Success.
|
||||
|
||||
*1*
|
||||
An error occurred (invalid arguments, a failed mount/run, etc.).
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
*bwrap*(1), *containers-storage*(1), *fuse-overlayfs*(1), *nsenter*(1)
|
||||
|
||||
The project's README.md and docs/networking-design.md, installed alongside
|
||||
the source, cover the full architecture and the networking design in more
|
||||
detail than fits here.
|
||||
|
||||
# AUTHOR
|
||||
|
||||
Written by Viorel Munteanu. Licensed GPL-2.0-or-later.
|
||||
Reference in New Issue
Block a user