Commit 8785f237 authored by Balasankar "Balu" C's avatar Balasankar "Balu" C

Move existing dirs to a temp location while restore

Instead of renaming existing storage directories to a timestamped
format, create a timestamped directory in a temporary location and move
the individual files and folders inside storage directories to it. This
helps us with nested storage directories.
parent 9b76d851
......@@ -5,9 +5,5 @@ module Backup
def initialize
super('artifacts', JobArtifactUploader.root)
end
def create_files_dir
Dir.mkdir(app_files_dir, 0700)
end
end
end
......@@ -5,9 +5,5 @@ module Backup
def initialize
super('builds', Settings.gitlab_ci.builds_path)
end
def create_files_dir
Dir.mkdir(app_files_dir, 0700)
end
end
end
require 'open3'
require_relative 'helper'
module Backup
class Files
include Backup::Helper
attr_reader :name, :app_files_dir, :backup_tarball, :files_parent_dir
def initialize(name, app_files_dir)
......@@ -35,15 +38,22 @@ module Backup
def restore
backup_existing_files_dir
create_files_dir
run_pipeline!([%w(gzip -cd), %W(tar -C #{app_files_dir} -xf -)], in: backup_tarball)
run_pipeline!([%w(gzip -cd), %W(tar --unlink-first --recursive-unlink -C #{app_files_dir} -xf -)], in: backup_tarball)
end
def backup_existing_files_dir
timestamped_files_path = File.join(files_parent_dir, "#{name}.#{Time.now.to_i}")
timestamped_files_path = File.join(Gitlab.config.backup.path, "tmp", "#{name}.#{Time.now.to_i}")
if File.exist?(app_files_dir)
FileUtils.mv(app_files_dir, File.expand_path(timestamped_files_path))
# Move all files in the existing repos directory except . and .. to
# repositories.old.<timestamp> directory
FileUtils.mkdir_p(timestamped_files_path, mode: 0700)
files = Dir.glob(File.join(app_files_dir, "*"), File::FNM_DOTMATCH) - [File.join(app_files_dir, "."), File.join(app_files_dir, "..")]
begin
FileUtils.mv(files, timestamped_files_path)
rescue Errno::EACCES
access_denied_error(app_files_dir)
end
end
end
......
module Backup
module Helper
def access_denied_error(path)
message = <<~EOS
### NOTICE ###
As part of restore, the task tried to move existing content from #{path}.
However, it seems that directory contains files/folders that are not owned
by the user #{Gitlab.config.gitlab.user}. To proceed, please move the files
or folders inside #{path} to a secure location so that #{path} is empty and
run restore task again.
EOS
raise message
end
end
end
......@@ -5,9 +5,5 @@ module Backup
def initialize
super('lfs', Settings.lfs.storage_path)
end
def create_files_dir
Dir.mkdir(app_files_dir, 0700)
end
end
end
......@@ -5,9 +5,5 @@ module Backup
def initialize
super('pages', Gitlab.config.pages.path)
end
def create_files_dir
Dir.mkdir(app_files_dir, 0700)
end
end
end
......@@ -5,9 +5,5 @@ module Backup
def initialize
super('registry', Settings.registry.path)
end
def create_files_dir
Dir.mkdir(app_files_dir, 0700)
end
end
end
require 'yaml'
require_relative 'helper'
module Backup
class Repository
include Backup::Helper
# rubocop:disable Metrics/AbcSize
def dump
prepare
......@@ -63,18 +66,27 @@ module Backup
end
end
def restore
def prepare_directories
Gitlab.config.repositories.storages.each do |name, repository_storage|
path = repository_storage.legacy_disk_path
next unless File.exist?(path)
# Move repos dir to 'repositories.old' dir
bk_repos_path = File.join(path, '..', 'repositories.old.' + Time.now.to_i.to_s)
FileUtils.mv(path, bk_repos_path)
# This is expected from gitlab:check
FileUtils.mkdir_p(path, mode: 02770)
# Move all files in the existing repos directory except . and .. to
# repositories.old.<timestamp> directory
bk_repos_path = File.join(Gitlab.config.backup.path, "tmp", "#{name}-repositories.old." + Time.now.to_i.to_s)
FileUtils.mkdir_p(bk_repos_path, mode: 0700)
files = Dir.glob(File.join(path, "*"), File::FNM_DOTMATCH) - [File.join(path, "."), File.join(path, "..")]
begin
FileUtils.mv(files, bk_repos_path)
rescue Errno::EACCES
access_denied_error(path)
end
end
end
def restore
prepare_directories
Project.find_each(batch_size: 1000) do |project|
progress.print " * #{display_repo_path(project)} ... "
path_to_project_repo = path_to_repo(project)
......
......@@ -5,9 +5,5 @@ module Backup
def initialize
super('uploads', Rails.root.join('public/uploads'))
end
def create_files_dir
Dir.mkdir(app_files_dir)
end
end
end
......@@ -7,6 +7,8 @@ describe Backup::Repository do
before do
allow(progress).to receive(:puts)
allow(progress).to receive(:print)
allow(FileUtils).to receive(:mkdir_p).and_return(true)
allow(FileUtils).to receive(:mv).and_return(true)
allow_any_instance_of(String).to receive(:color) do |string, _color|
string
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment