diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-18 00:07:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-18 00:07:42 +0000 |
commit | c8ccf45aa0aa17413b107f9bbf9d6f160eaa8779 (patch) | |
tree | 77b07d805562786cf9b218e25e0ed18fae396448 /app | |
parent | 360ee1db0bf3bba2fc7aad7f230ec80829561227 (diff) | |
download | gitlab-ce-c8ccf45aa0aa17413b107f9bbf9d6f160eaa8779.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
18 files changed, 89 insertions, 21 deletions
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue index d03de91ea07..6695c6179cf 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue +++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue @@ -70,10 +70,12 @@ export default { }, update(data) { const { pipelineSchedules: { nodes: list = [], count } = {} } = data.project || {}; + const currentUser = data.currentUser || {}; return { list, count, + currentUser, }; }, error() { @@ -279,6 +281,7 @@ export default { <pipeline-schedules-table v-else :schedules="schedules.list" + :current-user="schedules.currentUser" @showTakeOwnershipModal="setTakeOwnershipModal" @showDeleteModal="setDeleteModal" @playPipelineSchedule="playPipelineSchedule" diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue b/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue index 45b4f618e17..5bd58bfd95d 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue +++ b/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue @@ -23,13 +23,20 @@ export default { type: Object, required: true, }, + currentUser: { + type: Object, + required: true, + }, }, computed: { canPlay() { return this.schedule.userPermissions.playPipelineSchedule; }, + isCurrentUserOwner() { + return this.schedule.owner.username === this.currentUser.username; + }, canTakeOwnership() { - return this.schedule.userPermissions.takeOwnershipPipelineSchedule; + return !this.isCurrentUserOwner && this.schedule.userPermissions.adminPipelineSchedule; }, canUpdate() { return this.schedule.userPermissions.updatePipelineSchedule; diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue b/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue index e8cfc5b29f3..0b95e2037e8 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue +++ b/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue @@ -59,6 +59,10 @@ export default { type: Array, required: true, }, + currentUser: { + type: Object, + required: true, + }, }, }; </script> @@ -94,6 +98,7 @@ export default { <template #cell(actions)="{ item }"> <pipeline-schedule-actions :schedule="item" + :current-user="currentUser" @showTakeOwnershipModal="$emit('showTakeOwnershipModal', $event)" @showDeleteModal="$emit('showDeleteModal', $event)" @playPipelineSchedule="$emit('playPipelineSchedule', $event)" diff --git a/app/assets/javascripts/ci/pipeline_schedules/graphql/queries/get_pipeline_schedules.query.graphql b/app/assets/javascripts/ci/pipeline_schedules/graphql/queries/get_pipeline_schedules.query.graphql index 9f6cb429cca..6167c7dc577 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/graphql/queries/get_pipeline_schedules.query.graphql +++ b/app/assets/javascripts/ci/pipeline_schedules/graphql/queries/get_pipeline_schedules.query.graphql @@ -1,4 +1,8 @@ query getPipelineSchedulesQuery($projectPath: ID!, $status: PipelineScheduleStatus) { + currentUser { + id + username + } project(fullPath: $projectPath) { id pipelineSchedules(status: $status) { @@ -25,13 +29,13 @@ query getPipelineSchedulesQuery($projectPath: ID!, $status: PipelineScheduleStat realNextRun owner { id + username avatarUrl name webPath } userPermissions { playPipelineSchedule - takeOwnershipPipelineSchedule updatePipelineSchedule adminPipelineSchedule } diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index bbc62c03957..fb332fec3b5 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -8,8 +8,7 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController before_action :authorize_read_pipeline_schedule! before_action :authorize_create_pipeline_schedule!, only: [:new, :create] before_action :authorize_update_pipeline_schedule!, only: [:edit, :update] - before_action :authorize_take_ownership_pipeline_schedule!, only: [:take_ownership] - before_action :authorize_admin_pipeline_schedule!, only: [:destroy] + before_action :authorize_admin_pipeline_schedule!, only: [:take_ownership, :destroy] before_action :push_schedule_feature_flag, only: [:index, :new, :edit] feature_category :continuous_integration @@ -111,10 +110,6 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController return access_denied! unless can?(current_user, :update_pipeline_schedule, schedule) end - def authorize_take_ownership_pipeline_schedule! - return access_denied! unless can?(current_user, :take_ownership_pipeline_schedule, schedule) - end - def authorize_admin_pipeline_schedule! return access_denied! unless can?(current_user, :admin_pipeline_schedule, schedule) end diff --git a/app/graphql/mutations/ci/pipeline_schedule/take_ownership.rb b/app/graphql/mutations/ci/pipeline_schedule/take_ownership.rb index 2e4312f0045..d71ef738cab 100644 --- a/app/graphql/mutations/ci/pipeline_schedule/take_ownership.rb +++ b/app/graphql/mutations/ci/pipeline_schedule/take_ownership.rb @@ -6,7 +6,7 @@ module Mutations class TakeOwnership < Base graphql_name 'PipelineScheduleTakeOwnership' - authorize :take_ownership_pipeline_schedule + authorize :admin_pipeline_schedule field :pipeline_schedule, Types::Ci::PipelineScheduleType, diff --git a/app/graphql/types/permission_types/ci/pipeline_schedules.rb b/app/graphql/types/permission_types/ci/pipeline_schedules.rb index 268ac6096d0..dd9d94aa578 100644 --- a/app/graphql/types/permission_types/ci/pipeline_schedules.rb +++ b/app/graphql/types/permission_types/ci/pipeline_schedules.rb @@ -6,11 +6,16 @@ module Types class PipelineSchedules < BasePermissionType graphql_name 'PipelineSchedulePermissions' - abilities :take_ownership_pipeline_schedule, - :update_pipeline_schedule, + abilities :update_pipeline_schedule, :admin_pipeline_schedule ability_field :play_pipeline_schedule, calls_gitaly: true + ability_field :take_ownership_pipeline_schedule, + deprecated: { + reason: 'Use admin_pipeline_schedule permission to determine if the user can take ownership ' \ + 'of a pipeline schedule', + milestone: '15.9' + } end end end diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index f8b3777841d..4f3ba55452e 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -55,7 +55,9 @@ module Ci has_one :"job_artifacts_#{key}", -> { where(file_type: value) }, class_name: 'Ci::JobArtifact', foreign_key: :job_id, inverse_of: :job end - has_one :runner_machine, through: :metadata, class_name: 'Ci::RunnerMachine' + has_one :runner_machine_build, class_name: 'Ci::RunnerMachineBuild', foreign_key: :build_id, inverse_of: :build, + autosave: true + has_one :runner_machine, through: :runner_machine_build, class_name: 'Ci::RunnerMachine' has_one :runner_session, class_name: 'Ci::BuildRunnerSession', validate: true, foreign_key: :build_id, inverse_of: :build has_one :trace_metadata, class_name: 'Ci::BuildTraceMetadata', foreign_key: :build_id, inverse_of: :build diff --git a/app/models/ci/build_metadata.rb b/app/models/ci/build_metadata.rb index b294afd405d..4c723bb7c0c 100644 --- a/app/models/ci/build_metadata.rb +++ b/app/models/ci/build_metadata.rb @@ -18,7 +18,6 @@ module Ci belongs_to :build, class_name: 'CommitStatus' belongs_to :project - belongs_to :runner_machine, class_name: 'Ci::RunnerMachine' before_create :set_build_project diff --git a/app/models/ci/runner_machine.rb b/app/models/ci/runner_machine.rb index e52659a011f..537ef79b921 100644 --- a/app/models/ci/runner_machine.rb +++ b/app/models/ci/runner_machine.rb @@ -10,12 +10,12 @@ module Ci ignore_column :machine_xid, remove_with: '15.11', remove_after: '2022-03-22' # The `UPDATE_CONTACT_COLUMN_EVERY` defines how often the Runner Machine DB entry can be updated - UPDATE_CONTACT_COLUMN_EVERY = 40.minutes..55.minutes + UPDATE_CONTACT_COLUMN_EVERY = (40.minutes)..(55.minutes) belongs_to :runner - has_many :build_metadata, class_name: 'Ci::BuildMetadata' - has_many :builds, through: :build_metadata, class_name: 'Ci::Build' + has_many :runner_machine_builds, inverse_of: :runner_machine, class_name: 'Ci::RunnerMachineBuild' + has_many :builds, through: :runner_machine_builds, class_name: 'Ci::Build' belongs_to :runner_version, inverse_of: :runner_machines, primary_key: :version, foreign_key: :version, class_name: 'Ci::RunnerVersion' diff --git a/app/models/ci/runner_machine_build.rb b/app/models/ci/runner_machine_build.rb new file mode 100644 index 00000000000..2e0a6a76bcc --- /dev/null +++ b/app/models/ci/runner_machine_build.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Ci + class RunnerMachineBuild < Ci::ApplicationRecord + include Ci::Partitionable + include PartitionedTable + + self.table_name = :p_ci_runner_machine_builds + self.primary_key = :build_id + + partitionable scope: :build + partitioned_by :partition_id, + strategy: :ci_sliding_list, + next_partition_if: -> { false }, + detach_partition_if: -> { false } + + belongs_to :build, inverse_of: :runner_machine_build, class_name: 'Ci::Build' + belongs_to :runner_machine, inverse_of: :runner_machine_builds, class_name: 'Ci::RunnerMachine' + + validates :build, presence: true + validates :runner_machine, presence: true + end +end diff --git a/app/models/concerns/cascading_namespace_setting_attribute.rb b/app/models/concerns/cascading_namespace_setting_attribute.rb index 731729a1ed5..d0ee4f33ce6 100644 --- a/app/models/concerns/cascading_namespace_setting_attribute.rb +++ b/app/models/concerns/cascading_namespace_setting_attribute.rb @@ -57,11 +57,13 @@ module CascadingNamespaceSettingAttribute # private methods define_validator_methods(attribute) + define_attr_before_save(attribute) define_after_update(attribute) validate :"#{attribute}_changeable?" validate :"lock_#{attribute}_changeable?" + before_save :"before_save_#{attribute}", if: -> { will_save_change_to_attribute?(attribute) } after_update :"clear_descendant_#{attribute}_locks", if: -> { saved_change_to_attribute?("lock_#{attribute}", to: true) } end end @@ -92,13 +94,26 @@ module CascadingNamespaceSettingAttribute def define_attr_writer(attribute) define_method("#{attribute}=") do |value| - return value if value == cascaded_ancestor_value(attribute) + return value if read_attribute(attribute).nil? && to_bool(value) == cascaded_ancestor_value(attribute) clear_memoization(attribute) super(value) end end + def define_attr_before_save(attribute) + # rubocop:disable GitlabSecurity/PublicSend + define_method("before_save_#{attribute}") do + new_value = public_send(attribute) + if public_send("#{attribute}_was").nil? && new_value == cascaded_ancestor_value(attribute) + write_attribute(attribute, nil) + end + end + # rubocop:enable GitlabSecurity/PublicSend + + private :"before_save_#{attribute}" + end + def define_lock_attr_writer(attribute) define_method("lock_#{attribute}=") do |value| attr_value = public_send(attribute) # rubocop:disable GitlabSecurity/PublicSend @@ -239,4 +254,8 @@ module CascadingNamespaceSettingAttribute namespace.descendants.pluck(:id) end end + + def to_bool(value) + ActiveModel::Type::Boolean.new.cast(value) + end end diff --git a/app/models/concerns/ci/partitionable.rb b/app/models/concerns/ci/partitionable.rb index d6ba0f4488f..246f254576f 100644 --- a/app/models/concerns/ci/partitionable.rb +++ b/app/models/concerns/ci/partitionable.rb @@ -36,6 +36,7 @@ module Ci Ci::Pipeline Ci::PendingBuild Ci::RunningBuild + Ci::RunnerMachineBuild Ci::PipelineVariable Ci::Sources::Pipeline Ci::Stage diff --git a/app/models/concerns/partitioned_table.rb b/app/models/concerns/partitioned_table.rb index f95f9dd8ad7..c322a736e79 100644 --- a/app/models/concerns/partitioned_table.rb +++ b/app/models/concerns/partitioned_table.rb @@ -8,7 +8,8 @@ module PartitionedTable PARTITIONING_STRATEGIES = { monthly: Gitlab::Database::Partitioning::MonthlyStrategy, - sliding_list: Gitlab::Database::Partitioning::SlidingListStrategy + sliding_list: Gitlab::Database::Partitioning::SlidingListStrategy, + ci_sliding_list: Gitlab::Database::Partitioning::CiSlidingListStrategy }.freeze def partitioned_by(partitioning_key, strategy:, **kwargs) diff --git a/app/policies/ci/pipeline_schedule_policy.rb b/app/policies/ci/pipeline_schedule_policy.rb index 3a674bfef92..7b0d484f9f7 100644 --- a/app/policies/ci/pipeline_schedule_policy.rb +++ b/app/policies/ci/pipeline_schedule_policy.rb @@ -23,6 +23,10 @@ module Ci enable :update_pipeline_schedule end + # `take_ownership_pipeline_schedule` is deprecated, and should not be used. It can be removed in 17.0 + # once the deprecated field `take_ownership_pipeline_schedule` is removed from the GraphQL type + # `PermissionTypes::Ci::PipelineSchedules`. + # Use `admin_pipeline_schedule` to decide if a user has the ability to take ownership of a pipeline schedule. rule { can?(:admin_pipeline_schedule) & ~owner_of_schedule }.policy do enable :take_ownership_pipeline_schedule end diff --git a/app/services/ci/pipeline_schedules/take_ownership_service.rb b/app/services/ci/pipeline_schedules/take_ownership_service.rb index 9b4001c74bd..b4d193cb875 100644 --- a/app/services/ci/pipeline_schedules/take_ownership_service.rb +++ b/app/services/ci/pipeline_schedules/take_ownership_service.rb @@ -23,7 +23,7 @@ module Ci attr_reader :schedule, :user def allowed? - user.can?(:take_ownership_pipeline_schedule, schedule) + user.can?(:admin_pipeline_schedule, schedule) end def forbidden diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb index 205da2632c2..8db96ea47c2 100644 --- a/app/services/ci/register_job_service.rb +++ b/app/services/ci/register_job_service.rb @@ -244,7 +244,7 @@ module Ci def assign_runner!(build, params) build.runner_id = runner.id build.runner_session_attributes = params[:session] if params[:session].present? - build.ensure_metadata.runner_machine = runner_machine if runner_machine + build.runner_machine = runner_machine if runner_machine failure_reason, _ = pre_assign_runner_checks.find { |_, check| check.call(build, params) } diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml index 0de31f59033..37b2b3ecfde 100644 --- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml +++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml @@ -37,7 +37,7 @@ - if can?(current_user, :play_pipeline_schedule, pipeline_schedule) = link_to play_pipeline_schedule_path(pipeline_schedule), method: :post, title: _('Play'), class: 'btn gl-button btn-default btn-icon' do = sprite_icon('play') - - if can?(current_user, :take_ownership_pipeline_schedule, pipeline_schedule) + - if can?(current_user, :admin_pipeline_schedule, pipeline_schedule) && pipeline_schedule.owner != current_user = render Pajamas::ButtonComponent.new(button_options: { class: 'js-take-ownership-button has-tooltip', title: s_('PipelineSchedule|Take ownership to edit'), data: { url: take_ownership_pipeline_schedule_path(pipeline_schedule) } }) do = s_('PipelineSchedules|Take ownership') - if can?(current_user, :update_pipeline_schedule, pipeline_schedule) |