class Provisionator::Ec2Userdata

Public Class Methods

new(options={}) click to toggle source
# File lib/provisionator/ec2_userdata.rb, line 5
def initialize options={}
  [:app_name, :chef_node, :chef_repo, :config_repo, :app_repo].each do |option|
    raise "option ':#{option}' is required" if options[option].nil?
  end
  @app_dir = "/home/ubuntu/.#{options[:app_name]}"
  @chef_dir = "#{@app_dir}/#{options[:chef_dir] || 'provision/chef'}"

  options[:ruby_patch] ||= 'p247'
  options[:ebs_mount_paths] = ebs_mount_paths(options[:ebs_volumes]) if options[:ebs_volumes]
  options[:rails_env] ||= 'production'
  @options = options
end

Public Instance Methods

ebs_mount_paths(ebs_volumes) click to toggle source
# File lib/provisionator/ec2_userdata.rb, line 19
def ebs_mount_paths ebs_volumes
  available_device_mappings = ("/dev/xvdf".."/dev/xvdp").to_a
  ebs_volumes.map do |ebs_volume|
    [available_device_mappings.shift, ebs_volume[:mount_location]]
  end
end
render() click to toggle source
# File lib/provisionator/ec2_userdata.rb, line 26
def render
  ERB.new(template).result(binding)
end
template() click to toggle source
# File lib/provisionator/ec2_userdata.rb, line 30
    def template
<<-TEMPLATE
#!/bin/bash -xe
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1

locale-gen en_US.UTF-8
dpkg-reconfigure locales
update-locale LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

<% if @options[:ebs_mount_paths] %>
  <% @options[:ebs_mount_paths].each do |device, mount_point| %>
    mkfs.ext4 <%= device %>
    mkdir -p -m 000 <%= mount_point %>
    echo "<%= device %> <%= mount_point %> auto noatime 0 0" >> /etc/fstab
    mount <%= device %> <%= mount_point %>
  <% end %>
<% end %>

apt-get update

function add_line_to_file {
  (test -f "$2" && grep "$1" $2) || echo "$1" >> $2
}

add_line_to_file "StrictHostKeyChecking no" /etc/ssh/ssh_config
add_line_to_file "UserKnownHostsFile=/dev/null" /etc/ssh/ssh_config

add_line_to_file "install: --no-document" /etc/skel/.gemrc
add_line_to_file "install: --no-document" /root/.gemrc
add_line_to_file "install: --no-document" /home/ubuntu/.gemrc
add_line_to_file "install: --no-document" /etc/gemrc

#install ruby
RUBY_PATCH=<%= @options[:ruby_patch] %>
function install_ruby {
  apt-get -y install build-essential zlib1g-dev libssl-dev libreadline-dev libyaml-dev libcurl4-openssl-dev
  cd /tmp
  wget ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.0.tar.gz
  tar -xvzf ruby-2.1.0.tar.gz
  cd ruby-2.1.0/
  ./configure --prefix=/usr/local
  make
  make install
}
ruby -v | grep 2.1.0 || install_ruby

function install_chef {
  gem install chef
  gem install ruby-shadow
  mkdir -p /var/cache/chef
  chown ubuntu:ubuntu /var/cache/chef
}
gem list | grep chef || install_chef

apt-get install git-core -y

gem install bundler

cd /home/ubuntu

<% if @options[:ssh_key] %>
  mkdir -p /home/ubuntu/.ssh
  echo "<%= @options[:ssh_key] %>" > /home/ubuntu/.ssh/id_rsa
  chown -R ubuntu:ubuntu /home/ubuntu/.ssh
  chmod 400 /home/ubuntu/.ssh/id_rsa
<% end %>

APP_NAME=<%= @options[:app_name] %>
APP_PATH=<%= @options[:app_path] || "/u/apps/#{@options[:app_name]}" %>

su ubuntu -c 'git clone <%= @options[:chef_repo] %> /home/ubuntu/.chef'
su ubuntu -c 'git clone <%= @options[:config_repo] %> /home/ubuntu/.config'
su ubuntu -c 'git clone <%= @options[:app_repo] %> /home/ubuntu/.<%= @options[:app_name] %>'

ln -s /home/ubuntu/.config/$APP_NAME/<%= @options[:rails_env] %>/app.sh /etc/profile.d/$APP_NAME.sh

. /etc/profile.d/$APP_NAME.sh
echo <%= @options[:chef_node] %> > /home/ubuntu/.chef_node
chown ubuntu:ubuntu /home/ubuntu/.chef_node

<% unless @options[:no_release] %>
  mkdir -p $APP_PATH $APP_PATH/releases $APP_PATH/shared $APP_PATH/shared/system $APP_PATH/shared/log $APP_PATH/shared/pids $APP_PATH/shared/sockets
  chmod g+w $APP_PATH $APP_PATH/releases $APP_PATH/shared $APP_PATH/shared/system $APP_PATH/shared/log $APP_PATH/shared/pids $APP_PATH/shared/sockets
  chown -R ubuntu:ubuntu /u/
  su ubuntu -c "git clone -q #{@options[:app_repo]} $APP_PATH/shared/cached-copy"
  $(cd $APP_PATH/shared/cached-copy && APP_REVISION=$(git rev-parse HEAD))
  cp -RPp $APP_PATH/shared/cached-copy $APP_PATH/releases/20130516070710
  echo $APP_REVISION > $APP_PATH/releases/20130516070710/REVISION
  ln -s $APP_PATH/releases/20130516070710 $APP_PATH/current
  test -d $APP_PATH/current/log && rm -R $APP_PATH/current/log
  ln -s $APP_PATH/shared/log $APP_PATH/current/log 
  mkdir $APP_PATH/current/tmp
  ln -s $APP_PATH/shared/pids/ $APP_PATH/current/tmp/pids
  ln -s $APP_PATH/shared/database.yml $APP_PATH/current/config/

  <% if @options[:chef_pre_bundle] %>
    chef-solo -c <%= "#{@chef_dir}/solo.rb" %> -j <%= "#{@chef_dir}/#{@options[:chef_pre_bundle]}.json" %> -l debug
  <% end %>

  bundle install --gemfile $APP_PATH/releases/20130516070710/Gemfile --path $APP_PATH/shared/bundle --deployment --without development test
  chown -R ubuntu:ubuntu /u/
<% end %>

chef-solo -c <%= "#{@chef_dir}/solo.rb" %> -j <%= "#{@chef_dir}/#{@options[:chef_node]}.json" %> -l debug
TEMPLATE
    end