Ruby and FuseFS

by Caleb Tennis

Recently, I starting an attempt to upgrade one of our critical pieces of software to a new underlying library revision, and it proving to be quite a challenge.

I’ll spare the details, but suffice to say it’s not pretty. One aspect I’m currently focusing on is a nice way to share data between modules, those already written and those yet to be written. Historically we’ve used IPC shared memory, which for ruggedly defined structures works very well. However, for dynamic streaming data, it doesn’t fare so well. Furthermore, I need a well defined interface - an abstract one, if you will, that works between various programming languages and toolkits.

Enter the filesystem. I recently discovered the fuse filesystem, and its Ruby counterpart FuseFS. Man oh man what a gem this little guy is.

Here’s a small snippet of what I’m currently accomplishing with FuseFS:

I have an application config file, which is stored in INI format like this:


[Group1]
key1=value1
key2=value2
...


And here’s a snippet of Ruby:


require 'fusefs'

$configfile = “/home/me/blah/myconfigfile.ini”

module INI
def self.read(filename)
inimap = { }
hdr = nil
File.open(filename).each do |row|
if row =~ /^\[(.+)\]$/
hdr = $1
inimap[hdr] = { }
elsif row =~ /^(.+)\=(.+)$/
hdr && inimap[hdr][$1] = $2
end
end
inimap
end
end

class SettingsDir < FuseFS::MetaDir
def initialize
super
confighash = INI.read($configfile)
confighash.each do |key,value|
mkdir(’/’ + key)
value.each do |key2,value2|
write_to(’/’ + key + ‘/’ + key2, value2+”\n”)
end
end
end
end
root = SettingsDir.new
FuseFS.set_root(root)
FuseFS.mount_under ARGV.shift
FuseFS.run


This code is simple. It reads an INI file, and creates a hash of hashes, and uses that to create a fake directory structure within the operating system. If I run this code, I can open a shell in another window and access this information via the filesystem:


tc@tc8 ~/configfs $ ls settings
Group1 Group2 Group3

tc@tc8 ~/configfs $ ls settings/Group1
key1 key2 key3

tc@tc8 ~/configfs $ more settings/Group1/key1
value1


As you can see, my hash of hashes is now available via the filesystem. Any application now has access to this abstracted information. From this point, it’s fairly trivial to implement a reverse setup, where when you write data to one of the files it saves that back to the hash, which in turn updates the INI file.

Granted, this is a mildly convoluted way to read and write to an INI file, but the point here is that we don’t have to worry about the INI file at all. This system would work for any backend, such as a SQL system or CSV file backend.

I’m pretty impressed so far, and I’ve only scratched the surface of what’s possible.