forked from poise/application_ruby
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Checkpoint lots of work. Includes application cookbook split to appli…
…cation_(rails, django). Also hey look, Django and Gunicorn plugins!
- Loading branch information
0 parents
commit a100358
Showing
14 changed files
with
803 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
{ | ||
"id": "my_app", | ||
"server_roles": [ | ||
"application specific role(s), typically the name of the app, e.g., my_app", | ||
"my_app" | ||
], | ||
"type": { | ||
"my_app": [ | ||
"recipes in this application cookbook to run for this role", | ||
"rails", | ||
"unicorn" | ||
] | ||
}, | ||
"memcached_role": [ | ||
"name of the role used for the app-specific memcached server", | ||
"my_app_memcached" | ||
], | ||
"database_slave_role": [ | ||
"name of the role used by database slaves, typically named after the app, 'my_app_database_slave'", | ||
"my_app_database_slave" | ||
], | ||
"database_master_role": [ | ||
"name of the role used by database master, typically named after the app 'my_app_database_master'", | ||
"my_app_database_master" | ||
], | ||
"repository": "git@github.com:company/my_app.git", | ||
"revision": { | ||
"production": "commit hash, branch or tag to deploy" | ||
}, | ||
"force": { | ||
"production": "true or false w/o quotes to force deployment, see the rails.rb recipe" | ||
}, | ||
"migrate": { | ||
"production": "true or false boolean to force migration, see rails.rb recipe" | ||
}, | ||
"databases": { | ||
"production": { | ||
"reconnect": "true", | ||
"encoding": "utf8", | ||
"username": "db_user", | ||
"adapter": "mysql", | ||
"password": "awesome_password", | ||
"database": "db_name_production" | ||
} | ||
}, | ||
"mysql_root_password": { | ||
"production": "password for the root user in mysql" | ||
}, | ||
"mysql_debian_password": { | ||
"production": "password for the debian-sys-maint user on ubuntu/debian" | ||
}, | ||
"mysql_repl_password": { | ||
"production": "password for the 'repl' user for replication." | ||
}, | ||
"snapshots_to_keep": { | ||
"production": "if using EBS, integer of the number of snapshots we're going to keep for this environment." | ||
}, | ||
"deploy_key": "SSH private key used to deploy from a private git repository", | ||
"deploy_to": "path to deploy, e.g. /srv/my_app", | ||
"owner": "owner for the application files when deployed", | ||
"group": "group for the application files when deployed", | ||
"packages": { | ||
"package_name": "specific packages required for installation at the OS level to run the app like libraries and specific version, e.g.", | ||
"curl": "7.19.5-1ubuntu2" | ||
}, | ||
"gems": { | ||
"gem_name": "specific gems required for installation to run the application, and if a specific version is required, e.g.", | ||
"rails": "2.3.5" | ||
}, | ||
"memcached": { | ||
"production": { | ||
"namespace": "specify the memcache namespace, ie my_app_environment" | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name "production" | ||
description "Production environment" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
maintainer "Opscode, Inc." | ||
maintainer_email "cookbooks@opscode.com" | ||
license "Apache 2.0" | ||
description "Deploys and configures Rails applications" | ||
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) | ||
version "0.99.12" | ||
|
||
%w{ application runit unicorn apache2 passenger_apache2 }.each do |cb| | ||
depends cb | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# | ||
# Author:: Noah Kantrowitz <noah@opscode.com> | ||
# Cookbook Name:: application | ||
# Provider:: rails | ||
# | ||
# Copyright:: 2011, Opscode, Inc <legal@opscode.com> | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
action :before_compile do | ||
|
||
new_resource.migration_command "rake db:migrate" if !new_resource.migration_command | ||
|
||
new_resource.environment.update({ | ||
"RAILS_ENV" => new_resource.environment_name, | ||
}) | ||
|
||
new_resource.symlink_before_migrate.update({ | ||
"database.yml" => "config/database.yml", | ||
"memcached.yml" => "config/memcached.yml", | ||
}) | ||
|
||
end | ||
|
||
action :before_deploy do | ||
|
||
new_resource.environment['RAILS_ENV'] = new_resource.environment_name | ||
|
||
new_resource.gems.each do |gem, ver| | ||
gem_package gem do | ||
action :install | ||
version ver if ver && ver.length > 0 | ||
end | ||
end | ||
|
||
if new_resource.database_master_role | ||
dbm = nil | ||
# If we are the database master | ||
if node['roles'].include?(new_resource.database_master_role) | ||
dbm = node | ||
else | ||
# Find the database master | ||
results = search(:node, "role:#{new_resource.database_master_role} AND chef_environment:#{node.chef_environment}", nil, 0, 1) | ||
rows = results[0] | ||
if rows.length == 1 | ||
dbm = rows[0] | ||
end | ||
end | ||
|
||
# Assuming we have one... | ||
if dbm | ||
template "#{new_resource.path}/shared/database.yml" do | ||
source "database.yml.erb" | ||
cookbook "application_rails" | ||
owner new_resource.owner | ||
group new_resource.group | ||
mode "644" | ||
variables( | ||
:host => (dbm.attribute?('cloud') ? dbm['cloud']['local_ipv4'] : dbm['ipaddress']), | ||
:database => new_resource.database, | ||
:rails_env => new_resource.environment_name | ||
) | ||
end | ||
else | ||
Chef::Log.warn("No node with role #{new_resource.database_master_role}, database.yml not rendered!") | ||
end | ||
end | ||
|
||
if new_resource.memcached_role | ||
results = search(:node, "role:#{new_resource.memcached_role} AND chef_environment:#{node.chef_environment} NOT hostname:#{node[:hostname]}") | ||
if results.length == 0 | ||
if node['roles'].include?(new_resource.memcached_role) | ||
results << node | ||
end | ||
end | ||
template "#{new_resource.path}/shared/memcached.yml" do | ||
source "memcached.yml.erb" | ||
cookbook "application_rails" | ||
owner new_resource.owner | ||
group new_resource.group | ||
mode "644" | ||
variables( | ||
:memcached_envs => new_resource.memcached, | ||
:hosts => results.sort_by { |r| r.name } | ||
) | ||
end | ||
end | ||
|
||
end | ||
|
||
action :before_migrate do | ||
|
||
gem_names = new_resource.gems.map{|gem, ver| gem} | ||
if gem_names.include?('bundler') | ||
Chef::Log.info "Running bundle install" | ||
directory "#{new_resource.path}/shared/vendor_bundle" do | ||
owner new_resource.owner | ||
group new_resource.group | ||
mode '0755' | ||
end | ||
link "#{new_resource.release_path}/vendor/bundle" do | ||
to "#{new_resource.path}/shared/vendor_bundle" | ||
end | ||
common_groups = %w{development test cucumber staging production} | ||
bundler_deployment = new_resource.bundler_deployment | ||
if bundler_deployment.nil? | ||
# Check for a Gemfile.lock | ||
bundler_deployment = ::File.exists?(::File.join(new_resource.release_path, "Gemfile.lock")) | ||
end | ||
execute "bundle install #{bundler_deployment ? "--deployment " : ""}--without #{(common_groups -([node.chef_environment])).join(' ')}" do | ||
ignore_failure true | ||
cwd new_resource.release_path | ||
end | ||
elsif gem_names.include?('bundler08') | ||
Chef::Log.info "Running gem bundle" | ||
execute "gem bundle" do | ||
ignore_failure true | ||
cwd new_resource.release_path | ||
end | ||
else | ||
# chef runs before_migrate, then symlink_before_migrate symlinks, then migrations, | ||
# yet our before_migrate needs database.yml to exist (and must complete before | ||
# migrations). | ||
# | ||
# maybe worth doing run_symlinks_before_migrate before before_migrate callbacks, | ||
# or an add'l callback. | ||
execute "(ln -s ../../../shared/database.yml config/database.yml && rake gems:install); rm config/database.yml" do | ||
ignore_failure true | ||
cwd new_resource.release_path | ||
end | ||
end | ||
|
||
if new_resource.migration_command.include?('rake') && !gem_names.include?('rake') | ||
gem_package "rake" do | ||
action :install | ||
end | ||
end | ||
|
||
end | ||
|
||
action :before_symlink do | ||
|
||
ruby_block "remove_run_migrations" do | ||
block do | ||
if node.role?("#{new_resource.id}_run_migrations") | ||
Chef::Log.info("Migrations were run, removing role[#{new_resource.id}_run_migrations]") | ||
node.run_list.remove("role[#{new_resource.id}_run_migrations]") | ||
end | ||
end | ||
end | ||
|
||
end | ||
|
||
action :before_restart do | ||
end | ||
|
||
action :after_restart do | ||
end | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# | ||
# Author:: Noah Kantrowitz <noah@opscode.com> | ||
# Cookbook Name:: application | ||
# Provider:: unicorn | ||
# | ||
# Copyright:: 2011, Opscode, Inc <legal@opscode.com> | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
action :before_compile do | ||
new_resource.restart_command "/etc/init.d/#{new_resource.id} hup" if !new_resource.restart_command | ||
end | ||
|
||
action :before_deploy do | ||
end | ||
|
||
action :before_migrate do | ||
end | ||
|
||
action :before_symlink do | ||
end | ||
|
||
action :before_restart do | ||
|
||
new_resource = @new_resource | ||
|
||
unicorn_config "/etc/unicorn/#{new_resource.id}.rb" do | ||
listen({ new_resource.port => new_resource.options }) | ||
working_directory ::File.join(new_resource.path, 'current') | ||
worker_timeout new_resource.worker_timeout | ||
preload_app new_resource.preload_app | ||
worker_processes new_resource.worker_processes | ||
before_fork new_resource.before_fork | ||
end | ||
|
||
runit_service new_resource.id do | ||
template_name 'unicorn' | ||
cookbook 'application_rails' | ||
options( | ||
:app => new_resource, | ||
:rails_env => new_resource.environment_name, | ||
:smells_like_rack => ::File.exists?(::File.join(new_resource.path, "current", "config.ru")) | ||
) | ||
run_restart false | ||
end | ||
|
||
end | ||
|
||
action :after_restart do | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# | ||
# Author:: Noah Kantrowitz <noah@opscode.com> | ||
# Cookbook Name:: application | ||
# Resource:: rails | ||
# | ||
# Copyright:: 2011, Opscode, Inc <legal@opscode.com> | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
include Chef::Resource::ApplicationBase | ||
|
||
attribute :database_master_role, :kind_of => [String, NilClass], :default => nil | ||
attribute :memcached_role, :kind_of => [String, NilClass], :default => nil | ||
attribute :gems, :kind_of => [Array, Hash], :default => [] | ||
attribute :bundler_deployment, :kind_of => [NilClass, TrueClass, FalseClass], :default => nil | ||
|
||
def database(*args, &block) | ||
@database ||= Mash.new | ||
@database.update(options_block(*args, &block)) | ||
end | ||
|
||
def memcached(*args, &block) | ||
@database ||= Mash.new | ||
@database.update(options_block(*args, &block)) | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# | ||
# Author:: Noah Kantrowitz <noah@opscode.com> | ||
# Cookbook Name:: application | ||
# Resource:: unicorn | ||
# | ||
# Copyright:: 2011, Opscode, Inc <legal@opscode.com> | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
include Chef::Resource::ApplicationBase | ||
|
||
attribute :preload_app, :kind_of => [TrueClass, FalseClass], :default => false | ||
attribute :worker_processes, :kind_of => Integer, :default => [node[:cpu][:total].to_i * 4, 8].min | ||
attribute :before_fork, :kind_of => String, :default => 'sleep 1' | ||
attribute :port, :kind_of => Integer, :default => 8080 | ||
attribute :worker_timeout, :kind_of => Integer, :default => 60 | ||
attribute :bundler, :kind_of => [TrueClass, FalseClass], :default => false | ||
|
||
def options(*args, &block) | ||
@options ||= Mash[:tcp_nodelay => true, :backlog => 100] | ||
@options.update(options_block(*args, &block)) | ||
end |
Oops, something went wrong.