start ruby+sinatra keep server
authorTom Clegg <tom@clinicalfuture.com>
Wed, 24 Apr 2013 00:22:32 +0000 (17:22 -0700)
committerTom Clegg <tom@clinicalfuture.com>
Wed, 24 Apr 2013 00:23:42 +0000 (17:23 -0700)
services/keep/INSTALL [new file with mode: 0644]
services/keep/keepd [new file with mode: 0755]

diff --git a/services/keep/INSTALL b/services/keep/INSTALL
new file mode 100644 (file)
index 0000000..e30b29a
--- /dev/null
@@ -0,0 +1,6 @@
+rvm use 1.9.3
+gem install sinatra
+gem install getopt
+
+mkdir -p /some-mount-point/keep
+./keepd
diff --git a/services/keep/keepd b/services/keep/keepd
new file mode 100755 (executable)
index 0000000..b006afb
--- /dev/null
@@ -0,0 +1,82 @@
+#!/usr/bin/env ruby
+
+require 'getopt/long'
+include Getopt
+$opt = Long.getopts(
+                   ["--debug", "-d", BOOLEAN],
+                   ["--port", "-p", OPTIONAL],
+                   ["--root-dir", "-r", OPTIONAL]
+                   )
+default_opt = {
+  'port' => 25107,
+  'root-dir' => '/'
+}
+$opt = default_opt.merge $opt
+
+ARGV.reject! { |x| true }    # prevent sinatra from trying to parse it
+require 'sinatra'
+
+# Configure sinatra server
+set :port, $opt['port'].to_i
+configure do
+  mime_type :binary, 'application/octet-stream'
+end
+
+def debuglog(loglevel, msg)
+  if $opt['debug'] or loglevel < 2
+    $stderr.puts "[keepd/#{$$} #{Time.now}] #{msg}"
+  end
+end
+
+# Configure backing store directories
+keepdirs = []
+rootdir = $opt['root-dir'].sub(/\/+$/, '')
+`mount`.split("\n").each do |mountline|
+  dev, on_txt, mountpoint, type_txt, fstype, opts = mountline.split
+  if on_txt == 'on' and type_txt == 'type'
+    debuglog 2, "dir #{mountpoint} is mounted"
+    if mountpoint[0..(rootdir.length)] == rootdir + '/'
+      debuglog 2, "dir #{mountpoint} is in #{rootdir}"
+      keepdir = "#{mountpoint.sub /\/$/, ''}/keep"
+      if File.exists? "#{keepdir}/."
+        keepdirs << { :root => "#{keepdir}", :readonly => false }
+        if opts.gsub(/[\(\)]/, '').split(',').index('ro')
+          keepdirs[-1][:readonly] = true
+        end
+        debuglog 1, "keepdir #{keepdirs[-1].inspect}"
+      end
+    end
+  end
+end
+
+get '/:locator' do |locator|
+  regs = locator.match /^([0-9a-f]{32,})/
+  if regs
+    hash = regs[1]
+    subdir = hash[0..2]
+    found = false
+    keepdirs.each do |keepdir|
+      backfile = "#{keepdir[:root]}/#{subdir}/#{hash}"
+      if File.exists? backfile
+        data = nil
+        File.open("#{keepdir[:root]}/lock", "a+") do |f|
+          if f.flock File::LOCK_EX
+            data = File.read backfile
+          end
+        end
+        if data
+          found = true
+          content_type :binary
+          body data
+          break
+        end
+      end
+    end
+    if not found
+      status 404
+      body 'not found'
+    end
+  else
+    pass
+  end
+end