refactor backup/restore
This commit is contained in:
parent
362d82d10e
commit
c33d5e16fe
5 changed files with 140 additions and 103 deletions
|
@ -21,7 +21,7 @@ GitLab supports the following databases:
|
|||
mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
|
||||
|
||||
# Grant the GitLab user necessary permissopns on the table.
|
||||
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost';
|
||||
mysql> GRANT SELECT, LOCK TABLES, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost';
|
||||
|
||||
# Quit the database session
|
||||
mysql> \q
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
require 'yaml'
|
||||
|
||||
class Backup
|
||||
attr_reader :config, :db_dir
|
||||
|
||||
def initialize
|
||||
@config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
|
||||
@db_dir = File.join(Gitlab.config.backup.path, 'db')
|
||||
FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir)
|
||||
end
|
||||
|
||||
def backup_db
|
||||
case config["adapter"]
|
||||
when /^mysql/ then
|
||||
system("mysqldump #{mysql_args} #{config['database']} > #{db_file_name}")
|
||||
when "postgresql" then
|
||||
pg_env
|
||||
system("pg_dump #{config['database']} > #{db_file_name}")
|
||||
end
|
||||
end
|
||||
|
||||
def restore_db
|
||||
case config["adapter"]
|
||||
when /^mysql/ then
|
||||
system("mysql #{mysql_args} #{config['database']} < #{db_file_name}")
|
||||
when "postgresql" then
|
||||
pg_env
|
||||
system("pg_restore #{config['database']} #{db_file_name}")
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def db_file_name
|
||||
File.join(db_dir, 'database.sql')
|
||||
end
|
||||
|
||||
def mysql_args
|
||||
args = {
|
||||
'host' => '--host',
|
||||
'port' => '--port',
|
||||
'socket' => '--socket',
|
||||
'username' => '--user',
|
||||
'encoding' => '--default-character-set',
|
||||
'password' => '--password'
|
||||
}
|
||||
args.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact.join(' ')
|
||||
end
|
||||
|
||||
def pg_env
|
||||
ENV['PGUSER'] = config["username"] if config["username"]
|
||||
ENV['PGHOST'] = config["host"] if config["host"]
|
||||
ENV['PGPORT'] = config["port"].to_s if config["port"]
|
||||
ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
|
||||
end
|
||||
end
|
58
lib/backup/database.rb
Normal file
58
lib/backup/database.rb
Normal file
|
@ -0,0 +1,58 @@
|
|||
require 'yaml'
|
||||
|
||||
module Backup
|
||||
class Database
|
||||
attr_reader :config, :db_dir
|
||||
|
||||
def initialize
|
||||
@config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
|
||||
@db_dir = File.join(Gitlab.config.backup.path, 'db')
|
||||
FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir)
|
||||
end
|
||||
|
||||
def dump
|
||||
case config["adapter"]
|
||||
when /^mysql/ then
|
||||
system("mysqldump #{mysql_args} #{config['database']} > #{db_file_name}")
|
||||
when "postgresql" then
|
||||
pg_env
|
||||
system("pg_dump #{config['database']} > #{db_file_name}")
|
||||
end
|
||||
end
|
||||
|
||||
def restore
|
||||
case config["adapter"]
|
||||
when /^mysql/ then
|
||||
system("mysql #{mysql_args} #{config['database']} < #{db_file_name}")
|
||||
when "postgresql" then
|
||||
pg_env
|
||||
system("pg_restore #{config['database']} #{db_file_name}")
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def db_file_name
|
||||
File.join(db_dir, 'database.sql')
|
||||
end
|
||||
|
||||
def mysql_args
|
||||
args = {
|
||||
'host' => '--host',
|
||||
'port' => '--port',
|
||||
'socket' => '--socket',
|
||||
'username' => '--user',
|
||||
'encoding' => '--default-character-set',
|
||||
'password' => '--password'
|
||||
}
|
||||
args.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact.join(' ')
|
||||
end
|
||||
|
||||
def pg_env
|
||||
ENV['PGUSER'] = config["username"] if config["username"]
|
||||
ENV['PGHOST'] = config["host"] if config["host"]
|
||||
ENV['PGPORT'] = config["port"].to_s if config["port"]
|
||||
ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
|
||||
end
|
||||
end
|
||||
end
|
74
lib/backup/repository.rb
Normal file
74
lib/backup/repository.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
require 'yaml'
|
||||
|
||||
module Backup
|
||||
class Repository
|
||||
attr_reader :repos_path
|
||||
|
||||
def dump
|
||||
prepare
|
||||
|
||||
Project.find_each(batch_size: 1000) do |project|
|
||||
print " * #{project.path_with_namespace} ... "
|
||||
|
||||
if project.empty_repo?
|
||||
puts "[SKIPPED]".cyan
|
||||
next
|
||||
end
|
||||
|
||||
# Create namespace dir if missing
|
||||
FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.path)) if project.namespace
|
||||
|
||||
if system("cd #{path_to_repo(project)} > /dev/null 2>&1 && git bundle create #{path_to_bundle(project)} --all > /dev/null 2>&1")
|
||||
puts "[DONE]".green
|
||||
else
|
||||
puts "[FAILED]".red
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def restore
|
||||
if File.exists?(repos_path)
|
||||
# Move repos dir to 'repositories.old' dir
|
||||
bk_repos_path = File.join(repos_path, '..', 'repositories.old')
|
||||
FileUtils.mv(repos_path, bk_repos_path)
|
||||
end
|
||||
|
||||
FileUtils.mkdir_p(repos_path)
|
||||
|
||||
Project.find_each(batch_size: 1000) do |project|
|
||||
print "#{project.path_with_namespace} ... "
|
||||
|
||||
project.namespace.ensure_dir_exist if project.namespace
|
||||
|
||||
if system("git clone --bare #{path_to_bundle(project)} #{path_to_repo(project)} > /dev/null 2>&1")
|
||||
puts "[DONE]".green
|
||||
else
|
||||
puts "[FAILED]".red
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def path_to_repo(project)
|
||||
File.join(repos_path, project.path_with_namespace + '.git')
|
||||
end
|
||||
|
||||
def path_to_bundle(project)
|
||||
File.join(backup_repos_path, project.path_with_namespace + ".bundle")
|
||||
end
|
||||
|
||||
def repos_path
|
||||
Gitlab.config.gitlab_shell.repos_path
|
||||
end
|
||||
|
||||
def backup_repos_path
|
||||
File.join(Gitlab.config.backup.path, "repositories")
|
||||
end
|
||||
|
||||
def prepare
|
||||
FileUtils.rm_rf(backup_repos_path)
|
||||
FileUtils.mkdir_p(backup_repos_path)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -111,67 +111,28 @@ namespace :gitlab do
|
|||
|
||||
namespace :repo do
|
||||
task :create => :environment do
|
||||
backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
|
||||
FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
|
||||
puts "Dumping repositories ...".blue
|
||||
|
||||
Project.find_each(:batch_size => 1000) do |project|
|
||||
print " * #{project.path_with_namespace} ... "
|
||||
|
||||
if project.empty_repo?
|
||||
puts "[SKIPPED]".cyan
|
||||
next
|
||||
end
|
||||
|
||||
# Create namespace dir if missing
|
||||
FileUtils.mkdir_p(File.join(backup_path_repo, project.namespace.path)) if project.namespace
|
||||
|
||||
# Build a destination path for backup
|
||||
path_to_bundle = File.join(backup_path_repo, project.path_with_namespace + ".bundle")
|
||||
|
||||
if Kernel.system("cd #{project.repository.path_to_repo} > /dev/null 2>&1 && git bundle create #{path_to_bundle} --all > /dev/null 2>&1")
|
||||
puts "[DONE]".green
|
||||
else
|
||||
puts "[FAILED]".red
|
||||
end
|
||||
end
|
||||
Backup::Repository.new.dump
|
||||
puts "done".green
|
||||
end
|
||||
|
||||
task :restore => :environment do
|
||||
backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
|
||||
repos_path = Gitlab.config.gitlab_shell.repos_path
|
||||
|
||||
puts "Restoring repositories ... "
|
||||
|
||||
Project.find_each(:batch_size => 1000) do |project|
|
||||
print "#{project.path_with_namespace} ... "
|
||||
|
||||
if project.namespace
|
||||
project.namespace.ensure_dir_exist
|
||||
end
|
||||
|
||||
# Build a backup path
|
||||
path_to_bundle = File.join(backup_path_repo, project.path_with_namespace + ".bundle")
|
||||
|
||||
if Kernel.system("git clone --bare #{path_to_bundle} #{project.repository.path_to_repo} > /dev/null 2>&1")
|
||||
puts "[DONE]".green
|
||||
else
|
||||
puts "[FAILED]".red
|
||||
end
|
||||
end
|
||||
puts "Restoring repositories ...".blue
|
||||
Backup::Repository.new.restore
|
||||
puts "done".green
|
||||
end
|
||||
end
|
||||
|
||||
namespace :db do
|
||||
task :create => :environment do
|
||||
puts "Dumping database ... ".blue
|
||||
Backup.new.backup_db
|
||||
Backup::Database.new.dump
|
||||
puts "done".green
|
||||
end
|
||||
|
||||
task :restore => :environment do
|
||||
puts "Restoring database ... ".blue
|
||||
Backup.new.restore_db
|
||||
Backup::Database.new.restore
|
||||
puts "done".green
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue