ConsulFS implements a FUSE filesystem that is backed by a Consul Key-Value store. Each key in the key store is represented by a file. Read and write the file to get and put the key's value. "/" characters in a key name are used to break up the keys into different directories.
This project should be considered alpha-quality. It works, but it might not handle everything you can throw at it.
ConsulFS uses FUSE to implement a file system as a user-space process. Most popular Linux distributions will already include a FUSE module, so no further packages need to be installed. OS X systems will need to install a third-party file system package to mount FUSE volumes. FUSE for OS X is the preferred FUSE package at the time of this writing.
There are currently no binary packages available for ConsulFS, so you will need to build the package yourself. ConsulFS is written in Go, so install the Go toolchain available for your system. Look for a "golang" package in your system's package manager (Linux) or in Homebrew (OS X). Binary packages can also be downloaded from golang.org.
Once FUSE and Go are installed, you can download, build, and install ConsulFS by running the following command:
$ go get github.com/bwester/consulfs/cmd/consulfs
That will create the binary $GOPATH/bin/consulfs
, which you can call directly
or copy to your preferred location for binaries.
The consulfs
command is used to mount a Consul Key-Value store onto a file
system path. The basic form of the command is:
$ consulfs [options] [consul_address] /mount/path
There aren't many options, but you can run consulfs --help
to see them. The
address of a Consul agent is optional, and if you omit it, the local agent will
be used.
ConsulFS runs in the foreground, where it displays all error messages. If you interrupt the process with ^C or send it a SIGTERM or SIGINT, it will attempt to unmount the file system before exiting. Or, if the mount point is unmounted through other means ("umount" or "fusermount"), the process will exit.
ConsulFS represents each key in Consul as a file in the file system. The slash character "/" is a key interpreted as a directory separator, and key names are broken up in the straightforward way. Reads and writes on a file will cause GETs and PUTs, respectively, to the key in order to fetch and update the key's value.
Consul doesn't itself store directores; those are simply inferred from the keys. As such, Consul is not updated when creating or removing an empty directory.
For example, the key "foo/bar" is exposed to the file system as the file "bar" in the directory "foo". When "bar" is read, a GET is performed for "foo/bar" and its value will be read. Writes to "bar" first GET "foo/bar", change the written bytes, then save them with a PUT to "foo/bar" containing the entire key's contents. In the directory "foo", if you write to a new file "baz", the key "foo/baz" will be written.
ConsulFS does not currently support durable timestamps, owners, or mode bits--there isn't enough metadata in Consul to store these! The timestamps are faked, and owner/mode bits are fixed: attempts to change them will return an error.
ConsulFS doesn't perform any local caching of key values (this was much easier
to write!), so every read will always get the latest value. Writes to a file
atomically PUT the key's value. This might cause an occasional write()
syscall to fail in the presence of concurrent writers. As you might imagine,
ConsulFS is currently kinda slow when accessing remote file systems. Future
versions may introduce a data cache.
Directory listings are briefly cached, for about 1 second. The access patterns generated by FUSE repeatedly access this kind of metadata, so a small cache is required to get any kind of usable performance.