Initial Chef repository

This commit is contained in:
Greg Karékinian
2015-07-21 19:45:23 +02:00
parent 7e5401fc71
commit ee4079fa85
1151 changed files with 185163 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
application Cookbook CHANGELOG
=======================
This file is used to list changes made in each version of the application cookbook.
v4.1.6
------
- Support for Chef 12.
- Add `strict_ssh` option to enable host key checking.
- Add `keep_releases` option to control number of releases to keep.
- Allow passing a path to a file for `deploy_key`.
v4.1.4
------
### Bug
- **[COOK-3343](https://tickets.opscode.com/browse/COOK-3343)** - Can't parse release candidate version number
v4.1.2
------
### Bug
- **[COOK-3343](https://tickets.opscode.com/browse/COOK-3343)** - Can't parse release candidate version number
v4.1.0
------
### Bug
- [COOK-3343] - Can't parse release candidate version number
v4.0.0
------
### Breaking
- Removes compatability with Chef 10
### Improvement
- **[COOK-3564](https://tickets.opscode.com/browse/COOK-3564)** - Replace calls to `Chef::Mixin::RecipeDefinitionDSLCore`
v3.0.0
------
### Bug
- [COOK-3306]: Multiple Memory Leaks in Application Cookbook
v2.0.4
------
### Bug
- [COOK-2812]: application cookbook doesn't allow to specify a block as `restart_command`
v2.0.2
------
### Bug
- [COOK-2537]: Provide proper `respond_to` behavior when using `method_missing`
- [COOK-2713]: application resource should Allow sub-resource attributes to propogate up
### Improvement
- [COOK-2597]: Allow customization for `shallow_clone` when doing a git deploy
v2.0.0
------
This release is incompatible with previous releases (hence major version change). The recipes used in older versions are deprecated and completely removed. See README.md for further detail.
- [COOK-1673] - `deploy_revision` in the application cookbook gives an argument error
- [COOK-1820] - Application cookbook: remove deprecated recipes
v1.0.4
------
- [COOK-1567] - Add git submodules to application cookbook
v1.0.2
------
- [COOK-1312] - string callbacks fail with method not found (really included this time)
- [COOK-1332] - add `release_path` and `shared_path` methods
- [COOK-1333] - add example for running migrations
- [COOK-1360] - fix minor typos in README
- [COOK-1374] - use runit attributes in unicorn run script
v1.0.0
------
This release introduces the LWRP for application deployment, as well as other improvements. The recipes will be deprecated in August 2012 as indicated by their warning messages and in the README.md.
- [COOK-634] - Implement LWRP for application deployment
- [COOK-1116] - use other SCMs than git
- [COOK-1252] - add `:force_deploy` that maps to corresponding action of deploy resource
- [COOK-1253] - fix rollback error
- [COOK-1312] - string callbacks fail with method not found
- [COOK-1313] - implicit file based hooks aren't invoked
- [COOK-1318] - Create `to_ary` method to resolve issue in resources() lookup on "application[foo]" resources
v0.99.14
--------
- [COOK-1065] - use pip in virtualenv during deploy
v0.99.12
--------
- [COOK-606] application cookbook deployment recipes should use ipaddress instead of fqdn
v0.99.11
--------
- make the `_default` `chef_environment` look like production rails env
v0.99.10
--------
- Use Chef 0.10's `node.chef_environment` instead of `node['app_environment']`.

View File

@@ -0,0 +1,206 @@
Application cookbook
====================
This cookbook is designed to be able to describe and deploy web applications. It provides the basic infrastructure; other cookbooks are required to support specific combinations of frameworks and application servers. The following cookbooks are available at this time:
- [application_java](https://github.com/opscode-cookbooks/application_java) (Java and Tomcat)
- [application_nginx](https://github.com/opscode-cookbooks/application_nginx) (nginx reverse proxy)
- [application_php](https://github.com/opscode-cookbooks/application_php) (PHP with `mod_php_apache2`)
- [application_python](https://github.com/opscode-cookbooks/application_python) (Django with Gunicorn)
- [application_ruby](https://github.com/opscode-cookbooks/application_ruby) (Rails with Passenger or Unicorn)
Backwards Compatibility
-----------------------
- Version 4.0.0 dropped support for Chef 10
- Version 2.0.0 dropped support for the `apps` data bag.
Requirements
------------
The previous dependencies have been moved out to the application-stack-specific cookbooks, and this cookbook has no external dependencies.
Resources/Providers
-------------------
The `application` LWRP configures the basic properties of most applications, regardless of the framework or application server they use. These include:
- SCM information for the deployment, such as the repository URL and branch name;
- deployment destination, including the filesystem path to deploy to;
- any OS packages to install as dependencies;
- optional callback to control the deployment.
This LWRP uses the `deploy_revision` LWRP to perform the bulk of its tasks, and many concepts and parameters map directly to it. Check the documentation for `deploy_revision` for more information.
Configuration of framework-specific aspects of the application are performed by invoking a sub-resource; see the appropriate cookbook for more documentation.
### Actions
- `:deploy`: deploy an application, including any necessary configuration, restarting the associated service if necessary
- `:force_deploy`: same as `:deploy`, but it will send a `:force_deploy` action to the deploy resource, directing it to deploy the application even if the same revision is already deployed
### Attribute Parameters
- `name`: name attribute. The name of the application you are setting up. This will be used to derive the default value for other attribute
- `packages`: an Array or Hash of packages to be installed before starting the deployment
- `path`: target path of the deployment; it will be created if it does not exist
- `owner`: the user that shall own the target path
- `group`: the group that shall own the target path
- `keep_releases`: count of keep releases
- `strategy`: the underlying LWRP that will be used to perform the deployment. The default is `:deploy_revision`, and it should never be necessary to change it
- `scm_provider`: the provider class to use for the deployment. It defaults to `Chef::Provider::Git`, you can set it to `Chef::Provider::Subversion` to deploy from an SVN repository
- `repository`: the URL of the repository the application should be checked out from
- `revision`: an identifier pointing to the revision that should be checked out
- `deploy_key`: the private key to use to access the repository via SSH, or path to a file containing the key
- `rollback_on_error`: if true, exceptions during a deployment will be caught and a clean rollback to the previous version will be attempted; the exception will then be re-raised. Defaults to true; change it only if you know what you are doing
- `environment`: a Hash of environment variables to set while running migrations
- `purge_before_symlink`: an Array of paths (relative to the checkout) to remove before creating symlinks
- `create_dirs_before_symlink`: an Array of paths (relative to the checkout) pointing to directories to create before creating symlinks
- `symlinks`: a Hash of shared/dir/path => release/dir/path. It determines which files and dirs in the shared directory get symlinked to the current release directory
- `symlink_before_migrate`: similar to symlinks, except that they will be linked before any migration is run
- `migrate`: if `true` then migrations will be run; defaults to false
- `migration_command`: a command to run to migrate the application from the previous to the current state
- `restart_command`: a command to run when restarting the application
- `environment_name`: the name of a framework-specific "environment" (for example the Rails environment). By default it is the same as the Chef environment, unless it is `_default`, in which case it is set to `production`
- `enable_submodules`: whether to enable git submodules in the deploy, passed into the deploy resource.
### Callback Attributes
You can also set a few attributes on this LWRP that are interpreted as callback to be called at specific points during a deployment. If you pass a block, it will be evaluated within a new context. If you pass a string, it will be interpreted as a path (relative to the release directory) to a file; if it exists, it will be loaded and evaluated as though it were a Chef recipe.
The following callback attributes are available:
- `before_deploy`: invoked immediately after initial setup and before the deployment proper is started. This callback will be invoked on every Chef run
- `before_migrate`
- `before_symlink`
- `before_restart`
- `after_restart`
### Sub-resources
Anything that is not a known attribute will be interpreted as the name of a sub-resource; the resource will be looked up, and any nested attribute will be passed to it. More than one sub-resource can be added to an application; the order is significant, with the latter sub-resources overriding any sub-resource that comes before.
Sub-resources can set their own values for some attributes; if they do, they will be merged together with the attribute set on the main resource. The attributes that support this behavior are the following:
- `environment`: environment variables from the application and from sub-resources will be merged together, with later resources overriding values set in the application or previous resources
- `migration_command`: commands from the application and from sub-resources will be concatenated together joined with '&&' and run as a single shell command. The migration will only succeed if all the commands succeed
- `restart_command`: commands from the application and from sub-resources will be evaluated in order
- `symlink_before_migrate`: will be concatenated as a single array
- `callbacks`: sub-resources callbacks will be invoked first, followed by the application callbacks
Usage
-----
To use the application cookbook we recommend creating a cookbook named after the application, e.g. `my_app`. In `metadata.rb` you should declare a dependency on this cookbook and any framework cookbook the application may need. For example a Rails application may include:
```ruby
depends 'application'
depends 'application_ruby'
```
The default recipe should describe your application using the `application` LWRP; you may also include additional recipes, for example to set up a database, queues, search engines and other components of your application.
A recipe using this LWRP may look like this:
```ruby
application 'my_app' do
path '/deploy/to/dir'
owner 'app-user'
group 'app-group'
repository 'http://git.example.com/my-app.git'
revision 'production'
# Apply the rails LWRP from application_ruby
rails do
# Rails-specific configuration. See the README in the
# application_ruby cookbook for more information.
end
# Apply the passenger_apache2 LWRP, also from application_ruby
passenger_apache2 do
# Passenger-specific configuration.
end
end
```
You can of course use any code necessary to determine the value of attributes:
```ruby
application 'my_app' do
repository 'http://git.example.com/my-app.git'
revision node.chef_environment == 'production' ? 'production' : 'develop'
end
```
Attributes from the application and from sub-resources are merged together:
```ruby
application 'my_app' do
restart_command 'kill -1 `cat /var/run/one.pid`'
environment 'LC_ALL' => 'en', 'FOO' => 'bar'
rails do
restart_command 'touch /tmp/something'
environment 'LC_ALL' => 'en_US'
end
passenger_apache2 do
environment 'FOO' => 'baz'
end
end
# at the end, you will have:
#
# restart_command #=> kill -1 `cat /var/run/one.pid` && touch /tmp/something
# environment #=> LC_ALL=en_US FOO=baz
```
Most databases have the concept of migrations (or you can just use your own):
```ruby
application 'my_app' do
path '/deploy/to/dir'
owner 'app-user'
group 'app-group'
repository 'http://git.example.com/my-app.git'
revision 'production'
php do
migrate true
migration_command 'your-applications-migrate-command'
end
end
```
This will run `your-applications-migrate-command`, with the current directory set to the directory of the current checkout.
To use the application cookbook, we recommend creating a role named after the application, e.g. `my_app`. Create a Ruby DSL role in your chef-repo, or create the role directly with knife.
```ruby
name 'my_app'
description 'My application deployment'
run_list([
'recipe[my_app::default]'
])
```
License and Authors
-------------------
- Author: Adam Jacob (<adam@opscode.com>)
- Author: Andrea Campi (<andrea.campi@zephirworks.com.com>)
- Author: Joshua Timberman (<joshua@opscode.com>)
- Author: Noah Kantrowitz (<noah@opscode.com>)
- Author: Seth Chisamore (<schisamo@opscode.com>)
```text
Copyright 2009-2013, Opscode, Inc.
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.
```

View File

@@ -0,0 +1,189 @@
#
# Author:: Noah Kantrowitz <noah@opscode.com>
# Cookbook Name:: application
# Library:: default
#
# Copyright:: 2011-2012, 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.
#
require "chef/mixin/from_file"
class Chef
class Resource
# Monkey-Patch the blacklists to prevent infinite recursion in #to_json and similar
# (this is global state,thus the set-union operator to change it idempotently + to not leak)
[ :@application, :@application_provider ].each do |ivar|
FORBIDDEN_IVARS << ivar unless FORBIDDEN_IVARS.include?(ivar)
HIDDEN_IVARS << ivar unless HIDDEN_IVARS.include?(ivar)
end
end
end
class ApplicationCookbook
module OptionsCollector
def options
@options ||= {}
end
def method_missing(method_sym, value=nil, &block)
super
rescue NameError
value ||= block
method_sym = method_sym.to_s.chomp('=').to_sym
options[method_sym] = value if value
options[method_sym] ||= nil
end
end
module ResourceBase
def self.included(klass)
klass.actions :before_compile, :before_deploy, :before_migrate, :before_symlink, :before_restart, :after_restart
klass.attribute :id, :kind_of => String, :name_attribute => true
klass.attribute :environment, :kind_of => Hash, :default => {}
klass.attribute :purge_before_symlink, :kind_of => Array, :default => []
klass.attribute :create_dirs_before_symlink, :kind_of => Array, :default => []
klass.attribute :symlinks, :kind_of => Hash, :default => {}
klass.attribute :symlink_before_migrate, :kind_of => Hash, :default => {}
klass.attribute :migration_command, :kind_of => [String, NilClass], :default => nil
klass.attribute :application
klass.attribute :application_provider
klass.attribute :type
end
def restart_command(arg=nil, &block)
arg ||= block
raise "Invalid restart command" unless !arg || arg.is_a?(String) || arg.is_a?(Proc)
@restart_command = arg if arg
@restart_command
end
def method_missing(name, *args)
if application.respond_to? name
application.send(name, *args)
else
super
end
end
class OptionsBlock
include ApplicationCookbook::OptionsCollector
end
def options_block(options=nil, &block)
options ||= {}
if block
collector = OptionsBlock.new
collector.instance_eval(&block)
options.update(collector.options)
end
options
end
def find_matching_role(role, single=true, &block)
return nil if !role
nodes = []
if node['roles'].include? role
nodes << node
end
if !single || nodes.empty?
search(:node, "role:#{role} AND chef_environment:#{node.chef_environment}") do |n|
nodes << n
end
end
if block
nodes.each do |n|
yield n
end
else
if single
nodes.first
else
nodes
end
end
end
def find_database_server(role)
dbm = find_matching_role(role)
Chef::Log.warn("No node with role #{role}") if role && !dbm
if respond_to?(:database) && database.has_key?('host')
database['host']
elsif dbm && dbm.attribute?('cloud')
dbm['cloud']['local_ipv4']
elsif dbm
dbm['ipaddress']
end
end
end
module ProviderBase
def self.included(klass)
klass.send(:include, Chef::Mixin::FromFile)
end
def deploy_provider
@deploy_provider ||= begin
provider = @deploy_resource.provider_for_action(:nothing)
provider.load_current_resource
provider
end
end
def release_path
deploy_provider.release_path
end
def shared_path
@deploy_resource.shared_path
end
def callback(what, callback_code=nil)
Chef::Log.debug("Got callback #{what}: #{callback_code.inspect}")
@collection = Chef::ResourceCollection.new
case callback_code
when Proc
Chef::Log.info "#{@new_resource} running callback #{what}"
safe_recipe_eval(&callback_code)
when String
callback_file = "#{release_path}/#{callback_code}"
unless ::File.exist?(callback_file)
raise RuntimeError, "Can't find your callback file #{callback_file}"
end
run_callback_from_file(callback_file)
when nil
nil
else
raise RuntimeError, "You gave me a callback I don't know what to do with: #{callback_code.inspect}"
end
end
def run_callback_from_file(callback_file)
if ::File.exist?(callback_file)
Dir.chdir(release_path) do
Chef::Log.info "#{@new_resource} running deploy hook #{callback_file}"
safe_recipe_eval { from_file(callback_file) }
end
end
end
def safe_recipe_eval(&callback_code)
recipe_eval(&callback_code)
converge if respond_to?(:converge)
end
end
end

View File

@@ -0,0 +1,11 @@
if defined?(ChefSpec)
def deploy_application(resource)
ChefSpec::Matchers::ResourceMatcher.new(:application, :deploy, resource)
end
def force_deploy_application(resource)
ChefSpec::Matchers::ResourceMatcher.new(:application, :force_deploy, resource)
end
end

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,191 @@
#
# Author:: Noah Kantrowitz <noah@opscode.com>
# Cookbook Name:: application
# Provider:: default
#
# Copyright:: 2011-2012, 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 ApplicationCookbook::ProviderBase
action :deploy do
before_compile
before_deploy
run_deploy
end
action :force_deploy do
before_compile
before_deploy
run_deploy(true)
end
action :restart do
before_compile
run_actions_with_context(:before_restart, @run_context)
run_restart
run_actions_with_context(:after_restart, @run_context)
@new_resource.updated_by_last_action(true)
end
protected
def before_compile
new_resource.application_provider self
new_resource.sub_resources.each do |resource|
resource.application_provider self
resource.run_action :before_compile
end
end
def before_deploy
new_resource.packages.each do |pkg,ver|
package pkg do
action :install
version ver if ver && ver.length > 0
end
end
directory new_resource.path do
owner new_resource.owner
group new_resource.group
mode '0755'
recursive true
end
directory "#{new_resource.path}/shared" do
owner new_resource.owner
group new_resource.group
mode '0755'
recursive true
end
if new_resource.deploy_key
if ::File.exists?(new_resource.deploy_key)
deploy_key = open(new_resource.deploy_key, &:read)
else
deploy_key = new_resource.deploy_key
end
file "#{new_resource.path}/id_deploy" do
content deploy_key
owner new_resource.owner
group new_resource.group
mode '0600'
end
template "#{new_resource.path}/deploy-ssh-wrapper" do
source "deploy-ssh-wrapper.erb"
cookbook "application"
owner new_resource.owner
group new_resource.group
mode "0755"
variables :id => new_resource.name, :deploy_to => new_resource.path, :strict_ssh => new_resource.strict_ssh
end
end
ruby_block "#{new_resource.name} before_deploy" do
block do
new_resource.sub_resources.each do |resource|
resource.run_action :before_deploy
end
callback(:before_deploy, new_resource.before_deploy)
end
end
end
def run_deploy(force = false)
# Alias to a variable so I can use in sub-resources
new_resource = @new_resource
# Also alias to variable so it can be used in sub-resources
app_provider = self
@deploy_resource = send(new_resource.strategy.to_sym, new_resource.name) do
action force ? :force_deploy : :deploy
scm_provider new_resource.scm_provider
revision new_resource.revision
repository new_resource.repository
enable_submodules new_resource.enable_submodules
user new_resource.owner
group new_resource.group
keep_releases new_resource.keep_releases
deploy_to new_resource.path
ssh_wrapper "#{new_resource.path}/deploy-ssh-wrapper" if new_resource.deploy_key
shallow_clone new_resource.shallow_clone
rollback_on_error new_resource.rollback_on_error
all_environments = ([new_resource.environment]+new_resource.sub_resources.map{|res| res.environment}).inject({}){|acc, val| acc.merge(val)}
environment all_environments
migrate new_resource.migrate
all_migration_commands = ([new_resource.migration_command]+new_resource.sub_resources.map{|res| res.migration_command}).select{|cmd| cmd && !cmd.empty?}
migration_command all_migration_commands.join(' && ')
restart_command do
([new_resource]+new_resource.sub_resources).each do |res|
cmd = res.restart_command
if cmd.is_a? Proc
app_provider.deploy_provider.instance_eval(&cmd) # @see libraries/default.rb
elsif cmd && !cmd.empty?
execute cmd do
user new_resource.owner
group new_resource.group
environment all_environments
end
end
end
end
purge_before_symlink (new_resource.purge_before_symlink + new_resource.sub_resources.map(&:purge_before_symlink)).flatten
create_dirs_before_symlink (new_resource.create_dirs_before_symlink + new_resource.sub_resources.map(&:create_dirs_before_symlink)).flatten
all_symlinks = [new_resource.symlinks]+new_resource.sub_resources.map{|res| res.symlinks}
symlinks all_symlinks.inject({}){|acc, val| acc.merge(val)}
all_symlinks_before_migrate = [new_resource.symlink_before_migrate]+new_resource.sub_resources.map{|res| res.symlink_before_migrate}
symlink_before_migrate all_symlinks_before_migrate.inject({}){|acc, val| acc.merge(val)}
before_migrate do
app_provider.send(:run_actions_with_context, :before_migrate, @run_context)
end
before_symlink do
app_provider.send(:run_actions_with_context, :before_symlink, @run_context)
end
before_restart do
app_provider.send(:run_actions_with_context, :before_restart, @run_context)
end
after_restart do
app_provider.send(:run_actions_with_context, :after_restart, @run_context)
end
end
end
def run_actions_with_context(action, context)
new_resource.sub_resources.each do |resource|
saved_run_context = resource.instance_variable_get :@run_context
resource.instance_variable_set :@run_context, context
resource.run_action action
resource.instance_variable_set :@run_context, saved_run_context
end
callback(action, new_resource.send(action))
end

View File

@@ -0,0 +1,19 @@
#
# Cookbook Name:: application
# Recipe:: default
#
# Copyright:: 2012, 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.
#
# Empty placeholder recipe, use the LWRPs, see README.md.

View File

@@ -0,0 +1,178 @@
#
# Author:: Noah Kantrowitz <noah@opscode.com>
# Cookbook Name:: application
# Resource:: default
#
# Copyright:: 2011-2012, 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.
#
require 'weakref'
include Chef::DSL::Recipe
def initialize(*args)
super
@action = :deploy
@sub_resources = []
end
actions :deploy, :force_deploy
attribute :name, :kind_of => String, :name_attribute => true
attribute :environment_name, :kind_of => String, :default => (node.chef_environment =~ /_default/ ? "production" : node.chef_environment)
attribute :path, :kind_of => String
attribute :owner, :kind_of => String
attribute :group, :kind_of => String
attribute :keep_releases, :kind_of => Integer, :default => 5
attribute :strategy, :kind_of => [String, Symbol], :default => :deploy_revision
attribute :scm_provider, :kind_of => [Class, String, Symbol]
attribute :revision, :kind_of => String
attribute :repository, :kind_of => String
attribute :enable_submodules, :kind_of => [TrueClass, FalseClass], :default => false
attribute :environment, :kind_of => Hash, :default => {}
attribute :deploy_key, :kind_of => [String, NilClass], :default => nil
attribute :strict_ssh, :kind_of => [TrueClass, FalseClass], :default => false
attribute :shallow_clone, :kind_of => [TrueClass, FalseClass], :default => false
attribute :force, :kind_of => [TrueClass, FalseClass], :default => false
attribute :rollback_on_error, :kind_of => [TrueClass, FalseClass], :default => true
attribute :purge_before_symlink, :kind_of => Array, :default => []
attribute :create_dirs_before_symlink, :kind_of => Array, :default => []
attribute :symlinks, :kind_of => Hash, :default => {}
attribute :symlink_before_migrate, :kind_of => Hash, :default => {}
attribute :migrate, :kind_of => [TrueClass, FalseClass], :default => false
attribute :migration_command, :kind_of => [String, NilClass], :default => nil
attribute :packages, :kind_of => [Array, Hash], :default => []
attribute :application_provider
attr_reader :sub_resources
def restart_command(arg=nil, &block)
arg ||= block
set_or_return(:restart_command, arg, :kind_of => [Proc, String])
end
# Callback fires before deploy is started.
def before_deploy(arg=nil, &block)
arg ||= block
set_or_return(:before_deploy, arg, :kind_of => [Proc, String])
end
# Callback fires before migration is run.
def before_migrate(arg=nil, &block)
arg ||= block
set_or_return(:before_migrate, arg, :kind_of => [Proc, String])
end
# Callback fires before symlinking
def before_symlink(arg=nil, &block)
arg ||= block
set_or_return(:before_symlink, arg, :kind_of => [Proc, String])
end
# Callback fires before restart
def before_restart(arg=nil, &block)
arg ||= block
set_or_return(:before_restart, arg, :kind_of => [Proc, String])
end
# Callback fires after restart
def after_restart(arg=nil, &block)
arg ||= block
set_or_return(:after_restart, arg, :kind_of => [Proc, String])
end
def release_path
application_provider.release_path
end
def shared_path
application_provider.shared_path
end
def method_missing(name, *args, &block)
# Build the set of names to check for a valid resource
lookup_path = ["application_#{name}"]
run_context.cookbook_collection.each do |cookbook_name, cookbook_ver|
if cookbook_name.start_with?("application_")
lookup_path << "#{cookbook_name}_#{name}"
end
end
lookup_path << name
resource = nil
# Try to find our resource
lookup_path.each do |resource_name|
begin
Chef::Log.debug "Trying to load application resource #{resource_name} for #{name}"
resource = super(resource_name.to_sym, self.name, &block)
break
rescue NameError => e
# Works on any MRI ruby
if e.name == resource_name.to_sym || e.inspect =~ /\b#{resource_name}\b/
next
else
raise e
end
end
end
raise NameError, "No resource found for #{name}. Tried #{lookup_path.join(', ')}" unless resource
# Enforce action :nothing in case people forget
resource.action :nothing
# Make this a weakref to prevent a cycle between the application resource and the sub resources
resource.application WeakRef.new(self)
resource.type name
@sub_resources << resource
resource
end
def do_i_respond_to?(*args)
name = args.first.to_s
# Build the set of names to check for a valid resource
lookup_path = ["application_#{name}"]
run_context.cookbook_collection.each do |cookbook_name, cookbook_ver|
if cookbook_name.start_with?("application_")
lookup_path << "#{cookbook_name}_#{name}"
end
end
lookup_path << name
found = false
# Try to find our resource
lookup_path.each do |resource_name|
begin
Chef::Log.debug "Looking for application resource #{resource_name} for #{name}"
Chef::Resource.resource_for_node(resource_name.to_sym, node)
found = true
break
rescue NameError => e
# Keep calm and carry on
end
end
found
end
# If we are using a current version of ruby, use respond_to_missing?
# instead of respond_to? so we provide proper behavior
if(Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('1.9.1'))
def respond_to_missing?(*args)
super || do_i_respond_to?(*args)
end
else
def respond_to?(*args)
super || do_i_respond_to?(*args)
end
end
def to_ary
nil
end
alias :to_a :to_ary

View File

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
#
# Deploy SSH Wrapper
# App: <%= @id %>
#
# Rendered by Chef - local changes will be replaced
/usr/bin/env ssh <% unless @strict_ssh %>-o "StrictHostKeyChecking=no" <% end %>-i "<%= @deploy_to %>/id_deploy" $@