process

package
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: GPL-3.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InstalledRVersions

func InstalledRVersions() []string

InstalledRVersions returns the R versions installed under rigBase. Each entry is the directory name (e.g. "4.5.0", "4.4.3").

func ResolveRBinary

func ResolveRBinary(version, fallback string) (string, bool)

ResolveRBinary maps a requested R version (e.g. "4.5.0") to the full path of a rig-managed R binary. Resolution order:

  1. Exact match: /opt/R/<version>/bin/R
  2. Minor match: highest /opt/R/<major>.<minor>.*/bin/R
  3. Fallback: the configured default R path

Returns the resolved path and whether the fallback was used. When version is empty the fallback is returned directly (not considered a miss).

func RunBwrapExec added in v0.0.4

func RunBwrapExec(args []string) error

RunBwrapExec is the `blockyard bwrap-exec --uid W --gid G -- <bwrap> <bwrap-args>` subcommand the process backend invokes instead of calling bwrap directly. It drops into the worker's (uid, gid), restores the dumpable flag that the kernel clears on suid transitions, and execs bwrap.

Why this isn't `SysProcAttr.Credential`: Go's fork+exec does setgroups+setgid+setuid but never calls `prctl(PR_SET_DUMPABLE, 1)` afterward. The kernel marks the process non-dumpable after any credential transition (even root→user), and a non-dumpable process sees /proc/self/uid_map as owned by root (not the current ruid). bwrap's unprivileged uid_map write then fails with EPERM — "bwrap: setting up uid map: Permission denied". Restoring dumpable between setuid and exec makes /proc/self/uid_map owned by the worker UID again, so bwrap can write the identity uid_map that makes worker traffic host-identifiable for iptables owner-match rules.

Exported because both cmd/blockyard/main.go and the process package's TestMain dispatch to it: in tests, os.Executable() returns the test binary rather than the blockyard binary, so the test binary must also recognise the "bwrap-exec" first arg and execute the shim itself — otherwise exec.Command(testbin, "bwrap-exec", ...) re-enters the test runner and the whole suite recurses.

Returns an error for any misuse; on success it never returns (execve replaces the process).

func RunPreflight

func RunPreflight(cfg *config.ProcessConfig, fullCfg *config.Config, cgroups *cgroupManager) *preflight.Report

RunPreflight verifies the process backend prerequisites. Called by (*ProcessBackend).Preflight() with the full config so the egress probe can read Redis/vault/database addresses and the resource- limit check can read server-level defaults.

Check ordering matters: bwrap/R/userns are prerequisites for checkBwrapHostUIDMapping (it spawns bwrap), and that check is a prerequisite for checkWorkerEgress (which also spawns bwrap and whose results are meaningful only if the host UID mapping is effective). If a prerequisite fails we still run the later checks — they'll fail too, and emitting all failures at once is more useful than bailing at the first.

cgroups is the optional cgroup-v2 delegation manager; nil is safe and tests pass nil directly. The manager feeds checkCgroupDelegation and the worker-egress probe's cgroup enrollment.

Types

type ProcessBackend

type ProcessBackend struct {
	// contains filtered or unexported fields
}

ProcessBackend implements backend.Backend using bubblewrap.

func New

func New(fullCfg *config.Config, rc *redisstate.Client, db *sqlx.DB) (*ProcessBackend, error)

New creates a ProcessBackend. Verifies that bwrap exists at the configured path and that the worker mount point can be reached from inside the bwrap sandbox. The full config is stored so Preflight() can read the addresses of Redis/vault/database for the egress probe and the server-level resource-limit fields for the warning check.

rc and db are the shared connection pools opened by main.go before the backend factory runs. The allocator implementation is picked by config.ResolveSessionStoreMode(cfg) — the same selector that drives session, registry, and worker-map storage — so a deployment that asks for Postgres-primary sessions also gets Postgres-primary allocators. The allocator path is the only place this backend touches rc/db; both can be nil in test/single-process configurations and the memory allocators take over.

func (*ProcessBackend) Addr

func (b *ProcessBackend) Addr(_ context.Context, id string) (string, error)

func (*ProcessBackend) Build

func (*ProcessBackend) CheckRVersion

func (b *ProcessBackend) CheckRVersion(version string) error

func (*ProcessBackend) CleanupOrphanResources

func (b *ProcessBackend) CleanupOrphanResources(ctx context.Context) error

CleanupOrphanResources implements backend.Backend. Workers from a previous run are already dead (Pdeathsig killed them with the server), so the in-memory variants have nothing to clean up. The Redis variants, however, carry owned claims across server restarts and need a scan-and-delete at startup to return crashed-session ports and UIDs to the pool.

func (*ProcessBackend) HealthCheck

func (b *ProcessBackend) HealthCheck(ctx context.Context, id string) bool

func (*ProcessBackend) ListManaged

func (b *ProcessBackend) ListManaged(_ context.Context) ([]backend.ManagedResource, error)

func (*ProcessBackend) Logs

func (*ProcessBackend) Preflight

func (b *ProcessBackend) Preflight(_ context.Context) (*preflight.Report, error)

Preflight implements backend.Backend by delegating to RunPreflight.

func (*ProcessBackend) RemoveResource

func (b *ProcessBackend) RemoveResource(_ context.Context, r backend.ManagedResource) error

func (*ProcessBackend) Spawn

func (*ProcessBackend) Stop

func (b *ProcessBackend) Stop(_ context.Context, id string) error

func (*ProcessBackend) UpdateResources

func (b *ProcessBackend) UpdateResources(_ context.Context, _ string, _ int64, _ int64) error

UpdateResources is not supported by the process backend: we do not enforce per-worker cgroup limits (decision #6), so there is nothing to update. Returning ErrNotSupported lets callers distinguish "cannot do this" from "ran into a real error"; api/apps.go checks for ErrNotSupported and skips its warning log so app-update requests do not spam one noisy warning per worker.

func (*ProcessBackend) WorkerResourceUsage

func (b *ProcessBackend) WorkerResourceUsage(_ context.Context, id string) (*backend.WorkerResourceUsageResult, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL