Donald Plummer's Blog

I'm a software developer in Seattle, WA.

Markdown in Go templates

While building this blog, I ran into a problem. I was storing the blog posts in markdown format. Using the blackfriday markdown processor, I was getting back raw HTML:

func (article *Article) ParsedBody() string {
  output := blackfriday.MarkdownCommon([]byte(article.Body))
  return string(output)
}

Then in my template I’d try to render the ParsedBody:

{{with .ArticleShow}}
  <div class="blog-post">
    <!-- title, etc ... -->
    {{.ParsedBody}}
  </div>
{{end}}

But that escapes the body:

  <div class="blog-post">
    <!-- title, etc ... -->
    &gt;p&lt;Hello world!&gt;/p&lt;
  </div>

The answer is to not return a string, but to return a template.HTML type:

func (article *Article) ParsedBody() template.HTML {
  output := blackfriday.MarkdownCommon([]byte(article.Body))
  return template.HTML(output)
}

New blog in Go

I’ve been playing with go for a few months now. I recently needed to do a large ETL for work, copying price data from about 1000 mysql databases and loading it into a single database with a different schema. Leveraging our existing rails codebase wasn’t going to work, the migration of 15 million records was going to take on the order of weeks. So in a weekend I wrote a command line tool in go. That was a lot of fun.

Then about a week ago I got an email out of the blue from a CTO at a startup asking about one of my blog posts. I thought, “man, I should really be posting to my blog more”. Plus, I wanted to write a webapp in go. So here it is!

The code is available on github. I have several goals in mind:

  • Live markdown editor. Right now all the content is actually compiled into the binary and loaded into redis on startup. Which makes using redis pretty dumb. But my goal is to just store everything in redis, and allow myself to draft and publish posts from the web (like a real blog!)
  • Comments. Not sure how I want this, but I’ve already had people email me comments on posts, and I’d like to share that. So I need to add something here. I’m thinking of either disqus or login with github.
  • Versions on my posts. Like git or a wiki. Could be cool to mark comments as outdated after updating it based on feedback. Like github issues.

DHCPCD timeouts on new archlinux installs

In installing a new Cisco RV320 router at the office, I ran into some trouble with the DHCP server. My desktop could get an IP address, but my laptop couldn’t. The request (with sudo dhcpcd -d -4 eth0) would just timeout without a response.

I compared the /etc/dhcpcd.conf file between machines and found that newer Archlinux installs configure the duid option. Disabled that and viola, dhcp works!

Archlinux Zeus and URXVT broken with latest glibc

When running sudo pacman -Syu today, I found that both zeus and urxvt broke. I use urxvt as my terminal, and at first I was at a loss as to how to troubleshoot, till my coworker pointed out I could just run xterm.

zeus breaks with “exit status 1” and then just hanging.

urxvt breaks with “urxvt: can’t initialize pseudo-tty, aborting”

In both cases, when I downgraded glibc to 2.17-6 the problem was fixed. I needed to also downgrade binutils to 2.23.2-2.

Also, to fix zeus, the json gem needed to be upgraded to 1.8.0.

Starting God with an init script

  1. Get the default gem set:

    $ rvm list default
    
  2. Create a wrapper script for the init script to use

    $ rvmsudo wrapper ruby-1.9.3-p374-railsexpress bootup god
    
  3. Create the directory god will log to:

    $ sudo mkdir /var/log/god
    
  4. Create the /etc/init.d/god init script:

    #!/bin/bash
    #
    # God under multi-user RVM
    #
    # http://god.rubyforge.org
    # http://beginrescueend.com/integration/god/
    #
    # chkconfig: - 85 15
    # description: Control the God gem. Expects the gem to \
    #              to be installed under a multi-user RVM \
    #              installation. Requires RVM wrapper.
    #
    
    
    ### BEGIN INIT INFO
    # Provides:          god
    # Required-Start:    $remote_fs $network
    # Required-Stop:     $remote_fs $network
    # Default-Start:
    # Default-Stop:
    # Description:       God under multi-user RVM
    # Short-Description: Control God under multi-user RVM
    ### END INIT INFO
    
    
    # Source function library.
    . /etc/rc.d/init.d/functions
    
    
    prog=god
    exec=/usr/local/rvm/bin/bootup_$prog
    
    
    # Default values.
    CONFIG_FILE=/etc/god.conf.rb
    LOG_FILE=/var/log/god/god.log
    LOG_LEVEL=info
    PID_FILE=/var/run/god/god.pid
    
    
    start_god() {
      [ -x $exec ] || exit 5
      echo -n $"Starting $prog: "
      status_god_quiet && echo -n "already running" && warning && echo && exit 0
      daemon --user root "$exec \
        -c $CONFIG_FILE \
        -l $LOG_FILE \
        --log-level $LOG_LEVEL \
        -P $PID_FILE >/dev/null"
      retval=$?
      echo
      return $retval
    }
    
    
    stop_god() {
      echo -n $"Stopping $prog: "
      retval=0
      if ! status_god_quiet ; then
        echo -n "already stopped" && warning
      else
        $exec quit >/dev/null
        retval=$?
      fi
      echo
      return $retval
    }
    
    
    restart_god() {
      stop_god
      start_god
    }
    
    
    status_god() {
      status -p $PID_FILE $prog
    }
    
    
    status_god_quiet() {
      status_god >/dev/null 2>&1
    }
    
    
    case "$1" in
      start)
        start_god
        ;;
      stop)
        stop_god
        ;;
      restart)
        restart_god
        ;;
      status)
        status_god
        ;;
      *)
        echo $"Usage: $0 {start|stop|status|restart}"
        exit 2
    esac
    
    
    exit $?
    
  5. Be sure to change the CONFIG_FILE setting in the init script to match the location of the god config file you want to use.

  6. Make it executable:

    # chmod +x /etc/init.d/god
    
  7. Add it to chkconfig:

    $ chkconfig --add god
    $ chkconfig god on
    
  8. Start god:

    # /etc/init.d/god start
    

Using Papertrail

For CentOS 5.5:

  1. Install rsyslog if you don’t already have it:

    $ yum install rsyslog
    
  2. Use rsyslog instead of syslog:

  3. Add papertrail to rsyslog config.

  4. Stop syslog and start rsyslog:

    /etc/init.d/syslog stop && /etc/init.d/rsyslog start
    
  5. Configure startups:

    $ /sbin/chkconfig syslog off
    $ /sbin/chkconfig --level 2345 rsyslog on
    
  6. If SNMPd logging is too verbose

Segfaults with REE on ArchLinux

If you’re like me and develop on archlinux, but your Rails apps use REE still, you may have had some problems recently. Specifically, GCC 4.7 breaks REE, producing segfaults when you want to run code.

I recently realized the solution, which is pretty simple. Install GCC 4.6, then install REE with that instead.

$ sudo pacman -S gcc-4.6
$ rvm reinstall ree --with-gcc=/usr/bin/gcc-4.6