5
6
7
8
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# File 'lib/capistrano-redeploy.rb', line 5
def self.extended(configuration)
configuration.load {
namespace(:redeploy) {
desc("Redeploy current running application.")
task(:default, :except => { :no_release => true }) {
update
}
task(:update, :except => { :no_release => true }) {
transaction do
update_code
finalize_update
end
}
_cset(:redeploy_path) { current_release }
task(:update_code, :except => { :no_release => true }) {
begin
tmpdir = capture("mktemp -d /tmp/redeploy.XXXXXXXXXX").strip
run("rm -rf #{tmpdir.dump} && mkdir -p #{tmpdir}")
deploy!(tmpdir)
redeploy!(tmpdir, redeploy_path)
ensure
run("rm -rf #{tmpdir.dump}")
end
}
on(:load) {
if fetch(:redeploy_use_assets, false)
before "redeploy:finalize_update", "deploy:assets:symlink"
after "redeploy:update_code", "deploy:assets:precompile"
before "redeploy:assets:precompile", "deploy:assets:update_asset_mtimes"
end
}
def _middle_copy(object)
o = object.clone
object.instance_variables.each do |k|
v = object.instance_variable_get(k)
o.instance_variable_set(k, v ? v.clone : v)
end
o
end
_cset(:redeploy_variables, {})
def deploy!(destination, options={})
begin
releases_path = capture("mktemp -d /tmp/releases.XXXXXXXXXX", options).strip
release_path = File.join(releases_path, release_name)
run("rm -rf #{releases_path.dump} && mkdir -p #{releases_path.dump}", options)
c = _middle_copy(top)
c.instance_eval do
set(:deploy_to, File.dirname(releases_path))
set(:releases_path, releases_path)
set(:release_path, release_path)
set(:revision) { source.head }
set(:source) { ::Capistrano::Deploy::SCM.new(scm, self) }
set(:real_revision) { source.local.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { run_locally(cmd) } } }
set(:strategy) { ::Capistrano::Deploy::Strategy.new(deploy_via, self) }
redeploy_variables.each do |key, val|
set(key, val)
end
logger.debug("Fetching source for re-deployment from #{repository} (#{scm}) via #{deploy_via}.")
strategy.deploy!
end
run("rsync -lrpt #{(release_path + "/").dump} #{destination.dump}", options)
ensure
run("rm -rf #{releases_path.dump}", options)
end
end
_cset(:redeploy_children, %w(public))
_cset(:redeploy_exclusions, %w(assets system))
_cset(:redeploy_path_map) {
s = fetch(:redeploy_source, ".").to_s
d = fetch(:redeploy_destination, ".").to_s
Hash[redeploy_children.map { |c| [File.join(s, c), File.join(d, c)] }]
}
def absolute_path_map(source, destination)
map = redeploy_path_map.map { |s_subdir, d_subdir|
[ File.expand_path(File.join(source, s_subdir)), File.expand_path(File.join(destination, d_subdir)) ]
}
Hash[map]
end
def redeploy!(source, destination, options={})
exclusions = redeploy_exclusions.map { |e| "--exclude=#{e.dump}" }.join(" ")
absolute_path_map(source, destination).each do |s, d|
logger.debug("Re-deploying from `#{s}' to `#{d}'.")
run("mkdir -p #{s.dump} #{d.dump}", options)
run("rsync -lrpt #{exclusions} #{(s + "/").dump} #{d.dump}", options)
end
end
task(:finalize_update, :except => { :no_release => true }) {
escaped_release = redeploy_path.to_s.shellescape
commands = []
commands << "chmod -R -- g+w #{escaped_release}" if fetch(:group_writable, true)
shared_children.map do |dir|
d = dir.shellescape
if (dir.rindex('/')) then
commands += ["rm -rf -- #{escaped_release}/#{d}",
"mkdir -p -- #{escaped_release}/#{dir.slice(0..(dir.rindex('/'))).shellescape}"]
else
commands << "rm -rf -- #{escaped_release}/#{d}"
end
commands << "ln -s -- #{shared_path}/#{dir.split('/').last.shellescape} #{escaped_release}/#{d}"
end
run commands.join(' && ') if commands.any?
if fetch(:normalize_asset_timestamps, true)
stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
asset_paths = fetch(:public_children, %w(images stylesheets javascripts)).map { |p| "#{escaped_release}/public/#{p}" }
run("find #{asset_paths.join(" ")} -exec touch -t #{stamp} -- {} ';'; true",
:env => { "TZ" => "UTC" }) if asset_paths.any?
end
}
}
}
end
|