class RailsPwnerer::App::Database

Public Instance Methods

admin_database(app_name, instance_name, action = :create) click to toggle source

creates/drops the mysql database for the application

   # File lib/rails_pwnerer/app/db/mysql.rb
 9   def admin_database(app_name, instance_name, action = :create)
10     app_config = RailsPwnerer::Config[app_name, instance_name]
11     # exit and don't complain if the app is busted
12     return unless app_config and File.exists? app_config[:app_path]
13 
14     db_name, db_user, db_pass = app_config[:db_name], app_config[:db_user], app_config[:db_pass]
15     
16     with_temp_dir do
17       # put together the admin script
18       case action
19       when :create
20       sql_commands = <<ENDSQL
21         CREATE DATABASE #{db_name} DEFAULT CHARSET=utf8;
22         GRANT ALL ON #{db_name}.* TO '#{db_user}'@'localhost' IDENTIFIED BY '#{db_pass}' WITH GRANT OPTION;
23 ENDSQL
24       when :rekey
25       sql_commands = <<ENDSQL
26         GRANT ALL ON #{db_name}.* TO '#{db_user}'@'localhost' IDENTIFIED BY '#{db_pass}' WITH GRANT OPTION;
27 ENDSQL
28       
29       when :drop
30       sql_commands = <<ENDSQL
31         DROP DATABASE #{db_name};
32 ENDSQL
33       end
34       
35       # run it
36       File.open('admin_db.sql', 'w') { |f| f.write sql_commands }
37       dbroot_name = RailsPwnerer::Config[:host][:dbroot_name]
38       dbroot_pass = RailsPwnerer::Config[:host][:dbroot_pass]
39       dbpass_arg = dbroot_pass.empty? ? '' : "-p#{dbroot_pass}"
40       system "mysql -u#{dbroot_name} #{dbpass_arg} < admin_db.sql"
41       
42       # cleanup
43       File.delete('admin_db.sql')
44     end    
45   end
configure_rails(app_name, instance_name) click to toggle source

configures rails to use the database in the production environment

   # File lib/rails_pwnerer/app/db/mysql.rb
69 def configure_rails(app_name, instance_name)
70   app_config = RailsPwnerer::Config[app_name, instance_name]
71   db_name, db_user, db_pass = app_config[:db_name], app_config[:db_user], app_config[:db_pass]
72   
73   config_file = File.join app_config[:app_path], 'config', 'database.yml'
74   configuration = File.open(config_file, 'r') { |f| YAML.load f }
75   configuration['production'] ||= {}
76   if !configuration['production']['adapter'] or
77      !(/mysql/ =~ configuration['production']['adapter'])
78     configuration['production']['adapter'] = 'mysql2'
79   end
80   configuration['production']['encoding'] ||= 'utf8'
81   configuration['production'].merge! 'database' => db_name, 'username' => db_user, 'password' => db_pass
82   configuration['production'].merge! mysql_host_info()    
83   File.open(config_file, 'w') { |f| YAML.dump(configuration, f) }
84   
85   # bonus: lock down the database so only the right user can access it
86   pwnerer_user = app_config[:pwnerer_user]
87   File.chmod(0600, config_file)
88   File.chown(uid_for_username(pwnerer_user), gid_for_username(pwnerer_user), config_file)
89 end
control_all(action) click to toggle source
    # File lib/rails_pwnerer/app/db/mysql.rb
178 def control_all(action)
179   case action
180   when :start
181     control_boot_script('mysql', :start)
182   when :stop
183     control_boot_script('mysql', :stop)
184   end
185 end
dump_database(app_name, instance_name) click to toggle source

creates a database dump in the backup area

    # File lib/rails_pwnerer/app/db/mysql.rb
104 def dump_database(app_name, instance_name)
105   app_config = RailsPwnerer::Config[app_name, instance_name]
106   db_name, db_user, db_pass = app_config[:db_name], app_config[:db_user], app_config[:db_pass]
107 
108   pwnerer_user = app_config[:pwnerer_user]
109   pwnerer_uid = uid_for_username(pwnerer_user)
110   pwnerer_gid = gid_for_username(pwnerer_user)
111   
112   timestamp = Time.now.strftime '%Y%m%d%H%M%S'
113   dump_file = "db/#{app_name}.#{instance_name}_#{timestamp}.sql"
114   Dir.chdir app_config[:backup_path] do
115     system("mysqldump --add-drop-database --add-drop-table" +
116            " --skip-extended-insert --single-transaction" +
117            " -u#{db_user} -p#{db_pass} #{db_name} > #{dump_file}")
118     # lockdown the file
119     File.chmod(0400, dump_file)
120     File.chown(pwnerer_uid, pwnerer_gid, dump_file)
121   end
122 end
load_database(app_name, instance_name) click to toggle source

loads the latest database dump from the backup area

    # File lib/rails_pwnerer/app/db/mysql.rb
125 def load_database(app_name, instance_name)
126   app_config = RailsPwnerer::Config[app_name, instance_name]
127   db_name, db_user, db_pass = app_config[:db_name], app_config[:db_user], app_config[:db_pass]
128   
129   Dir.chdir app_config[:backup_path] do
130     # find the latest dump and load it in
131     dump_file = Dir.glob("db/#{app_name}.#{instance_name}_*").max
132     unless dump_file
133       dump_file = Dir.glob("db/#{app_name}.*").max
134     end
135     Kernel.system "mysql -u#{db_user} -p#{db_pass} #{db_name} < #{dump_file}"
136   end
137 end
manage(app_name, instance_name, action) click to toggle source

backs up or restores the database

    # File lib/rails_pwnerer/app/db/mysql.rb
158 def manage(app_name, instance_name, action)
159   case action
160   when :checkpoint
161     dump_database app_name, instance_name
162   when :rollback
163     admin_database app_name, instance_name, :drop
164     admin_database app_name, instance_name, :create
165     load_database app_name, instance_name
166     configure_rails app_name, instance_name
167     migrate_database app_name, instance_name
168   when :rekey
169     admin_database app_name, instance_name, :rekey
170     configure_rails app_name, instance_name
171   when :db_reset
172     admin_database app_name, instance_name, :drop
173     admin_database app_name, instance_name, :create
174     migrate_database app_name, instance_name
175   end
176 end
migrate_database(app_name, instance_name) click to toggle source

migrates the database to the latest schema version

    # File lib/rails_pwnerer/app/db/mysql.rb
 92 def migrate_database(app_name, instance_name)
 93   Dir.chdir RailsPwnerer::Config[app_name, instance_name][:app_path] do
 94     # now migrate the database
 95     if File.exist?('Gemfile')
 96       Kernel.system 'bundle exec rake db:migrate RAILS_ENV=production'
 97     else
 98       Kernel.system 'rake db:migrate RAILS_ENV=production'
 99     end
100   end
101 end
mysql_host_info() click to toggle source
   # File lib/rails_pwnerer/app/db/mysql.rb
47 def mysql_host_info()
48   # try UNIX sockets first, for best performance
49   begin
50     socket_line = `mysql_config --socket`
51     socket_line.strip!
52     return {'socket' => socket_line} unless socket_line.empty?
53   rescue
54   end
55     
56   # oh well, TCP will have to suffice
57   begin
58     port_line = `mysql_config --port`
59     port = port_line.strip.to_i
60     return {'host' => 'localhost', 'port' => port} unless port == 0    
61   rescue
62   end
63   
64   # giving up, the mysql gem will have to figure it out
65   return {}
66 end
remove(app_name, instance_name) click to toggle source
    # File lib/rails_pwnerer/app/db/mysql.rb
152 def remove(app_name, instance_name)
153   control_boot_script('mysql', :start)
154   admin_database app_name, instance_name, :drop    
155 end
setup(app_name, instance_name) click to toggle source
    # File lib/rails_pwnerer/app/db/mysql.rb
139 def setup(app_name, instance_name)
140   control_boot_script('mysql', :start)
141   admin_database app_name, instance_name, :create
142   configure_rails app_name, instance_name
143   migrate_database app_name, instance_name
144 end
update(app_name, instance_name) click to toggle source
    # File lib/rails_pwnerer/app/db/mysql.rb
146 def update(app_name, instance_name)
147   control_boot_script('mysql', :start)
148   configure_rails app_name, instance_name
149   migrate_database app_name, instance_name
150 end