Commit e664c95a authored by Stan Hu's avatar Stan Hu

Merge branch '208193-add-expiration-started-at-to-container-repositories' into 'master'

Add expiration_policy_started_at support in container repositories

See merge request gitlab-org/gitlab!42598
parents f82bcb41 a942048a
...@@ -107,6 +107,14 @@ class ContainerRepository < ApplicationRecord ...@@ -107,6 +107,14 @@ class ContainerRepository < ApplicationRecord
client.delete_repository_tag_by_name(self.path, name) client.delete_repository_tag_by_name(self.path, name)
end end
def reset_expiration_policy_started_at!
update!(expiration_policy_started_at: nil)
end
def start_expiration_policy!
update!(expiration_policy_started_at: Time.zone.now)
end
def self.build_from_path(path) def self.build_from_path(path)
self.new(project: path.repository_project, self.new(project: path.repository_project,
name: path.repository_name) name: path.repository_name)
......
...@@ -16,9 +16,17 @@ class CleanupContainerRepositoryWorker # rubocop:disable Scalability/IdempotentW ...@@ -16,9 +16,17 @@ class CleanupContainerRepositoryWorker # rubocop:disable Scalability/IdempotentW
return unless valid? return unless valid?
Projects::ContainerRepository::CleanupTagsService if run_by_container_expiration_policy?
container_repository.start_expiration_policy!
end
result = Projects::ContainerRepository::CleanupTagsService
.new(project, current_user, params) .new(project, current_user, params)
.execute(container_repository) .execute(container_repository)
if run_by_container_expiration_policy? && result[:status] == :success
container_repository.reset_expiration_policy_started_at!
end
end end
private private
...@@ -30,7 +38,7 @@ class CleanupContainerRepositoryWorker # rubocop:disable Scalability/IdempotentW ...@@ -30,7 +38,7 @@ class CleanupContainerRepositoryWorker # rubocop:disable Scalability/IdempotentW
end end
def run_by_container_expiration_policy? def run_by_container_expiration_policy?
@params['container_expiration_policy'] && container_repository && project @params['container_expiration_policy'] && container_repository.present? && project.present?
end end
def project def project
......
---
title: Add expiration policy started at support in container repositories
merge_request: 42598
author:
type: added
# frozen_string_literal: true
class AddExpirationPolicyStartedAtToContainerRepositories < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
add_column(:container_repositories, :expiration_policy_started_at, :datetime_with_timezone)
end
def down
remove_column(:container_repositories, :expiration_policy_started_at)
end
end
8cabe224e89ef77fe4a2bc1f8bf7381faaa10d1cab4907a26aeb2162a126af52
\ No newline at end of file
...@@ -11083,7 +11083,8 @@ CREATE TABLE container_repositories ( ...@@ -11083,7 +11083,8 @@ CREATE TABLE container_repositories (
name character varying NOT NULL, name character varying NOT NULL,
created_at timestamp without time zone NOT NULL, created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL,
status smallint status smallint,
expiration_policy_started_at timestamp with time zone
); );
CREATE SEQUENCE container_repositories_id_seq CREATE SEQUENCE container_repositories_id_seq
......
...@@ -41,7 +41,8 @@ Example response: ...@@ -41,7 +41,8 @@ Example response:
"path": "group/project", "path": "group/project",
"project_id": 9, "project_id": 9,
"location": "gitlab.example.com:5000/group/project", "location": "gitlab.example.com:5000/group/project",
"created_at": "2019-01-10T13:38:57.391Z" "created_at": "2019-01-10T13:38:57.391Z",
"cleanup_policy_started_at": "2020-01-10T15:40:57.391Z"
}, },
{ {
"id": 2, "id": 2,
...@@ -49,7 +50,8 @@ Example response: ...@@ -49,7 +50,8 @@ Example response:
"path": "group/project/releases", "path": "group/project/releases",
"project_id": 9, "project_id": 9,
"location": "gitlab.example.com:5000/group/project/releases", "location": "gitlab.example.com:5000/group/project/releases",
"created_at": "2019-01-10T13:39:08.229Z" "created_at": "2019-01-10T13:39:08.229Z",
"cleanup_policy_started_at": "2020-08-17T03:12:35.489Z"
} }
] ]
``` ```
...@@ -84,6 +86,7 @@ Example response: ...@@ -84,6 +86,7 @@ Example response:
"project_id": 9, "project_id": 9,
"location": "gitlab.example.com:5000/group/project", "location": "gitlab.example.com:5000/group/project",
"created_at": "2019-01-10T13:38:57.391Z", "created_at": "2019-01-10T13:38:57.391Z",
"cleanup_policy_started_at": "2020-08-17T03:12:35.489Z",
"tags_count": 1, "tags_count": 1,
"tags": [ "tags": [
{ {
...@@ -100,6 +103,7 @@ Example response: ...@@ -100,6 +103,7 @@ Example response:
"project_id": 11, "project_id": 11,
"location": "gitlab.example.com:5000/group/other_project", "location": "gitlab.example.com:5000/group/other_project",
"created_at": "2019-01-10T13:39:08.229Z", "created_at": "2019-01-10T13:39:08.229Z",
"cleanup_policy_started_at": "2020-01-10T15:40:57.391Z",
"tags_count": 3, "tags_count": 3,
"tags": [ "tags": [
{ {
......
...@@ -16,6 +16,7 @@ module API ...@@ -16,6 +16,7 @@ module API
expose :project_id expose :project_id
expose :location expose :location
expose :created_at expose :created_at
expose :expiration_policy_started_at, as: :cleanup_policy_started_at
expose :tags_count, if: -> (_, options) { options[:tags_count] } expose :tags_count, if: -> (_, options) { options[:tags_count] }
expose :tags, using: Tag, if: -> (_, options) { options[:tags] } expose :tags, using: Tag, if: -> (_, options) { options[:tags] }
end end
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
"created_at": { "created_at": {
"type": "date-time" "type": "date-time"
}, },
"cleanup_policy_started_at": {
"type": "date-time"
},
"tags_path": { "tags_path": {
"type": "string" "type": "string"
}, },
......
...@@ -184,6 +184,33 @@ RSpec.describe ContainerRepository do ...@@ -184,6 +184,33 @@ RSpec.describe ContainerRepository do
end end
end end
describe '#start_expiration_policy!' do
subject { repository.start_expiration_policy! }
it 'sets the expiration policy started at to now' do
Timecop.freeze do
expect { subject }
.to change { repository.expiration_policy_started_at }.from(nil).to(Time.zone.now)
end
end
end
describe '#reset_expiration_policy_started_at!' do
subject { repository.reset_expiration_policy_started_at! }
before do
repository.start_expiration_policy!
end
it 'resets the expiration policy started at' do
started_at = repository.expiration_policy_started_at
expect(started_at).not_to be_nil
expect { subject }
.to change { repository.expiration_policy_started_at }.from(started_at).to(nil)
end
end
describe '.build_from_path' do describe '.build_from_path' do
let(:registry_path) do let(:registry_path) do
ContainerRegistry::Path.new(project.full_path + '/some/image') ContainerRegistry::Path.new(project.full_path + '/some/image')
......
...@@ -40,14 +40,35 @@ RSpec.describe CleanupContainerRepositoryWorker, :clean_gitlab_redis_shared_stat ...@@ -40,14 +40,35 @@ RSpec.describe CleanupContainerRepositoryWorker, :clean_gitlab_redis_shared_stat
context 'container expiration policy' do context 'container expiration policy' do
let(:params) { { key: 'value', 'container_expiration_policy' => true } } let(:params) { { key: 'value', 'container_expiration_policy' => true } }
before do
allow(ContainerRepository)
.to receive(:find_by_id).with(repository.id).and_return(repository)
end
it 'executes the destroy service' do it 'executes the destroy service' do
expect(repository).to receive(:start_expiration_policy!).and_call_original
expect(repository).to receive(:reset_expiration_policy_started_at!).and_call_original
expect(Projects::ContainerRepository::CleanupTagsService).to receive(:new) expect(Projects::ContainerRepository::CleanupTagsService).to receive(:new)
.with(project, nil, params.merge('container_expiration_policy' => true)) .with(project, nil, params.merge('container_expiration_policy' => true))
.and_return(service) .and_return(service)
expect(service).to receive(:execute) expect(service).to receive(:execute).and_return(status: :success)
subject.perform(nil, repository.id, params)
expect(repository.reload.expiration_policy_started_at).to be_nil
end
it "doesn't reset the expiration policy started at if the destroy service returns an error" do
expect(repository).to receive(:start_expiration_policy!).and_call_original
expect(repository).not_to receive(:reset_expiration_policy_started_at!)
expect(Projects::ContainerRepository::CleanupTagsService).to receive(:new)
.with(project, nil, params.merge('container_expiration_policy' => true))
.and_return(service)
expect(service).to receive(:execute).and_return(status: :error, message: 'timeout while deleting tags')
subject.perform(nil, repository.id, params) subject.perform(nil, repository.id, params)
expect(repository.reload.expiration_policy_started_at).not_to be_nil
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment