Commit 74d906ea authored by Michael Kozono's avatar Michael Kozono

Log repo update event on keep around

parent 575bfa8a
......@@ -666,8 +666,7 @@ module Ci
def keep_around_commits
return unless project
project.repository.keep_around(self.sha)
project.repository.keep_around(self.before_sha)
project.repository.keep_around(self.sha, self.before_sha)
end
def valid_source
......
......@@ -191,14 +191,18 @@ class DiffNote < Note
end
def keep_around_commits
project.repository.keep_around(self.original_position.base_sha)
project.repository.keep_around(self.original_position.start_sha)
project.repository.keep_around(self.original_position.head_sha)
shas = [
self.original_position.base_sha,
self.original_position.start_sha,
self.original_position.head_sha
]
if self.position != self.original_position
project.repository.keep_around(self.position.base_sha)
project.repository.keep_around(self.position.start_sha)
project.repository.keep_around(self.position.head_sha)
shas << self.position.base_sha
shas << self.position.start_sha
shas << self.position.head_sha
end
project.repository.keep_around(*shas)
end
end
......@@ -314,9 +314,7 @@ class MergeRequestDiff < ActiveRecord::Base
def keep_around_commits
[repository, merge_request.source_project.repository].uniq.each do |repo|
repo.keep_around(start_commit_sha)
repo.keep_around(head_commit_sha)
repo.keep_around(base_commit_sha)
repo.keep_around(start_commit_sha, head_commit_sha, base_commit_sha)
end
end
end
......@@ -252,16 +252,23 @@ class Repository
# Git GC will delete commits from the repository that are no longer in any
# branches or tags, but we want to keep some of these commits around, for
# example if they have comments or CI builds.
def keep_around(sha)
return unless sha.present? && commit_by(oid: sha)
#
# For Geo's sake, pass in multiple shas rather than calling it multiple times,
# to avoid unnecessary syncing.
def keep_around(*shas)
shas.each do |sha|
begin
next unless sha.present? && commit_by(oid: sha)
return if kept_around?(sha)
next if kept_around?(sha)
# This will still fail if the file is corrupted (e.g. 0 bytes)
raw_repository.write_ref(keep_around_ref_name(sha), sha, shell: false)
rescue Gitlab::Git::CommandError => ex
Rails.logger.error "Unable to create keep-around reference for repository #{disk_path}: #{ex}"
end
end
end
def kept_around?(sha)
ref_exists?(keep_around_ref_name(sha))
......
......@@ -5,6 +5,7 @@ module EE
# and be prepended in the `Repository` model
module Repository
extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
MIRROR_REMOTE = "upstream".freeze
......@@ -69,5 +70,19 @@ module EE
false
end
end
override :keep_around
def keep_around(*shas)
super
ensure
log_geo_updated_event
end
def log_geo_updated_event
return unless ::Gitlab::Geo.primary?
source = is_wiki ? ::Geo::RepositoryUpdatedEvent::WIKI : ::Geo::RepositoryUpdatedEvent::REPOSITORY
::Geo::RepositoryUpdatedService.new(self.project, source: source).execute
end
end
end
---
title: 'Geo: Replicate keep around refs'
merge_request: 6922
author:
type: fixed
......@@ -2,6 +2,7 @@ require 'spec_helper'
describe Repository do
include RepoHelpers
include ::EE::GeoHelpers
TestBlob = Struct.new(:path)
let(:project) { create(:project, :repository) }
......@@ -113,4 +114,44 @@ describe Repository do
expect(repository.upstream_branches.first.name).to eq('upstream_branch')
end
end
describe '#keep_around' do
set(:primary_node) { create(:geo_node, :primary) }
set(:secondary_node) { create(:geo_node) }
let(:sha) { sample_commit.id }
context 'on a Geo primary' do
before do
stub_current_geo_node(primary_node)
end
context 'when a single SHA is passed' do
it 'creates a RepositoryUpdatedEvent' do
expect do
repository.keep_around(sha)
end.to change { ::Geo::RepositoryUpdatedEvent.count }.by(1)
end
end
context 'when multiple SHAs are passed' do
it 'creates exactly one RepositoryUpdatedEvent' do
expect do
repository.keep_around(sha, sample_big_commit.id)
end.to change { ::Geo::RepositoryUpdatedEvent.count }.by(1)
end
end
end
context 'on a Geo secondary' do
before do
stub_current_geo_node(secondary_node)
end
it 'does not create a RepositoryUpdatedEvent' do
expect do
repository.keep_around(sha)
end.not_to change { ::Geo::RepositoryUpdatedEvent.count }
end
end
end
end
......@@ -2005,6 +2005,24 @@ describe Repository do
File.delete(path)
end
context 'for multiple SHAs' do
it 'skips non-existent SHAs' do
repository.keep_around('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', sample_commit.id)
expect(repository.kept_around?(sample_commit.id)).to be_truthy
end
it 'skips already-kept-around SHAs' do
repository.keep_around(sample_commit.id)
expect(repository.raw_repository).to receive(:write_ref).exactly(1).and_call_original
repository.keep_around(sample_commit.id, another_sample_commit.id)
expect(repository.kept_around?(another_sample_commit.id)).to be_truthy
end
end
end
describe '#update_ref' do
......
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