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>2022-11-15 12:09:33 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-11-15 12:09:33 +0300
commit25fdad39f53eb46b346076fd07bc2db9bc1d8ccb (patch)
treeb2aec078df9f1414ff11e0940558fa2d8377000a /lib/gitlab/import_export
parentfbea3a224e10049658a7c31bbe7455dc43a4456e (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/import_export')
-rw-r--r--lib/gitlab/import_export/project/exported_relations_merger.rb56
-rw-r--r--lib/gitlab/import_export/project/relation_saver.rb2
-rw-r--r--lib/gitlab/import_export/recursive_merge_folders.rb74
3 files changed, 131 insertions, 1 deletions
diff --git a/lib/gitlab/import_export/project/exported_relations_merger.rb b/lib/gitlab/import_export/project/exported_relations_merger.rb
new file mode 100644
index 00000000000..dda3d00d608
--- /dev/null
+++ b/lib/gitlab/import_export/project/exported_relations_merger.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module ImportExport
+ module Project
+ class ExportedRelationsMerger
+ include Gitlab::ImportExport::CommandLineUtil
+
+ def initialize(export_job:, shared:)
+ @export_job = export_job
+ @shared = shared
+ end
+
+ def save
+ Dir.mktmpdir do |dirpath|
+ export_job.relation_exports.each do |relation_export|
+ relation = relation_export.relation
+ upload = relation_export.upload
+ filename = upload.export_file.filename
+
+ tar_gz_full_path = File.join(dirpath, filename)
+ decompress_path = File.join(dirpath, relation)
+ Gitlab::Utils.check_path_traversal!(tar_gz_full_path)
+ Gitlab::Utils.check_path_traversal!(decompress_path)
+
+ # Download tar.gz
+ download_or_copy_upload(
+ upload.export_file, tar_gz_full_path, size_limit: relation_export.upload.export_file.size
+ )
+
+ # Decompress tar.gz
+ mkdir_p(decompress_path)
+ untar_zxf(dir: decompress_path, archive: tar_gz_full_path)
+ File.delete(tar_gz_full_path)
+
+ # Merge decompressed files into export_path
+ RecursiveMergeFolders.merge(decompress_path, shared.export_path)
+ FileUtils.rm_r(decompress_path)
+ rescue StandardError => e
+ shared.error(e)
+ false
+ end
+ end
+
+ shared.errors.empty?
+ end
+
+ private
+
+ attr_reader :shared, :export_job
+
+ delegate :project, to: :export_job
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import_export/project/relation_saver.rb b/lib/gitlab/import_export/project/relation_saver.rb
index 8e91adac196..967239e17c1 100644
--- a/lib/gitlab/import_export/project/relation_saver.rb
+++ b/lib/gitlab/import_export/project/relation_saver.rb
@@ -32,7 +32,7 @@ module Gitlab
project,
reader.project_tree,
json_writer,
- exportable_path: 'project',
+ exportable_path: 'tree/project',
current_user: nil
)
end
diff --git a/lib/gitlab/import_export/recursive_merge_folders.rb b/lib/gitlab/import_export/recursive_merge_folders.rb
new file mode 100644
index 00000000000..982358699bd
--- /dev/null
+++ b/lib/gitlab/import_export/recursive_merge_folders.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+#
+# This class is used by Import/Export to move files and folders from a source folders into a target folders
+# that can already have the same folders in it, resolving in a merged folder.
+#
+# Example:
+#
+# source path
+# |-- tree
+# | |-- project
+# | |-- labels.ndjson
+# |-- uploads
+# | |-- folder1
+# | | |-- image1.png
+# | |-- folder2
+# | | |-- image2.png
+#
+# target path
+# |-- tree
+# | |-- project
+# | |-- issues.ndjson
+# |-- uploads
+# | |-- folder1
+# | | |-- image3.png
+# | |-- folder3
+# | | |-- image4.png
+#
+# target path after merge
+# |-- tree
+# | |-- project
+# | | |-- issues.ndjson
+# | | |-- labels.ndjson
+# |-- uploads
+# | |-- folder1
+# | | |-- image1.png
+# | | |-- image3.png
+# | |-- folder2
+# | | |-- image2.png
+# | |-- folder3
+# | | |-- image4.png
+
+module Gitlab
+ module ImportExport
+ class RecursiveMergeFolders
+ DEFAULT_DIR_MODE = 0o700
+
+ def self.merge(source_path, target_path)
+ Gitlab::Utils.check_path_traversal!(source_path)
+ Gitlab::Utils.check_path_traversal!(target_path)
+ Gitlab::Utils.check_allowed_absolute_path!(source_path, [Dir.tmpdir])
+
+ recursive_merge(source_path, target_path)
+ end
+
+ def self.recursive_merge(source_path, target_path)
+ Dir.children(source_path).each do |child|
+ source_child = File.join(source_path, child)
+ target_child = File.join(target_path, child)
+
+ next if File.lstat(source_child).symlink?
+
+ if File.directory?(source_child)
+ FileUtils.mkdir_p(target_child, mode: DEFAULT_DIR_MODE) unless File.exist?(target_child)
+ recursive_merge(source_child, target_child)
+ else
+ FileUtils.mv(source_child, target_child)
+ end
+ end
+ end
+
+ private_class_method :recursive_merge
+ end
+ end
+end