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