dumont
Backends

Bunny Storage

A filesystem over Bunny.net Edge Storage, spoken as plain HTTP.

A vfs.FileSystem over Bunny.net Edge Storage, spoken as plain HTTP (no SDK). Auth is the storage-zone password sent in the AccessKey header.

Configuration

remotes:
  cdn:                        # addressed as cdn://path/to/file
    type: bunnystorage
    zone: my-storage-zone
    region: ny                # optional; selects <region>.storage.bunnycdn.com
    # endpoint: https://storage.bunnycdn.com   # optional explicit base URL
    # prefix: dumont          # optional: root the remote at zone/<prefix>
    emulate: true             # optional: add random write/append via RMW
    credentials:
      password: env:BUNNY_STORAGE_PASSWORD

The remote name is the URI scheme and the whole path follows it (cdn://images/logo.png); the zone and credentials are fixed per remote.

Capabilities

CapValueWhy
RandomReadwhole-object GET
RandomWritewhole-object PUT
Append
Truncate
AtomicRenamerename = download + upload + delete
Directoriesmodeled as synthesized-from-prefix
MTimeLastChanged (second resolution)
CaseSensitivekeys are case-sensitive

Wrap with emulate: true for random write/append, and the metadata cache cuts listing round-trips automatically.

Semantic surprises

  • No HEAD for a single object. Stat lists the parent directory and finds the entry — Bunny's listing reports Length, LastChanged, and IsDirectory per child.
  • Directories are modeled as synthesized. Although Bunny does persist directory objects (created implicitly when a file is uploaded into a path), empty directories can't be created via the API, so dumont treats a directory as existing iff it has children. Mkdir is a no-op (the path appears once a file lands in it); removing an empty directory issues a recursive DELETE on the trailing-slash path.
  • Rename copies. There is no server-side copy: Rename downloads, re-uploads under the new key, and deletes the old (non-atomic; directory rename iterates every descendant).
  • mtime is second-resolution, truncated so Stat and ReadDir agree.

Testing

  • A full conformance suite runs against an in-process mock of the API (no credentials, always runs).

  • An integration suite runs the same battery plus a smoke test against a real zone when BUNNY_STORAGE_ZONE and BUNNY_STORAGE_PASSWORD are set. Each run is sandboxed under a unique key prefix and deleted on completion, leaving the zone clean:

    BUNNY_STORAGE_ZONE=my-zone BUNNY_STORAGE_PASSWORD=... \
      go test -run TestIntegration ./backend/bunnystorage/

On this page