Posted by
Moser on July 6, 2010
When you encounter a hard disk crash like I did recently (my fault – dropped my laptop), one of the most important files to restore is your GnuPG private key ring or at least a revocation certificate for your public key(s). I did not have any backup
. But at least I had created a revocation certificate, which was now hidden somewhere on my unmountable partition.
Scalpel, a file carving tool, helped me out.
There is a Ubuntu package (and I believe there should be packages for most distributions):
sudo apt-get install scalpel
It’s configuration is in /etc/scalpel/scalpel.conf. It offers some GPG related rules, but none for a revocation certificate. I used these rules:
revoc y 100000 -----BEGIN\040PGP\040PUBLIC\040KEY\040BLOCK-----\x0aVersion:\040GnuPG\040v1.4.10\040(GNU/Linux)\x0aComment:\040A\040revocation\040certificate\040should\040follow
revoc y 100000 -----BEGIN\040PGP\040PUBLIC\040KEY\040BLOCK-----\x0aVersion:\040GnuPG\040v1.4.9\040(GNU/Linux)\x0aComment:\040A\040revocation\040certificate\040should\040follow
revoc y 100000 -----BEGIN\040PGP\040PUBLIC\040KEY\040BLOCK-----\x0aVersion:\040GnuPG\040v1.4.8\040(GNU/Linux)\x0aComment:\040A\040revocation\040certificate\040should\040follow
I wasn’t quite sure which version of GPG I had installed at the time I created the keys, so I created rules for all possible versions. (See manpage for syntax explanation.)
It took about 2 hours to scan the image of my 250 GB hard drive and scalpel successfully restored my revocation certificate.
I also tried some of the supplied rules but I think they are not suitable for restoring files from an image of a whole hard drive. (Most of them just look for two bytes that mark the beginning of the file.)
Posted by
Moser on February 9, 2010
I did a little performance test to find out which database to use in a JRuby desktop application. To have a comparison value I also ran the test (insert, find+update, destroy each 500 times) with MRI and the native sqlite3 driver. It revealed that the jdbcsqlite3 adapter is really sloooooooooow:
$ ruby test.rb sqlite3
user system total real
insert 0.4500 0.0900 0.5400 ( 7.303116)
find and update 0.4900 0.1400 0.6300 ( 6.984390)
destroy 0.3300 0.1100 0.4400 ( 7.261199)
$ jruby test.rb jdbcsqlite3
user system total real
insert 17.2500 0.0000 17.2500 ( 17.250000)
find and update 16.3270 0.0000 16.3270 ( 16.327000)
destroy 15.0900 0.0000 15.0900 ( 15.089000)
$ jruby test.rb h2
user system total real
insert 1.9320 0.0000 1.9320 ( 1.932000)
find and update 0.7800 0.0000 0.7800 ( 0.780000)
destroy 0.3180 0.0000 0.3180 ( 0.318000)
That’s what I call an easy decision.
My setup can be downloaded here.
Posted by
Moser on February 7, 2010
There is a important difference between the two block syntaxes in Ruby: Their precedence.
Consider following code:
def method1(*args)
puts "method1 got a block" if block_given?
end
def method2(*args)
puts "method2 got a block" if block_given?
end
method1 method2 do
end
method1 method2 {
}
You would expect both method calls to produce the same result, wouldn’t you?
Output:
method1 got a block
method2 got a block
Obviously the do-end block is passed to the first method in the expression while the {} block is passed to the method called directly before it.
Another example shows that the assignment does not count as a method call here:
#[...]
class Foo
def bar=(o)
puts "Foo#bar= got a block" if block_given?
end
end
foo = Foo.new
foo.bar = method1 method2 do
end
#method1 got a block
foo.bar = method1 method2 {
}
#method2 got a block
Posted by
Moser on January 8, 2010
Under the impression of loosing some really important data because of a damaged partition table on a USB flash drive I am developing a backup strategy for my system.
I know myself and so I decided that I need to automate this. While trying to figure out how one can run a script as soon as a specific drive is mounted, I came across DeviceKit. It’s the planned replacement of HAL and is used in Ubuntu Karmic. Udev is not an option for me, because I don’t want to mess around with mounting myself (and I hate running stuff as root…).
So here is what I found out about using DBus and DeviceKit in Python:
import dbus
bus = dbus.SystemBus()
proxy = bus.get_object("org.freedesktop.DeviceKit.Disks",
"/org/freedesktop/DeviceKit/Disks")
iface = dbus.Interface(proxy, "org.freedesktop.DeviceKit.Disks")
#enumerates all devices
print iface.EnumerateDevices()
#gets the device kit path of a specific device
path = iface.FindDeviceByDeviceFile("/dev/sdc1")
#= "/org/freedesktop/DeviceKit/Disks/devices/sdc"
#gets an object representing the device specified by the path
device = bus.get_object("org.freedesktop.DeviceKit.Disks", path)
#prints some XML that shows you the available methods, signals and properties
print device.Introspect()
#gets a proxy for getting properties
device_prop = dbus.Interface(device, "org.freedesktop.DBus.Properties")
#you need to specify an interface (properties could be ambiguous)
print device_prop.Get("org.freedesktop.DeviceKit.Disks.Device", "device-mount-paths")
#gets a proxy you can call methods on
device_iface = dbus.Interface(device, "org.freedesktop.DeviceKit.Disks.Device")
#unmounts the partition
device_iface.FilesystemUnmount(dbus.Array([], 's'))
The DBus API of DeviceKit is documented here.
Now we want to be notified when a drive is mounted:
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop
def device_added_callback(device):
print 'Device %s was added' % (device)
def device_changed_callback(device):
print 'Device %s was changed' % (device)
#must be done before connecting to DBus
DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
proxy = bus.get_object("org.freedesktop.DeviceKit.Disks",
"/org/freedesktop/DeviceKit/Disks")
iface = dbus.Interface(proxy, "org.freedesktop.DeviceKit.Disks")
#addes two signal listeners
iface.connect_to_signal('DeviceAdded', device_added_callback)
iface.connect_to_signal('DeviceChanged', device_changed_callback)
#start the main loop
mainloop = gobject.MainLoop()
mainloop.run()
A typical output when a flash drive is plugged in looks like this:
Device /org/freedesktop/DeviceKit/Disks/devices/sdc was added
Device /org/freedesktop/DeviceKit/Disks/devices/sdc1 was added
Device /org/freedesktop/DeviceKit/Disks/devices/sdc1 was changed
With this knowledge I’m currently working on a little python script that runs in background and executes a shell script when a file system is mounted. I’ll post it, when it’s finished
Posted by
Moser on October 20, 2009
Sequel’s STI is not so well documented as ActiveRecord’s is. Because it cost me about 20 minutes to find out about it’s syntax, I post a little example.
class A < Sequel::Model
plugin :single_table_inheritance, :object_type
end
class B < A
end
The second argument is the name of the column to be used to store the class name in DB. Don’t use ‘type’ here, it collides with Ruby’s Object#type.
This works with version 3.5.0 and should work with any version >= 2.12.0.