diff options
Diffstat (limited to 'lib/chef/resource/deploy.rb')
-rw-r--r-- | lib/chef/resource/deploy.rb | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/lib/chef/resource/deploy.rb b/lib/chef/resource/deploy.rb new file mode 100644 index 0000000000..8b614028bf --- /dev/null +++ b/lib/chef/resource/deploy.rb @@ -0,0 +1,403 @@ +# +# Author:: Daniel DeLeo (<dan@kallistec.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# 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. +# + +# EX: +# deploy "/my/deploy/dir" do +# repo "git@github.com/whoami/project" +# revision "abc123" # or "HEAD" or "TAG_for_1.0" or (subversion) "1234" +# user "deploy_ninja" +# enable_submodules true +# migrate true +# migration_command "rake db:migrate" +# environment "RAILS_ENV" => "production", "OTHER_ENV" => "foo" +# shallow_clone true +# action :deploy # or :rollback +# restart_command "touch tmp/restart.txt" +# git_ssh_wrapper "wrap-ssh4git.sh" +# scm_provider Chef::Provider::Git # is the default, for svn: Chef::Provider::Subversion +# svn_username "whoami" +# svn_password "supersecret" +# end + +require "chef/resource/scm" + +class Chef + class Resource + + # Deploy: Deploy apps from a source control repository. + # + # Callbacks: + # Callbacks can be a block or a string. If given a block, the code + # is evaluated as an embedded recipe, and run at the specified + # point in the deploy process. If given a string, the string is taken as + # a path to a callback file/recipe. Paths are evaluated relative to the + # release directory. Callback files can contain chef code (resources, etc.) + # + class Deploy < Chef::Resource + + provider_base Chef::Provider::Deploy + + identity_attr :repository + + state_attrs :deploy_to, :revision + + def initialize(name, run_context=nil) + super + @resource_name = :deploy + @deploy_to = name + @environment = nil + @repository_cache = 'cached-copy' + @copy_exclude = [] + @purge_before_symlink = %w{log tmp/pids public/system} + @create_dirs_before_symlink = %w{tmp public config} + @symlink_before_migrate = {"config/database.yml" => "config/database.yml"} + @symlinks = {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"} + @revision = 'HEAD' + @action = :deploy + @migrate = false + @rollback_on_error = false + @remote = "origin" + @enable_submodules = false + @shallow_clone = false + @scm_provider = Chef::Provider::Git + @svn_force_export = false + @provider = Chef::Provider::Deploy::Timestamped + @allowed_actions.push(:force_deploy, :deploy, :rollback) + @additional_remotes = Hash[] + @keep_releases = 5 + end + + # where the checked out/cloned code goes + def destination + @destination ||= shared_path + "/#{@repository_cache}" + end + + # where shared stuff goes, i.e., logs, tmp, etc. goes here + def shared_path + @shared_path ||= @deploy_to + "/shared" + end + + # where the deployed version of your code goes + def current_path + @current_path ||= @deploy_to + "/current" + end + + def depth + @shallow_clone ? "5" : nil + end + + # note: deploy_to is your application "meta-root." + def deploy_to(arg=nil) + set_or_return( + :deploy_to, + arg, + :kind_of => [ String ] + ) + end + + def repo(arg=nil) + set_or_return( + :repo, + arg, + :kind_of => [ String ] + ) + end + alias :repository :repo + + def remote(arg=nil) + set_or_return( + :remote, + arg, + :kind_of => [ String ] + ) + end + + def role(arg=nil) + set_or_return( + :role, + arg, + :kind_of => [ String ] + ) + end + + def restart_command(arg=nil, &block) + arg ||= block + set_or_return( + :restart_command, + arg, + :kind_of => [ String, Proc ] + ) + end + alias :restart :restart_command + + def migrate(arg=nil) + set_or_return( + :migrate, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + def migration_command(arg=nil) + set_or_return( + :migration_command, + arg, + :kind_of => [ String ] + ) + end + + def rollback_on_error(arg=nil) + set_or_return( + :rollback_on_error, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + def user(arg=nil) + set_or_return( + :user, + arg, + :kind_of => [ String ] + ) + end + + def group(arg=nil) + set_or_return( + :group, + arg, + :kind_of => [ String ] + ) + end + + def enable_submodules(arg=nil) + set_or_return( + :enable_submodules, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + def shallow_clone(arg=nil) + set_or_return( + :shallow_clone, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + def repository_cache(arg=nil) + set_or_return( + :repository_cache, + arg, + :kind_of => [ String ] + ) + end + + def copy_exclude(arg=nil) + set_or_return( + :copy_exclude, + arg, + :kind_of => [ String ] + ) + end + + def revision(arg=nil) + set_or_return( + :revision, + arg, + :kind_of => [ String ] + ) + end + alias :branch :revision + + def git_ssh_wrapper(arg=nil) + set_or_return( + :git_ssh_wrapper, + arg, + :kind_of => [ String ] + ) + end + alias :ssh_wrapper :git_ssh_wrapper + + def svn_username(arg=nil) + set_or_return( + :svn_username, + arg, + :kind_of => [ String ] + ) + end + + def svn_password(arg=nil) + set_or_return( + :svn_password, + arg, + :kind_of => [ String ] + ) + end + + def svn_arguments(arg=nil) + set_or_return( + :svn_arguments, + arg, + :kind_of => [ String ] + ) + end + + def svn_info_args(arg=nil) + set_or_return( + :svn_arguments, + arg, + :kind_of => [ String ]) + end + + def scm_provider(arg=nil) + klass = if arg.kind_of?(String) || arg.kind_of?(Symbol) + lookup_provider_constant(arg) + else + arg + end + set_or_return( + :scm_provider, + klass, + :kind_of => [ Class ] + ) + end + + def svn_force_export(arg=nil) + set_or_return( + :svn_force_export, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + def environment(arg=nil) + if arg.is_a?(String) + Chef::Log.debug "Setting RAILS_ENV, RACK_ENV, and MERB_ENV to `#{arg}'" + Chef::Log.warn "[DEPRECATED] please modify your deploy recipe or attributes to set the environment using a hash" + arg = {"RAILS_ENV"=>arg,"MERB_ENV"=>arg,"RACK_ENV"=>arg} + end + set_or_return( + :environment, + arg, + :kind_of => [ Hash ] + ) + end + + # The number of old release directories to keep around after cleanup + def keep_releases(arg=nil) + [set_or_return( + :keep_releases, + arg, + :kind_of => [ Integer ]), 1].max + end + + # An array of paths, relative to your app's root, to be purged from a + # SCM clone/checkout before symlinking. Use this to get rid of files and + # directories you want to be shared between releases. + # Default: ["log", "tmp/pids", "public/system"] + def purge_before_symlink(arg=nil) + set_or_return( + :purge_before_symlink, + arg, + :kind_of => Array + ) + end + + # An array of paths, relative to your app's root, where you expect dirs to + # exist before symlinking. This runs after #purge_before_symlink, so you + # can use this to recreate dirs that you had previously purged. + # For example, if you plan to use a shared directory for pids, and you + # want it to be located in $APP_ROOT/tmp/pids, you could purge tmp, + # then specify tmp here so that the tmp directory will exist when you + # symlink the pids directory in to the current release. + # Default: ["tmp", "public", "config"] + def create_dirs_before_symlink(arg=nil) + set_or_return( + :create_dirs_before_symlink, + arg, + :kind_of => Array + ) + end + + # A Hash of shared/dir/path => release/dir/path. This attribute determines + # which files and dirs in the shared directory get symlinked to the current + # release directory, and where they go. If you have a directory + # $shared/pids that you would like to symlink as $current_release/tmp/pids + # you specify it as "pids" => "tmp/pids" + # Default {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"} + def symlinks(arg=nil) + set_or_return( + :symlinks, + arg, + :kind_of => Hash + ) + end + + # A Hash of shared/dir/path => release/dir/path. This attribute determines + # which files in the shared directory get symlinked to the current release + # directory and where they go. Unlike map_shared_files, these are symlinked + # *before* any migration is run. + # For a rails/merb app, this is used to link in a known good database.yml + # (with the production db password) before running migrate. + # Default {"config/database.yml" => "config/database.yml"} + def symlink_before_migrate(arg=nil) + set_or_return( + :symlink_before_migrate, + arg, + :kind_of => Hash + ) + 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 additional_remotes(arg=nil) + set_or_return( + :additional_remotes, + arg, + :kind_of => Hash + ) + end + + end + end +end |