Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
commit7e9c479f7de77702622631cff2628a9c8dcbc627 (patch)
treec8f718a08e110ad7e1894510980d2155a6549197 /lib/backup/files.rb
parente852b0ae16db4052c1c567d9efa4facc81146e88 (diff)
Add latest changes from gitlab-org/gitlab@13-6-stable-eev13.6.0-rc42
Diffstat (limited to 'lib/backup/files.rb')
-rw-r--r--lib/backup/files.rb61
1 files changed, 50 insertions, 11 deletions
diff --git a/lib/backup/files.rb b/lib/backup/files.rb
index 619a62fd6f6..a0948f8c0f5 100644
--- a/lib/backup/files.rb
+++ b/lib/backup/files.rb
@@ -26,7 +26,7 @@ module Backup
FileUtils.rm_f(backup_tarball)
if ENV['STRATEGY'] == 'copy'
- cmd = [%w(rsync -a), exclude_dirs(:rsync), %W(#{app_files_dir} #{Gitlab.config.backup.path})].flatten
+ cmd = [%w[rsync -a], exclude_dirs(:rsync), %W[#{app_files_dir} #{Gitlab.config.backup.path}]].flatten
output, status = Gitlab::Popen.popen(cmd)
unless status == 0
@@ -34,19 +34,27 @@ module Backup
raise Backup::Error, 'Backup failed'
end
- tar_cmd = [tar, exclude_dirs(:tar), %W(-C #{@backup_files_dir} -cf - .)].flatten
- run_pipeline!([tar_cmd, gzip_cmd], out: [backup_tarball, 'w', 0600])
+ tar_cmd = [tar, exclude_dirs(:tar), %W[-C #{@backup_files_dir} -cf - .]].flatten
+ status_list, output = run_pipeline!([tar_cmd, gzip_cmd], out: [backup_tarball, 'w', 0600])
FileUtils.rm_rf(@backup_files_dir)
else
- tar_cmd = [tar, exclude_dirs(:tar), %W(-C #{app_files_dir} -cf - .)].flatten
- run_pipeline!([tar_cmd, gzip_cmd], out: [backup_tarball, 'w', 0600])
+ tar_cmd = [tar, exclude_dirs(:tar), %W[-C #{app_files_dir} -cf - .]].flatten
+ status_list, output = run_pipeline!([tar_cmd, gzip_cmd], out: [backup_tarball, 'w', 0600])
+ end
+
+ unless pipeline_succeeded?(tar_status: status_list[0], gzip_status: status_list[1], output: output)
+ raise Backup::Error, "Backup operation failed: #{output}"
end
end
def restore
backup_existing_files_dir
- run_pipeline!([%w(gzip -cd), %W(#{tar} --unlink-first --recursive-unlink -C #{app_files_dir} -xf -)], in: backup_tarball)
+ cmd_list = [%w[gzip -cd], %W[#{tar} --unlink-first --recursive-unlink -C #{app_files_dir} -xf -]]
+ status_list, output = run_pipeline!(cmd_list, in: backup_tarball)
+ unless pipeline_succeeded?(gzip_status: status_list[0], tar_status: status_list[1], output: output)
+ raise Backup::Error, "Restore operation failed: #{output}"
+ end
end
def tar
@@ -78,13 +86,44 @@ module Backup
def run_pipeline!(cmd_list, options = {})
err_r, err_w = IO.pipe
options[:err] = err_w
- status = Open3.pipeline(*cmd_list, options)
+ status_list = Open3.pipeline(*cmd_list, options)
err_w.close
- return if status.compact.all?(&:success?)
- regex = /^g?tar: \.: Cannot mkdir: No such file or directory$/
- error = err_r.read
- raise Backup::Error, "Backup failed. #{error}" unless error =~ regex
+ [status_list, err_r.read]
+ end
+
+ def noncritical_warning?(warning)
+ noncritical_warnings = [
+ /^g?tar: \.: Cannot mkdir: No such file or directory$/
+ ]
+
+ noncritical_warnings.map { |w| warning =~ w }.any?
+ end
+
+ def pipeline_succeeded?(tar_status:, gzip_status:, output:)
+ return false unless gzip_status&.success?
+
+ tar_status&.success? || tar_ignore_non_success?(tar_status.exitstatus, output)
+ end
+
+ def tar_ignore_non_success?(exitstatus, output)
+ # tar can exit with nonzero code:
+ # 1 - if some files changed (i.e. a CI job is currently writes to log)
+ # 2 - if it cannot create `.` directory (see issue https://gitlab.com/gitlab-org/gitlab/-/issues/22442)
+ # http://www.gnu.org/software/tar/manual/html_section/tar_19.html#Synopsis
+ # so check tar status 1 or stderr output against some non-critical warnings
+ if exitstatus == 1
+ $stdout.puts "Ignoring tar exit status 1 'Some files differ': #{output}"
+ return true
+ end
+
+ # allow tar to fail with other non-success status if output contain non-critical warning
+ if noncritical_warning?(output)
+ $stdout.puts "Ignoring non-success exit status #{exitstatus} due to output of non-critical warning(s): #{output}"
+ return true
+ end
+
+ false
end
def exclude_dirs(fmt)