backup revision 4ec9d8b62c3c1a001548eb0883b6f81e00c391a0
842ae4bd224140319ae7feec1872b93dfd491143fielding#!/usr/bin/env ruby
842ae4bd224140319ae7feec1872b93dfd491143fielding
842ae4bd224140319ae7feec1872b93dfd491143fieldingrequire 'tmpdir.rb'
842ae4bd224140319ae7feec1872b93dfd491143fieldingrequire 'fileutils'
842ae4bd224140319ae7feec1872b93dfd491143fieldingrequire 'pathname'
842ae4bd224140319ae7feec1872b93dfd491143fieldingrequire 'open3'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkrequire 'pry'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkrequire 'pry-byebug'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkmodule Backup
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk class Backup
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk # Amount of backups that have to be there at least
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk BACKUPS_COUNT = 3
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk # Backups are valid for 7 days
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk BACKUPS_VALIDITY_TIME = 7 * 60 * 60 * 24
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk MAINTENANCE_FILE = 'maintenance.txt'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk SQL_DUMP_FILE = 'ontohub_sql_dump.postgresql'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk REPOSITORY_FILE = 'ontohub_repositories.tar.gz'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk DATA_DIRS = %w(data/repositories data/git_daemon)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk attr_reader :db_name, :data_root, :backup_root, :backup_instance_dir
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk attr_reader :dry_run, :verbose, :sql_dump_as_postgres_user
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def initialize(db_name, data_root, backup_root,
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk verbose: false, dry_run: true, sql_dump_as_postgres_user: false)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk @db_name = db_name
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk @data_root = Pathname.new(data_root)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk @backup_root = Pathname.new(backup_root)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk @dry_run = dry_run
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk @verbose = verbose
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk @sql_dump_as_postgres_user = sql_dump_as_postgres_user
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def create
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts 'Creating backup...'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk enable_maintenance_mode
e8f95a682820a599fe41b22977010636be5c2717jim initialize_backup
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk create_sql_dump
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk create_repository_archive
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk # We needed to create the directory for the script to continue later on.
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk Dir.rmdir(backup_instance_dir) if dry_run
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk disable_maintenance_mode
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts "Created backup in #{backup_instance_dir}"
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk self.class.prune(backup_root)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def restore(backup_name)
8a4550aaf4cab45fa059d40a998e25df322c5641niq enable_maintenance_mode
8a4550aaf4cab45fa059d40a998e25df322c5641niq initialize_restore(backup_name)
8a4550aaf4cab45fa059d40a998e25df322c5641niq restore_sql_dump
8a4550aaf4cab45fa059d40a998e25df322c5641niq restore_repository_archive
8a4550aaf4cab45fa059d40a998e25df322c5641niq disable_maintenance_mode
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts "Restored backup from #{backup_instance_dir}"
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niq def self.prune(backup_root)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk if !Dir.exists?(backup_root)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk $stderr.puts "Nothing to prune: There is no backup directory."
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk return
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq now = Time.now
8a4550aaf4cab45fa059d40a998e25df322c5641niq backup_dirs_allowed_to_delete(Dir.new(backup_root).entries).each do |dir|
8a4550aaf4cab45fa059d40a998e25df322c5641niq backup = backup_root.join(dir)
8a4550aaf4cab45fa059d40a998e25df322c5641niq if now - File.new(backup).ctime > BACKUPS_VALIDITY_TIME
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts "removing old backup: #{dir}"
8a4550aaf4cab45fa059d40a998e25df322c5641niq FileUtils.rm_r(backup)
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
d045ce8e2b813c57d5b6e28b2485c02b91613759rpluem protected
d045ce8e2b813c57d5b6e28b2485c02b91613759rpluem
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def new_backup_name
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk Time.now.strftime("%Y-%m-%d_%H-%M-%S")
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def initialize_backup
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk @backup_instance_dir = backup_root.join(new_backup_name)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts "FileUtils.mkdir_p #{backup_instance_dir}" if verbose
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk # Create directory even in dry run to let the script continue.
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk FileUtils.mkdir_p(backup_instance_dir)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def create_sql_dump
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts 'Creating SQL dump...'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk Dir.chdir(backup_instance_dir) do
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk exec('pg_dump', pg_user_switch, '-Fc', db_name,
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk file_dest: SQL_DUMP_FILE)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def create_repository_archive
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts 'Creating repository archive...'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk Dir.chdir(data_root.join('..')) do
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk archive_file = backup_instance_dir.join(REPOSITORY_FILE)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk exec('tar', verbose ? '-v' : '', '-czf', archive_file.to_s,
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk *DATA_DIRS.map(&:to_s))
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def initialize_restore(backup_name)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk @backup_instance_dir = backup_root.join(backup_name)
8a4550aaf4cab45fa059d40a998e25df322c5641niq unless Dir.exists?(backup_instance_dir)
8a4550aaf4cab45fa059d40a998e25df322c5641niq $stderr.puts "Error: Backup '#{backup_name}' does not exist in #{backup_root}."
8a4550aaf4cab45fa059d40a998e25df322c5641niq exit
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def restore_sql_dump
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk 'Restoring SQL dump...'
8a4550aaf4cab45fa059d40a998e25df322c5641niq Dir.chdir(backup_instance_dir) do
8a4550aaf4cab45fa059d40a998e25df322c5641niq exec('pg_restore', '-c', pg_user_switch, '-d', db_name, SQL_DUMP_FILE)
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niq def restore_repository_archive
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts 'Restoring repository archive...'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk Dir.chdir(data_root.join('..')) do
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk tmpdir = Dir.mktmpdir
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk move_data_dirs_to_tmpdir(tmpdir)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk begin
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk extract_archive
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk remove_tmpdir(tmpdir)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk rescue => e
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts <<-MSG
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkAn error occured while restoring the repositories:
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk#{e.message}
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkYou can find the pre-restore repositories at #{tmpdir}
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkDo something about it.
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk MSG
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk raise e
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def move_data_dirs_to_tmpdir(tmpdir)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts "FileUtils.mv(#{DATA_DIRS}, #{tmpdir})" if verbose
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk FileUtils.mv(DATA_DIRS, tmpdir) unless dry_run
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk rescue Errno::EACCES
e8f95a682820a599fe41b22977010636be5c2717jim puts <<-MSG
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
8a4550aaf4cab45fa059d40a998e25df322c5641niqAs the current user I have no access to move the repository data
8a4550aaf4cab45fa059d40a998e25df322c5641niqdirectories #{DATA_DIRS.join(' ')} to a temporary directory #{tmpdir}.
8a4550aaf4cab45fa059d40a998e25df322c5641niqThis is used as a backup for the case of an error while restoring.
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkTo continue, I try the command again using sudo.
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk MSG
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk exec('sudo', 'mv', *DATA_DIRS.map(&:to_s), tmpdir)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def extract_archive
d045ce8e2b813c57d5b6e28b2485c02b91613759rpluem archive_file = backup_instance_dir.join(REPOSITORY_FILE)
d045ce8e2b813c57d5b6e28b2485c02b91613759rpluem puts <<-MSG
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
d045ce8e2b813c57d5b6e28b2485c02b91613759rpluemSuper user privileges are needed to reset the file permissions as
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkthey were before the backup. If you refuse to enter the password
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk(Crtl-C) or enter a wrong password, only the permissions will not be
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkrestored and all restored files will belong to the current user/group.
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk MSG
8a4550aaf4cab45fa059d40a998e25df322c5641niq try_as_sudo_with_fallback('tar', verbose ? '-v' : '', '-xzf',
f02523893633e6b12ce7fa344d9c3fef3f2e488cniq archive_file.to_s, *DATA_DIRS.map(&:to_s))
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niq def remove_tmpdir(tmpdir)
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts "FileUtils.remove_entry(#{tmpdir})" if verbose
8a4550aaf4cab45fa059d40a998e25df322c5641niq FileUtils.remove_entry(tmpdir) # even do this in dry run
8a4550aaf4cab45fa059d40a998e25df322c5641niq rescue Errno::EACCES
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts <<-MSG
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niqAs the current user I have no access to remove the temporary
8a4550aaf4cab45fa059d40a998e25df322c5641niqdirectory #{tmpdir}.
8a4550aaf4cab45fa059d40a998e25df322c5641niqTo continue, I try the command again using sudo.
8a4550aaf4cab45fa059d40a998e25df322c5641niq MSG
8a4550aaf4cab45fa059d40a998e25df322c5641niq exec('sudo', 'rm', '-r', tmpdir)
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niq def enable_maintenance_mode
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts 'Enabling maintenance mode...'
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts "FileUtils.touch #{maintenance_file}" if verbose
8a4550aaf4cab45fa059d40a998e25df322c5641niq FileUtils.touch maintenance_file unless dry_run
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niq def disable_maintenance_mode
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts 'Disabling maintenance mode...'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk puts "FileUtils.rm #{maintenance_file}" if verbose
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk FileUtils.rm maintenance_file unless dry_run
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def exec(*args, file_dest: nil)
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts "[executing next command in #{Dir.getwd}]" if verbose
8a4550aaf4cab45fa059d40a998e25df322c5641niq out = args.join(' ')
8a4550aaf4cab45fa059d40a998e25df322c5641niq out << " > #{file_dest}" if file_dest
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts out if verbose
8a4550aaf4cab45fa059d40a998e25df322c5641niq Subprocess.run(*args, file_dest: file_dest) unless dry_run
d045ce8e2b813c57d5b6e28b2485c02b91613759rpluem end
418ee053321d0ee451bb482a9becdfcd3344201fjim
418ee053321d0ee451bb482a9becdfcd3344201fjim def try_as_sudo_with_fallback(*args)
418ee053321d0ee451bb482a9becdfcd3344201fjim unless exec('sudo', *args)
8a4550aaf4cab45fa059d40a998e25df322c5641niq sudo_not_given_fallback(*args) # Wrong sudo password
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq rescue Exception => e
8a4550aaf4cab45fa059d40a998e25df322c5641niq raise e unless e.is_a?(Interrupt) # Ctrl-C when asked for password
8a4550aaf4cab45fa059d40a998e25df322c5641niq sudo_not_given_fallback(*args)
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niq def sudo_not_given_fallback(*args)
8a4550aaf4cab45fa059d40a998e25df322c5641niq puts 'Super user privileges not granted. Trying as normal user.'
8a4550aaf4cab45fa059d40a998e25df322c5641niq exec(*args)
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def maintenance_file
8a4550aaf4cab45fa059d40a998e25df322c5641niq data_root.join(MAINTENANCE_FILE)
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niq def pg_user_switch
8a4550aaf4cab45fa059d40a998e25df322c5641niq sql_dump_as_postgres_user ? ' -U postgres' : ''
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def self.backup_dirs_allowed_to_delete(entries)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk entries.reject{ |entry| %w(. ..).include?(entry) }[0..-(BACKUPS_COUNT+1)]
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk class Subprocess
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def self.run(*args, file_dest: nil)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk stdin, stdout, stderr, wait_thr, io_dest = run_streaming(*args,
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk file_dest: file_dest)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk exit_code = wait_thr.value # wait for the process to finish
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk io_dest.close if io_dest
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk [stdout.read, stderr.read, exit_code]
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk def self.run_streaming(*args, file_dest: nil)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk stdin, stdout, stderr, wait_thr = Open3.popen3(*args)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk io_dest = nil
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk if file_dest
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk io_dest = File.open(file_dest, 'w')
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk IO.copy_stream(stdout, io_dest)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk [stdin, stdout, stderr, wait_thr, io_dest]
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niqend
8a4550aaf4cab45fa059d40a998e25df322c5641niq
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkdef data_root(rails_root)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk File.realpath(rails_root.join('data'))
8a4550aaf4cab45fa059d40a998e25df322c5641niqend
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niqdef on_development_system?(rails_root)
8a4550aaf4cab45fa059d40a998e25df322c5641niq !File.symlink?(rails_root.join('data'))
8a4550aaf4cab45fa059d40a998e25df322c5641niqend
8a4550aaf4cab45fa059d40a998e25df322c5641niq
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk# We assume, this script runs in "RAILS_ROOT/script/".
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkRAILS_ROOT = Pathname.new(__FILE__).dirname.join('..')
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkDATABASE = if on_development_system?(RAILS_ROOT)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk 'ontohub_development'
8a4550aaf4cab45fa059d40a998e25df322c5641niq else
8a4550aaf4cab45fa059d40a998e25df322c5641niq 'ontohub'
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkBACKUP_ROOT = if on_development_system?(RAILS_ROOT)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk RAILS_ROOT.join('tmp', 'backup')
8a4550aaf4cab45fa059d40a998e25df322c5641niq else
8a4550aaf4cab45fa059d40a998e25df322c5641niq File.realpath('/home/ontohub/ontohub_data_backup')
8a4550aaf4cab45fa059d40a998e25df322c5641niq end
8a4550aaf4cab45fa059d40a998e25df322c5641niq
8a4550aaf4cab45fa059d40a998e25df322c5641niqbackup = Backup::Backup.new(DATABASE, data_root(RAILS_ROOT), BACKUP_ROOT,
8a4550aaf4cab45fa059d40a998e25df322c5641niq sql_dump_as_postgres_user: on_development_system?(RAILS_ROOT),
8a4550aaf4cab45fa059d40a998e25df322c5641niq dry_run: false, verbose: true)
8a4550aaf4cab45fa059d40a998e25df322c5641niq
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkcase ARGV.first
8a4550aaf4cab45fa059d40a998e25df322c5641niqwhen 'create'
8a4550aaf4cab45fa059d40a998e25df322c5641niq backup.create
8a4550aaf4cab45fa059d40a998e25df322c5641niqwhen 'restore'
8a4550aaf4cab45fa059d40a998e25df322c5641niq if ARGV.length == 1
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk $stderr.puts 'To restore a backup, you need to specify one with the arguments'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk $stderr.puts '"restore backup_name"'
8a4550aaf4cab45fa059d40a998e25df322c5641niq exit
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk end
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk backup_name = ARGV[1]
8a4550aaf4cab45fa059d40a998e25df322c5641niq backup.restore(backup_name)
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkwhen 'prune'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk Backup::Backup.prune(BACKUP_ROOT)
d045ce8e2b813c57d5b6e28b2485c02b91613759rpluemelse
d045ce8e2b813c57d5b6e28b2485c02b91613759rpluem $stderr.puts 'unknown or missing parameter'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk $stderr.puts 'use parameter "create" or "restore <backup_name>" or "prune"'
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk exit
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturkend
13852d30fd6e3ffee07702f9222a0dd5aeec75ebmturk