Class: CachedDeploy

Inherits:
Object
  • Object
show all
Defined in:
lib/chef-deploy/cached_deploy.rb

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ CachedDeploy

:repository_cache :shared_path :repository :release_path :copy_exclude :revision :user :group



195
196
197
198
# File 'lib/chef-deploy/cached_deploy.rb', line 195

def initialize(opts={})
  @configuration = opts
  @configuration[:shared_path] = "#{@configuration[:deploy_to]}/shared"
end

Instance Method Details

#all_releasesObject



82
83
84
# File 'lib/chef-deploy/cached_deploy.rb', line 82

def all_releases
  `ls #{release_dir}`.split("\n").sort.map{|r| File.join(release_dir, r)}
end

#callback(what) ⇒ Object

before_symlink before_restart



60
61
62
63
64
65
66
67
# File 'lib/chef-deploy/cached_deploy.rb', line 60

def callback(what)
  if File.exist?("#{latest_release}/deploy/#{what}.rb")
    Dir.chdir(latest_release) do
      Chef::Log.info "running deploy hook: #{latest_release}/deploy/#{what}.rb"
      instance_eval(IO.read("#{latest_release}/deploy/#{what}.rb"))
    end
  end
end

#check_current_revision_and_noop_if_same_and_deployed(newrev) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/chef-deploy/cached_deploy.rb', line 50

def check_current_revision_and_noop_if_same_and_deployed(newrev)
  IO.read("#{latest_release}/REVISION").chomp == newrev &&
  IO.read("#{shared_path}/DEPLOYED_REVISION").chomp == newrev
    
rescue
  false
end

#chef_run(cmd) ⇒ Object



175
176
177
# File 'lib/chef-deploy/cached_deploy.rb', line 175

def chef_run(cmd)
  Chef::Mixin::Command.run_command(:command => cmd)
end

#cleanupObject



86
87
88
89
90
# File 'lib/chef-deploy/cached_deploy.rb', line 86

def cleanup
  while all_releases.size >= 5
    FileUtils.rm_rf oldest_release
  end
end

#configurationObject



200
201
202
# File 'lib/chef-deploy/cached_deploy.rb', line 200

def configuration
  @configuration
end

#current_pathObject



124
125
126
# File 'lib/chef-deploy/cached_deploy.rb', line 124

def current_path
  "#{@configuration[:deploy_to]}/current"
end

#deployObject

Executes the SCM command for this strategy and writes the REVISION mark file to each host.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/chef-deploy/cached_deploy.rb', line 9

def deploy
  @configuration[:release_path] = "#{@configuration[:deploy_to]}/releases/#{Time.now.utc.strftime("%Y%m%d%H%M%S")}"
  if @configuration[:revision] == ''
     @configuration[:revision] = source.query_revision(@configuration[:branch]) {|cmd| run_with_result "#{cmd}"}
  end
  
  return if check_current_revision_and_noop_if_same_and_deployed(@configuration[:revision])
  
  Chef::Log.info "ensuring proper ownership"
  chef_run(fix_ownership_command(user, group, @configuration[:deploy_to]))
  
  Chef::Log.info "deploying branch: #{@configuration[:branch]} rev: #{@configuration[:revision]}"
  Chef::Log.info "updating the cached checkout"
  chef_run(update_repository_cache)
  Chef::Log.info "copying the cached version to #{release_path}"
  chef_run(copy_repository_cache)
  install_gems
  prepare_directories
  
  chef_run(fix_ownership_command(user, group, @configuration[:deploy_to]))
  
  callback(:before_migrate)
  migrate
  callback(:before_symlink)
  symlink
  callback(:before_restart)
  restart
  callback(:after_restart)
  cleanup

  mark_deployed
  @configuration[:new_resource].updated = true
end

#fix_ownership_command(user, group, path) ⇒ Object



102
103
104
# File 'lib/chef-deploy/cached_deploy.rb', line 102

def fix_ownership_command(user, group, path)
  "find -L #{path} \\( ! -group #{group} -o ! -user #{user} \\) -exec chown #{user}:#{group} \\{\\} \\;"
end

#groupObject



120
121
122
# File 'lib/chef-deploy/cached_deploy.rb', line 120

def group
  @configuration[:group] || user
end

#latest_releaseObject



69
70
71
# File 'lib/chef-deploy/cached_deploy.rb', line 69

def latest_release
  all_releases.last
end

#migrateObject



106
107
108
109
110
111
112
113
114
# File 'lib/chef-deploy/cached_deploy.rb', line 106

def migrate
  if @configuration[:migrate]
    chef_run "ln -nfs #{shared_path}/config/database.yml #{latest_release}/config/database.yml"
    chef_run "ln -nfs #{shared_path}/log #{latest_release}/log"
    Chef::Log.info "Migrating: cd #{latest_release} && sudo -u #{user} RAILS_ENV=#{@configuration[:environment]} RACK_ENV=#{@configuration[:environment]} MERB_ENV=#{@configuration[:environment]} #{@configuration[:migration_command]}"
    chef_run(fix_ownership_command(user, group, latest_release))
    chef_run("cd #{latest_release} && sudo -u #{user} RAILS_ENV=#{@configuration[:environment]} RACK_ENV=#{@configuration[:environment]} MERB_ENV=#{@configuration[:environment]} #{@configuration[:migration_command]}")
  end
end

#nodeObject



140
141
142
# File 'lib/chef-deploy/cached_deploy.rb', line 140

def node
  @configuration[:node]
end

#oldest_releaseObject



78
79
80
# File 'lib/chef-deploy/cached_deploy.rb', line 78

def oldest_release
  all_releases.first
end

#previous_release(current = latest_release) ⇒ Object



73
74
75
76
# File 'lib/chef-deploy/cached_deploy.rb', line 73

def previous_release(current=latest_release)
  index = all_releases.index(current)
  all_releases[index-1]
end

#release_dirObject



132
133
134
# File 'lib/chef-deploy/cached_deploy.rb', line 132

def release_dir
  "#{@configuration[:deploy_to]}/releases"
end

#release_pathObject



136
137
138
# File 'lib/chef-deploy/cached_deploy.rb', line 136

def release_path
  @configuration[:release_path]
end

#restartObject



43
44
45
46
47
48
# File 'lib/chef-deploy/cached_deploy.rb', line 43

def restart
  unless @configuration[:restart_command].empty?
    Chef::Log.info "restarting app: #{latest_release}"
    chef_run("cd #{current_path} && sudo -u #{user} INLINEDIR=/tmp RAILS_ENV=#{@configuration[:environment]} RACK_ENV=#{@configuration[:environment]} MERB_ENV=#{@configuration[:environment]} #{@configuration[:restart_command]}")
  end
end

#rollbackObject



92
93
94
95
96
97
98
99
100
# File 'lib/chef-deploy/cached_deploy.rb', line 92

def rollback
  Chef::Log.info "rolling back to previous release"
  symlink(previous_release)
  FileUtils.rm_rf latest_release
  Chef::Log.info "restarting with previous release"
  restart

  @configuration[:new_resource].updated = true
end

#run(cmd) ⇒ Object



179
180
181
# File 'lib/chef-deploy/cached_deploy.rb', line 179

def run(cmd)
  Chef::Mixin::Command.run_command(:command => cmd, :user => user)
end

#run_with_result(cmd) ⇒ Object

Raises:



169
170
171
172
173
# File 'lib/chef-deploy/cached_deploy.rb', line 169

def run_with_result(cmd)
  res = `#{cmd} 2>&1`
  raise(ChefDeployFailure, res) unless $? == 0
  res
end

#shared_pathObject



128
129
130
# File 'lib/chef-deploy/cached_deploy.rb', line 128

def shared_path
  configuration[:shared_path]
end

#sourceObject



204
205
206
207
208
209
210
211
# File 'lib/chef-deploy/cached_deploy.rb', line 204

def source
  @source ||= case configuration[:scm]
  when 'git'
    Git.new configuration
  when 'svn'
    Subversion.new configuration
  end
end

#sudo(cmd) ⇒ Object



183
184
185
# File 'lib/chef-deploy/cached_deploy.rb', line 183

def sudo(cmd)
  Chef::Mixin::Command.run_command(:command => cmd)
end


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/chef-deploy/cached_deploy.rb', line 144

def symlink(release_to_link=latest_release)
  Chef::Log.info "symlinking and finishing deploy"
  symlink = false
  begin
    chef_run [ "find #{release_to_link} ! -perm /g+w -exec chmod g+w \\{\\} \\;",
          "rm -rf #{release_to_link}/log #{release_to_link}/public/system #{release_to_link}/tmp/pids",
          "mkdir -p #{release_to_link}/tmp",
          "ln -nfs #{shared_path}/log #{release_to_link}/log",
          "mkdir -p #{release_to_link}/public",
          "mkdir -p #{release_to_link}/config",
          "ln -nfs #{shared_path}/system #{release_to_link}/public/system",
          "ln -nfs #{shared_path}/pids #{release_to_link}/tmp/pids",
          "ln -nfs #{shared_path}/config/database.yml #{release_to_link}/config/database.yml",
          fix_ownership_command(user, group, release_to_link)
        ].join(" && ")

    symlink = true
    chef_run "rm -f #{current_path} && ln -nfs #{release_to_link} #{current_path} && #{fix_ownership_command(user, group, current_path)}"
  rescue => e
    chef_run "rm -f #{current_path} && ln -nfs #{previous_release(release_to_link)} #{current_path} && #{fix_ownership_command(user, group, current_path)}" if symlink
    chef_run "rm -rf #{release_to_link}"
    raise e
  end
end

#userObject



116
117
118
# File 'lib/chef-deploy/cached_deploy.rb', line 116

def user
  @configuration[:user] || 'nobody'
end