Commit 1868378f authored by Mike Greiling's avatar Mike Greiling

Merge branch 'mk/suggest-geo-check-in-error' into 'master'

Geo: Help admins diagnose configuration problems

Closes #10342

See merge request gitlab-org/gitlab-ee!9988
parents e15bb700 0d442d26
......@@ -23,12 +23,69 @@ to help identify if something is wrong:
![Geo health check](img/geo_node_healthcheck.png)
There is also an option to check the status of the **secondary** node by running a special rake task:
If the UI is not working, or you are unable to log in, you can run the Geo
health check manually to get this information as well as a few more details.
This rake task can be run on an app node in the **primary** or **secondary**
Geo nodes:
```sh
sudo gitlab-rake gitlab:geo:check
```
Example output:
```
Checking Geo ...
GitLab Geo is available ... yes
GitLab Geo is enabled ... yes
GitLab Geo secondary database is correctly configured ... yes
Using database streaming replication? ... yes
GitLab Geo tracking database is configured to use Foreign Data Wrapper? ... yes
GitLab Geo tracking database Foreign Data Wrapper schema is up-to-date? ... yes
GitLab Geo HTTP(S) connectivity ...
* Can connect to the primary node ... yes
HTTP/HTTPS repository cloning is enabled ... yes
Machine clock is synchronized ... yes
Git user has default SSH configuration? ... yes
OpenSSH configured to use AuthorizedKeysCommand ... yes
GitLab configured to disable writing to authorized_keys file ... yes
GitLab configured to store new projects in hashed storage? ... yes
All projects are in hashed storage? ... yes
Checking Geo ... Finished
```
Current sync information can be found manually by running this rake task on any
**secondary** app node:
```sh
sudo gitlab-rake geo:status
```
Example output:
```
http://secondary.example.com/
-----------------------------------------------------
GitLab Version: 11.8.1-ee
Geo Role: Secondary
Health Status: Healthy
Repositories: 190/190 (100%)
Verified Repositories: 190/190 (100%)
Wikis: 190/190 (100%)
Verified Wikis: 190/190 (100%)
LFS Objects: 35/35 (100%)
Attachments: 528/528 (100%)
CI job artifacts: 477/477 (100%)
Repositories Checked: 0/190 (0%)
Sync Settings: Full
Database replication lag: 0 seconds
Last event ID seen from primary: 2158 (about 2 minute ago)
Last event ID processed by cursor: 2158 (about 2 minute ago)
Last status report was: 4 minutes ago
```
## Is Postgres replication working?
### Are my nodes pointing to the correct database instance?
......
......@@ -34,6 +34,10 @@ export default {
type: Boolean,
required: true,
},
geoTroubleshootingHelpPath: {
type: String,
required: true,
},
},
data() {
return {
......@@ -213,6 +217,7 @@ export default {
:primary-node="node.primary"
:node-actions-allowed="nodeActionsAllowed"
:node-edit-allowed="nodeEditAllowed"
:geo-troubleshooting-help-path="geoTroubleshootingHelpPath"
/>
<deprecated-modal
v-show="showModal"
......
<script>
/* eslint-disable vue/no-side-effects-in-computed-properties */
import { GlLink } from '@gitlab/ui';
import { s__ } from '~/locale';
import NodeDetailsSectionMain from './node_detail_sections/node_details_section_main.vue';
......@@ -9,6 +10,7 @@ import NodeDetailsSectionOther from './node_detail_sections/node_details_section
export default {
components: {
GlLink,
NodeDetailsSectionMain,
NodeDetailsSectionSync,
NodeDetailsSectionVerification,
......@@ -31,6 +33,10 @@ export default {
type: Boolean,
required: true,
},
geoTroubleshootingHelpPath: {
type: String,
required: true,
},
},
data() {
return {
......@@ -80,7 +86,12 @@ export default {
:node-type-primary="node.primary"
/>
<div v-if="hasError || hasVersionMismatch" class="node-health-message-container">
<p class="node-health-message">{{ errorMessage }}</p>
<p class="node-health-message">
{{ errorMessage }}
<gl-link :href="geoTroubleshootingHelpPath">{{
s__('Geo|Please refer to Geo Troubleshooting.')
}}</gl-link>
</p>
</div>
</div>
</template>
<script>
import { GlLink } from '@gitlab/ui';
import eventHub from '../event_hub';
import GeoNodeHeader from './geo_node_header.vue';
......@@ -6,6 +8,7 @@ import GeoNodeDetails from './geo_node_details.vue';
export default {
components: {
GlLink,
GeoNodeHeader,
GeoNodeDetails,
},
......@@ -26,6 +29,10 @@ export default {
type: Boolean,
required: true,
},
geoTroubleshootingHelpPath: {
type: String,
required: true,
},
},
data() {
return {
......@@ -84,9 +91,15 @@ export default {
:node-details="nodeDetails"
:node-edit-allowed="nodeEditAllowed"
:node-actions-allowed="nodeActionsAllowed"
:geo-troubleshooting-help-path="geoTroubleshootingHelpPath"
/>
<div v-if="isNodeDetailsFailed" class="node-health-message-container">
<p class="health-message node-health-message">{{ errorMessage }}</p>
<p class="node-health-message">
{{ errorMessage
}}<gl-link :href="geoTroubleshootingHelpPath">{{
s__('Geo|Please refer to Geo Troubleshooting.')
}}</gl-link>
</p>
</div>
</div>
</template>
......@@ -18,6 +18,10 @@ export default {
type: Boolean,
required: true,
},
geoTroubleshootingHelpPath: {
type: String,
required: true,
},
},
};
</script>
......@@ -31,6 +35,7 @@ export default {
:primary-node="node.primary"
:node-actions-allowed="nodeActionsAllowed"
:node-edit-allowed="nodeEditAllowed"
:geo-troubleshooting-help-path="geoTroubleshootingHelpPath"
/>
</div>
</template>
......@@ -24,9 +24,10 @@ export default () => {
},
data() {
const { dataset } = this.$options.el;
const { primaryVersion, primaryRevision, geoTroubleshootingHelpPath } = dataset;
const nodeActionsAllowed = parseBoolean(dataset.nodeActionsAllowed);
const nodeEditAllowed = parseBoolean(dataset.nodeEditAllowed);
const store = new GeoNodesStore(dataset.primaryVersion, dataset.primaryRevision);
const store = new GeoNodesStore(primaryVersion, primaryRevision);
const service = new GeoNodesService();
return {
......@@ -34,6 +35,7 @@ export default () => {
service,
nodeActionsAllowed,
nodeEditAllowed,
geoTroubleshootingHelpPath,
};
},
render(createElement) {
......@@ -43,6 +45,7 @@ export default () => {
service: this.service,
nodeActionsAllowed: this.nodeActionsAllowed,
nodeEditAllowed: this.nodeEditAllowed,
geoTroubleshootingHelpPath: this.geoTroubleshootingHelpPath,
},
});
},
......
......@@ -85,7 +85,7 @@
.node-health-message {
margin-bottom: 0;
padding: 2px $gl-padding-8;
padding: $gl-padding;
background-color: $red-100;
color: $red-500;
}
......
......@@ -30,7 +30,8 @@ module EE
primary_version: version.to_s,
primary_revision: revision.to_s,
node_actions_allowed: ::Gitlab::Database.db_read_write?.to_s,
node_edit_allowed: ::Gitlab::Geo.license_allows?.to_s
node_edit_allowed: ::Gitlab::Geo.license_allows?.to_s,
geo_troubleshooting_help_path: help_page_path('administration/geo/replication/troubleshooting.md')
}
end
......
---
title: 'Geo: Help admins diagnose configuration problems'
merge_request: 9988
author:
type: added
......@@ -26,6 +26,7 @@ const createComponent = () => {
service,
nodeActionsAllowed: true,
nodeEditAllowed: true,
geoTroubleshootingHelpPath: '/foo/bar',
});
};
......
......@@ -17,6 +17,7 @@ const createComponent = ({
nodeDetails,
nodeActionsAllowed,
nodeEditAllowed,
geoTroubleshootingHelpPath: '/foo/bar',
});
};
......@@ -80,5 +81,17 @@ describe('GeoNodeDetailsComponent', () => {
it('renders container elements correctly', () => {
expect(vm.$el.classList.contains('card-body')).toBe(true);
});
it('renders troubleshooting URL within error message section', done => {
vm.nodeDetails.healthy = false;
vm.errorMessage = 'Foobar';
vm.$nextTick(() => {
expect(vm.$el.querySelector('.node-health-message-container a').getAttribute('href')).toBe(
'/foo/bar',
);
done();
});
});
});
});
......@@ -13,6 +13,7 @@ const createComponent = (node = mockNode) => {
primaryNode: true,
nodeActionsAllowed: true,
nodeEditAllowed: true,
geoTroubleshootingHelpPath: '/foo/bar',
});
};
......@@ -147,8 +148,11 @@ describe('GeoNodeItemComponent', () => {
vm.isNodeDetailsFailed = true;
vm.errorMessage = err;
Vue.nextTick(() => {
expect(vm.$el.querySelectorAll('p.health-message').length).not.toBe(0);
expect(vm.$el.querySelector('p.health-message').innerText.trim()).toBe(err);
expect(vm.$el.querySelectorAll('p.node-health-message').length).not.toBe(0);
expect(vm.$el.querySelector('p.node-health-message').innerText.trim()).toContain(err);
expect(vm.$el.querySelector('p.node-health-message a').getAttribute('href')).toBe(
'/foo/bar',
);
done();
});
});
......
......@@ -11,6 +11,7 @@ const createComponent = () => {
nodes: mockNodes,
nodeActionsAllowed: true,
nodeEditAllowed: true,
geoTroubleshootingHelpPath: '/foo/bar',
});
};
......
......@@ -4938,6 +4938,9 @@ msgstr ""
msgid "Geo|Pending verification"
msgstr ""
msgid "Geo|Please refer to Geo Troubleshooting."
msgstr ""
msgid "Geo|Project (ID: %{project_id}) no longer exists on the primary. It is safe to remove this entry, as this will not remove any data on disk."
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