gitpusshuten 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/.bundle/config +2 -0
  2. data/.gitignore +4 -0
  3. data/Gemfile +9 -0
  4. data/Gemfile.lock +53 -0
  5. data/README.md +7 -0
  6. data/bin/gitpusshuten +4 -0
  7. data/bin/heavenly +4 -0
  8. data/bin/ten +4 -0
  9. data/gitpusshuten.gemspec +26 -0
  10. data/lib/gitpusshuten/cli.rb +78 -0
  11. data/lib/gitpusshuten/command.rb +147 -0
  12. data/lib/gitpusshuten/commands/base.rb +246 -0
  13. data/lib/gitpusshuten/commands/delete.rb +27 -0
  14. data/lib/gitpusshuten/commands/help.rb +36 -0
  15. data/lib/gitpusshuten/commands/initialize.rb +61 -0
  16. data/lib/gitpusshuten/commands/push.rb +54 -0
  17. data/lib/gitpusshuten/commands/remote.rb +29 -0
  18. data/lib/gitpusshuten/commands/user.rb +252 -0
  19. data/lib/gitpusshuten/commands/version.rb +21 -0
  20. data/lib/gitpusshuten/configuration.rb +122 -0
  21. data/lib/gitpusshuten/environment.rb +70 -0
  22. data/lib/gitpusshuten/gem.rb +33 -0
  23. data/lib/gitpusshuten/git.rb +111 -0
  24. data/lib/gitpusshuten/helpers/environment/installers.rb +59 -0
  25. data/lib/gitpusshuten/helpers/environment/packages.rb +21 -0
  26. data/lib/gitpusshuten/helpers/environment/scp.rb +57 -0
  27. data/lib/gitpusshuten/helpers/environment/ssh.rb +77 -0
  28. data/lib/gitpusshuten/helpers/environment/ssh_key.rb +79 -0
  29. data/lib/gitpusshuten/helpers/environment/user.rb +70 -0
  30. data/lib/gitpusshuten/helpers/spinner.rb +98 -0
  31. data/lib/gitpusshuten/hook.rb +26 -0
  32. data/lib/gitpusshuten/hooks.rb +147 -0
  33. data/lib/gitpusshuten/initializer.rb +95 -0
  34. data/lib/gitpusshuten/local.rb +35 -0
  35. data/lib/gitpusshuten/log.rb +83 -0
  36. data/lib/gitpusshuten/modules/active_record/hooks.rb +19 -0
  37. data/lib/gitpusshuten/modules/apache/command.rb +354 -0
  38. data/lib/gitpusshuten/modules/bundler/command.rb +43 -0
  39. data/lib/gitpusshuten/modules/bundler/hooks.rb +8 -0
  40. data/lib/gitpusshuten/modules/mysql/command.rb +192 -0
  41. data/lib/gitpusshuten/modules/nanoc/hooks.rb +9 -0
  42. data/lib/gitpusshuten/modules/nginx/command.rb +447 -0
  43. data/lib/gitpusshuten/modules/passenger/command.rb +310 -0
  44. data/lib/gitpusshuten/modules/passenger/hooks.rb +4 -0
  45. data/lib/gitpusshuten/modules/rvm/command.rb +277 -0
  46. data/lib/gitpusshuten.rb +21 -0
  47. data/lib/templates/config.rb +37 -0
  48. data/lib/templates/hooks.rb +40 -0
  49. data/spec/cli_spec.rb +83 -0
  50. data/spec/command_spec.rb +76 -0
  51. data/spec/configuration_spec.rb +45 -0
  52. data/spec/environment_spec.rb +64 -0
  53. data/spec/fixtures/combined_hooks.rb +23 -0
  54. data/spec/fixtures/config.rb +23 -0
  55. data/spec/fixtures/hooks.rb +37 -0
  56. data/spec/fixtures/passenger.json +1 -0
  57. data/spec/gem_spec.rb +28 -0
  58. data/spec/git_spec.rb +59 -0
  59. data/spec/gitpusshuten_spec.rb +9 -0
  60. data/spec/hook_spec.rb +48 -0
  61. data/spec/hooks_spec.rb +150 -0
  62. data/spec/initializer_spec.rb +26 -0
  63. data/spec/log_spec.rb +20 -0
  64. data/spec/spec_helper.rb +43 -0
  65. metadata +220 -0
@@ -0,0 +1,447 @@
1
+ module GitPusshuTen
2
+ module Commands
3
+ class Nginx < GitPusshuTen::Commands::Base
4
+ description "[Module] NginX commands."
5
+ usage "nginx <command> <for|from|to> <environment> (environment)"
6
+ example "heavenly nginx install to staging # Installs the Nginx web server"
7
+ example "heavenly nginx setup staging environment # Sets up a managable vhost environment."
8
+ example "heavenly nginx update-configuration for staging # Only for Passenger users, when updating Ruby/Passenger versions."
9
+ example "heavenly nginx download-configuration from staging # Downloads the Nginx configuration file from the specified environment."
10
+ example "heavenly nginx upload-configuration to staging # Uploads the NginX configuration file to the specified environment."
11
+ example "heavenly nginx create-vhost for production # Creates a local vhost template for the specified environment."
12
+ example "heavenly nginx delete-vhost from production # Deletes the remote vhost for the specified environment."
13
+ example "heavenly nginx upload-vhost to staging # Uploads your local vhost to the server for the specified environment."
14
+ example "heavenly nginx download-vhost from production # Downloads the remote vhost from the specified environment."
15
+ example "heavenly nginx start staging environment # Starts the NginX webserver."
16
+ example "heavenly nginx stop production environment # Stops the NginX webserver."
17
+ example "heavenly nginx restart production environment # Restarts the NginX webserver."
18
+ example "heavenly nginx reload production environment # Reloads the NginX webserver."
19
+
20
+ def initialize(*objects)
21
+ super
22
+
23
+ @command = cli.arguments.shift
24
+
25
+ help if command.nil? or e.name.nil?
26
+
27
+ @command = @command.underscore
28
+ end
29
+
30
+ ##
31
+ # Installs the NginX web server
32
+ def perform_install!
33
+ warning "If you are planning to use #{y('Ruby')} and #{y('Passenger')} then #{r("DON'T")} use this NginX installer."
34
+ warning "Instead, use the Passenger module to install it."
35
+ standard "\n\s\s#{y("heavenly passenger install to #{y(e.name)}")}\n\n"
36
+
37
+ message "If you do not plan on using #{y('Ruby')} on this server, then this stand-alone installation should be fine."
38
+ message "Do you want to continue?"
39
+ exit unless yes?
40
+
41
+ prompt_for_root_password!
42
+
43
+ Spinner.return :message => "Installing NginX web server.." do
44
+ e.install!('nginx')
45
+ g('Done!')
46
+ end
47
+ message "NginX has been installed in #{y('/etc/nginx')}."
48
+ GitPusshuTen::Initializer.new('nginx', 'setup', 'for', "#{e.name}")
49
+ end
50
+
51
+ ##
52
+ # Starts Nginx
53
+ def perform_start!
54
+ ensure_nginx_executable_is_installed!
55
+ message "Starting Nginx."
56
+ puts e.execute_as_root("/etc/init.d/nginx start")
57
+ end
58
+
59
+ ##
60
+ # Stops Nginx
61
+ def perform_stop!
62
+ ensure_nginx_executable_is_installed!
63
+ message "Stopping Nginx."
64
+ puts e.execute_as_root("/etc/init.d/nginx stop")
65
+ end
66
+
67
+ ##
68
+ # Restarts Nginx
69
+ def perform_restart!
70
+ ensure_nginx_executable_is_installed!
71
+ message "Restarting Nginx."
72
+ perform_stop!
73
+ perform_start!
74
+ end
75
+
76
+ ##
77
+ # Reload Nginx
78
+ def perform_reload!
79
+ ensure_nginx_executable_is_installed!
80
+ message "Reloading Nginx Configuration."
81
+ puts e.execute_as_root("/etc/init.d/nginx reload")
82
+ end
83
+
84
+ ##
85
+ # Sets up a vHost directory and injects a snippet into the nginx.conf
86
+ def perform_setup!
87
+ find_nginx!
88
+
89
+ ##
90
+ # Creates a tmp dir
91
+ local.create_tmp_dir!
92
+
93
+ ##
94
+ # Downloads the NginX configuration file to tmp dir
95
+ e.scp_as_root(:download, @nginx_conf, local.tmp_dir)
96
+
97
+ ##
98
+ # Set the path to the downloaded file
99
+ local_file = File.join(local.tmp_dir, @nginx_conf_name)
100
+
101
+ if not File.read(local_file).include?('include sites-enabled/*;')
102
+ message "Configuring NginX configuration file."
103
+
104
+ ##
105
+ # Inject the 'include sites-enabled/*'
106
+ contents = File.read(local_file).sub(/http(\s|\t|\n){0,}\{/, "http {\n\s\s\s\sinclude sites-enabled/*;\n")
107
+ File.open(local_file, 'w') do |file|
108
+ file << contents
109
+ end
110
+
111
+ ##
112
+ # Make a backup of the old nginx.conf
113
+ message "Creating a backup of old NginX configuration file."
114
+ e.execute_as_root("cp '#{@nginx_conf}' '#{@nginx_conf}.backup.#{Time.now.to_i}'")
115
+
116
+ ##
117
+ # Upload the file back
118
+ message "Updating NginX configuration file."
119
+ e.scp_as_root(:upload, local_file, @nginx_conf)
120
+
121
+ ##
122
+ # Create the vhosts dir on the server
123
+ message "Creating #{@nginx_vhosts_dir} directory."
124
+ e.execute_as_root("mkdir -p #{@nginx_vhosts_dir}")
125
+ end
126
+
127
+ ##
128
+ # Removes the tmp dir
129
+ message "Cleaning up #{local.tmp_dir}"
130
+ local.remove_tmp_dir!
131
+
132
+ ##
133
+ # Create NginX directory
134
+ # Create NginX vhost file (if it doesn't already exist)
135
+ create_vhost_template_file!
136
+ end
137
+
138
+ ##
139
+ # Downloads the NginX configuration file
140
+ def perform_download_config!
141
+ find_nginx!
142
+ if not @nginx_conf
143
+ error "Could not find the NginX configuration file in #{y(@nginx_conf)}"
144
+ exit
145
+ end
146
+
147
+ local_nginx_dir = File.join(local.gitpusshuten_dir, 'nginx')
148
+ local.execute("mkdir -p '#{local_nginx_dir}'")
149
+ Spinner.return :message => "Downloading NginX configuration file to #{y(local_nginx_dir)}.." do
150
+ e.scp_as_root(:download, @nginx_conf, local_nginx_dir)
151
+ g('Done!')
152
+ end
153
+ end
154
+
155
+ ##
156
+ # Uploads the NginX configuration file
157
+ def perform_upload_config!
158
+ find_nginx!
159
+ if not e.directory?('/etc/nginx')
160
+ error "Could not find the NginX installation directory in #{y('/etc/nginx')}"
161
+ exit
162
+ end
163
+
164
+ local_configuration_file = File.join(local.gitpusshuten_dir, 'nginx', 'nginx.conf')
165
+ if not File.exist?(local_configuration_file)
166
+ error "Could not find the local NginX configuration file in #{y(local_configuration_file)}"
167
+ exit
168
+ end
169
+
170
+ Spinner.return :message => "Uploading NginX configuration file #{y(local_configuration_file)}.." do
171
+ e.scp_as_root(:upload, local_configuration_file, @nginx_conf)
172
+ g('Done!')
173
+ end
174
+ end
175
+
176
+ ##
177
+ # Updates a local vhost
178
+ def perform_upload_vhost!
179
+ find_nginx!
180
+
181
+ if not e.directory?(@nginx_vhosts_dir)
182
+ error "Could not upload your vhost because the vhost directory does not exist on the server."
183
+ error "Did you run #{y("heavenly nginx setup for #{e.name}")} yet?"
184
+ exit
185
+ end
186
+
187
+ vhost_file = File.join(local.gitpusshuten_dir, 'nginx', "#{e.name}.vhost")
188
+ if File.exist?(vhost_file)
189
+ message "Uploading #{y(vhost_file)} to " + y(File.join(@nginx_vhosts_dir, "#{e.sanitized_app_name}.#{e.name}.vhost!"))
190
+
191
+ prompt_for_root_password!
192
+
193
+ Spinner.return :message => "Uploading vhost.." do
194
+ e.scp_as_root(:upload, vhost_file, File.join(@nginx_vhosts_dir, "#{e.sanitized_app_name}.#{e.name}.vhost"))
195
+ g("Finished uploading!")
196
+ end
197
+
198
+ perform_restart!
199
+ else
200
+ error "Could not locate vhost file #{y(vhost_file)}."
201
+ error "Did you run #{y("heavenly nginx setup for #{e.name}")} yet?"
202
+ exit
203
+ end
204
+ end
205
+
206
+ ##
207
+ # Deletes a vhost
208
+ def perform_delete_vhost!
209
+ find_nginx!
210
+
211
+ vhost_file = File.join(@nginx_vhosts_dir, "#{e.sanitized_app_name}.#{e.name}.vhost")
212
+ if e.file?(vhost_file)
213
+ Spinner.return :message => "Deleting #{y(vhost_file)}!" do
214
+ e.execute_as_root("rm #{vhost_file}")
215
+ g('Done!')
216
+ end
217
+ perform_reload!
218
+ else
219
+ message "#{y(vhost_file)} does not exist."
220
+ exit
221
+ end
222
+ end
223
+
224
+ ##
225
+ # Creates a vhost
226
+ def perform_create_vhost!
227
+ create_vhost_template_file!
228
+ end
229
+
230
+ ##
231
+ # Performs the Update Configuration command
232
+ # This is particularly used when you change Passenger or Ruby versions
233
+ # so these are updated in the nginx.conf file.
234
+ def perform_update_configuration!
235
+ find_nginx!
236
+
237
+ message "Checking the #{y(@nginx_conf)} for current Passenger configuration."
238
+ config_contents = e.execute_as_root("cat '#{@nginx_conf}'")
239
+ if not config_contents.include? 'passenger_root' or not config_contents.include?('passenger_ruby')
240
+ error "Could not find Passenger configuration, has it ever been set up?"
241
+ exit
242
+ end
243
+
244
+ message "Checking if Passenger is installed under the #{y('default')} Ruby."
245
+ if not e.installed?('passenger')
246
+ message "Passenger isn't installed for the current Ruby"
247
+ Spinner.return :message => "Installing latest Phusion Passenger Gem.." do
248
+ e.execute_as_root('gem install passenger --no-ri --no-rdoc')
249
+ g("Done!")
250
+ end
251
+ end
252
+
253
+ Spinner.return :message => "Finding current Phusion Passenger Gem version..." do
254
+ if e.execute_as_root('passenger-config --version') =~ /(\d+\.\d+\..+)/
255
+ @passenger_version = $1.chomp.strip
256
+ g('Found!')
257
+ else
258
+ r('Could not find the current Passenger version.')
259
+ end
260
+ end
261
+
262
+ exit if @passenger_version.nil?
263
+
264
+ Spinner.return :message => "Finding current Ruby version for the current Phusion Passenger Gem.." do
265
+ if e.execute_as_root('passenger-config --root') =~ /\/usr\/local\/rvm\/gems\/(.+)\/gems\/passenger-.+/
266
+ @ruby_version = $1.chomp.strip
267
+ g('Found!')
268
+ else
269
+ r("Could not find the current Ruby version under which the Passenger Gem has been installed.")
270
+ end
271
+ end
272
+
273
+ exit if @ruby_version.nil?
274
+
275
+ puts <<-INFO
276
+
277
+
278
+ [Detected Versions]
279
+
280
+ Ruby Version: #{@ruby_version}
281
+ Phusion Passenger Version: #{@passenger_version}
282
+
283
+
284
+ INFO
285
+
286
+ message "NginX will now be configured to work with the above versions. Is this correct?"
287
+ exit unless yes?
288
+
289
+ ##
290
+ # Checks to see if Passengers WatchDog is available in the current Passenger gem
291
+ # If it is not, then Passenger needs to run the "passenger-install-nginx-module" so it gets installed
292
+ if not e.directory?("/usr/local/rvm/gems/#{@ruby_version}/gems/passenger-#{@passenger_version}/agents")
293
+ message "Phusion Passenger has not yet been installed for this Ruby's Passenger Gem."
294
+ message "You need to update #{y('NginX')} and #{y('Passenger')} to proceed with the configuration.\n\n"
295
+ message "Would you like to update #{y('NginX')} and #{y('Phusion Passenger')} #{y(@passenger_version)} for #{y(@ruby_version)}?"
296
+ message "NOTE: Your current #{y('NginX')} configuration will #{g('not')} be lost."
297
+
298
+ if yes?
299
+ Spinner.return :message => "Ensuring #{y('Phusion Passenger')} and #{y('NginX')} dependencies are installed.." do
300
+ e.install!("build-essential libcurl4-openssl-dev bison openssl libreadline5 libreadline5-dev curl git-core zlib1g zlib1g-dev libssl-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev")
301
+ g("Done!")
302
+ end
303
+
304
+ message "Installing NginX with the Phusion Passenger Module."
305
+ Spinner.return :message => "Installing, this may take a while.." do
306
+ e.execute_as_root("passenger-install-nginx-module --auto --auto-download --prefix='/etc/nginx'")
307
+ g("Done!")
308
+ end
309
+ else
310
+ exit
311
+ end
312
+ end
313
+
314
+ ##
315
+ # Creates a tmp dir
316
+ local.create_tmp_dir!
317
+
318
+ ##
319
+ # Downloads the NGINX configuration file to tmp dir
320
+ message "Updating Phusion Passenger paths in the NginX Configuration."
321
+ Spinner.return :message => "Configuring NginX.." do
322
+ e.scp_as_root(:download, @nginx_conf, local.tmp_dir)
323
+
324
+ local_configuration_file = File.join(local.tmp_dir, @nginx_conf_name)
325
+ update = File.read(local_configuration_file)
326
+ update.sub! /passenger_root \/usr\/local\/rvm\/gems\/(.+)\/gems\/passenger\-(.+)\;/,
327
+ "passenger_root /usr/local/rvm/gems/#{@ruby_version}/gems/passenger-#{@passenger_version};"
328
+
329
+ update.sub! /passenger_ruby \/usr\/local\/rvm\/wrappers\/(.+)\/ruby\;/,
330
+ "passenger_ruby /usr/local/rvm/wrappers/#{@ruby_version}/ruby;"
331
+
332
+ File.open(local_configuration_file, 'w') do |file|
333
+ file << update
334
+ end
335
+
336
+ ##
337
+ # Create a backup of the current configuration file
338
+ e.execute_as_root("cp '#{@nginx_conf}' '#{@nginx_conf}.backup.#{Time.now.to_i}'")
339
+
340
+ ##
341
+ # Upload the updated NginX configuration file
342
+ e.scp_as_root(:upload, local_configuration_file, @nginx_conf)
343
+
344
+ ##
345
+ # Remove the local tmp directory
346
+ local.remove_tmp_dir!
347
+
348
+ g("Done!")
349
+ end
350
+
351
+ message "NginX configuration file has been updated!"
352
+ message "#{y(@nginx_conf)}\n\n"
353
+
354
+ warning "If you changed #{y('Ruby versions')}, be sure that all your application gems are installed."
355
+ warning "If you only updated #{y('Phusion Passenger')} and did not change #{y('Ruby versions')}"
356
+ warning "then you should be able to just restart #{y('NginX')} right away since all application gems should still be in tact.\n\n"
357
+
358
+ message "When ready, run the following command to restart #{y('NginX')} and have the applied updates take effect:"
359
+ standard "\n\s\s#{y("heavenly nginx restart for #{e.name}")}"
360
+ end
361
+
362
+ def perform_download_vhost!
363
+ load_configuration!
364
+ find_correct_paths!
365
+
366
+ remote_vhost = File.join(@nginx_vhosts_dir, "#{e.sanitized_app_name}.#{e.name}.vhost")
367
+ if not e.file?(remote_vhost) # prompts root
368
+ error "There is no vhost currently present in #{y(remote_vhost)}."
369
+ exit
370
+ end
371
+
372
+ local_vhost = File.join(local.gitpusshuten_dir, 'nginx', "#{e.name}.vhost")
373
+ if File.exist?(local_vhost)
374
+ warning "#{y(local_vhost)} already exists. Do you want to overwrite it?"
375
+ exit unless yes?
376
+ end
377
+
378
+ local.execute("mkdir -p #{File.join(local.gitpusshuten_dir, 'nginx')}")
379
+ Spinner.return :message => "Downloading vhost.." do
380
+ e.scp_as_root(:download, remote_vhost, local_vhost)
381
+ g("Finished downloading!")
382
+ end
383
+ message "You can find the vhost in: #{y(local_vhost)}."
384
+ end
385
+
386
+ ##
387
+ # Installs the Nginx executable if it does not exist
388
+ def ensure_nginx_executable_is_installed!
389
+ if not e.file?("/etc/init.d/nginx")
390
+ message "Installing NginX executable for starting/stopping/restarting/reloading Nginx."
391
+ e.download_packages!('$HOME', :root)
392
+ e.execute_as_root("cp $HOME/gitpusshuten-packages/modules/nginx/nginx /etc/init.d/nginx")
393
+ e.clean_up_packages!('$HOME', :root)
394
+ end
395
+ end
396
+
397
+ ##
398
+ # Creates a vhost template file if it doesn't already exist.
399
+ def create_vhost_template_file!
400
+ local.execute("mkdir -p '#{File.join(local.gitpusshuten_dir, 'nginx')}'")
401
+ vhost_file = File.join(local.gitpusshuten_dir, 'nginx', "#{e.name}.vhost")
402
+
403
+ create_file = true
404
+ if File.exist?(vhost_file)
405
+ warning "#{y(vhost_file)} already exists, do you want to overwrite it?"
406
+ create_file = yes?
407
+ end
408
+
409
+ if create_file
410
+ File.open(vhost_file, 'w') do |file|
411
+ file << "server {\n"
412
+ file << "\s\slisten 80;\n"
413
+ file << "\s\sserver_name mydomain.com www.mydomain.com;\n"
414
+ file << "\s\sroot #{e.app_dir}/public;\n"
415
+ file << "\s\s# passenger_enabled on; # For Phusion Passenger users\n"
416
+ file << "}\n"
417
+ end
418
+ message "The vhost has been created in #{y(vhost_file)}."
419
+ end
420
+ end
421
+
422
+ ##
423
+ # Finds and sets the NginX Conf path
424
+ def find_nginx!
425
+ ##
426
+ # NginX Conf path you get from Passenger
427
+ if e.file?('/etc/nginx/conf/nginx.conf')
428
+ @nginx_conf = '/etc/nginx/conf/nginx.conf'
429
+ @nginx_conf_dir = '/etc/nginx/conf'
430
+ end
431
+
432
+ ##
433
+ # NginX Conf path you get from Aptitude
434
+ if e.file?('/etc/nginx/nginx.conf')
435
+ @nginx_conf = '/etc/nginx/nginx.conf'
436
+ @nginx_conf_dir = '/etc/nginx'
437
+ end
438
+
439
+ ##
440
+ # Set additional configuration
441
+ @nginx_conf_name = @nginx_conf.split('/').last
442
+ @nginx_vhosts_dir = @nginx_conf_dir + '/sites-enabled'
443
+ end
444
+
445
+ end
446
+ end
447
+ end