A Plakar integration that uses Backblaze B2 as a backend. It implements all three connector types:
- storage — a B2 bucket as the Plakar repository backend
- importer — a B2 bucket as a backup source (
plakar backup) - exporter — restore a snapshot to a B2 bucket (
plakar restore)
All three use the b2 protocol, so the same b2://bucket location works as a
repository, a source, or a destination depending on the command.
It talks to B2's own Native API (v3) rather than the S3-compatible gateway,
so it handles the real B2 protocol: the authorize handshake, per-upload URLs,
SHA-1 on upload, and fileId-keyed deletes.
b2/ B2 Native API client (HTTP only, no Plakar types)
config/ shared config parsing (credentials + b2:// location)
storage/ storage connector + schema.json
importer/ importer connector + schema.json
exporter/ exporter connector + schema.json
plugin/ one-line gRPC entrypoints per connector
manifest.yaml · Makefile · go.mod · go.sum
The B2 client and the config parsing are shared by all three connectors; each connector package only holds the Plakar-facing mapping.
make build # builds backblazeStorage / backblazeImporter / backblazeExporter
make install # packages a .ptar and installs it into plakar
plakar pkg show | grep backblaze # -> backblaze@v1.0.0Requires Go 1.24+ and the plakar CLI on PATH. Run go mod tidy once to
generate go.sum.
export PLAKAR_PASSPHRASE=somepass # avoids the interactive prompt
# storage: B2 bucket as a repository
plakar store add myB2 b2://my-bucket \
application_key_id=YOUR_KEY_ID application_key=YOUR_APP_KEY
plakar at @myB2 create
plakar at @myB2 backup /path/to/data
plakar at @myB2 ls
plakar at @myB2 restore -to /tmp/out <snapid>
# importer: B2 bucket as a backup source
plakar source add b2src b2://my-bucket \
application_key_id=YOUR_KEY_ID application_key=YOUR_APP_KEY
plakar at /path/to/repo backup @b2src
# exporter: restore to a B2 bucket
plakar destination add b2dst b2://my-bucket/restore-prefix \
application_key_id=YOUR_KEY_ID application_key=YOUR_APP_KEY
plakar at /path/to/repo restore -to @b2dst <snapid>Plakar addresses objects by a (resource, MAC) pair — resource is packfile,
state or lock, and the MAC is the object's content id. The storage connector
maps that pair to a B2 object key under an optional prefix:
(packfile, MAC) → <prefix>/packfiles/<xx>/<mac> (<xx> = first MAC byte, hex)
(state, MAC) → <prefix>/states/<xx>/<mac>
(lock, MAC) → <prefix>/locks/<mac>
That mapping lives in one place (storage.macPath); List derives the directory
prefixes from the same scheme and decodes the MAC back out of each key. The repo
config is stored at <prefix>/CONFIG — Create writes it (refusing to overwrite
an initialised repo), Open reads it back.
The connectors register the b2 protocol with flag 0 (remote backend, not a
local filesystem), and the plugin/*/main.go files just hand each constructor to
the SDK entrypoint.
Following the existing S3 integration, this connector always works on the latest version of an object and doesn't manage versions.
go build ./... && go vet ./...
export PLAKAR_PASSPHRASE=somepass
plakar store ping @myB2
plakar at @myB2 create
plakar at @myB2 backup /some/dir
plakar at @myB2 restore -to /tmp/out <snapid>
plakar at @myB2 check
PLAKAR_LOCKLESS=1 plakar at @myB2 maintenancecheck is the most useful single command — it reads every packfile back from B2
and verifies content hashes, so a broken Put/Get mapping fails it.
One gotcha while developing: plugins talk to Plakar over gRPC on stdin/stdout, so anything written to stdout corrupts the stream — use stderr for debug output.