summaryrefslogtreecommitdiff
path: root/app/services/projects
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 15:40:28 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 15:40:28 +0000
commitb595cb0c1dec83de5bdee18284abe86614bed33b (patch)
tree8c3d4540f193c5ff98019352f554e921b3a41a72 /app/services/projects
parent2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff)
downloadgitlab-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.rb13
-rw-r--r--app/services/projects/blame_service.rb9
-rw-r--r--app/services/projects/create_service.rb12
-rw-r--r--app/services/projects/destroy_service.rb41
-rw-r--r--app/services/projects/fork_service.rb16
-rw-r--r--app/services/projects/group_links/update_service.rb2
-rw-r--r--app/services/projects/move_deploy_keys_projects_service.rb11
-rw-r--r--app/services/projects/operations/update_service.rb10
-rw-r--r--app/services/projects/update_pages_service.rb143
-rw-r--r--app/services/projects/update_service.rb16
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