go-volumes

Pure-Go block storage — a copy-on-write volume pool plus pluggable backings (local file, S3, OCI artifact). Carve thin, snapshottable volumes, then put a filesystem on top. No cgo, no root, no device-mapper.

pure Go no cgo no root copy-on-write snapshots ZFS-inspired S3-backed OCI artifacts BSD-3-Clause
Documentation GitHub

go-volumes builds a pooled, copy-on-write volume layer in pure Go: a pool owns a flat array of fixed-size physical blocks backed by a single file, volumes are logical block devices carved out of it, and snapshots are immutable, reference-counted captures. Writes are copy-on-write, so overwriting a block shared with a snapshot allocates a fresh one and leaves the snapshot untouched.

A ZFS-inspired alternative to LVM thin provisioning. LVM thin snapshots can corrupt when the pool fills past a threshold; here a copy-on-write write fails cleanly and atomically with ErrPoolFull before any on-disk state changes, so a mounted filesystem sees a normal ENOSPC rather than silent corruption. A Volume implements ReadAt, WriteAt, Sync, Size, Truncate and Close — the same block-backend shape the go-filesystems ext4/xfs drivers accept — so you can format and mount straight onto a pool volume.

One contract, swappable backings. The Device contract (ReadAt/WriteAt/Size/Sync/Close) is all a filesystem driver sees, so where the bytes live is pluggable: a local file, an S3-compatible bucket (from-scratch AWS Signature V4, standard library only — no aws-sdk-go), or an immutable, content-addressed OCI artifact — chunk-deduped, so a mostly-empty sparse image freezes to a handful of blobs regardless of its logical size.

Repositories

interface libcontract

The block-device Device contract (package volume)

stdlib only โ€” io.ReaderAt/WriterAt + Size/Sync/Close

The shared block-device contract every layer reads and writes through: a fixed-size, random-access Device (ReadAt/WriteAt/Size/Sync/Close) plus a ReadOnly subset and optional capabilities (Truncate, Name, ReadOnly, Discard). It decouples WHERE the bytes live from the filesystem FORMAT on top โ€” pool's *Volume satisfies Device verbatim, and a go-filesystems driver writes its on-disk image through it without caring which backing is underneath.

pool libstorage

Pooled, copy-on-write volume manager (Volume / Snapshot)

pure Go โ€” no cgo, no root, no device-mapper

A small, ZFS-inspired alternative to LVM thin provisioning: a pool owns a flat array of fixed-size blocks in one file, volumes are carved out of it, and snapshots are immutable, reference-counted, copy-on-write captures. When the pool fills, a CoW write fails cleanly and atomically with ErrPoolFull before any on-disk state changes โ€” so snapshots can't be corrupted the way LVM thin snapshots can. A Volume implements ReadAt/WriteAt/Sync/Size/Truncate/Close, the block-backend shape go-filesystems' ext4/xfs drivers accept. Pluggable Backing decides where the bytes live.

s3 libbacking

S3-backed block store (pool Backing) โ€” from-scratch SigV4

stdlib only โ€” no aws-sdk-go, no minio-go

A pure-Go S3-backed block store satisfying pool's Backing interface: it maps a flat byte address space onto fixed-size chunk objects in any S3-compatible bucket, with an in-memory write-back cache, so a copy-on-write pool โ€” or any block consumer โ€” runs on object storage with no local file. AWS Signature Version 4 is implemented from scratch on crypto/hmac + crypto/sha256 and validated byte-for-byte against the official AWS SigV4 test suite.

oci libbacking

Freeze a volume into an immutable, content-addressed OCI artifact

stdlib only โ€” OCI Distribution v2 client over net/http

Freeze a block-volume image into an immutable, content-addressed OCI artifact (push to any registry) and re-open it as a read-only backing (pull on demand, LRU byte cache). Each chunk is sha256-addressed and pushed once, so identical chunks โ€” especially the all-zero holes of a sparse image โ€” collapse to a single blob: a mostly-empty disk freezes to a handful of blobs regardless of logical size. Plugs into pool's OpenWith as a genuinely immutable backing, and rejects every write.

nbd libbacking

NBD (Network Block Device) server + client

pure Go (CGO=0) โ€” stdlib only

A from-scratch NBD (Network Block Device) server and client. The server exports any volume.Device so a remote consumer โ€” the Linux kernel nbd-client, qemu-nbd / QEMU, or libnbd tooling (nbdinfo/nbdcopy) โ€” can attach it over the wire; the client dials a remote export and presents it back as a local Device that plugs straight into the pool and replica stack.

replica libstorage

Synchronous N-way replication engine (replica.Engine)

pure Go (CGO=0) โ€” stdlib only

A replication engine for highly-available block volumes: it fronts N synchronous replicas โ€” each any volume.Device (in production an nbd client to a remote node) โ€” so every write fans out to all replicas and reads are served from a healthy one. Degraded/failed replicas are tracked and re-synced, giving the data plane underneath replica-ha.

replica-ha libstorage

HA control plane โ€” leader election over a replica.Engine

pure Go (CGO=0) โ€” stdlib only

The high-availability control plane for replicated block volumes: it drives a replica.Engine (the data plane that mirrors a volume across N synchronous replicas) under leader election, so a single writer owns the volume at a time and failover to a surviving node is automatic โ€” HA block storage with no device-mapper, no cluster manager, pure Go.

Pure Go with no cgo, no root, and no device-mapper. Snapshots are immutable and reference-counted; the pool refuses a copy-on-write write atomically when it's full rather than risk corruption. go-volumes pairs with go-filesystems for the filesystem on top and go-fde for encryption underneath. BSD-3-Clause throughout.