gitpusshuten 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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