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



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

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

Instance Method Details

#all_releasesObject



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

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

#callback(what) ⇒ Object

before_symlink before_restart



52
53
54
55
56
57
58
59
# File 'lib/chef-deploy/cached_deploy.rb', line 52

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(newrev) ⇒ Object



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

def check_current_revision_and_noop_if_same(newrev)
  IO.read("#{latest_release}/REVISION").chomp == newrev
rescue
  false
end

#chef_run(cmd) ⇒ Object



161
162
163
# File 'lib/chef-deploy/cached_deploy.rb', line 161

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

#cleanupObject



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

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

#configurationObject



186
187
188
# File 'lib/chef-deploy/cached_deploy.rb', line 186

def configuration
  @configuration
end

#current_pathObject



110
111
112
# File 'lib/chef-deploy/cached_deploy.rb', line 110

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
# 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
  
  Chef::Log.info "ensuring proper ownership"
  chef_run("chown -R #{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
  
  chef_run("chown -R #{user}:#{group} #{@configuration[:deploy_to]}")    
  
  callback(:before_migrate)
  migrate
  callback(:before_symlink)
  symlink
  callback(:before_restart)
  restart
  callback(:after_restart)
  cleanup
end

#groupObject



106
107
108
# File 'lib/chef-deploy/cached_deploy.rb', line 106

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

#latest_releaseObject



61
62
63
# File 'lib/chef-deploy/cached_deploy.rb', line 61

def latest_release
  all_releases.last
end

#migrateObject



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

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("chown -R #{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



126
127
128
# File 'lib/chef-deploy/cached_deploy.rb', line 126

def node
  @configuration[:node]
end

#oldest_releaseObject



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

def oldest_release
  all_releases.first
end

#previous_release(current = latest_release) ⇒ Object



65
66
67
68
# File 'lib/chef-deploy/cached_deploy.rb', line 65

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

#release_dirObject



118
119
120
# File 'lib/chef-deploy/cached_deploy.rb', line 118

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

#release_pathObject



122
123
124
# File 'lib/chef-deploy/cached_deploy.rb', line 122

def release_path
  @configuration[:release_path]
end

#restartObject



37
38
39
40
41
42
# File 'lib/chef-deploy/cached_deploy.rb', line 37

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



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

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
end

#run(cmd) ⇒ Object



165
166
167
# File 'lib/chef-deploy/cached_deploy.rb', line 165

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

#run_with_result(cmd) ⇒ Object

Raises:



155
156
157
158
159
# File 'lib/chef-deploy/cached_deploy.rb', line 155

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

#shared_pathObject



114
115
116
# File 'lib/chef-deploy/cached_deploy.rb', line 114

def shared_path
  configuration[:shared_path]
end

#sourceObject



190
191
192
193
194
195
196
197
# File 'lib/chef-deploy/cached_deploy.rb', line 190

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

#sudo(cmd) ⇒ Object



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

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


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/chef-deploy/cached_deploy.rb', line 130

def symlink(release_to_link=latest_release)
  Chef::Log.info "symlinking and finishing deploy"
  symlink = false
  begin
    chef_run [ "chmod -R g+w #{release_to_link}",
          "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",
          "chown -R #{user}:#{group} #{release_to_link}"
        ].join(" && ")

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

#userObject



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

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