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