Skip to content

Instantly share code, notes, and snippets.

@flaneur2020
Created January 3, 2013 15:10
Show Gist options
  • Select an option

  • Save flaneur2020/4444163 to your computer and use it in GitHub Desktop.

Select an option

Save flaneur2020/4444163 to your computer and use it in GitHub Desktop.
mysqlfs.rb
#!/usr/bin/ruby
#
# Quick proof of concept hack to get a MySQL Filesystem working via FUSE.
#
# Once mounted you can view all database tables and their contents.
#
# NB: Assumes mysqldump will run with: --user='root' --pass=''
#
# Documentation:
#
# http://www.debian-administration.org/articles/619
#
# Steve
# --
#
require 'fusefs'
class MySQLDIR
# login credentials for MySQL
attr_reader :username, :password
#
# Constructor here is where you change the username
# and password.
#
def initialize( username = "root", password = "" )
@username = username
@password = password
end
#
# Find all databases
#
def get_databases()
`mysql --batch --user=#{@username} --pass='#{@password}' -e "show databases" | grep -v ^Database\$`.split("\n")
end
#
# Show the tables for the named database
#
def get_tables(db)
# strip the leading "/"
if ( db =~ /^\/(.*)/ )
db=$1
end
`mysql --batch --user='#{@username}' --pass='#{@password}' #{db} -e "show tables" | grep -v ^Tables_in_#{db}\$`.split("\n")
end
#
# Read the contents of a path, two versions:
#
# contents(/) => Show databases
# contents(/dbname) => Show tables in database "dbname"
#
def contents(path)
if ( path == "/" )
get_databases()
else
names = get_tables( path )
results = Array.new
names.each do |name|
results.push( "#{name}.sql" )
results.push( "#{name}.data" )
end
results
end
end
#
# Is the given path a directory?
#
def directory?(path)
paths = get_databases()
paths.each do |db|
return true if ( "/#{db}" == path )
end
nil
end
#
# Always true is fine. Oddly enough.
#
def file?(path)
true
end
#
# Read a file
#
# either:
#
# database-name/table-name.sql => Table structure
# database-name/table-name.data => Table structure + data
#
def read_file(path)
# reading "dbname/table" == dumping structure.
if ( path =~ /^\/([^\/]+)\/(.*)$/ )
db=$1
tbl=$2
if ( tbl =~ /(.*)\.sql$/i )
`mysqldump --user='#{@username}' --pass='#{@password}' #{db} #{$1} --no-data`
elsif (tbl =~ /(.*)\.data$/i )
`mysqldump --user='#{@username}' --pass='#{@password}' #{db} #{$1}`
else
nil
end
end
end
end
#
# Make sure we have a mount-point
#
if ( ! File.directory?( "/mysql" ) )
puts "/mysql doesn't exist"
exit
end
#
# Make sure we're root
#
if ( ENV["USER"] != "root" )
puts "Run me as root, please"
exit
end
#
# Load the module - which might not be present.
#
Kernel.system( "modprobe fuse 2>/dev/null >/dev/null" )
#
# Setup & run.
#
dir = MySQLDIR.new()
FuseFS.set_root(dir)
FuseFS.mount_to "/mysql", "allow_other"
FuseFS.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment