diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/compare_service.rb | 12 | ||||
-rw-r--r-- | app/services/issuable/destroy_service.rb | 9 | ||||
-rw-r--r-- | app/services/issuable_base_service.rb | 33 | ||||
-rw-r--r-- | app/services/issues/base_service.rb | 8 | ||||
-rw-r--r-- | app/services/issues/update_service.rb | 7 | ||||
-rw-r--r-- | app/services/merge_requests/base_service.rb | 8 | ||||
-rw-r--r-- | app/services/merge_requests/build_service.rb | 16 | ||||
-rw-r--r-- | app/services/merge_requests/update_service.rb | 5 | ||||
-rw-r--r-- | app/services/projects/hashed_storage/migrate_attachments_service.rb | 54 | ||||
-rw-r--r-- | app/services/projects/hashed_storage/migrate_repository_service.rb | 70 | ||||
-rw-r--r-- | app/services/projects/hashed_storage_migration_service.rb | 62 | ||||
-rw-r--r-- | app/services/projects/update_service.rb | 10 |
12 files changed, 202 insertions, 92 deletions
diff --git a/app/services/compare_service.rb b/app/services/compare_service.rb index 53f16a236d2..1db91c3c90c 100644 --- a/app/services/compare_service.rb +++ b/app/services/compare_service.rb @@ -1,17 +1,17 @@ require 'securerandom' -# Compare 2 branches for one repo or between repositories +# Compare 2 refs for one repo or between repositories # and return Gitlab::Git::Compare object that responds to commits and diffs class CompareService - attr_reader :start_project, :start_branch_name + attr_reader :start_project, :start_ref_name - def initialize(new_start_project, new_start_branch_name) + def initialize(new_start_project, new_start_ref_name) @start_project = new_start_project - @start_branch_name = new_start_branch_name + @start_ref_name = new_start_ref_name end - def execute(target_project, target_branch, straight: false) - raw_compare = target_project.repository.compare_source_branch(target_branch, start_project.repository, start_branch_name, straight: straight) + def execute(target_project, target_ref, straight: false) + raw_compare = target_project.repository.compare_source_branch(target_ref, start_project.repository, start_ref_name, straight: straight) Compare.new(raw_compare, target_project, straight: straight) if raw_compare end diff --git a/app/services/issuable/destroy_service.rb b/app/services/issuable/destroy_service.rb new file mode 100644 index 00000000000..0610b401213 --- /dev/null +++ b/app/services/issuable/destroy_service.rb @@ -0,0 +1,9 @@ +module Issuable + class DestroyService < IssuableBaseService + def execute(issuable) + if issuable.destroy + issuable.update_project_counter_caches + end + end + end +end diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 39a7299ff60..2c51ac13815 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -169,10 +169,7 @@ class IssuableBaseService < BaseService change_todo(issuable) toggle_award(issuable) filter_params(issuable) - old_labels = issuable.labels.to_a - old_mentioned_users = issuable.mentioned_users.to_a - old_assignees = issuable.assignees.to_a - old_total_time_spent = issuable.total_time_spent + old_associations = associations_before_update(issuable) label_ids = process_label_ids(params, existing_label_ids: issuable.label_ids) params[:label_ids] = label_ids if labels_changing?(issuable.label_ids, label_ids) @@ -193,18 +190,13 @@ class IssuableBaseService < BaseService if issuable.with_transaction_returning_status { issuable.save } # We do not touch as it will affect a update on updated_at field ActiveRecord::Base.no_touching do - Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, old_labels) + Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, old_associations[:labels]) end - handle_changes( - issuable, - old_labels: old_labels, - old_mentioned_users: old_mentioned_users, - old_assignees: old_assignees - ) + handle_changes(issuable, old_associations: old_associations) new_assignees = issuable.assignees.to_a - affected_assignees = (old_assignees + new_assignees) - (old_assignees & new_assignees) + affected_assignees = (old_associations[:assignees] + new_assignees) - (old_associations[:assignees] & new_assignees) invalidate_cache_counts(issuable, users: affected_assignees.compact) after_update(issuable) @@ -212,9 +204,8 @@ class IssuableBaseService < BaseService execute_hooks( issuable, 'update', - old_labels: old_labels, - old_assignees: old_assignees, - old_total_time_spent: old_total_time_spent) + old_associations: old_associations + ) issuable.update_project_counter_caches if update_project_counters end @@ -267,6 +258,18 @@ class IssuableBaseService < BaseService end end + def associations_before_update(issuable) + associations = + { + labels: issuable.labels.to_a, + mentioned_users: issuable.mentioned_users.to_a, + assignees: issuable.assignees.to_a + } + associations[:total_time_spent] = issuable.total_time_spent if issuable.respond_to?(:total_time_spent) + + associations + end + def has_changes?(issuable, old_labels: [], old_assignees: []) valid_attrs = [:title, :description, :assignee_id, :milestone_id, :target_branch] diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb index 0f711bcc3cf..9f6cfc0f6d3 100644 --- a/app/services/issues/base_service.rb +++ b/app/services/issues/base_service.rb @@ -1,7 +1,7 @@ module Issues class BaseService < ::IssuableBaseService - def hook_data(issue, action, old_labels: [], old_assignees: [], old_total_time_spent: nil) - hook_data = issue.to_hook_data(current_user, old_labels: old_labels, old_assignees: old_assignees, old_total_time_spent: old_total_time_spent) + def hook_data(issue, action, old_associations: {}) + hook_data = issue.to_hook_data(current_user, old_associations: old_associations) hook_data[:object_attributes][:action] = action hook_data @@ -22,8 +22,8 @@ module Issues issue, issue.project, current_user, old_assignees) end - def execute_hooks(issue, action = 'open', old_labels: [], old_assignees: [], old_total_time_spent: nil) - issue_data = hook_data(issue, action, old_labels: old_labels, old_assignees: old_assignees, old_total_time_spent: old_total_time_spent) + def execute_hooks(issue, action = 'open', old_associations: {}) + issue_data = hook_data(issue, action, old_associations: old_associations) hooks_scope = issue.confidential? ? :confidential_issue_hooks : :issue_hooks issue.project.execute_hooks(issue_data, hooks_scope) issue.project.execute_services(issue_data, hooks_scope) diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 1b7b5927c5a..d7aa7e2347e 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -14,9 +14,10 @@ module Issues end def handle_changes(issue, options) - old_labels = options[:old_labels] || [] - old_mentioned_users = options[:old_mentioned_users] || [] - old_assignees = options[:old_assignees] || [] + old_associations = options.fetch(:old_associations, {}) + old_labels = old_associations.fetch(:labels, []) + old_mentioned_users = old_associations.fetch(:mentioned_users, []) + old_assignees = old_associations.fetch(:assignees, []) if has_changes?(issue, old_labels: old_labels, old_assignees: old_assignees) todo_service.mark_pending_todos_as_done(issue, current_user) diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index f6ffd48deae..6b32d65a74b 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -4,8 +4,8 @@ module MergeRequests SystemNoteService.change_status(merge_request, merge_request.target_project, current_user, state, nil) end - def hook_data(merge_request, action, old_rev: nil, old_labels: [], old_assignees: [], old_total_time_spent: nil) - hook_data = merge_request.to_hook_data(current_user, old_labels: old_labels, old_assignees: old_assignees, old_total_time_spent: old_total_time_spent) + def hook_data(merge_request, action, old_rev: nil, old_associations: {}) + hook_data = merge_request.to_hook_data(current_user, old_associations: old_associations) hook_data[:object_attributes][:action] = action if old_rev && !Gitlab::Git.blank_ref?(old_rev) hook_data[:object_attributes][:oldrev] = old_rev @@ -14,9 +14,9 @@ module MergeRequests hook_data end - def execute_hooks(merge_request, action = 'open', old_rev: nil, old_labels: [], old_assignees: [], old_total_time_spent: nil) + def execute_hooks(merge_request, action = 'open', old_rev: nil, old_associations: {}) if merge_request.project - merge_data = hook_data(merge_request, action, old_rev: old_rev, old_labels: old_labels, old_assignees: old_assignees, old_total_time_spent: old_total_time_spent) + merge_data = hook_data(merge_request, action, old_rev: old_rev, old_associations: old_associations) merge_request.project.execute_hooks(merge_data, :merge_request_hooks) merge_request.project.execute_services(merge_data, :merge_request_hooks) end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index f3b99e1ec8c..8223e5fed7f 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -18,7 +18,17 @@ module MergeRequests attr_accessor :merge_request - delegate :target_branch, :source_branch, :source_project, :target_project, :compare_commits, :wip_title, :description, :errors, to: :merge_request + delegate :target_branch, + :target_branch_ref, + :target_project, + :source_branch, + :source_branch_ref, + :source_project, + :compare_commits, + :wip_title, + :description, + :errors, + to: :merge_request def find_source_project return source_project if source_project.present? && can?(current_user, :read_project, source_project) @@ -54,10 +64,10 @@ module MergeRequests def compare_branches compare = CompareService.new( source_project, - source_branch + source_branch_ref ).execute( target_project, - target_branch + target_branch_ref ) if compare diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index 1f394cacc64..c153872c874 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -22,8 +22,9 @@ module MergeRequests end def handle_changes(merge_request, options) - old_labels = options[:old_labels] || [] - old_mentioned_users = options[:old_mentioned_users] || [] + old_associations = options.fetch(:old_associations, {}) + old_labels = old_associations.fetch(:labels, []) + old_mentioned_users = old_associations.fetch(:mentioned_users, []) if has_changes?(merge_request, old_labels: old_labels) todo_service.mark_pending_todos_as_done(merge_request, current_user) diff --git a/app/services/projects/hashed_storage/migrate_attachments_service.rb b/app/services/projects/hashed_storage/migrate_attachments_service.rb new file mode 100644 index 00000000000..f8aaec8a9c0 --- /dev/null +++ b/app/services/projects/hashed_storage/migrate_attachments_service.rb @@ -0,0 +1,54 @@ +module Projects + module HashedStorage + AttachmentMigrationError = Class.new(StandardError) + + class MigrateAttachmentsService < BaseService + attr_reader :logger, :old_path, :new_path + + def initialize(project, logger = nil) + @project = project + @logger = logger || Rails.logger + end + + def execute + @old_path = project.full_path + @new_path = project.disk_path + + origin = FileUploader.dynamic_path_segment(project) + project.storage_version = ::Project::HASHED_STORAGE_FEATURES[:attachments] + target = FileUploader.dynamic_path_segment(project) + + result = move_folder!(origin, target) + project.save! + + if result && block_given? + yield + end + + result + end + + private + + def move_folder!(old_path, new_path) + unless File.directory?(old_path) + logger.info("Skipped attachments migration from '#{old_path}' to '#{new_path}', source path doesn't exist or is not a directory (PROJECT_ID=#{project.id})") + return + end + + if File.exist?(new_path) + logger.error("Cannot migrate attachments from '#{old_path}' to '#{new_path}', target path already exist (PROJECT_ID=#{project.id})") + raise AttachmentMigrationError, "Target path '#{new_path}' already exist" + end + + # Create hashed storage base path folder + FileUtils.mkdir_p(File.dirname(new_path)) + + FileUtils.mv(old_path, new_path) + logger.info("Migrated project attachments from '#{old_path}' to '#{new_path}' (PROJECT_ID=#{project.id})") + + true + end + end + end +end diff --git a/app/services/projects/hashed_storage/migrate_repository_service.rb b/app/services/projects/hashed_storage/migrate_repository_service.rb new file mode 100644 index 00000000000..7212e7524ab --- /dev/null +++ b/app/services/projects/hashed_storage/migrate_repository_service.rb @@ -0,0 +1,70 @@ +module Projects + module HashedStorage + class MigrateRepositoryService < BaseService + include Gitlab::ShellAdapter + + attr_reader :old_disk_path, :new_disk_path, :old_wiki_disk_path, :old_storage_version, :logger + + def initialize(project, logger = nil) + @project = project + @logger = logger || Rails.logger + end + + def execute + @old_disk_path = project.disk_path + has_wiki = project.wiki.repository_exists? + + @old_storage_version = project.storage_version + project.storage_version = ::Project::HASHED_STORAGE_FEATURES[:repository] + project.ensure_storage_path_exists + + @new_disk_path = project.disk_path + + result = move_repository(@old_disk_path, @new_disk_path) + + if has_wiki + @old_wiki_disk_path = "#{@old_disk_path}.wiki" + result &&= move_repository("#{@old_wiki_disk_path}", "#{@new_disk_path}.wiki") + end + + unless result + rollback_folder_move + project.storage_version = nil + end + + project.repository_read_only = false + project.save! + + if result && block_given? + yield + end + + result + end + + private + + def move_repository(from_name, to_name) + from_exists = gitlab_shell.exists?(project.repository_storage_path, "#{from_name}.git") + to_exists = gitlab_shell.exists?(project.repository_storage_path, "#{to_name}.git") + + # If we don't find the repository on either original or target we should log that as it could be an issue if the + # project was not originally empty. + if !from_exists && !to_exists + logger.warn "Can't find a repository on either source or target paths for #{project.full_path} (ID=#{project.id}) ..." + return false + elsif !from_exists + # Repository have been moved already. + return true + end + + gitlab_shell.mv_repository(project.repository_storage_path, from_name, to_name) + end + + def rollback_folder_move + move_repository(@new_disk_path, @old_disk_path) + move_repository("#{@new_disk_path}.wiki", "#{@old_disk_path}.wiki") + end + end + end +end diff --git a/app/services/projects/hashed_storage_migration_service.rb b/app/services/projects/hashed_storage_migration_service.rb index f5945f3b87f..662702c1db5 100644 --- a/app/services/projects/hashed_storage_migration_service.rb +++ b/app/services/projects/hashed_storage_migration_service.rb @@ -1,68 +1,22 @@ module Projects class HashedStorageMigrationService < BaseService - include Gitlab::ShellAdapter - - attr_reader :old_disk_path, :new_disk_path + attr_reader :logger def initialize(project, logger = nil) @project = project - @logger ||= Rails.logger + @logger = logger || Rails.logger end def execute - return if project.hashed_storage?(:repository) - - @old_disk_path = project.disk_path - has_wiki = project.wiki.repository_exists? - - project.storage_version = Storage::HashedProject::STORAGE_VERSION - project.ensure_storage_path_exists - - @new_disk_path = project.disk_path - - result = move_repository(@old_disk_path, @new_disk_path) - - if has_wiki - result &&= move_repository("#{@old_disk_path}.wiki", "#{@new_disk_path}.wiki") - end - - unless result - rollback_folder_move - return + # Migrate repository from Legacy to Hashed Storage + unless project.hashed_storage?(:repository) + return unless HashedStorage::MigrateRepositoryService.new(project, logger).execute end - project.repository_read_only = false - project.save! - - block_given? ? yield : result - end - - private - - def move_repository(from_name, to_name) - from_exists = gitlab_shell.exists?(project.repository_storage_path, "#{from_name}.git") - to_exists = gitlab_shell.exists?(project.repository_storage_path, "#{to_name}.git") - - # If we don't find the repository on either original or target we should log that as it could be an issue if the - # project was not originally empty. - if !from_exists && !to_exists - logger.warn "Can't find a repository on either source or target paths for #{project.full_path} (ID=#{project.id}) ..." - return false - elsif !from_exists - # Repository have been moved already. - return true + # Migrate attachments from Legacy to Hashed Storage + unless project.hashed_storage?(:attachments) + HashedStorage::MigrateAttachmentsService.new(project, logger).execute end - - gitlab_shell.mv_repository(project.repository_storage_path, from_name, to_name) - end - - def rollback_folder_move - move_repository(@new_disk_path, @old_disk_path) - move_repository("#{@new_disk_path}.wiki", "#{@old_disk_path}.wiki") - end - - def logger - @logger end end end diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb index 13e292a18bf..72eecc61c96 100644 --- a/app/services/projects/update_service.rb +++ b/app/services/projects/update_service.rb @@ -15,7 +15,7 @@ module Projects return error("Could not set the default branch") unless project.change_head(params[:default_branch]) end - if project.update_attributes(params.except(:default_branch)) + if project.update_attributes(update_params) if project.previous_changes.include?('path') project.rename_repo else @@ -31,8 +31,16 @@ module Projects end end + def run_auto_devops_pipeline? + params.dig(:run_auto_devops_pipeline_explicit) == 'true' || params.dig(:run_auto_devops_pipeline_implicit) == 'true' + end + private + def update_params + params.except(:default_branch, :run_auto_devops_pipeline_explicit, :run_auto_devops_pipeline_implicit) + end + def renaming_project_with_container_registry_tags? new_path = params[:path] |