Commit 493221ef authored by Valery Sizov's avatar Valery Sizov Committed by Douglas Barbosa Alexandre

Geo Node status for container repositories

We need to show the status of container sync
parent 82d5bb43
# frozen_string_literal: true
class AddGeoContainerRepositoryCounters < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
change_table :geo_node_statuses do |t|
t.column :container_repositories_count, :integer
t.column :container_repositories_synced_count, :integer
t.column :container_repositories_failed_count, :integer
t.column :container_repositories_registry_count, :integer
end
end
end
...@@ -1429,6 +1429,10 @@ ActiveRecord::Schema.define(version: 2019_08_02_235445) do ...@@ -1429,6 +1429,10 @@ ActiveRecord::Schema.define(version: 2019_08_02_235445) do
t.integer "repositories_retrying_verification_count" t.integer "repositories_retrying_verification_count"
t.integer "wikis_retrying_verification_count" t.integer "wikis_retrying_verification_count"
t.integer "projects_count" t.integer "projects_count"
t.integer "container_repositories_count"
t.integer "container_repositories_synced_count"
t.integer "container_repositories_failed_count"
t.integer "container_repositories_registry_count"
t.index ["geo_node_id"], name: "index_geo_node_statuses_on_geo_node_id", unique: true t.index ["geo_node_id"], name: "index_geo_node_statuses_on_geo_node_id", unique: true
end end
......
...@@ -192,6 +192,10 @@ Example response: ...@@ -192,6 +192,10 @@ Example response:
"job_artifacts_failed_count": nil, "job_artifacts_failed_count": nil,
"job_artifacts_synced_missing_on_primary_count": 0, "job_artifacts_synced_missing_on_primary_count": 0,
"job_artifacts_synced_in_percentage": "0.00%", "job_artifacts_synced_in_percentage": "0.00%",
"container_repositories_count": 3,
"container_repositories_synced_count": nil,
"container_repositories_failed_count": nil,
"container_repositories_synced_in_percentage": "0.00%",
"projects_count": 41, "projects_count": 41,
"repositories_failed_count": nil, "repositories_failed_count": nil,
"repositories_synced_count": nil, "repositories_synced_count": nil,
...@@ -255,6 +259,10 @@ Example response: ...@@ -255,6 +259,10 @@ Example response:
"job_artifacts_failed_count": 1, "job_artifacts_failed_count": 1,
"job_artifacts_synced_missing_on_primary_count": 0, "job_artifacts_synced_missing_on_primary_count": 0,
"job_artifacts_synced_in_percentage": "50.00%", "job_artifacts_synced_in_percentage": "50.00%",
"container_repositories_count": 3,
"container_repositories_synced_count": nil,
"container_repositories_failed_count": nil,
"container_repositories_synced_in_percentage": "0.00%",
"projects_count": 41, "projects_count": 41,
"repositories_failed_count": 1, "repositories_failed_count": 1,
"repositories_synced_count": 40, "repositories_synced_count": 40,
...@@ -334,6 +342,10 @@ Example response: ...@@ -334,6 +342,10 @@ Example response:
"job_artifacts_failed_count": 1, "job_artifacts_failed_count": 1,
"job_artifacts_synced_missing_on_primary_count": 0, "job_artifacts_synced_missing_on_primary_count": 0,
"job_artifacts_synced_in_percentage": "50.00%", "job_artifacts_synced_in_percentage": "50.00%",
"container_repositories_count": 3,
"container_repositories_synced_count": nil,
"container_repositories_failed_count": nil,
"container_repositories_synced_in_percentage": "0.00%",
"projects_count": 41, "projects_count": 41,
"repositories_failed_count": 1, "repositories_failed_count": 1,
"repositories_synced_count": 40, "repositories_synced_count": 40,
......
...@@ -56,6 +56,11 @@ export default { ...@@ -56,6 +56,11 @@ export default {
itemValue: this.nodeDetails.jobArtifacts, itemValue: this.nodeDetails.jobArtifacts,
itemValueType: VALUE_TYPE.GRAPH, itemValueType: VALUE_TYPE.GRAPH,
}, },
{
itemTitle: s__('GeoNodes|Local container repositories'),
itemValue: this.nodeDetails.containerRepositories,
itemValueType: VALUE_TYPE.GRAPH,
},
{ {
itemTitle: s__('GeoNodes|Data replication lag'), itemTitle: s__('GeoNodes|Data replication lag'),
itemValue: this.dbReplicationLag(), itemValue: this.dbReplicationLag(),
......
...@@ -119,6 +119,11 @@ export default class GeoNodesStore { ...@@ -119,6 +119,11 @@ export default class GeoNodesStore {
successCount: rawNodeDetails.job_artifacts_synced_count || 0, successCount: rawNodeDetails.job_artifacts_synced_count || 0,
failureCount: rawNodeDetails.job_artifacts_failed_count || 0, failureCount: rawNodeDetails.job_artifacts_failed_count || 0,
}, },
containerRepositories: {
totalCount: rawNodeDetails.container_repositories_count || 0,
successCount: rawNodeDetails.container_repositories_synced_count || 0,
failureCount: rawNodeDetails.container_repositories_failed_count || 0,
},
attachments: { attachments: {
totalCount: rawNodeDetails.attachments_count || 0, totalCount: rawNodeDetails.attachments_count || 0,
successCount: rawNodeDetails.attachments_synced_count || 0, successCount: rawNodeDetails.attachments_synced_count || 0,
......
...@@ -87,7 +87,11 @@ class GeoNodeStatus < ApplicationRecord ...@@ -87,7 +87,11 @@ class GeoNodeStatus < ApplicationRecord
repositories_checked_count: 'Number of repositories checked', repositories_checked_count: 'Number of repositories checked',
repositories_checked_failed_count: 'Number of failed repositories checked', repositories_checked_failed_count: 'Number of failed repositories checked',
repositories_retrying_verification_count: 'Number of repositories verification failures that Geo is actively trying to correct on secondary', repositories_retrying_verification_count: 'Number of repositories verification failures that Geo is actively trying to correct on secondary',
wikis_retrying_verification_count: 'Number of wikis verification failures that Geo is actively trying to correct on secondary' wikis_retrying_verification_count: 'Number of wikis verification failures that Geo is actively trying to correct on secondary',
container_repositories_count: 'Total number of syncable container repositories available on primary',
container_repositories_synced_count: 'Number of syncable container repositories synced on secondary',
container_repositories_failed_count: 'Number of syncable container repositories failed to sync on secondary',
container_repositories_registry_count: 'Number of container repositories in the registry'
}.freeze }.freeze
EXPIRATION_IN_MINUTES = 5 EXPIRATION_IN_MINUTES = 5
...@@ -224,17 +228,18 @@ class GeoNodeStatus < ApplicationRecord ...@@ -224,17 +228,18 @@ class GeoNodeStatus < ApplicationRecord
end end
end end
attr_in_percentage :repositories_synced, :repositories_synced_count, :repositories_count attr_in_percentage :repositories_synced, :repositories_synced_count, :repositories_count
attr_in_percentage :repositories_checksummed, :repositories_checksummed_count, :repositories_count attr_in_percentage :repositories_checksummed, :repositories_checksummed_count, :repositories_count
attr_in_percentage :repositories_verified, :repositories_verified_count, :repositories_count attr_in_percentage :repositories_verified, :repositories_verified_count, :repositories_count
attr_in_percentage :repositories_checked, :repositories_checked_count, :repositories_count attr_in_percentage :repositories_checked, :repositories_checked_count, :repositories_count
attr_in_percentage :wikis_synced, :wikis_synced_count, :wikis_count attr_in_percentage :wikis_synced, :wikis_synced_count, :wikis_count
attr_in_percentage :wikis_checksummed, :wikis_checksummed_count, :wikis_count attr_in_percentage :wikis_checksummed, :wikis_checksummed_count, :wikis_count
attr_in_percentage :wikis_verified, :wikis_verified_count, :wikis_count attr_in_percentage :wikis_verified, :wikis_verified_count, :wikis_count
attr_in_percentage :lfs_objects_synced, :lfs_objects_synced_count, :lfs_objects_count attr_in_percentage :lfs_objects_synced, :lfs_objects_synced_count, :lfs_objects_count
attr_in_percentage :job_artifacts_synced, :job_artifacts_synced_count, :job_artifacts_count attr_in_percentage :job_artifacts_synced, :job_artifacts_synced_count, :job_artifacts_count
attr_in_percentage :attachments_synced, :attachments_synced_count, :attachments_count attr_in_percentage :attachments_synced, :attachments_synced_count, :attachments_count
attr_in_percentage :replication_slots_used, :replication_slots_used_count, :replication_slots_count attr_in_percentage :replication_slots_used, :replication_slots_used_count, :replication_slots_count
attr_in_percentage :container_repositories_synced, :container_repositories_synced_count, :container_repositories_count
def storage_shards_match? def storage_shards_match?
return true if geo_node.primary? return true if geo_node.primary?
...@@ -293,16 +298,30 @@ class GeoNodeStatus < ApplicationRecord ...@@ -293,16 +298,30 @@ class GeoNodeStatus < ApplicationRecord
self.repositories_failed_count = registries_for_failed_projects(:repository).count self.repositories_failed_count = registries_for_failed_projects(:repository).count
self.wikis_synced_count = registries_for_synced_projects(:wiki).count self.wikis_synced_count = registries_for_synced_projects(:wiki).count
self.wikis_failed_count = registries_for_failed_projects(:wiki).count self.wikis_failed_count = registries_for_failed_projects(:wiki).count
load_lfs_objects_data
load_job_artifacts_data
load_attachments_data
load_container_registry_data
end
def load_lfs_objects_data
self.lfs_objects_count = lfs_objects_finder.count_syncable self.lfs_objects_count = lfs_objects_finder.count_syncable
self.lfs_objects_synced_count = lfs_objects_finder.count_synced self.lfs_objects_synced_count = lfs_objects_finder.count_synced
self.lfs_objects_failed_count = lfs_objects_finder.count_failed self.lfs_objects_failed_count = lfs_objects_finder.count_failed
self.lfs_objects_registry_count = lfs_objects_finder.count_registry self.lfs_objects_registry_count = lfs_objects_finder.count_registry
self.lfs_objects_synced_missing_on_primary_count = lfs_objects_finder.count_synced_missing_on_primary self.lfs_objects_synced_missing_on_primary_count = lfs_objects_finder.count_synced_missing_on_primary
end
def load_job_artifacts_data
self.job_artifacts_count = job_artifacts_finder.count_syncable self.job_artifacts_count = job_artifacts_finder.count_syncable
self.job_artifacts_synced_count = job_artifacts_finder.count_synced self.job_artifacts_synced_count = job_artifacts_finder.count_synced
self.job_artifacts_failed_count = job_artifacts_finder.count_failed self.job_artifacts_failed_count = job_artifacts_finder.count_failed
self.job_artifacts_registry_count = job_artifacts_finder.count_registry self.job_artifacts_registry_count = job_artifacts_finder.count_registry
self.job_artifacts_synced_missing_on_primary_count = job_artifacts_finder.count_synced_missing_on_primary self.job_artifacts_synced_missing_on_primary_count = job_artifacts_finder.count_synced_missing_on_primary
end
def load_attachments_data
self.attachments_count = attachments_finder.count_syncable self.attachments_count = attachments_finder.count_syncable
self.attachments_synced_count = attachments_finder.count_synced self.attachments_synced_count = attachments_finder.count_synced
self.attachments_failed_count = attachments_finder.count_failed self.attachments_failed_count = attachments_finder.count_failed
...@@ -310,6 +329,13 @@ class GeoNodeStatus < ApplicationRecord ...@@ -310,6 +329,13 @@ class GeoNodeStatus < ApplicationRecord
self.attachments_synced_missing_on_primary_count = attachments_finder.count_synced_missing_on_primary self.attachments_synced_missing_on_primary_count = attachments_finder.count_synced_missing_on_primary
end end
def load_container_registry_data
self.container_repositories_count = container_repository_finder.count_syncable
self.container_repositories_synced_count = container_repository_finder.count_synced
self.container_repositories_failed_count = container_repository_finder.count_failed
self.container_repositories_registry_count = container_repository_finder.count_registry
end
def load_repository_check_data def load_repository_check_data
if Gitlab::Geo.primary? if Gitlab::Geo.primary?
self.repositories_checked_count = Project.where.not(last_repository_check_at: nil).count self.repositories_checked_count = Project.where.not(last_repository_check_at: nil).count
...@@ -356,6 +382,10 @@ class GeoNodeStatus < ApplicationRecord ...@@ -356,6 +382,10 @@ class GeoNodeStatus < ApplicationRecord
@job_artifacts_finder ||= Geo::JobArtifactRegistryFinder.new(current_node_id: geo_node.id) @job_artifacts_finder ||= Geo::JobArtifactRegistryFinder.new(current_node_id: geo_node.id)
end end
def container_repository_finder
@container_repository_finder ||= Geo::ContainerRepositoryRegistryFinder.new(current_node_id: geo_node.id)
end
def registries_for_synced_projects(type) def registries_for_synced_projects(type)
Geo::ProjectRegistrySyncedFinder Geo::ProjectRegistrySyncedFinder
.new(current_node: geo_node, type: type) .new(current_node: geo_node, type: type)
......
---
title: Add counter columns to geo_node_statuses database table
merge_request: 14943
author:
type: other
...@@ -564,6 +564,13 @@ module EE ...@@ -564,6 +564,13 @@ module EE
number_to_percentage(node.job_artifacts_synced_in_percentage, precision: 2) number_to_percentage(node.job_artifacts_synced_in_percentage, precision: 2)
end end
expose :container_repositories_count
expose :container_repositories_synced_count
expose :container_repositories_failed_count
expose :container_repositories_synced_in_percentage do |node|
number_to_percentage(node.container_repositories_synced_in_percentage, precision: 2)
end
expose :projects_count expose :projects_count
expose :repositories_failed_count expose :repositories_failed_count
......
...@@ -292,6 +292,13 @@ namespace :geo do ...@@ -292,6 +292,13 @@ namespace :geo do
print "#{current_node_status.job_artifacts_synced_count}/#{current_node_status.job_artifacts_count} " print "#{current_node_status.job_artifacts_synced_count}/#{current_node_status.job_artifacts_count} "
puts using_percentage(current_node_status.job_artifacts_synced_in_percentage) puts using_percentage(current_node_status.job_artifacts_synced_in_percentage)
if Gitlab.config.geo.registry_replication.enabled
print 'Container repositories: '.rjust(GEO_STATUS_COLUMN_WIDTH)
show_failed_value(current_node_status.container_repositories_failed_count)
print "#{current_node_status.container_repositories_synced_count || 0}/#{current_node_status.container_repositories_count || 0} "
puts using_percentage(current_node_status.container_repositories_synced_in_percentage)
end
if Gitlab::CurrentSettings.repository_checks_enabled if Gitlab::CurrentSettings.repository_checks_enabled
print 'Repositories Checked: '.rjust(GEO_STATUS_COLUMN_WIDTH) print 'Repositories Checked: '.rjust(GEO_STATUS_COLUMN_WIDTH)
show_failed_value(current_node_status.repositories_checked_failed_count) show_failed_value(current_node_status.repositories_checked_failed_count)
......
...@@ -17,6 +17,9 @@ FactoryBot.define do ...@@ -17,6 +17,9 @@ FactoryBot.define do
job_artifacts_failed_count 3 job_artifacts_failed_count 3
job_artifacts_synced_count 577 job_artifacts_synced_count 577
job_artifacts_synced_missing_on_primary_count 91 job_artifacts_synced_missing_on_primary_count 91
container_repositories_count 400
container_repositories_failed_count 3
container_repositories_synced_count 200
projects_count 10 projects_count 10
repositories_synced_count 5 repositories_synced_count 5
repositories_failed_count 0 repositories_failed_count 0
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
"job_artifacts_synced_count", "job_artifacts_synced_count",
"job_artifacts_synced_missing_on_primary_count", "job_artifacts_synced_missing_on_primary_count",
"db_replication_lag_seconds", "db_replication_lag_seconds",
"container_repositories_count",
"container_repositories_failed_count",
"container_repositories_synced_count",
"projects_count", "projects_count",
"repositories_failed_count", "repositories_failed_count",
"repositories_synced_count", "repositories_synced_count",
...@@ -81,6 +84,10 @@ ...@@ -81,6 +84,10 @@
"job_artifacts_synced_count": { "type": ["integer", "null"] }, "job_artifacts_synced_count": { "type": ["integer", "null"] },
"job_artifacts_synced_missing_on_primary_count": { "type": ["integer", "null"] }, "job_artifacts_synced_missing_on_primary_count": { "type": ["integer", "null"] },
"job_artifacts_synced_in_percentage": { "type": "string" }, "job_artifacts_synced_in_percentage": { "type": "string" },
"container_repositories_count": { "type": "integer" },
"container_repositories_failed_count": { "type": ["integer", "null"] },
"container_repositories_synced_count": { "type": ["integer", "null"] },
"container_repositories_synced_in_percentage": { "type": "string" },
"projects_count": { "type": "integer" }, "projects_count": { "type": "integer" },
"repositories_failed_count": { "type": ["integer", "null"] }, "repositories_failed_count": { "type": ["integer", "null"] },
"repository_verification_enabled": { "type": "boolean" }, "repository_verification_enabled": { "type": "boolean" },
......
...@@ -74,6 +74,10 @@ export const rawMockNodeDetails = { ...@@ -74,6 +74,10 @@ export const rawMockNodeDetails = {
job_artifacts_synced_count: 0, job_artifacts_synced_count: 0,
job_artifacts_failed_count: 0, job_artifacts_failed_count: 0,
job_artifacts_synced_in_percentage: '0.00%', job_artifacts_synced_in_percentage: '0.00%',
container_repositories_count: 0,
container_repositories_synced_count: 0,
container_repositories_failed_count: 0,
container_repositories_synced_in_percentage: '0.00%',
repositories_failed_count: 0, repositories_failed_count: 0,
repositories_synced_count: 12, repositories_synced_count: 12,
repositories_synced_in_percentage: '100.00%', repositories_synced_in_percentage: '100.00%',
...@@ -179,6 +183,11 @@ export const mockNodeDetails = { ...@@ -179,6 +183,11 @@ export const mockNodeDetails = {
successCount: 0, successCount: 0,
failureCount: 0, failureCount: 0,
}, },
containerRepositories: {
totalCount: 0,
successCount: 0,
failureCount: 0,
},
attachments: { attachments: {
totalCount: 0, totalCount: 0,
successCount: 0, successCount: 0,
......
...@@ -83,6 +83,18 @@ describe EE::API::Entities::GeoNodeStatus do ...@@ -83,6 +83,18 @@ describe EE::API::Entities::GeoNodeStatus do
end end
end end
describe '#container_repositories_synced_in_percentage' do
it 'formats as percentage' do
geo_node_status.assign_attributes(
container_repositories_count: 256,
container_repositories_failed_count: 12,
container_repositories_synced_count: 123
)
expect(subject[:container_repositories_synced_in_percentage]).to eq '48.05%'
end
end
describe '#repositories_synced_in_percentage' do describe '#repositories_synced_in_percentage' do
it 'formats as percentage' do it 'formats as percentage' do
geo_node_status.assign_attributes(projects_count: 10, geo_node_status.assign_attributes(projects_count: 10,
......
...@@ -637,6 +637,72 @@ describe GeoNodeStatus, :geo, :geo_fdw do ...@@ -637,6 +637,72 @@ describe GeoNodeStatus, :geo, :geo_fdw do
end end
end end
describe '#container_repositories_count' do
it 'counts all the repositories' do
create(:container_repository)
create(:container_repository)
expect(subject.container_repositories_count).to eq(2)
end
end
describe '#container_repositories_synced_count' do
it 'counts synced repositories' do
create(:container_repository_registry, :synced)
create(:container_repository_registry, :synced)
create(:container_repository_registry, :sync_failed)
expect(subject.container_repositories_synced_count).to eq(2)
end
end
describe '#container_repositories_failed_count' do
it 'counts failed to sync repositories' do
create(:container_repository_registry, :synced)
create(:container_repository_registry, :sync_failed)
create(:container_repository_registry, :sync_failed)
expect(subject.container_repositories_failed_count).to eq(2)
end
end
describe '#container_repositories_registry_count' do
it 'counts number of registries for repositories' do
create(:container_repository_registry, :synced)
create(:container_repository_registry, :sync_failed)
create(:container_repository_registry, :sync_failed)
create(:container_repository)
expect(subject.container_repositories_registry_count).to eq(3)
end
end
describe '#container_repositories_synced_in_percentage' do
let(:container_repository) { create(:container_repository, project: project_1) }
before do
create(:container_repository, project: project_1)
create_list(:container_repository, 2, project: project_3)
end
it 'returns 0 when no objects are available' do
expect(subject.container_repositories_synced_in_percentage).to eq(0)
end
it 'returns the right percentage with no group restrictions' do
create(:container_repository_registry, :synced, container_repository: container_repository)
expect(subject.container_repositories_synced_in_percentage).to be_within(0.0001).of(25)
end
it 'returns the right percentage with group restrictions' do
secondary.update!(selective_sync_type: 'namespaces', namespaces: [group])
create(:container_repository_registry, :synced, container_repository: container_repository)
expect(subject.container_repositories_synced_in_percentage).to be_within(0.0001).of(50)
end
end
describe '#repositories_verified_count' do describe '#repositories_verified_count' do
before do before do
stub_current_geo_node(secondary) stub_current_geo_node(secondary)
......
...@@ -265,6 +265,9 @@ describe API::Geo do ...@@ -265,6 +265,9 @@ describe API::Geo do
job_artifacts_synced_count: 50, job_artifacts_synced_count: 50,
job_artifacts_failed_count: 12, job_artifacts_failed_count: 12,
job_artifacts_synced_missing_on_primary_count: 5, job_artifacts_synced_missing_on_primary_count: 5,
container_repositories_count: 100,
container_repositories_synced_count: 50,
container_repositories_failed_count: 12,
attachments_count: 30, attachments_count: 30,
attachments_synced_count: 30, attachments_synced_count: 30,
attachments_failed_count: 25, attachments_failed_count: 25,
......
...@@ -28,6 +28,9 @@ describe Geo::MetricsUpdateService, :geo, :prometheus do ...@@ -28,6 +28,9 @@ describe Geo::MetricsUpdateService, :geo, :prometheus do
job_artifacts_synced_count: 50, job_artifacts_synced_count: 50,
job_artifacts_failed_count: 12, job_artifacts_failed_count: 12,
job_artifacts_synced_missing_on_primary_count: 5, job_artifacts_synced_missing_on_primary_count: 5,
container_repositories_count: 100,
container_repositories_synced_count: 50,
container_repositories_failed_count: 12,
attachments_count: 30, attachments_count: 30,
attachments_synced_count: 30, attachments_synced_count: 30,
attachments_failed_count: 25, attachments_failed_count: 25,
...@@ -56,6 +59,7 @@ describe Geo::MetricsUpdateService, :geo, :prometheus do ...@@ -56,6 +59,7 @@ describe Geo::MetricsUpdateService, :geo, :prometheus do
lfs_objects_count: 100, lfs_objects_count: 100,
job_artifacts_count: 100, job_artifacts_count: 100,
attachments_count: 30, attachments_count: 30,
container_repositories_count: 100,
last_event_id: 2, last_event_id: 2,
last_event_date: event_date, last_event_date: event_date,
event_log_max_id: 555 event_log_max_id: 555
......
...@@ -6604,6 +6604,9 @@ msgstr "" ...@@ -6604,6 +6604,9 @@ msgstr ""
msgid "GeoNodes|Local attachments" msgid "GeoNodes|Local attachments"
msgstr "" msgstr ""
msgid "GeoNodes|Local container repositories"
msgstr ""
msgid "GeoNodes|Local job artifacts" msgid "GeoNodes|Local job artifacts"
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