Commit 295a408a authored by Stan Hu's avatar Stan Hu

Merge branch 'da-geo-verify-gitlab-version' into 'master'

Resolve "Geo - Send GitLab version in status page and verify that all versions are the same"

Closes #2115

See merge request gitlab-org/gitlab-ee!3667
parents 0c625e59 450d1a88
......@@ -13,6 +13,8 @@ const healthyIcon = 'fa-check';
const unhealthyIcon = 'fa-times';
const unknownIcon = 'fa-times';
const notAvailable = 'Not Available';
const versionMismatch = 'Does not match the primary node version';
const versionMismatchClass = 'geo-node-version-mismatch';
class GeoNodeStatus {
constructor(el) {
......@@ -29,9 +31,13 @@ class GeoNodeStatus {
this.$lastEventSeen = $('.js-last-event-seen', this.$status);
this.$lastCursorEvent = $('.js-last-cursor-event', this.$status);
this.$health = $('.js-health-message', this.$status.parent());
this.$version = $('.js-gitlab-version', this.$status);
this.$secondaryVersion = $('.js-secondary-version', this.$status);
this.endpoint = this.$el.data('status-url');
this.$advancedStatus = $('.js-advanced-geo-node-status-toggler', this.$status.parent());
this.$advancedStatus.on('click', GeoNodeStatus.toggleShowAdvancedStatus.bind(this));
this.primaryVersion = $('.js-primary-version').text();
this.primaryRevision = $('.js-primary-revision').text().replace(/\W/g, '');
this.statusInterval = new SmartInterval({
callback: this.getStatus.bind(this),
......@@ -182,6 +188,7 @@ class GeoNodeStatus {
healthStatus: status.health_status,
healthMessage: status.health,
});
this.$version.text(status.version);
// Replication lag can be nil if the secondary isn't actually streaming
if (status.db_replication_lag_seconds !== null && status.db_replication_lag_seconds >= 0) {
......@@ -194,6 +201,15 @@ class GeoNodeStatus {
this.$dbReplicationLag.text('UNKNOWN');
}
if (!this.primaryVersion || (this.primaryVersion === status.version
&& this.primaryRevision === status.revision)) {
this.$secondaryVersion.removeClass(`${versionMismatchClass}`);
this.$secondaryVersion.text(`${status.version} (${status.revision})`);
} else {
this.$secondaryVersion.addClass(`${versionMismatchClass}`);
this.$secondaryVersion.text(`${status.version} (${status.revision}) - ${versionMismatch}`);
}
if (status.repositories_count > 0) {
const repositoriesStats = GeoNodeStatus.getSyncStatistics({
syncedCount: status.repositories_synced_count,
......
......@@ -127,6 +127,10 @@
}
}
.geo-node-version-mismatch {
color: $gl-danger;
}
.node-badge {
color: $white-light;
display: inline-block;
......
......@@ -2,8 +2,7 @@ class GeoNodeStatus < ActiveRecord::Base
belongs_to :geo_node
# Whether we were successful in reaching this node
attr_accessor :success
attr_accessor :health_status
attr_accessor :success, :health_status, :version, :revision
# Be sure to keep this consistent with Prometheus naming conventions
PROMETHEUS_METRICS = {
......@@ -48,7 +47,7 @@ class GeoNodeStatus < ActiveRecord::Base
def self.allowed_params
excluded_params = %w(id created_at updated_at).freeze
extra_params = %w(success health health_status last_event_timestamp cursor_last_event_timestamp).freeze
extra_params = %w(success health health_status last_event_timestamp cursor_last_event_timestamp version revision).freeze
self.column_names - excluded_params + extra_params
end
......
......@@ -39,9 +39,22 @@ class GeoNodeStatusEntity < Grape::Entity
expose :last_successful_status_check_timestamp
expose :version
expose :revision
expose :namespaces, using: NamespaceEntity
private
def namespaces
object.geo_node.namespaces
end
def version
Gitlab::VERSION
end
def revision
Gitlab::REVISION
end
end
......@@ -29,14 +29,27 @@
.node-badge.current-node Current node
- if node.primary?
.node-badge.primary-node Primary
%span.help-block Primary node
%p
%span.help-block Primary node
%p
%span.help-block
GitLab version:
%span.js-primary-version= Gitlab::VERSION
%small.js-primary-revision
= "(#{Gitlab::REVISION})"
- else
= status_loading_icon
%table.geo-node-status.js-geo-node-status.hidden
%tr
%td
.help-block
GitLab version:
%td
.node-info.prepend-top-5.prepend-left-5.js-secondary-version
- if node.enabled?
%tr
%td
.help-block
.help-block.prepend-top-10
Health Status:
%td
.health-status.prepend-top-10.prepend-left-5.js-health-status
......
---
title: Geo - Show GitLab version for each node in the Geo status page
merge_request:
author:
type: added
......@@ -97,7 +97,9 @@ Example response:
"last_event_timestamp": 1509681166,
"cursor_last_event_id": 23,
"cursor_last_event_timestamp": 1509681166,
"last_successful_status_check_timestamp": 1510125024
"last_successful_status_check_timestamp": 1510125024,
"version": "10.3.0",
"revision": "33d33a096a"
}
]
```
......@@ -136,7 +138,9 @@ Example response:
"last_event_timestamp": 1509681166,
"cursor_last_event_id": 23,
"cursor_last_event_timestamp": 1509681166,
"last_successful_status_check_timestamp": 1510125268
"last_successful_status_check_timestamp": 1510125268,
"version": "10.3.0",
"revision": "33d33a096a"
}
```
......
......@@ -19,7 +19,9 @@
"last_event_timestamp",
"cursor_last_event_id",
"cursor_last_event_timestamp",
"namespaces"
"namespaces",
"version",
"revision"
],
"properties" : {
"geo_node_id": { "type": "integer" },
......@@ -44,7 +46,9 @@
"cursor_last_event_id": { "type": ["integer", "null"] },
"cursor_last_event_timestamp": { "type": ["integer", "null"] },
"last_successful_status_check_timestamp": { "type": ["integer", "null"] },
"namespaces": { "type": "array" }
"namespaces": { "type": "array" },
"version": { "type": ["string"] },
"revision": { "type": ["string"] }
},
"additionalProperties": false
}
......@@ -62,7 +62,9 @@ describe API::GeoNodes, :geo, api: true do
describe 'GET /geo_nodes/:id/status' do
it 'retrieves the Geo nodes status if admin is logged in' do
stub_current_geo_node(primary)
expect(GeoNodeStatus).not_to receive(:current_node_status)
get api("/geo_nodes/#{secondary.id}/status", admin)
expect(response).to have_gitlab_http_status(200)
......@@ -71,6 +73,7 @@ describe API::GeoNodes, :geo, api: true do
it 'fetches the current node status' do
stub_current_geo_node(secondary)
expect(GeoNode).to receive(:find).and_return(secondary)
expect(GeoNodeStatus).to receive(:current_node_status).and_call_original
......
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