class Pvcglue::Db
Public Class Methods
configure_database_yml()
click to toggle source
# File lib/pvcglue/db.rb, line 112 def self.configure_database_yml Pvcglue.render_template('database.yml.erb', Pvcglue::Db.database_yml_file_name) end
database_yml_file_name()
click to toggle source
# File lib/pvcglue/db.rb, line 59 def self.database_yml_file_name File.join(Pvcglue::Capistrano.application_config_dir, 'database.yml') end
db_host_public()
click to toggle source
# File lib/pvcglue/db.rb, line 98 def self.db_host_public # Assume 1 pg server Pvcglue.cloud.minions_filtered('pg').values.first.public_ip end
file_helper(file_name)
click to toggle source
# File lib/pvcglue/db.rb, line 104 def self.file_helper(file_name) # TODO: make it more helpful ;) stage = Pvcglue.cloud.stage_name || "dev" file_name = "#{Pvcglue.configuration.application_name}_#{stage}_#{Time.now.strftime("%Y-%m-%d-%H%M")}.dump" unless file_name # "#{File.dirname(file_name)}/#{File.basename(file_name, '.*')}.dump" file_name end
local()
click to toggle source
# File lib/pvcglue/db.rb, line 77 def self.local @local ||= begin dev = local_info["development"] Db_Config.new(dev["host"], dev["port"], dev["database"], dev["username"], dev["password"], :local) end end
local_info()
click to toggle source
# File lib/pvcglue/db.rb, line 66 def self.local_info @local_info ||= begin template = Tilt::ERBTemplate.new('config/database.yml') output = template.render # puts output.inspect info = YAML::load(output) # puts info.inspect info end end
remote()
click to toggle source
# File lib/pvcglue/db.rb, line 84 def self.remote @remote ||= begin Pvcglue::Env.initialize_stage_env env = Pvcglue.cloud.stage_env Db_Config.new(db_host_public, env["DB_USER_POSTGRES_PORT"], env["DB_USER_POSTGRES_DATABASE"], env["DB_USER_POSTGRES_USERNAME"], env["DB_USER_POSTGRES_PASSWORD"], :remote ) end end
Public Instance Methods
config()
click to toggle source
# File lib/pvcglue/db.rb, line 7 def config Pvcglue::Db.configure_database_yml end
destroy_all()
click to toggle source
# File lib/pvcglue/db.rb, line 42 def destroy_all raise(Thor::Error, "Stage should not be set for this command.") unless Pvcglue.cloud.stage_name.nil? pg_destroy(self.class.local) end
destroy_prod?(db)
click to toggle source
# File lib/pvcglue/db.rb, line 122 def destroy_prod?(db) say("Are you *REALLY* sure you want to DESTROY the PRODUCTION database?") input = ask("Type 'destroy #{db.database.downcase}' if you are:") raise(Thor::Error, "Ain't gonna do it.") if input.downcase != "destroy #{db.database.downcase}" puts "ok, going through with the it... (I sure hope you know what you are doing, Keith!)" end
dump(file_name = nil)
click to toggle source
# File lib/pvcglue/db.rb, line 28 def dump(file_name = nil) raise(Thor::Error, "Stage should not be set for this command. (Use 'pull' for remote databases.)") unless Pvcglue.cloud.stage_name.nil? pg_dump(self.class.local, file_name, options[:fast]) end
info()
click to toggle source
# File lib/pvcglue/db.rb, line 49 def info if Pvcglue.cloud.stage_name pp self.class.remote else pp self.class.local end end
pg_destroy(dest)
click to toggle source
# File lib/pvcglue/db.rb, line 220 def pg_destroy(dest) sql = "\"select 'drop database '||datname||';' "\ "from pg_database "\ "where datistemplate=false and datname <> '#{dest.username}' "\ "and datname <> 'postgres'\"" # I had to use the double for loop because for whatever reason # calling ${line[0]} throws a bad substitution error # This is also why I escaped the string with a regex bash = "#!/bin/bash\n while read line; do "\ "s_esc=\"$(echo \"$line\" | sed 's/[^-A-Za-z0-9_]/\\ /g')\"; "\ "for word in $s_esc; do "\ "if [ $word = \"drop\" ]; then "\ "for word in $s_esc; do "\ "if [ $word != \"drop\" ] && [ $word != \"database\" ]; then "\ "echo \"$s_esc\"; "\ "dropdb \"$word\"\; "\ "fi "\ "done; "\ "break; "\ "fi "\ "done; "\ "done < dd.sql; " cmd = "psql #{dest.username} -c " cmd += sql cmd += " > dd.sql;" cmd += bash cmd += "rm dd.sql" puts cmd unless system({"PGPASSWORD" => dest.password}, cmd) puts "ERROR:" puts $?.inspect end end
pg_dump(db, file_name, fast)
click to toggle source
# File lib/pvcglue/db.rb, line 130 def pg_dump(db, file_name, fast) # TODO: Refactor into the db package file_name = self.class.file_helper(file_name) if db.kind == :remote minion = Pvcglue.cloud.minions_filtered('pg').values.first # Assume 1 pg server host = minion.public_ip port = Pvcglue.cloud.port_in_context(:shell) user = minion.remote_user_name end cmd = "pg_dump -Fc --no-acl --no-owner -h #{db.host} -p #{db.port}" cmd += " -U #{db.username}" if db.username if fast Pvcglue.cloud.exclude_tables.each do |table| cmd += " --exclude-table=#{table}" end end cmd += " #{db.database} -v -f #{file_name}" puts cmd cmd = " PGPASSWORD=#{db.password} #{cmd}" if db.kind == :remote unless Pvcglue.run_remote(host, port, user, cmd) puts "ERROR:" puts $?.inspect raise("Error: #{$?}") end cmd = %{scp -P #{port} #{user}@#{host}:#{file_name} #{file_name}} puts "Running `#{cmd}`" unless system cmd raise("Error: #{$?}") end else unless system(cmd) puts "ERROR:" puts $?.inspect raise("Error: #{$?}") end end end
pg_restore(db, file_name, fast = false)
click to toggle source
# File lib/pvcglue/db.rb, line 177 def pg_restore(db, file_name, fast = false) # TODO: Refactor into the db package Pvcglue.cloud.stage_name == 'production' && destroy_prod?(db) file_name = self.class.file_helper(file_name) if db.kind == :remote minion = Pvcglue.cloud.minions_filtered('pg').values.first host = minion.public_ip port = Pvcglue.cloud.port_in_context(:shell) user = minion.remote_user_name # cmd = %{scp -P #{port} #{file_name} #{user}@#{host}:#{file_name}} cmd = %{rsync -avhPe "ssh -p #{port}" --progress #{file_name} #{user}@#{host}:#{file_name}} unless system cmd raise("Error: #{$?}") end unless fast # Drop and recreate DB Pvcglue::Packages.apply('postgresql-app-stage-db-drop'.to_sym, :build, Pvcglue.cloud.minions_filtered('db')) Pvcglue::Packages.apply('postgresql-app-stage-conf'.to_sym, :build, Pvcglue.cloud.minions_filtered('db')) end end cmd = "pg_restore --verbose --clean --no-acl --no-owner -h #{db.host} -p #{db.port}" cmd += " -U #{db.username}" if db.username cmd += " -d #{db.database} #{file_name}" puts cmd if db.kind == :remote unless Pvcglue.run_remote(host, port, user, " PGPASSWORD=#{db.password} #{cmd}") puts "ERROR:" puts $?.inspect end else unless system(" PGPASSWORD=#{db.password} #{cmd}") raise("Error: #{$?}") end end end
pull(file_name = nil)
click to toggle source
# File lib/pvcglue/db.rb, line 21 def pull(file_name = nil) raise(Thor::Error, "Stage required.") if Pvcglue.cloud.stage_name.nil? pg_dump(self.class.remote, file_name, options[:fast]) end
push(file_name = nil)
click to toggle source
# File lib/pvcglue/db.rb, line 13 def push(file_name = nil) raise(Thor::Error, "Stage required.") if Pvcglue.cloud.stage_name.nil? pg_restore(self.class.remote, file_name, options[:fast]) end
restore(file_name = nil)
click to toggle source
# File lib/pvcglue/db.rb, line 35 def restore(file_name = nil) raise(Thor::Error, "Stage should not be set for this command. (Use 'push' for remote databases.)") unless Pvcglue.cloud.stage_name.nil? pg_restore(self.class.local, file_name) end