Documentation
¶
Index ¶
- Constants
- Variables
- func ConfineToSandbox(spec SandboxSpec) error
- func EncodeSandboxSpec(spec SandboxSpec) (string, error)
- func ExecutionTimeout() time.Duration
- func LaunchSandbox(spec SandboxSpec, childPath string, childArgs []string, env []string, ...) error
- func PolicyJSON(policy Policy) ([]byte, error)
- func RejectSecretEnvironment(env []string) error
- func SandboxEnvironment() []string
- func SandboxSupported() (bool, string)
- func SanitizedEnvironment(cacheRoot string) []string
- func SecretLikeEnvName(name string) bool
- func SecretLikePathName(rel string) bool
- func UnsafeExportDirectory(rel string) bool
- func UnsafeExportFile(rel string) bool
- type ExportResult
- type File
- type Limits
- type Options
- type Policy
- type SandboxSpec
- type Workspace
Constants ¶
const ( DefaultMaxFiles = 128 DefaultMaxFileBytes = 256 * 1024 DefaultMaxTotalBytes = 2 * 1024 * 1024 )
const ( SandboxWorkspacePath = "/workspace" SandboxOutputPath = "/out" SandboxGoRootPath = "/goroot" SandboxGoModCachePath = "/gomodcache" SandboxGoCachePath = "/cache" SandboxTmpPath = "/tmp" )
Fixed in-sandbox mount points. The build always runs against these paths after confinement, regardless of where the host staged the inputs.
const SandboxUnsupportedExitCode = 99
SandboxUnsupportedExitCode is the exit status the re-executed child uses to tell the parent that confinement could not be established here (e.g. the kernel denied a required mount inside the namespace). The parent maps this code back to ErrSandboxUnsupported so hosted execution fails closed cleanly instead of surfacing an opaque non-zero exit. It is outside the range the Go toolchain or the build itself returns.
Variables ¶
var ErrSandboxUnsupported = errors.New("playground sandbox is not supported on this platform")
ErrSandboxUnsupported is returned when OS-level confinement is not available on this platform or kernel. Hosted execution must fail closed on this error, never fall back to running the build unconfined.
Functions ¶
func ConfineToSandbox ¶ added in v0.6.0
func ConfineToSandbox(spec SandboxSpec) error
ConfineToSandbox is run by the re-executed child, already inside the new namespaces. It builds a minimal root that exposes only the toolchain, a throwaway module-cache overlay, the staged workspace, and the output directory, then pivot_roots into it so the host filesystem becomes unreachable. Finally it applies resource limits and no-new-privileges. Any failure is returned so the caller aborts; partial confinement never runs the build.
Some environments create the namespaces but then deny a required mount inside them (a container with a positive max_user_namespaces but a restrictive mount policy reports exactly this: "mount proc: operation not permitted"). Such a failure means the sandbox cannot be established here, not that the build is broken, so it is reported as ErrSandboxUnsupported and the child exits with SandboxUnsupportedExitCode so the parent fails closed cleanly.
func EncodeSandboxSpec ¶ added in v0.6.0
func EncodeSandboxSpec(spec SandboxSpec) (string, error)
EncodeSandboxSpec serializes a spec for handoff to the re-executed child.
func ExecutionTimeout ¶
func LaunchSandbox ¶ added in v0.6.0
func LaunchSandbox(spec SandboxSpec, childPath string, childArgs []string, env []string, stdout, stderr io.Writer, timeout time.Duration) error
LaunchSandbox runs childArgs (the re-executed gowdk build) inside fresh user, mount, PID, network, IPC, and UTS namespaces. The network namespace has no configured interface, so the child has no network. The wall-clock timeout kills the child; because it is PID 1 of its namespace, the kernel reaps the whole process tree with it.
func PolicyJSON ¶
func RejectSecretEnvironment ¶
func SandboxEnvironment ¶ added in v0.6.0
func SandboxEnvironment() []string
SandboxEnvironment returns the environment the build runs with inside the confined root: the toolchain and caches point at the fixed in-sandbox paths, the module proxy and checksum database are disabled, and no host environment leaks in. It is deliberately built from constants, not os.Environ().
func SandboxSupported ¶ added in v0.6.0
SandboxSupported reports whether the kernel offers the namespaces this sandbox needs. It is intentionally conservative: a false result must make hosted execution fail closed rather than run unconfined.
Reading max_user_namespaces alone is not enough: containers (notably the CI runners) report a positive limit yet still deny the unprivileged clone via seccomp/AppArmor, so the value lies about what actually works. We therefore follow the cheap sysfs check with a real clone probe and only report support when the namespaces can genuinely be created.
func SanitizedEnvironment ¶
func SecretLikeEnvName ¶
func SecretLikePathName ¶
func UnsafeExportDirectory ¶
func UnsafeExportFile ¶
Types ¶
type ExportResult ¶
func ExportArchive ¶
func ExportArchive(sourceDir string, archivePath string, options Options) (ExportResult, error)
type Policy ¶
type Policy struct {
HostedExecutionEnabled bool `json:"hostedExecutionEnabled"`
Workspace string `json:"workspace"`
Network string `json:"network"`
Filesystem string `json:"filesystem"`
Persistence string `json:"persistence"`
VersionPinning string `json:"versionPinning"`
Export string `json:"export"`
Limits Limits `json:"limits"`
Environment []string `json:"environment"`
RequiredAbuseControls []string `json:"requiredAbuseControls"`
}
func DefaultPolicy ¶
func DefaultPolicy() Policy
type SandboxSpec ¶ added in v0.6.0
type SandboxSpec struct {
// WorkspaceRoot is the staged, disposable project copy (writable inside).
WorkspaceRoot string `json:"workspaceRoot"`
// OutputDir receives build output (writable inside).
OutputDir string `json:"outputDir"`
// GoRoot is the host GOROOT exposed read-only so the toolchain can run.
GoRoot string `json:"goRoot"`
// GoModCache is the host module cache exposed through a throwaway writable
// overlay so offline builds resolve cached modules without persisting writes.
// Its lower layer is readable by the sandboxed build, so a hosted runner must
// point this at a per-session cache holding only the submitted project's
// dependencies, never a shared cache with other tenants' private modules.
GoModCache string `json:"goModCache"`
// MaxAddressSpaceBytes caps the virtual address space (RLIMIT_AS). Zero
// leaves the limit unset.
MaxAddressSpaceBytes uint64 `json:"maxAddressSpaceBytes"`
// MaxCPUSeconds caps CPU time (RLIMIT_CPU). Zero leaves it unset.
MaxCPUSeconds uint64 `json:"maxCPUSeconds"`
// MaxFileSizeBytes caps any single written file (RLIMIT_FSIZE). Zero leaves
// it unset.
MaxFileSizeBytes uint64 `json:"maxFileSizeBytes"`
// MaxOpenFiles caps open descriptors (RLIMIT_NOFILE). Zero leaves it unset.
MaxOpenFiles uint64 `json:"maxOpenFiles"`
// MaxProcesses caps processes for the sandboxed user (RLIMIT_NPROC). Zero
// leaves it unset.
MaxProcesses uint64 `json:"maxProcesses"`
// MaxTmpfsBytes caps the size of each writable tmpfs mounted inside the
// sandbox (the root, build cache, and /tmp). tmpfs is page-cache backed, so
// without this a build could write until host memory is exhausted. Zero
// leaves the tmpfs unbounded (host default). It is a per-mount cap, not an
// aggregate one; total memory is the outer cgroup boundary's responsibility.
MaxTmpfsBytes uint64 `json:"maxTmpfsBytes"`
}
SandboxSpec describes a confined build execution. All paths are absolute host paths; the sandbox remaps them to fixed locations inside the confined root.
func DecodeSandboxSpec ¶ added in v0.6.0
func DecodeSandboxSpec(encoded string) (SandboxSpec, error)
DecodeSandboxSpec parses a spec produced by EncodeSandboxSpec.