Documentation
¶
Overview ¶
Package sandbox runs a real binary inside a given rootfs using Linux namespaces + pivot_root, implemented directly on golang.org/x/sys/unix (no libcontainer / runc dependency).
Topology recap: the agent itself lives in the control-root and is NOT affected by rollback. Each command the agent runs becomes a child here, with the inner-env subvolume as its root. The child is PID 1 of a fresh PID namespace, so killing it (see repo.killAll on checkout) tears down the whole inner-env process tree.
Networking: we deliberately do NOT create a new network namespace, so the child shares the host network and `apt install` can reach the internet. The host's /etc/resolv.conf is bind-mounted in for DNS.
Index ¶
- func Child()
- func IsChild() bool
- func Run(rootfs string, args, env []string, stdin io.Reader, stdout, stderr io.Writer) error
- func RunPTY(rootfs string, args, env []string, rootless bool) (int, error)
- func RunRootless(rootfs string, args, env []string, stdin io.Reader, stdout, stderr io.Writer) error
- func Start(rootfs string, args, env []string, out io.Writer) (*exec.Cmd, error)
- func StartRootless(rootfs string, args, env []string, out io.Writer) (*exec.Cmd, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Child ¶
func Child()
Child is the entry point for the re-executed process. It sets up the inner-env root and execs the target command. It never returns on success.
func IsChild ¶
func IsChild() bool
IsChild reports whether the current process was re-executed as the namespaced child (i.e. os.Args == [exe, "__child", rootfs, cmd...]).
func RunPTY ¶
RunPTY runs an interactive command inside rootfs on a pseudo-terminal that's wired to the caller's terminal (raw mode + window-size propagation). rootless adds a user namespace so a non-root caller can do it. Returns the exit code.
When stdin is not a terminal (e.g. piped), the call falls back to a plain non-PTY run with the same plumbing — the caller still gets stdout/stderr.
Previously this file hand-rolled /dev/ptmx / TIOCSPTLCK / TIOCGPTN / /dev/pts path-joining / termios raw-mode bit flips / SIGWINCH plumbing — about 130 lines of brittle ioctl wrangling. creack/pty + golang.org/x/term shrink it to ~30 well-tested lines (pure-Go, no cgo, no extra runtime dependencies).
func RunRootless ¶
func RunRootless(rootfs string, args, env []string, stdin io.Reader, stdout, stderr io.Writer) error
RunRootless is like Run but creates a new USER namespace too, mapping container root (uid/gid 0) to the caller's real uid/gid. This lets an unprivileged, non-root process (e.g. a restricted K8s pod running as uid 1001) gain namespaced CAP_SYS_ADMIN and thus do mount/pivot_root — without any host privilege.
Types ¶
This section is empty.