runtime

package
v1.0.0-rc.1 Latest Latest
Warning

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

Go to latest
Published: Jun 13, 2026 License: Apache-2.0 Imports: 34 Imported by: 0

Documentation

Overview

Package runtime abstracts where branch instances run (Docker now, K8s in P3).

Index

Constants

View Source
const LabelInstance = "pgbranch.instance"

LabelInstance tags every managed resource with the owning registry's instance id (registry.InstanceID()). Reconcile reclaims only resources carrying ITS id, so concurrent pgbranch instances sharing one Docker daemon (and the parallel IT suite) never GC each other's live containers/volumes.

Variables

This section is empty.

Functions

func DockerHostFromCLIContext

func DockerHostFromCLIContext() string

DockerHostFromCLIContext resolves the docker endpoint from the CLI's current context (~/.docker/config.json + contexts/meta). The Go SDK's FromEnv only honors DOCKER_HOST, so without this, setups like Colima (where /var/run/docker.sock is absent or stale) fail. Returns "" when unresolvable. Exported so integration helpers can prime DOCKER_HOST for libraries (e.g. testcontainers) that don't read docker CLI contexts.

func NewKubeClient

func NewKubeClient(kubeconfig string) (kubernetes.Interface, error)

NewKubeClient builds a kubernetes.Interface from the same in-cluster / kubeconfig loading path the kube driver uses (kubeconfig=="" → in-cluster, then KUBECONFIG / ~/.kube/config). branchd reuses it for the leader-election Lease so HA shares the driver's cluster credentials.

Types

type BranchSpec

type BranchSpec struct {
	Name       string // container name, e.g. pgbranch-br-pr-1
	Image      string
	Env        []string
	Mounts     []Mount
	Entrypoint []string // overrides image entrypoint
	Labels     map[string]string
	Network    string
}

BranchSpec is a long-running branch Postgres container.

type CSIConfig

type CSIConfig struct {
	// StorageClass provisions every pgbranch PVC; it must support PVC
	// dataSource cloning (or VolumeSnapshots when SnapshotClass is set).
	StorageClass string
	// SnapshotClass switches branch cloning from PVC dataSource clones to
	// VolumeSnapshot + restore ("" = direct PVC clones).
	SnapshotClass string
	// VolumeSize is the storage request of every pgbranch PVC ("" = 10Gi).
	VolumeSize string
}

CSIConfig configures the csi storage strategy.

type ContainerInfo

type ContainerInfo struct {
	ID      string
	Running bool
	Host    string // address the instance is reachable on (127.0.0.1 for docker, pod IP for k8s)
	Port    int    // port on Host (docker: host port mapped to 5432, 0 if none)
	Labels  map[string]string
}

type DockerDriver

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

func NewDockerDriver

func NewDockerDriver() (*DockerDriver, error)

func (*DockerDriver) CloneVolume

func (d *DockerDriver) CloneVolume(ctx context.Context, src, dst string, labels map[string]string) error

CloneVolume provisions dst as a copy of src. Docker named volumes have no copy-on-write clone primitive, so this is a full `cp -a` through a helper container — a generic fallback satisfying the Driver contract; no engine flow uses it on docker today (the overlay and zfs backends have cheaper mechanisms).

func (*DockerDriver) CreateVolume

func (d *DockerDriver) CreateVolume(ctx context.Context, name string, labels map[string]string) error

func (*DockerDriver) EnsureImage

func (d *DockerDriver) EnsureImage(ctx context.Context, ref string) error

func (*DockerDriver) Exec

func (d *DockerDriver) Exec(ctx context.Context, id string, cmd []string) error

func (*DockerDriver) ExecOutput added in v0.3.0

func (d *DockerDriver) ExecOutput(ctx context.Context, id string, cmd []string) (string, error)

ExecOutput runs cmd in the container and returns its stdout. The exec API multiplexes stdout/stderr over one attached stream (stdcopy); stderr is kept separate so captured output (e.g. a pg_dump) stays clean, and is embedded in the error on non-zero exit.

func (*DockerDriver) Inspect

func (d *DockerDriver) Inspect(ctx context.Context, id string) (ContainerInfo, error)

func (*DockerDriver) ListManaged

func (d *DockerDriver) ListManaged(ctx context.Context) ([]ContainerInfo, error)

func (*DockerDriver) ListManagedVolumes

func (d *DockerDriver) ListManagedVolumes(ctx context.Context, instanceID string) ([]string, error)

func (*DockerDriver) RemoveVolume

func (d *DockerDriver) RemoveVolume(ctx context.Context, name string) error

func (*DockerDriver) RunHelper

func (d *DockerDriver) RunHelper(ctx context.Context, spec HelperSpec) (string, error)

func (*DockerDriver) StartBranch

func (d *DockerDriver) StartBranch(ctx context.Context, spec BranchSpec) (string, error)

func (*DockerDriver) StopRemove

func (d *DockerDriver) StopRemove(ctx context.Context, id string) error

type Driver

type Driver interface {
	EnsureImage(ctx context.Context, image string) error
	CreateVolume(ctx context.Context, name string, labels map[string]string) error
	RemoveVolume(ctx context.Context, name string) error
	// CloneVolume provisions dst as a copy of src (dst must not exist; labels
	// land on dst). Copy-on-write where the storage supports it (kube csi:
	// PVC dataSource clone / snapshot restore); a full copy elsewhere.
	CloneVolume(ctx context.Context, src, dst string, labels map[string]string) error
	RunHelper(ctx context.Context, spec HelperSpec) (output string, err error)
	StartBranch(ctx context.Context, spec BranchSpec) (id string, err error)
	Exec(ctx context.Context, containerID string, cmd []string) error // error on non-zero exit
	// ExecOutput is Exec with the command's stdout captured and returned
	// (stderr goes into the error on failure). Used where the engine needs
	// in-container command output (pg_dump, row-count probes) against a
	// RUNNING instance — RunHelper can also capture output but spins a new
	// container, which cannot reach an instance's local socket.
	ExecOutput(ctx context.Context, containerID string, cmd []string) (string, error)
	Inspect(ctx context.Context, containerID string) (ContainerInfo, error)
	StopRemove(ctx context.Context, containerID string) error
	ListManaged(ctx context.Context) ([]ContainerInfo, error) // label pgbranch.managed=true
	// ListManagedVolumes returns the names of every volume carrying both the
	// pgbranch.managed=true label AND pgbranch.instance=<instanceID> (docker
	// named volumes / kube PVCs). Reconcile uses it to find orphaned rw and
	// source-layer volumes owned by THIS registry; scoping by instance id keeps
	// one instance from GC'ing another's volumes on a shared daemon. The zfs
	// backend manages datasets, not driver volumes, so its driver may return an
	// empty list (zfs orphans are GC'd via the per-branch/source paths instead).
	ListManagedVolumes(ctx context.Context, instanceID string) ([]string, error)
}

type HelperSpec

type HelperSpec struct {
	Image   string
	Cmd     []string
	Env     []string
	Mounts  []Mount
	Network string
	User    string // e.g. "postgres" for pg_basebackup so file ownership is uid 999
	// Privileged runs the helper with full privileges, with HostDevices
	// mapped in (zfs backend: /dev/zfs). The docker driver maps the devices
	// explicitly; on kube a privileged container sees host devices anyway.
	Privileged  bool
	HostDevices []string
}

HelperSpec is a one-shot container performing a data operation (seeding, file fixes, measurements). Run blocks until exit and returns the captured combined output; non-zero exit = error including that output.

type KubeDriver

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

KubeDriver runs branches as pods. Where the data lives is a pluggable storage strategy:

  • hostPath (default): "volumes" are subdirectories of dataRoot on one designated storage node; every pod is pinned there with nodeName and branch pods get SYS_ADMIN for their in-container overlay mount (decision 1: single-node dev/test scope).
  • csi: "volumes" are PersistentVolumeClaims and branches are PVC clones; pods schedule anywhere, need no extra capabilities, and run postgres directly on their claim (multi-node scope, decision 4 / Phase 5 D).

Container IDs are pod names.

func NewKubeDriver

func NewKubeDriver(kubeconfig, namespace, nodeName, dataRoot string) (*KubeDriver, error)

NewKubeDriver connects to the cluster with the hostPath storage strategy (all data under dataRoot on the named storage node).

func NewKubeDriverCSI

func NewKubeDriverCSI(kubeconfig, namespace string, csi CSIConfig) (*KubeDriver, error)

NewKubeDriverCSI connects to the cluster with the csi storage strategy: volumes are PVCs, branches are PVC clones, pods schedule on any node.

func (*KubeDriver) CloneVolume

func (d *KubeDriver) CloneVolume(ctx context.Context, src, dst string, labels map[string]string) error

CloneVolume provisions dst as a copy of src: a full `cp -a` through a helper pod (hostPath) or a copy-on-write PVC clone / snapshot restore (csi).

func (*KubeDriver) CreateVolume

func (d *KubeDriver) CreateVolume(ctx context.Context, name string, labels map[string]string) error

CreateVolume provisions an empty volume (hostPath: node dir via helper pod; csi: PVC) carrying the given labels.

func (*KubeDriver) EnsureImage

func (d *KubeDriver) EnsureImage(ctx context.Context, image string) error

EnsureImage is a no-op: the kubelet pulls images on pod start.

func (*KubeDriver) Exec

func (d *KubeDriver) Exec(ctx context.Context, id string, cmd []string) error

Exec runs cmd in the pod's first container and fails on non-zero exit with captured output, matching the docker driver's contract.

func (*KubeDriver) ExecOutput added in v0.3.0

func (d *KubeDriver) ExecOutput(ctx context.Context, id string, cmd []string) (string, error)

ExecOutput runs cmd in the pod's first container over the SPDY exec subresource and returns the captured stdout; stderr is kept separate and embedded in the error on failure (non-zero exit surfaces as a stream error).

func (*KubeDriver) Inspect

func (d *KubeDriver) Inspect(ctx context.Context, id string) (ContainerInfo, error)

func (*KubeDriver) ListManaged

func (d *KubeDriver) ListManaged(ctx context.Context) ([]ContainerInfo, error)

func (*KubeDriver) ListManagedVolumes

func (d *KubeDriver) ListManagedVolumes(ctx context.Context, instanceID string) ([]string, error)

ListManagedVolumes returns every pgbranch-managed volume name (delegated to the storage strategy: hostPath dirs or labelled PVCs).

func (*KubeDriver) RemoveVolume

func (d *KubeDriver) RemoveVolume(ctx context.Context, name string) error

RemoveVolume deletes the volume. Idempotent (removing a missing volume succeeds).

func (*KubeDriver) RunHelper

func (d *KubeDriver) RunHelper(ctx context.Context, spec HelperSpec) (string, error)

func (*KubeDriver) StartBranch

func (d *KubeDriver) StartBranch(ctx context.Context, spec BranchSpec) (string, error)

func (*KubeDriver) StopRemove

func (d *KubeDriver) StopRemove(ctx context.Context, id string) error

StopRemove deletes the pod (30s grace, background propagation) and waits until it is gone so a same-name recreate (branch reset) cannot collide. Idempotent: NotFound is success.

type Mount

type Mount struct {
	Kind     MountKind
	Volume   string // volume name (MountVolume) or absolute host path (MountHostPath)
	Target   string
	ReadOnly bool
}

type MountKind

type MountKind string

MountKind selects how Mount.Volume is interpreted.

const (
	// MountVolume (the zero value) names a managed volume: a docker named
	// volume, or a dataRoot subdirectory on the kube storage node.
	MountVolume MountKind = ""
	// MountHostPath bind-mounts an absolute host path. Used by the zfs
	// backend to mount dataset mountpoints; the path must already exist.
	MountHostPath MountKind = "hostpath"
)

Jump to

Keyboard shortcuts

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