|
require "fileutils"
|
|
|
|
namespace :db do
|
|
desc <<-END_DESC
|
|
Make a dump of your database
|
|
|
|
Foreman will make a dump of your database at the provided location, or it will put it in #{File.expand_path('../../db', __dir__)} if no destination file is provided.
|
|
A valid config/database.yml file with the database details is needed to perform this operation.
|
|
|
|
Available conditions:
|
|
* destination => path to dump output file (defaults to #{File.expand_path('../../db', __dir__)}/foreman.EPOCH.sql)
|
|
* tables => optional comma separated list of tables (you can use regex to match multiple)
|
|
Specifies the list of tables to include in the dump.
|
|
This option works for postgres and mysql only.
|
|
Example:
|
|
rake db:dump destination=/mydir/dumps/foreman.sql RAILS_ENV=production # puts production dump in /mydir/dumps/foreman.sql
|
|
rake db:dump tables="hostgro.*"# will match ["hostgroup_classes", "hostgroups"]
|
|
|
|
END_DESC
|
|
|
|
task :dump => :environment do
|
|
config = Rails.configuration.database_configuration[Rails.env]
|
|
backup_dir = File.expand_path('../../db', __dir__)
|
|
backup_name = ENV['destination'] || File.join(backup_dir, "foreman.#{Time.now.to_i}")
|
|
unless ENV["destination"].present?
|
|
if config["adapter"] == "sqlite3"
|
|
backup_name << '.sqlite3'
|
|
else
|
|
backup_name << '.sql'
|
|
end
|
|
end
|
|
|
|
if ENV['tables'].present?
|
|
tables = get_matched_tables(ENV['tables'].split(","))
|
|
if tables.blank?
|
|
puts "No tables matching your pattern. '#{ENV['tables']}'."
|
|
exit(0)
|
|
else
|
|
puts "Generating dump for the following tables -> #{tables.inspect}"
|
|
end
|
|
else
|
|
tables = []
|
|
end
|
|
puts "Your backup is going to be created in: #{backup_name}"
|
|
case config['adapter']
|
|
when 'mysql', 'mysql2'
|
|
mysql_dump(backup_name, config, tables)
|
|
when 'postgresql'
|
|
postgres_dump(backup_name, config, tables)
|
|
when 'sqlite3'
|
|
sqlite_dump(backup_name, config)
|
|
else
|
|
puts 'Your database is not supported by Foreman.' and exit(1)
|
|
end
|
|
|
|
puts "Completed."
|
|
end
|
|
|
|
def mysql_dump(name, config, tables = [])
|
|
cmd = "mysqldump --opt #{config['database']} -u #{config['username']} "
|
|
cmd += " -p#{config['password']} " if config['password'].present?
|
|
cmd += " -h #{config['host']} " if config['host'].present?
|
|
cmd += " -P #{config['port']} " if config['port'].present?
|
|
cmd += " #{tables.join(' ')} " if tables.present?
|
|
cmd += " > #{name}"
|
|
system(cmd)
|
|
end
|
|
|
|
def postgres_dump(name, config, tables = [])
|
|
cmd = "pg_dump -Fc #{config['database']} -U #{config['username']} "
|
|
cmd += " -h #{config['host']} " if config['host'].present?
|
|
cmd += " -p #{config['port']} " if config['port'].present?
|
|
cmd += " " + (tables.map {|t| "-t #{t}"}).join(" ") + " " if tables.present?
|
|
cmd += " > #{name}"
|
|
system({'PGPASSWORD' => config['password']}, cmd)
|
|
end
|
|
|
|
def sqlite_dump(name, config)
|
|
FileUtils.cp config['database'], name
|
|
end
|
|
|
|
def get_matched_tables(input_table_names)
|
|
existing_tables = ActiveRecord::Base.connection.tables.sort
|
|
input_table_names.map do |table_name|
|
|
table_name.strip!
|
|
if existing_tables.include? table_name
|
|
table_name
|
|
else
|
|
existing_tables.grep(/#{table_name}/)
|
|
end
|
|
end.flatten
|
|
end
|
|
|
|
desc <<-END_DESC
|
|
Import a database dump
|
|
|
|
Foreman will import a database from the provided location.
|
|
A valid config/database.yml file with the database details is needed to perform this operation.
|
|
|
|
Available conditions:
|
|
* file => database dump file path
|
|
|
|
Example:
|
|
rake db:import_dump file=/mydir/dumps/foreman.db RAILS_ENV=production # imports /mydir/dumps/foreman.db as the production db
|
|
END_DESC
|
|
|
|
task :import_dump => :environment do
|
|
unless ENV['file']
|
|
puts "Run this task with a file argument with the location of your db dump,
|
|
'rake db:import_dump file=DBDUMPLOCATION" and return
|
|
end
|
|
config = Rails.configuration.database_configuration[Rails.env]
|
|
|
|
puts "Your backup is going to be imported from: #{ENV['file']}"
|
|
puts "You can backup the old database '#{config['database']}' by running:"
|
|
puts " - foreman-rake db:dump destination=/mydir/dumps/foreman.sql RAILS_ENV=#{Rails.env}"
|
|
puts "This task will destroy your old database tables! Are you sure you want to continue? [y/N]"
|
|
input = STDIN.gets.chomp
|
|
abort("Bye!") unless input.downcase == "y"
|
|
case config['adapter']
|
|
when 'mysql', 'mysql2'
|
|
mysql_import(ENV['file'], config)
|
|
when 'postgresql'
|
|
postgres_import(ENV['file'], config)
|
|
when 'sqlite3'
|
|
sqlite_import(ENV['file'], config)
|
|
else
|
|
puts 'Your database dump cannot be imported by Foreman.' and exit(1)
|
|
end
|
|
|
|
puts "Completed."
|
|
end
|
|
|
|
def mysql_import(file, config)
|
|
cmd = "mysql #{config['database']} -u #{config['username']} "
|
|
cmd += " -p#{config['password']} " if config['password'].present?
|
|
cmd += " -h #{config['host']} " if config['host'].present?
|
|
cmd += " -P #{config['port']} " if config['port'].present?
|
|
cmd += " < #{file}"
|
|
system(cmd)
|
|
end
|
|
|
|
def postgres_import(file, config)
|
|
cmd = "pg_restore -d #{config['database']} -U #{config['username']} --clean"
|
|
cmd += " -h #{config['host']} " if config['host'].present?
|
|
cmd += " -p #{config['port']} " if config['port'].present?
|
|
cmd += " #{file}"
|
|
system({'PGPASSWORD' => config['password']}, cmd)
|
|
system(cmd)
|
|
end
|
|
|
|
def sqlite_import(name, config)
|
|
FileUtils.cp name, config['database']
|
|
end
|
|
end
|