VladTheEnterprising 0.1.8 → 0.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of VladTheEnterprising might be problematic. Click here for more details.

data.tar.gz.sig CHANGED
Binary file
data/README.txt CHANGED
@@ -95,8 +95,11 @@ Currently consists of the following:
95
95
 
96
96
  Migrations and Versioning
97
97
  =========================
98
-
99
- As of 1.8, schema migrations and versioning are supported. By
98
+
99
+ As of 0.2.0, schema creations are supported. The ddl is expected to
100
+ be in: db/schemas/[SchemaName].sql
101
+
102
+ As of 0.1.8, schema migrations and versioning are supported. By
100
103
  default the app will look under db/migrations/[schema name]/[version
101
104
  no]-[text]/[upgrade.sql|rollback.sql]
102
105
 
@@ -139,6 +142,7 @@ Currently consists of the following:
139
142
  being that there's ssh and the mysql client available on the
140
143
  db_master.
141
144
 
145
+
142
146
  * The Xen Master
143
147
 
144
148
  Beginnings of a series of tasks for autmating the creation and
data/Rakefile CHANGED
@@ -8,6 +8,8 @@ require './lib/nytd/dbslayer'
8
8
 
9
9
  require './lib/vlad/enterprising.rb'
10
10
  require './lib/nytd/builder'
11
+ require './lib/nytd/util'
12
+ require './lib/nytd/cnx_mysql'
11
13
  Hoe.new('VladTheEnterprising', VLAD_ENTERPRISING_VERSION) do |p|
12
14
  p.rubyforge_name = 'vlad_the_enterprising'
13
15
  p.author = 'Michael L. Welles'
@@ -21,4 +23,11 @@ Hoe.new('VladTheEnterprising', VLAD_ENTERPRISING_VERSION) do |p|
21
23
  end
22
24
  Vlad.load()
23
25
 
26
+ if defined?( target_environment ) and ( target_environment == :production )
27
+ unless ENV['FORCE']
28
+ certain = ask('Are you sure you want to target production? [Y/n]')
29
+ raise "Oops, good thing we checked. Aborting." unless certain == "Y"
30
+ end
31
+ end
32
+
24
33
  # vim: syntax=Ruby
@@ -20,7 +20,7 @@ namespace :vlad do
20
20
  puts "#{target_host} mysql user open file ulimit: #{n}"
21
21
  end
22
22
 
23
-
23
+
24
24
  desc "Bootstraps mysql slave candiates, installs mysql, syncs them to the master, and starts them."
25
25
  task :bootstrap_new_slaves => [
26
26
  :assert_production_target_subset,
@@ -41,9 +41,9 @@ namespace :vlad do
41
41
  :check_slaves,]
42
42
 
43
43
 
44
- task :ask_root_password do
44
+ task :ask_root_password do
45
45
  mysql_root_password
46
- end
46
+ end
47
47
 
48
48
  task :ask_replication_password do
49
49
  mysql_replication_password
@@ -109,10 +109,12 @@ namespace :vlad do
109
109
  slaves = Rake::RemoteTask.hosts_for(:new_slave)
110
110
  slaves.each do |slave|
111
111
  name = slave.gsub(/\..*$/,"").gsub(/-/, "")
112
- mysql_query "grant all privileges on *.* to '#{name}_dump'@'#{slave}' identified by '#{mysql_replication_password}'", "", :u => "root", :p => mysql_root_password
112
+ mysql_query :sql => "grant all privileges on *.* to '#{name}_dump'@'#{slave}' identified by '#{mysql_replication_password}'",
113
+ :u => "root", :p => mysql_root_password
113
114
  ip = Resolv.getaddress(slave)
114
115
  if ip
115
- mysql_query "grant all privileges on *.* to '#{name}_dump'@'#{ip}' identified by '#{mysql_replication_password}'", "", :u => "root", :p => mysql_root_password
116
+ mysql_query :sql => "grant all privileges on *.* to '#{name}_dump'@'#{ip}' identified by '#{mysql_replication_password}'",
117
+ :u => "root", :p => mysql_root_password
116
118
  end
117
119
  end
118
120
  end
@@ -121,10 +123,12 @@ namespace :vlad do
121
123
  slaves = Rake::RemoteTask.hosts_for(:new_slave)
122
124
  slaves.each do |slave|
123
125
  name = slave.gsub(/\..*$/,"").gsub(/-/, "")
124
- mysql_query "grant replication slave, super, reload on *.* to '#{name}_repl'@'#{slave}' identified by '#{mysql_replication_password}'", "", :u => "root", :p => mysql_root_password
126
+ mysql_query :sql => "grant replication slave, super, reload on *.* to '#{name}_repl'@'#{slave}' identified by '#{mysql_replication_password}'",
127
+ :u => "root", :p => mysql_root_password
125
128
  ip = Resolv.getaddress(slave)
126
129
  if ip
127
- mysql_query "grant replication slave, super, reload on *.* to '#{name}_repl'@'#{ip}' identified by '#{mysql_replication_password}'", "", :u => "root", :p => mysql_root_password
130
+ mysql_query :sql => "grant replication slave, super, reload on *.* to '#{name}_repl'@'#{ip}' identified by '#{mysql_replication_password}'",
131
+ :u => "root", :p => mysql_root_password
128
132
  end
129
133
  end
130
134
  end
@@ -133,8 +137,10 @@ namespace :vlad do
133
137
  slaves = Rake::RemoteTask.hosts_for(:new_slave)
134
138
  slaves.each do |slave|
135
139
  name = slave.gsub(/\..*$/,"").gsub(/-/, "")
136
- mysql_query "REVOKE replication slave, super, reload FROM #{name}_repl", "", :u => "root", :p => mysql_root_password, :force => true
137
- mysql_query "drop user #{name}_repl", "", :u => "root", :p => mysql_root_password, :force => true
140
+ mysql_query :sql => "REVOKE replication slave, super, reload FROM #{name}_repl",
141
+ :u => "root", :p => mysql_root_password, :force => true
142
+ mysql_query :sql => "drop user #{name}_repl",
143
+ :u => "root", :p => mysql_root_password, :force => true
138
144
  end
139
145
  end
140
146
 
@@ -144,8 +150,10 @@ namespace :vlad do
144
150
  slaves = Rake::RemoteTask.hosts_for(:new_slave)
145
151
  slaves.each do |slave|
146
152
  name = slave.gsub(/\..*$/,"").gsub(/-/, "")
147
- mysql_query "REVOKE ALL PRIVILEGES, GRANT OPTION FROM #{name}_dump", "", :u => "root", :p => mysql_root_password, :force => true
148
- mysql_query "drop user #{name}_dump", "", :u => "root", :p => mysql_root_password, :force => true
153
+ mysql_query :sql => "REVOKE ALL PRIVILEGES, GRANT OPTION FROM #{name}_dump",
154
+ :u => "root", :p => mysql_root_password, :force => true
155
+ mysql_query :sql => "drop user #{name}_dump",
156
+ :u => "root", :p => mysql_root_password, :force => true
149
157
  end
150
158
  end
151
159
 
@@ -240,9 +248,11 @@ namespace :vlad do
240
248
 
241
249
  remote_task :start_new_slaves, :roles => :new_slave do
242
250
  begin
243
- mysql_query "flush privileges; slave start;", "", :u => "root"
251
+ mysql_query :sql => "flush privileges; slave start;",
252
+ :u => "root"
244
253
  rescue
245
- mysql_query "flush privileges; slave start;", "", :u => "root", :p => mysql_root_password
254
+ mysql_query "flush privileges; slave start;",
255
+ :u => "root", :p => mysql_root_password
246
256
  end
247
257
  end
248
258
 
@@ -259,12 +269,13 @@ namespace :vlad do
259
269
  datfile = dumpfile.sub(/\.gz$/,"").sub(/-/, "-#{database}-")
260
270
  dumpfile = datfile + ".gz"
261
271
  run "mkdir -p `dirname #{datfile}`; exit 0"
262
- run "#{mysqldump} --single-transaction -uroot -p'#{mysql_root_password}' #{db_arg} > #{datfile}"
272
+ run "#{mysqldump} --routines --single-transaction -uroot -p'#{mysql_root_password}' #{db_arg} > #{datfile}"
263
273
  `mkdir -p \`dirname #{datfile}\``
264
274
  run "nice gzip #{datfile}"
265
275
  cmd="ssh #{target_host} cat #{dumpfile} > #{dumpfile}"
266
276
  `#{cmd}`
267
- run "if [ -e #{dumpfile} ]; then rm #{dumpfile}; else exit 1; fi"
277
+ run "if [ -e #{dumpfile} ]; then rm #{dumpfile}; else exit 1; fi"
278
+ FileUtils.ln_sf(File.basename(dumpfile), "dumps/#{ENV['DATABASE']}-latest.dat.gz")
268
279
  puts "Done: #{dumpfile}"
269
280
  end
270
281
  task :dump => [:ask_root_password]
@@ -350,17 +361,21 @@ namespace :vlad do
350
361
 
351
362
  desc "stops replication on all slaves"
352
363
  remote_task :stop_slaves, :roles => [:db_slave, :new_slave] do
353
- mysql_query "slave stop;", "", :u => "root", :p => mysql_root_password
364
+ mysql_query :sql => "slave stop;",
365
+ :u => "root", :p => mysql_root_password
354
366
  end
355
367
 
356
368
  desc "starts replication on all slaves"
357
369
  remote_task :start_slaves, :roles => [:db_slave, :new_slave] do
358
- mysql_query "flush privileges; slave start;", "", :u => "root", :p => mysql_root_password
370
+ mysql_query :sql => "slave start;",
371
+ :u => "root", :p => mysql_root_password
359
372
  end
373
+
360
374
  desc "shows available databases"
361
375
  remote_task :show_all_databases, :roles => :db_master do
362
376
  puts "#{target_host}"
363
- mysql_query "SHOW DATABASES;", "", :u => "root", :p => mysql_root_password
377
+ mysql_query :sql => "SHOW DATABASES;",
378
+ :u => "root", :p => mysql_root_password
364
379
  end
365
380
  task :show_all_databases => [:ask_root_password]
366
381
 
@@ -383,20 +398,30 @@ namespace :vlad do
383
398
  desc "Executes query specified in QUERY='' argument on database specified in the DATABASE='' argument on the :db_master for the target environment and prints the results"
384
399
  remote_task :query, :roles => :db_master do
385
400
  raise "Please specify what QUERY to run against what database, i.e. QUERY='select foo from bar' DATABASE='Movies' TARGET='staging'" unless ENV['QUERY']
386
- puts mysql_query(ENV['QUERY'],ENV['DATABASE'], :u => 'root', :p => mysql_root_password )
401
+ puts mysql_query(:sql => ENV['QUERY'],
402
+ :db => ENV['DATABASE'],
403
+ :u => 'root', :p => mysql_root_password )
387
404
  end
388
405
 
389
406
  desc "Executes query specified in QUERY='' argument on database specified in the DATABASE='' argument on all the slaves for the target environment and prints the results"
390
407
  remote_task :query_slaves, :roles => :db_slave do
391
408
  raise "Please specify what QUERY to run against what database, i.e. QUERY='select foo from bar' DATABASE='Movies' TARGET='staging'" unless ENV['QUERY']
392
- puts "#{target_host}: " + mysql_query(ENV['QUERY'],ENV['DATABASE'], :u => 'root', :p => mysql_root_password ).gsub("\n", "*****")
409
+ puts "#{target_host}: " + mysql_query( :sql => ENV['QUERY'], :db => ENV['DATABASE'], :u => 'root', :p => mysql_root_password ).gsub("\n", "*****")
393
410
  end
394
411
 
412
+ remote_task :install_slave_crontab, :roles => :db_slave do
413
+ file = "files/mysql/crontabs/db_slave.crontab"
414
+ if File.exist?(file)
415
+ scp file, ".crontab"
416
+ run "crontab .crontab"
417
+ end
418
+ end
419
+
395
420
  remote_task :schema_info, :roles => :db_master do
396
421
  databases.select{ |db| db == "mysql" ? false : true }.each do |database|
397
422
  begin
398
- output = mysql_query("select version from schema_info limit 1",
399
- database,
423
+ output = mysql_query(:sql => "select version from schema_info limit 1",
424
+ :db => database,
400
425
  :u => 'root',
401
426
  :p => mysql_root_password)
402
427
 
@@ -409,7 +434,38 @@ namespace :vlad do
409
434
  end
410
435
  end
411
436
  task :schema_info => [:ask_root_password]
412
-
437
+
438
+ desc "Creates a database specified by DATABASE argument, using schema defined in db/schemas/[DATABASE].sql"
439
+ remote_task :create_database, :roles => :db_master do
440
+ database = ENV['DATABASE']
441
+ sql = File.read("db/schemas/#{database}.sql")
442
+ src = Tempfile.new("#{database}-create").path
443
+ create = "CREATE DATABASE IF NOT EXISTS #{database};\n"
444
+ File.open(src, "w") do |f|
445
+ f.write(sql)
446
+ if Rake.application.options.trace
447
+ puts create
448
+ puts sql
449
+ end
450
+ end
451
+ mysql_query( :sql => create, :u => 'root', :p => mysql_root_password)
452
+ scp src, src
453
+ mysql_query( :sql => "source #{src};",
454
+ :db => database,
455
+ :u => 'root',
456
+ :p => mysql_root_password)
457
+ end
458
+ task :create_database => [:assert_single_master]
459
+
460
+ remote_task :drop_database, :roles => :db_master do
461
+ database = ENV['DATABASE']
462
+ drop = "DROP DATABASE IF EXISTS #{database}"
463
+ mysql_query( :sql => drop,
464
+ :u => 'root',
465
+ :p => mysql_root_password)
466
+ end
467
+ task :drop_database => [:assert_single_master]
468
+
413
469
  desc "Runs db migrations for current TARGET can be controlled with better granuarity with DATABASE and VERSION arguments"
414
470
  remote_task :migrate, :roles => :db_master do
415
471
  assert_database_if_version_given()
@@ -420,17 +476,18 @@ namespace :vlad do
420
476
  targets.each do |database|
421
477
  database_dir = File.join(migration_dir, database)
422
478
  begin
423
- output = mysql_query("select version from schema_info limit 1",
424
- database,
479
+ output = mysql_query(:sql => "select version from schema_info limit 1",
480
+ :db => database,
425
481
  :u => 'root',
426
482
  :p => mysql_root_password)
427
- current_version = output.split(/\n/)[1].to_i
483
+ puts output if Rake.application.options.trace
484
+ current_version = output.split(/\n/)[1].to_i
428
485
  rescue
429
486
  current_version = 0
430
487
  end
431
488
  migrations = { }
432
489
  dirs = Dir.new(database_dir).entries.select{|d| d.match(/^\d+/)}
433
- dirs.each { |dir| migrations[dir.sub(/[^\d]*$/, "")] = dir }
490
+ dirs.each { |dir| migrations[dir.sub(/[^\d].*$/, "")] = dir }
434
491
  target_version = ENV['VERSION'].to_i if ENV['VERSION']
435
492
  target_version ||= migrations.keys.sort{|a,b| a.to_i <=> b.to_i }.last.to_i rescue 0
436
493
  case
@@ -450,18 +507,18 @@ namespace :vlad do
450
507
  have_migrations = lambda{ false }
451
508
  puts "#{database} already at version #{target_version} on #{target_host}"
452
509
  end
453
-
510
+ sql = "CREATE TABLE IF NOT EXISTS schema_info ( version INT default 0 );\n"
511
+ mysql_query(:sql => sql,
512
+ :db => database,
513
+ :u => 'root', :p => mysql_root_password)
454
514
  while have_migrations.call() do
455
515
  next_version = iterator.call(current_version)
456
516
  migration_file = next_file.call(current_version)
457
517
  if migration_file && File.exist?(migration_file)
458
- sql = "start transaction;\n"
459
- sql << "CREATE TABLE IF NOT EXISTS schema_info ( version INT default 0 );\n"
460
- sql << File.read(migration_file)
518
+ sql = File.read(migration_file)
461
519
  sql << "\n"
462
520
  sql << "update schema_info set version = #{next_version};\n"
463
- sql << "commit;"
464
- src = "/tmp/#{database}-version-#{File.basename(File.dirname(migration_file))}-#{File.basename(migration_file)}"
521
+ src = Tempfile.new("#{database}-version-#{File.basename(File.dirname(migration_file))}-#{File.basename(migration_file)}").path
465
522
  File.open(src, "w"){ |f| f.write(sql) }
466
523
  scp src, src
467
524
  if Rake.application.options.trace
@@ -469,7 +526,10 @@ namespace :vlad do
469
526
  puts sql
470
527
  puts "============================================\n"
471
528
  end
472
- mysql_query("source #{src};", database, :u => 'root', :p => mysql_root_password)
529
+ mysql_query(:source => src,
530
+ :db => database,
531
+ :u => 'root',
532
+ :p => mysql_root_password)
473
533
  puts "Executed: #{migration_file} on #{target_host}"
474
534
  end
475
535
  current_version = next_version
@@ -478,19 +538,31 @@ namespace :vlad do
478
538
  end
479
539
  end
480
540
  task :migrate => [:ask_root_password, :assert_single_master]
481
-
541
+
542
+ desc "restores the latest dump available for given DATABASE to specified TARGET"
543
+ task :restore_latest => [:set_dumpfile, :restore]
544
+
545
+ task :set_dumpfile do
546
+ ENV["DUMPFILE"] = "dumps/#{ENV['DATABASE']}-latest.dat.gz"
547
+ end
548
+
482
549
  desc "restores a dump to current db_master from file set in mysql_dumpfile or in a DUMPFILE argument"
483
550
  remote_task :restore, :roles => :db_master do
551
+ dump ||= "dumps/#{ENV['DATABASE']}-latest.dat.gz"
484
552
  dump = ENV["DUMPFILE"] || dump
485
- raise "Please specify a valid dumpfile to restore via :mysql_dumpfile in the config or use the DUMPFILE argument!" unless File.exist?(dump)
553
+ raise "Can't find DUMPFILE '#{dump}' create specify a valid dumpfile to restore via the DUMPFILE argument!" unless File.exist?(dump)
486
554
  scp dump, dump
487
555
  p = ""
488
556
  unless mysql_root_password.nil? or mysql_root_password == ""
489
557
  p = "-p'#{mysql_root_password}' "
490
558
  end
491
559
  if ENV['DATABASE']
492
- mysql_query "DROP DATABASE IF EXISTS #{ENV['DATABASE']}", "", :u => 'root', :p => mysql_root_password
493
- mysql_query "CREATE DATABASE IF NOT EXISTS #{ENV['DATABASE']}", "", :u => 'root', :p => mysql_root_password
560
+ mysql_query :sql => "DROP DATABASE IF EXISTS #{ENV['DATABASE']}",
561
+ :u => 'root',
562
+ :p => mysql_root_password
563
+ mysql_query :sql => "CREATE DATABASE IF NOT EXISTS #{ENV['DATABASE']}",
564
+ :u => 'root',
565
+ :p => mysql_root_password
494
566
  end
495
567
  run "cat #{dump} | gunzip - | #{mysql_path_bin}/mysql -uroot #{p} #{ENV['DATABASE']}"
496
568
  end
@@ -578,7 +650,7 @@ def mysql_replication_password
578
650
  end
579
651
 
580
652
  class Rake::RemoteTask
581
- def mysql_query( sql, database="", options = {})
653
+ def mysql_query( options = {} )
582
654
  if options[:force]
583
655
  force_enabled = true
584
656
  options[:force] = nil
@@ -586,19 +658,35 @@ class Rake::RemoteTask
586
658
  if options[:p] == ""
587
659
  options[:p] = nil
588
660
  end
661
+ if options[:sql]
662
+ f=Tempfile.new("sql")
663
+ File.open(f.path, "w"){ |file| file.write(options[:sql])}
664
+ scp f.path, f.path + ".sql"
665
+ options[:source] = f.path + ".sql"
666
+ if Rake.application.options.trace
667
+ puts "#{options[:source]}: #{options[:sql]}"
668
+ end
669
+ end
670
+ database = options[:db]
589
671
  args = options.keys.collect do |key|
590
672
  case key
591
673
  when :p :
592
- if options[key] && options[key] != ""
593
- "-#{key}'#{options[key]}'"
594
- end
674
+ if options[key] && options[key] != ""
675
+ "-#{key}'#{options[key]}'"
676
+ end
595
677
  when :force :
596
- ""
678
+ ""
679
+ when :db :
680
+ ""
681
+ when :sql :
682
+ ""
683
+ when :source :
684
+ "-e 'source #{options[:source]};'"
597
685
  else
598
686
  "-#{key}'#{options[key]}'"
599
687
  end
600
688
  end.join " "
601
- command = "echo \"#{sql}\" | #{mysql} #{args} #{database}"
689
+ command = "#{mysql} #{args} #{database}"
602
690
  command << "; exit 0" if force_enabled
603
691
  run command
604
692
  end
@@ -4,7 +4,7 @@ require 'vlad/environmentalist'
4
4
  require 'vlad/xen_master'
5
5
  require 'vlad/dba'
6
6
  require 'vlad/webmaster/apache'
7
- VLAD_ENTERPRISING_VERSION = '0.1.8' unless defined? VLAD_ENTERPRISING_VERSION
7
+ VLAD_ENTERPRISING_VERSION = '0.2' unless defined? VLAD_ENTERPRISING_VERSION
8
8
 
9
9
 
10
10
  # rsync the given files to <tt>target_host</tt>.
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: VladTheEnterprising
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.8
7
- date: 2007-11-02 00:00:00 -04:00
6
+ version: "0.2"
7
+ date: 2008-01-02 00:00:00 -05:00
8
8
  summary: Adds 'enterprisey' features to Vlad The Deployer
9
9
  require_paths:
10
10
  - lib
metadata.gz.sig CHANGED
Binary file