<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sean's Obsessions &#187; Linux/Unix/OpenSource</title>
	<atom:link href="http://ertw.com/blog/category/linuxunixopensource/feed/" rel="self" type="application/rss+xml" />
	<link>http://ertw.com/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Mon, 30 Jan 2012 08:55:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Nagios paging using Twilio</title>
		<link>http://ertw.com/blog/2011/09/07/nagios-paging-using-twilio/</link>
		<comments>http://ertw.com/blog/2011/09/07/nagios-paging-using-twilio/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 19:48:45 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>
		<category><![CDATA[Telephony]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=355</guid>
		<description><![CDATA[&#1080;&#1082;&#1086;&#1085;&#1086;&#1087;&#1080;&#1089;I use Nagios to monitor the health of a few servers, and would like to be paged if something goes wrong. When I set it up a couple of years ago, I used SMS Gateway which was $10 for 100 SMSes. I was able to page with a simple curl command. However I&#8217;d get the [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://ikoni.eu/">&#1080;&#1082;&#1086;&#1085;&#1086;&#1087;&#1080;&#1089;</a></font>I use Nagios to monitor the health of a few servers, and would like to be paged if something goes wrong.</p>
<p>When I set it up a couple of years ago, I used <a href="http://smsgateway.ca/">SMS Gateway</a> which was $10 for 100 SMSes. I was able to page with a simple curl command. However I&#8217;d get the odd page that wouldn&#8217;t go through, and despite being very responsive, the support wasn&#8217;t very reassuring.</p>
<p>Now that I&#8217;ve depleted my 100 pages, I figured I&#8217;d move over to <a href="http://twilio.com">Twilio</a> because they&#8217;re pretty slick, and the reliability has to be better.</p>
<p>Some Nagios code, first:</p>
<pre><code>
define contactgroup{
        contactgroup_name       important
        alias                   Sean Buzz
        members                 sean, page
}
define contact{
        contact_name                    page
        alias                           page
        service_notification_commands   notify-by-page
        host_notification_commands      host-notify-by-page
        service_notification_period 24x7
        host_notification_period 24x7
        service_notification_options w,u,c,r
        host_notification_options d,u,r
        pager                           nobody@localhost
}
define service{
        use                             local-service         ; Name of service template to use
        host_name                       localhost
        service_description             smallpayroll.ca
        contact_groups                  important
        check_command                   check_http_string!smallpayroll.ca!Easy to use
        }
</code></pre>
<p>The first stanza creates a contact group called &#8220;important&#8221; that emails sean, and pages. The second stanza implements the &#8220;host-notify-by-page&#8221; and &#8220;notify-by-page&#8221; which do the actual paging.  The final stanza is an example of a service that would get paged on. If the <b>check_http_string</b> check fails, the &#8220;important&#8221; contact group is notified.</p>
<p>The code to page is as follows:</p>
<pre><code>
define command {
        command_name    notify-by-page
        command_line    curl --data-urlencode "From=YOURTWILIONUMBER" --data-urlencode "To=YOURCELL" --data-urlencode "Body=[Nagios] $NOTIFICATIONTYPE$ $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$" https://SID:TOKEN@api.twilio.com/2010-04-01/Accounts/SID/SMS/Messages >> /tmp/sms
}
define command {
        command_name    host-notify-by-page
        command_line    curl --data-urlencode "From=YOURTWILIONUMBER" --data-urlencode "To=YOURCELL" --data-urlencode "Body=[Nagios] $HOSTSTATE$ alert for $HOSTNAME$" https://SID:TOKEN@api.twilio.com/2010-04-01/Accounts/SID/SMS/Messages >> /tmp/sms
}
</code></pre>
<p>To get the SID and TOKEN (note there are two instances of the SID, the second is in the URL right after accounts) go to your dashboard and look at the top:</p>
<p><a href="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-sid-token.png"><img src="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-sid-token-300x37.png" alt="" title="twilio-sid-token" width="300" height="37" class="alignnone size-medium wp-image-358" /></a></p>
<p>To get a number click on <b>Numbers</b> then <b>Buy a Number</b>:</p>
<p><a href="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-buy-a-number.png"><img src="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-buy-a-number-300x67.png" alt="" title="twilio-buy-a-number" width="300" height="67" class="alignnone size-medium wp-image-357" /></a></p>
<p>Then search for a number. It should be in the USA, as it looks like Canadian numbers don&#8217;t support SMS. You can verify this by clicking on &#8220;Buy&#8221;:<br />
<a href="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-sms-enabled.png"><img src="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-sms-enabled.png" alt="" title="twilio-sms-enabled" width="678" height="397" class="alignnone size-full wp-image-359" /></a></p>
<p>Buy the number for $1/month. You don&#8217;t have to set up any URLs with it if you&#8217;re doing outbound only.</p>
<p>YOURCELL should be obvious <img src='http://ertw.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  It could also be templated within Nagios.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/09/07/nagios-paging-using-twilio/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>&quot;cd&quot; tricks to increase your efficiency</title>
		<link>http://ertw.com/blog/2011/03/04/quotcdquot-tricks-to-increase-your-efficiency/</link>
		<comments>http://ertw.com/blog/2011/03/04/quotcdquot-tricks-to-increase-your-efficiency/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 20:33:12 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=303</guid>
		<description><![CDATA[&#1055;&#1086;&#1076;&#1072;&#1088;&#1098;&#1094;&#1080;&#1074;&#1080;&#1082;I was doing some work that involved moving between several directories. Remembering about pushd and popd, I googled around to try and find out how to use them properly. I found this article which was helpful, but what was even better was one of the comments talking about &#8220;cd -&#8221;. [root@host tmp]# pwd /tmp [root@host [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://ikoni.eu/">&#1055;&#1086;&#1076;&#1072;&#1088;&#1098;&#1094;&#1080;</a></font><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://vikuslugi-ovi.com/">&#1074;&#1080;&#1082;</a></font>I was doing some work that involved moving between several directories. Remembering about pushd and popd, I googled around to try and find out how to use them properly. I found <a href="http://eriwen.com/bash/pushd-and-popd/">this article</a> which was helpful, but what was even better was one of the comments talking about &#8220;cd -&#8221;.</p>
<pre><code>
[root@host tmp]# pwd
/tmp
[root@host tmp]# cd -
/auto/tmp/sean
[root@host sean]# pwd
/auto/tmp/sean
[root@host sean]# cd -
/tmp
[root@host tmp]# pwd
/tmp
</code></pre>
<p>What it does is cycle you between your last two directories. It also operates outside of the pushd/popd stack:</p>
<pre><code>
[root@host tmp]# dirs
/tmp
</code></pre>
<p>So you should still be able to use those!</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/03/04/quotcdquot-tricks-to-increase-your-efficiency/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Telling your wordpress environments apart</title>
		<link>http://ertw.com/blog/2011/02/16/telling-your-wordpress-environments-apart/</link>
		<comments>http://ertw.com/blog/2011/02/16/telling-your-wordpress-environments-apart/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 21:15:54 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=297</guid>
		<description><![CDATA[I am doing some work with WordPress, where we have a development server and a production server. The development side is set up as a git repo, and the production side pulls from the dev repo when we want to pull in changes: git pull origin master I move between the two environments using the [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I am doing some work with WordPress, where we have a development server and a production server. The development side is set up as a git repo, and the production side pulls from the dev repo when we want to pull in changes: </p>
<pre><code>git pull origin master</code></pre>
<p>I move between the two environments using the host file, which sometimes means I&#8217;m not sure which environment I&#8217;m in. I put the following in functions.php to help me out:</p>
<pre><code>function mysite_i_am_in_dev() {
  // Red border if we're in dev mode
  echo '&lt;!-- dev mode -->&lt;style type="text/css"> body { border: 2px solid #FF0000; } &lt;/style>';
}

if ($_SERVER["SERVER_ADDR"] == "x.x.x.x") { // x.x.x.x is the IP address of your dev server
  add_action('wp_head', 'mysite_i_am_in_dev');
  add_action('admin_head', 'mysite_i_am_in_dev');
}
</code></pre>
<p>So now, anyone viewing the development server will have a small red border around the screen.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/02/16/telling-your-wordpress-environments-apart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting the beanstalk worker from capistrano</title>
		<link>http://ertw.com/blog/2011/01/16/starting-the-beanstalk-worker-from-capistrano/</link>
		<comments>http://ertw.com/blog/2011/01/16/starting-the-beanstalk-worker-from-capistrano/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 17:36:31 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=291</guid>
		<description><![CDATA[I recently changed SmallPayroll to use Beanstalkd instead of delayed_job for background processing. delayed_job is an awesome tool and makes asynchronous processing so simple. However I wanted to have multiple queues so that I could have different workers processing different queues, and have some upcoming needs to process the jobs quicker than the 5 second [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I recently changed <a href="http://SmallPayroll.ca">SmallPayroll</a> to use <a href="http://kr.github.com/beanstalkd/">Beanstalkd</a> instead of <a href="https://github.com/collectiveidea/delayed_job">delayed_job</a> for background processing. delayed_job is an awesome tool and makes asynchronous processing so simple. However I wanted to have multiple queues so that I could have different workers processing different queues, and have some upcoming needs to process the jobs quicker than the 5 second polling time.</p>
<p>After watching <a href="http://railscasts.com/episodes/243-beanstalkd-and-stalker">railscasts on beanstalkd and stalker</a> I decided to use that. Beanstalkd is a lightweight job processor, and stalker makes it very simple to use from the client end.  </p>
<p>I used to have an observer that said</p>
<pre><code>class UserObserver < ActiveRecord::Observer
  def after_create(user)
    UserMailer.send_later(:deliver_welcome_email, user)
    UserMailer.send_later(:deliver_notify_admin, user)
  end
end</code></pre>
<p>This became:</p>
<pre><code>class UserObserver < ActiveRecord::Observer
  def after_create(user)
    Stalker.enqueue("email.new_user", :user_id => user.id)
  end
end</code></pre>
<p>delayed_job was nice in that the job would just run against the model, but now I have to process the job in config/worker.rb:</p>
<pre><code>require 'stalker'
include Stalker
require File.expand_path("../environment", __FILE__)

job 'default' do |args|
  puts "I don't support the default queue"
end

job 'email.new_user' do |args|
  user = User.find(args["user_id"])
  UserMailer.deliver_welcome_email(user)
  UserMailer.deliver_notify_admin(user)
end</code></pre>
<p>One thing about stalker is that it wants you to pass simple objects instead of ActiveRecord objects, so I queue the user_id instead of the user model.</p>
<p>The script above monitors the default tube, which I don't use, because the <a href="http://search.cpan.org/~gbarr/Nagios-Plugin-Beanstalk-0.04/lib/Nagios/Plugin/Beanstalk.pm">nagios plugin for beanstalk</a> expects someone to monitor it (after setting it all up, I guess I could have set it up to ignore that tube). I'm also using the <a href="https://gist.github.com/169876">munin plugin for beanstalkd</a> to graph the activity in the daemon.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-7559692267475906";
google_ad_channel = "ertw-blog-inline";
google_ui_features = "rc:6";
google_ad_width = 250;
google_ad_height = 250;
google_ad_format = "250x250_as";
google_ad_type = "text_image";
google_alternate_ad_url = "?adsensem-benice=250x250";
google_color_border = "99a9ba";
google_color_bg = "FFFFFF";
google_color_link = "000000";
google_color_text = "000000";
google_color_url = "99a9ba";

//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<br />
Then, script/worker uses the daemons gem to start the job and restart it if it crashes:</p>
<pre><code>#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'

pwd  = File.dirname(File.expand_path(__FILE__))
file = pwd + '/../config/worker.rb'

Daemons.run_proc(
  'payroll-generic-worker', # name of daemon
  :dir_mode => :normal,
  :dir => File.join(pwd, '../tmp/pids'),
  :backtrace => true,
  :monitor => true,
  :log_output => true
) do
  exec "stalk #{file}"
end</code></pre>
<p>Finally, some capistrano magic to start the worker with the deploy inside config/deploy.rb</p>
<pre><code>namespace :beanstalk do
  desc "Start beanstalk process"
  task :start, :roles => :app do
    run "cd #{current_path}; RAILS_ENV=production script/worker start"
  end

  desc "Stop beanstalk process"
  task :stop, :roles => :app do
    run "cd #{current_path}; RAILS_ENV=production script/worker stop"
  end

  desc "Restart beanstalk process"
  task :restart, :roles => :app do
    run "cd #{current_path}; RAILS_ENV=production script/worker restart"
  end
end

after "deploy:start", "beanstalk:start"
after "deploy:stop", "beanstalk:stop"
after "deploy:restart", "beanstalk:restart"
</code></pre>
<p>The only problem I've run into so far is that my HTML email seems to go out without the text/html content-type. Fixing that was a simple matter of putting <code>content_type  'text/html'</code> inside my mailer, which wasn't needed when I was using delayed_job.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/01/16/starting-the-beanstalk-worker-from-capistrano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing ExceptionNotifier for Rails 3</title>
		<link>http://ertw.com/blog/2010/12/09/installing-exceptionnotifier-for-rails-3/</link>
		<comments>http://ertw.com/blog/2010/12/09/installing-exceptionnotifier-for-rails-3/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 15:23:15 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=286</guid>
		<description><![CDATA[I was just fighting with this, and being new to the Rails 3 way of things, the docs didn&#8217;t quite make sense. Step 1 &#8211; Install the plugin rails plugin install https://github.com/rails/exception_notification.git Step 2 &#8211; Edit config/application.rb: module MyApp class Application < Rails::Application # ..... # somewhere in this block put the following: config.middleware.use "::ExceptionNotifier", [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I was just fighting with this, and being new to the Rails 3 way of things, the docs didn&#8217;t quite make sense.</p>
<p>Step 1 &#8211; Install the plugin</p>
<pre><code> rails plugin install https://github.com/rails/exception_notification.git</code></pre>
<p>Step 2 &#8211; Edit config/application.rb:</p>
<pre><code>module MyApp
  class Application < Rails::Application
    # .....
    #  somewhere in this block put the following:

    config.middleware.use "::ExceptionNotifier",
      :email_prefix => "[MyApp Error] ",
      :sender_address => %{"notifier" <notifier@example.com>},
      :exception_recipients => %w{youraddress@example.com}
</code></pre>
<p>3. Verify:</p>
<pre><code>$ rake middleware | grep ExceptionNotifier
use ExceptionNotifier
</code></pre>
<p>Now you&#8217;ll get any application errors emailed to the addresses in the exception_recipients array.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2010/12/09/installing-exceptionnotifier-for-rails-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EPEL nginx rpm and upgrade from 0.6.x to 0.8.x</title>
		<link>http://ertw.com/blog/2010/11/19/epel-nginx-rpm-and-upgrade-from-0-6-x-to-0-8-x/</link>
		<comments>http://ertw.com/blog/2010/11/19/epel-nginx-rpm-and-upgrade-from-0-6-x-to-0-8-x/#comments</comments>
		<pubDate>Fri, 19 Nov 2010 15:02:38 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=283</guid>
		<description><![CDATA[I just upgraded my nginx rpm and my site refused to start. /var/log/nginx/error.log reported the following: 2010/11/19 09:30:08 [emerg] 27885#0: eventfd() failed (38: Function not implemented) 2010/11/19 09:30:08 [alert] 27884#0: worker process 27885 exited with fatal code 2 and can not be respawn It turns out the new nginx rpm was compiled with &#8211;with-file-aio which [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I just upgraded my nginx rpm and my site refused to start. /var/log/nginx/error.log reported the following:</p>
<blockquote><p>2010/11/19 09:30:08 [emerg] 27885#0: eventfd() failed (38: Function not implemented)<br />
2010/11/19 09:30:08 [alert] 27884#0: worker process 27885 exited with fatal code 2 and can not be respawn
</p></blockquote>
<p>It turns out the new nginx rpm was compiled with &#8211;with-file-aio which uses the eventfd() call:</p>
<p><code>
<pre>[root@smallpayroll ~]# nginx -V
nginx version: nginx/0.8.53
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-48)
TLS SNI support disabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-file-aio --with-mail_ssl_module --with-ipv6 --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables' --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables'
</pre>
<p></code></p>
<p>eventfd() wasn&#8217;t available until Kernel 2.6.22. I was running 2.6.18 because that&#8217;s what my VPS offered when I started. Fortunately it was a quick option in the <a href="http://ertw.com/linode.php">Linode</a> panel, a reboot, and now I&#8217;m running 2.6.32.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2010/11/19/epel-nginx-rpm-and-upgrade-from-0-6-x-to-0-8-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with git</title>
		<link>http://ertw.com/blog/2010/09/27/fun-with-git/</link>
		<comments>http://ertw.com/blog/2010/09/27/fun-with-git/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 02:40:04 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=277</guid>
		<description><![CDATA[&#1090;&#1088;&#1072;&#1087;&#1077;&#1079;&#1085;&#1080; &#1084;&#1072;&#1089;&#1080;I&#8217;ve started using Git instead of svn. Like many other people, I tried it out to get easier branching, but found it&#8217;s just a pleasure to use in general. One great feature is that git can work with an SVN repository. You use git to check out some SVN code into a local git [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://www.videnov.com/">&#1090;&#1088;&#1072;&#1087;&#1077;&#1079;&#1085;&#1080; &#1084;&#1072;&#1089;&#1080;</a></font>I&#8217;ve started using Git instead of svn. Like many other people, I tried it out to get easier branching, but found it&#8217;s just a pleasure to use in general.</p>
<p>One great feature is that git can work with an SVN repository. You use git to check out some SVN code into a local git repository, you work with the repo as if it were git, then you commit your changes back to svn.</p>
<p>The lowdown on this is:</p>
<pre><code>
# Check out the svn repo
# It may take a while because it's copying all the changes, not just a checkout
git svn init http://myrepo/myproject/trunk myproject
cd myproject
# do some work
# commit to git
git commit -a -m "did some work"
# send updates to svn
git svn dcommit
</code></pre>
<p>But wait, someone else has done some work and you want to pull the latest changes from svn to your git repo</p>
<pre><code>git svn rebase</code></pre>
<p>Nice eh?<br />
<script type="text/javascript"><!--
google_ad_client = "pub-7559692267475906";
google_ad_channel = "ertw-blog-inline";
google_ui_features = "rc:6";
google_ad_width = 250;
google_ad_height = 250;
google_ad_format = "250x250_as";
google_ad_type = "text_image";
google_alternate_ad_url = "?adsensem-benice=250x250";
google_color_border = "99a9ba";
google_color_bg = "FFFFFF";
google_color_link = "000000";
google_color_text = "000000";
google_color_url = "99a9ba";

//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<br />
So let&#8217;s say you&#8217;re working in your git repo, and want to branch</p>
<pre><code>
git branch somefeature
git checkout somefeature
</code></pre>
<p>You&#8217;re working along, and you want to pull changes from svn into master and your branch.</p>
<pre><code>
git checkout master
git svn rebase
# master is up to date
# so merge master into the branch
git checkout somefeature
git merge master
</code></pre>
<p>This is so easy to use! Previously, with SVN, I&#8217;d branch, work on the feature, and then merge back to trunk. Given how painful merges were, there was no hope that I&#8217;d be merging trunk changes into my feature branch.</p>
<p>I&#8217;m sure my tune will change the first time I blow up my repository though <img src='http://ertw.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2010/09/27/fun-with-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Piping with the find command and dealing with spaces</title>
		<link>http://ertw.com/blog/2010/04/07/piping-with-the-find-command-and-dealing-with-spaces/</link>
		<comments>http://ertw.com/blog/2010/04/07/piping-with-the-find-command-and-dealing-with-spaces/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 16:49:42 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=256</guid>
		<description><![CDATA[I often use the find command as such: grep foo `find . -name \*.php` which looks for foo in all the PHP files. If the list of files gets too long for the shell, then xargs is the better option: find . -name \*.php &#124; xargs grep foo /dev/null This breaks up the command into [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I often use the find command as such:</p>
<pre><code>grep foo `find . -name \*.php`</code></pre>
<p>which looks for foo in all the PHP files. If the list of files gets too long for the shell, then xargs is the better option:</p>
<pre><code>find . -name \*.php | xargs grep foo /dev/null</code></pre>
<p>This breaks up the command into manageable chunks. The /dev/null is there in case xargs only passes one file name to the command, this ensures there will be two file names to trigger the printing of the matching file (there&#8217;s probably an option, but I like this way better)</p>
<p>The problem with find -print |xargs is that a file or directory with spaces causes problems. For instance &#8220;xxx yyy/blah.php&#8221; will run</p>
<p><code>grep foo /dev/null xxx yyy/blah.php</code></p>
<p>neither of which exist.</p>
<p>My first hack at it was to revert to programmer mode and do a loop:</p>
<pre><code>
find . -name \*.php | while read A; do grep foo "$A" /dev/null; done
</code>
</pre>
<p>The best solution I found so far is to use -printf to force find to quote the file when it spits out the file name and get back into the xargs/stream mode of thinking:</p>
<pre><code>
find . -name \*.php -printf '"%h/%f"\n' | xargs grep foo /dev/null
</code></pre>
<p>Maybe there&#8217;s an easier way? (besides shooting people that use spaces in directory or file names)</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2010/04/07/piping-with-the-find-command-and-dealing-with-spaces/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Top 1 best database management tool &#8211; and how to use it</title>
		<link>http://ertw.com/blog/2009/11/15/top-1-best-database-management-tool-and-how-to-use-it/</link>
		<comments>http://ertw.com/blog/2009/11/15/top-1-best-database-management-tool-and-how-to-use-it/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 20:06:50 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=231</guid>
		<description><![CDATA[I&#8217;m noticing that more and more of the items that pop up in my feed reader are of the &#8220;Top N&#8221; variety. Some are decent, where the author breaks the topic down into subgroups and then shows one or two tools for each purpose. However some of them are just silly, such as the &#8220;top [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m noticing that more and more of the items that pop up in my feed reader are of the &#8220;Top N&#8221; variety. Some are decent, where the author breaks the topic down into subgroups and then shows one or two tools for each purpose. However some of them are just silly, such as the &#8220;top 100 photoshop tutorials&#8221;, which is really &#8220;the last 50 Photoshop tutorials I bookmarked, and 50 that I just Googled&#8221;.</p>
<p>So when I read <a href="http://sixrevisions.com/tools/top-five-best-database-management-tools/">Top Five Best Database Management Tools</a>, I wondered what the heck the value was. Some of the tools were for Microsoft SQL server, some were for MySQL, and there was no criteria for the list other than &#8220;reader favourites&#8221;. </p>
<p>So, in an effort to answer the &#8220;how do I manage my database&#8221; question, here&#8217;s the top 1 database management tool, and how to use it.</p>
<p>But first, a disclaimer.  It&#8217;s only the top tool if:</p>
<ul>
<li>You use mySQL</li>
<li>Your web server can serve PHP</li>
<li>You&#8217;re me</li>
</ul>
<p>The tool is <a href="http://www.phpmyadmin.net/home_page/index.php">phpMyAdmin</a>. That should come as no surprise, because it&#8217;s on everyone else&#8217;s top N list. There may be better, but it&#8217;s easy to install and probably handles anything you can throw at it. If you&#8217;re not using MySQL, or you have something better, then go ahead and use it!</p>
<p>So go to the homepage and download the software. If you&#8217;re in Windows grab the .zip version, if you&#8217;re in Linux, grab the .gz version.</p>
<p>First, uncompress the software to somewhere outside your document root. Doing it this way makes management a bit easier in the future, but slightly complicates the installation.  On my machine, I&#8217;d go</p>
<pre>
<code>
cd /var/www
tar -xzf tar -xzf /tmp/phpMyAdmin-3.2.3-all-languages.tar.gz
ln -s phpMyAdmin-3.2.3-all-languages phpMyAdmin
</code>
</pre>
<p>Line 1 gets you to the parent directory of the web stuff (at least in RedHat/CentOS). Line 2 uncompresses the software. Line 3 creates a symbolic link to the current version.</p>
<p>Next we&#8217;ll create an Apache configuration file to handle access to the software. You can do this in the main httpd.conf file, but most distributions have a directory where extra configurations are loaded.</p>
<p>/etc/httpd/conf.d/phpmyadmin.conf:</p>
<pre><code>
Alias /phpMyAdmin/ /var/www/phpMyAdmin/

&lt;Location /phpMyAdmin/&gt;
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
    Allow from 192.168.1.0/24
    Allow from 1.2.3.4
&lt;/Location&gt;
</code></pre>
<p>Line 1 maps anything under /phpMyAdmin/ (note the trailing /) to /var/www/phpMyAdmin/. The latter is a symlink to the current version, so if you want to upgrade you can have both versions uncompressed and use the symlink to change the active version. You can also choose a more friendly name, if you&#8217;d like.</p>
<p>The rest of the code restricts access to the localhost (127.0.0.1), the local network, and a certain outside address. If you want everyone to access it, delete the Location stanza and everything inside it (leaving only the Alias)</p>
<p>If you go to the URL, you&#8217;ll be able to log in using your username and password.</p>
<p>An interesting thing about phpMyAdmin is that it can manage several servers from one web page. In this case, the login screen will allow you to choose the server. This is great if you have multiple mySQL servers, or if your web server and SQL server are on separate devices.</p>
<p>The easiest way to do this is to use the web based configuration:</p>
<pre>
<code>
mkdir /var/www/phpMyAdmin/config
chmod 777 /var/www/phpMyAdmin/config
</code>
</pre>
<p>Then hop over to http://127.0.0.1/phpMyAdmin/setup/ (or whatever your server is) and follow the instructions to create several servers. Unless you have a specific reason to, you can choose the defaults (except for the server name!)</p>
<p>Once you&#8217;re done, protect the directory from writing and copy the generated file to the root:</p>
<pre><code>chmod 755 /var/www/phpMyAdmin/config
cp /var/www/phpMyAdmin/config/config.inc.php /var/www/phpMyAdmin</code></pre>
<p>If you&#8217;d rather not use the web interface, copy the config.sample.inc.php to config.inc.php and go from there.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2009/11/15/top-1-best-database-management-tool-and-how-to-use-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>svn merge</title>
		<link>http://ertw.com/blog/2009/08/27/svn-merge/</link>
		<comments>http://ertw.com/blog/2009/08/27/svn-merge/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 18:23:17 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[svn merge rails payroll]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=220</guid>
		<description><![CDATA[(this is one of those &#8220;so I remember it&#8221; posts that might help others) Edit: See below for a more accurate way to merge the trunk back into HEAD I&#8217;ve got some code that I&#8217;m storing in SVN. In traditional SVN form, I&#8217;ve got my repo set up as /trunk /branches So my work is [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>(this is one of those &#8220;so I remember it&#8221; posts that might help others)<br />
<b>Edit: See below for a more accurate way to merge the trunk back into HEAD</b></p>
<p>I&#8217;ve got some code that I&#8217;m storing in SVN. In traditional SVN form, I&#8217;ve got my repo set up as</p>
<p>/trunk<br />
/branches </p>
<p>So my work is done out of trunk, ie</p>
<pre><code>svn co http://home.ertw.com/svn/repos/payroll/trunk/ payroll</code></pre>
<p>I then had some major rework I wanted to do. Rather than continuing to develop out of trunk, I wanted to keep these changes separate so that I could continue working on other things in the code base at the same time as the rework. In svn, that&#8217;s done as a branch. From the root of the checked out code:</p>
<pre><code>svn copy http://home.ertw.com/svn/repos/payroll/trunk http://home.ertw.com/svn/repos/payroll/branches/engine_mark_2
svn switch http://home.ertw.com/svn/repos/payroll/branches/engine_mark_2
</code></pre>
<p>The first command copies all the files from the trunk to a branch called &#8220;branches/engine_mark_2&#8243;. Note that the &#8220;trunk&#8221; and &#8220;branches&#8221; are just directories, they have no meaning themselves. I could develop out of /, or even out of /fred and branch to /wilma.</p>
<p>The second command switches the current repository from /trunk to /branches/engine_mark_2. I had just checked in all the code, so nothing had to change, it was just a pointer to where I was storing changes.</p>
<p>So, I could continue working on this branch, and also check out /trunk to somewhere else to make changes.</p>
<p>After all the work in the branch is done and checked in, take a look at the current branch:</p>
<pre><code>
[sean@sergeant payroll]$ svn info
Path: .
URL: http://home.ertw.com/svn/repos/payroll/branches/engine_mark_2
Repository Root: http://home.ertw.com/svn/repos/payroll
Repository UUID: 116013b7-0df0-436d-95c2-deac7dca3705
Revision: 92
Node Kind: directory
Schedule: normal
Last Changed Author: sean
Last Changed Rev: 92
Last Changed Date: 2009-08-24 20:57:22 -0500 (Mon, 24 Aug 2009)
</code></pre>
<p>The revision the branch started at is 92.</p>
<p>I checked out a copy of /trunk to another directory:</p>
<pre><code>svn co http://home.ertw.com/svn/repos/payroll/trunk payrolltrunk; cd payrolltrunk</code></pre>
<p>Then merge version 92 to the head, giving the url to the branch:</p>
<pre><code>
svn merge -r 92:HEAD http://home.ertw.com/svn/repos/payroll/branches/engine_mark_2
--- Merging r93 through r95 into '.':
U    test/unit/accrual_test.rb
U    test/unit/employer_test.rb
U    test/factories.rb
U    test/lib/tax_calc_test.rb
U    test/lib/cpp_ei_test.rb
--- Merging r93 through r95 into 'test/lib/finalize_test.rb':
U    test/lib/finalize_test.rb
--- Merging r93 through r95 into '.':
U    test/lib/pre_flight_test.rb
A    test/lib/payroll_procedure_test.rb
U    app/models/employee.rb
U    app/models/accrual.rb
U    app/models/employer.rb
U    app/controllers/payroll_controller.rb
U    db/schema.rb
A    db/migrate/20090827031532_add_payroll_run_to_accrual.rb
A    db/migrate/20090827032200_add_status_to_employee.rb
U    lib/payroll_engine.rb
</code></pre>
<p>At this point you&#8217;re sitting in a copy of HEAD with the branches changes merged it. Thankfully I had no conflicts, otherwise I&#8217;d have to resolve those before continuing by looking at the files with a status of &#8220;C&#8221; and fixing the conflicts that are marked by SVN inside the file.</p>
<p>Finally, commit the changes to HEAD:</p>
<pre><code>svn commit</code></pre>
<p>Then, either wipe out all your checked out copies and check out HEAD again, or switch your working copy of the branch back to head:</p>
<pre><code> svn switch http://home.ertw.com/svn/repos/payroll/trunk</code></pre>
<p>The branch can stay as is.</p>
<p><b>Edit</b><br />
After doing this again I found a problem trying this again when I had added files to the repository in the branch, and was getting &#8220;Skipped missing target&#8221; errors.  </p>
<pre><code>
svn log --verbose --stop-on-copy $BRANCH
...
------------------------------------------------------------------------
r106 | sean | 2009-09-04 07:56:23 -0500 (Fri, 04 Sep 2009) | 2 lines
Changed paths:
   A /branches/reporting (from /trunk:105)

Branching to integrate reports

# now in a checked out version of trunk
[sean@sergeant payroll]$ svn merge -r 106:HEAD $BRANCH
--- Merging r107 through r117 into '.':
A    test/unit/helpers/payroll_history_helper_test.rb
U    test/unit/accrual_test.rb
U    test/functional/payroll_controller_test.rb
A    test/functional/payroll_history_controller_test.rb
A    app/helpers/payroll_history_helper.rb
U    app/models/employee.rb
U    app/models/payroll_run.rb
U    app/models/accrual.rb
U    app/models/employer.rb
U    app/controllers/payroll_controller.rb
A    app/controllers/payroll_history_controller.rb
U    app/views/layouts/application.html.erb
U    app/views/payroll/run_final.html.erb
A    app/views/payroll_history
A    app/views/payroll_history/index.html.erb
A    app/views/payroll_history/get.html.erb
A    app/reports
A    app/reports/pay_stub_aggregator.rb
A    app/reports/pay_stub_controller.rb
U    config/environment.rb
U    db/schema.rb
U    lib/payroll_engine.rb
</code></pre>
<p><b>Second edit</b></p>
<p>So I was working in a branch (copied at revision 147) and had made some updates to HEAD that I wanted to sync up.</p>
<p>From my working copy of the branch:</p>
<pre><code>
$ svn merge --dry-run -r 147:149 http://home.ertw.com/svn/repos/payroll/trunk .
U    test/lib/cpp_ei_test.rb
U    lib/payroll_engine.rb
</code></pre>
<p>The &#8211;dry-run tells me which files will be updated. That was good, so I re-ran without the &#8211;dry-run.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2009/08/27/svn-merge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

