Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

updated hook implementation, hooks are now instance_eval'd within the…

… chef-deploy resource

see README for more info, way more usefull hooks now
  • Loading branch information...
commit ab690b10185b111c6a3b6c3e29ccdc1331ac74fa 2 parents b316e0a + 0027c32
authored
22  README.rdoc
Source Rendered
@@ -40,9 +40,23 @@ APP_ROOT/
40 40
     before_restart.rb
41 41
     after_restart.rb
42 42
 
43  
-These scripts will be called with two command line params in ARGV:
  43
+These scripts will be instance_eval'd in the context of the chef-deploy resource. This means that you will have certain commands and variables available to you in these hooks. For example:
44 44
 
45  
-ruby before_migrate.rb production app_master
  45
+run "echo 'release_path: #{release_path}' >> #{shared_path}/logs.log"
  46
+run "echo 'current_path: #{current_path}' >> #{shared_path}/logs.log"
  47
+run "echo 'shared_path: #{shared_path}' >> #{shared_path}/logs.log"
  48
+sudo "echo 'sudo works' >> /root/sudo.log"
46 49
 
47  
-Where ARGV[0] is the RAILS_ENV, MERB_ENV or RACK_ENV and ARGV[1] is the role passed in to the deploy resource, this 
48  
-can be used to identify certain servers as database, application, cache, etc roles so you can act accordingly
  50
+
  51
+You have access to a run command and a sudo command. Both of these will run shell commands, run will run as your normal unix user that the app is deployed as and sudo will run as root for when you need more permissions.
  52
+
  53
+You will have variables like in capistrano:
  54
+
  55
+release_path: this is the full path to the current release:  /data/appname/releases/12345678
  56
+shared_path: this is the path to the shared dir: /data/appname/shared
  57
+current_path: this is the path to the currently symlinked release:  /data/appname/current
  58
+node:  node is the full chef node object, this will have all of the JSON collected by ohai as well as any custom json you passed into your client run. THis way you can get at *any* data you have available to any of your chef recipes.
  59
+
  60
+Using subversion:
  61
+
  62
+In your deploy block, simply add: scm 'subversion' (as well as svn_username and svn_password, if needed). Obviously, git-specific options like enable_submodules can be removed as they're not applicable.
4  Rakefile
@@ -5,7 +5,7 @@ require 'date'
5 5
 require 'spec/rake/spectask'
6 6
 
7 7
 GEM = "chef-deploy"
8  
-GEM_VERSION = "0.1.3"
  8
+GEM_VERSION = "0.2.0"
9 9
 AUTHOR = "Ezra Zygmuntowicz"
10 10
 EMAIL = "Your Email"
11 11
 HOMEPAGE = "http://example.com"
@@ -54,4 +54,4 @@ task :make_spec do
54 54
   File.open("#{GEM}.gemspec", "w") do |file|
55 55
     file.puts spec.to_ruby
56 56
   end
57  
-end
  57
+end
62  lib/chef-deploy.rb
... ...
@@ -1,3 +1,4 @@
  1
+require File.join(File.dirname(__FILE__), 'chef-deploy/subversion')
1 2
 require File.join(File.dirname(__FILE__), 'chef-deploy/git')
2 3
 require File.join(File.dirname(__FILE__), 'chef-deploy/cached_deploy')
3 4
 
@@ -151,6 +152,30 @@ def git_ssh_wrapper(arg=nil)
151 152
           :kind_of => [ String ]
152 153
         )
153 154
       end
  155
+      
  156
+      def scm(arg=nil)
  157
+        set_or_return(
  158
+          :scm,
  159
+          arg,
  160
+          :kind_of => [ String ]
  161
+        )
  162
+      end
  163
+ 
  164
+      def svn_username(arg=nil)
  165
+        set_or_return(
  166
+          :svn_username,
  167
+          arg,
  168
+          :kind_of => [ String ]
  169
+        )
  170
+      end
  171
+ 
  172
+      def svn_password(arg=nil)
  173
+        set_or_return(
  174
+          :svn_password,
  175
+          arg,
  176
+          :kind_of => [ String ]
  177
+        )
  178
+      end
154 179
  
155 180
     end
156 181
   end
@@ -161,24 +186,27 @@ class Deploy < Chef::Provider
161 186
       def load_current_resource
162 187
         FileUtils.mkdir_p "#{@new_resource.name}/shared"
163 188
         FileUtils.mkdir_p "#{@new_resource.name}/releases"
164  
-        @dep = CachedDeploy.new  :user       => @new_resource.user,
165  
-                                :group      => @new_resource.group,
166  
-                                :role       => @new_resource.role,
167  
-                                :branch     => (@new_resource.branch || 'HEAD'),
168  
-                                :restart_command => (@new_resource.restart_command || ""),
169  
-                                :repository => @new_resource.repo,
170  
-                                :environment => @new_resource.environment,
171  
-                                :migration_command => @new_resource.migration_command,
172  
-                                :migrate => @new_resource.migrate,
173  
-                                :deploy_to  => @new_resource.name,
174  
-                                :repository_cache  => @new_resource.repository_cache,
175  
-                                :copy_exclude  => @new_resource.copy_exclude,
176  
-                                :revision  => (@new_resource.revision || ''),
  189
+        @dep = CachedDeploy.new :user                  => @new_resource.user,
  190
+                                :group                 => @new_resource.group,
  191
+                                :role                  => @new_resource.role,
  192
+                                :branch                => (@new_resource.branch || 'HEAD'),
  193
+                                :restart_command       => (@new_resource.restart_command || ""),
  194
+                                :repository            => @new_resource.repo,
  195
+                                :environment           => @new_resource.environment,
  196
+                                :migration_command     => @new_resource.migration_command,
  197
+                                :migrate               => @new_resource.migrate,
  198
+                                :deploy_to             => @new_resource.name,
  199
+                                :repository_cache      => @new_resource.repository_cache,
  200
+                                :copy_exclude          => @new_resource.copy_exclude,
  201
+                                :revision              => (@new_resource.revision || ''),
177 202
                                 :git_enable_submodules => @new_resource.enable_submodules,
178  
-                                :git_shallow_clone  => @new_resource.shallow_clone,
179  
-                                :node => @node,
180  
-                                :new_resource => @new_resource,
181  
-                                :git_ssh_wrapper => @git_ssh_wrapper
  203
+                                :git_shallow_clone     => @new_resource.shallow_clone,
  204
+                                :svn_username          => @new_resource.svn_username,
  205
+                                :svn_password          => @new_resource.svn_password,
  206
+                                :scm                   => @new_resource.scm || 'git',
  207
+                                :node                  => @node,
  208
+                                :new_resource          => @new_resource,
  209
+                                :git_ssh_wrapper       => @git_ssh_wrapper
182 210
       end
183 211
       
184 212
       def action_deploy
42  lib/chef-deploy/cached_deploy.rb
@@ -9,10 +9,11 @@ class CachedDeploy
9 9
   def deploy
10 10
     @configuration[:release_path] = "#{@configuration[:deploy_to]}/releases/#{Time.now.utc.strftime("%Y%m%d%H%M%S")}"
11 11
     if @configuration[:revision] == ''
12  
-       @configuration[:revision] = source.query_revision(@configuration[:branch]) {|cmd| run "#{cmd}"}
  12
+       @configuration[:revision] = source.query_revision(@configuration[:branch]) {|cmd| run_with_result "#{cmd}"}
13 13
     end
14 14
     
15 15
     if check_current_revision_and_noop_if_same(@configuration[:revision])
  16
+      Chef::Log.info "Revision is already deployed, running migrations if there are any"
16 17
       migrate
17 18
       symlink
18 19
       return
@@ -24,7 +25,7 @@ def deploy
24 25
     Chef::Log.info "deploying branch: #{@configuration[:branch]} rev: #{@configuration[:revision]}"
25 26
     Chef::Log.info "updating the cached checkout"
26 27
     chef_run(update_repository_cache)
27  
-    Chef::Log.info "copying the cached version to #{configuration[:release_path]}"
  28
+    Chef::Log.info "copying the cached version to #{release_path}"
28 29
     chef_run(copy_repository_cache)
29 30
     install_gems
30 31
     
@@ -58,7 +59,7 @@ def check_current_revision_and_noop_if_same(newrev)
58 59
   def callback(what)
59 60
     if File.exist?("#{latest_release}/deploy/#{what}.rb")
60 61
       Chef::Log.info "running deploy hook: #{latest_release}/deploy/#{what}.rb"
61  
-      chef_run("cd #{latest_release} && sudo -u #{user} ruby deploy/#{what}.rb #{@configuration[:environment]} #{@configuration[:role]}")
  62
+      instance_eval(IO.read("#{latest_release}/deploy/#{what}.rb"))
62 63
     end
63 64
   end
64 65
   
@@ -76,7 +77,7 @@ def oldest_release
76 77
   end
77 78
   
78 79
   def all_releases
79  
-    `ls #{release_path}`.split("\n").sort.map{|r| File.join(release_path, r)}
  80
+    `ls #{release_dir}`.split("\n").sort.map{|r| File.join(release_dir, r)}
80 81
   end
81 82
   
82 83
   def cleanup
@@ -118,10 +119,18 @@ def shared_path
118 119
     configuration[:shared_path]
119 120
   end
120 121
   
121  
-  def release_path
  122
+  def release_dir
122 123
     "#{@configuration[:deploy_to]}/releases"
123 124
   end
124 125
   
  126
+  def release_path
  127
+    @configuration[:release_path]
  128
+  end
  129
+  
  130
+  def node
  131
+    @configuration[:node]
  132
+  end
  133
+  
125 134
   def symlink(release_to_link=latest_release)
126 135
     Chef::Log.info "symlinking and finishing deploy"
127 136
     symlink = false
@@ -147,7 +156,7 @@ def symlink(release_to_link=latest_release)
147 156
     end
148 157
   end
149 158
   
150  
-  def run(cmd)
  159
+  def run_with_result(cmd)
151 160
     res = `#{cmd} 2>&1`
152 161
     raise(ChefDeployFailure, res) unless $? == 0
153 162
     res
@@ -157,6 +166,14 @@ def chef_run(cmd)
157 166
     Chef::Mixin::Command.run_command(:command => cmd)
158 167
   end
159 168
   
  169
+  def run(cmd)
  170
+    Chef::Mixin::Command.run_command(:command => cmd, :user => user)
  171
+  end
  172
+  
  173
+  def sudo(cmd)
  174
+    Chef::Mixin::Command.run_command(:command => cmd)
  175
+  end
  176
+  
160 177
   # :repository_cache
161 178
   # :shared_path
162 179
   # :repository
@@ -175,7 +192,12 @@ def configuration
175 192
   end
176 193
   
177 194
   def source
178  
-    @source ||= Git.new(configuration)
  195
+    @source ||= case configuration[:scm]
  196
+    when 'git'
  197
+      Git.new configuration
  198
+    when 'svn'
  199
+      Subversion.new configuration
  200
+    end
179 201
   end
180 202
 
181 203
   private
@@ -237,10 +259,10 @@ def update_repository_cache
237 259
 
238 260
     def copy_repository_cache
239 261
       if copy_exclude.empty? 
240  
-        return "cp -RPp #{repository_cache} #{configuration[:release_path]} && #{mark}"
  262
+        return "cp -RPp #{repository_cache} #{release_path} && #{mark}"
241 263
       else
242 264
         exclusions = copy_exclude.map { |e| "--exclude=\"#{e}\"" }.join(' ')
243  
-        return "rsync -lrpt #{exclusions} #{repository_cache}/* #{configuration[:release_path]} && #{mark}"
  265
+        return "rsync -lrpt #{exclusions} #{repository_cache}/* #{release_path} && #{mark}"
244 266
       end
245 267
     end
246 268
     
@@ -249,7 +271,7 @@ def revision
249 271
     end
250 272
     
251 273
     def mark
252  
-      "(echo #{revision} > #{configuration[:release_path]}/REVISION)"
  274
+      "(echo #{revision} > #{release_path}/REVISION)"
253 275
     end
254 276
     
255 277
     def copy_exclude
18  lib/chef-deploy/git.rb
@@ -98,22 +98,22 @@ def log(from, to=nil)
98 98
 
99 99
   # Getting the actual commit id, in case we were passed a tag
100 100
   # or partial sha or something - it will return the sha if you pass a sha, too
101  
-  def query_revision(revision)
102  
-    raise ArgumentError, "Deploying remote branches is no longer supported.  Specify the remote branch as a local branch for the git repository you're deploying from (ie: '#{revision.gsub('origin/', '')}' rather than '#{revision}')." if revision =~ /^origin\//
103  
-    return revision if revision =~ /^[0-9a-f]{40}$/
104  
-    command = scm('ls-remote', configuration[:repository], revision)
  101
+  def query_revision(reference)
  102
+    raise ArgumentError, "Deploying remote branches is no longer supported.  Specify the remote branch as a local branch for the git repository you're deploying from (ie: '#{reference.gsub('origin/', '')}' rather than '#{reference}')." if reference =~ /^origin\//
  103
+    sha_hash = '[0-9a-f]{40}'
  104
+    return reference if reference =~ /^#{sha_hash}$/     # it's already a sha
  105
+    command = scm('ls-remote', configuration[:repository], reference)
105 106
     result = nil
106 107
     begin
107 108
       result = yield(command)
108 109
     rescue ChefDeployFailure => e
109 110
       raise obvious_error("Could not access the remote Git repository. If this is a private repository, please verify that the deploy key for your application has been added to your remote Git account.", e)
110 111
     end
111  
-    rev, ref = result.split(/[\t\n]/)
112  
-    newrev = nil
113  
-    if ref.sub(/refs\/.*?\//, '').strip == revision
114  
-      newrev = rev
  112
+    unless result =~ /^(#{sha_hash})\s+(\S+)/
  113
+      raise "Unable to resolve reference for '#{reference}' on repository '#{configuration[:repository]}'."
115 114
     end
116  
-    raise "Unable to resolve revision for '#{revision}' on repository '#{configuration[:repository]}'." unless newrev =~ /^[0-9a-f]{40}$/
  115
+    newrev = $1
  116
+    newref = $2
117 117
     return newrev
118 118
   end
119 119
   
16  lib/chef-deploy/subversion.rb
... ...
@@ -1,3 +1,5 @@
  1
+require 'yaml'
  2
+
1 3
 class Subversion
2 4
 
3 5
   def initialize(opts={})
@@ -27,13 +29,13 @@ def checkout(revision, destination)
27 29
   # Returns the command that will do an "svn update" to the given
28 30
   # revision, for the working copy at the given destination.
29 31
   def sync(revision, destination)
30  
-    scm :update, arguments, verbose, authentication, "-r#{revision}", destination
  32
+    scm :update, config[:arguments], verbose, authentication, "-r#{revision}", destination
31 33
   end
32 34
 
33 35
   # Returns the command that will do an "svn export" of the given revision
34 36
   # to the given destination.
35 37
   def export(revision, destination)
36  
-    scm :export, arguments, verbose, authentication, "-r#{revision}", repository, destination
  38
+    scm :export, config[:arguments], verbose, authentication, "-r#{revision}", repository, destination
37 39
   end
38 40
 
39 41
   # Returns the command that will do an "svn diff" for the two revisions.
@@ -72,15 +74,17 @@ def next_revision(revision)
72 74
     # switch, since Capistrano will check for that prompt in the output
73 75
     # and will respond appropriately.
74 76
     def authentication
75  
-      username = config(:svn_username)
  77
+      username = config[:svn_username]
76 78
       return "" unless username
77  
-      result = "--username #{config(:svn_username)} "
78  
-      result << "--password #{config(:svn_password)} "
  79
+      result = "--username #{config[:svn_username]} "
  80
+      result << "--password #{config[:svn_password]} "
79 81
       result
80 82
     end
81 83
 
82 84
     # If verbose output is requested, return nil, otherwise return the
83 85
     # command-line switch for "quiet" ("-q").
  86
+    # FIXME: This is currently flipped logically since it doesn't check
  87
+    # for any verbosity configuration flag
84 88
     def verbose
85 89
       "-q"
86 90
     end
@@ -96,6 +100,6 @@ def scm(*args)
96 100
     end
97 101
 
98 102
     def svn_password_prompt
99  
-      config[:password]
  103
+      config[:svn_password]
100 104
     end
101 105
 end

0 notes on commit ab690b1

Please sign in to comment.
Something went wrong with that request. Please try again.