Stop. Emacs Time.

October 3rd, 2008

I decided to get all crazy and re-theme my blog based on my favorite editor. It's still got a couple of rough edges, but it's coming along. Please comment with any strangeness.

Windy City Rails Wrap-up

September 23rd, 2008

Saturday’s Windy City Rails event was great! There were some great talks and good conversation. I would like to thank Chicago Ruby along with the conference organizers who made all of this possible.

You can download slides for my sleight of hand and my security talk in the previous links.

Speaking at Windy City Rails

August 20th, 2008

I just got word from the tribal council at the Windy City Rails conference that they have accepted two of my proposals. I will be giving my RailsConf 2008 talk “De-Railing: Smashing the Rails Stack” along with “Sleight of Hand for the Ruby Man”. The De-Railing talk is a security focused session on steps to take to ensure that your Rails application has what it needs to keep data safe from attackers. The Sleight of Hand talk is a session on metaprogramming tips, tricks, and pitfalls with Ruby and with Rails. Stay tuned for more info closer to the September 20th conference date.

Adventures in Clojure: Getting Started

August 16th, 2008

Following Stu’s series on Java.next I decided to take a look into clojure. Clojure is a pretty cool language. It’s a lisp dialect that runs on the JVM. This is cool for a couple of reasons. First, you get all the advantages of the jvm. Second, you get the advantage of interoperability with java libraries. I am not necessarily excited about the later, nonetheless, there are still advantages to having solutions to problems that you can use to quickly get things done.

Although clojure has a nice website with decent language descriptions and a helpful wiki, getting started can leave you a little wanting. Here’s a more precise setup guide to get you going. I am using Ubuntu Hardy on my desktop PC so this guide will be geared towards it.

First, let’s install the necessary base libraries

1
2
3

% sudo apt-get install sun-java6-jdk maven2 subversion

Now let’s check out the clojure source and build it

1
2
3
4
5

% svn co https://clojure.svn.sourceforge.net/svnroot/clojure/trunk clojure
% cd clojure
% mvn install

When maven gets finished you should end up with a shiny new jar in the target dir of the clojure source directory. Now to test this out let’s try the following from inside the clojure directory.

1
2
3
4
5

% java -cp target/clojure-lang-1.0-SNAPSHOT.jar clojure.lang.Repl
Clojure
user=> 

Now that we have the basics setup we need to get our environment setup for real programming. The first enhancements come to the repl. It would be nice to have command completion, parenthesis matching (this is lisp after all), history across sessions, and last but not least editor hooks. The wiki suggests both JLine and rlwrap. JLine is ok, but lacking in the ability to do command completion and some other goodies. That being said let’s install rlwrap so that we get the most out of our environment.

1
2
3

% sudo apt-get install rlwrap

Next we need to create a script to make launching the clojure environment a little bit easier. Here’a a script from the wiki to help us out.

1
2
3
4
5
6
7
8
9
10
11
12

#!/bin/bash
BREAK_CHARS="(){}[],^%$#@\"\";:''|\\"
CLOJURE_DIR=/usr/local/clojure
CLOJURE_JAR=$CLOJURE_DIR/target/clojure-lang-1.0-SNAPSHOT.jar
if [ -z "$1" ]; then
    rlwrap --remember -c -b $BREAK_CHARS -f /home/abedra/.clj_completions \
        java -cp $CLOJURE_JAR clojure.lang.Repl
else
    java -cp $CLOJURE_JAR clojure.lang.Script $1
fi

As you can see I moved the clojure directory to /usr/local/. I also had to modify the path to the .clj_completions file. Just copy this script, save it, chmod +x, and move it to /usr/local/bin/. Make sure you properly modify the paths. Last, just go ahead a create an empty file at ~/.clj_completions. We will populate that next. Let’s use this script to populate the .clj_completions.

1
2
3
4
5
6
7
8
9

(defmacro with-out-file [pathname & body]
  `(with-open stream# (new java.io.FileWriter ~pathname)
     (binding [*out* stream#]
       ~@body)))

(def completions (keys (ns-publics (find-ns 'clojure))))
(with-out-file "clj-keys.txt" (doseq x completions (println x)))

Save this code as clj-completions.clj. Now simply run the script.

1
2
3

% clj clj-completions.clj

Once it’s finished you’ll end up with a file named clj-keys.txt. Simply move that file to ~/.clj_completions and you are ready to rock. Now let’s test out our new hotness. Once you invoke clj try typing in some code and pressing tab. You should get something like this.

Now you are ready to get programming! Stay tuned for more adventures in clojure.

Upgrades

July 8th, 2008

I just updated to the current git master version of mephisto. I was running an old version of 7.3, so if anything is out of whack please shoot me a message and let me know. I am working on getting the syntax highlighting working again, it was suffering from some boundary issues.

Sleight of Hand for the Ruby Man

June 12th, 2008

Chad Humphries pointed me to this tasty bit of code. Since Ruby so graciously lets you open up classes anywhere, it’s nice to know where the right place to debug is. Simply put the following code into a globally accessible place (I just used .irbrc) and you will have the method available.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

module Kernel

  # which { some_object.some_method() } => <file>:<line>:
  def where_is_this_defined(settings={}, &block)
    settings[:debug] ||= false
    settings[:educated_guess] ||= false
    
    events = []
    
    set_trace_func lambda { |event, file, line, id, binding, classname|
      events << { :event => event, :file => file, :line => line, :id => id, :binding => binding, :classname => classname }
      
      if settings[:debug]
        puts "event => #{event}"
        puts "file => #{file}"
        puts "line => #{line}"
        puts "id => #{id}"
        puts "binding => #{binding}"
        puts "classname => #{classname}"
        puts ''
      end
    }
    yield
    set_trace_func(nil)

    events.each do |event|
      next unless event[:event] == 'call' or (event[:event] == 'return' and event[:classname].included_modules.include?(ActiveRecord::Associations))
      return "#{event[:classname]} received message '#{event[:id]}', Line \##{event[:line]} of #{event[:file]}"
    end
    
    # def self.crazy_custom_finder
    #  return find(:all......)
    # end
    # return unless event == 'call' or (event == 'return' and classname.included_modules.include?(ActiveRecord::Associations))
    # which_file = "Line \##{line} of #{file}"
    if settings[:educated_guess] and events.size > 3
      event = events[-3]
      return "#{event[:classname]} received message '#{event[:id]}', Line \##{event[:line]} of #{event[:file]}"
    end
    
    return 'Unable to determine where method was defined.'
  end

end

Once you have that you can simply open up script/console or irb and give it a whirl

1
2
3

>> where_is_this_defined {Streamlined.ui_for(:foo)}
=> "Streamlined received message 'ui_for', Line #6 of /Users/abedra/src/someapp/trunk/lib/extensions/streamlined/streamlined.rb"

This tells us that the ui_for method of streamlined is actually being called from an extension that the project made rather than the streamlined plugin itself. This would save you lots of time trying to debug the wrong method! Give it a try.

Rails on OpenBSD 4.3

June 7th, 2008

OpenBSD released version 4.3 of their OS on May first. This version is especially exciting because there has been considerable effort made by the ports contributors to get the Rails stack up to date. This makes setting up a server with OpenBSD considerably easier than my last set of posts regading deploying with OpenBSD. A few things have changed, but the idea is the same, so I will run through a full stack setup from a scratch install. If you need information on installing OpenBSD there is a great tutorial that will get you started.

Post Install

You will be greeted with a vanilla install and not a whole lot to work with. Let’s get some basic sytem tools installed. We will use OpenBSD’s pkg_add tool to get us up and running quickly. The stack we will setup will include:

  • Helpful system tools
  • Ruby / Rails
  • Thin
  • MySQL
  • nginx

Helpful System Tools


# build the locate database
% /usr/libexec/locate.updatedb
# setup pkg_add path for easy installs
% export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.3/packages/i386/
# install bash (optional)
% pkg_add -i bash
% chsh -s bash
# install other needed system tools.  we use pkg_add with the -i
# flag for interactive mode.  this way it will ask you what version
# of a specific software you want if there is more than one available.
% pkg_add -i curl nano subversion git

Ruby / Rails / Thin


% pkg_add -i ruby ruby-iconv ruby-gems
% gem update --system
% gem install rails thin
# if you want to use thin with sockets you will need to install
# eventmachine from source to get version 0.11
% gem install eventmachine --source http://code.macournoyer.com

MySQL


% pkg_add -i mysql-server
% mysql_install_db
# start mysql
% mysqld_safe &

Create the file /etc/rc.conf.local and place the following into it.


mysql="YES" 

Now open up /etc/rc.local and add the following script just before the ending echo ”.”.


if [ X"${mysql}" == X"YES" -a -x /usr/local/bin/mysqld_safe ]; then

    echo -n " mysqld"; /usr/local/bin/mysqld_safe --user=_mysql --log --open-files-limit=256 &

    for i in 1 2 3 4 5 6; do
        if [ -S /var/run/mysql/mysql.sock ]; then
            break
        else
            sleep 1
            echo -n "." 
        fi
    done
fi

This will setup mysql to start when the system boots.

nginx


% pkg_add -i nginx

Then open up /etc/rc.local and add the following after your mysql entry.


if [ -x /usr/local/sbin/nginx ]; then
   echo -n ' nginx'; /usr/local/sbin/nginx
fi

This will setup nginx to start when the system boots. I like to modify my nginx configs a little bit taking a little away from the debian linux apache2 and nginx configs.


% cd /etc/nginx
% mv nginx.conf nginx.conf.orig
% mkdir sites-available
% mkdir sites-enabled
% curl -O http://aaronbedra.com/nginx.conf
% cd sites-available
% curl -O http://aaronbedra.com/vhost

This will enable nginx to automagically load any vhost file that is in sites-enabled. We use the sites-available and sites-enabled directories and symlink from one to another. I prefer this, you don’t have to do this if you already have an nginx setup you like to use. Assuming you followed the above steps the only thing you have left to do is edit the vhost file and add your sites information. I would suggest renaming the vhost file to something a little more descriptive as well. Don’t forget to create the directory in /var/log/nginx/yoursite or nginx will fail to start. Once you have completed that you just need to symlink your new config into sites-enabled and restart nginx.


% ln -s /etc/nginx/sites-available/vhost /etc/nginx/sites-enabled/vhost
# start nginx
% nginx
# restart nginx
% kill -HUP `cat /var/run/nginx.pid`

Post Setup Notes

There is one small problem with eventmachine on OpenBSD. When thin intializes eventmachine at application boot time, it tries to use the wrong eventmachine library. You need to use the pure ruby version. An easy way to fix this is to add the following to your .profile


export EVENTMACHINE_LIBRARY="pure_ruby" 

This will make eventmachine happy and thin able to run. The reason for choosing thin and nginx over the other implementations is because thin can connect to to nginx via sockets, and nginx is just plain easier to configure, not to mention faster. Obviously you can season this setup to taste if you prefer other stack implementations.

Surviving the Reboot

It’s good practice to have a thin config file that can start your application. Let’s take a look at how to configure thin for your app.


% mkdir /etc/thin
% thin config -C /etc/thin/your_config.yml -s2 -S /tmp/thin.sock

This will create a thin config file that will spawn to instances of thin (s2) and use sockets instead of ports. You can change the number of instances it spawns or where you want to put your sockets if you so desire. Now that you have a running system, you just need to add one more thing to make sure that your app starts if your server reboots. To make this work you need to do two things.


% ln -s /usr/local/bin/thin /usr/bin/thin

This will make sure thin is available at boot time. Next you need to add a line in etc/rc.local to start your app. Add this after the other startup scripts you added previously.


echo -n " thin"; thin start -C /etc/thin/your_config.yml

Happy OpenBSD-ing!

Railsconf Talk

June 1st, 2008

Here are the slides from my railsconf talk. Thanks for all of you that showed up and gave support!

Shame on you O'Reilly!

May 30th, 2008

I have a bone to pick with the mensa that decided that it was important to give each Railsconf attendee a badge that had all of their personal information encoded on a barcode on the back side.

From the back of the badge:

“Your name, email address, job title, organization, address and phone number are encoded on this card. Please recycle this card at the end of the conference”

What? Is there a magical card swiper that gives you money and ever lasting happiness? Exactly why do I need to carry around a badge with all that information? Do they really expect me to give it back to someone else for “recycling” at the end of the conference? This is one badge that is going in the shredder!

Refactotum Time!

May 29th, 2008

The crew is doing a tutorial today at Railsconf 2008 in Portland. We will be presenting on contributing to open source projects. There will be a short demo of some of the tips and tricks we use when we are contributing, followed by a couple hours of open time to contribute to your favorite open source projects. Bring your laptop and join the fun! We are going to be focusing on projects hosted with git, so if you haven’t already installed it, now is the time.

Rails Security Audit Peepcode is now Available!

May 28th, 2008

I just finished writing a pdf book for Peepcode Screencasts about security auditing Rails applications. The book covers all the high level concepts needed to properly determine and fix security related problems in your code and on your servers. The contents include:

  • Cross Site Scripting
  • Model Security and SQL Injection
  • Fuzzing Testing / Spidering
  • Server Security
  • Risk Ananlysis

This book is a must have for any serious Rails developer exposing their applications to the web. The best part is you can get your very own copy right now for only $9! Peepcode has also recently released a few more great books, so it might be a good time to pony up for a 5 or even 10 pack and sharpen your development skills.

MBTI Meme

April 25th, 2008

We were sitting around our office talking about our team and the subject of MBTI came up. We started talking about ourselves and how we should be putting together teams for our various projects and why. I think this is a great thing to consider when staffing a project and will probably serve as an invaluable asset going down the road. That being said, my type is

meaning I am Extroverted, favor intuition, thinking, and perception. The test I took is free and can be found here. What type are you?

Tagging: Rob, Muness, Jason, Joe, and Evan

Announcing Fixture Busters... {dot}com

April 18th, 2008

I have been on a testing / refactoring rampage over the last few months and have learned an awful lot about making tests better. One particular pain point that I have run into is the use of fixtures in people's test suites. A lot of people already know that fixtures are a bad thing, but few people do anything about it. That's all about to change. I am going to start putting up screencasts that show you how to refactor the fixtures right out of your tests! If you have any Rails applications that you want to throw on the fire feel free to email the code to aaron at my domain dot com. Please no client projects, open source code only! I don't want to do your work for you.

You can find the site at http://fixturebusters.com. It will have some super duper styling love and the first screencast up sometime in the next week so stop on over and check it out!

MPI Ruby - Officially Released

April 17th, 2008

A while ago I annouced that I had updated the seemingly dead MPI Ruby project to work with Ruby 1.8.x. I have been testing things out and have had some very helpful feedback. Things seem to be working well for me so I am announcing the official release of the library. With the recent "release" of GItHub I decided to put the good bits up there. The clone url is:

git://github.com/abedra/mpi-ruby.git
If you are running leopard and have XCode Tools installed, all you have to do is:

$ ./configure
$ make
$ sudo make install
and you should be in happy parallel land. If you don't have the new Apple hotness, you need to install OpenMPI. Happy high performance parallel computing!

MPI Ruby lesson - Basic Communication

April 17th, 2008

Here is a demonstration of basic communication with MPI Ruby.
1
2
3
4
5
6
7
8
9
10
11
12
13

myrank = MPI::Comm::WORLD.rank()
csize = MPI::Comm::WORLD.size()

if myrank % 2 == 0 then
  if myrank + 1 != csize then
    hello = "Hello, I'm #{myrank}, you must be #{myrank+1}"
    MPI::Comm::WORLD.send(hello, myrank + 1, 0)
  end
else
  msg, status = MPI::Comm::WORLD.recv(myrank - 1, 0)
  puts "I'm #{myrank} and this message came from #{status.source} with tag #{status.tag}: '#{msg}'"
end
This script sets up interprocess communication, sends / receives basic 'hello' messages and determines who the message came from and what status the message was. This is a simple starter example of how to send and receive between processes with MPI. Let's try running it:

$ mpirun -np 16 mpi_ruby basic.rb
We get an output similar to this:

I'm 13 and this message came from 12 with tag 0: 'Hello, I'm 12, you must be 13'
I'm 1 and this message came from 0 with tag 0: 'Hello, I'm 0, you must be 1'
I'm 3 and this message came from 2 with tag 0: 'Hello, I'm 2, you must be 3'
I'm 5 and this message came from 4 with tag 0: 'Hello, I'm 4, you must be 5'
I'm 7 and this message came from 6 with tag 0: 'Hello, I'm 6, you must be 7'
I'm 9 and this message came from 8 with tag 0: 'Hello, I'm 8, you must be 9'
I'm 11 and this message came from 10 with tag 0: 'Hello, I'm 10, you must be 11'
I'm 15 and this message came from 14 with tag 0: 'Hello, I'm 14, you must be 15'
-U:**- index.html.erb   (Ruby RoR RHTML)
M-x visit-site http://aaronbedra.com