Hi all,

*I'd like to share openfuse, a FUSE library for OpenBSD writtenentirely in
Go and released under the BSD license.*

It talks to fuse(4) directly. There is no cgo and no libfuse
underneath, so building a filesystem is just "go build". Since
there is no C code, you don't need a C toolchain to cross-compile
either: GOOS=openbsd go build works from any machine. As far as I
know, it is the first FUSE library for OpenBSD written purely in Go.
Its only dependency is golang.org/x/sys, it was developed against
OpenBSD 8.0, and its version numbers follow OpenBSD releases.

The design is built around Go's fs.FS interface: you hand any fs.FS
to the library and it is mounted as a real filesystem. Files embedded
in the binary, files made up in code and zip archives all work
read-only out of the box. A filesystem gets write support by
implementing a few optional interfaces, as the in-memory memfs
package in the repository does:

  //go:embed docs
  var docs embed.FS

  func mount(dir string, readOnly bool, fsys fs.FS) {
    opts := fuse.Options{Name: "openfuse", ReadOnly: readOnly}
    f, err := fuse.Mount(dir, opts, fshandler.New(fsys))
    if err != nil {
      log.Fatal(err)
    }
    go f.Serve(context.Background(), slog.Default())
  }

  func main() {
    // Read-only: files compiled into the binary.
    mount("/mnt/embed", true, docs)

    // Read-only: files made up in code.
    mount("/mnt/synthetic", true, fstest.MapFS{
      "now.txt": {Data: []byte(time.Now().String()), Mode: 0o444},
    })

    // Read-only: a zip archive, browsed without extracting it.
    archive, err := zip.OpenReader("backup.zip")
    if err != nil {
      log.Fatal(err)
    }
    mount("/mnt/zip", true, archive)

    // Read-write: a filesystem kept in memory.
    mount("/mnt/memfs", false, memfs.New())

    select {}
  }

To try it you need Go 1.27, and root to mount:

  $ git clone https://github.com/RogueTeam/openfuse
  $ cd openfuse/examples/hello
  $ go build
  $ mkdir -p /tmp/hello
  $ doas ./hello /tmp/hello

Then, from another terminal:

  $ doas cat /tmp/hello/hello.txt

Ctrl-C stops it and unmounts the directory. The examples directory
also has memfs (read-write), mirror (os.DirFS), embed and zip.

Requests are served one at a time; the project puts correctness ahead
of speed. Bug reports and feedback are very welcome.

https://github.com/RogueTeam/openfuse

Antonio

Reply via email to