oneblackbear-obbistrano 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README.txt +3 -3
  2. data/obbistrano.rb +476 -0
  3. metadata +2 -2
data/README.txt CHANGED
@@ -1,6 +1,6 @@
1
- == Automated Server and application deployment
1
+ = Automated Server and application deployment
2
2
 
3
- === Server-wide setup
3
+ == Server-wide setup
4
4
 
5
5
  @cap host:setup -s h=xxxx@
6
6
  Ensures that there is a setup for each app on the specified server.
@@ -14,7 +14,7 @@ Triggers an Amazon S3 backup of the backup folder.
14
14
 
15
15
 
16
16
 
17
- === Application Level Setup
17
+ == Application Level Setup
18
18
 
19
19
  @cap app:deploy -s a=xxxx@
20
20
 
data/obbistrano.rb ADDED
@@ -0,0 +1,476 @@
1
+ require 'rubygems'
2
+ require 'activeresource'
3
+
4
+ TTL = 86400
5
+ API_PASSWORD = fetch "slicehost_api_key", false
6
+
7
+ class Record < ActiveResource::Base
8
+ self.site = "https://#{API_PASSWORD}@api.slicehost.com/"
9
+ end
10
+
11
+ class Zone < ActiveResource::Base
12
+ self.site = "https://#{API_PASSWORD}@api.slicehost.com/"
13
+ end
14
+
15
+ class Slice < ActiveResource::Base
16
+ self.site = "https://#{API_PASSWORD}@api.slicehost.com/"
17
+ end
18
+
19
+
20
+ desc "Setup Application Config"
21
+ task :config_setup do
22
+ # options = YAML.load(File.read("config.yml"))
23
+ # set :working_server, h rescue nil
24
+ # set :working_app, a rescue nil
25
+ set :root_pass, root rescue nil
26
+ end
27
+ #
28
+ # task :config_write do
29
+ # File.open('config.yml', 'w') { |f| f.puts options.to_yaml }
30
+ # #puts "Hello I'm about to mangle your config file"
31
+ # end
32
+
33
+ namespace :slicehost do
34
+
35
+ desc "Sets up slicehost DNS for each of the servers specified with a role of web."
36
+ task :setup do
37
+ get_slice_ip
38
+ servers = find_servers :roles => :web
39
+ servers.each do |s|
40
+ if !zone = Zone.find(:first, :params => {:origin => "#{s}."})
41
+ zone = Zone.new(:origin => s, :ttl => TTL)
42
+ zone.save
43
+ end
44
+ recordOne = Record.new(:record_type => 'A', :zone_id => zone.id, :name => 'www', :data => "#{slice_ip}")
45
+ recordTwo = Record.new(:record_type => 'A', :zone_id => zone.id, :name => '@', :data => "#{slice_ip}")
46
+ recordThree = Record.new(:record_type => 'A', :zone_id => zone.id, :name => 'beta', :data => "#{slice_ip}")
47
+ recordFour = Record.new(:record_type => 'A', :zone_id => zone.id, :name => zone.origin, :data => "#{slice_ip}")
48
+ recordFive = Record.new(:record_type => 'NS', :zone_id => zone.id, :name => zone.origin, :data => 'ns1.slicehost.net.')
49
+ recordSix = Record.new(:record_type => 'NS', :zone_id => zone.id, :name => zone.origin, :data => 'ns2.slicehost.net.')
50
+ recordSeven = Record.new(:record_type => 'NS', :zone_id => zone.id, :name => zone.origin, :data => 'ns3.slicehost.net.')
51
+ [recordOne, recordTwo, recordThree, recordFour, recordFive, recordSix, recordSeven].each {|r| r.save}
52
+ end
53
+ end
54
+
55
+ task :get_slice_ip do
56
+ set :slice_ip, get_ip(fetch("host", false))
57
+ end
58
+
59
+ desc "Sets up slicehost DNS for Google Apps usage on each of the servers specified with a role of web."
60
+ task :googleapps do
61
+ API_PASSWORD = "#{slicehost_api_key}"
62
+ mx_records = <<-RECORD
63
+ ASPMX.L.GOOGLE.COM.
64
+ ALT1.ASPMX.L.GOOGLE.COM.
65
+ ALT2.ASPMX.L.GOOGLE.COM.
66
+ ASPMX2.GOOGLEMAIL.COM.
67
+ ASPMX3.GOOGLEMAIL.COM.
68
+ RECORD
69
+ servers = find_servers :roles => :web
70
+ servers.each do |s|
71
+ mx_aux = %w[5 10 10 20 20 30 ]
72
+ aux_count = 0
73
+ zone = Zone.find(:first, :params => {:origin => "#{s}."})
74
+ mx_records.each do |rec|
75
+ r = Record.new(:record_type => 'MX', :zone_id => zone.id, :name => "#{s}." , :data => "#{rec}", :aux => mx_aux[aux_count])
76
+ r.save
77
+ aux_count =+ 1
78
+ end
79
+ recordOne = Record.new(:record_type => 'CNAME', :zone_id => zone.id, :name => 'mail', :data => "ghs.google.com.")
80
+ recordTwo = Record.new(:record_type => 'CNAME', :zone_id => zone.id, :name => 'docs', :data => "ghs.google.com.")
81
+ [recordOne, recordTwo].each {|r| r.save}
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+
88
+
89
+
90
+ namespace :host do
91
+
92
+ desc "Checks we have information to proceed with server operations"
93
+ task :config_check do
94
+ config_setup
95
+ "#{working_server}" rescue @parent.logger.log 0,"You need to specify a host to run the operation on. Use cap task -s h=yourhost"
96
+ @use_applications = [ ]
97
+ options["apps"].each do |app, settings|
98
+ @use_applications << app if settings["server"]==working_server
99
+ end
100
+ end
101
+
102
+
103
+ desc "Performs a local backup of the applications and databases on the server"
104
+ task :backup do
105
+ config_check
106
+ @use_applications.each do |app|
107
+ set :working_app, app
108
+ @parent.app.backup
109
+ end
110
+ end
111
+
112
+ desc "Backs up the local backup folder to remote Amazon S3 storage"
113
+ task :s3backup do
114
+ config_check
115
+ end
116
+
117
+
118
+
119
+ end
120
+
121
+ namespace :app do
122
+
123
+
124
+ task :config_check do
125
+ config_setup
126
+ databases rescue set(:databases, ["#{application}"])
127
+ end
128
+
129
+ task :needs_root do
130
+ config_check
131
+ puts "*** This operation needs root access - Please pass in a root password using -s root=password" if !defined? "#{root_pass}"
132
+ exit if !defined? "#{root_pass}"
133
+ end
134
+
135
+
136
+
137
+ # =============================================================================
138
+ # DEPLOYING APPLICATIONS
139
+ # =============================================================================
140
+
141
+ desc "Uses the specified repository to deploy an application. Also checks for correct versions of PHPWax and plugins."
142
+ task :deploy do
143
+ config_check
144
+ deploy_check
145
+ php_wax_deploy if defined? "#{phpwax}"
146
+ cms_deploy if defined? "#{cms}"
147
+ end
148
+
149
+ task :deploy_check do
150
+ fetch "repository" rescue abort "You have not specified a repository for this application"
151
+ git_deploy if repository.include? "git"
152
+ svn_deploy if repository.include? "svn"
153
+ end
154
+
155
+ task :git_deploy do
156
+ begin
157
+ run "ls #{deploy_to}/.git"
158
+ rescue
159
+ run "git init"
160
+ run "git remote add origin #{repository}"
161
+ end
162
+ run "git pull origin #{branch}"
163
+ end
164
+
165
+ task :svn_deploy do
166
+ run "svn export #{repository} #{deploy_to} --force"
167
+ end
168
+
169
+ task :cms_deploy do
170
+ begin
171
+ run "ls plugins/cms/.git"
172
+ rescue
173
+ run "mkdir -p plugins/cms"
174
+ run "cd plugins/cms && git init"
175
+ run "cd plugins/cms && git remote add origin git://github.com:phpwax/wildfire.git"
176
+ end
177
+ run "cd plugins/cms && git checkout #{cms}"
178
+ end
179
+
180
+ task :php_wax_deploy do
181
+ begin
182
+ run "ls wax/.git"
183
+ rescue
184
+ run "mkdir wax"
185
+ run "cd wax && git init"
186
+ run "cd wax && git remote add origin git://github.com/phpwax/phpwax.git"
187
+ run "cd wax && git pull origin master"
188
+ end
189
+ run "cd wax && git checkout #{phpwax}"
190
+ end
191
+
192
+ ####### ##############
193
+
194
+
195
+ # =============================================================================
196
+ # GENERAL ADMIN FOR APPLICATIONS
197
+ # =============================================================================
198
+
199
+ desc "Restarts the Apache Server."
200
+ task :restart do
201
+ config_check
202
+ needs_root
203
+ with_user("root", "#{root_pass}") do
204
+ run "/etc/rc.d/init.d/httpd restart"
205
+ end
206
+ end
207
+
208
+ task :clearcache do
209
+ run "rm -f tmp/cache/*"
210
+ end
211
+
212
+ task :clearlogs do
213
+ run "rm -f tmp/log/*"
214
+ end
215
+
216
+
217
+ # =============================================================================
218
+ # BACKING UP APPLICATIONS
219
+ # =============================================================================
220
+
221
+ desc "Starts the backup process by checking which type to perform then performs the necessary back ups."
222
+ task :backup do
223
+ config_check
224
+ needs_root
225
+ backup_check
226
+ end
227
+
228
+ task :backup_check do
229
+ if defined? "#{repository}"
230
+ if repository.include? "git"
231
+ git_mysql_backup
232
+ upload_only_backup
233
+ elsif repository.include? "svn"
234
+ standard_mysql_backup
235
+ upload_only_backup
236
+ end
237
+ else
238
+ puts "No repository for #{application}"
239
+ standard_mysql_backup
240
+ simple_fs_backup
241
+ end
242
+ end
243
+
244
+ task :simple_fs_backup do
245
+ with_user("root", "#{root_pass}") do
246
+ run "mkdir -p /backup/#{application}"
247
+ run "rsync -avzh /home/#{application}/ /backup/#{application}/"
248
+ end
249
+ end
250
+
251
+ task :upload_only_backup do
252
+ with_user("root", "#{root_pass}") do
253
+ run "mkdir -p /backup/#{application}"
254
+ run "rsync -avzh /home/#{application}/public/files/ /backup/#{application}/"
255
+ end
256
+ end
257
+
258
+ task :standard_mysql_backup do
259
+ run "mkdir -p public/files"
260
+ databases.each do |db|
261
+ run "mysqldump #{db} --skip-comments --add-drop-table -u#{user} -p#{password} > public/files/#{db}.sql";
262
+ end
263
+ upload_only_backup
264
+ end
265
+
266
+ task :git_mysql_backup do
267
+ transaction do
268
+ run "mkdir -p tmp/backup"
269
+ run "ln -s ../../.git/ tmp/backup/.git"
270
+ begin
271
+ run "cd tmp/backup && git branch db"
272
+ run "cd tmp/backup && git branch -d db"
273
+ rescue
274
+ end
275
+ run "cd tmp/backup && git symbolic-ref HEAD refs/heads/db"
276
+ run "cd tmp/backup && mv .git/index .git/index_old"
277
+ databases.each do |db|
278
+ run "cd tmp/backup && mysqldump #{db} --skip-comments --add-drop-table -u#{user} -p#{password} > #{db}.sql";
279
+ end
280
+ run "cd tmp/backup && git add ."
281
+ run "cd tmp/backup && git commit -m 'database update'" rescue ""
282
+ run "cd tmp/backup && git push origin db"
283
+ run "rm -Rf ./tmp/backup"
284
+ run "mv -f .git/index_old .git/index" rescue ""
285
+ run "git symbolic-ref HEAD refs/heads/#{branch}"
286
+ on_rollback do
287
+ run "rm -Rf ./tmp/backup"
288
+ run "mv -f .git/index_old .git/index" rescue ""
289
+ run "git symbolic-ref HEAD refs/heads/#{branch}"
290
+ end
291
+ end
292
+ end
293
+
294
+ # =============================================================================
295
+ # RESTORING BACKED-UP APPLICATIONS
296
+ # =============================================================================
297
+
298
+ desc "Restores a backed up application, database and other files."
299
+ task :restore do
300
+ if defined? repository
301
+ if repository.include? "git"
302
+ upload_only_restore
303
+ git_mysql_restore
304
+ elsif repository.include? "svn"
305
+ upload_only_restore
306
+ standard_mysql_restore
307
+ end
308
+ else
309
+ simple_fs_restore
310
+ standard_mysql_restore
311
+ end
312
+ end
313
+
314
+ task :upload_only_restore do
315
+ with_user("root", "#{root_pass}") do
316
+ run "rsync -avzh /backup/#{application}/ /home/#{application}/public/files/"
317
+ end
318
+ end
319
+
320
+ task :git_mysql_restore do
321
+ run "mkdir -p tmp/backup"
322
+ run "ln -s ../../ tmp/backup/.git"
323
+ run "cd tmp/backup && git symbolic-ref HEAD refs/heads/db"
324
+ run "cd tmp/backup && mv .git/index .git/index_old"
325
+ "#{databases}".each do |db|
326
+ run "cd tmp/backup && mysql #{db} -u#{user} -p#{password} < #{db}.sql"
327
+ end
328
+ run "rm -Rf ./tmp/backup"
329
+ run "mv -f .git/index_old .git/index" rescue ""
330
+ run "git symbolic-ref HEAD refs/heads/#{branch}"
331
+ end
332
+
333
+ desc "Just runs rSync back to the home directory"
334
+ task :simple_fs_restore do
335
+ with_user("root", "#{root_pass}") do
336
+ run "rsync -avzh /backup/#{application}/ /home/#{application}/"
337
+ end
338
+ end
339
+
340
+ task :standard_mysql_restore do
341
+ "#{databases}".each do |db|
342
+ run "cd tmp/backup && mysql #{db} -u#{user} -p#{password} < public/files/#{db}.sql"
343
+ end
344
+ end
345
+
346
+ # =============================================================================
347
+ # USER AND APPLICATION SETUP AND INITIALISATION
348
+ # =============================================================================
349
+
350
+ desc "General setup task which creates a new user on the host, sets up a mysql database and login, creates an apache vhost file and finally generates an ssh key for the user."
351
+ task :setup do
352
+ config_check
353
+ try_login
354
+ setup_mysql
355
+ vhost
356
+ ssh_key
357
+ end
358
+
359
+
360
+ task :setup_user do
361
+ needs_root
362
+ set :user_to_add, "#{user}"
363
+ set :passwd_to_add, "#{password}"
364
+ with_user("root", "#{root_pass}") do
365
+ run "useradd -p `openssl passwd #{passwd_to_add}` #{user_to_add}"
366
+ end
367
+ end
368
+
369
+ task :setup_mysql do
370
+ with_user("root", "#{root_pass}") do
371
+ "#{databases}".each do |db|
372
+ run "mysql -uroot -p#{root_pass} -e 'CREATE DATABASE #{db}'"
373
+ run "musql -uroot -p#{root_pass} -e 'GRANT ALL PRIVILEGES ON `#{db}` . * TO '#{user_to_add}'@'localhost' IDENTIFIED BY '#{passwd_to_add}';"
374
+ end
375
+ end
376
+
377
+ end
378
+
379
+ task :try_login do
380
+ config_check
381
+ begin
382
+ run "ls"
383
+ puts "Logged in ok"
384
+ rescue
385
+ print "==== The user does not yet exist. Would you like to create? [Y/N]"
386
+ line = STDIN.gets.upcase.strip
387
+ puts "*** Could not continue as the login does not exist" if line !="Y"
388
+ exit if line != "Y"
389
+ setup_user
390
+ end
391
+ end
392
+
393
+ desc "Creates or gets an ssh key for the application"
394
+ task :ssh_key do
395
+ config_check
396
+ begin
397
+ run "cat .ssh/id_rsa.pub"
398
+ rescue
399
+ run "ssh-keygen -t rsa -f .ssh/id_rsa -N ''"
400
+ run "cat .ssh/id_rsa.pub"
401
+ end
402
+ end
403
+
404
+ desc "Creates an Apache virtual host file"
405
+ task :vhost do
406
+ config_check
407
+ needs_root
408
+ with_user("root", "#{root_pass}") do
409
+ public_ip = ""
410
+ run "ifconfig eth0 | grep inet | awk '{print $2}' | sed 's/addr://'" do |_, _, public_ip| end
411
+ public_ip = public_ip.strip
412
+ f = File.open('templates/apache_vhost.erb')
413
+ contents = f.read
414
+ f.close
415
+ buffer = ERB.new(contents)
416
+ config = buffer.result(binding())
417
+ put config, "/etc/httpd/conf.d/#{application}-apache-vhost.conf"
418
+ end
419
+
420
+ end
421
+
422
+ # =============================================================================
423
+ # +MIGRATING+ APPLICATIONS
424
+ # =============================================================================
425
+
426
+ desc "Runs a backup of an application, copies to another server and then sets up on new server"
427
+ task :copy_site do
428
+ config_check
429
+ needs_root
430
+ backup
431
+ print "==== Which server would you like to copy #{application} to? [Full Domain Name] "
432
+ line = STDIN.gets.strip
433
+ begin
434
+ new_server = options["servers"][line]["domain"]
435
+ rescue
436
+ puts "*** Can't find that new server in the config"
437
+ exit
438
+ end
439
+ with_user("root", "#{root_pass}") do
440
+ run "rsync -avzh . -e ssh root@#{new_server}:/backup/#{application}/ --exclude 'tmp/*' --exclude '.git/*'"
441
+ end
442
+ options["apps"]["#{application}"]["server"] = line
443
+ config_write
444
+ try_login
445
+ restore
446
+ end
447
+
448
+ end
449
+
450
+
451
+ def get_ip(domain)
452
+ require 'socket'
453
+ t = TCPSocket.gethostbyname(domain)
454
+ t[3]
455
+ end
456
+
457
+ def with_user(new_user, new_pass, &block)
458
+ old_user, old_pass = user, password
459
+ set :user, new_user
460
+ set :password, new_pass
461
+ close_sessions
462
+ yield
463
+ set :user, old_user
464
+ set :password, old_pass
465
+ close_sessions
466
+ end
467
+ def close_sessions
468
+ sessions.values.each { |session| session.close }
469
+ sessions.clear
470
+ end
471
+
472
+
473
+
474
+
475
+
476
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oneblackbear-obbistrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Riley
@@ -43,7 +43,7 @@ extra_rdoc_files: []
43
43
 
44
44
  files:
45
45
  - README.txt
46
- - capfile
46
+ - obbistrano.rb
47
47
  has_rdoc: false
48
48
  homepage: http://github.com/oneblackbear/obbistrano
49
49
  post_install_message: