Commit f361b479 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre Committed by Mayra Cabrera

Rename recheck actions to reverify

It's not clear what is clear what "recheck" means in the Geo context.
Since we use verification instead of check everywhere this change these
actions to use "reverify" instead.
parent 630d4df0
...@@ -34,10 +34,10 @@ class Admin::Geo::ProjectsController < Admin::Geo::ApplicationController ...@@ -34,10 +34,10 @@ class Admin::Geo::ProjectsController < Admin::Geo::ApplicationController
redirect_back_or_admin_geo_projects(notice: s_('Geo|Tracking entry for project (%{project_id}) was successfully removed.') % { project_id: @registry.project_id }) redirect_back_or_admin_geo_projects(notice: s_('Geo|Tracking entry for project (%{project_id}) was successfully removed.') % { project_id: @registry.project_id })
end end
def recheck def reverify
@registry.flag_repository_for_recheck! @registry.flag_repository_for_reverify!
redirect_back_or_admin_geo_projects(notice: s_('Geo|%{name} is scheduled for re-check') % { name: @registry.project.full_name }) redirect_back_or_admin_geo_projects(notice: s_('Geo|%{name} is scheduled for re-verify') % { name: @registry.project.full_name })
end end
def resync def resync
...@@ -52,10 +52,10 @@ class Admin::Geo::ProjectsController < Admin::Geo::ApplicationController ...@@ -52,10 +52,10 @@ class Admin::Geo::ProjectsController < Admin::Geo::ApplicationController
redirect_back_or_admin_geo_projects(notice: s_('Geo|%{name} is scheduled for forced re-download') % { name: @registry.project.full_name }) redirect_back_or_admin_geo_projects(notice: s_('Geo|%{name} is scheduled for forced re-download') % { name: @registry.project.full_name })
end end
def recheck_all def reverify_all
Geo::Batch::ProjectRegistrySchedulerWorker.perform_async(:recheck_repositories) Geo::Batch::ProjectRegistrySchedulerWorker.perform_async(:reverify_repositories)
redirect_back_or_admin_geo_projects(notice: s_('Geo|All projects are being scheduled for re-check')) redirect_back_or_admin_geo_projects(notice: s_('Geo|All projects are being scheduled for re-verify'))
end end
def resync_all def resync_all
......
...@@ -186,7 +186,7 @@ class Geo::ProjectRegistry < Geo::BaseRegistry ...@@ -186,7 +186,7 @@ class Geo::ProjectRegistry < Geo::BaseRegistry
) )
end end
def self.flag_repositories_for_recheck! def self.flag_repositories_for_reverify!
update_all( update_all(
repository_verification_checksum_sha: nil, repository_verification_checksum_sha: nil,
last_repository_verification_failure: nil, last_repository_verification_failure: nil,
...@@ -389,8 +389,8 @@ class Geo::ProjectRegistry < Geo::BaseRegistry ...@@ -389,8 +389,8 @@ class Geo::ProjectRegistry < Geo::BaseRegistry
# Flag the repository to be re-checked # Flag the repository to be re-checked
# #
# This operation happens only in the database and the recheck will be triggered after by the cron job # This operation happens only in the database and the reverify will be triggered after by the cron job
def flag_repository_for_recheck! def flag_repository_for_reverify!
self.update(repository_verification_checksum_sha: nil, last_repository_verification_failure: nil, repository_checksum_mismatch: false) self.update(repository_verification_checksum_sha: nil, last_repository_verification_failure: nil, repository_checksum_mismatch: false)
end end
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
%strong.header-text-primary.flex-fill %strong.header-text-primary.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project) = link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
- unless project_registry.pending_verification? - unless project_registry.pending_verification?
= link_to(recheck_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do = link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Recheck') = s_('Geo|Reverify')
- unless project_registry.resync_repository? - unless project_registry.resync_repository?
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do = link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync') = s_('Geo|Resync')
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
%strong.header-text-primary.flex-fill %strong.header-text-primary.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project) = link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
- unless project_registry.pending_verification? - unless project_registry.pending_verification?
= link_to(recheck_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do = link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Recheck') = s_('Geo|Reverify')
- unless project_registry.resync_repository? - unless project_registry.resync_repository?
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do = link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync') = s_('Geo|Resync')
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
- else - else
%strong.header-text-primary.flex-fill %strong.header-text-primary.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project) = link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
= link_to(recheck_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do = link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Recheck') = s_('Geo|Reverify')
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do = link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync') = s_('Geo|Resync')
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
%ul.dropdown-menu.dropdown-menu-right %ul.dropdown-menu.dropdown-menu-right
%li.dropdown-header= s_('Geo|Batch operations') %li.dropdown-header= s_('Geo|Batch operations')
%li= link_to s_('Geo|Resync all projects'), resync_all_admin_geo_projects_path, method: :post %li= link_to s_('Geo|Resync all projects'), resync_all_admin_geo_projects_path, method: :post
%li= link_to s_('Geo|Recheck all projects'), recheck_all_admin_geo_projects_path, method: :post %li= link_to s_('Geo|Reverify all projects'), reverify_all_admin_geo_projects_path, method: :post
- case params[:sync_status] - case params[:sync_status]
- when 'never' - when 'never'
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
.card-header .card-header
= s_('Geo|Geo Status') = s_('Geo|Geo Status')
.float-right .float-right
= link_to(recheck_admin_geo_project_path(@project.project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do = link_to(reverify_admin_geo_project_path(@project.project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Recheck') = s_('Geo|Reverify')
= link_to(resync_admin_geo_project_path(@project.project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do = link_to(resync_admin_geo_project_path(@project.project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync') = s_('Geo|Resync')
= render partial: "admin/geo/projects/registry_#{@project.project_registry.synchronization_state}", locals: { project_registry: @project.project_registry } = render partial: "admin/geo/projects/registry_#{@project.project_registry.synchronization_state}", locals: { project_registry: @project.project_registry }
...@@ -15,10 +15,17 @@ module Geo ...@@ -15,10 +15,17 @@ module Geo
BATCH_SIZE = 10000 BATCH_SIZE = 10000
LEASE_TIMEOUT = 2.minutes # TTL for X amount of loops to happen until it is renewed LEASE_TIMEOUT = 2.minutes # TTL for X amount of loops to happen until it is renewed
RENEW_AFTER_LOOPS = 20 # renew lease at every 20 loops has finished RENEW_AFTER_LOOPS = 20 # renew lease at every 20 loops has finished
OPERATIONS = [:resync_repositories, :recheck_repositories].freeze OPERATIONS = [:resync_repositories, :reverify_repositories].freeze
DELAY_INTERVAL = 10.seconds.to_i # base delay for scheduling batch execution DELAY_INTERVAL = 10.seconds.to_i # base delay for scheduling batch execution
def perform(operation) def perform(operation)
# TODO: This is a temporary workaround for backward compatibility
# to avoid jobs that have been already scheduled to fail.
# See https://gitlab.com/gitlab-org/gitlab-ee/issues/13318
if operation.to_sym == :recheck_repositories
operation = :reverify_repositories
end
return fail_invalid_operation!(operation) unless OPERATIONS.include?(operation.to_sym) return fail_invalid_operation!(operation) unless OPERATIONS.include?(operation.to_sym)
try_obtain_lease do try_obtain_lease do
......
...@@ -12,14 +12,21 @@ module Geo ...@@ -12,14 +12,21 @@ module Geo
include ::Gitlab::Geo::LogHelpers include ::Gitlab::Geo::LogHelpers
BATCH_SIZE = 250 BATCH_SIZE = 250
OPERATIONS = [:resync_repositories, :recheck_repositories].freeze OPERATIONS = [:resync_repositories, :reverify_repositories].freeze
def perform(operation, range) def perform(operation, range)
# TODO: This is a temporary workaround for backward compatibility
# to avoid jobs that have been already scheduled to fail.
# See https://gitlab.com/gitlab-org/gitlab-ee/issues/13318
if operation.to_sym == :recheck_repositories
operation = :reverify_repositories
end
case operation.to_sym case operation.to_sym
when :resync_repositories when :resync_repositories
resync_repositories(range) resync_repositories(range)
when :recheck_repositories when :reverify_repositories
recheck_repositories(range) reverify_repositories(range)
else else
fail_invalid_operation!(operation) fail_invalid_operation!(operation)
end end
...@@ -33,9 +40,9 @@ module Geo ...@@ -33,9 +40,9 @@ module Geo
end end
end end
def recheck_repositories(range) def reverify_repositories(range)
Geo::ProjectRegistry.with_range(range[0], range[1]).each_batch(of: BATCH_SIZE) do |batch| Geo::ProjectRegistry.with_range(range[0], range[1]).each_batch(of: BATCH_SIZE) do |batch|
batch.flag_repositories_for_recheck! batch.flag_repositories_for_reverify!
end end
end end
......
---
title: Geo - Rename recheck actions to reverify
merge_request: 14979
author:
type: other
...@@ -30,13 +30,13 @@ namespace :admin do ...@@ -30,13 +30,13 @@ namespace :admin do
resources :projects, only: [:index, :destroy] do resources :projects, only: [:index, :destroy] do
member do member do
post :recheck post :reverify
post :resync post :resync
post :force_redownload post :force_redownload
end end
collection do collection do
post :recheck_all post :reverify_all
post :resync_all post :resync_all
end end
end end
......
...@@ -12,7 +12,7 @@ module EE ...@@ -12,7 +12,7 @@ module EE
}.freeze }.freeze
WHITELISTED_GEO_ROUTES_TRACKING_DB = { WHITELISTED_GEO_ROUTES_TRACKING_DB = {
'admin/geo/projects' => %w{destroy resync recheck force_redownload resync_all recheck_all}, 'admin/geo/projects' => %w{destroy resync reverify force_redownload resync_all reverify_all},
'admin/geo/uploads' => %w{destroy} 'admin/geo/uploads' => %w{destroy}
}.freeze }.freeze
......
...@@ -118,8 +118,8 @@ describe Admin::Geo::ProjectsController, :geo do ...@@ -118,8 +118,8 @@ describe Admin::Geo::ProjectsController, :geo do
end end
end end
describe '#recheck' do describe '#reverify' do
subject { post :recheck, params: { id: synced_registry } } subject { post :reverify, params: { id: synced_registry } }
it_behaves_like 'license required' it_behaves_like 'license required'
...@@ -128,9 +128,9 @@ describe Admin::Geo::ProjectsController, :geo do ...@@ -128,9 +128,9 @@ describe Admin::Geo::ProjectsController, :geo do
stub_licensed_features(geo: true) stub_licensed_features(geo: true)
end end
it 'flags registry for recheck' do it 'flags registry for reverify' do
expect(subject).to redirect_to(admin_geo_projects_path) expect(subject).to redirect_to(admin_geo_projects_path)
expect(flash[:notice]).to include('is scheduled for re-check') expect(flash[:notice]).to include('is scheduled for re-verify')
expect(synced_registry.reload.pending_verification?).to be_truthy expect(synced_registry.reload.pending_verification?).to be_truthy
end end
end end
...@@ -154,8 +154,8 @@ describe Admin::Geo::ProjectsController, :geo do ...@@ -154,8 +154,8 @@ describe Admin::Geo::ProjectsController, :geo do
end end
end end
describe '#recheck_all' do describe '#reverify_all' do
subject { post :recheck_all } subject { post :reverify_all }
it_behaves_like 'license required' it_behaves_like 'license required'
...@@ -167,14 +167,14 @@ describe Admin::Geo::ProjectsController, :geo do ...@@ -167,14 +167,14 @@ describe Admin::Geo::ProjectsController, :geo do
it 'schedules a batch job' do it 'schedules a batch job' do
Sidekiq::Testing.fake! do Sidekiq::Testing.fake! do
expect { subject }.to change(Geo::Batch::ProjectRegistrySchedulerWorker.jobs, :size).by(1) expect { subject }.to change(Geo::Batch::ProjectRegistrySchedulerWorker.jobs, :size).by(1)
expect(Geo::Batch::ProjectRegistrySchedulerWorker.jobs.last['args']).to include('recheck_repositories') expect(Geo::Batch::ProjectRegistrySchedulerWorker.jobs.last['args']).to include('reverify_repositories')
end end
end end
it 'redirects back and display confirmation' do it 'redirects back and display confirmation' do
Sidekiq::Testing.inline! do Sidekiq::Testing.inline! do
expect(subject).to redirect_to(admin_geo_projects_path) expect(subject).to redirect_to(admin_geo_projects_path)
expect(flash[:notice]).to include('All projects are being scheduled for re-check') expect(flash[:notice]).to include('All projects are being scheduled for re-verify')
end end
end end
end end
......
...@@ -57,9 +57,9 @@ describe Gitlab::Middleware::ReadOnly do ...@@ -57,9 +57,9 @@ describe Gitlab::Middleware::ReadOnly do
it_behaves_like 'whitelisted request', :post, '/admin/geo/projects/1/resync' it_behaves_like 'whitelisted request', :post, '/admin/geo/projects/1/resync'
it_behaves_like 'whitelisted request', :post, '/admin/geo/projects/1/recheck' it_behaves_like 'whitelisted request', :post, '/admin/geo/projects/1/reverify'
it_behaves_like 'whitelisted request', :post, '/admin/geo/projects/recheck_all' it_behaves_like 'whitelisted request', :post, '/admin/geo/projects/reverify_all'
it_behaves_like 'whitelisted request', :post, '/admin/geo/projects/resync_all' it_behaves_like 'whitelisted request', :post, '/admin/geo/projects/resync_all'
......
...@@ -175,11 +175,11 @@ describe Geo::ProjectRegistry do ...@@ -175,11 +175,11 @@ describe Geo::ProjectRegistry do
end end
end end
describe '.flag_repositories_for_recheck!' do describe '.flag_repositories_for_reverify!' do
it 'modified record to a recheck state' do it 'modified record to a reverify state' do
registry = create(:geo_project_registry, :repository_verified) registry = create(:geo_project_registry, :repository_verified)
described_class.flag_repositories_for_recheck! described_class.flag_repositories_for_reverify!
expect(registry.reload).to have_attributes( expect(registry.reload).to have_attributes(
repository_verification_checksum_sha: nil, repository_verification_checksum_sha: nil,
...@@ -930,10 +930,10 @@ describe Geo::ProjectRegistry do ...@@ -930,10 +930,10 @@ describe Geo::ProjectRegistry do
end end
end end
describe '#flag_repository_for_recheck!' do describe '#flag_repository_for_reverify!' do
it 'modified record to a recheck state' do it 'modified record to a reverify state' do
registry = create(:geo_project_registry, :repository_verified) registry = create(:geo_project_registry, :repository_verified)
registry.flag_repository_for_recheck! registry.flag_repository_for_reverify!
expect(registry).to have_attributes( expect(registry).to have_attributes(
repository_verification_checksum_sha: nil, repository_verification_checksum_sha: nil,
...@@ -962,7 +962,7 @@ describe Geo::ProjectRegistry do ...@@ -962,7 +962,7 @@ describe Geo::ProjectRegistry do
end end
describe '#flag_repository_for_redownload!' do describe '#flag_repository_for_redownload!' do
it 'modified record to a recheck state' do it 'modified record to a redownload state' do
registry = create(:geo_project_registry, :repository_verified) registry = create(:geo_project_registry, :repository_verified)
registry.flag_repository_for_redownload! registry.flag_repository_for_redownload!
......
...@@ -13,8 +13,8 @@ describe 'EE-specific admin routing' do ...@@ -13,8 +13,8 @@ describe 'EE-specific admin routing' do
expect(delete("/admin/geo/projects/#{project_registry.id}")).to route_to('admin/geo/projects#destroy', id: project_registry.to_param) expect(delete("/admin/geo/projects/#{project_registry.id}")).to route_to('admin/geo/projects#destroy', id: project_registry.to_param)
end end
it 'routes post /:id/recheck to #recheck' do it 'routes post /:id/reverify to #reverify' do
expect(post("admin/geo/projects/#{project_registry.id}/recheck")).to route_to('admin/geo/projects#recheck', id: project_registry.to_param) expect(post("admin/geo/projects/#{project_registry.id}/reverify")).to route_to('admin/geo/projects#reverify', id: project_registry.to_param)
end end
it 'routes post /:id/resync to #resync' do it 'routes post /:id/resync to #resync' do
......
...@@ -19,10 +19,21 @@ RSpec.describe Geo::Batch::ProjectRegistrySchedulerWorker do ...@@ -19,10 +19,21 @@ RSpec.describe Geo::Batch::ProjectRegistrySchedulerWorker do
context 'when operation is :recheck_repositories' do context 'when operation is :recheck_repositories' do
let!(:registry) { create(:geo_project_registry, :repository_verified) } let!(:registry) { create(:geo_project_registry, :repository_verified) }
it 'schedules batches of repositories for recheck' do it 'schedules batches of repositories for reverify' do
Sidekiq::Testing.fake! do Sidekiq::Testing.fake! do
expect { subject.perform(:recheck_repositories) }.to change(Geo::Batch::ProjectRegistryWorker.jobs, :size).by(1) expect { subject.perform(:recheck_repositories) }.to change(Geo::Batch::ProjectRegistryWorker.jobs, :size).by(1)
expect(Geo::Batch::ProjectRegistryWorker.jobs.last['args']).to include('recheck_repositories') expect(Geo::Batch::ProjectRegistryWorker.jobs.last['args']).to include('reverify_repositories')
end
end
end
context 'when operation is :reverify_repositories' do
let!(:registry) { create(:geo_project_registry, :repository_verified) }
it 'schedules batches of repositories for reverify' do
Sidekiq::Testing.fake! do
expect { subject.perform(:reverify_repositories) }.to change(Geo::Batch::ProjectRegistryWorker.jobs, :size).by(1)
expect(Geo::Batch::ProjectRegistryWorker.jobs.last['args']).to include('reverify_repositories')
end end
end end
...@@ -30,7 +41,7 @@ RSpec.describe Geo::Batch::ProjectRegistrySchedulerWorker do ...@@ -30,7 +41,7 @@ RSpec.describe Geo::Batch::ProjectRegistrySchedulerWorker do
stub_exclusive_lease_taken(lease_key, timeout: lease_timeout) stub_exclusive_lease_taken(lease_key, timeout: lease_timeout)
Sidekiq::Testing.fake! do Sidekiq::Testing.fake! do
expect { subject.perform(:recheck_repositories) }.not_to change(Geo::Batch::ProjectRegistryWorker.jobs, :size) expect { subject.perform(:reverify_repositories) }.not_to change(Geo::Batch::ProjectRegistryWorker.jobs, :size)
end end
end end
end end
......
...@@ -17,7 +17,7 @@ RSpec.describe Geo::Batch::ProjectRegistryWorker do ...@@ -17,7 +17,7 @@ RSpec.describe Geo::Batch::ProjectRegistryWorker do
context 'when operation is :recheck_repositories' do context 'when operation is :recheck_repositories' do
let!(:registry) { create(:geo_project_registry, :repository_verified) } let!(:registry) { create(:geo_project_registry, :repository_verified) }
it 'flags repositories for recheck' do it 'flags repositories for reverify' do
Sidekiq::Testing.inline! do Sidekiq::Testing.inline! do
subject.perform(:recheck_repositories, range) subject.perform(:recheck_repositories, range)
end end
...@@ -26,6 +26,18 @@ RSpec.describe Geo::Batch::ProjectRegistryWorker do ...@@ -26,6 +26,18 @@ RSpec.describe Geo::Batch::ProjectRegistryWorker do
end end
end end
context 'when operation is :reverify_repositories' do
let!(:registry) { create(:geo_project_registry, :repository_verified) }
it 'flags repositories for reverify' do
Sidekiq::Testing.inline! do
subject.perform(:reverify_repositories, range)
end
expect(registry.reload.repository_verification_pending?).to be_truthy
end
end
context 'when operation is :resync_repositories' do context 'when operation is :resync_repositories' do
let!(:registry) { create(:geo_project_registry, :synced) } let!(:registry) { create(:geo_project_registry, :synced) }
......
...@@ -6685,10 +6685,10 @@ msgstr "" ...@@ -6685,10 +6685,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for forced re-download" msgid "Geo|%{name} is scheduled for forced re-download"
msgstr "" msgstr ""
msgid "Geo|%{name} is scheduled for re-check" msgid "Geo|%{name} is scheduled for re-sync"
msgstr "" msgstr ""
msgid "Geo|%{name} is scheduled for re-sync" msgid "Geo|%{name} is scheduled for re-verify"
msgstr "" msgstr ""
msgid "Geo|All" msgid "Geo|All"
...@@ -6697,10 +6697,10 @@ msgstr "" ...@@ -6697,10 +6697,10 @@ msgstr ""
msgid "Geo|All projects" msgid "Geo|All projects"
msgstr "" msgstr ""
msgid "Geo|All projects are being scheduled for re-check" msgid "Geo|All projects are being scheduled for re-sync"
msgstr "" msgstr ""
msgid "Geo|All projects are being scheduled for re-sync" msgid "Geo|All projects are being scheduled for re-verify"
msgstr "" msgstr ""
msgid "Geo|Batch operations" msgid "Geo|Batch operations"
...@@ -6790,12 +6790,6 @@ msgstr "" ...@@ -6790,12 +6790,6 @@ msgstr ""
msgid "Geo|Re-verification interval" msgid "Geo|Re-verification interval"
msgstr "" msgstr ""
msgid "Geo|Recheck"
msgstr ""
msgid "Geo|Recheck all projects"
msgstr ""
msgid "Geo|Redownload" msgid "Geo|Redownload"
msgstr "" msgstr ""
...@@ -6814,6 +6808,12 @@ msgstr "" ...@@ -6814,6 +6808,12 @@ msgstr ""
msgid "Geo|Retry count" msgid "Geo|Retry count"
msgstr "" msgstr ""
msgid "Geo|Reverify"
msgstr ""
msgid "Geo|Reverify all projects"
msgstr ""
msgid "Geo|Select groups to replicate." msgid "Geo|Select groups to replicate."
msgstr "" msgstr ""
......
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