alex's blog

Adding more disk space to an LVM-based partition in Red Hat 5

In this example, I have a Red Hat 5 VM running in VMWare Fusion on a MacBook Pro. The '/' partition is on a single LVM logical volume. I want to increase its size from 20GB to 25GB. If you're not using LVM, try these instructions instead : http://www.howtoforge.com/linux_resizing_ext3_partitions_p2

Here's the problem:

[root@rhel5-oracle ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                       19G   18G  6.2M 100% /
/dev/sda1              99M   18M   77M  19% /boot
tmpfs                 506M     0  506M   0% /dev/shm

First step is to shut down the VM and give it more disk space via the VMWare 'Settings' panel. In this example, I just added space to the existing single virtual disk, but you could just as well create a separate virtual disk. The instructions below work just as well if you've got a non-virtual OS which you want to add more real physical storage to.

Then boot the VM again, and do the following in the guest OS.

fdisk /dev/sda

Create a new partition for the newly available space.

## Check what you're starting with.
Command (m for help): p

Disk /dev/sda: 26.8 GB, 26843545600 bytes
255 heads, 63 sectors/track, 3263 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14        2610    20860402+  8e  Linux LVM

## Create the new partition
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (2611-3263, default 2611):
Using default value 2611
Last cylinder or +size or +sizeM or +sizeK (2611-3263, default 3263):
Using default value 3263

## Make it LVM
Command (m for help): t
Partition number (1-4): 3
Hex code (type L to list codes): 8e
Changed system type of partition 3 to 8e (Linux LVM)

## Double-check
Command (m for help): p

Disk /dev/sda: 26.8 GB, 26843545600 bytes
255 heads, 63 sectors/track, 3263 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14        2610    20860402+  8e  Linux LVM
/dev/sda3            2611        3263     5245222+  8e  Linux LVM

## Commit your changes
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.

Now reboot the VM and proceed. Online resizing of ext3 is supported in 2.6 kernels, so you don't even need to use Knoppix or some other CD-based distro.

[root@rhel5-oracle ~]# pvcreate /dev/sda3
  Physical volume "/dev/sda3" successfully created
[root@rhel5-oracle ~]# vgextend VolGroup00 /dev/sda3
  Volume group "VolGroup00" successfully extended
[root@rhel5-oracle ~]# lvextend -L+5G /dev/VolGroup00/LogVol00
  Extending logical volume LogVol00 to 23.88 GB
  Logical volume LogVol00 successfully resized
[root@rhel5-oracle ~]# resize2fs /dev/mapper/VolGroup00-LogVol00

And here's the final outcome...

[root@rhel5-oracle ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                       24G   18G  4.6G  80% /
/dev/sda1              99M   18M   77M  19% /boot
tmpfs                 506M     0  506M   0% /dev/shm

Determine which process is listening on a TCP port in Linux

Note to self...

[root@rhel5-oracle ~]$ lsof -i tcp:1521 -nP
COMMAND  PID   USER   FD   TYPE DEVICE SIZE NODE NAME
tnslsnr 5640 oracle   10u  IPv4  11104       TCP *:1521 (LISTEN)
tnslsnr 5640 oracle   12u  IPv4  11424       TCP 127.0.0.1:1521->127.0.0.1:10948 (ESTABLISHED)
oracle  5742 oracle   16u  IPv4  11423       TCP 127.0.0.1:10948->127.0.0.1:1521 (ESTABLISHED)

Which environment is it, really?

Rails uses the environment variable $RAILS_ENV to control which set of configuration files should be loaded. This includes, among many other things, what database to connect to. I tend to have lots of terminal windows open, doing several things at once. There are lots of circumstances where it's useful to switch to a different Rails environment for some tasks. The danger here, though, is that plenty of things you might do in a personal local development environment aren't at all safe to do in a production environment. (Dropping and re-loading test data into the production database is a particular no-no.)

I used to frequently echo $RAILS_ENV to check what a particular terminal window was set to. The trouble is it's easy to forget to do this. Having multiple terminals in multiple environments becomes a time bomb waiting to go off.

The solution I cooked up is to add some information about my $RAILS_ENV right in the terminal prompt. The concept is pretty simple, but getting the particular bash incantation correct took some doing. Adding this to your .profile in OSX will give you a colored prompt. Green for 'development', and red for any other environment. Should be pretty easy to fine-tune for your specific needs.

export RAILS_ENV=development
export PS1='`if [ "$RAILS_ENV" == "development" ]; then echo -n "\[\033[01;32m\]"; else echo -n "\[\033[01;31m\]"; fi;`$RAILS_ENV:\[\033[01;34m\]\w\[\033[00m\]\$ '

Here's what it looks like in action:

rails_terminal_prompt

I do most of my work in OSX 10.5, which uses GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0). I suspect this could be tweaked to work in more versions of bash.


Put some Swedish Chef in your Ruby app!

I wrote a Ruby port of a PHP class I found which will 'translate' English strings to Swedish Chef. I posted the Cheferizer code to GitHub a few days ago, so go crazy. Many thanks to Erik Bakker, the author of the encheferizer.php class I used as a model. He, in turn, gives credit to John Hagerman as the original author of the Chef-ing algorithm he implemented. All the URLs cited in that source code were dead, so I don't link to them here, but I am grateful for the inspiration. Maybe the whole world has moved beyond being entertained by silly stuff like this, but I sure hope not.

include 'cheferize'
class String
  include Cheferize
end

>> "This is a test!".to_chef
=> "Tees is e test, bork bork bork!"

Here's a slightly longer example of the time you can waste paying tribute to a personal hero... First the original English.

Cheferize is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

Cheferize is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Cheferize; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

And now, enter the Chef.

Cheffereeze-a is free-a sufftvere; yuoo cun redeestriboote-a it und/ur mudeeffy
it under zee terms ooff zee GNU Generel Poobleec Leecense-a es poobleeshed by
zee Free-a Sufftvere-a Fuoondeshun; ieezeer ferseeun 2 ooff zee Leecense, oor
(et yuoor oopshun) uny leter ferseeun.

Cheffereeze-a is deestribooted in zee hupe-a tet it veell be-a useffool,
boot VITOUT UnY VERRUnTY; veetuoot ifee zee impleeed verrunty ooff
MERCHUnTEBILITY oor FITNESS FOR E PERTICULER PURPOSE. See-a zee
GNU Generel Poobleec Leecense-a fur mure-a deteeels.

Yuoo shuoold hefe-a receeefed e cupy ooff zee GNU Generel Poobleec Leecense-a
elung veet Cheffereeze; iff nut, vreete-a tu zee Free-a Sufftvere-a
Fuoondeshun, Inc., 51 Frunkleen St, Feefft Fluur, Bustun, MA 02110-1301 USA

Read data in an ActiveRecord-based Rails session

Here's a simple method you can use in a console to determine the contents of an existing Rails session. All you need is the session id.

def read_session( sess_id )
  result = ActiveRecord::Base.connection.select_all( "SELECT * FROM sessions WHERE session_id = '#{sess_id}'" )
  Marshal.restore( Base64.decode64( result[ 0 ][ 'data' ] ) ) if result[ 0 ]
end

The return value will be a Hash, or nil if no session is found for that id.

Note this doesn't do any input-escaping, so it's open to SQL injection. Don't expose this code to users. (That's a good idea for lots of reasons, given what it does.)

Suppose you want to just watch a particular session in your console...

def report_session( sess_id )
  i = 0
  while true
    puts "#{i} : #{read_session( sess_id ).inspect}"
    i += 1
    sleep 1
  end
end

$ script/console
Loading development environment (Rails 2.2.2)
>> report_session 'a3fbc5de20723a242b54a73cad4221bb'
0 : {"flash"=>{}}
1 : {"flash"=>{}}
2 : {"flash"=>{}}
3 : {"flash"=>{}}
...

It'll keep updating with session data until you kill it with Control-c.

Automatic Per-Controller CSS in Rails

This is a simple method I've been using to automatically include controller-specific stylesheets. If you have app/controllers/users_controller.rb, then public/stylesheets/users.css will be included automatically if it exists. I'm sure this has been done before, but here's my take on it.

# app/helpers/application_helper.rb
module ApplicationHelper
  def controller_stylesheet
    controller_name = controller.controller_name
    if File.exists?( "#{Rails.root}/public/stylesheets/#{controller_name}.css" )
      stylesheet_link_tag( controller_name )
    end
  end
end

<!-- app/layouts/application.html.erb -->
<html>
  <head>
    <%= controller_stylesheet %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

Installing Darwin Calendar Server 2.3 on Ubuntu 9.10

Back in my original 'calendarserver on Linux' posting, I wrote about how to set up Apple's Darwin Calendar Server (DCS) on Ubuntu Linux. At the time, I neglected to mention that was Ubuntu 8.10. This turns out to be important, because I have since built a new server using Ubuntu 9.10 and discovered some important differences in the new Ubuntu.

The art of not losing things

My wife is better at finding things than I am. I am better at not losing things than she is. It's an important difference.

Being good at 'finding things' means she's more careful when she goes place to place looking for something. She notices details I don't. She thinks of places to look which don't occur to me.

Being good at 'not losing' things means I tend to put stuff back in the same place every time. Sara is constantly losing her keys, purse, or cell phone because she tends to drop them wherever, then go looking for them later. I tend to put stuff back in one place. (Notice I say *tend to*. I'm definitely not claiming any perfection here. I need her help plenty of times finding stuff I've stupidly dropped in some random place...) I developed the habit because, as mentioned above, I'm not very good at looking for things. This is my way of working around my own lack of search skill.

Whenever I have something in my hands which I no longer want to be holding, I tend to ask the question "where is the first place I'd look for this thing?" Whichever place first comes to mind is the place where I put the thing. Not perfect, but a lot better that before, when I combined the 'drop stuff anywhere' storage strategy and the 'carelessly and unproductively scan for things' search algorithm.

Why does this matter in the context of a blog about coding? I think the same rules about 'where to put things' apply really well to software or database design. 'How do I want to search for this?' should play a large part in 'how should I store this data?'.

Of course there are plenty of other concerns. For example, tailoring a database schema too closely to a single kind of search often reduces the ease with which you can perform other kinds of searches of that data. But 'how will I search for this stuff' should be *part* of the design process. And, if you can't answer that question at all, I think it's worth asking 'do I really need to store this data at all?'

Opting Out of Verizon's DNS Services

Got weird error trying to access www.google.com.

No Googles!

Co-worker helped me figure out this was Verizon's 'DNS Assistance' messing up.
http://www.verizon.net/central/vzc.portal?_nfpb=true&_pageLabel=vzc_help...

Tried their 'opt out' option. Visiting a non-existent domain brings up an incredibly lame error page. The page you see below is HTML copy/pasted from the standard Internet Explorer page (including image references to 'C:\...'), with some Verizon links slapped on the end of it. Wow.

Verizon DNS Assistance Fail.

What the heck?

I switched to 4.2.2.1 and 4.2.2.2, but there are plenty of other public DNS providers. This is kinda funny since 4.2.2.1 is also a Verizon server, but it doesn't have this annoying 'helpful' feature.

http://www.tech-faq.com/public-dns-servers.shtml


Our Smart President

Just read a story about the Obama administration using the Drupal CMS for whitehouse.gov. Maybe we can say they're learning from us here at Deanspot?

http://techpresident.com/blog-entry/whitehousegov-goes-drupal

http://www.drupal.org

DRY? How about DROP?

The acronym DRY is popular with Rails folks, and maybe elsewhere. Don't Repeat Yourself. If you see two sections of your code doing essentially the same thing, create a single method which is called from those two places. Less code, less maintenance, better test coverage, less chance for errors later on. In database terminology, I'd talk about eliminating redundancy and avoiding update anomalies. It's the same thing. It's great advice, and clearly captures a bit of wisdom that (I'd venture to say) is applicable to most any kind of programming.

In addition to not repeating yourself, though, how about Don't Repeat Other People? Open source is all about scratching your own itch, so if you're driven to solve an old problem in a new way, go for it. But think first about why you're doing it.

Consistent Tab Navigation in OSX

Tab navigation is one area where the OSX user experience seriously lacks consistency. It seems like every application implements a different keyboard shortcut for 'next tab' and 'previous tab'. I am a person who uses lots of tabs in many different programs, and I prefer to do as much as possible from the keyboard. Reaching back and forth from keyboard to mouse is a pain. The fact that it's a different key combination in every application is a serious annoyance.

I've taken things into my own hands and tried to hack some consistency out of this keyboard jungle.

Compiling Ganglia gmond and gmetad on OSX 10.5

Ganglia is a set of daemons used for performance monitoring. It works on OSX, but getting it running on that platform can be a bit touchy. Here's the series of steps which have worked for me recently.

Note : I'm writing this for those who already knows what Ganglia is, and want to get it running on OSX. There are lots of other articles out there describing Ganglia, what it's used for, and offering more detailed configuration information.

Looking for Rails help?

Well, if you're reading this, you probably know me, so just ask me directly. Otherwise, try Rails Mentors, a new site that's just been launched to connect experienced and newer programmers.

Posting to Drupal from an iPhone via SMS

Why?

Why do I want to do this? The iPhone allows you to send regular emails, and the MailHandler Drupal module already allows you to submit content via email. This is about 90% of what I want. I'm going to be driving cross-country, and in many places I'll have phone reception but no data service. SMS requires only normal cell reception, not Edge/3G/etc data coverage, so this is pretty important for me.

Why don't I just use Twitter? That's harder to answer. Mainly, DIY is more fun.

So, all objections being skillfully silenced, here's what I did...

Programming & Professionalism

The post below is a response to a talk given at the recent RailsConf, about professionalism and programming. There's a bit of profanity, so don't read if you're easily offended. If you don't have any such unreasonable hangups, I think there are a lot of excellent ideas here.

http://gilesbowkett.blogspot.com/2009/05/what-killed-smalltalk-my-balls....

Making Donuts

External Hard Drive for Sale

http://phoenix.craigslist.org/evl/sys/1104192621.html

Free delivery for family and friends!

Sold! To the man in the funny hat. Yes, you sir, you in the back.

Easy way to list public methods for a Ruby object

I often have new code I'm trying to figure out, and constantly jumping back and forth between a console and a web browser with documentation sometimes really slows me down. Often times it's easy enough to remember which method you want just by seeing a list, even without detailed descriptions.

Any object has a public_methods method, which returns an array of strings listing the commands. Trouble is, all the methods it inherits are of course listed in there, and Object provides a LOT of stuff. It's easy for the interesting stuff about the instance at hand to get lost in that noise.

So, I'm trying a little experiment. I added this snippet to my ~/.irbrc file. Works on Linux and OSX, and in either normal irb or in the Rails console.

class Object
  # print public methods which are not inherited from Object
  def pm
    (self.public_methods - Object.public_methods).sort
  end
end
Now any object has a pm method. So what?

Loading development environment (Rails 2.2.2)
>> class Blah
>>   def foo; end
>>   def bar; end
>>   def blatz; end
>> end
=> nil
>> b = Blah.new
=> #<Blah:0x12b6b04>
>> b.pm
=> ["bar", "blatz", "foo"]
>> b.public_methods
=> ["returning", "to_yaml", "pretty_print_cycle", "inspect", "method_exists?", "stubs", "to_param", "extend_with_included_modules_from", "subclasses_of", "require_or_load", "clone", "method", "to_enum", "to_yaml_properties", "public_methods", "__metaclass__", "to_json", "suppress", "instance_variable_defined?", "instance_variable_names", "dclone", "equal?", "blatz", "freeze", "expects", "with_options", "foo", "methods", "respond_to?", "geometry_data_types", "instance_exec", "enable_warnings", "to_matcher", "to_query", "silence_warnings", "reset_mocha", "to_c", "dup", "enum_for", "instance_variables", "__id__", "copy_instance_variables_from", "duplicable?", "eql?", "object_id", "pretty_inspect", "require", "id", "send", "singleton_methods", "silence_stderr", "encode64", "class_eval", "taint", "taguri", "require_association", "stubba_method", "instance_variable_get", "frozen?", "instance_of?", "__send__", "require_library_or_gem", "b64encode", "to_a", "pretty_print", "taguri=", "daemonize", "remove_subclasses_of", "`", "type", "debugger", "blank?", "instance_eval", "protected_methods", "display", "==", "silence_stream", "unloadable", "decode64", "===", "acts_like?", "pm", "c", "to_yaml_style", "instance_variable_set", "extend", "kind_of?", "to_s", "extended_by", "class", "hash", "breakpoint", "present?", "mocha", "private_methods", "=~", "tainted?", "decode_b", "mocha_inspect", "instance_values", "untaint", "nil?", "load_with_new_constant_marking", "__is_a__", "bar", "stubba_object", "pretty_print_inspect", "require_dependency", "is_a?", "pretty_print_instance_variables", "metaclass"]

See the difference? Call it micro-documentation.

Installing Apple's calendarserver on Ubuntu

Update : 12 Dec 2009

I've added a new post describing how to install Darwin Calendar Server (aka DCS, aka Apple's Calendar Server) from source on Ubuntu 9.10.


I've wanted to have a shared family calendar for a while. We've tried paper calendars. They never got updated, and moving things around was a pain. Sara may disagree with me, she still prefers a regular paper datebook. But the ability to remind each other of when various things are scheduled is really better in the electronic world. My work uses calendarserver (part of OSX Server) to schedule meetings, and combined with a client program like iCal, it's a great system. Just because it's Apple, though, doesn't mean it's only available for Mac users. Programs like Outlook for Windows or Evolution for linux can also subscribe to calendars published by calendarserver. You can find a partial list of compatible clients at http://trac.calendarserver.org/wiki/CalendarClients, but any program which can speak CalDAV should work fine.

CalendarServer is, itself, freely available. You don't need a Mac server, and you don't have to buy OSX. It's written in Python, so it runs on pretty much any platform, and is distributed under an MIT license. It's even available via apt in recent Ubuntu releases, which makes it really really easy to set up if you have an Ubuntu machine handy. These are some quick notes about how I configured this for our local network.

Syndicate content