Skip to content

Latest commit

 

History

History
84 lines (67 loc) · 3.95 KB

README.md

File metadata and controls

84 lines (67 loc) · 3.95 KB

ConsulFS

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.

Installation

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.

Command line usage

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.

File system model

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.

Consistency

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.