Set Ansible Variables from the Command Line

If you ever wanted pass in ‘parameters’ to your Ansible playbooks via the command line when you are running the playbook through ansible-playbook here is the way to do it. Command line ansible-playbook --extra-vars '{"NODE_ENV":"staging","GIT_BRANCH":"develop"}' playbook.yml or the shorter version (thanks mpdehaan) ansible-playbook "-e 'NODE_ENV=staging GIT_BRANCH=develop'" playbook.yml Here you are setting NODE_ENV and GIT_BRANCH variables (if it wasn’t obvious). Now inside your playbook you will have something like the following - name: Node apps deploy hosts: all gather_facts: no vars: git_branch: "{{ GIT_BRANCH|default('develop') }}" node_env: "{{ NODE_ENV|default('staging') }}" tasks: - command echo "{{ node_env }}" - command echo "{{ git_branch }}" That’s about it. ...

October 24, 2014

Setting up Centralized Logging to S3 with logrotated

What we are trying to do here Get all logs to be backup to S3 whenever logrotated runs or whenever the machine is shutdown/restarted (so that if you have AWS auto scaling enabled, you won’t loose any logs). Basic Steps Install s3cmd Setup a script to upload logs to S3 (that’ll be called via logrotated) Setup a init.d script to run logrotated -f (forced) on shutdown/restart Setup logrotated scripts to call your S3 upload script Install s3cmd sudo apt-get install s3cmd setup s3cmd by running ...

August 27, 2014

Using Varnish (v4) as a reverse proxy cache with Rails

Setting up Varnish You can install varnish by following the official installation guide (this one is for Ubuntu, but you can find a official guide that supports your OS) at: https://www.varnish-cache.org/installation/ubuntu Make sure to edit /etc/default/varnish and change DEAMON_OPTS so that varnish listens on port 80 /etc/default/varnish DAEMON_OPTS="-a :80 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,256m" Caching only selected requests (white listing what to be cached) The following code will ensure that Varnish will only cache whatever that matches the filters define. Everything else will be passed to the backend. ...

August 22, 2014

Using MongoDB 2.6 with TravisCI Builds

At the time of writing this post TravisCI uses mongodb 2.4 (when you put in mongodb under services in .travis.yml) and does not support the new version 2.6 ‘out of the box’. However, if you do need 2.6 for your code to run properly you could easily install it your self. You can add the following to your before_install (in .travis.yml) to do that. .travis.yml before_install: - "sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10" - "echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list" - "sudo apt-get update" - "sudo apt-get install mongodb-org-server” References https://github.com/travis-ci/travis-ci/issues/2246 https://github.com/kraih/mango/blob/master/.travis.yml

July 11, 2014

Configuring TravisCI and Coveralls for a node.js project

First include your coveralls token in. .coveralls.yml service_name: travis-pro repo_token: your_token We were already using mocha. And to get the coverage data I’ve added istanbul plus the coveralls module for actually submitting that data to coveralls. package.json "devDependencies": { "mocha": "~1.19.0", "istanbul": "^0.2.10", "coveralls": "^2.10.0" } Makefile In the Makefile, I’ve added a build step called test-coveralls test-coveralls: @NODE_ENV=test ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha */test/*.js --report lcovonly -- -R spec -t 30000 Which, when run will generate coverage data and save it in ...

May 30, 2014

Solving 'Rails bug': 3.0.20: UTF8-encoded JSON request params result in Encoding::CompatibilityError

So I ran acrross a bug: 3.0.20: UTF8-encoded JSON request params result in Encoding::CompatibilityError (https://github.com/rails/rails/issues/9136( in Rails 3.0.20. Which is no longer supported. And ended up writing the Rack middlewear listed below as a ‘fix’. My code is heavily inspired by this post here by Pivotal Labs: Sanitizing POST params with custom Rack middleware (http://pivotallabs.com/sanitizing-post-params-with-custom-rack-middleware/) Rack Middlewear for force_encoding request bodies to UTF-8 JSONScrubber # config/initializers/json_scrubber.rb require 'uri' class JSONScrubber def initialize(app, options) @app = app @routes = options[:routes] end def call(env) scrub(env) @app.call(env) end private def scrub(env) return unless @routes.include?(env['PATH_INFO']) rack_input = env['rack.input'].read.force_encoding(Encoding::UTF_8) env['rack.input'] = StringIO.new(rack_input) ensure env['rack.input'].rewind end end Rails.application.config.middleware.insert_before(0, JSONScrubber, routes: ['/api/some_action_here.json']) JSONScrubberSpec # json_scrubber_spec.rb # encoding: UTF-8 require 'spec_helper' describe JSONScrubber do let(:app) { ->(env) { [200, env, "app"] } } let :middleware do JSONScrubber.new(app, routes: ['/api/some_action_here.json']) end it 'converts non UTF-8 (ASCII-8BIT) encoded response bodies (with special characters) to UTF-8 encoded response bodies' do env = env_for('http://app.abcapp.com.au/api/some_action_here.json') request_array = set_input_and_call env, 'ASCII-8BIT' expect(request_array[0]).to eq(200) expect(request_array[1]['rack.input'].read.encoding.to_s).to eq('UTF-8') end it 'process UTF-8 encoded response bodies (with special characters) without issue' do env = env_for('http://app.abcapp.com.au/api/some_action_here.json') request_array = set_input_and_call env, 'UTF-8' expect(request_array[0]).to eq(200) expect(request_array[1]['rack.input'].read.encoding.to_s).to eq('UTF-8') end it "will only modify requests who's paths match the given path options" do env = env_for('http://app.abcapp.com.au/api/dont_touch_me.json') request_array = set_input_and_call env, 'ASCII-8BIT' expect(request_array[0]).to eq(200) expect(request_array[1]['rack.input'].read.encoding.to_s).to eq('ASCII-8BIT') end def env_for url, opts={} Rack::MockRequest.env_for(url, opts) end def set_input_and_call env, encoding rack_input = %q("{"data":{"name":"Name ❤ ☀ ☆ ☂ ☻ ♞ ☯ ☭ ☢ € → ☎ ❄ ♫ ✂ ▷ ✇ ♎ ⇧ ☮ ♻ ⌘ ⌛ ☘","email":"[email protected]","org":"Sch☂ ☻ool","day":"Teacher"}}") env['rack.input'] = StringIO.new(rack_input.force_encoding(encoding)) env['rack.input'].rewind middleware.call(env) end end This should force_encode all request bodies to UTF-8. So if they happen to have any special unicode characters it won’t break your code. ...

May 16, 2014

Ruby Time.parse, Time. strptime and Time zones

This is a note to myself. So it might not be entirly useful to other folks. Note: my system’s time zone is set to +1000 Brisbane time. Recently I stumbled accross a bug in our code base where, Time.parse was used (incorrectly) to create a Time object from a string. Time and specially Time.zone related stuff tend to be very complicated and is quite easy to misunderstand. The whole codebase was full of lines of code like the following: ...

May 14, 2014

Installing gems with native extensions on TravisCI

I was mucking around with TravisCI recently. And when I was setting up a Rails project with travis. I hit a wall trying to get a ruby gem (https://github.com/da4nik/geoip2) with a native extention (https://github.com/maxmind/libmaxminddb) to get to install on travis. Thanks to GeoIP2-python (https://github.com/maxmind/GeoIP2-python/blob/master/.travis.yml)'s travis.yml I figured out how to solve the issue. It’s pretty straight forward really. Travis builds your project on a Ubuntu machine on cloud. So you’d install anything on it just as you would on a Ubuntu box. ...

May 13, 2014

virt-resize --shrink : Resizing a KVM VM Storage Image (which is a LVM partition)

I had to do some work relating to kvm last week. Including resizing (shrinking) a existing VM and then making a clone of it. I had to do a fair bit of googling and tinkering around to figure out how this can be done. Below is a summary of what I ended up doing. Note The fact that the storage images of the VMs were infact LVM partitions played a part in how I had to go about doing the resizing. In retrospect, if LVM was out of the picture (and the if the images were just files) things would have been much easier. Of course this does not mean that LVM + KVM is a bad thing. It makes things a little bit more complicated though. ...

April 9, 2014

Renting a room in Australia

I recently moved to Gold Coast, Queensland, Australia. Finding accommodation seemed a bit daunting at first. I was looking to a rent a room, or shared accommodation in other words. If you are in the same situation the following information should make things a bit easier for you. And of course most of the information bellow is not Queensland specific. Sites Best sites to find rooms for rent (housemates, flatmates, house share…etc) ...

April 6, 2014