2019-12-11 07:08:10 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class ContainerExpirationPolicy < ApplicationRecord
|
2020-01-11 10:07:49 -05:00
|
|
|
include Schedulable
|
2020-04-10 08:09:36 -04:00
|
|
|
include UsageStatistics
|
2020-10-19 14:08:54 -04:00
|
|
|
include EachBatch
|
2020-01-11 10:07:49 -05:00
|
|
|
|
2020-10-26 14:08:27 -04:00
|
|
|
POLICY_PARAMS = %w[
|
|
|
|
older_than
|
|
|
|
keep_n
|
|
|
|
name_regex
|
|
|
|
name_regex_keep
|
|
|
|
].freeze
|
|
|
|
|
2019-12-11 07:08:10 -05:00
|
|
|
belongs_to :project, inverse_of: :container_expiration_policy
|
|
|
|
|
2020-01-11 10:07:49 -05:00
|
|
|
delegate :container_repositories, to: :project
|
|
|
|
|
2019-12-11 07:08:10 -05:00
|
|
|
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
|
2020-10-27 20:08:34 -04:00
|
|
|
validates :name_regex, presence: true, if: :enabled?
|
2020-06-11 08:08:54 -04:00
|
|
|
validates :name_regex, untrusted_regexp: true, if: :enabled?
|
|
|
|
validates :name_regex_keep, untrusted_regexp: true, if: :enabled?
|
2019-12-11 07:08:10 -05:00
|
|
|
|
2020-01-11 10:07:49 -05:00
|
|
|
scope :active, -> { where(enabled: true) }
|
2020-02-11 10:08:44 -05:00
|
|
|
scope :preloaded, -> { preload(project: [:route]) }
|
2020-01-11 10:07:49 -05:00
|
|
|
|
2020-10-26 14:08:27 -04:00
|
|
|
def self.with_container_repositories
|
|
|
|
where(
|
2020-10-19 14:08:54 -04:00
|
|
|
'EXISTS (?)',
|
|
|
|
ContainerRepository.select(1)
|
|
|
|
.where(
|
|
|
|
'container_repositories.project_id = container_expiration_policies.project_id'
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2021-06-16 14:10:35 -04:00
|
|
|
def self.without_container_repositories
|
|
|
|
where.not(
|
|
|
|
'EXISTS(?)',
|
|
|
|
ContainerRepository.select(1)
|
|
|
|
.where(
|
|
|
|
'container_repositories.project_id = container_expiration_policies.project_id'
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2019-12-11 07:08:10 -05:00
|
|
|
def self.keep_n_options
|
|
|
|
{
|
|
|
|
1 => _('%{tags} tag per image name') % { tags: 1 },
|
|
|
|
5 => _('%{tags} tags per image name') % { tags: 5 },
|
|
|
|
10 => _('%{tags} tags per image name') % { tags: 10 },
|
|
|
|
25 => _('%{tags} tags per image name') % { tags: 25 },
|
|
|
|
50 => _('%{tags} tags per image name') % { tags: 50 },
|
|
|
|
100 => _('%{tags} tags per image name') % { tags: 100 }
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.cadence_options
|
|
|
|
{
|
|
|
|
'1d': _('Every day'),
|
|
|
|
'7d': _('Every week'),
|
|
|
|
'14d': _('Every two weeks'),
|
|
|
|
'1month': _('Every month'),
|
|
|
|
'3month': _('Every three months')
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.older_than_options
|
|
|
|
{
|
|
|
|
'7d': _('%{days} days until tags are automatically removed') % { days: 7 },
|
|
|
|
'14d': _('%{days} days until tags are automatically removed') % { days: 14 },
|
|
|
|
'30d': _('%{days} days until tags are automatically removed') % { days: 30 },
|
2021-09-29 08:11:22 -04:00
|
|
|
'60d': _('%{days} days until tags are automatically removed') % { days: 60 },
|
2019-12-11 07:08:10 -05:00
|
|
|
'90d': _('%{days} days until tags are automatically removed') % { days: 90 }
|
|
|
|
}
|
|
|
|
end
|
2020-01-11 10:07:49 -05:00
|
|
|
|
|
|
|
def set_next_run_at
|
|
|
|
self.next_run_at = Time.zone.now + ChronicDuration.parse(cadence).seconds
|
|
|
|
end
|
2020-06-16 02:08:27 -04:00
|
|
|
|
|
|
|
def disable!
|
|
|
|
update_attribute(:enabled, false)
|
|
|
|
end
|
2020-10-26 14:08:27 -04:00
|
|
|
|
|
|
|
def policy_params
|
|
|
|
attributes.slice(*POLICY_PARAMS)
|
|
|
|
end
|
2019-12-11 07:08:10 -05:00
|
|
|
end
|