Class: WhiskeyDisk

Inherits:
Object
  • Object
show all
Defined in:
lib/whiskey_disk.rb,
lib/whiskey_disk/config.rb

Defined Under Namespace

Classes: Config

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configurationObject



19
20
21
# File 'lib/whiskey_disk.rb', line 19

def configuration
  @configuration ||= WhiskeyDisk::Config.fetch
end

.resultsObject (readonly)

Returns the value of attribute results.



6
7
8
# File 'lib/whiskey_disk.rb', line 6

def results
  @results
end

Class Method Details

.[](key) ⇒ Object



23
24
25
# File 'lib/whiskey_disk.rb', line 23

def [](key)
  configuration[key.to_s]
end

.apply_staleness_check(commands) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/whiskey_disk.rb', line 90

def apply_staleness_check(commands)
  needs(:deploy_to, :repository)
  
  check = "cd #{self[:deploy_to]}; " +
          "ml=\`cat .git/refs/heads/#{branch}\`; " +
          "mr=\`git ls-remote #{self[:repository]} refs/heads/#{branch}\`; "
  
  if self[:deploy_config_to]
    check += "cd #{self[:deploy_config_to]}; " +
             "cl=\`cat .git/refs/heads/#{config_branch}\`; " +
             "cr=\`git ls-remote #{self[:config_repository]} refs/heads/#{config_branch}\`; "
  end
  
  check += "if [[ $ml != ${mr%%\t*} ]] " +
           (self[:deploy_config_to] ? "|| [[ $cl != ${cr%%\t*} ]]" : '') +
           "; then #{commands}; else echo \"No changes to deploy.\"; fi"
end

.branchObject



60
61
62
# File 'lib/whiskey_disk.rb', line 60

def branch
  (self[:branch] and self[:branch] != '') ? self[:branch] : 'master'
end

.bufferObject



15
16
17
# File 'lib/whiskey_disk.rb', line 15

def buffer
  @buffer ||= []
end

.build_command(domain, cmd) ⇒ Object



131
132
133
# File 'lib/whiskey_disk.rb', line 131

def build_command(domain, cmd)
  "#{'set -x; ' if Config.debug?}" + encode_roles(domain[:roles]) + cmd
end

.build_path(path) ⇒ Object



228
229
230
231
# File 'lib/whiskey_disk.rb', line 228

def build_path(path)
  return path if path =~ %r{^/}
  File.join(self[:deploy_to], path)
end

.bundleObject



112
113
114
115
# File 'lib/whiskey_disk.rb', line 112

def bundle
  return '' if buffer.empty?
  (staleness_checks_enabled? and check_staleness?) ? apply_staleness_check(join_commands) : join_commands
end

.capture_git_changesObject



281
282
283
284
# File 'lib/whiskey_disk.rb', line 281

def capture_git_changes
  needs(:deploy_to)
  enqueue "git diff --name-only ${ml}..HEAD > #{self[:deploy_to]}/.whiskey_disk_git_changes"
end

.check_staleness?Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/whiskey_disk.rb', line 27

def check_staleness?
  WhiskeyDisk::Config.check_staleness?
end

.checkout_configuration_repositoryObject



253
254
255
256
# File 'lib/whiskey_disk.rb', line 253

def checkout_configuration_repository
  needs(:deploy_config_to, :config_repository)
  clone_repository(self[:config_repository], self[:deploy_config_to], config_branch)
end

.checkout_main_repositoryObject



248
249
250
251
# File 'lib/whiskey_disk.rb', line 248

def checkout_main_repository
  needs(:deploy_to, :repository)
  clone_repository(self[:repository], self[:deploy_to], branch)
end

.clone_repository(repo, path, my_branch) ⇒ Object



208
209
210
211
212
# File 'lib/whiskey_disk.rb', line 208

def clone_repository(repo, path, my_branch)
  enqueue "cd #{parent_path(path)}"
  enqueue("if [ -e #{path} ]; then echo 'Repository already cloned to [#{path}].  Skipping.'; " +
          "else git clone #{repo} #{tail_path(path)} && #{safe_branch_checkout(path, my_branch)}; fi")
end

.config_branchObject



64
65
66
# File 'lib/whiskey_disk.rb', line 64

def config_branch
  (self[:config_branch] and self[:config_branch] != '') ? self[:config_branch] : 'master'
end

.domain_limit_match?(domain, limit) ⇒ Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/whiskey_disk.rb', line 117

def domain_limit_match?(domain, limit)
  domain.sub(%r{^.*@}, '') == limit
end

.domain_of_interest?(domain) ⇒ Boolean

Returns:

  • (Boolean)


121
122
123
124
# File 'lib/whiskey_disk.rb', line 121

def domain_of_interest?(domain)
  return true unless limit = WhiskeyDisk::Config.domain_limit
  domain_limit_match?(domain, limit)
end

.enable_staleness_checksObject



31
32
33
# File 'lib/whiskey_disk.rb', line 31

def enable_staleness_checks
  @staleness_checks = true
end

.encode_roles(roles) ⇒ Object



126
127
128
129
# File 'lib/whiskey_disk.rb', line 126

def encode_roles(roles)
  return '' unless roles and !roles.empty?
  "export WD_ROLES='#{roles.join(':')}'; "
end

.enqueue(command) ⇒ Object



39
40
41
# File 'lib/whiskey_disk.rb', line 39

def enqueue(command)
  buffer << command
end

.ensure_config_parent_path_is_presentObject



243
244
245
246
# File 'lib/whiskey_disk.rb', line 243

def ensure_config_parent_path_is_present
  needs(:deploy_config_to)
  enqueue "mkdir -p #{parent_path(self[:deploy_config_to])}"
end

.ensure_main_parent_path_is_presentObject



238
239
240
241
# File 'lib/whiskey_disk.rb', line 238

def ensure_main_parent_path_is_present
  needs(:deploy_to)
  enqueue "mkdir -p #{parent_path(self[:deploy_to])}"
end

.env_varsObject



68
69
70
71
72
73
74
# File 'lib/whiskey_disk.rb', line 68

def env_vars
  return '' unless self[:rake_env]
  self[:rake_env].keys.inject('') do |buffer,k| 
    buffer += "#{k}='#{self[:rake_env][k]}' "
    buffer
  end
end

.flushObject



151
152
153
154
155
156
157
158
159
# File 'lib/whiskey_disk.rb', line 151

def flush
  needs(:domain)
  self[:domain].each do |domain|
    next unless domain_of_interest?(domain[:name])
    puts "Deploying #{domain[:name]}..."
    status = remote?(domain[:name]) ? run(domain, bundle) : shell(domain, bundle)
    record_result(domain[:name], status)
  end
end

.has_config_repo?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/whiskey_disk.rb', line 52

def has_config_repo?
  ! (self[:config_repository].nil? or self[:config_repository] == '')
end

.if_file_present(path, cmd) ⇒ Object



196
197
198
# File 'lib/whiskey_disk.rb', line 196

def if_file_present(path, cmd)
  "if [ -e #{path} ]; then #{cmd}; fi"
end

.if_task_defined(task, cmd) ⇒ Object



200
201
202
# File 'lib/whiskey_disk.rb', line 200

def if_task_defined(task, cmd)
  %Q(rakep=`#{env_vars} rake -P` && if [[ `echo "${rakep}" | grep #{task}` != "" ]]; then #{cmd}; fi )
end

.initialize_all_changesObject



275
276
277
278
279
# File 'lib/whiskey_disk.rb', line 275

def initialize_all_changes
  needs(:deploy_to)
  initialize_git_changes
  initialize_rsync_changes
end

.initialize_git_changesObject



264
265
266
267
268
# File 'lib/whiskey_disk.rb', line 264

def initialize_git_changes
  needs(:deploy_to)
  enqueue "rm -f #{self[:deploy_to]}/.whiskey_disk_git_changes"
  snapshot_git_revision
end

.initialize_rsync_changesObject



270
271
272
273
# File 'lib/whiskey_disk.rb', line 270

def initialize_rsync_changes
  needs(:deploy_to)
  enqueue "rm -f #{self[:deploy_to]}/.whiskey_disk_rsync_changes"
end

.join_commandsObject



108
109
110
# File 'lib/whiskey_disk.rb', line 108

def join_commands
  buffer.collect {|c| "{ #{c} ; }"}.join(' && ')
end

.needs(*keys) ⇒ Object



84
85
86
87
88
# File 'lib/whiskey_disk.rb', line 84

def needs(*keys)
  keys.each do |key|
    raise "No value for '#{key}' declared in configuration files [#{WhiskeyDisk::Config.configuration_file}]" unless self[key]
  end
end

.parent_path(path) ⇒ Object



76
77
78
# File 'lib/whiskey_disk.rb', line 76

def parent_path(path)
  File.split(path).first
end

.project_name_specified?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/whiskey_disk.rb', line 56

def project_name_specified?
  self[:project] != 'unnamed_project'
end

.record_result(domain, status) ⇒ Object



161
162
163
164
# File 'lib/whiskey_disk.rb', line 161

def record_result(domain, status)
  @results ||= []
  @results << { :domain => domain, :status => status }
end

.refresh_checkout(path, repo_branch) ⇒ Object



214
215
216
217
218
219
# File 'lib/whiskey_disk.rb', line 214

def refresh_checkout(path, repo_branch)
  enqueue "cd #{path}"
  enqueue "git fetch origin +refs/heads/#{repo_branch}:refs/remotes/origin/#{repo_branch} #{'&>/dev/null' unless Config.debug?}"
  enqueue "git checkout #{repo_branch} #{'&>/dev/null' unless Config.debug?}"
  enqueue "git reset --hard origin/#{repo_branch} #{'&>/dev/null' unless Config.debug?}"
end

.refresh_configurationObject



299
300
301
302
303
304
305
306
# File 'lib/whiskey_disk.rb', line 299

def refresh_configuration
  needs(:deploy_to, :deploy_config_to)
  raise "Must specify project name when using a configuration repository." unless project_name_specified?
  enqueue "echo Rsyncing configuration..."
  enqueue("rsync -a#{'v --progress' if Config.debug?} " + '--log-format="%t [%p] %i %n" ' +
          "#{self[:deploy_config_to]}/#{self[:project]}/#{self[:config_target]}/ #{self[:deploy_to]}/ " + 
          "> #{self[:deploy_to]}/.whiskey_disk_rsync_changes")
end

.remote?(domain) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
46
47
48
49
50
# File 'lib/whiskey_disk.rb', line 43

def remote?(domain)
  return false unless domain
  return false if domain == 'local'
  limit = WhiskeyDisk::Config.domain_limit 
  return false if limit and domain_limit_match?(domain, limit)

  true
end

.resetObject



8
9
10
11
12
13
# File 'lib/whiskey_disk.rb', line 8

def reset
  @configuration = nil
  @buffer = nil
  @staleness_checks = nil
  @results = nil
end

.run(domain, cmd) ⇒ Object



135
136
137
# File 'lib/whiskey_disk.rb', line 135

def run(domain, cmd)
  ssh(domain, cmd)
end

.run_post_deploy_hooksObject



314
315
316
317
318
# File 'lib/whiskey_disk.rb', line 314

def run_post_deploy_hooks
  needs(:deploy_to)
  run_script(self[:post_deploy_script])
  run_rake_task(self[:deploy_to], "deploy:post_deploy")
end

.run_post_setup_hooksObject



308
309
310
311
312
# File 'lib/whiskey_disk.rb', line 308

def run_post_setup_hooks
  needs(:deploy_to)
  run_script(self[:post_setup_script])
  run_rake_task(self[:deploy_to], "deploy:post_setup")
end

.run_rake_task(path, task_name) ⇒ Object



221
222
223
224
225
226
# File 'lib/whiskey_disk.rb', line 221

def run_rake_task(path, task_name)
  enqueue "echo Running rake #{task_name}..."
  enqueue "cd #{path}"
  enqueue(if_file_present("#{self[:deploy_to]}/Rakefile", 
    if_task_defined(task_name, "#{env_vars} rake #{'--trace' if Config.debug?} #{task_name} to=#{self[:environment]}")))
end

.run_script(script) ⇒ Object



233
234
235
236
# File 'lib/whiskey_disk.rb', line 233

def run_script(script)
  return unless script
  enqueue(%Q<cd #{self[:deploy_to]}; echo "Running post script..."; #{env_vars} bash #{'-x' if Config.debug?} #{build_path(script)}>)
end

.safe_branch_checkout(path, my_branch) ⇒ Object



204
205
206
# File 'lib/whiskey_disk.rb', line 204

def safe_branch_checkout(path, my_branch)
  %Q(cd #{path} && git checkout -b #{my_branch} origin/#{my_branch} || git checkout #{my_branch} origin/#{my_branch} || git checkout #{my_branch})
end

.shell(domain, cmd) ⇒ Object



146
147
148
149
# File 'lib/whiskey_disk.rb', line 146

def shell(domain, cmd)
  puts "Running command locally: [#{cmd}]" if Config.debug?
  system('bash', '-c', build_command(domain, cmd))
end

.snapshot_git_revisionObject



258
259
260
261
262
# File 'lib/whiskey_disk.rb', line 258

def snapshot_git_revision
  needs(:deploy_to)
  enqueue "cd #{self[:deploy_to]}"
  enqueue %Q{ml=\`cat .git/refs/heads/#{branch}\`}
end

.ssh(domain, cmd) ⇒ Object



139
140
141
142
143
144
# File 'lib/whiskey_disk.rb', line 139

def ssh(domain, cmd)
  puts "Running command on [#{domain}]: [#{cmd}]" if Config.debug?
  args = [domain[:name], build_command(domain, cmd)]
  args.unshift '-v' if Config.debug?
  system('ssh', *args)
end

.staleness_checks_enabled?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/whiskey_disk.rb', line 35

def staleness_checks_enabled?
  !!@staleness_checks
end

.success?Boolean

Returns:

  • (Boolean)


191
192
193
194
# File 'lib/whiskey_disk.rb', line 191

def success?
  return true if !results or results.empty?
  results.all? {|result| result[:status] }
end

.summarizeObject



179
180
181
182
183
184
185
186
187
188
189
# File 'lib/whiskey_disk.rb', line 179

def summarize
  puts "\nResults:"
  if results and not results.empty?
    total, successes, failures = summarize_results(results)
    puts "Total: #{total} deployment#{total == 1 ? '' : 's'}, " +
      "#{successes} success#{successes == 1 ? '' : 'es'}, " +
      "#{failures} failure#{failures == 1 ? '' : 's'}."
  else
    puts "No deployments to report."
  end       
end

.summarize_results(results) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/whiskey_disk.rb', line 166

def summarize_results(results)
  successes = failures = 0
  results.each do |result|
    puts "#{result[:domain]} => #{result[:status] ? 'succeeded' : 'failed'}."
    if result[:status]
      successes += 1 
    else
      failures += 1
    end
  end
  [successes + failures, successes, failures]
end

.tail_path(path) ⇒ Object



80
81
82
# File 'lib/whiskey_disk.rb', line 80

def tail_path(path)
  File.split(path).last
end

.update_configuration_repository_checkoutObject



293
294
295
296
297
# File 'lib/whiskey_disk.rb', line 293

def update_configuration_repository_checkout
  needs(:deploy_config_to)
  initialize_rsync_changes
  refresh_checkout(self[:deploy_config_to], config_branch)
end

.update_main_repository_checkoutObject



286
287
288
289
290
291
# File 'lib/whiskey_disk.rb', line 286

def update_main_repository_checkout
  needs(:deploy_to)
  initialize_git_changes
  refresh_checkout(self[:deploy_to], branch)
  capture_git_changes
end