Skip to content

Commit

Permalink
refactor backup/restore
Browse files Browse the repository at this point in the history
  • Loading branch information
dzaporozhets committed Apr 5, 2013
1 parent 362d82d commit c33d5e1
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 103 deletions.
2 changes: 1 addition & 1 deletion doc/install/databases.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
56 changes: 0 additions & 56 deletions lib/backup.rb

This file was deleted.

58 changes: 58 additions & 0 deletions lib/backup/database.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 74 additions & 0 deletions lib/backup/repository.rb
Original file line number Diff line number Diff line change
@@ -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
53 changes: 7 additions & 46 deletions lib/tasks/gitlab/backup.rake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c33d5e1

Please sign in to comment.