If you’re like me and installed Fedora in a VirtualBox by just clicking through defaults you’ll find that when you try to do anything you’ve setup a box with very little disk space. At least in my case I ended up with a virtual hard drive with 8G max and a root partition with 5.5G allocated. It’s okay though because by blindly clicking through defaults I ended up using LVM2 for that root partition.

So since I have LVM in place I can simply add another disk and extend the logical volume/partition onto it. Easy as cake as they say.

1) Add a disk – this is VirtualBox so shut down the the box and then from settings, storage add another device. I went with 50G this time. Really – you bought developers PCs with only 138G drives in them? Oh well, it’ll expand to use what I need up to that 50G limit.

2) Add an LVM physical volume – startup that machine and then use “fdisk /dev/sdb” to create a partition on the new drive and then “pvcreate /dev/sdb1″

3) Add that physical volume to my volume group. I didn’t know the name of that volume group so “vgs” showed me that it is vg_machinename and then “vgextend vg_machinename /dev/sdb1″

4) Extend the logical volume to increase take advantage of some of that newly available space. I wasn’t sure of the logical volume name so “df” showed me that it is /dev/mapper/vg_machinename-lv_root and so “lvextend -L50G /dev/mapper/vg_machinename-lv_root” and I’m good right? Well sort of. The logical volume is bigger but the filesystem is still the same size.

5) Extend the file system over that new larger logical volume. Since it’s mounted on / I can’t unmount so shutdown and boot off of the live CD image I used to install. Then “e2fsck -f /dev/mapper/vg_machinename-lv_root” followed by “resize2fs /dev/mapper/vg_machinename-lv_root”.

6) Unmount the CD image, reboot and voila – lots more elbow room.

Not exactly an end user kind of operation but not a horrible ordeal either and all without losing the stuff I had on there already. The same basic process should work for other distributions as long as you’re using LVM2 and ext4 as the filesystem though the naming will likely be somewhat different.

Dec 162010

So I have a model that uses an integer to track it’s state which can be one of several predetermined states – proposed, accepted, rejected – which I’ve mapped to an integer. I’ve used ruby magic to make lots of syntactically pretty methods so that I can do things like @proposal.accepted? and can transition it like @proposal.rejected!. It’s all data driven so that I can add new states easily. Off the top of my head:

@@states = {1 => 'Proposed', 2 => 'Accepted', 3 => 'Rejected'}
 
@@states.each_pair do |k,v|
  define_method "#{v.downcase}?" { self.state_id == k }
  define_method "#{v.downcase}!" { self.state_id = k }
end

That’s all great but in a related table I find the need to select only related objects of a certain state. What I initially got is something like this:

has_many accepted_proposals  ... conditions => 'proposals.state_id = 2'

Now if there’s one thing I’ve learned to hate it’s magic numbers sprinkled around the code. What I want is to write something like:

has_many accepted_proposals ... conditions => ['proposals.state_id = ?', Proposal.accepted_state_id]

And so I tried to define it like my other useful utility methods except … you can’t use define_method to make a class method, only an instance method. I didn’t like this but then while discussing it with a colleague I had the thought – method_missing! I’ve never had cause to use to use it before but the idea is pretty simple. Insert your own code that can pattern match against a method name that isn’t previously defined and do something useful. And what you end up with is something like this:

@@state_ids = Hash.new
@@states.each_pair do |k,v|
  @@state_id[v.downcase] = k
end
 
def self.method_missing(method_sym, *arguments, &block)
  if method_sym.to_s =~ /^(.*)_state_id$/
    @@state_ids[$1]
  else
    super
  end
end

So adding a new state to the class variable effectively gives me 3 automagically generated methods, @proposal.state?, @proposal.state! and Proposal.state_state_id. Very sweet.

Now of course I can do this in a more traditional way with a class method that would look something like Proposal.state_id(‘accepted) but that seems vaguely unsatisfying while the method_missing approach just reeks of awesome.

© 2011 nestoriak.com Suffusion theme by Sayontan Sinha