diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-07-20 15:40:28 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-07-20 15:40:28 +0000 |
commit | b595cb0c1dec83de5bdee18284abe86614bed33b (patch) | |
tree | 8c3d4540f193c5ff98019352f554e921b3a41a72 /app/services/projects | |
parent | 2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff) | |
download | gitlab-ce-b595cb0c1dec83de5bdee18284abe86614bed33b.tar.gz |
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'app/services/projects')
-rw-r--r-- | app/services/projects/after_rename_service.rb | 13 | ||||
-rw-r--r-- | app/services/projects/blame_service.rb | 9 | ||||
-rw-r--r-- | app/services/projects/create_service.rb | 12 | ||||
-rw-r--r-- | app/services/projects/destroy_service.rb | 41 | ||||
-rw-r--r-- | app/services/projects/fork_service.rb | 16 | ||||
-rw-r--r-- | app/services/projects/group_links/update_service.rb | 2 | ||||
-rw-r--r-- | app/services/projects/move_deploy_keys_projects_service.rb | 11 | ||||
-rw-r--r-- | app/services/projects/operations/update_service.rb | 10 | ||||
-rw-r--r-- | app/services/projects/update_pages_service.rb | 143 | ||||
-rw-r--r-- | app/services/projects/update_service.rb | 16 |
10 files changed, 130 insertions, 143 deletions
diff --git a/app/services/projects/after_rename_service.rb b/app/services/projects/after_rename_service.rb index 2ed4346e5ca..9dc957b5be2 100644 --- a/app/services/projects/after_rename_service.rb +++ b/app/services/projects/after_rename_service.rb @@ -46,6 +46,7 @@ module Projects update_repository_configuration rename_transferred_documents log_completion + publish_event end def first_ensure_no_registry_tags_are_present @@ -132,6 +133,18 @@ module Projects raise RenameFailedError, error end + + def publish_event + event = Projects::ProjectPathChangedEvent.new(data: { + project_id: project.id, + namespace_id: project.namespace_id, + root_namespace_id: project.root_namespace.id, + old_path: full_path_before, + new_path: full_path_after + }) + + Gitlab::EventStore.publish(event) + end end end diff --git a/app/services/projects/blame_service.rb b/app/services/projects/blame_service.rb index f7c1240a3ba..b324ea27360 100644 --- a/app/services/projects/blame_service.rb +++ b/app/services/projects/blame_service.rb @@ -12,6 +12,8 @@ module Projects @page = extract_page(params) end + attr_reader :page + def blame Gitlab::Blame.new(blob, commit, range: blame_range) end @@ -19,15 +21,14 @@ module Projects def pagination return unless pagination_enabled? - Kaminari.paginate_array([], total_count: blob_lines_count) + Kaminari.paginate_array([], total_count: blob_lines_count, limit: per_page) + .tap { |pagination| pagination.max_paginates_per(per_page) } .page(page) - .per(per_page) - .limit(per_page) end private - attr_reader :blob, :commit, :page + attr_reader :blob, :commit def blame_range return unless pagination_enabled? diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index c7f284bec9b..9bc8bb428fb 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -129,6 +129,8 @@ module Projects create_readme if @initialize_with_readme create_sast_commit if @initialize_with_sast + + publish_event end def create_project_settings @@ -294,6 +296,16 @@ module Projects params[:topic_list] ||= topic_list if topic_list end + + def publish_event + event = Projects::ProjectCreatedEvent.new(data: { + project_id: project.id, + namespace_id: project.namespace_id, + root_namespace_id: project.root_namespace.id + }) + + Gitlab::EventStore.publish(event) + end end end diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index bc5be5bdff3..06a44b07f9f 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -132,7 +132,7 @@ module Projects destroy_web_hooks! destroy_project_bots! destroy_ci_records! - destroy_mr_diff_commits! + destroy_mr_diff_relations! # Rails attempts to load all related records into memory before # destroying: https://github.com/rails/rails/issues/22510 @@ -153,23 +153,28 @@ module Projects # cascading deletes may exceed statement timeouts, causing failures. # (see https://gitlab.com/gitlab-org/gitlab/-/issues/346166) # + # Removing merge_request_diff_files records may also cause timeouts, so they + # can be deleted in batches as well. + # # rubocop: disable CodeReuse/ActiveRecord - def destroy_mr_diff_commits! + def destroy_mr_diff_relations! mr_batch_size = 100 delete_batch_size = 1000 project.merge_requests.each_batch(column: :iid, of: mr_batch_size) do |relation_ids| - loop do - inner_query = MergeRequestDiffCommit - .select(:merge_request_diff_id, :relative_order) - .where(merge_request_diff_id: MergeRequestDiff.where(merge_request_id: relation_ids).select(:id)) - .limit(delete_batch_size) - - deleted_rows = MergeRequestDiffCommit - .where('(merge_request_diff_commits.merge_request_diff_id, merge_request_diff_commits.relative_order) IN (?)', inner_query) - .delete_all - - break if deleted_rows == 0 + [MergeRequestDiffCommit, MergeRequestDiffFile].each do |model| + loop do + inner_query = model + .select(:merge_request_diff_id, :relative_order) + .where(merge_request_diff_id: MergeRequestDiff.where(merge_request_id: relation_ids).select(:id)) + .limit(delete_batch_size) + + deleted_rows = model + .where("(#{model.table_name}.merge_request_diff_id, #{model.table_name}.relative_order) IN (?)", inner_query) # rubocop:disable GitlabSecurity/SqlInjection + .delete_all + + break if deleted_rows == 0 + end end end end @@ -212,7 +217,7 @@ module Projects # produces smaller and faster queries to the database. def destroy_web_hooks! project.hooks.find_each do |web_hook| - result = ::WebHooks::DestroyService.new(current_user).sync_destroy(web_hook) + result = ::WebHooks::DestroyService.new(current_user).execute(web_hook) unless result[:status] == :success raise_error(s_('DeleteProject|Failed to remove webhooks. Please try again or contact administrator.')) @@ -263,8 +268,12 @@ module Projects end def publish_project_deleted_event_for(project) - data = { project_id: project.id, namespace_id: project.namespace_id } - event = Projects::ProjectDeletedEvent.new(data: data) + event = Projects::ProjectDeletedEvent.new(data: { + project_id: project.id, + namespace_id: project.namespace_id, + root_namespace_id: project.root_namespace.id + }) + Gitlab::EventStore.publish(event) end end diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index 3e8d6563709..70a04cd556a 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -5,7 +5,10 @@ module Projects def execute(fork_to_project = nil) forked_project = fork_to_project ? link_existing_project(fork_to_project) : fork_new_project - refresh_forks_count if forked_project&.saved? + if forked_project&.saved? + refresh_forks_count + stream_audit_event(forked_project) + end forked_project end @@ -62,7 +65,10 @@ module Projects # exception. relations_block: -> (project) { build_fork_network_member(project) }, skip_disk_validation: skip_disk_validation, - external_authorization_classification_label: @project.external_authorization_classification_label + external_authorization_classification_label: @project.external_authorization_classification_label, + suggestion_commit_message: @project.suggestion_commit_message, + merge_commit_template: @project.merge_commit_template, + squash_commit_template: @project.squash_commit_template } if @project.avatar.present? && @project.avatar.image? @@ -133,5 +139,11 @@ module Projects def target_mr_default_target_self @target_mr_default_target_self ||= params[:mr_default_target_self] end + + def stream_audit_event(forked_project) + # Defined in EE + end end end + +Projects::ForkService.prepend_mod diff --git a/app/services/projects/group_links/update_service.rb b/app/services/projects/group_links/update_service.rb index a836b96cac3..c271b0a2307 100644 --- a/app/services/projects/group_links/update_service.rb +++ b/app/services/projects/group_links/update_service.rb @@ -37,3 +37,5 @@ module Projects end end end + +Projects::GroupLinks::UpdateService.prepend_mod diff --git a/app/services/projects/move_deploy_keys_projects_service.rb b/app/services/projects/move_deploy_keys_projects_service.rb index 98ba5eb3f13..a45b78db383 100644 --- a/app/services/projects/move_deploy_keys_projects_service.rb +++ b/app/services/projects/move_deploy_keys_projects_service.rb @@ -5,6 +5,10 @@ module Projects def execute(source_project, remove_remaining_elements: true) return unless super + # The SHA256 fingerprint should be there, but just in case it isn't + # we want to make sure it's generated. Otherwise we might delete keys. + ensure_sha256_fingerprints + Project.transaction do move_deploy_keys_projects remove_remaining_deploy_keys_projects if remove_remaining_elements @@ -15,6 +19,11 @@ module Projects private + def ensure_sha256_fingerprints + @project.deploy_keys.each(&:ensure_sha256_fingerprint!) + source_project.deploy_keys.each(&:ensure_sha256_fingerprint!) + end + def move_deploy_keys_projects non_existent_deploy_keys_projects.update_all(project_id: @project.id) end @@ -23,7 +32,7 @@ module Projects def non_existent_deploy_keys_projects source_project.deploy_keys_projects .joins(:deploy_key) - .where.not(keys: { fingerprint: @project.deploy_keys.select(:fingerprint) }) + .where.not(keys: { fingerprint_sha256: @project.deploy_keys.select(:fingerprint_sha256) }) end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/services/projects/operations/update_service.rb b/app/services/projects/operations/update_service.rb index 7e4e0d7378e..b2166dc84c7 100644 --- a/app/services/projects/operations/update_service.rb +++ b/app/services/projects/operations/update_service.rb @@ -18,7 +18,6 @@ module Projects .merge(grafana_integration_params) .merge(prometheus_integration_params) .merge(incident_management_setting_params) - .merge(tracing_setting_params) end def alerting_setting_params @@ -132,15 +131,6 @@ module Projects { incident_management_setting_attributes: attrs } end - - def tracing_setting_params - attr = params[:tracing_setting_attributes] - return {} unless attr - - destroy = attr[:external_url].blank? - - { tracing_setting_attributes: attr.merge(_destroy: destroy) } - end end end end diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index 8ded2516b97..dd1c2b94e18 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -2,21 +2,17 @@ module Projects class UpdatePagesService < BaseService - InvalidStateError = Class.new(StandardError) - WrongUploadedDeploymentSizeError = Class.new(StandardError) - BLOCK_SIZE = 32.kilobytes - PUBLIC_DIR = 'public' - # old deployment can be cached by pages daemon # so we need to give pages daemon some time update cache # 10 minutes is enough, but 30 feels safer OLD_DEPLOYMENTS_DESTRUCTION_DELAY = 30.minutes.freeze - attr_reader :build + attr_reader :build, :deployment_update def initialize(project, build) @project = project @build = build + @deployment_update = ::Gitlab::Pages::DeploymentUpdate.new(project, build) end def execute @@ -29,20 +25,20 @@ module Projects job.run! end - validate_state! - validate_max_size! - validate_public_folder! - validate_max_entries! + return error(deployment_update.errors.first.full_message) unless deployment_update.valid? build.artifacts_file.use_file do |artifacts_path| - create_pages_deployment(artifacts_path, build) - success + deployment = create_pages_deployment(artifacts_path, build) + + break error('The uploaded artifact size does not match the expected value') unless deployment + + if deployment_update.valid? + update_project_pages_deployment(deployment) + success + else + error(deployment_update.errors.first.full_message) + end end - rescue InvalidStateError => e - error(e.message) - rescue WrongUploadedDeploymentSizeError => e - error("Uploading artifacts to pages storage failed") - raise e rescue StandardError => e error(e.message) raise e @@ -53,13 +49,14 @@ module Projects def success @commit_status.success @project.mark_pages_as_deployed + publish_deployed_event super end def error(message) register_failure log_error("Projects::UpdatePagesService: #{message}") - @commit_status.allow_failure = !latest? + @commit_status.allow_failure = !deployment_update.latest? @commit_status.description = message @commit_status.drop(:script_failure) super @@ -75,24 +72,22 @@ module Projects def create_pages_deployment(artifacts_path, build) sha256 = build.job_artifacts_archive.file_sha256 - - deployment = nil File.open(artifacts_path) do |file| - deployment = project.pages_deployments.create!(file: file, - file_count: entries_count, - file_sha256: sha256, - ci_build_id: build.id - ) - - if deployment.size != file.size || deployment.file.size != file.size - raise(WrongUploadedDeploymentSizeError) - end + deployment = project.pages_deployments.create!( + file: file, + file_count: deployment_update.entries_count, + file_sha256: sha256, + ci_build_id: build.id + ) - validate_outdated_sha! + break if deployment.size != file.size || deployment.file.size != file.size - project.update_pages_deployment!(deployment) + deployment end + end + def update_project_pages_deployment(deployment) + project.update_pages_deployment!(deployment) DestroyPagesDeploymentsWorker.perform_in( OLD_DEPLOYMENTS_DESTRUCTION_DELAY, project.id, @@ -108,17 +103,6 @@ module Projects build.artifacts_file.path end - def latest_sha - project.commit(build.ref).try(:sha).to_s - ensure - # Close any file descriptors that were opened and free libgit2 buffers - project.cleanup - end - - def sha - build.sha - end - def register_attempt pages_deployments_total_counter.increment end @@ -135,75 +119,14 @@ module Projects @pages_deployments_failed_total_counter ||= Gitlab::Metrics.counter(:pages_deployments_failed_total, "Counter of GitLab Pages deployments which failed") end - def validate_state! - raise InvalidStateError, 'missing pages artifacts' unless build.artifacts? - raise InvalidStateError, 'missing artifacts metadata' unless build.artifacts_metadata? - - validate_outdated_sha! - end - - def validate_outdated_sha! - return if latest? + def publish_deployed_event + event = ::Pages::PageDeployedEvent.new(data: { + project_id: project.id, + namespace_id: project.namespace_id, + root_namespace_id: project.root_namespace.id + }) - # use pipeline_id in case the build is retried - last_deployed_pipeline_id = project.pages_metadatum&.pages_deployment&.ci_build&.pipeline_id - - return unless last_deployed_pipeline_id - return if last_deployed_pipeline_id <= build.pipeline_id - - raise InvalidStateError, 'build SHA is outdated for this ref' - end - - def latest? - # check if sha for the ref is still the most recent one - # this helps in case when multiple deployments happens - sha == latest_sha - end - - def validate_max_size! - if total_size > max_size - raise InvalidStateError, "artifacts for pages are too large: #{total_size}" - end - end - - # Calculate page size after extract - def total_size - @total_size ||= build.artifacts_metadata_entry(PUBLIC_DIR + '/', recursive: true).total_size - end - - def max_size_from_settings - Gitlab::CurrentSettings.max_pages_size.megabytes - end - - def max_size - max_pages_size = max_size_from_settings - - return ::Gitlab::Pages::MAX_SIZE if max_pages_size == 0 - - max_pages_size - end - - def validate_max_entries! - if pages_file_entries_limit > 0 && entries_count > pages_file_entries_limit - raise InvalidStateError, "pages site contains #{entries_count} file entries, while limit is set to #{pages_file_entries_limit}" - end - end - - def validate_public_folder! - raise InvalidStateError, 'Error: The `public/` folder is missing, or not declared in `.gitlab-ci.yml`.' unless total_size > 0 - end - - def entries_count - # we're using the full archive and pages daemon needs to read it - # so we want the total count from entries, not only "public/" directory - # because it better approximates work we need to do before we can serve the site - @entries_count = build.artifacts_metadata_entry("", recursive: true).entries.count - end - - def pages_file_entries_limit - project.actual_limits.pages_file_entries + Gitlab::EventStore.publish(event) end end end - -Projects::UpdatePagesService.prepend_mod_with('Projects::UpdatePagesService') diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb index fb810af3e6b..5708421014a 100644 --- a/app/services/projects/update_service.rb +++ b/app/services/projects/update_service.rb @@ -10,6 +10,7 @@ module Projects def execute build_topics remove_unallowed_params + mirror_operations_access_level_changes validate! ensure_wiki_exists if enabling_wiki? @@ -82,6 +83,21 @@ module Projects params.delete(:emails_disabled) unless can?(current_user, :set_emails_disabled, project) end + # Temporary code to sync permissions changes as operations access setting + # is being split into monitor_access_level, deployments_access_level, infrastructure_access_level. + # To be removed as part of https://gitlab.com/gitlab-org/gitlab/-/issues/364240 + def mirror_operations_access_level_changes + return if Feature.enabled?(:split_operations_visibility_permissions, project) + + operations_access_level = params.dig(:project_feature_attributes, :operations_access_level) + + return if operations_access_level.nil? + + [:monitor_access_level, :infrastructure_access_level, :feature_flags_access_level, :environments_access_level].each do |key| + params[:project_feature_attributes][key] = operations_access_level + end + end + def after_update todos_features_changes = %w( issues_access_level |