Class: Harrison::Deploy
- Inherits:
-
Base
- Object
- Base
- Harrison::Deploy
show all
- Defined in:
- lib/harrison/deploy.rb
Defined Under Namespace
Classes: Phase
Instance Attribute Summary collapse
Attributes inherited from Base
#options
Instance Method Summary
collapse
Methods inherited from Base
#download, #exec, option_helper, #upload
Constructor Details
#initialize(opts = {}) ⇒ Deploy
Returns a new instance of Deploy.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/harrison/deploy.rb', line 15
def initialize(opts={})
self.class.option_helper(:hosts)
self.class.option_helper(:base_dir)
self.class.option_helper(:deploy_via)
self.class.option_helper(:keep)
self.class.option_helper(:confirm)
arg_opts = [
[ :hosts, "List of remote hosts to deploy to. Can also be specified in Harrisonfile.", :type => :strings ],
[ :keep, "Number of recent deploys to keep after a successful deploy. (Including the most recent deploy.) Defaults to keeping all deploys forever.", :type => :integer ],
[ :confirm, "Whether to interactively confirm the list of target hosts for deployment.", :type => :flag, :default => true ],
]
super(arg_opts, opts)
self.add_default_phases
end
|
Instance Attribute Details
#artifact ⇒ Object
Returns the value of attribute artifact.
5
6
7
|
# File 'lib/harrison/deploy.rb', line 5
def artifact
@artifact
end
|
#deploy_link ⇒ Object
Returns the value of attribute deploy_link.
8
9
10
|
# File 'lib/harrison/deploy.rb', line 8
def deploy_link
@deploy_link
end
|
#host ⇒ Object
The specific host among –hosts that we are currently working on.
6
7
8
|
# File 'lib/harrison/deploy.rb', line 6
def host
@host
end
|
#phases ⇒ Object
Returns the value of attribute phases.
11
12
13
|
# File 'lib/harrison/deploy.rb', line 11
def phases
@phases
end
|
#release_dir ⇒ Object
Returns the value of attribute release_dir.
7
8
9
|
# File 'lib/harrison/deploy.rb', line 7
def release_dir
@release_dir
end
|
#rollback ⇒ Object
Returns the value of attribute rollback.
10
11
12
|
# File 'lib/harrison/deploy.rb', line 10
def rollback
@rollback
end
|
Instance Method Details
#add_phase(name, &block) ⇒ Object
49
50
51
52
53
|
# File 'lib/harrison/deploy.rb', line 49
def add_phase(name, &block)
@_phases ||= Hash.new
@_phases[name] = Harrison::Deploy::Phase.new(name, &block)
end
|
#cleanup_deploys(limit) ⇒ Object
171
172
173
174
175
176
177
178
179
180
181
182
|
# File 'lib/harrison/deploy.rb', line 171
def cleanup_deploys(limit)
purge_deploys = self.deploys.sort.reverse.slice(limit..-1) || []
if purge_deploys.size > 0
puts "[#{self.host}] Purging #{purge_deploys.size} old deploys. (Keeping #{limit}...)"
purge_deploys.each do |stale_deploy|
remote_exec("cd deploys && rm -f #{stale_deploy}")
end
end
end
|
#cleanup_releases ⇒ Object
184
185
186
187
188
189
190
191
192
193
|
# File 'lib/harrison/deploy.rb', line 184
def cleanup_releases
keep_releases = self.active_releases
self.releases.each do |release|
unless keep_releases.include?(release)
remote_exec("cd releases && rm -rf #{release}")
end
end
end
|
#close(host = nil) ⇒ Object
195
196
197
198
199
200
201
202
203
|
# File 'lib/harrison/deploy.rb', line 195
def close(host=nil)
if host
@_conns[host].close if @_conns && @_conns[host]
elsif @_conns
@_conns.keys.each do |host|
@_conns[host].close unless @_conns[host].closed?
end
end
end
|
#current_symlink ⇒ Object
59
60
61
|
# File 'lib/harrison/deploy.rb', line 59
def current_symlink
"#{self.remote_project_dir}/current"
end
|
#invoke_user_block ⇒ Object
13
|
# File 'lib/harrison/deploy.rb', line 13
alias :invoke_user_block :run
|
#parse(args) ⇒ Object
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/harrison/deploy.rb', line 35
def parse(args)
super
@_argv_hosts = self.hosts.dup if self.hosts
self.rollback = args[0] == 'rollback'
unless self.rollback
self.artifact = args[1] || abort("ERROR: You must specify the artifact to be deployed as an argument to this command.")
end
end
|
#remote_exec(cmd) ⇒ Object
55
56
57
|
# File 'lib/harrison/deploy.rb', line 55
def remote_exec(cmd)
super("cd #{remote_project_dir} && #{cmd}")
end
|
#revert_current_symlink ⇒ Object
72
73
74
75
76
77
|
# File 'lib/harrison/deploy.rb', line 72
def revert_current_symlink
if @_old_current
self.remote_exec("ln -sfn #{@_old_current} #{self.current_symlink}")
end
end
|
#run ⇒ Object
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
# File 'lib/harrison/deploy.rb', line 79
def run
self.hosts = @_argv_hosts if @_argv_hosts
if self.hosts.respond_to?(:call)
resolved_hosts = self.hosts.call(self)
self.hosts = resolved_hosts
end
if !self.hosts || self.hosts.empty?
abort("ERROR: You must specify one or more hosts to deploy/rollback on, either in your Harrisonfile or via --hosts.")
end
if self.confirm
self.hosts.each { |h| puts " - #{h}" }
exit unless HighLine.new.agree("\nProceed with above-listed hosts?")
puts ""
end
self.phases ||= [ :upload, :extract, :link, :cleanup ]
self.base_dir ||= '/opt'
if self.rollback
puts "Rolling back \"#{project}\" to previously deployed release on #{hosts.size} hosts...\n\n"
self.host = hosts[0]
last_deploy = self.deploys.sort.reverse[1] || abort("ERROR: No previous deploy to rollback to.")
self.release_dir = remote_exec("cd deploys && readlink -vn #{last_deploy}")
self.phases.delete(:upload)
self.phases.delete(:extract)
self.phases.delete(:cleanup)
else
puts "Deploying #{artifact} for \"#{project}\" onto #{hosts.size} hosts...\n\n"
self.release_dir = "#{remote_project_dir}/releases/" + File.basename(artifact, '.tar.gz')
end
self.deploy_link = "#{remote_project_dir}/deploys/" + Time.new.utc.strftime('%Y-%m-%d_%H%M%S')
progress_stack = []
failed = catch(:failure) do
self.phases.each do |phase_name|
phase = @_phases[phase_name] || abort("ERROR: Could not resolve \"#{phase_name}\" as a deployment phase.")
self.hosts.each do |host|
self.host = host
phase._run(self)
progress_stack << { host: host, phase: phase_name }
end
end
false
end
if failed
print "\n"
progress_stack.reverse.each do |progress|
self.host = progress[:host]
phase = @_phases[progress[:phase]]
catch(:failure) do
phase._fail(self)
end
end
abort "\nDeployment failed, previously completed deployment actions have been reverted."
else
if self.rollback
puts "\nSucessfully rolled back #{project} on #{hosts.join(', ')}."
else
puts "\nSucessfully deployed #{artifact} to #{hosts.join(', ')}."
end
end
end
|
#update_current_symlink ⇒ Object
63
64
65
66
67
68
69
70
|
# File 'lib/harrison/deploy.rb', line 63
def update_current_symlink
@_old_current ||= self.remote_exec("if [ -L #{current_symlink} ]; then readlink -vn #{current_symlink}; fi")
@_old_current = nil if @_old_current.empty?
self.remote_exec("ln -sfn #{self.deploy_link} #{self.current_symlink}")
end
|