diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/projects/alerting/notify_service.rb | 49 | ||||
-rw-r--r-- | app/services/projects/container_repository/delete_tags_service.rb | 24 | ||||
-rw-r--r-- | app/services/projects/lsif_data_service.rb | 46 |
3 files changed, 109 insertions, 10 deletions
diff --git a/app/services/projects/alerting/notify_service.rb b/app/services/projects/alerting/notify_service.rb new file mode 100644 index 00000000000..4ca3b154e4b --- /dev/null +++ b/app/services/projects/alerting/notify_service.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Projects + module Alerting + class NotifyService < BaseService + include Gitlab::Utils::StrongMemoize + + def execute(token) + return forbidden unless alerts_service_activated? + return unauthorized unless valid_token?(token) + + process_incident_issues + + ServiceResponse.success + rescue Gitlab::Alerting::NotificationPayloadParser::BadPayloadError + bad_request + end + + private + + delegate :alerts_service, :alerts_service_activated?, to: :project + + def process_incident_issues + IncidentManagement::ProcessAlertWorker + .perform_async(project.id, parsed_payload) + end + + def parsed_payload + Gitlab::Alerting::NotificationPayloadParser.call(params.to_h) + end + + def valid_token?(token) + token == alerts_service.token + end + + def bad_request + ServiceResponse.error(message: 'Bad Request', http_status: 400) + end + + def unauthorized + ServiceResponse.error(message: 'Unauthorized', http_status: 401) + end + + def forbidden + ServiceResponse.error(message: 'Forbidden', http_status: 403) + end + end + end +end diff --git a/app/services/projects/container_repository/delete_tags_service.rb b/app/services/projects/container_repository/delete_tags_service.rb index 88ff3c2c9df..d19f275e928 100644 --- a/app/services/projects/container_repository/delete_tags_service.rb +++ b/app/services/projects/container_repository/delete_tags_service.rb @@ -14,12 +14,25 @@ module Projects private + # Delete tags by name with a single DELETE request. This is only supported + # by the GitLab Container Registry fork. See + # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23325 for details. + def fast_delete(container_repository, tag_names) + deleted_tags = tag_names.select do |name| + container_repository.delete_tag_by_name(name) + end + + deleted_tags.any? ? success(deleted: deleted_tags) : error('could not delete tags') + end + # Replace a tag on the registry with a dummy tag. # This is a hack as the registry doesn't support deleting individual # tags. This code effectively pushes a dummy image and assigns the tag to it. # This way when the tag is deleted only the dummy image is affected. + # This is used to preverse compatibility with third-party registries that + # don't support fast delete. # See https://gitlab.com/gitlab-org/gitlab/issues/15737 for a discussion - def smart_delete(container_repository, tag_names) + def slow_delete(container_repository, tag_names) # generates the blobs for the dummy image dummy_manifest = container_repository.client.generate_empty_manifest(container_repository.path) return error('could not generate manifest') if dummy_manifest.nil? @@ -36,6 +49,15 @@ module Projects end end + def smart_delete(container_repository, tag_names) + fast_delete_enabled = Feature.enabled?(:container_registry_fast_tag_delete, default_enabled: true) + if fast_delete_enabled && container_repository.client.supports_tag_delete? + fast_delete(container_repository, tag_names) + else + slow_delete(container_repository, tag_names) + end + end + # update the manifests of the tags with the new dummy image def replace_tag_manifests(container_repository, dummy_manifest, tag_names) deleted_tags = {} diff --git a/app/services/projects/lsif_data_service.rb b/app/services/projects/lsif_data_service.rb index 00103f364bf..1282a0736e7 100644 --- a/app/services/projects/lsif_data_service.rb +++ b/app/services/projects/lsif_data_service.rb @@ -2,7 +2,8 @@ module Projects class LsifDataService - attr_reader :file, :project, :path, :commit_id + attr_reader :file, :project, :path, :commit_id, + :docs, :doc_ranges, :ranges, :def_refs CACHE_EXPIRE_IN = 1.hour @@ -14,19 +15,18 @@ module Projects end def execute - docs, doc_ranges, ranges = - fetch_data.values_at('docs', 'doc_ranges', 'ranges') - - doc_id = doc_id_from(docs) + fetch_data! doc_ranges[doc_id]&.map do |range_id| - line_data, column_data = ranges[range_id]['loc'] + location, ref_id = ranges[range_id].values_at('loc', 'ref_id') + line_data, column_data = location { start_line: line_data.first, end_line: line_data.last, start_char: column_data.first, - end_char: column_data.last + end_char: column_data.last, + definition_url: definition_url_for(def_refs[ref_id]) } end end @@ -47,8 +47,17 @@ module Projects end end - def doc_id_from(docs) - docs.reduce(nil) do |doc_id, (id, doc_path)| + def fetch_data! + data = fetch_data + + @docs = data['docs'] + @doc_ranges = data['doc_ranges'] + @ranges = data['ranges'] + @def_refs = data['def_refs'] + end + + def doc_id + @doc_id ||= docs.reduce(nil) do |doc_id, (id, doc_path)| next doc_id unless doc_path =~ /#{path}$/ if doc_id.nil? || docs[doc_id].size > doc_path.size @@ -58,5 +67,24 @@ module Projects doc_id end end + + def dir_absolute_path + @dir_absolute_path ||= docs[doc_id]&.delete_suffix(path) + end + + def definition_url_for(ref_id) + return unless range = ranges[ref_id] + + def_doc_id, location = range.values_at('doc_id', 'loc') + localized_doc_url = docs[def_doc_id].delete_prefix(dir_absolute_path) + + # location is stored as [[start_line, end_line], [start_char, end_char]] + start_line = location.first.first + + line_anchor = "L#{start_line + 1}" + definition_ref_path = [commit_id, localized_doc_url].join('/') + + Gitlab::Routing.url_helpers.project_blob_path(project, definition_ref_path, anchor: line_anchor) + end end end |