Class: CachedDeploy

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

Direct Known Subclasses

CachedDeploySymfony

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ CachedDeploy

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



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

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

Instance Method Details

#all_releasesObject



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

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

#callback(what) ⇒ Object

before_symlink before_restart



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

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



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

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

#chef_run(cmd) ⇒ Object



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

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

#cleanupObject



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

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

#configurationObject



191
192
193
# File 'lib/chef-deploy/cached_deploy.rb', line 191

def configuration
  @configuration
end

#current_pathObject



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

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
 
  if check_current_revision_and_noop_if_same @configuration[:revision]
    Chef::Log.info "skipping deploy, no updates"
    return false
  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_symlink)
  symlink
  callback(:before_migrate)
  migrate
  callback(:before_restart)
  restart
  callback(:after_restart)
  cleanup
end

#groupObject



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

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

#latest_releaseObject



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

def latest_release
  all_releases.last
end

#migrateObject



98
99
100
101
102
103
104
105
# File 'lib/chef-deploy/cached_deploy.rb', line 98

def migrate
  if @configuration[:migrate]
    chef_run "ln -nfs #{shared_path}/config/database.yml #{latest_release}/config/database.yml"
    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



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

def node
  @configuration[:node]
end

#oldest_releaseObject



76
77
78
# File 'lib/chef-deploy/cached_deploy.rb', line 76

def oldest_release
  all_releases.first
end

#previous_release(current = latest_release) ⇒ Object



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

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

#release_dirObject



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

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

#release_pathObject



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

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} RAILS_ENV=#{@configuration[:environment]} RACK_ENV=#{@configuration[:environment]} MERB_ENV=#{@configuration[:environment]} #{@configuration[:restart_command]}")
  end
end

#rollbackObject



90
91
92
93
94
95
96
# File 'lib/chef-deploy/cached_deploy.rb', line 90

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



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

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

#run_with_result(cmd) ⇒ Object

Raises:



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

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

#shared_pathObject



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

def shared_path
  configuration[:shared_path]
end

#sourceObject



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

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

#sudo(cmd) ⇒ Object



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

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


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/chef-deploy/cached_deploy.rb', line 135

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



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

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