Hacks

A place to save and share all the nasty little hacks that make the world go round and round.

The word "hacker" has an unfairly negative connotation from being portrayed in the media as people who break into computers. In reality, hacking just means building something quickly or testing the boundaries of what can be done. Like most things, it can be used for good or bad, but the vast majority of hackers I’ve met tend to be idealistic people who want to have a positive impact on the world.

Mark Zuckerberg


Articles on Hacks

Gather Windows on Ubuntu

On my Ubuntu laptop, I found that when the display goes to sleep, I would consistantly have this issue where some of my active windows would end up on a hidden workspace. Super annoying, especially because I found myself having to kill the app to get them back. After a little googling, I found those following script, which when coupled with a custom keybinding did the trick.

I placed the following file in $HOME/bin, which I already have added to my path, and named it gather.

#!/bin/bash
# From: https://github.com/mezga0153/offscreen-window-restore

width=`xrandr | grep current | awk {'print $8'}`

`wmctrl -l -G | awk -v w=$width '{
    if ($8 != "unity-dash" && $8 != "Hud") {
        if ($3 >= w || $3 < 0) {
            system("wmctrl -i -r " $1 " -e 0," sqrt($3*$3) % w ",-1,-1,-1");
        }
    }
}'`

I then ensured that it was executable with chmod 755 $HOME/bin/gather. Once done, I added a keybind, for me Super-g, via System Settings > Keyboard > Shortcuts > Custom Shortcuts.

Note:

I had to install wmctrl as well for this to work, with:

apt-get install -y wmctrl

Enjoy!

boot2docker Wrapper Script

I put together this simple wrapper function for simplifying boot2docker interactions on my Macbook.

Note: I refer to .bashrc as the target as it's the more common shell. However, this has been tested and I personally use it within zsh.

Basic Usage

$ docker reload
# purge current boot2docker environment

$ docker up
# start boot2docker and export environment

$ docker reset|restart|reup
# stop and restart boot2docker

$ docker clean
# remove all orphaned image shards and all containers that aren't running - DANGEROUS

$ docker [etc]
# all other arguements are passed directly passed through to docker

The Functions

# file: ~/.bashrc

#############################################################
# Function -- Docker/Boot2Docker
#############################################################
function docker_shellinit {
  local _shellinit="$(boot2docker shellinit)"
  eval "$(echo ${_shellinit})"
  echo "${_shellinit}" > ~/.boot2dockerrc
}

function docker_reup {
  echo "+ running vpn fix"
  docker_down

  echo "+ resetting vbox route"

  local _iface="$(VBoxManage showvminfo boot2docker-vm --machinereadable | grep hostonlyadapter | cut -d '"' -f 2)"
  echo "++ sudo route -n add -net 192.168.59.0/24 -interface ${_iface}"

  sudo route -n add -net 192.168.59.0/24 -interface ${_iface} && \
    docker_up
}

function docker_reset {
  echo "+ clearing docker variables"
  unset DOCKER_HOST
  unset DOCKER_CERT_PATH
  unset DOCKER_TLS_VERIFY
  docker_shellinit
}

function docker_up {
  echo "+ starting boot2docker"
  boot2docker up
  b2dSTATUS=$?
  docker_reset
  return $b2dSTATUS
}

function docker_down {
  echo "+ stopping boot2docker"
  boot2docker down
  return 0
}

function docker_clean {
  echo "+ clean containers"
  docker ps -a | grep 'Exited ' | awk '{ print $NF }' | xargs docker rm
  docker ps -a | grep -v 'Up ' | awk '{ print $NF }' | xargs docker rm

  echo "+ clean images"
  docker images | grep '^<none>' | awk '{ print $3 }' | xargs docker rmi
}

function b2d {
  case "$@" in
  reload)
    docker_reset
    return 0;;
  reset|fix|reup|fuck)
    docker_reup
    return $?;;
  up)
    docker_up
    return $?;;
  down)
    docker_down
    return $?;;
  clean)
    docker_clean
    return $?;;
  esac
  boot2docker $@
}

docker_exec="$(which docker)"
function docker {
  case "$@" in
  reload)
    docker_reset
    return 0;;
  reset|fix|reup|fuck)
    docker_reup
    return $?;;
  up)
    docker_up
    return $?;;
  down)
    docker_down
    return $?;;
  clean)
    docker_clean
    return $?;;
  esac
  $docker_exec $@
}

Installation

$ curl -s https://gist.githubusercontent.com/jmervine/6713d10ab05fecd6e1aa/raw/5c5f7020696e23dffa6f046816239574f42767ee/boot2dockerrc.sh >> ~/.bashrc

Forking in Node.js / Threading HTTPerf with HTTPerf.js

Occasionally, we want to generate load beyond what a single httperf thread can handle, especially when working in Node.js, where the connection limits can get very high. The code sample below does that, but also serves as an example of how to use the cluster module to fork actions and collect the resulting data. Enjoy!

Simple Timing in Node.js

I just stumbled upon a cool feature of Node.js for adding timing to applications using console.time and console.timeEnd`.

// pointless example that show all parts
console.time('timer');
setTimeout(function() {
    console.timeEnd('timer');
}, 500);

// => timer: 511ms

Note: I've heard (and in somecases proven) that in most cases console. method are not asynchronous (i.e. blocking) and therefore should never be used in production code. Notice that in the above example, console.time and console.timeEnd appear to have about 11ms of overhead on my machine.

Pretty Sleep using Node.js

$ node -e 'n=0; setInterval(function(){n++;if(n>=20){console.log(".");process.exit(0);}process.stdout.write(".");},1000);'

WiFi/Bluetooth Hack for the HP Folio 13

Someone asked for this recently, I'm not going to go in to great detail at this time, but I found it while looking through my gists and thought I would share.

Simple replace your /etc/rc.local with the following and it should unlock the hardware airplane mode on startup.

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

rfkill unblock wifi
sleep 5
rmmod -w -s hp-wmi
#modprobe -r -s hp-wmi

exit 0

get the gist

Hack: Deploying with git and rake-remote_task

This is an update to my previous post: Hack: Deploying with git, replacing the use of pure rake, for rake-remote_task.

Add the following to your Rakefile

require 'rake/remote_task'

set :domain,      ENV.fetch(PRODUCTION_HOST, "www.yourhost.com")
set :environment, ENV.fetch(RACK_ENV,        "production")

set :app_path,    "/path/to/app/install"

remote_task :deploy do
  run "set -x; cd #{app_path} && git pull && bundle"
end

remote_task :restart do
  run "set -x; cd #{app_path} && RACK_ENV=#{environment} bundle exec rake unicorn:restart --trace"
end

Then run

$ RACK_ENV=production PRODUCTION_HOST=www.foohost.com bundle exec rake deploy restart

or just

$ RACK_ENV=production PRODUCTION_HOST=www.foohost.com bundle exec rake deploy

Note -- This assumes the following:

  • You've checked out your repo on your remote host.
  • You've setup your app and it's running on your remote server.
  • You're using using Unicorn.
  • You're using Bundler.

Install MySQL on CentOS 6

A simple script to install MySQL on CentOS 6.

#!/usr/bin/bash
#
# sudo bash < <(curl -s https://gist.github.com/jmervine/5373441/raw/)

set -x
cd /tmp
wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-shared-5.6.10-1.el6.x86_64.rpm/from/http://cdn.mysql.com/
wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-client-5.6.10-1.el6.x86_64.rpm/from/http://cdn.mysql.com/
wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-server-5.6.10-1.el6.x86_64.rpm/from/http://cdn.mysql.com/
wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-devel-5.6.10-1.el6.i686.rpm/from/http://cdn.mysql.com/

rpm -qa | grep mysql-libs && yum remove -y mysql-libs

yum install -y MySQL-shared-5.6.10-1.el6.x86_64.rpm
yum install -y MySQL-client-5.6.10-1.el6.x86_64.rpm
yum install -y MySQL-server-5.6.10-1.el6.x86_64.rpm
yum install -y MySQL-devel-5.6.10-1.el6.i686.rpm

Link to gist.

HTTPerf.rb Example

Here's an example of a simple script using HTTPerb.rb. It's a quick and dirty script used for getting quick differences between changes.

Using curl to Test HTTPS with Self Signed Certs

$ curl https://<domain>/path/to.html --insecure

Also see: HTTPS: Creating Slef-signed Certs.

Killing Caps Lock on Ubuntu

  1. Create xmodmap file:

     $ xmodmap -pke > ~/.xmodmap
    
  2. Edit the newly created ~/.xmodmap file, changing the line starting with keycode 66 = to map to a key of your choice. Here's an example where I'm mapping Caps Lock to the Escape key:

     keycode  66 = Escape NoSymbol Escape
    
  3. Load your new map, disabling Caps Lock:

     xmodmap ~/.xmodmap
    
  4. (optionally) You can set this to autostart when you launch Unity by creating the following file:

     $ cat .config/autostart/xmodmap.desktop
     [Desktop Entry]
     Type=Application
     Exec=xmodmap ~/.xmodmap
     Hidden=false
     NoDisplay=false
     X-GNOME-Autostart-enabled=true
     Name[en_US]=xmodmap
     Name=xmodmap
     Comment[en_US]=
     Comment=
    

Fast Hostname Completion with ZSH

Credit goes to this post for this: http://nion.modprobe.de/blog/archives/521-hostname-completion-with-zsh.html

In your ~/.zshrc

local knownhosts
knownhosts=( ${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[0-9]*}%%\ *}%%,*} )
zstyle ':completion:*:(ssh|scp|sftp):*' hosts $knownhosts

In your ~/.ssh/config

HashKnownHosts no

Thin Wrapper Script

Their may be others, there may be better, but this is mine.

# file: APP_ROOT/thin.sh
#
#!/usr/bin/env bash
# source config if present
test -f ./config/thinrc && source ./config/thinrc

# set up primary defaults
test "$RACK_ENV"  || RACK_ENV="development"
test "$THIN_PORT" || THIN_PORT="4321"
test "$THIN_PID"  || THIN_PID="./log/listener.pid"
test "$THIN_LOG"  || THIN_LOG="./log/listener.log"

test "$DEBUG"     && set -x

if ! test "$1"
then
    echo "Usage: listener start|stop|restart"
    echo " "
    echo "Takes the following overides as environemnt variables:"
    echo " "
    echo "  RACK_ENV  :: default $RACK_ENV"
    echo "  THIN_PORT :: default $THIN_PORT"
    echo "  THIN_PID  :: default $THIN_PID"
    echo "  THIN_LOG  :: default $THIN_LOG"
    echo " "
    echo "Takes config file as './config/thinrc' with overides above. "
    echo " "
    exit 0
fi

RACK_ENV=$RACK_ENV thin --port $THIN_PORT --pid $THIN_PID --log $THIN_LOG --daemonize $1

# vim: set filetype=sh

gist


And if you need external configs...

# file: APP_ROOT/config/thinrc
#
# Directory pathing context should be that of the thin
# init script sourcing this file, not this file itself.
#
# allow for overides as such
test "$RACK_ENV"  || RACK_ENV="production"
test "$THIN_PORT" || THIN_PORT="4321"
test "$THIN_PID"  || THIN_PID="./log/listener.pid"
test "$THIN_LOG"  || THIN_LOG="./log/listener.log"

# force defaults as such
#RACK_ENV="development"
#THIN_PORT="4321"
#THIN_PID="./log/listener.pid"
#THIN_LOG="./log/listener.log"

# vim: set filetype=sh

gist

What is Thin?


Published on in Ruby, Hacks

Rails script/server Unicorn Replacement

A script to replace script/server in Rails, which runs Unicorn over Webrick, because it's faster. This script is designed for development only!

Minimum Version Checking with BASH/ZSH

Thanks to @retr0h:

[[ $(zsh --version | awk '{print $2}') > 4.3.17 ]]

# usage

if [[ $(zsh --version | awk '{print $2}') > 4.3.17 ]]; then
    # do someting that only higher zsh versions support
else
    # do something else for low versions
fi

This was my origitional (not so sexy solution).

The following line will print zsh version information if the version is greater then or equal to 4.3.17, otherwise it will return blank:

zsh --version | awk '{print $2}' | awk -F'.' ' ( $1 > 4 || ( $1 == 4 && $2 > 3 ) || ( $1 == 4 && $2 == 3 && $3 >= 17 ) ) '

An example usage would be something like:

#!/usr/bin/env bash
if test "$( zsh --version | awk '{print $2}' | awk -F'.' ' ( $1 > 4 || ( $1 == 4 && $2 > 3 ) || ( $1 == 4 && $2 == 3 && $3 >= 17 ) ) ' )"
then
    # do someting that only higher zsh versions support
else
    # do something else for low versions
fi

Web Pasting with "gistcli"

Found this simple Python script which allows for cli gist posts -- (thanks to pranavk).

You can install it like so

$ mkdir ~/bin
$ echo "export PATH=~/bin:$PATH" >> ~/.zshrc
$ cd ~/bin
$ wget https://raw.github.com/pranavk/gist-cli/master/gistcli
$ chmod 755 gistcli
$ source ~/.zshrc

Usage examples

# simple echo to gist
echo "test gist" | gistcli

# file to gist
gistcli -f myfile.txt

# private
echo "ssssh, don't tell anyone!" | gistcli -p

# from tty, EOF from '.' on it's own line
gistcli -
Foo, bar bah bing!
.

Note: There's also a slightly more mature Ruby gist cli tool at github.com/defunkt/gist but I had issues getting it to work with my RMV setup.

Hack: Deploying with git

This has been updated, see: Hack: Deploying with git and rake-remote_remote

Add the following to your Rakefile

ENV['PRODUCTION_HOST'] ||= "www.yourhost.com"
task :deploy do
  system("ssh #{PRODUCTION_HOST} 'set -x; cd /path/to/app/install && git pull && bundle'")
end

desc "restart production" 
task :restart do
  system("ssh #{PRODUCTION_HOST} 'set -x; cd /path/to/app/install && RACK_ENV=#{ENV['RACK_ENV']} bundle exec rake unicorn:restart --trace'")
end

Then run

$ RACK_ENV=production PRODUCTION_HOST=www.foohost.com bundle exec rake deploy restart

or just

$ RACK_ENV=production PRODUCTION_HOST=www.foohost.com bundle exec rake deploy

Note -- This assumes the following:

  • You've checked out your repo on your remote host.
  • You've setup your app and it's running on your remote server.
  • You're using using Unicorn.
  • You're using Bundler.

Hack: Generating gh-pages

With rake

Add the following to your Rakefile

desc "generate and update gh-pages"
task :pages do
  system(" set -x; bundle exec rspec ") or abort
  system(" set -x; bundle exec yardoc --protected ./lib/**/*.rb ") or abort
  system(" set -x; mv -v ./doc /tmp ") or abort
  system(" set -x; mv -v ./coverage /tmp ") or abort
  system(" set -x; git checkout gh-pages ") or abort
  system(" set -x; rm -rf ./doc ./coverage ") or abort
  system(" set -x; mv -v /tmp/doc . ") or abort
  system(" set -x; mv -v /tmp/coverage . ") or abort
  system(" set -x; git add . ") or abort 
  system(" set -x; git commit --all -m 'updating doc and coverage' ") or abort
  system(" set -x; git checkout master ") or abort
  puts "don't forget to run: git push origin gh-pages"
end

Then run

$ bundle exec rake pages
$ git push gh-pages

Or less ugly, with bash...

Create scripts/pages

#!/usr/bin/env bash
set -xue 
bundle exec rspec 
bundle exec yardoc --protected ./lib/**/*.rb
mv -v ./doc /tmp 
mv -v ./coverage /tmp 
git checkout gh-pages
rm -rf ./doc ./coverage 
mv -v /tmp/doc .
mv -v /tmp/coverage . 
git add .
git commit --all -m 'updating doc and coverage'
git checkout master
echo "don't forget to run: git push origin gh-pages"

Then run

$ chmod 755 ./scripts/pages
$ ./scripts/pages

Note -- I opted for the rake method because I use rake in my projects.

BASH Arrays

Basic Array handling in BASH, because I always forget.

# basic itteration
items=( a b c d e )

for i in "${items[@]}"
do
    echo -n $i
done

#=> abcde

# update specific array slot
items[1]="foo"

# access specific array slot
echo ${items[1]}

#=> foo