From 90184b64bb3412cfd291b45c8997671cdb1ca95a Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Sat, 11 Jan 2020 15:07:49 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- app/models/ci/pipeline_schedule.rb | 10 +--------- app/models/concerns/schedulable.rb | 21 +++++++++++++++++++++ app/models/container_expiration_policy.rb | 11 +++++++++++ app/services/container_expiration_policy_service.rb | 15 +++++++++++++++ app/workers/all_queues.yml | 1 + app/workers/container_expiration_policy_worker.rb | 16 ++++++++++++++++ 6 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 app/models/concerns/schedulable.rb create mode 100644 app/services/container_expiration_policy_service.rb create mode 100644 app/workers/container_expiration_policy_worker.rb (limited to 'app') diff --git a/app/models/ci/pipeline_schedule.rb b/app/models/ci/pipeline_schedule.rb index 946241b7d4c..9a1445e624c 100644 --- a/app/models/ci/pipeline_schedule.rb +++ b/app/models/ci/pipeline_schedule.rb @@ -5,6 +5,7 @@ module Ci extend Gitlab::Ci::Model include Importable include StripAttribute + include Schedulable belongs_to :project belongs_to :owner, class_name: 'User' @@ -18,13 +19,10 @@ module Ci validates :description, presence: true validates :variables, variable_duplicates: true - before_save :set_next_run_at - strip_attributes :cron scope :active, -> { where(active: true) } scope :inactive, -> { where(active: false) } - scope :runnable_schedules, -> { active.where("next_run_at < ?", Time.now) } scope :preloaded, -> { preload(:owner, :project) } accepts_nested_attributes_for :variables, allow_destroy: true @@ -62,12 +60,6 @@ module Ci end end - def schedule_next_run! - save! # with set_next_run_at - rescue ActiveRecord::RecordInvalid - update_column(:next_run_at, nil) # update without validation - end - def job_variables variables&.map(&:to_runner_variable) || [] end diff --git a/app/models/concerns/schedulable.rb b/app/models/concerns/schedulable.rb new file mode 100644 index 00000000000..6fdca4f50c3 --- /dev/null +++ b/app/models/concerns/schedulable.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Schedulable + extend ActiveSupport::Concern + + included do + scope :runnable_schedules, -> { active.where("next_run_at < ?", Time.zone.now) } + + before_save :set_next_run_at + end + + def schedule_next_run! + save! # with set_next_run_at + rescue ActiveRecord::RecordInvalid + update_column(:next_run_at, nil) # update without validation + end + + def set_next_run_at + raise NotImplementedError + end +end diff --git a/app/models/container_expiration_policy.rb b/app/models/container_expiration_policy.rb index f60a0179c83..c929a78a7f9 100644 --- a/app/models/container_expiration_policy.rb +++ b/app/models/container_expiration_policy.rb @@ -1,14 +1,21 @@ # frozen_string_literal: true class ContainerExpirationPolicy < ApplicationRecord + include Schedulable + belongs_to :project, inverse_of: :container_expiration_policy + delegate :container_repositories, to: :project + validates :project, presence: true validates :enabled, inclusion: { in: [true, false] } validates :cadence, presence: true, inclusion: { in: ->(_) { self.cadence_options.stringify_keys } } validates :older_than, inclusion: { in: ->(_) { self.older_than_options.stringify_keys } }, allow_nil: true validates :keep_n, inclusion: { in: ->(_) { self.keep_n_options.keys } }, allow_nil: true + scope :active, -> { where(enabled: true) } + scope :preloaded, -> { preload(:project) } + def self.keep_n_options { 1 => _('%{tags} tag per image name') % { tags: 1 }, @@ -38,4 +45,8 @@ class ContainerExpirationPolicy < ApplicationRecord '90d': _('%{days} days until tags are automatically removed') % { days: 90 } } end + + def set_next_run_at + self.next_run_at = Time.zone.now + ChronicDuration.parse(cadence).seconds + end end diff --git a/app/services/container_expiration_policy_service.rb b/app/services/container_expiration_policy_service.rb new file mode 100644 index 00000000000..5d141d4d64d --- /dev/null +++ b/app/services/container_expiration_policy_service.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class ContainerExpirationPolicyService < BaseService + def execute(container_expiration_policy) + container_expiration_policy.schedule_next_run! + + container_expiration_policy.container_repositories.find_each do |container_repository| + CleanupContainerRepositoryWorker.perform_async( + current_user.id, + container_repository.id, + container_expiration_policy.attributes.except("created_at", "updated_at") + ) + end + end +end diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 6afc326ed37..330e9fafa69 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -10,6 +10,7 @@ - chaos:chaos_sleep - cronjob:admin_email +- cronjob:container_expiration_policy - cronjob:expire_build_artifacts - cronjob:gitlab_usage_ping - cronjob:import_export_project_cleanup diff --git a/app/workers/container_expiration_policy_worker.rb b/app/workers/container_expiration_policy_worker.rb new file mode 100644 index 00000000000..595208230f6 --- /dev/null +++ b/app/workers/container_expiration_policy_worker.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class ContainerExpirationPolicyWorker + include ApplicationWorker + include CronjobQueue + + feature_category :container_registry + + def perform + ContainerExpirationPolicy.runnable_schedules.preloaded.find_each do |container_expiration_policy| + ContainerExpirationPolicyService.new( + container_expiration_policy.project, container_expiration_policy.project.owner + ).execute(container_expiration_policy) + end + end +end -- cgit v1.2.1