Created
November 6, 2014 07:46
-
-
Save hemalvarambhia/aa5b5954da7b97fc767d to your computer and use it in GitHub Desktop.
One of the recipes in the legacy chef repo shown at the November London Chef Users Meetup.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Determine which apps require the 'app' tier to be set up on this node: | |
tier_apps = ai_stack.apps_for_tier(node, 'app') | |
# Initialize an array to store user names that will later be added to the | |
# "sshlogin" group: | |
sshlogin_users = [] | |
# Perform configuration required by all apps: | |
unless tier_apps.empty? | |
# Ensure all dependencies necessary to build Ruby are present: | |
include_recipe 'build-essential' | |
# Install packages useful for apps that use the asset pipeline functionality. | |
include_recipe 'ai_stack::asset_pipeline' | |
ruby_dependencies = %w{ | |
openssl libreadline6 libreadline6-dev zlib1g zlib1g-dev libssl-dev libyaml-dev | |
libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libc6-dev libncurses5-dev | |
} | |
ruby_dependencies.each { |name| package(name) } | |
# Ensure PostgreSQL client libraries are installed: | |
include_recipe 'postgresql::client' | |
package 'libpq-dev' | |
# Ensure runit is installed: | |
include_recipe 'runit' | |
# Ensure mercurial is installed: | |
include_recipe 'mercurial' | |
# Include the logrotate recipe: | |
include_recipe 'logrotate' | |
end | |
# Configure apps which run on this node: | |
tier_apps.each do |app_name, tiers| | |
spec = data_bag_item('ai_apps', app_name) | |
user_name = spec['user'] | |
user_home = "/home/#{user_name}" | |
# Create a user for the app: | |
user(user_name) do | |
home user_home | |
shell "/bin/bash" | |
supports :manage_home => true | |
end | |
# Generate an SSH key: | |
execute("ssh-keygen") do | |
command %Q{ssh-keygen -q -t rsa -f #{user_home}/.ssh/id_rsa -P ""} | |
user user_name | |
group user_name | |
cwd user_home | |
creates "#{user_home}/.ssh/id_rsa.pub" | |
end | |
# Create an authorized_keys file populated with developer SSH keys: | |
template "#{user_home}/.ssh/authorized_keys" do | |
source "authorized_keys.erb" | |
owner user_name | |
group user_name | |
mode "0644" | |
variables(:ssh_keys => search(:ssh_keys, '*:*')) | |
end | |
# Add any extra package repositories | |
if spec['package_repositories'] | |
spec['package_repositories'].each do |repo| | |
apt_repository repo[:name] do | |
uri repo[:uri] | |
distribution repo[:distribution] # e.g. lucid | |
components repo[:components] # e.g. ["main"] | |
keyserver repo[:keyserver] | |
key repo[:key] | |
end | |
end | |
end | |
# Install any OS packages required by the application: | |
if spec['packages'] | |
spec['packages'].each { |package_name| package(package_name) } | |
end | |
# Add the app user to any required groups: | |
if spec['groups'] | |
spec['groups'].each do |group_name| | |
group(group_name) do | |
action :modify | |
members [user_name] | |
append true | |
end | |
end | |
end | |
package("curl") do | |
not_if "test -f #{user_home}/.rvm" | |
end | |
package("git-core") do | |
not_if "test -f #{user_home}/.rvm" | |
end | |
# Install RVM: | |
bash("install rvm for #{app_name}") do | |
code "bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)" | |
user user_name | |
group user_name | |
cwd user_home | |
creates "#{user_home}/.rvm" | |
environment({"HOME" => user_home}) | |
end | |
# Alter the user's .bashrc file so that RVM is loaded correctly in interactive and non-interactive shells: | |
cookbook_file("#{user_home}/.bashrc") do | |
source "bashrc" | |
owner user_name | |
group user_name | |
mode "0644" | |
action :create | |
end | |
# Create a $HOME/bin directory: | |
directory "#{user_home}/bin" do | |
owner user_name | |
group user_name | |
mode "0755" | |
end | |
# Install the rvm_wrapper.sh script in the $HOME/bin directory: | |
rvm_wrapper = "#{user_home}/bin/rvm_wrapper.sh" | |
template(rvm_wrapper) do | |
source "rvm_wrapper.sh.erb" | |
owner user_name | |
group user_name | |
mode "0755" | |
variables(:user_home => user_home) | |
end | |
# Install the required Ruby versions: | |
ruby_versions = spec['ruby'] | |
default_ruby_version = ruby_versions.first | |
## | |
# NOTE jruby installs seem to be a bit flakey | |
## | |
ruby_versions.each do |ruby_version| | |
bash("rvm install for #{ruby_version}") do | |
user user_name | |
group user_name | |
code "#{rvm_wrapper} rvm install #{ruby_version}" | |
## | |
# This line seems to cause problems when there are two users with the | |
# same ruby version. The second one is assumed to be installed to the | |
# user but it is actually installed to the other user | |
# | |
# However you will get a spurious message about reinstalling ruby | |
# | |
## | |
# not_if "#{rvm_wrapper} rvm list | grep #{ruby_version}", :user => user_name | |
end | |
# Create an RVM wrapper script for bundler: | |
bash("rvm bundler wrapper for #{ruby_version}") do | |
user user_name | |
code "#{rvm_wrapper} rvm wrapper #{ruby_version} #{app_name} bundle" | |
creates "#{user_home}/.rvm/bin/#{app_name}_bundle" | |
end | |
end | |
# Set the default Ruby version to the first version given: | |
bash("rvm default to #{default_ruby_version}") do | |
user user_name | |
group user_name | |
code "#{rvm_wrapper} rvm --default use #{default_ruby_version}" | |
not_if "#{rvm_wrapper} rvm list default | grep #{default_ruby_version}", :user => user_name | |
end | |
# Gems, if installed, will be installed against the default version of ruby | |
if spec['gems'] | |
# Install gems manually for applications that don't manage their dependencies | |
# using Bundler: | |
spec['gems'].each do |name, version_and_source| | |
version, source = version_and_source | |
# Use rubygems.org as the default gem source: | |
source ||= 'http://rubygems.org' | |
bash("gem install #{name}") do | |
user user_name | |
code "#{rvm_wrapper} gem install #{name} --version #{version} --source #{source}" | |
not_if "#{rvm_wrapper} gem list | grep #{name} | grep #{version}", :user => user_name | |
end | |
end | |
else | |
# Install the Bundler gem: | |
bash("gem install bundler") do | |
user user_name | |
code "#{rvm_wrapper} gem install bundler" | |
not_if "#{rvm_wrapper} gem list | grep bundler", :user => user_name | |
end | |
end | |
# Create a service directory for the app user: | |
user_service_dir = "#{user_home}/service" | |
directory(user_service_dir) do | |
owner user_name | |
group user_name | |
mode "0755" | |
end | |
# Create a new runsvdir service for the app service directory: | |
runsvdir_path = "/etc/sv/runsvdir-#{user_name}" | |
directory(runsvdir_path) do | |
owner "root" | |
group "root" | |
mode "0755" | |
end | |
# Create a run script for the runsvdir service: | |
template(File.join(runsvdir_path, "run")) do | |
source "runsvdir.erb" | |
owner "root" | |
group "root" | |
mode "0755" | |
variables(:user_name => user_name, :service_dir => "#{user_home}/service") | |
end | |
# And tell runit about the runsvdir service: | |
link("/etc/service/#{File.basename(runsvdir_path)}") { to runsvdir_path } | |
# Create a directory for the application to live in: | |
app_path = "#{user_home}/#{spec['id']}" | |
directory(app_path) do | |
owner user_name | |
group user_name | |
mode "0755" | |
end | |
# Create an app "shared" directory: | |
shared_path = "#{app_path}/shared" | |
directory(shared_path) do | |
owner user_name | |
group user_name | |
mode "0755" | |
end | |
# Create a database.yml file: | |
template("#{shared_path}/database.yml") do | |
source "database.yml.erb" | |
owner user_name | |
group user_name | |
mode "0755" | |
variables(:data => spec) | |
end | |
# Configure logrotate: | |
package "dbus" | |
logrotate_app "app-#{user_name}-logs" do | |
cookbook "logrotate" | |
path "#{shared_path}/log/*.log" | |
frequency "daily" | |
rotate 30 | |
create "644 #{user_name} #{user_name}" | |
dateext | |
end | |
# Any application running it's "app" tier on this node should also be part of the sshlogin group: | |
sshlogin_users << user_name | |
end | |
# Allow application users to login via SSH (for deployment): | |
group "sshlogin" do | |
members sshlogin_users | |
append true | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment