Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-07-24 12:09:32 +00:00
parent fd7c75bf60
commit f296f23500
85 changed files with 2607 additions and 1745 deletions

View File

@ -105,6 +105,12 @@ trigger-omnibus:
branch: $TRIGGER_BRANCH
strategy: depend
# Same as trigger-omnibus but is manual and runs follow-up-e2e:package-and-test-ee automatically right after
trigger-omnibus-and-follow-up-e2e:
extends:
- trigger-omnibus
- .qa:rules:manual-omnibus-and-follow-up-e2e
trigger-omnibus as-if-foss:
extends:
- trigger-omnibus
@ -129,6 +135,20 @@ e2e:package-and-test-ee:
QA_RUN_TYPE: e2e-package-and-test
PIPELINE_NAME: E2E Omnibus GitLab EE
# Same as e2e:package-and-test-ee but runs automatically after trigger-omnibus-and-follow-up-e2e
follow-up-e2e:package-and-test-ee:
extends:
- .e2e-trigger-base
- .qa:rules:follow-up-e2e
needs:
- build-qa-image
- trigger-omnibus-and-follow-up-e2e
- e2e-test-pipeline-generate
variables:
RELEASE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/build/omnibus-gitlab-mirror/gitlab-ee:${CI_COMMIT_SHA}"
QA_RUN_TYPE: e2e-package-and-test
PIPELINE_NAME: E2E Omnibus GitLab EE
e2e:package-and-test-ce:
extends:
- e2e:package-and-test-ee
@ -187,4 +207,3 @@ e2e:test-on-gdk:
DYNAMIC_PIPELINE_YML: test-on-gdk-pipeline.yml
SKIP_MESSAGE: Skipping test-on-gdk due to mr containing only quarantine changes!
GDK_IMAGE: "${CI_REGISTRY_IMAGE}/gitlab-qa-gdk:${CI_COMMIT_SHA}"
allow_failure: true

View File

@ -892,6 +892,8 @@
# - build the final stage in code-change pipelines (including MRs), and scheduled pipelines
# This has to match ".qa:rules:e2e:test-on-gdk" otherwise there won't be an image available to run GDK in the test jobs.
# Unfortunately, we can't just include ".qa:rules:e2e:test-on-gdk" because some of the conditions are manual
# Since the smoke test job is not allowed to fail, the `build-gdk-image` job is also not allowed to fail.
# It's better to fail early and avoid wasting resources running test jobs that would just fail anyway.
.build-images:rules:build-gdk-image:
rules:
- if: '$QA_RUN_TESTS_ON_GDK !~ /true|yes|1/i'
@ -902,7 +904,6 @@
- <<: *if-default-branch-refs # Includes scheduled pipelines
variables:
BUILD_GDK_BASE: "true"
allow_failure: true
# We want to also rebuild the base image if MRs change certain components.
- <<: *if-merge-request
variables:
@ -916,37 +917,32 @@
- GITLAB_METRICS_EXPORTER_VERSION
- GITLAB_SHELL_VERSION
- GITALY_SERVER_VERSION
allow_failure: true
# The rest are included to be consistent with .qa:rules:e2e:test-on-gdk
- <<: *if-merge-request-targeting-stable-branch
changes: *setup-test-env-patterns
allow_failure: true
- <<: *if-ruby3_1-branch
allow_failure: true
# We include the job under the matching conditions below, but unlike in .qa:rules:e2e:test-on-gdk we don't need to
# set OMNIBUS_GITLAB_BUILD_ON_ALL_OS when testing against GDK
- <<: *if-merge-request
changes: *dependency-patterns
allow_failure: true
- <<: *if-merge-request-labels-run-all-e2e
allow_failure: true
- <<: *if-merge-request
changes: *feature-flag-development-config-patterns
allow_failure: true
- <<: *if-merge-request
changes: *initializers-patterns
allow_failure: true
- <<: *if-merge-request
changes: *nodejs-patterns
allow_failure: true
- <<: *if-merge-request
changes: *ci-qa-patterns
allow_failure: true
- <<: *if-dot-com-gitlab-org-and-security-merge-request-manual-ff-package-and-e2e
changes: *feature-flag-development-config-patterns
when: manual
- <<: *if-dot-com-gitlab-org-and-security-merge-request-and-qa-tests-specified
changes: *code-patterns
- <<: *if-merge-request
changes: *code-qa-patterns
allow_failure: true
- <<: *if-force-ci
allow_failure: true
when: manual
.build-images:rules:build-assets-image:
rules:
@ -1452,6 +1448,43 @@
- <<: *if-force-ci
allow_failure: true
# All rules copied from qa:rules:package-and-test-ee but jobs are automatic and not allowed to fail
.qa:rules:trigger-omnibus-env:
rules:
# From .qa:rules:package-and-test-common
- !reference [".qa:rules:package-and-test-never-run", rules]
- <<: *if-merge-request-targeting-stable-branch
changes: *setup-test-env-patterns
- <<: *if-ruby3_1-branch
variables:
USE_OLD_RUBY_VERSION: 'false'
CACHE_EDITION: 'GITLAB_RUBY3_1'
- <<: *if-merge-request
changes: *dependency-patterns
variables:
OMNIBUS_GITLAB_BUILD_ON_ALL_OS: 'true'
- <<: *if-merge-request-labels-run-all-e2e
- <<: *if-dot-com-gitlab-org-and-security-merge-request-manual-ff-package-and-e2e
changes: *feature-flag-development-config-patterns
- <<: *if-merge-request
changes: *feature-flag-development-config-patterns
- <<: *if-merge-request
changes: *initializers-patterns
- <<: *if-merge-request
changes: *nodejs-patterns
- <<: *if-merge-request
changes: *ci-qa-patterns
- <<: *if-merge-request
changes: *qa-patterns
- <<: *if-dot-com-gitlab-org-and-security-merge-request-and-qa-tests-specified
changes: *code-patterns
- <<: *if-force-ci
# From .qa:rules:package-and-test-schedule
- <<: *if-dot-com-gitlab-org-schedule
# From .qa:rules:code-merge-request-manual
- <<: *if-merge-request
changes: *code-patterns
.qa:rules:package-and-test-never-run:
rules:
- <<: *if-not-canonical-namespace
@ -1512,18 +1545,62 @@
# manually. That rule is now in ".qa:rules:code-merge-request-manual" so it can be included when needed and we can
# still use ".qa:rules:package-and-test-common" in jobs we don't want to be manual.
# Like .qa:rules:package-and-test-common but not allowed to fail.
# It's named `e2e` instead of `package-and-test` because it's used for e2e tests on GDK (and could be used
# for other e2e tests)
.qa:rules:e2e-blocking:
rules:
- !reference [".qa:rules:package-and-test-never-run", rules]
- <<: *if-merge-request-targeting-stable-branch
changes: *setup-test-env-patterns
- <<: *if-ruby3_1-branch
variables:
USE_OLD_RUBY_VERSION: 'false'
CACHE_EDITION: 'GITLAB_RUBY3_1'
- <<: *if-merge-request
changes: *dependency-patterns
- <<: *if-merge-request-labels-run-all-e2e
- <<: *if-dot-com-gitlab-org-and-security-merge-request-manual-ff-package-and-e2e
changes: *feature-flag-development-config-patterns
when: manual
- <<: *if-merge-request
changes: *nodejs-patterns
- <<: *if-merge-request
changes:
- qa/Gemfile.lock # qa/Gemfile.lock is a part of *qa-patterns, so this rule must be placed before the one with *qa-patterns changes
variables:
UPDATE_QA_CACHE: "true"
- <<: *if-dot-com-gitlab-org-and-security-merge-request-and-qa-tests-specified
changes: *code-patterns
- <<: *if-merge-request
changes: *code-qa-patterns # Includes all CI changes
- <<: *if-force-ci
when: manual
.qa:e2e-test-schedule-variables: &qa-e2e-test-schedule-variables
variables:
CREATE_TEST_FAILURE_ISSUES: "true"
PROCESS_TEST_RESULTS: "true"
KNAPSACK_GENERATE_REPORT: "true"
UPDATE_QA_CACHE: "true"
QA_SAVE_TEST_METRICS: "true"
QA_EXPORT_TEST_METRICS: "false" # on main runs, metrics are exported to separate bucket via rake task for better consistency
.qa:rules:package-and-test-schedule:
rules:
- <<: *if-dot-com-gitlab-org-schedule
allow_failure: true
variables:
CREATE_TEST_FAILURE_ISSUES: "true"
PROCESS_TEST_RESULTS: "true"
KNAPSACK_GENERATE_REPORT: "true"
UPDATE_QA_CACHE: "true"
QA_SAVE_TEST_METRICS: "true"
QA_EXPORT_TEST_METRICS: "false" # on main runs, metrics are exported to separate bucket via rake task for better consistency
<<: *qa-e2e-test-schedule-variables
.qa:rules:e2e-schedule-blocking:
rules:
- <<: *if-dot-com-gitlab-org-schedule
<<: *qa-e2e-test-schedule-variables
# Note: If any changes are made to this rule, the following should also be updated:
# 1) .qa:rules:manual-omnibus-and-follow-up-e2e
# 2) .qa:rules:follow-up-e2e
# 3) .qa:rules:trigger-omnibus-env
.qa:rules:package-and-test-ee:
rules:
- !reference [".qa:rules:package-and-test-common", rules]
@ -1555,12 +1632,8 @@
when: never
- <<: *if-default-branch-schedule-nightly # already executed in the 2-hourly schedule
when: never
- !reference [".qa:rules:package-and-test-common", rules]
- !reference [".qa:rules:package-and-test-schedule", rules]
# Run automatically in all other code MRs that weren't included in ".qa:rules:package-and-test-common".
- <<: *if-merge-request
changes: *code-patterns
allow_failure: true
- !reference [".qa:rules:e2e-blocking", rules]
- !reference [".qa:rules:e2e-schedule-blocking", rules]
.qa:rules:package-and-test-old-nav:
rules:
@ -1598,6 +1671,94 @@
- !reference [".qa:rules:package-and-test-nightly", rules]
- !reference [".qa:rules:package-and-test-ce", rules]
# These are based on `.qa:rules:trigger-omnibus` but with automatic jobs changed to `when: never.`
# If any changes are made to this rule, `.qa:rules:follow-up-e2e` should also be updated.
.qa:rules:manual-omnibus-and-follow-up-e2e:
rules:
- !reference [".qa:rules:package-and-test-never-run", rules]
- !reference [".qa:rules:code-merge-request-manual", rules]
- <<: *if-dot-com-gitlab-org-schedule
when: never
- <<: *if-merge-request-targeting-stable-branch
changes: *setup-test-env-patterns
when: never
- <<: *if-ruby3_1-branch
when: never
- <<: *if-merge-request
changes: *dependency-patterns
when: never
- <<: *if-merge-request-labels-run-all-e2e
when: never
- <<: *if-dot-com-gitlab-org-and-security-merge-request-manual-ff-package-and-e2e
changes: *feature-flag-development-config-patterns
when: manual
allow_failure: true
- <<: *if-merge-request
changes: *feature-flag-development-config-patterns
when: never
- <<: *if-merge-request
changes: *initializers-patterns
when: never
- <<: *if-merge-request
changes: *nodejs-patterns
when: never
- <<: *if-merge-request
changes: *ci-qa-patterns
when: never
- <<: *if-merge-request
changes: *qa-patterns
when: never
- <<: *if-dot-com-gitlab-org-and-security-merge-request-and-qa-tests-specified
changes: *code-patterns
when: never
- <<: *if-force-ci
when: manual
allow_failure: true
# These are based on `.qa:rules:manual-omnibus-and-follow-up-e2e` but with manual jobs changed to automatic
.qa:rules:follow-up-e2e:
rules:
- !reference [".qa:rules:package-and-test-never-run", rules]
- <<: *if-merge-request
changes: *code-patterns
allow_failure: true
- <<: *if-dot-com-gitlab-org-schedule
when: never
- <<: *if-merge-request-targeting-stable-branch
changes: *setup-test-env-patterns
when: never
- <<: *if-ruby3_1-branch
when: never
- <<: *if-merge-request
changes: *dependency-patterns
when: never
- <<: *if-merge-request-labels-run-all-e2e
when: never
- <<: *if-dot-com-gitlab-org-and-security-merge-request-manual-ff-package-and-e2e
changes: *feature-flag-development-config-patterns
allow_failure: true
- <<: *if-merge-request
changes: *feature-flag-development-config-patterns
when: never
- <<: *if-merge-request
changes: *initializers-patterns
when: never
- <<: *if-merge-request
changes: *nodejs-patterns
when: never
- <<: *if-merge-request
changes: *ci-qa-patterns
when: never
- <<: *if-merge-request
changes: *qa-patterns
when: never
- <<: *if-dot-com-gitlab-org-and-security-merge-request-and-qa-tests-specified
changes: *code-patterns
when: never
- <<: *if-force-ci
allow_failure: true
###############
# Rails rules #
###############

View File

@ -176,7 +176,7 @@ e2e-test-pipeline-generate:
trigger-omnibus-env:
stage: prepare
extends:
- .qa:rules:package-and-test-ee
- .qa:rules:trigger-omnibus-env
needs:
# We need this job because we need its `cached-assets-hash.txt` artifact, so that we can pass the assets image tag to the downstream omnibus-gitlab pipeline.
- compile-production-assets

View File

@ -86,7 +86,6 @@ variables:
dotenv: suite_status.env
expire_in: 7 days
when: always
allow_failure: true
download-knapsack-report:
extends:
@ -143,6 +142,7 @@ gdk-qa-smoke-with-load-balancer:
- changes:
- ".gitlab/ci/test-on-gdk/**"
- "lib/gitlab/database/load_balancing/**/*"
allow_failure: true
gdk-qa-reliable:
extends:
@ -153,6 +153,7 @@ gdk-qa-reliable:
QA_RUN_TYPE: gdk-qa-blocking
rules:
- when: always
allow_failure: true
gdk-qa-reliable-with-load-balancer:
extends:
@ -171,6 +172,7 @@ gdk-qa-reliable-with-load-balancer:
- changes:
- ".gitlab/ci/test-on-gdk/**"
- "lib/gitlab/database/load_balancing/**/*"
allow_failure: true
gdk-qa-non-blocking:
extends:
@ -181,6 +183,7 @@ gdk-qa-non-blocking:
QA_RUN_TYPE: gdk-qa-non-blocking
rules:
- when: manual
allow_failure: true
# ==========================================
# Post test stage

View File

@ -169,7 +169,11 @@ export default {
/>
</div>
<template v-if="getNoteableData.current_user.can_approve">
<gl-form-checkbox v-model="noteData.approve" data-testid="approve_merge_request">
<gl-form-checkbox
v-model="noteData.approve"
data-testid="approve_merge_request"
class="gl-mt-4"
>
{{ __('Approve merge request') }}
</gl-form-checkbox>
<approval-password
@ -180,7 +184,7 @@ export default {
data-testid="approve_password"
/>
</template>
<div class="gl-display-flex gl-justify-content-start gl-mt-5">
<div class="gl-display-flex gl-justify-content-start gl-mt-4">
<gl-button
:loading="isSubmitting"
variant="confirm"

View File

@ -46,7 +46,7 @@ export default class ArchivedProjectsService {
number_users_with_delimiter: 0,
star_count: project.star_count,
updated_at: project.updated_at,
marked_for_deletion: project.marked_for_deletion_at !== null,
marked_for_deletion: Boolean(project.marked_for_deletion_at),
last_activity_at: project.last_activity_at,
};
}),

View File

@ -1,11 +1,20 @@
<script>
import { GlDropdown, GlDropdownItem, GlIcon, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
import {
GlDisclosureDropdown,
GlDisclosureDropdownItem,
GlIcon,
GlButtonGroup,
GlButton,
GlTooltipDirective as GlTooltip,
} from '@gitlab/ui';
export default {
components: {
GlIcon,
GlDropdown,
GlDropdownItem,
GlDisclosureDropdown,
GlDisclosureDropdownItem,
GlButtonGroup,
GlButton,
},
directives: {
GlTooltip,
@ -34,20 +43,31 @@ export default {
<template>
<span class="gl-white-space-nowrap gl-inline-flex gl-align-items-center">
<gl-dropdown
v-if="isAvailableForImport || isFinished"
:text="isFinished ? __('Re-import with projects') : __('Import with projects')"
:disabled="isInvalid"
variant="confirm"
category="secondary"
data-qa-selector="import_group_button"
split
@click="importGroup({ migrateProjects: true })"
>
<gl-dropdown-item @click="importGroup({ migrateProjects: false })">{{
isFinished ? __('Re-import without projects') : __('Import without projects')
}}</gl-dropdown-item>
</gl-dropdown>
<gl-button-group v-if="isAvailableForImport || isFinished">
<gl-button
variant="confirm"
category="secondary"
@click="importGroup({ migrateProjects: true })"
>{{ isFinished ? __('Re-import with projects') : __('Import with projects') }}</gl-button
>
<gl-disclosure-dropdown
toggle-text="Import options"
text-sr-only
:disabled="isInvalid"
icon="chevron-down"
no-caret
variant="confirm"
category="secondary"
data-qa-selector="import_group_button"
>
<gl-disclosure-dropdown-item @action="importGroup({ migrateProjects: false })">
<template #list-item>
{{ isFinished ? __('Re-import without projects') : __('Import without projects') }}
</template></gl-disclosure-dropdown-item
>
</gl-disclosure-dropdown>
</gl-button-group>
<gl-icon
v-if="isFinished"
v-gl-tooltip

View File

@ -45,7 +45,7 @@ export const PACKAGE_FORWARDING_FORM_BUTTON = __('Save changes');
export const DEPENDENCY_PROXY_HEADER = s__('DependencyProxy|Dependency Proxy');
export const DEPENDENCY_PROXY_DESCRIPTION = s__(
'DependencyProxy|Enable the Dependency Proxy and settings for clearing the cache.',
'DependencyProxy|Enable the Dependency Proxy to cache container images from Docker Hub and automatically clear the cache.',
);
export const PACKAGE_FORWARDING_FIELDS = [

View File

@ -3,6 +3,7 @@ import initVueAlerts from '~/vue_alerts';
import NoEmojiValidator from '~/emoji/no_emoji_validator';
import { initLanguageSwitcher } from '~/language_switcher';
import LengthValidator from '~/validators/length_validator';
import mountEmailVerificationApplication from '~/sessions/new';
import OAuthRememberMe from './oauth_remember_me';
import preserveUrlFragment from './preserve_url_fragment';
import SigninTabsMemoizer from './signin_tabs_memoizer';
@ -22,3 +23,4 @@ new OAuthRememberMe({
preserveUrlFragment(window.location.hash);
initVueAlerts();
initLanguageSwitcher();
mountEmailVerificationApplication();

View File

@ -0,0 +1,174 @@
<script>
import { GlSprintf, GlForm, GlFormGroup, GlFormInput, GlButton } from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility';
import { createAlert, VARIANT_SUCCESS } from '~/alert';
import axios from '~/lib/utils/axios_utils';
import {
I18N_EXPLANATION,
I18N_INPUT_LABEL,
I18N_EMAIL_EMPTY_CODE,
I18N_EMAIL_INVALID_CODE,
I18N_SUBMIT_BUTTON,
I18N_RESEND_LINK,
I18N_EMAIL_RESEND_SUCCESS,
I18N_GENERIC_ERROR,
VERIFICATION_CODE_REGEX,
SUCCESS_RESPONSE,
FAILURE_RESPONSE,
} from '../constants';
export default {
name: 'EmailVerification',
components: {
GlSprintf,
GlForm,
GlFormGroup,
GlFormInput,
GlButton,
},
props: {
obfuscatedEmail: {
type: String,
required: true,
},
verifyPath: {
type: String,
required: true,
},
resendPath: {
type: String,
required: true,
},
},
data() {
return {
verificationCode: '',
submitted: false,
verifyError: '',
};
},
computed: {
inputValidation() {
return {
state: !(this.submitted && this.invalidFeedback),
message: this.invalidFeedback,
};
},
invalidFeedback() {
if (!this.submitted) {
return '';
}
if (!this.verificationCode) {
return I18N_EMAIL_EMPTY_CODE;
}
if (!VERIFICATION_CODE_REGEX.test(this.verificationCode)) {
return I18N_EMAIL_INVALID_CODE;
}
return this.verifyError;
},
},
watch: {
verificationCode() {
this.verifyError = '';
},
},
methods: {
verify() {
this.submitted = true;
if (!this.inputValidation.state) return;
axios
.post(this.verifyPath, { user: { verification_token: this.verificationCode } })
.then(this.handleVerificationResponse)
.catch(this.handleError);
},
handleVerificationResponse(response) {
if (response.data.status === undefined) {
this.handleError();
} else if (response.data.status === SUCCESS_RESPONSE) {
visitUrl(response.data.redirect_path);
} else if (response.data.status === FAILURE_RESPONSE) {
this.verifyError = response.data.message;
}
},
resend() {
axios
.post(this.resendPath)
.then(this.handleResendResponse)
.catch(this.handleError)
.finally(this.resetForm);
},
handleResendResponse(response) {
if (response.data.status === undefined) {
this.handleError();
} else if (response.data.status === SUCCESS_RESPONSE) {
createAlert({
message: I18N_EMAIL_RESEND_SUCCESS,
variant: VARIANT_SUCCESS,
});
} else if (response.data.status === FAILURE_RESPONSE) {
createAlert({ message: response.data.message });
}
},
handleError(error) {
createAlert({
message: I18N_GENERIC_ERROR,
captureError: true,
error,
});
},
resetForm() {
this.verificationCode = '';
this.submitted = false;
this.$refs.input.$el.focus();
},
},
i18n: {
explanation: I18N_EXPLANATION,
inputLabel: I18N_INPUT_LABEL,
submitButton: I18N_SUBMIT_BUTTON,
resendLink: I18N_RESEND_LINK,
},
};
</script>
<template>
<gl-form @submit.prevent="verify">
<section class="gl-mb-5">
<gl-sprintf :message="$options.i18n.explanation">
<template #email>
<strong>{{ obfuscatedEmail }}</strong>
</template>
</gl-sprintf>
</section>
<gl-form-group
:label="$options.i18n.inputLabel"
label-for="verification-code"
:state="inputValidation.state"
:invalid-feedback="inputValidation.message"
>
<gl-form-input
id="verification-code"
ref="input"
v-model="verificationCode"
autofocus
autocomplete="one-time-code"
inputmode="numeric"
maxlength="6"
:state="inputValidation.state"
/>
</gl-form-group>
<section class="gl-mt-5">
<gl-button block variant="confirm" type="submit" :disabled="!inputValidation.state">{{
$options.i18n.submitButton
}}</gl-button>
<gl-button block variant="link" class="gl-mt-3 gl-h-7" @click="resend">{{
$options.i18n.resendLink
}}</gl-button>
</section>
</gl-form>
</template>

View File

@ -0,0 +1,18 @@
import { s__ } from '~/locale';
export const I18N_EXPLANATION = s__(
"IdentityVerification|For added security, you'll need to verify your identity. We've sent a verification code to %{email}",
);
export const I18N_INPUT_LABEL = s__('IdentityVerification|Verification code');
export const I18N_EMAIL_EMPTY_CODE = s__('IdentityVerification|Enter a code.');
export const I18N_EMAIL_INVALID_CODE = s__('IdentityVerification|Please enter a valid code');
export const I18N_SUBMIT_BUTTON = s__('IdentityVerification|Verify code');
export const I18N_RESEND_LINK = s__('IdentityVerification|Resend code');
export const I18N_EMAIL_RESEND_SUCCESS = s__('IdentityVerification|A new code has been sent.');
export const I18N_GENERIC_ERROR = s__(
'IdentityVerification|Something went wrong. Please try again.',
);
export const VERIFICATION_CODE_REGEX = /^\d{6}$/;
export const SUCCESS_RESPONSE = 'success';
export const FAILURE_RESPONSE = 'failure';

View File

@ -0,0 +1,22 @@
import Vue from 'vue';
import EmailVerification from './components/email_verification.vue';
export default () => {
const el = document.querySelector('.js-email-verification');
if (!el) {
return null;
}
const { obfuscatedEmail, verifyPath, resendPath } = el.dataset;
return new Vue({
el,
name: 'EmailVerificationRoot',
render(createElement) {
return createElement(EmailVerification, {
props: { obfuscatedEmail, verifyPath, resendPath },
});
},
});
};

View File

@ -35,12 +35,22 @@ export default {
return sprintf(s__('CiCdAnalytics|Date range: %{range}'), { range: this.chart.range });
},
},
methods: {
onInput(selectedChart) {
this.selectedChart = selectedChart;
this.$emit('select-chart', selectedChart);
},
},
};
</script>
<template>
<div>
<div class="gl-display-flex gl-flex-wrap gl-gap-5">
<segmented-control-button-group v-model="selectedChart" :options="chartRanges" />
<segmented-control-button-group
:options="chartRanges"
:value="selectedChart"
@input="onInput"
/>
<slot name="extend-button-group"></slot>
</div>
<ci-cd-analytics-area-chart

View File

@ -1,8 +1,9 @@
<script>
import { GlForm, GlFormInput, GlFormGroup } from '@gitlab/ui';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import LabelsSelect from '~/sidebar/components/labels/labels_select_vue/labels_select_root.vue';
import { VARIANT_EMBEDDED } from '~/sidebar/components/labels/labels_select_widget/constants';
import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue';
import { __ } from '~/locale';
export default {
VARIANT_EMBEDDED,
@ -10,7 +11,7 @@ export default {
GlForm,
GlFormInput,
GlFormGroup,
MarkdownField,
MarkdownEditor,
LabelsSelect,
},
props: {
@ -31,6 +32,14 @@ export default {
required: true,
},
},
descriptionFormFieldProps: {
ariaLabel: __('Description'),
class: 'rspec-issuable-form-description',
placeholder: __('Write a comment or drag your files here…'),
dataQaSelector: 'issuable_form_description_field',
id: 'issuable-description',
name: 'issuable-description',
},
data() {
return {
issuableTitle: '',
@ -68,26 +77,12 @@ export default {
<div data-testid="issuable-description" class="form-group row">
<label for="issuable-description" class="col-12">{{ __('Description') }}</label>
<div class="col-12">
<markdown-field
:markdown-preview-path="descriptionPreviewPath"
<markdown-editor
v-model="issuableDescription"
:render-markdown-path="descriptionPreviewPath"
:markdown-docs-path="descriptionHelpPath"
:add-spacing-classes="false"
:show-suggest-popover="true"
:textarea-value="issuableDescription"
>
<template #textarea>
<textarea
id="issuable-description"
ref="textarea"
v-model="issuableDescription"
dir="auto"
class="note-textarea rspec-issuable-form-description js-gfm-input js-autosize markdown-area"
data-qa-selector="issuable_form_description_field"
:aria-label="__('Description')"
:placeholder="__('Write a comment or drag your files here…')"
></textarea>
</template>
</markdown-field>
:form-field-props="$options.descriptionFormFieldProps"
/>
</div>
</div>
<div data-testid="issuable-labels" class="form-group row">

View File

@ -1,5 +1,11 @@
<script>
import { GlDropdown, GlDropdownItem, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
import {
GlDisclosureDropdown,
GlDisclosureDropdownItem,
GlIcon,
GlLoadingIcon,
GlTooltipDirective,
} from '@gitlab/ui';
import { isEmpty } from 'lodash';
import { s__ } from '~/locale';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
@ -20,8 +26,8 @@ import WorkItemChildrenWrapper from './work_item_children_wrapper.vue';
export default {
components: {
GlDropdown,
GlDropdownItem,
GlDisclosureDropdown,
GlDisclosureDropdownItem,
GlIcon,
GlLoadingIcon,
WidgetWrapper,
@ -211,26 +217,30 @@ export default {
</span>
</template>
<template #header-right>
<gl-dropdown
<gl-disclosure-dropdown
v-if="canUpdate && canAddTask"
right
placement="right"
size="small"
:text="$options.i18n.addChildButtonLabel"
:toggle-text="$options.i18n.addChildButtonLabel"
data-testid="toggle-form"
>
<gl-dropdown-item
<gl-disclosure-dropdown-item
data-testid="toggle-create-form"
@click="showAddForm($options.FORM_TYPES.create)"
@action="showAddForm($options.FORM_TYPES.create)"
>
{{ $options.i18n.createChildOptionLabel }}
</gl-dropdown-item>
<gl-dropdown-item
<template #list-item>
{{ $options.i18n.createChildOptionLabel }}
</template>
</gl-disclosure-dropdown-item>
<gl-disclosure-dropdown-item
data-testid="toggle-add-form"
@click="showAddForm($options.FORM_TYPES.add)"
@action="showAddForm($options.FORM_TYPES.add)"
>
{{ $options.i18n.addChildOptionLabel }}
</gl-dropdown-item>
</gl-dropdown>
<template #list-item>
{{ $options.i18n.addChildOptionLabel }}
</template>
</gl-disclosure-dropdown-item>
</gl-disclosure-dropdown>
</template>
<template #body>
<div class="gl-new-card-content">

View File

@ -124,21 +124,25 @@ $sticky-header-z-index: 98;
display: block;
height: $gl-padding-8;
position: sticky;
top: calc(#{$calc-application-header-height} + 40px);
box-shadow: 0 1px 1px $gray-200;
top: calc(#{$calc-application-header-height} + 36px);
box-shadow: 0 1px 0 $gray-100;
}
}
.settings-sticky-header-inner {
position: sticky;
padding: $gl-padding $gl-padding $gl-padding-12;
padding: $gl-padding-12 $gl-padding $gl-padding-8;
margin: #{-$gl-padding} #{-$gl-padding} 0;
background: $body-bg;
}
.settings-sticky-footer {
bottom: 0;
padding-top: $gl-padding-8;
padding-bottom: $gl-padding-8;
box-shadow: 0 #{-$gl-padding-4} $gl-padding-12 $gl-padding-4 $body-bg;
padding: $gl-padding-8 0;
box-shadow: 0 -1px 0 $gray-100;
}
// Header shouldn't be sticky if only one section on page
.settings-sticky-header:first-of-type:last-of-type {
position: static;
}

View File

@ -12,6 +12,7 @@ module VerifiesWithEmail
skip_before_action :required_signup_info, only: :successful_verification
end
# rubocop:disable Metrics/PerceivedComplexity
def verify_with_email
return unless user = find_user || find_verification_user
@ -34,18 +35,27 @@ module VerifiesWithEmail
# - their account has been locked because of too many failed login attempts, or
# - they have logged in before, but never from the current ip address
reason = 'sign in from untrusted IP address' unless user.access_locked?
send_verification_instructions(user, reason: reason)
send_verification_instructions(user, reason: reason) unless send_rate_limited?(user)
prompt_for_email_verification(user)
end
end
end
end
# rubocop:enable Metrics/PerceivedComplexity
def resend_verification_code
return unless user = find_verification_user
send_verification_instructions(user)
prompt_for_email_verification(user)
if send_rate_limited?(user)
message = format(
s_("IdentityVerification|You've reached the maximum amount of resends. Wait %{interval} and try again."),
interval: rate_limit_interval(:email_verification_code_send)
)
render json: { status: :failure, message: message }
else
send_verification_instructions(user)
render json: { status: :success }
end
end
def successful_verification
@ -67,19 +77,7 @@ module VerifiesWithEmail
User.find_by_id(session[:verification_user_id])
end
# After successful verification and calling sign_in, devise redirects the
# user to this path. Override it to show the successful verified page.
def after_sign_in_path_for(resource)
if action_name == 'create' && session[:verification_user_id] == resource.id
return users_successful_verification_path
end
super
end
def send_verification_instructions(user, reason: nil)
return if send_rate_limited?(user)
service = Users::EmailVerification::GenerateTokenService.new(attr: :unlock_token, user: user)
raw_token, encrypted_token = service.execute
user.unlock_token = encrypted_token
@ -101,21 +99,23 @@ module VerifiesWithEmail
if result[:status] == :success
handle_verification_success(user)
render json: { status: :success, redirect_path: users_successful_verification_path }
else
handle_verification_failure(user, result[:reason], result[:message])
render json: result
end
end
def render_sign_in_rate_limited
message = format(
s_('IdentityVerification|Maximum login attempts exceeded. Wait %{interval} and try again.'),
interval: user_sign_in_interval
interval: rate_limit_interval(:user_sign_in)
)
redirect_to new_user_session_path, alert: message
end
def user_sign_in_interval
interval_in_seconds = Gitlab::ApplicationRateLimiter.rate_limits[:user_sign_in][:interval]
def rate_limit_interval(rate_limit)
interval_in_seconds = Gitlab::ApplicationRateLimiter.rate_limits[rate_limit][:interval]
distance_of_time_in_words(interval_in_seconds)
end
@ -126,8 +126,6 @@ module VerifiesWithEmail
def handle_verification_failure(user, reason, message)
user.errors.add(:base, message)
log_verification(user, :failed_attempt, reason)
prompt_for_email_verification(user)
end
def handle_verification_success(user)
@ -135,6 +133,10 @@ module VerifiesWithEmail
log_verification(user, :successful)
sign_in(user)
log_audit_event(current_user, user, with: authentication_method)
log_user_activity(user)
verify_known_sign_in
end
def trusted_ip_address?(user)
@ -146,6 +148,7 @@ module VerifiesWithEmail
def prompt_for_email_verification(user)
session[:verification_user_id] = user.id
self.resource = user
add_gon_variables # Necessary to set the sprite_icons path, since we skip the ApplicationController before_filters
render 'devise/sessions/email_verification'
end

View File

@ -1,37 +0,0 @@
# frozen_string_literal: true
module Metrics
class UsersStarredDashboardsFinder
def initialize(user:, project:, params: {})
@user = user
@project = project
@params = params
end
def execute
return ::Metrics::UsersStarredDashboard.none unless Ability.allowed?(user, :read_metrics_user_starred_dashboard, project)
items = starred_dashboards
items = by_project(items)
by_dashboard(items)
end
private
attr_reader :user, :project, :params
def by_project(items)
items.for_project(project)
end
def by_dashboard(items)
return items unless params[:dashboard_path]
items.merge(starred_dashboards.for_project_dashboard(project, params[:dashboard_path]))
end
def starred_dashboards
@starred_dashboards ||= user.metrics_users_starred_dashboards
end
end
end

View File

@ -40,10 +40,6 @@ module SessionsHelper
request.env['rack.session.options'][:expire_after] = expiry_s
end
def send_rate_limited?(user)
Gitlab::ApplicationRateLimiter.peek(:email_verification_code_send, scope: user)
end
def obfuscated_email(email)
# Moved to Gitlab::Utils::Email in 15.9
Gitlab::Utils::Email.obfuscated_email(email)
@ -52,4 +48,12 @@ module SessionsHelper
def remember_me_enabled?
Gitlab::CurrentSettings.remember_me_enabled?
end
def verification_data(user)
{
obfuscated_email: obfuscated_email(user.email),
verify_path: session_path(:user),
resend_path: users_resend_verification_code_path
}
end
end

View File

@ -498,7 +498,7 @@ class Note < ApplicationRecord
end
def can_be_discussion_note?
self.noteable.supports_discussions? && !part_of_discussion?
self.noteable.supports_discussions? && !part_of_discussion? && !system?
end
def can_create_todo?

View File

@ -2192,14 +2192,6 @@ class User < ApplicationRecord
callout_dismissed?(callout, ignore_dismissal_earlier_than)
end
def dismissed_callout_before?(feature_name, dismissed_before)
callout = callouts_by_feature_name[feature_name]
return false unless callout
callout.dismissed_before?(dismissed_before)
end
def dismissed_callout_for_group?(feature_name:, group:, ignore_dismissal_earlier_than: nil)
source_feature_name = "#{feature_name}_#{group.id}"
callout = group_callouts_by_feature_name[source_feature_name]

View File

@ -13,9 +13,5 @@ module Users
def dismissed_after?(dismissed_after)
dismissed_at > dismissed_after
end
def dismissed_before?(dismissed_before)
dismissed_at < dismissed_before
end
end
end

View File

@ -7,10 +7,18 @@ module PersonalAccessTokens
end
def execute
# Despite using #update_all, there should only be a single active token.
# A token family is a chain of rotated tokens. Once rotated, the
# previous token is revoked.
pat_family.active.update_all(revoked: true)
# A token family is a chain of rotated tokens. Once rotated, the previous
# token is revoked. As a result, a single token id should be returned by
# this query.
# rubocop: disable CodeReuse/ActiveRecord
token_ids = pat_family.active.pluck_primary_key
# We create another query based on the previous if any id exists. An
# alternative is to use a single query, like
# `pat_family.active.update_all(...)`). However, #update_all ignores
# the CTE, and tries to revoke *all* active tokens.
PersonalAccessToken.where(id: token_ids).update_all(revoked: true) if token_ids.any?
# rubocop: enable CodeReuse/ActiveRecord
ServiceResponse.success
end
@ -25,8 +33,16 @@ module PersonalAccessTokens
personal_access_token_table = Arel::Table.new(:personal_access_tokens)
cte << PersonalAccessToken
.select(
'personal_access_tokens.id',
'personal_access_tokens.revoked',
'personal_access_tokens.expires_at')
.where(personal_access_token_table[:previous_personal_access_token_id].eq(token.id))
cte << PersonalAccessToken
.select(
'personal_access_tokens.id',
'personal_access_tokens.revoked',
'personal_access_tokens.expires_at')
.from([personal_access_token_table, cte.table])
.where(personal_access_token_table[:previous_personal_access_token_id].eq(cte.table[:id]))
PersonalAccessToken.with.recursive(cte.to_arel).from(cte.alias_to(personal_access_token_table))

View File

@ -2,18 +2,7 @@
= render 'devise/shared/tab_single', tab_title: s_('IdentityVerification|Help us protect your account')
.login-box.gl-p-5
.login-body
= gitlab_ui_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post, html: { class: 'gl-show-field-errors' }) do |f|
%p
= s_("IdentityVerification|For added security, you'll need to verify your identity. We've sent a verification code to %{email}").html_safe % { email: "<strong>#{sanitize(obfuscated_email(resource.email))}</strong>".html_safe }
%div
= f.label :verification_token, s_('IdentityVerification|Verification code')
= f.text_field :verification_token, class: 'form-control gl-form-input', required: true, autofocus: true, autocomplete: 'off', title: s_('IdentityVerification|Please enter a valid code'), inputmode: 'numeric', maxlength: 6, pattern: '[0-9]{6}'
%p.gl-field-error.gl-mt-2
= resource.errors.full_messages.to_sentence
.gl-mt-5
= f.submit s_('IdentityVerification|Verify code'), class: 'gl-w-full', pajamas_button: true
- unless send_rate_limited?(resource)
= link_to s_('IdentityVerification|Resend code'), users_resend_verification_code_path, method: :post, class: 'form-control gl-button btn-link gl-mt-3 gl-mb-0'
.js-email-verification{ data: verification_data(resource) }
%p.gl-p-5.gl-text-secondary
- support_link_start = '<a href="https://about.gitlab.com/support/" target="_blank" rel="noopener noreferrer">'.html_safe
= s_("IdentityVerification|If you've lost access to the email associated to this account or having trouble with the code, %{link_start}here are some other steps you can take.%{link_end}").html_safe % { link_start: support_link_start, link_end: '</a>'.html_safe }

View File

@ -21,7 +21,6 @@
= render 'groups/invite_members_modal', group: @group
= dispensable_render_if_exists "shared/web_hooks/group_web_hook_disabled_alert"
= dispensable_render_if_exists "shared/code_suggestions_alert"
= dispensable_render_if_exists "shared/code_suggestions_third_party_alert", source: @group
= dispensable_render_if_exists "shared/free_user_cap_alert", source: @group
= dispensable_render_if_exists "shared/unlimited_members_during_trial_alert", resource: @group

View File

@ -23,7 +23,6 @@
= render 'projects/invite_members_modal', project: @project
= dispensable_render_if_exists "shared/web_hooks/web_hook_disabled_alert"
= dispensable_render_if_exists "projects/code_suggestions_alert", project: @project
= dispensable_render_if_exists "projects/code_suggestions_third_party_alert", project: @project
= dispensable_render_if_exists "projects/free_user_cap_alert", project: @project
= dispensable_render_if_exists 'shared/unlimited_members_during_trial_alert', resource: @project

View File

@ -1,66 +1,84 @@
- page_title _('Emails')
- profile_message = _('Used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}.') % { openingTag: "<a href='#{profile_path}' class='gl-text-blue-500!'>".html_safe, closingTag: '</a>'.html_safe}
- notification_message = _('Used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set.') % { openingTag: "<a href='#{profile_notifications_path}' class='gl-text-blue-500!'>".html_safe, closingTag: '</a>'.html_safe}
- public_email_message = _('Your public email will be displayed on your public profile.')
- commit_email_message = _('Used for web based operations, such as edits and merges.')
- @force_desktop_expanded_sidebar = true
.settings-section.js-search-settings-section
.settings-sticky-header
.settings-sticky-header-inner
%h4.gl-my-0
= _('Add email address')
= s_('Profiles|Email addresses')
%p.gl-text-secondary
= _('Control emails linked to your account')
%div
= gitlab_ui_form_for 'email', url: profile_emails_path do |f|
.form-group
= f.label :email, _('Email'), class: 'label-bold'
= f.text_field :email, class: 'form-control gl-form-input', data: { qa_selector: 'email_address_field' }
.gl-mt-3
= f.submit _('Add email address'), data: { qa_selector: 'add_email_address_button' }, pajamas_button: true
= s_('Profiles|Control emails linked to your account')
.settings-section.js-search-settings-section
.settings-sticky-header
.settings-sticky-header-inner
%h4.gl-my-0
= _('Linked emails (%{email_count})') % { email_count: @emails.load.size }
.account-well.gl-mb-3
%ul
%li
- profile_message = _('Your primary email is used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}.') % { openingTag: "<a href='#{profile_path}'>".html_safe, closingTag: '</a>'.html_safe}
= profile_message.html_safe
%li
= _('Your commit email is used for web based operations, such as edits and merges.')
%li
- notification_message = _('Your default notification email is used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set.') % { openingTag: "<a href='#{profile_notifications_path}'>".html_safe, closingTag: '</a>'.html_safe}
= notification_message.html_safe
%li
= _('Your public email will be displayed on your public profile.')
%li
= _('All email addresses will be used to identify your commits.')
%ul.content-list
%li
= render partial: 'shared/email_with_badge', locals: { email: @primary_email, verified: current_user.confirmed? }
%ul
%li= s_('Profiles|Primary email')
- if @primary_email == current_user.commit_email_or_default
%li= s_('Profiles|Commit email')
- if @primary_email == current_user.public_email
%li= s_('Profiles|Public email')
- if @primary_email == current_user.notification_email_or_default
%li= s_('Profiles|Default notification email')
- @emails.reject(&:user_primary_email?).each do |email|
%li{ data: { qa_selector: 'email_row_content' } }
.gl-display-flex.gl-justify-content-space-between.gl-flex-wrap.gl-gap-3
%div
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
.settings-section.js-search-settings-section
= render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card js-toggle-container' }, header_options: { class: 'gl-new-card-header' }, body_options: { class: 'gl-new-card-body gl-px-0' }) do |c|
- c.with_header do
.gl-new-card-title-wrapper
%h3.gl-new-card-title
= s_('Profiles|Linked emails')
.gl-new-card-count
= sprite_icon('mail', css_class: 'gl-mr-2')
= @emails.load.size
.gl-new-card-actions
= render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content" }) do
= s_('Profiles|Add new email')
- c.with_body do
.gl-new-card-add-form.gl-m-3.gl-mb-4.gl-display-none.js-toggle-content
%h4.gl-mt-0
= s_('Profiles|Add new email')
= gitlab_ui_form_for 'email', url: profile_emails_path do |f|
.form-group
= f.label :email, _('Profiles|Email'), class: 'label-bold'
= f.text_field :email, class: 'form-control gl-form-input', data: { qa_selector: 'email_address_field' }
.gl-mt-3
= f.submit s_('Profiles|Add email address'), data: { qa_selector: 'add_email_address_button' }, pajamas_button: true
= render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'gl-ml-2 js-toggle-button' }) do
= _('Cancel')
- if @emails.any?
%ul.content-list
%li{ class: 'gl-px-5!' }
= render partial: 'shared/email_with_badge', locals: { email: @primary_email, verified: current_user.confirmed? }
%ul
- if email.email == current_user.commit_email_or_default
%li= s_('Profiles|Commit email')
- if email.email == current_user.public_email
%li= s_('Profiles|Public email')
- if email.email == current_user.notification_email_or_default
%li= s_('Profiles|Notification email')
.gl-display-flex.gl-justify-content-end.gl-align-items-flex-end.gl-flex-grow-1.gl-flex-wrap-reverse.gl-gap-3
- unless email.confirmed?
- confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}"
= link_button_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, size: :small
%li.gl-mt-2
= s_('Profiles|Primary email')
.gl-text-secondary.gl-font-sm= profile_message.html_safe
- if @primary_email == current_user.commit_email_or_default
%li.gl-mt-2
= s_('Profiles|Commit email')
.gl-text-secondary.gl-font-sm= commit_email_message
- if @primary_email == current_user.public_email
%li.gl-mt-2
= s_('Profiles|Public email')
.gl-text-secondary.gl-font-sm= public_email_message
- if @primary_email == current_user.notification_email_or_default
%li.gl-mt-2
= s_('Profiles|Default notification email')
.gl-text-secondary.gl-font-sm= notification_message.html_safe
- @emails.reject(&:user_primary_email?).each do |email|
%li{ class: 'gl-px-5!', data: { qa_selector: 'email_row_content' } }
.gl-display-flex.gl-justify-content-space-between.gl-flex-wrap.gl-gap-3
%div
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
%ul
- if email.email == current_user.commit_email_or_default
%li.gl-mt-2
= s_('Profiles|Commit email')
.gl-text-secondary.gl-font-sm= commit_email_message
- if email.email == current_user.public_email
%li.gl-mt-2
= s_('Profiles|Public email')
.gl-text-secondary.gl-font-sm= public_email_message
- if email.email == current_user.notification_email_or_default
%li.gl-mt-2
= s_('Profiles|Default notification email')
.gl-text-secondary.gl-font-sm= notification_message.html_safe
.gl-display-flex.gl-sm-justify-content-end.gl-align-items-flex-end.gl-flex-grow-1.gl-flex-wrap-reverse.gl-gap-3
- unless email.confirmed?
- confirm_title = "#{email.confirmation_sent_at ? s_('Profiles|Resend confirmation email') : s_('Profiles|Send confirmation email')}"
= link_button_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, size: :small
= link_button_to nil, profile_email_path(email), data: { confirm: _('Are you sure?'), qa_selector: 'delete_email_link'}, method: :delete, variant: :danger, size: :small, icon: 'remove', 'aria-label': _('Remove')
= link_button_to nil, profile_email_path(email), data: { confirm: _('Are you sure?'), confirm_btn_variant: 'danger', qa_selector: 'delete_email_link'}, method: :delete, size: :small, icon: 'remove', 'aria-label': _('Remove')

View File

@ -8,3 +8,5 @@
.gl-mt-3
= f.submit s_('Profiles|Add key'), pajamas_button: true
= render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'gl-ml-2 js-toggle-button' }) do
= _('Cancel')

View File

@ -1,24 +1,29 @@
%li.key-list-item
.float-left.gl-mr-3
= sprite_icon('key', css_class: "settings-list-icon d-none d-sm-block gl-mt-4")
.key-list-item-info
- key.emails_with_verified_status.map do |email, verified|
= render partial: 'shared/email_with_badge', locals: { email: email, verified: verified }
%tr.key-list-item
%td{ data: { label: s_('Profiles|Key') } }
%div{ class: 'gl-display-flex! gl-pl-0!' }
= sprite_icon('key', css_class: "settings-list-icon d-none d-sm-inline gl-mr-2")
.gl-display-flex.gl-flex-direction-column.gl-text-truncate
%p.gl-text-truncate.gl-m-0
%code= key.fingerprint
- if key.subkeys.present?
.subkeys.gl-mt-3{ class: 'gl-text-left!' }
%span.gl-font-sm
= _('Subkeys:')
%ul.subkeys-list
- key.subkeys.each do |subkey|
%li
%p.gl-text-truncate.gl-m-0
%code= subkey.fingerprint
%span.text-truncate
%code= key.fingerprint
- if key.subkeys.present?
.subkeys
%span.bold
= _('Subkeys')
= ':'
%ul.subkeys-list
- key.subkeys.each do |subkey|
%li
%code= subkey.fingerprint
.float-right
%span.key-created-at
= html_escape(s_('Profiles|Created %{time_ago}')) % { time_ago: time_ago_with_tooltip(key.created_at) }
= link_button_to nil, profile_gpg_key_path(key), data: { confirm: _('Are you sure? Removing this GPG key does not affect already signed commits.') }, method: :delete, class: 'gl-ml-3', variant: :danger, icon: 'remove', 'aria-label': _('Remove')
= link_button_to revoke_profile_gpg_key_path(key), data: { confirm: _('Are you sure? All commits that were signed with this GPG key will be unverified.') }, method: :put, class: 'gl-ml-3', variant: :danger, 'aria-label': _('Revoke') do
%td{ data: { label: _('Status') } }
- key.emails_with_verified_status.map do |email, verified|
%div{ class: 'gl-text-left!' }
= render partial: 'shared/email_with_badge', locals: { email: email, verified: verified }
%td{ data: { label: _('Created') } }
= html_escape(s_('Created %{time_ago}')) % { time_ago: time_ago_with_tooltip(key.created_at) }
%td{ class: 'gl-py-3!', data: { label: _('Actions') } }
= link_button_to nil, profile_gpg_key_path(key), data: { confirm: _('Are you sure? Removing this GPG key does not affect already signed commits.'), confirm_btn_variant: 'danger' }, method: :delete, class: 'has-tooltip', icon: 'remove', category: :secondary, 'title': _('Remove'), 'aria-label': _('Remove')
= link_button_to revoke_profile_gpg_key_path(key), data: { confirm: _('Are you sure? All commits that were signed with this GPG key will be unverified.'), confirm_btn_variant: 'danger' }, method: :put, class: 'gl-ml-3', category: :secondary, variant: :danger, 'aria-label': _('Revoke') do
= _('Revoke')

View File

@ -1,10 +1,19 @@
- is_admin = local_assigns.fetch(:admin, false)
- hide_class = local_assigns.fetch(:hide_class, false)
- if @gpg_keys.any?
%ul.content-list
= render partial: 'profiles/gpg_keys/key', collection: @gpg_keys, locals: { is_admin: is_admin }
.table-holder
%table.table.b-table.gl-table.b-table-stacked-md.gl-mt-n1.gl-mb-n2.ssh-keys-list{ data: { qa_selector: 'ssh_keys_list' } }
%thead.d-none.d-md-table-header-group
%tr
%th= s_('Profiles|Key')
%th= _('Status')
%th= _('Created')
%th= _('Actions')
= render partial: 'profiles/gpg_keys/key', collection: @gpg_keys, locals: { is_admin: is_admin }
- else
%p.settings-message.text-center
%p.gl-new-card-empty.gl-px-5.gl-py-4.js-toggle-content{ class: hide_class }
- if is_admin
= _('There are no GPG keys associated with this account.')
- else

View File

@ -1,6 +1,8 @@
- page_title _('GPG Keys')
- add_page_specific_style 'page_bundles/profile'
- @force_desktop_expanded_sidebar = true
- add_form_class = 'gl-display-none' if !form_errors(@gpg_key)
- hide_class = 'gl-display-none' if form_errors(@gpg_key)
.settings-section.js-search-settings-section
.settings-sticky-header
@ -10,17 +12,24 @@
%p.gl-text-secondary
= _('GPG keys allow you to verify signed commits.')
%h5.gl-font-lg.gl-mt-0
= _('Add a GPG key')
%p
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') }
= _('Add a GPG key for secure access to GitLab. %{help_link_start}Learn more%{help_link_end}.').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
= render 'form'
= render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card js-toggle-container' }, header_options: { class: 'gl-new-card-header' }, body_options: { class: 'gl-new-card-body gl-px-0' }) do |c|
- c.with_header do
.gl-new-card-title-wrapper
%h3.gl-new-card-title
= _('Your GPG keys')
.gl-new-card-count
= sprite_icon('key', css_class: 'gl-mr-2')
= @gpg_keys.count
.gl-new-card-actions
= render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content #{hide_class}" }) do
= _('Add a GPG key')
- c.with_body do
.gl-new-card-add-form.gl-m-3.js-toggle-content{ class: add_form_class }
%h4.gl-mt-0
= _('Add a GPG key')
%p
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') }
= _('Add a GPG key for secure access to GitLab. %{help_link_start}Learn more%{help_link_end}.').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
= render 'form'
.settings-section.js-search-settings-section
.settings-sticky-header
.settings-sticky-header-inner
%h4.gl-my-0
= _('Your GPG keys (%{count})') % { count: @gpg_keys.count }
.gl-mb-3
= render 'key_table'
= render 'key_table', hide_class: hide_class

View File

@ -1,6 +1,7 @@
- variant = verified ? :success : :danger
- text = verified ? _('Verified') : _('Unverified')
%span.gl-mr-3
= email
= gl_badge_tag text, { variant: variant }
- if email
%span.gl-mr-2
= email
= gl_badge_tag text, { variant: variant, size: :sm }

View File

@ -0,0 +1,8 @@
---
name: telesign_callback
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125983
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/417703
milestone: '16.3'
type: development
group: group::anti-abuse
default_enabled: false

View File

@ -166,6 +166,7 @@ InitializerConnections.raise_if_new_database_connection do
draw :country
draw :country_state
draw :subscription
draw :phone_verification
scope '/push_from_secondary/:geo_node_id' do
draw :git_http

View File

@ -13,7 +13,7 @@ GitLab can read settings for certain features from encrypted settings files. The
- [Incoming email `user` and `password`](incoming_email.md#use-encrypted-credentials).
- [LDAP `bind_dn` and `password`](auth/ldap/index.md#use-encrypted-credentials).
- [Service Desk email `user` and `password`](../user/project/service_desk.md#use-encrypted-credentials).
- [Service Desk email `user` and `password`](../user/project/service_desk/index.md#use-encrypted-credentials).
- [SMTP `user_name` and `password`](raketasks/smtp.md#secrets).
To enable the encrypted configuration settings, a new base key must be generated for

View File

@ -16,7 +16,7 @@ GitLab has several features based on receiving incoming email messages:
- [New merge request by email](../user/project/merge_requests/creating_merge_requests.md#by-sending-an-email):
allow GitLab users to create a new merge request by sending an email to a
user-specific email address.
- [Service Desk](../user/project/service_desk.md): provide email support to
- [Service Desk](../user/project/service_desk/index.md): provide email support to
your customers through GitLab.
## Requirements
@ -80,7 +80,7 @@ Email is processed correctly when a configured email address is present in one o
The `References` header is also accepted, however it is used specifically to relate email responses to existing discussion threads. It is not used for creating issues by email.
In GitLab 14.6 and later, [Service Desk](../user/project/service_desk.md)
In GitLab 14.6 and later, [Service Desk](../user/project/service_desk/index.md)
also checks accepted headers.
Usually, the "To" field contains the email address of the primary receiver.
@ -529,7 +529,7 @@ incoming_email:
NOTE:
Supports [Reply by Email](reply_by_email.md) only.
Cannot support [Service Desk](../user/project/service_desk.md).
Cannot support [Service Desk](../user/project/service_desk/index.md).
Assumes the dedicated email address `incoming@exchange.example.com`.
@ -741,7 +741,7 @@ incoming_email:
NOTE:
Supports [Reply by Email](reply_by_email.md) only.
Cannot support [Service Desk](../user/project/service_desk.md).
Cannot support [Service Desk](../user/project/service_desk/index.md).
This example for Linux package installations assumes the dedicated email address `incoming@office365.example.com`:

View File

@ -12,7 +12,7 @@ The following are Service Desk email-related Rake tasks.
## Secrets
GitLab can use [Service Desk email](../../user/project/service_desk.md#configure-service-desk-alias-email) secrets read from an encrypted file instead of storing them in plaintext in the file system. The following Rake tasks are provided for updating the contents of the encrypted file.
GitLab can use [Service Desk email](../../user/project/service_desk/index.md#configure-service-desk-alias-email) secrets read from an encrypted file instead of storing them in plaintext in the file system. The following Rake tasks are provided for updating the contents of the encrypted file.
### Show secret

View File

@ -427,9 +427,9 @@ The following IPs will be used as an example:
To configure Consul:
1. SSH in to the server that will host Consul.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -453,8 +453,8 @@ To configure Consul:
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -504,19 +504,19 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Omnibus PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. These components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
needs privileges to create the `gitlabhq_production` database.
1. Configure the GitLab application servers with the appropriate details.
This step is covered in [Configuring the GitLab Rails application](#configure-gitlab-rails).
1. The number of nodes required to achieve HA may differ depending on the service compared to Omnibus and doesn't need to match accordingly.
1. The number of nodes required to achieve HA may differ depending on the service compared to the Linux package and doesn't need to match accordingly.
1. However, if [Database Load Balancing](../postgresql/database_load_balancing.md) via Read Replicas is desired for further improved performance it's recommended to follow the node count for the Reference Architecture.
### Standalone PostgreSQL using Omnibus GitLab
### Standalone PostgreSQL using the Linux package
The recommended Omnibus GitLab configuration for a PostgreSQL cluster with
The recommended Linux package configuration for a PostgreSQL cluster with
replication and failover requires:
- A minimum of three PostgreSQL nodes.
@ -653,8 +653,8 @@ PostgreSQL, with Patroni managing its failover, will default to use `pg_rewind`
Like most failover handling methods, this has a small chance of leading to data loss.
For more information, see the various [Patroni replication methods](../postgresql/replication_and_failover.md#selecting-the-appropriate-patroni-replication-method).
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -742,8 +742,8 @@ The following IPs will be used as an example:
node_exporter['listen_address'] = '0.0.0.0:9100'
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -851,9 +851,9 @@ a node and change its status from primary to replica (and vice versa).
#### Configure the primary Redis Cache node
1. SSH in to the **Primary** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -916,17 +916,17 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
#### Configure the replica Redis Cache nodes
1. SSH in to the **replica** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add same contents as the primary node in the previous section replacing `redis_master_node` with `redis_replica_node`:
@ -989,8 +989,8 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
1. Go through the steps again for all the other replica nodes, and
@ -1016,9 +1016,9 @@ a node and change its status from primary to replica (and vice versa).
#### Configure the primary Redis Persistent node
1. SSH in to the **Primary** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -1071,17 +1071,17 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
#### Configure the replica Redis Persistent nodes
1. SSH in to the **replica** Redis Persistent server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -1134,8 +1134,8 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
1. Go through the steps again for all the other replica nodes, and
@ -1191,7 +1191,7 @@ Praefect, the routing and transaction manager for Gitaly Cluster, requires its o
If you want to have a highly available setup, Praefect requires a third-party PostgreSQL database.
A built-in solution is being [worked on](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7292).
#### Praefect non-HA PostgreSQL standalone using Omnibus GitLab
#### Praefect non-HA PostgreSQL standalone using the Linux package
The following IPs will be used as an example:
@ -1253,8 +1253,8 @@ in the second step, do not supply the `EXTERNAL_URL` value.
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1296,11 +1296,11 @@ After the Praefect PostgreSQL server has been set up, you'll then need to config
We recommend the user be named `praefect` and the database `praefect_production`, and these can be configured as standard in PostgreSQL.
The password for the user is the same as the one you configured earlier as `<praefect_postgresql_password>`.
This is how this would work with a Omnibus GitLab PostgreSQL setup:
This is how this would work with a Linux package PostgreSQL setup:
1. SSH in to the Praefect PostgreSQL node.
1. Connect to the PostgreSQL server with administrative access.
The `gitlab-psql` user should be used here for this as it's added by default in Omnibus.
The `gitlab-psql` user should be used here for this as it's added by default in the Linux package.
The database `template1` is used because it is created by default on all PostgreSQL servers.
```shell
@ -1361,7 +1361,7 @@ The following IPs will be used as an example:
To configure the Praefect nodes, on each one:
1. SSH in to the Praefect server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux package
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit the `/etc/gitlab/gitlab.rb` file to configure Praefect:
@ -1473,8 +1473,8 @@ Updates to example must be made at:
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Praefect requires to run some database migrations, much like the main GitLab application. For this
you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node
@ -1534,7 +1534,7 @@ The following IPs will be used as an example:
On each node:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and _do not_ provide the `EXTERNAL_URL` value.
1. Edit the Gitaly server node's `/etc/gitlab/gitlab.rb` file to configure
@ -1656,8 +1656,8 @@ Updates to example must be made at:
}
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Save the file, and then [reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation).
@ -1762,7 +1762,7 @@ examples include the Object storage configuration.
To configure the Sidekiq nodes, on each one:
1. SSH in to the Sidekiq server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Create or edit `/etc/gitlab/gitlab.rb` and use the following configuration:
@ -1881,8 +1881,8 @@ Updates to example must be made at:
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -1926,7 +1926,7 @@ The following IPs will be used as an example:
On each node perform the following:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
@ -2042,11 +2042,11 @@ On each node perform the following:
sudo cp cert.pem /etc/gitlab/trusted-certs/
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the SSH host keys (all in the name format `/etc/ssh/ssh_host_*_key*`) from the first Omnibus node you configured and
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Copy the SSH host keys (all in the name format `/etc/ssh/ssh_host_*_key*`) from the first Linux package node you configured and
add or replace the files of the same name on this server. This ensures host mismatch errors aren't thrown
for your users as they hit the load balanced Rails nodes. If this is the first Omnibus node you are configuring,
for your users as they hit the load balanced Rails nodes. If this is the first Linux package node you are configuring,
then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -2104,7 +2104,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
## Configure Prometheus
The Omnibus GitLab package can be used to configure a standalone Monitoring node
The Linux package can be used to configure a standalone Monitoring node
running [Prometheus](../monitoring/prometheus/index.md) and
[Grafana](../monitoring/performance/grafana_configuration.md).
@ -2115,7 +2115,7 @@ The following IP will be used as an example:
To configure the Monitoring node:
1. SSH in to the Monitoring node.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
@ -2214,7 +2214,7 @@ in the future.
### Enable incremental logging
GitLab Runner returns job logs in chunks which Omnibus GitLab caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
GitLab Runner returns job logs in chunks which the Linux package caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
While sharing the job logs through NFS is supported, it's recommended to avoid the need to use NFS by enabling [incremental logging](../job_logs.md#incremental-logging-architecture) (required when no NFS node has been deployed). Incremental logging uses Redis instead of disk space for temporary caching of job logs.
@ -2246,7 +2246,7 @@ Prometheus, and Grafana.
Hybrid installations leverage the benefits of both cloud native and traditional
compute deployments. With this, _stateless_ components can benefit from cloud native
workload management benefits while _stateful_ components are deployed in compute VMs
with Omnibus to benefit from increased permanence.
with Linux package installations to benefit from increased permanence.
Refer to the Helm charts [Advanced configuration](https://docs.gitlab.com/charts/advanced/)
documentation for setup instructions including guidance on what GitLab secrets to sync
@ -2281,7 +2281,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements
- Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**.
- In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
Next are the backend components that run on static compute VMs using the Linux package (or External PaaS
services where applicable):
| Service | Nodes | Configuration | GCP | AWS |

View File

@ -92,7 +92,7 @@ cluster alongside your instance, read how to
Cloud Native Hybrid Reference Architecture is an alternative approach where select _stateless_
components are deployed in Kubernetes via our official [Helm Charts](https://docs.gitlab.com/charts/),
and _stateful_ components are deployed in compute VMs with Omnibus.
and _stateful_ components are deployed in compute VMs with the Linux package.
The [2k GitLab Cloud Native Hybrid](2k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) (non HA) and [3k GitLab Cloud Native Hybrid](3k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) (HA) reference architectures are the smallest we recommend in Kubernetes.
For environments that serve fewer users, you can lower the node specs. Depending on your user count, you can lower all suggested node specs as desired. However, it's recommended that you don't go lower than the [general requirements](../../install/requirements.md).

View File

@ -444,9 +444,9 @@ The following IPs will be used as an example:
To configure Consul:
1. SSH in to the server that will host Consul.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -470,8 +470,8 @@ To configure Consul:
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -521,19 +521,19 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Omnibus PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. These components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
needs privileges to create the `gitlabhq_production` database.
1. Configure the GitLab application servers with the appropriate details.
This step is covered in [Configuring the GitLab Rails application](#configure-gitlab-rails).
1. The number of nodes required to achieve HA may differ depending on the service compared to Omnibus and doesn't need to match accordingly.
1. The number of nodes required to achieve HA may differ depending on the service compared to the Linux package and doesn't need to match accordingly.
1. However, if [Database Load Balancing](../postgresql/database_load_balancing.md) via Read Replicas is desired for further improved performance it's recommended to follow the node count for the Reference Architecture.
### Standalone PostgreSQL using Omnibus GitLab
### Standalone PostgreSQL using the Linux package
The recommended Omnibus GitLab configuration for a PostgreSQL cluster with
The recommended Linux package configuration for a PostgreSQL cluster with
replication and failover requires:
- A minimum of three PostgreSQL nodes.
@ -670,8 +670,8 @@ PostgreSQL, with Patroni managing its failover, will default to use `pg_rewind`
Like most failover handling methods, this has a small chance of leading to data loss.
For more information, see the various [Patroni replication methods](../postgresql/replication_and_failover.md#selecting-the-appropriate-patroni-replication-method).
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -759,8 +759,8 @@ The following IPs will be used as an example:
node_exporter['listen_address'] = '0.0.0.0:9100'
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -868,9 +868,9 @@ a node and change its status from primary to replica (and vice versa).
#### Configure the primary Redis Cache node
1. SSH in to the **Primary** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -932,17 +932,17 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
#### Configure the replica Redis Cache nodes
1. SSH in to the **replica** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the same contents as the primary node in the previous section replacing `redis_master_node` with `redis_replica_node`:
@ -1004,8 +1004,8 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1031,9 +1031,9 @@ a node and change its status from primary to replica (and vice versa).
#### Configure the primary Redis Persistent node
1. SSH in to the **Primary** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -1086,17 +1086,17 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
#### Configure the replica Redis Persistent nodes
1. SSH in to the **replica** Redis Persistent server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -1152,8 +1152,8 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1210,7 +1210,7 @@ Praefect, the routing and transaction manager for Gitaly Cluster, requires its o
If you want to have a highly available setup, Praefect requires a third-party PostgreSQL database.
A built-in solution is being [worked on](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7292).
#### Praefect non-HA PostgreSQL standalone using Omnibus GitLab
#### Praefect non-HA PostgreSQL standalone using the Linux package
The following IPs will be used as an example:
@ -1272,8 +1272,8 @@ in the second step, do not supply the `EXTERNAL_URL` value.
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1313,11 +1313,11 @@ After the Praefect PostgreSQL server has been set up, you'll then need to config
We recommend the user be named `praefect` and the database `praefect_production`, and these can be configured as standard in PostgreSQL.
The password for the user is the same as the one you configured earlier as `<praefect_postgresql_password>`.
This is how this would work with a Omnibus GitLab PostgreSQL setup:
This is how this would work with a Linux package PostgreSQL setup:
1. SSH in to the Praefect PostgreSQL node.
1. Connect to the PostgreSQL server with administrative access.
The `gitlab-psql` user should be used here for this as it's added by default in Omnibus.
The `gitlab-psql` user should be used here for this as it's added by default in the Linux package.
The database `template1` is used because it is created by default on all PostgreSQL servers.
```shell
@ -1378,7 +1378,7 @@ The following IPs will be used as an example:
To configure the Praefect nodes, on each one:
1. SSH in to the Praefect server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux package
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit the `/etc/gitlab/gitlab.rb` file to configure Praefect:
@ -1490,8 +1490,8 @@ Updates to example must be made at:
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Praefect requires to run some database migrations, much like the main GitLab application. For this
you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node
@ -1551,7 +1551,7 @@ The following IPs will be used as an example:
On each node:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux package
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and _do not_ provide the `EXTERNAL_URL` value.
1. Edit the Gitaly server node's `/etc/gitlab/gitlab.rb` file to configure
@ -1673,8 +1673,8 @@ Updates to example must be made at:
}
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Save the file, and then [reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation).
@ -1779,7 +1779,7 @@ examples include the Object storage configuration.
To configure the Sidekiq nodes, on each one:
1. SSH in to the Sidekiq server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Create or edit `/etc/gitlab/gitlab.rb` and use the following configuration:
@ -1898,8 +1898,8 @@ Updates to example must be made at:
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -1945,7 +1945,7 @@ The following IPs will be used as an example:
On each node perform the following:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
@ -2061,11 +2061,11 @@ On each node perform the following:
sudo cp cert.pem /etc/gitlab/trusted-certs/
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the SSH host keys (all in the name format `/etc/ssh/ssh_host_*_key*`) from the first Omnibus node you configured and
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Copy the SSH host keys (all in the name format `/etc/ssh/ssh_host_*_key*`) from the first Linux package node you configured and
add or replace the files of the same name on this server. This ensures host mismatch errors aren't thrown
for your users as they hit the load balanced Rails nodes. If this is the first Omnibus node you are configuring,
for your users as they hit the load balanced Rails nodes. If this is the first Linux package node you are configuring,
then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -2123,7 +2123,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
## Configure Prometheus
The Omnibus GitLab package can be used to configure a standalone Monitoring node
The Linux package can be used to configure a standalone Monitoring node
running [Prometheus](../monitoring/prometheus/index.md) and
[Grafana](../monitoring/performance/grafana_configuration.md).
@ -2134,7 +2134,7 @@ The following IP will be used as an example:
To configure the Monitoring node:
1. SSH in to the Monitoring node.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
@ -2232,7 +2232,7 @@ in the future.
### Enable incremental logging
GitLab Runner returns job logs in chunks which Omnibus GitLab caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
GitLab Runner returns job logs in chunks which the Linux package caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
While sharing the job logs through NFS is supported, it's recommended to avoid the need to use NFS by enabling [incremental logging](../job_logs.md#incremental-logging-architecture) (required when no NFS node has been deployed). Incremental logging uses Redis instead of disk space for temporary caching of job logs.
@ -2264,7 +2264,7 @@ Prometheus, and Grafana.
Hybrid installations leverage the benefits of both cloud native and traditional
compute deployments. With this, _stateless_ components can benefit from cloud native
workload management benefits while _stateful_ components are deployed in compute VMs
with Omnibus to benefit from increased permanence.
with Linux package installations to benefit from increased permanence.
Refer to the Helm charts [Advanced configuration](https://docs.gitlab.com/charts/advanced/)
documentation for setup instructions including guidance on what GitLab secrets to sync
@ -2299,7 +2299,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements
- Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**.
- In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
Next are the backend components that run on static compute VMs using the Linux package (or External PaaS
services where applicable):
| Service | Nodes | Configuration | GCP | AWS |

View File

@ -253,7 +253,7 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Omnibus PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
@ -261,10 +261,10 @@ If you use a third party external service:
1. Configure the GitLab application servers with the appropriate details.
This step is covered in [Configuring the GitLab Rails application](#configure-gitlab-rails).
### Standalone PostgreSQL using Omnibus GitLab
### Standalone PostgreSQL using the Linux package
1. SSH in to the PostgreSQL server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Generate a password hash for PostgreSQL. This assumes you will use the default
@ -308,8 +308,8 @@ If you use a third party external service:
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
1. Note the PostgreSQL node's IP address or hostname, port, and
@ -336,14 +336,14 @@ You can optionally use a third party external service for Redis as long as it me
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
### Standalone Redis using Omnibus GitLab
### Standalone Redis using the Linux package
The Omnibus GitLab package can be used to configure a standalone Redis server.
The Linux package can be used to configure a standalone Redis server.
The steps below are the minimum necessary to configure a Redis server with
Omnibus:
the Linux package:
1. SSH in to the Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -367,8 +367,8 @@ Omnibus:
}
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -432,7 +432,7 @@ installation has two repository storages: `default` and `storage1`.
To configure the Gitaly server, on the server node you want to use for Gitaly:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux package
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and _do not_ provide the `EXTERNAL_URL` value.
1. Edit the Gitaly server node's `/etc/gitlab/gitlab.rb` file to configure
@ -517,8 +517,8 @@ Updates to example must be made at:
}
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -603,7 +603,7 @@ but this is dependent on workload.
On each node perform the following:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Create or edit `/etc/gitlab/gitlab.rb` and use the following configuration.
@ -717,8 +717,8 @@ On each node perform the following:
sudo cp cert.pem /etc/gitlab/trusted-certs/
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -768,12 +768,12 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
## Configure Prometheus
The Omnibus GitLab package can be used to configure a standalone Monitoring node
The Linux package can be used to configure a standalone Monitoring node
running [Prometheus](../monitoring/prometheus/index.md) and
[Grafana](../monitoring/performance/grafana_configuration.md):
1. SSH in to the Monitoring node.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -908,7 +908,7 @@ in the future.
### Enable incremental logging
GitLab Runner returns job logs in chunks which Omnibus GitLab caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
GitLab Runner returns job logs in chunks which the Linux package caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
While sharing the job logs through NFS is supported, it's recommended to avoid the need to use NFS by enabling [incremental logging](../job_logs.md#incremental-logging-architecture) (required when no NFS node has been deployed). Incremental logging uses Redis instead of disk space for temporary caching of job logs.
@ -940,7 +940,7 @@ Prometheus, and Grafana.
Hybrid installations leverage the benefits of both cloud native and traditional
compute deployments. With this, _stateless_ components can benefit from cloud native
workload management benefits while _stateful_ components are deployed in compute VMs
with Omnibus to benefit from increased permanence.
with Linux package installations to benefit from increased permanence.
Refer to the Helm charts [Advanced configuration](https://docs.gitlab.com/charts/advanced/)
documentation for setup instructions including guidance on what GitLab secrets to sync
@ -979,7 +979,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements
- Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**.
- In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
Next are the backend components that run on static compute VMs using the Linux package (or External PaaS
services where applicable):
| Service | Nodes | Configuration | GCP | AWS |

View File

@ -452,7 +452,7 @@ You can optionally use a third party external service for Redis as long as it me
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
### Standalone Redis using Omnibus GitLab
### Standalone Redis using the Linux package
This is the section where we install and set up the new Redis instances.
@ -474,9 +474,9 @@ a node and change its status from primary to replica (and vice versa).
#### Configuring the primary Redis instance
1. SSH in to the **Primary** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -518,8 +518,8 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -552,9 +552,9 @@ run: redis-exporter: (pid 30075) 76861s; run: log: (pid 29674) 76896s
#### Configuring the replica Redis instances
1. SSH in to the **replica** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -603,8 +603,8 @@ run: redis-exporter: (pid 30075) 76861s; run: log: (pid 29674) 76896s
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
1. Go through the steps again for all the other replica nodes, and
@ -651,9 +651,9 @@ clients to report `NOAUTH Authentication required.`.
To configure the Sentinel:
1. SSH in to the server that will host Consul/Sentinel.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -739,8 +739,8 @@ To configure the Sentinel:
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -791,19 +791,19 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Omnibus PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
needs privileges to create the `gitlabhq_production` database.
1. Configure the GitLab application servers with the appropriate details.
This step is covered in [Configuring the GitLab Rails application](#configure-gitlab-rails).
1. The number of nodes required to achieve HA may differ depending on the service compared to Omnibus and doesn't need to match accordingly.
1. The number of nodes required to achieve HA may differ depending on the service compared to the Linux package and doesn't need to match accordingly.
1. However, if [Database Load Balancing](../postgresql/database_load_balancing.md) via Read Replicas is desired for further improved performance it's recommended to follow the node count for the Reference Architecture.
### Standalone PostgreSQL using Omnibus GitLab
### Standalone PostgreSQL using the Linux package
The recommended Omnibus GitLab configuration for a PostgreSQL cluster with
The recommended Linux package configuration for a PostgreSQL cluster with
replication and failover requires:
- A minimum of three PostgreSQL nodes.
@ -940,8 +940,8 @@ PostgreSQL, with Patroni managing its failover, will default to use `pg_rewind`
Like most failover handling methods, this has a small chance of leading to data loss.
For more information, see the various [Patroni replication methods](../postgresql/replication_and_failover.md#selecting-the-appropriate-patroni-replication-method).
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1030,8 +1030,8 @@ The following IPs will be used as an example:
pgbouncer_exporter['listen_address'] = '0.0.0.0:9188'
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1138,7 +1138,7 @@ Praefect, the routing and transaction manager for Gitaly Cluster, requires its o
If you want to have a highly available setup, Praefect requires a third-party PostgreSQL database.
A built-in solution is being [worked on](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7292).
#### Praefect non-HA PostgreSQL standalone using Omnibus GitLab
#### Praefect non-HA PostgreSQL standalone using the Linux package
The following IPs will be used as an example:
@ -1200,8 +1200,8 @@ in the second step, do not supply the `EXTERNAL_URL` value.
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
1. Follow the [post configuration](#praefect-postgresql-post-configuration).
@ -1240,11 +1240,11 @@ After the Praefect PostgreSQL server has been set up, you'll then need to config
We recommend the user be named `praefect` and the database `praefect_production`, and these can be configured as standard in PostgreSQL.
The password for the user is the same as the one you configured earlier as `<praefect_postgresql_password>`.
This is how this would work with a Omnibus GitLab PostgreSQL setup:
This is how this would work with a Linux package PostgreSQL setup:
1. SSH in to the Praefect PostgreSQL node.
1. Connect to the PostgreSQL server with administrative access.
The `gitlab-psql` user should be used here for this as it's added by default in Omnibus.
The `gitlab-psql` user should be used here for this as it's added by default in the Linux package.
The database `template1` is used because it is created by default on all PostgreSQL servers.
```shell
@ -1305,7 +1305,7 @@ The following IPs will be used as an example:
To configure the Praefect nodes, on each one:
1. SSH in to the Praefect server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit the `/etc/gitlab/gitlab.rb` file to configure Praefect:
@ -1417,8 +1417,8 @@ Updates to example must be made at:
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Praefect requires to run some database migrations, much like the main GitLab application. For this
you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node
@ -1478,7 +1478,7 @@ The following IPs will be used as an example:
On each node:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux package
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and _do not_ provide the `EXTERNAL_URL` value.
1. Edit the Gitaly server node's `/etc/gitlab/gitlab.rb` file to configure
@ -1604,8 +1604,8 @@ Updates to example must be made at:
}
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Save the file, and then [reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation).
@ -1712,7 +1712,7 @@ The following IPs will be used as an example:
To configure the Sidekiq nodes, one each one:
1. SSH in to the Sidekiq server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Create or edit `/etc/gitlab/gitlab.rb` and use the following configuration:
@ -1824,8 +1824,8 @@ Updates to example must be made at:
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -1878,7 +1878,7 @@ examples include the Object storage configuration.
On each node perform the following:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Create or edit `/etc/gitlab/gitlab.rb` and use the following configuration.
@ -2011,11 +2011,11 @@ On each node perform the following:
sudo cp cert.pem /etc/gitlab/trusted-certs/
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the SSH host keys (all in the name format `/etc/ssh/ssh_host_*_key*`) from the first Omnibus node you configured and
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Copy the SSH host keys (all in the name format `/etc/ssh/ssh_host_*_key*`) from the first Linux package node you configured and
add or replace the files of the same name on this server. This ensures host mismatch errors aren't thrown
for your users as they hit the load balanced Rails nodes. If this is the first Omnibus node you are configuring,
for your users as they hit the load balanced Rails nodes. If this is the first Linux package node you are configuring,
then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -2080,12 +2080,12 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
## Configure Prometheus
The Omnibus GitLab package can be used to configure a standalone Monitoring node
The Linux package can be used to configure a standalone Monitoring node
running [Prometheus](../monitoring/prometheus/index.md) and
[Grafana](../monitoring/performance/grafana_configuration.md):
1. SSH in to the Monitoring node.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -2197,7 +2197,7 @@ in the future.
### Enable incremental logging
GitLab Runner returns job logs in chunks which Omnibus GitLab caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
GitLab Runner returns job logs in chunks which the Linux package caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
While sharing the job logs through NFS is supported, it's recommended to avoid the need to use NFS by enabling [incremental logging](../job_logs.md#incremental-logging-architecture) (required when no NFS node has been deployed). Incremental logging uses Redis instead of disk space for temporary caching of job logs.
@ -2238,7 +2238,7 @@ but with smaller performance requirements, several modifications can be consider
- Running select components in reputable Cloud PaaS solutions: Select components of the GitLab setup can instead be run on Cloud Provider PaaS solutions. By doing this, additional dependent components can also be removed:
- PostgreSQL: Can be run on reputable Cloud PaaS solutions such as Google Cloud SQL or Amazon RDS. In this setup, the PgBouncer and Consul nodes are no longer required:
- Consul may still be desired if [Prometheus](../monitoring/prometheus/index.md) auto discovery is a requirement, otherwise you would need to [manually add scrape configurations](../monitoring/prometheus/index.md#adding-custom-scrape-configurations) for all nodes.
- As Redis Sentinel runs on the same box as Consul in this architecture, it may need to be run on a separate box if Redis is still being run via Omnibus.
- As Redis Sentinel runs on the same box as Consul in this architecture, it may need to be run on a separate box if Redis is still being run using the Linux package.
- Redis: Can be run on reputable Cloud PaaS solutions such as Google Memorystore and AWS ElastiCache. In this setup, the Redis Sentinel is no longer required.
## Cloud Native Hybrid reference architecture with Helm Charts (alternative)
@ -2253,7 +2253,7 @@ Prometheus, and Grafana.
Hybrid installations leverage the benefits of both cloud native and traditional
compute deployments. With this, _stateless_ components can benefit from cloud native
workload management benefits while _stateful_ components are deployed in compute VMs
with Omnibus to benefit from increased permanence.
with Linux package installations to benefit from increased permanence.
Refer to the Helm charts [Advanced configuration](https://docs.gitlab.com/charts/advanced/)
documentation for setup instructions including guidance on what GitLab secrets to sync
@ -2288,7 +2288,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements
- Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**.
- In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
Next are the backend components that run on static compute VMs using the Linux package (or External PaaS
services where applicable):
| Service | Nodes | Configuration | GCP | AWS |

View File

@ -436,9 +436,9 @@ The following IPs will be used as an example:
To configure Consul:
1. SSH in to the server that will host Consul.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -462,8 +462,8 @@ To configure Consul:
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -513,19 +513,19 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Omnibus PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
needs privileges to create the `gitlabhq_production` database.
1. Configure the GitLab application servers with the appropriate details.
This step is covered in [Configuring the GitLab Rails application](#configure-gitlab-rails).
1. The number of nodes required to achieve HA may differ depending on the service compared to Omnibus and doesn't need to match accordingly.
1. The number of nodes required to achieve HA may differ depending on the service compared to the Linux package and doesn't need to match accordingly.
1. However, if [Database Load Balancing](../postgresql/database_load_balancing.md) via Read Replicas is desired for further improved performance it's recommended to follow the node count for the Reference Architecture.
### Standalone PostgreSQL using Omnibus GitLab
### Standalone PostgreSQL using the Linux package
The recommended Omnibus GitLab configuration for a PostgreSQL cluster with
The recommended Linux package configuration for a PostgreSQL cluster with
replication and failover requires:
- A minimum of three PostgreSQL nodes.
@ -663,8 +663,8 @@ PostgreSQL, with Patroni managing its failover, will default to use `pg_rewind`
Like most failover handling methods, this has a small chance of leading to data loss.
For more information, see the various [Patroni replication methods](../postgresql/replication_and_failover.md#selecting-the-appropriate-patroni-replication-method).
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -752,8 +752,8 @@ The following IPs will be used as an example:
node_exporter['listen_address'] = '0.0.0.0:9100'
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -861,9 +861,9 @@ a node and change its status from primary to replica (and vice versa).
#### Configure the primary Redis Cache node
1. SSH in to the **Primary** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -926,17 +926,17 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
#### Configure the replica Redis Cache nodes
1. SSH in to the **replica** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the same contents as the primary node in the previous section by replacing `redis_master_node` with `redis_replica_node`:
@ -999,9 +999,9 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package
node you configured and add or replace the file of the same name on this
server. If this is the first Omnibus node you are configuring then you
server. If this is the first Linux package node you are configuring then you
can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes
@ -1029,9 +1029,9 @@ a node and change its status from primary to replica (and vice versa).
#### Configure the primary Redis Persistent node
1. SSH in to the **Primary** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -1084,17 +1084,17 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
#### Configure the replica Redis Persistent nodes
1. SSH in to the **replica** Redis Persistent server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -1147,8 +1147,8 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1204,7 +1204,7 @@ Praefect, the routing and transaction manager for Gitaly Cluster, requires its o
If you want to have a highly available setup, Praefect requires a third-party PostgreSQL database.
A built-in solution is being [worked on](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7292).
#### Praefect non-HA PostgreSQL standalone using Omnibus GitLab
#### Praefect non-HA PostgreSQL standalone using the Linux package
The following IPs will be used as an example:
@ -1266,8 +1266,8 @@ in the second step, do not supply the `EXTERNAL_URL` value.
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1309,11 +1309,11 @@ After the Praefect PostgreSQL server has been set up, you'll then need to config
We recommend the user be named `praefect` and the database `praefect_production`, and these can be configured as standard in PostgreSQL.
The password for the user is the same as the one you configured earlier as `<praefect_postgresql_password>`.
This is how this would work with a Omnibus GitLab PostgreSQL setup:
This is how this would work with a Linux package PostgreSQL setup:
1. SSH in to the Praefect PostgreSQL node.
1. Connect to the PostgreSQL server with administrative access.
The `gitlab-psql` user should be used here for this as it's added by default in Omnibus.
The `gitlab-psql` user should be used here for this as it's added by default in the Linux package.
The database `template1` is used because it is created by default on all PostgreSQL servers.
```shell
@ -1374,7 +1374,7 @@ The following IPs will be used as an example:
To configure the Praefect nodes, on each one:
1. SSH in to the Praefect server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit the `/etc/gitlab/gitlab.rb` file to configure Praefect:
@ -1486,8 +1486,8 @@ Updates to example must be made at:
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Praefect requires to run some database migrations, much like the main GitLab application. For this
you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node
@ -1547,7 +1547,7 @@ The following IPs will be used as an example:
On each node:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and _do not_ provide the `EXTERNAL_URL` value.
1. Edit the Gitaly server node's `/etc/gitlab/gitlab.rb` file to configure
@ -1669,8 +1669,8 @@ Updates to example must be made at:
}
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Save the file, and then [reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation).
@ -1775,7 +1775,7 @@ examples include the Object storage configuration.
To configure the Sidekiq nodes, on each one:
1. SSH in to the Sidekiq server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Create or edit `/etc/gitlab/gitlab.rb` and use the following configuration:
@ -1894,8 +1894,8 @@ Updates to example must be made at:
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -1948,7 +1948,7 @@ The following IPs will be used as an example:
On each node perform the following:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
@ -2064,8 +2064,8 @@ On each node perform the following:
sudo cp cert.pem /etc/gitlab/trusted-certs/
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
```shell
@ -2122,7 +2122,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
## Configure Prometheus
The Omnibus GitLab package can be used to configure a standalone Monitoring node
The Linux package can be used to configure a standalone Monitoring node
running [Prometheus](../monitoring/prometheus/index.md) and
[Grafana](../monitoring/performance/grafana_configuration.md).
@ -2133,7 +2133,7 @@ The following IP will be used as an example:
To configure the Monitoring node:
1. SSH in to the Monitoring node.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
@ -2231,7 +2231,7 @@ in the future.
### Enable incremental logging
GitLab Runner returns job logs in chunks which Omnibus GitLab caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
GitLab Runner returns job logs in chunks which the Linux package caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
While sharing the job logs through NFS is supported, it's recommended to avoid the need to use NFS by enabling [incremental logging](../job_logs.md#incremental-logging-architecture) (required when no NFS node has been deployed). Incremental logging uses Redis instead of disk space for temporary caching of job logs.
@ -2263,7 +2263,7 @@ Prometheus, and Grafana.
Hybrid installations leverage the benefits of both cloud native and traditional
compute deployments. With this, _stateless_ components can benefit from cloud native
workload management benefits while _stateful_ components are deployed in compute VMs
with Omnibus to benefit from increased permanence.
with Linux package installations to benefit from increased permanence.
Refer to the Helm charts [Advanced configuration](https://docs.gitlab.com/charts/advanced/)
documentation for setup instructions including guidance on what GitLab secrets to sync
@ -2298,7 +2298,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements
- Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**.
- In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
Next are the backend components that run on static compute VMs using the Linux package (or External PaaS
services where applicable):
| Service | Nodes | Configuration | GCP | AWS |

View File

@ -446,7 +446,7 @@ You can optionally use a third party external service for Redis as long as it me
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
### Standalone Redis using Omnibus GitLab
### Standalone Redis using the Linux package
This is the section where we install and set up the new Redis instances.
@ -468,9 +468,9 @@ a node and change its status from primary to replica (and vice versa).
#### Configuring the primary Redis instance
1. SSH in to the **Primary** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -512,8 +512,8 @@ a node and change its status from primary to replica (and vice versa).
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -546,9 +546,9 @@ run: redis-exporter: (pid 30075) 76861s; run: log: (pid 29674) 76896s
#### Configuring the replica Redis instances
1. SSH in to the **replica** Redis server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -597,8 +597,8 @@ run: redis-exporter: (pid 30075) 76861s; run: log: (pid 29674) 76896s
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
1. Go through the steps again for all the other replica nodes, and
@ -645,9 +645,9 @@ clients to report `NOAUTH Authentication required.`.
To configure the Sentinel:
1. SSH in to the server that hosts Consul/Sentinel.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to both follow _only_ installation steps 1 and 2
on the page, and to select the correct Omnibus GitLab package, with the same version
on the page, and to select the correct Linux package, with the same version
and type (Community or Enterprise editions) as your current install.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -733,8 +733,8 @@ To configure the Sentinel:
gitlab_rails['auto_migrate'] = false
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
1. Go through the steps again for all the other Consul/Sentinel nodes, and
@ -784,19 +784,19 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Omnibus PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
needs privileges to create the `gitlabhq_production` database.
1. Configure the GitLab application servers with the appropriate details.
This step is covered in [Configuring the GitLab Rails application](#configure-gitlab-rails).
1. The number of nodes required to achieve HA may differ depending on the service compared to Omnibus and doesn't need to match accordingly.
1. The number of nodes required to achieve HA may differ depending on the service compared to the Linux package and doesn't need to match accordingly.
1. However, if [Database Load Balancing](../postgresql/database_load_balancing.md) via Read Replicas is desired for further improved performance it's recommended to follow the node count for the Reference Architecture.
### Standalone PostgreSQL using Omnibus GitLab
### Standalone PostgreSQL using the Linux package
The recommended Omnibus GitLab configuration for a PostgreSQL cluster with
The recommended Linux package configuration for a PostgreSQL cluster with
replication and failover requires:
- A minimum of three PostgreSQL nodes.
@ -933,8 +933,8 @@ PostgreSQL, with Patroni managing its failover, defaults to use `pg_rewind` by d
Like most failover handling methods, this has a small chance of leading to data loss.
For more information, see the various [Patroni replication methods](../postgresql/replication_and_failover.md#selecting-the-appropriate-patroni-replication-method).
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1023,8 +1023,8 @@ The following IPs are used as an example:
pgbouncer_exporter['listen_address'] = '0.0.0.0:9188'
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1131,7 +1131,7 @@ Praefect, the routing and transaction manager for Gitaly Cluster, requires its o
If you want to have a highly available setup, Praefect requires a third-party PostgreSQL database.
A built-in solution is being [worked on](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7292).
#### Praefect non-HA PostgreSQL standalone using Omnibus GitLab
#### Praefect non-HA PostgreSQL standalone using the Linux package
The following IPs are used as an example:
@ -1193,8 +1193,8 @@ in the second step, do not supply the `EXTERNAL_URL` value.
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@ -1234,11 +1234,11 @@ After the Praefect PostgreSQL server has been set up, you then need to configure
We recommend the user be named `praefect` and the database `praefect_production`, and these can be configured as standard in PostgreSQL.
The password for the user is the same as the one you configured earlier as `<praefect_postgresql_password>`.
This is how this would work with a Omnibus GitLab PostgreSQL setup:
This is how this would work with a Linux package PostgreSQL setup:
1. SSH in to the Praefect PostgreSQL node.
1. Connect to the PostgreSQL server with administrative access.
The `gitlab-psql` user should be used here for this as it's added by default in Omnibus.
The `gitlab-psql` user should be used here for this as it's added by default in the Linux package.
The database `template1` is used because it is created by default on all PostgreSQL servers.
```shell
@ -1299,7 +1299,7 @@ The following IPs are used as an example:
To configure the Praefect nodes, on each one:
1. SSH in to the Praefect server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit the `/etc/gitlab/gitlab.rb` file to configure Praefect:
@ -1411,8 +1411,8 @@ Updates to example must be made at:
# END user configuration
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Praefect requires to run some database migrations, much like the main GitLab application. For this
you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node
@ -1472,7 +1472,7 @@ The following IPs are used as an example:
On each node:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page, and _do not_ provide the `EXTERNAL_URL` value.
1. Edit the Gitaly server node's `/etc/gitlab/gitlab.rb` file to configure
@ -1594,8 +1594,8 @@ Updates to example must be made at:
}
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Save the file, and then [reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation).
@ -1700,7 +1700,7 @@ examples include the Object storage configuration.
To configure the Sidekiq nodes, one each one:
1. SSH in to the Sidekiq server.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux package
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Create or edit `/etc/gitlab/gitlab.rb` and use the following configuration:
@ -1813,8 +1813,8 @@ Updates to example must be made at:
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -1867,7 +1867,7 @@ examples include the Object storage configuration.
On each node perform the following:
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Create or edit `/etc/gitlab/gitlab.rb` and use the following configuration.
@ -2003,11 +2003,11 @@ On each node perform the following:
sudo cp cert.pem /etc/gitlab/trusted-certs/
```
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Omnibus node you configured and add or replace
the file of the same name on this server. If this is the first Omnibus node you are configuring then you can skip this step.
1. Copy the SSH host keys (all in the name format `/etc/ssh/ssh_host_*_key*`) from the first Omnibus node you configured and
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace
the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step.
1. Copy the SSH host keys (all in the name format `/etc/ssh/ssh_host_*_key*`) from the first Linux package node you configured and
add or replace the files of the same name on this server. This ensures host mismatch errors aren't thrown
for your users as they hit the load balanced Rails nodes. If this is the first Omnibus node you are configuring,
for your users as they hit the load balanced Rails nodes. If this is the first Linux package node you are configuring,
then you can skip this step.
1. To ensure database migrations are only run during reconfigure and not automatically on upgrade, run:
@ -2072,12 +2072,12 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
## Configure Prometheus
The Omnibus GitLab package can be used to configure a standalone Monitoring node
The Linux package can be used to configure a standalone Monitoring node
running [Prometheus](../monitoring/prometheus/index.md) and
[Grafana](../monitoring/performance/grafana_configuration.md):
1. SSH in to the Monitoring node.
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
1. [Download and install](https://about.gitlab.com/install/) the Linux
package of your choice. Be sure to follow _only_ installation steps 1 and 2
on the page.
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
@ -2189,7 +2189,7 @@ in the future.
### Enable incremental logging
GitLab Runner returns job logs in chunks which Omnibus GitLab caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
GitLab Runner returns job logs in chunks which the Linux package caches temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by default, even when using consolidated object storage. With default configuration, this directory needs to be shared through NFS on any GitLab Rails and Sidekiq nodes.
While sharing the job logs through NFS is supported, it's recommended to avoid the need to use NFS by enabling [incremental logging](../job_logs.md#incremental-logging-architecture) (required when no NFS node has been deployed). Incremental logging uses Redis instead of disk space for temporary caching of job logs.
@ -2221,7 +2221,7 @@ Prometheus, and Grafana.
Hybrid installations leverage the benefits of both cloud native and traditional
compute deployments. With this, _stateless_ components can benefit from cloud native
workload management benefits while _stateful_ components are deployed in compute VMs
with Omnibus to benefit from increased permanence.
with Linux package installations to benefit from increased permanence.
Refer to the Helm charts [Advanced configuration](https://docs.gitlab.com/charts/advanced/)
documentation for setup instructions including guidance on what GitLab secrets to sync
@ -2256,7 +2256,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements
- Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**.
- In production deployments, there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices.
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
Next are the backend components that run on static compute VMs using the Linux package (or External PaaS
services where applicable):
| Service | Nodes | Configuration | GCP | AWS |

View File

@ -268,7 +268,7 @@ Through testing and real life usage, the Reference Architectures are validated a
</thead>
<tbody>
<tr>
<td>Omnibus</td>
<td>Linux package</td>
<td>🟢</td>
<td>🟢</td>
<td>🟡<sup>1</sup></td>

View File

@ -63,7 +63,7 @@ This section documents the current behavior of GitLab when Silent Mode is enable
### Service Desk
Incoming emails still raise issues, but the users who sent the emails to [Service Desk](../../user/project/service_desk.md) are not notified of issue creation or comments on their issues.
Incoming emails still raise issues, but the users who sent the emails to [Service Desk](../../user/project/service_desk/index.md) are not notified of issue creation or comments on their issues.
### Webhooks

View File

@ -97,7 +97,7 @@ GET /users?external=true
```
GitLab supports bot users such as the [alert bot](../operations/incident_management/integrations.md)
or the [support bot](../user/project/service_desk.md#support-bot-user).
or the [support bot](../user/project/service_desk/index.md#support-bot-user).
You can exclude the following types of [internal users](../development/internal_users.md#internal-users)
from the users' list with the `exclude_internal=true` parameter
([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241144) in GitLab 13.4):

View File

@ -0,0 +1,221 @@
---
status: proposed
creation-date: "2023-05-19"
authors: [ "@jcai-gitlab", "@toon" ]
coach: [ ]
approvers: [ ]
owning-stage: "~devops::systems"
---
# Offload data to cheaper storage
## Summary
Managing Git data storage costs is a critical part of our business. Offloading
Git data to cheaper storage can save on storage cost.
## Motivation
At GitLab, we keep most Git data stored on SSDs to keep data access fast. This
makes sense for data that we frequently need to access. However, given that
storage costs scale with data growth, we can be a lot smarter about what kinds
of data we keep on SSDs and what kinds of data we can afford to offload to
cheaper storage.
For example, large files (or in Git nomenclature, "blobs") are not frequently
modified since they are usually non-text files (images, videos, binaries, etc).
Often, [Git LFS](https://git-lfs.com/) is used for repositories that contain
these large blobs in order to avoid having to push a large file onto the Git
server. However, this relies on client side setup.
Or, if a project is "stale" and hasn't been accessed in a long time, there is no
need to keep paying for fast storage for that project.
Instead, we can choose to put **all** blobs of that stale project onto cheaper
storage. This way, the application still has access to the commit history and
trees so the project browsing experience is not affected, but all files are on
slower storage since they are rarely accessed.
If we had a way to separate Git data into different categories, we could then
offload certain data to a secondary location that is cheaper. For example, we
could separate large files that may not be accessed as frequently from the rest
of the Git data and save it to an HDD rather than an SDD mount.
## Requirements
There are a set of requirements and invariants that must be given for any
particular solution.
### Saves storage cost
Ultimately, this solution needs to save on storage cost. Separating out certain
Git data for cheaper storage can go towards this savings.
We need to evaluate the solution's added cost against the projected savings from
offloading data to cheaper storage. Here are some criteria to consider:
- How much money would we save if all large blobs larger than X were put on HDD?
- How much money would we save if all stale projects had their blobs on HDD?
- What's the operational overhead for running the offloading mechanism in terms
of additional CPU/Memory cost?
- What's the network overhead? e.g. is there an extra roundtrip to a different
node via the network to retrieve large blobs.
- Access cost, e.g. when blobs would be stored in an object store.
### Opaque to downstream consumers of Gitaly
This feature is purely storage optimization and, except for potential
performance slowdown, shouldn't affect downstream consumers of Gitaly. For
example, the GitLab application should not have to change any of its logic in
order to support this feature.
This feature should be completely invisible to any callers of Gitaly. Rails or
any consumer should not need to know about this or manage it in any way.
### Operationally Simple
When working with Git data, we want to keep things as simple as possible to
minimize risk of repository corruption. Keep things operationally simple and
keep moving pieces outside of Git itself to a minimum. Any logic that modifies
repository data should be upstreamed in Git itself.
## Proposal
We will maintain a separate object database for each repository connected
through the [Git alternates mechansim](https://git-scm.com/docs/gitrepository-layout#Documentation/gitrepository-layout.txt-objects).
We can choose to filter out certain Git objects for this secondary object
database (ODB).
Place Git data into this secondary ODB based on a filter. We have
options based on [filters in Git](https://git-scm.com/docs/git-rev-list#Documentation/git-rev-list.txt---filterltfilter-specgt).
We can choose to place large blobs based on some limit into a secondary ODB, or
we can choose to place all blobs onto the secondary ODB.
## Design and implementation details
### Git
We need to add a feature to `git-repack(1)` that will allow us to segment
different kinds of blobs into different object databases. We're tracking this
effort in [this issue](https://gitlab.com/gitlab-org/git/-/issues/159).
### Gitaly
During Gitaly housekeeping, we can do the following:
1. Use `git-repack(1)` to write packfiles into both the main repository's object
database, and a secondary object database. Each repository has its own
secondary object database for offloading blobs based on some criteria.
1. Ensure the `.git/objects/info/alternates` file points to the secondary
object database from step (1).
### Criteria
Whether objects are offloaded to another object database can be determined based
on one or many of the following criteria.
#### By Tier
Free projects might have many blobs offloaded to cheaper storage, while Ultimate
projects have all their objects placed on the fastest storage.
#### By history
If a blob was added a long time ago and is not referred by any recent commit it
can get offloaded, while new blobs remain on the main ODB.
#### By size
Large blobs are a quick win to reduce the expensive storage size, so they might
get prioritized to move to cheaper storage.
#### Frequency of Access
Frequently used project might remain fully on fast storage, while inactive
projects might have their blob offloaded.
### Open Questions
#### How do we delete objects?
When we want to delete an unreachable object, the repack would need to be aware
of both ODBs and be able to evict unreachable objects regardless of whether
the objects are in the main ODB or in the secondary ODB. This picture is
complicated if the main ODB also has an [object pool](https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/object_pools.md)
ODB, since we wouldn't ever want to delete an object from the pool ODB.
#### Potential Solution: Modify Git to delete an object from alternates
We would need to modify repack to give it the ability to delete unreachable
objects in alternate ODBs. We could add repack configs `repack.alternates.*`
that tell it how to behave with alternate directories. For example, we could
have `repack.alternates.explodeUnreachable`, which indicates to repack that it
should behave like `-A` in any alternate ODB it is linked to.
#### How does this work with object pools?
When we use alternates, how does this interact with object pools? Does the
object pool also offload data to secondary storage? Does the object pool member?
In the most complex case this means that a single repository has four different
object databases, which may increase complexity.
Possibly we can mark some packfiles as "keep", using the
[--keep-pack](https://git-scm.com/docs/git-pack-objects#Documentation/git-pack-objects.txt---keep-packltpack-namegt)
and
[--honor-pack-keep](https://git-scm.com/docs/git-pack-objects#Documentation/git-pack-objects.txt---honor-pack-keep)
options.
#### Potential Solution: Do not allow object pools to offload their blobs
For the sake of not adding too much complexity, we could decide that object
pools will not offload their blobs. Instead, we can design housekeeping to
offload blobs from the repository before deduplicating with the object pool.
Theoretically, this means that offloaded blobs will not end up in the object
pool.
#### How will this work with Raft + WAL?
How will this mechanism interact with Raft and the write-ahead log?
The WAL uses hard-links and copy-free moves, to avoid slow copy operations. But
that does not work across different file systems. At some point repacks and such
will likely also go through the log. Transferring data between file systems can
lead to delays in transaction processing.
Ideally we keep the use of an alternate internal to the node and not have to
leak this complexity to the rest of the cluster. This is a challenge, given we
have to consider available space when making placement decisions. It's possible
to keep this internal by only showing the lower capacity of the two storages,
but that could also lead to inefficient storage use.
## Problems with the design
### Added complexity
The fact that we are adding another object pool to the mix adds complexity to
the system, and especially with repository replication since we are adding yet
another place to replicate data to.
### Possible change in cost over time
The cost of the different storage types might change over time. To anticipate
for this, it should be easy to adapt to such changes.
### More points of failure
Having some blobs on a separate storage device adds one more failure scenario
where the device hosting the large blobs may fail.
## Alternative Solutions
### Placing entire projects onto cheaper storage
Instead of placing Git data onto cheaper storage, the Rails application could
choose to move a project in its entirety to a mounted HDD drive.
#### Possible optimization
Giving these machines with cheaper storage extra RAM might help to deal with the
slow read/write speeds due to the use of page cache. It's not sure though this
will turn out to be cheaper overall.

View File

@ -67,6 +67,9 @@ the next scheduled time:
You can manually run scheduled pipelines once per minute.
When you run a scheduled pipeline manually, the pipeline runs with the
permissions of the user who triggered it, not the permissions of the schedule owner.
## Take ownership
Scheduled pipelines execute with the permissions of the user

View File

@ -16,6 +16,6 @@ When implementing new features, please refer to these existing features to avoid
- [Route Maps](../ci/review_apps/index.md#route-maps): `.gitlab/route-map.yml`.
- [Customize Auto DevOps Helm Values](../topics/autodevops/customize.md#customize-helm-chart-values): `.gitlab/auto-deploy-values.yaml`.
- [Insights](../user/project/insights/index.md#configure-project-insights): `.gitlab/insights.yml`.
- [Service Desk Templates](../user/project/service_desk.md#customize-emails-sent-to-the-requester): `.gitlab/service_desk_templates/`.
- [Service Desk Templates](../user/project/service_desk/index.md#customize-emails-sent-to-the-requester): `.gitlab/service_desk_templates/`.
- [Secret Detection Custom Rulesets](../user/application_security/secret_detection/index.md#disable-predefined-analyzer-rules): `.gitlab/secret-detection-ruleset.toml`
- [Static Analysis Custom Rulesets](../user/application_security/sast/customize_rulesets.md#create-the-configuration-file): `.gitlab/sast-ruleset.toml`

View File

@ -43,7 +43,7 @@ Other examples of internal users:
- [GitLab Admin Bot](https://gitlab.com/gitlab-org/gitlab/-/blob/278bc9018dd1515a10cbf15b6c6cd55cb5431407/app/models/user.rb#L950-960)
- [Alert Bot](../operations/incident_management/alerts.md#trigger-actions-from-alerts)
- [Ghost User](../user/profile/account/delete_account.md#associated-records)
- [Support Bot](../user/project/service_desk.md#support-bot-user)
- [Support Bot](../user/project/service_desk/index.md#support-bot-user)
- Visual Review Bot
- Resource access tokens, including:
- [Project access tokens](../user/project/settings/project_access_tokens.md).

View File

@ -107,7 +107,7 @@ the tiers are no longer mentioned in GitLab documentation:
- [Filtering merge requests](../user/project/merge_requests/index.md#filter-the-list-of-merge-requests) by approvers
- [Filtering merge requests](../user/project/merge_requests/index.md#filter-the-list-of-merge-requests) by "approved by"
- [Advanced search (Elasticsearch)](../user/search/advanced_search.md)
- [Service Desk](../user/project/service_desk.md)
- [Service Desk](../user/project/service_desk/index.md)
- [Storage usage statistics](../user/usage_quotas.md#storage-usage-statistics)
The following developer features continue to be available to Starter and

View File

@ -83,7 +83,7 @@ Every user is included in seat usage, with the following exceptions:
- GitLab-created service accounts:
- [Ghost User](../../user/profile/account/delete_account.md#associated-records).
- Bots such as:
- [Support Bot](../../user/project/service_desk.md#support-bot-user).
- [Support Bot](../../user/project/service_desk/index.md#support-bot-user).
- [Bot users for projects](../../user/project/settings/project_access_tokens.md#bot-users-for-projects).
- [Bot users for groups](../../user/group/settings/group_access_tokens.md#bot-users-for-groups).

View File

@ -57,7 +57,7 @@ billable user, with the following exceptions:
- GitLab-created service accounts:
- [Ghost User](../../user/profile/account/delete_account.md#associated-records).
- Bots such as:
- [Support Bot](../../user/project/service_desk.md#support-bot-user).
- [Support Bot](../../user/project/service_desk/index.md#support-bot-user).
- [Bot users for projects](../../user/project/settings/project_access_tokens.md#bot-users-for-projects).
- [Bot users for groups](../../user/group/settings/group_access_tokens.md#bot-users-for-groups).
- Other [internal users](../../development/internal_users.md#internal-users).

View File

@ -157,7 +157,7 @@ organizations using the GraphQL API.
## Issues
If you use [Service Desk](../project/service_desk.md) and create issues from emails,
If you use [Service Desk](../project/service_desk/index.md) and create issues from emails,
issues are linked to contacts matching the email addresses in the sender and CC of the email.
### View issues linked to a contact

View File

@ -73,7 +73,7 @@ The IP addresses for `mg.gitlab.com` are subject to change at any time.
On GitLab.com, there's a mailbox configured for Service Desk with the email address:
`contact-project+%{key}@incoming.gitlab.com`. To use this mailbox, configure the
[custom suffix](../project/service_desk.md#configure-a-suffix-for-service-desk-alias-email) in project
[custom suffix](../project/service_desk/index.md#configure-a-suffix-for-service-desk-alias-email) in project
settings.
## Backups

View File

@ -16,7 +16,7 @@ You might want to use these templates:
- For different stages of your workflow, for example, feature proposal, feature improvement, or a bug report.
- For every issue or merge request for a specific project, so the layout is consistent.
- For a [Service Desk email template](service_desk.md#use-a-custom-template-for-service-desk-tickets).
- For a [Service Desk email template](service_desk/index.md#use-a-custom-template-for-service-desk-tickets).
For description templates to work, they must be:

View File

@ -192,7 +192,7 @@ To create an issue in the GitLab project:
## Using Service Desk
To offer email support, enable [Service Desk](../service_desk.md) for your project.
To offer email support, enable [Service Desk](../service_desk/index.md) for your project.
Now, when your customer sends a new email, a new issue can be created in
the appropriate project and followed up from there.

View File

@ -1,914 +1,11 @@
---
stage: Monitor
group: Respond
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
redirect_to: 'service_desk/index.md'
remove_date: '2023-10-24'
---
# Service Desk **(FREE)**
This document was moved to [another location](service_desk/index.md).
> Moved to GitLab Free in 13.2.
With Service Desk, your customers
can email you bug reports, feature requests, or general feedback.
Service Desk provides a unique email address, so they don't need their own GitLab accounts.
Service Desk emails are created in your GitLab project as new issues.
Your team can respond directly from the project, while customers interact with the thread only
through email.
## Service Desk workflow
For example, let's assume you develop a game for iOS or Android.
The codebase is hosted in your GitLab instance, built and deployed
with GitLab CI/CD.
Here's how Service Desk works for you:
1. You provide a project-specific email address to your paying customers, who can email you directly
from the application.
1. Each email they send creates an issue in the appropriate project.
1. Your team members go to the Service Desk issue tracker, where they can see new support
requests and respond inside associated issues.
1. Your team communicates with the customer to understand the request.
1. Your team starts working on implementing code to solve your customer's problem.
1. When your team finishes the implementation, the merge request is merged and the issue
is closed automatically.
Meanwhile:
- The customer interacts with your team entirely through email, without needing access to your
GitLab instance.
- Your team saves time by not having to leave GitLab (or set up integrations) to follow up with
your customer.
## Configure Service Desk
By default, Service Desk is active in new projects.
If it's not active, you can do it in the project's settings.
Prerequisites:
- You must have at least the Maintainer role for the project.
- On GitLab self-managed, you must [set up incoming email](../../administration/incoming_email.md#set-it-up)
for the GitLab instance. You should use
[email sub-addressing](../../administration/incoming_email.md#email-sub-addressing),
but you can also use [catch-all mailboxes](../../administration/incoming_email.md#catch-all-mailbox).
To do this, you must have administrator access.
- You must have enabled [issue](settings/index.md#configure-project-visibility-features-and-permissions)
tracker for the project.
To enable Service Desk in your project:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
1. Expand **Service Desk**.
1. Turn on the **Activate Service Desk** toggle.
1. Optional. Complete the fields.
- [Add a suffix](#configure-a-suffix-for-service-desk-alias-email) to your Service Desk email address.
- If the list below **Template to append to all Service Desk issues** is empty, create a
[description template](description_templates.md) in your repository.
1. Select **Save changes**.
Service Desk is now enabled for this project.
If anyone sends an email to the address available below **Email address to use for Service Desk**,
GitLab creates a confidential issue with the email's content.
### Improve your project's security
To improve your Service Desk project's security, you should:
- Put the Service Desk email address behind an alias on your email system so you can change it later.
- [Enable Akismet](../../integration/akismet.md) on your GitLab instance to add spam checking to this service.
Unblocked email spam can result in many spam issues being created.
### Customize emails sent to the requester
> - Moved from GitLab Premium to GitLab Free in 13.2.
> - `UNSUBSCRIBE_URL`, `SYSTEM_HEADER`, `SYSTEM_FOOTER`, and `ADDITIONAL_TEXT` placeholders [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285512) in GitLab 15.9.
> - `%{ISSUE_DESCRIPTION}` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/223751) in GitLab 16.0.
> - `%{ISSUE_URL}` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/408793) in GitLab 16.1.
An email is sent to the requester when:
- A requester submits a new ticket by emailing Service Desk.
- A new public comment is added on a Service Desk ticket.
- Editing a comment does not trigger a new email to be sent.
You can customize the body of these email messages with Service Desk email templates. The templates
can include [GitLab Flavored Markdown](../markdown.md) and [some HTML tags](../markdown.md#inline-html).
For example, you can format the emails to include a header and footer in accordance with your
organization's brand guidelines. You can also include the following placeholders to display dynamic
content specific to the Service Desk ticket or your GitLab instance.
| Placeholder | `thank_you.md` | `new_note.md` | Description
| ---------------------- | ---------------------- | ---------------------- | -----------
| `%{ISSUE_ID}` | **{check-circle}** Yes | **{check-circle}** Yes | Ticket IID.
| `%{ISSUE_PATH}` | **{check-circle}** Yes | **{check-circle}** Yes | Project path appended with the ticket IID.
| `%{ISSUE_URL}` | **{check-circle}** Yes | **{check-circle}** Yes | URL of the ticket. External participants can only view the ticket if the project is public and ticket is not confidential (Service Desk tickets are confidential by default).
| `%{ISSUE_DESCRIPTION}` | **{check-circle}** Yes | **{check-circle}** Yes | Ticket description. If a user has edited the description, it may contain sensitive information that is not intended to be delivered to external participants. Use this placeholder with care and ideally only if you never modify descriptions or your team is aware of the template design.
| `%{UNSUBSCRIBE_URL}` | **{check-circle}** Yes | **{check-circle}** Yes | Unsubscribe URL.
| `%{NOTE_TEXT}` | **{dotted-circle}** No | **{check-circle}** Yes | The new comment added to the ticket by a user. Take care to include this placeholder in `new_note.md`. Otherwise, the requesters may never see the updates on their Service Desk ticket.
#### Thank you email
When a requester submits an issue through Service Desk, GitLab sends a **thank you email**.
Without additional configuration, GitLab sends the default thank you email.
To create a custom thank you email template:
1. In the `.gitlab/service_desk_templates/` directory of your repository, create a file named `thank_you.md`.
1. Populate the Markdown file with text, [GitLab Flavored Markdown](../markdown.md),
[some selected HTML tags](../markdown.md#inline-html), and placeholders to customize the reply
to Service Desk requesters.
#### New note email
When a Service Desk ticket has a new public comment, GitLab sends a **new note email**.
Without additional configuration, GitLab sends the content of the comment.
To keep your emails on brand, you can create a custom new note email template. To do so:
1. In the `.gitlab/service_desk_templates/` directory in your repository, create a file named `new_note.md`.
1. Populate the Markdown file with text, [GitLab Flavored Markdown](../markdown.md),
[some selected HTML tags](../markdown.md#inline-html), and placeholders to customize the new note
email. Be sure to include the `%{NOTE_TEXT}` in the template to make sure the email recipient can
read the contents of the comment.
#### Instance-level email header, footer, and additional text **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/344819) in GitLab 15.9.
Instance administrators can add a header, footer or additional text to the GitLab instance and apply
them to all emails sent from GitLab. If you're using a custom `thank_you.md` or `new_note.md`, to include
this content, add `%{SYSTEM_HEADER}`, `%{SYSTEM_FOOTER}`, or `%{ADDITIONAL_TEXT}` to your templates.
For more information, see [System header and footer messages](../../administration/appearance.md#system-header-and-footer-messages) and [custom additional text](../../administration/settings/email.md#custom-additional-text).
### Use a custom template for Service Desk tickets
You can select one [description template](description_templates.md#create-an-issue-template)
**per project** to be appended to every new Service Desk ticket's description.
You can set description templates at various levels:
- The entire [instance](description_templates.md#set-instance-level-description-templates).
- A specific [group or subgroup](description_templates.md#set-group-level-description-templates).
- A specific [project](description_templates.md#set-a-default-template-for-merge-requests-and-issues).
The templates are inherited. For example, in a project, you can also access templates set for the instance, or the project's parent groups.
Prerequisite:
- You must have [created a description template](description_templates.md#create-an-issue-template).
To use a custom description template with Service Desk:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
1. Expand **Service Desk**.
1. From the dropdown list **Template to append to all Service Desk issues**, search or select your template.
### Support Bot user
Behind the scenes, Service Desk works by the special Support Bot user creating issues.
This user isn't a [billable user](../../subscriptions/self_managed/index.md#billable-users),
so it does not count toward the license limit count.
In GitLab 16.0 and earlier, comments generated from Service Desk emails show `GitLab Support Bot`
as the author. In [GitLab 16.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/226995),
these comments show the email of the user who sent the email.
This feature only applies to comments made in GitLab 16.1 and later.
#### Change the Support Bot's display name
You can change the display name of the Support Bot user. Emails sent from Service Desk have
this name in the `From` header. The default display name is `GitLab Support Bot`.
To edit the custom email display name:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
1. Expand **Service Desk**.
1. Below **Email display name**, enter a new name.
1. Select **Save changes**.
### Use an additional Service Desk alias email **(FREE SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2201) in GitLab 13.0.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/284656) in GitLab 13.8.
You can use an additional alias email address for Service Desk on an instance level.
To do this, you must configure
a [`service_desk_email`](#configure-service-desk-alias-email) in the instance configuration. You can also configure a
[custom suffix](#configure-a-suffix-for-service-desk-alias-email) that replaces the default `-issue-` portion on the sub-addressing part.
#### Configure Service Desk alias email
NOTE:
On GitLab.com a custom mailbox is already configured with `contact-project+%{key}@incoming.gitlab.com` as the email address. You can still configure the
[custom suffix](#configure-a-suffix-for-service-desk-alias-email) in project settings.
Service Desk uses the [incoming email](../../administration/incoming_email.md)
configuration by default. However, to have a separate email address for Service Desk,
configure `service_desk_email` with a [custom suffix](#configure-a-suffix-for-service-desk-alias-email)
in project settings.
Prerequisites:
- The `address` must include the `+%{key}` placeholder in the `user` portion of the address,
before the `@`. The placeholder is used to identify the project where the issue should be created.
- The `service_desk_email` and `incoming_email` configurations must always use separate mailboxes
to make sure Service Desk emails are processed correctly.
To configure a custom mailbox for Service Desk with IMAP, add the following snippets to your configuration file in full:
::Tabs
:::TabTitle Linux package (Omnibus)
NOTE:
In GitLab 15.3 and later, Service Desk uses `webhook` (internal API call) by default instead of enqueuing a Sidekiq job.
To use `webhook` on a Linux package installation running GitLab 15.3, you must generate a secret file.
For more information, see [merge request 5927](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5927).
In GitLab 15.4, reconfiguring a Linux package installation generates this secret file automatically, so no
secret file configuration setting is needed.
For more information, see [issue 1462](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1462).
```ruby
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@gmail.com"
gitlab_rails['service_desk_email_email'] = "project_contact@gmail.com"
gitlab_rails['service_desk_email_password'] = "[REDACTED]"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_idle_timeout'] = 60
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
gitlab_rails['service_desk_email_host'] = "imap.gmail.com"
gitlab_rails['service_desk_email_port'] = 993
gitlab_rails['service_desk_email_ssl'] = true
gitlab_rails['service_desk_email_start_tls'] = false
```
:::TabTitle Self-compiled (source)
```yaml
service_desk_email:
enabled: true
address: "project_contact+%{key}@example.com"
user: "project_contact@example.com"
password: "[REDACTED]"
host: "imap.gmail.com"
delivery_method: webhook
secret_file: .gitlab-mailroom-secret
port: 993
ssl: true
start_tls: false
log_path: "log/mailroom.log"
mailbox: "inbox"
idle_timeout: 60
expunge_deleted: true
```
::EndTabs
The configuration options are the same as for configuring
[incoming email](../../administration/incoming_email.md#set-it-up).
##### Use encrypted credentials
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108279) in GitLab 15.9.
Instead of having the Service Desk email credentials stored in plaintext in the configuration files, you can optionally
use an encrypted file for the incoming email credentials.
Prerequisites:
- To use encrypted credentials, you must first enable the
[encrypted configuration](../../administration/encrypted_configuration.md).
The supported configuration items for the encrypted file are:
- `user`
- `password`
::Tabs
:::TabTitle Linux package (Omnibus)
1. If initially your Service Desk configuration in `/etc/gitlab/gitlab.rb` looked like:
```ruby
gitlab_rails['service_desk_email_email'] = "service-desk-email@mail.example.com"
gitlab_rails['service_desk_email_password'] = "examplepassword"
```
1. Edit the encrypted secret:
```shell
sudo gitlab-rake gitlab:service_desk_email:secret:edit EDITOR=vim
```
1. Enter the unencrypted contents of the Service Desk email secret:
```yaml
user: 'service-desk-email@mail.example.com'
password: 'examplepassword'
```
1. Edit `/etc/gitlab/gitlab.rb` and remove the `service_desk` settings for `email` and `password`.
1. Save the file and reconfigure GitLab:
```shell
sudo gitlab-ctl reconfigure
```
:::TabTitle Helm chart (Kubernetes)
Use a Kubernetes secret to store the Service Desk email password. For more information,
read about [Helm IMAP secrets](https://docs.gitlab.com/charts/installation/secrets.html#imap-password-for-service-desk-emails).
:::TabTitle Docker
1. If initially your Service Desk configuration in `docker-compose.yml` looked like:
```yaml
version: "3.6"
services:
gitlab:
image: 'gitlab/gitlab-ee:latest'
restart: always
hostname: 'gitlab.example.com'
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['service_desk_email_email'] = "service-desk-email@mail.example.com"
gitlab_rails['service_desk_email_password'] = "examplepassword"
```
1. Get inside the container, and edit the encrypted secret:
```shell
sudo docker exec -t <container_name> bash
gitlab-rake gitlab:service_desk_email:secret:edit EDITOR=editor
```
1. Enter the unencrypted contents of the Service Desk secret:
```yaml
user: 'service-desk-email@mail.example.com'
password: 'examplepassword'
```
1. Edit `docker-compose.yml` and remove the `service_desk` settings for `email` and `password`.
1. Save the file and restart GitLab:
```shell
docker compose up -d
```
:::TabTitle Self-compiled (source)
1. If initially your Service Desk configuration in `/home/git/gitlab/config/gitlab.yml` looked like:
```yaml
production:
service_desk_email:
user: 'service-desk-email@mail.example.com'
password: 'examplepassword'
```
1. Edit the encrypted secret:
```shell
bundle exec rake gitlab:service_desk_email:secret:edit EDITOR=vim RAILS_ENVIRONMENT=production
```
1. Enter the unencrypted contents of the Service Desk secret:
```yaml
user: 'service-desk-email@mail.example.com'
password: 'examplepassword'
```
1. Edit `/home/git/gitlab/config/gitlab.yml` and remove the `service_desk_email:` settings for `user` and `password`.
1. Save the file and restart GitLab and Mailroom
```shell
# For systems running systemd
sudo systemctl restart gitlab.target
# For systems running SysV init
sudo service gitlab restart
```
::EndTabs
##### Microsoft Graph
> - Alternative Azure deployments [introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5978) in GitLab 14.9.
> - [Introduced for self-compiled (source) installs](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116494) in GitLab 15.11.
`service_desk_email` can be configured to read Microsoft Exchange Online mailboxes with the Microsoft
Graph API instead of IMAP. Set up an OAuth 2.0 application for Microsoft Graph
[the same way as for incoming email](../../administration/incoming_email.md#microsoft-graph).
::Tabs
:::TabTitle Linux package (Omnibus)
1. Edit `/etc/gitlab/gitlab.rb` and add the following lines, substituting
the values you want:
```ruby
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.onmicrosoft.com"
gitlab_rails['service_desk_email_email'] = "project_contact@example.onmicrosoft.com"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
gitlab_rails['service_desk_email_inbox_method'] = 'microsoft_graph'
gitlab_rails['service_desk_email_inbox_options'] = {
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
'poll_interval': 60 # Optional
}
```
For Microsoft Cloud for US Government or [other Azure deployments](https://learn.microsoft.com/en-us/graph/deployments),
configure the `azure_ad_endpoint` and `graph_endpoint` settings. For example:
```ruby
gitlab_rails['service_desk_email_inbox_options'] = {
'azure_ad_endpoint': 'https://login.microsoftonline.us',
'graph_endpoint': 'https://graph.microsoft.us',
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
'poll_interval': 60 # Optional
}
```
:::TabTitle Helm chart (Kubernetes)
1. Create the [Kubernetes Secret containing the OAuth 2.0 application client secret](https://docs.gitlab.com/charts/installation/secrets.html#microsoft-graph-client-secret-for-service-desk-emails):
```shell
kubectl create secret generic service-desk-email-client-secret --from-literal=secret=<YOUR-CLIENT_SECRET>
```
1. Create the [Kubernetes Secret for the GitLab Service Desk email auth token](https://docs.gitlab.com/charts/installation/secrets.html#gitlab-service-desk-email-auth-token).
Replace `<name>` with the name of the [Helm release name](https://helm.sh/docs/intro/using_helm/) for the GitLab installation:
```shell
kubectl create secret generic <name>-service-desk-email-auth-token --from-literal=authToken=$(head -c 512 /dev/urandom | LC_CTYPE=C tr -cd 'a-zA-Z0-9' | head -c 32 | base64)
```
1. Export the Helm values:
```shell
helm get values gitlab > gitlab_values.yaml
```
1. Edit `gitlab_values.yaml`:
```yaml
global:
appConfig:
serviceDeskEmail:
enabled: true
address: "project_contact+%{key}@example.onmicrosoft.com"
user: "project_contact@example.onmicrosoft.com"
mailbox: inbox
inboxMethod: microsoft_graph
azureAdEndpoint: https://login.microsoftonline.com
graphEndpoint: https://graph.microsoft.com
tenantId: "YOUR-TENANT-ID"
clientId: "YOUR-CLIENT-ID"
clientSecret:
secret: service-desk-email-client-secret
key: secret
deliveryMethod: webhook
authToken:
secret: <name>-service-desk-email-auth-token
key: authToken
```
For Microsoft Cloud for US Government or [other Azure deployments](https://learn.microsoft.com/en-us/graph/deployments),
configure the `azureAdEndpoint` and `graphEndpoint` settings. These fields are case-sensitive:
```yaml
global:
appConfig:
serviceDeskEmail:
[..]
azureAdEndpoint: https://login.microsoftonline.us
graphEndpoint: https://graph.microsoft.us
[..]
```
1. Save the file and apply the new values:
```shell
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
```
:::TabTitle Docker
1. Edit `docker-compose.yml`:
```yaml
version: "3.6"
services:
gitlab:
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.onmicrosoft.com"
gitlab_rails['service_desk_email_email'] = "project_contact@example.onmicrosoft.com"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
gitlab_rails['service_desk_email_inbox_method'] = 'microsoft_graph'
gitlab_rails['service_desk_email_inbox_options'] = {
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
'poll_interval': 60 # Optional
}
```
1. Save the file and restart GitLab:
```shell
docker compose up -d
```
For Microsoft Cloud for US Government or [other Azure deployments](https://learn.microsoft.com/en-us/graph/deployments),
configure the `azure_ad_endpoint` and `graph_endpoint` settings:
1. Edit `docker-compose.yml`:
```yaml
version: "3.6"
services:
gitlab:
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.onmicrosoft.com"
gitlab_rails['service_desk_email_email'] = "project_contact@example.onmicrosoft.com"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
gitlab_rails['service_desk_email_inbox_method'] = 'microsoft_graph'
gitlab_rails['service_desk_email_inbox_options'] = {
'azure_ad_endpoint': 'https://login.microsoftonline.us',
'graph_endpoint': 'https://graph.microsoft.us',
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
'poll_interval': 60 # Optional
}
```
1. Save the file and restart GitLab:
```shell
docker compose up -d
```
:::TabTitle Self-compiled (source)
1. Edit `/home/git/gitlab/config/gitlab.yml`:
```yaml
service_desk_email:
enabled: true
address: "project_contact+%{key}@example.onmicrosoft.com"
user: "project_contact@example.onmicrosoft.com"
mailbox: "inbox"
delivery_method: webhook
log_path: "log/mailroom.log"
secret_file: .gitlab-mailroom-secret
inbox_method: "microsoft_graph"
inbox_options:
tenant_id: "<YOUR-TENANT-ID>"
client_id: "<YOUR-CLIENT-ID>"
client_secret: "<YOUR-CLIENT-SECRET>"
poll_interval: 60 # Optional
```
For Microsoft Cloud for US Government or [other Azure deployments](https://learn.microsoft.com/en-us/graph/deployments),
configure the `azure_ad_endpoint` and `graph_endpoint` settings. For example:
```yaml
service_desk_email:
enabled: true
address: "project_contact+%{key}@example.onmicrosoft.com"
user: "project_contact@example.onmicrosoft.com"
mailbox: "inbox"
delivery_method: webhook
log_path: "log/mailroom.log"
secret_file: .gitlab-mailroom-secret
inbox_method: "microsoft_graph"
inbox_options:
azure_ad_endpoint: "https://login.microsoftonline.us"
graph_endpoint: "https://graph.microsoft.us"
tenant_id: "<YOUR-TENANT-ID>"
client_id: "<YOUR-CLIENT-ID>"
client_secret: "<YOUR-CLIENT-SECRET>"
poll_interval: 60 # Optional
```
::EndTabs
#### Configure a suffix for Service Desk alias email
You can set a custom suffix in your project's Service Desk settings.
A suffix can contain only lowercase letters (`a-z`), numbers (`0-9`), or underscores (`_`).
When configured, the custom suffix creates a new Service Desk email address, consisting of the
`service_desk_email_address` setting and a key of the format: `<project_full_path>-<custom_suffix>`
Prerequisites:
- You must have configured a [Service Desk alias email](#configure-service-desk-alias-email).
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
1. Expand **Service Desk**.
1. Below **Email address suffix**, enter the suffix to use.
1. Select **Save changes**.
For example, suppose the `mygroup/myproject` project Service Desk settings has the following configured:
- Email address suffix is set to `support`.
- Service Desk email address is configured to `contact+%{key}@example.com`.
The Service Desk email address for this project is: `contact+mygroup-myproject-support@example.com`.
The [incoming email](../../administration/incoming_email.md) address still works.
If you don't configure a custom suffix, the default project identification is used for identifying
the project.
### Configure email ingestion in multi-node environments
A multi-node environment is a setup where GitLab is run across multiple servers
for scalability, fault tolerance, and performance reasons.
GitLab uses a separate process called `mail_room` to ingest new unread emails
from the `incoming_email` and `service_desk_email` mailboxes.
#### Helm chart (Kubernetes)
The [GitLab Helm chart](https://docs.gitlab.com/charts/) is made up of multiple subcharts, and one of them is
the [Mailroom subchart](https://docs.gitlab.com/charts/charts/gitlab/mailroom/index.html). Configure the
[common settings for `incoming_email`](https://docs.gitlab.com/charts/installation/command-line-options.html#incoming-email-configuration)
and the [common settings for `service_desk_email`](https://docs.gitlab.com/charts/installation/command-line-options.html#service-desk-email-configuration).
#### Linux package (Omnibus)
In multi-node Linux package installation environments, run `mail_room` only on one node. Run it either on a single
`rails` node (for example, `application_role`)
or completely separately.
##### Set up all nodes
1. Add basic configuration for `incoming_email` and `service_desk_email` on every node
to render email addresses in the web UI and in generated emails.
Find the `incoming_email` or `service_desk_email` section in `/etc/gitlab/gitlab.rb`:
::Tabs
:::TabTitle `incoming_email`
```ruby
gitlab_rails['incoming_email_enabled'] = true
gitlab_rails['incoming_email_address'] = "incoming+%{key}@example.com"
```
:::TabTitle `service_desk_email`
```ruby
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.com"
```
::EndTabs
1. GitLab offers two methods to transport emails from `mail_room` to the GitLab
application. You can configure the `delivery_method` for each email setting individually:
1. Recommended: `webhook` (default in GitLab 15.3 and later) sends the email payload via an API POST request to your GitLab
application. It uses a shared token to authenticate. If you choose this method,
make sure the `mail_room` process can access the API endpoint and distribute the shared
token across all application nodes.
::Tabs
:::TabTitle `incoming_email`
```ruby
gitlab_rails['incoming_email_delivery_method'] = "webhook"
# The URL that mail_room can contact. You can also use an internal URL or IP,
# just make sure mail_room can access the GitLab API via that address.
# Do not end with "/".
gitlab_rails['incoming_email_gitlab_url'] = "https://gitlab.example.com"
# The shared secret file that should contain a random token. Make sure it's the same on every node.
gitlab_rails['incoming_email_secret_file'] = ".gitlab_mailroom_secret"
```
:::TabTitle `service_desk_email`
```ruby
gitlab_rails['service_desk_email_delivery_method'] = "webhook"
# The URL that mail_room can contact. You can also use an internal URL or IP,
# just make sure mail_room can access the GitLab API via that address.
# Do not end with "/".
gitlab_rails['service_desk_email_gitlab_url'] = "https://gitlab.example.com"
# The shared secret file that should contain a random token. Make sure it's the same on every node.
gitlab_rails['service_desk_email_secret_file'] = ".gitlab_mailroom_secret"
```
::EndTabs
1. [Deprecated in GitLab 16.0 and planned for removal in 17.0)](../../update/deprecations.md#sidekiq-delivery-method-for-incoming_email-and-service_desk_email-is-deprecated):
If you experience issues with the `webhook` setup, use `sidekiq` to deliver the email payload directly to GitLab Sidekiq using Redis.
::Tabs
:::TabTitle `incoming_email`
```ruby
# It uses the Redis configuration to directly add Sidekiq jobs
gitlab_rails['incoming_email_delivery_method'] = "sidekiq"
```
:::TabTitle `service_desk_email`
```ruby
# It uses the Redis configuration to directly add Sidekiq jobs
gitlab_rails['service_desk_email_delivery_method'] = "sidekiq"
```
::EndTabs
1. Disable `mail_room` on all nodes that should not run email ingestion. For example, in `/etc/gitlab/gitlab.rb`:
```ruby
mailroom['enabled'] = false
```
1. [Reconfigure GitLab](../../administration/restart_gitlab.md) for the changes to take effect.
##### Set up a single email ingestion node
After setting up all nodes and disabling the `mail_room` process, enable `mail_room` on a single node.
This node polls the mailboxes for `incoming_email` and `service_desk_email` on a regular basis and
move new unread emails to GitLab.
1. Choose an existing node that additionally handles email ingestion.
1. Add [full configuration and credentials](../../administration/incoming_email.md#configuration-examples)
for `incoming_email` and `service_desk_email`.
1. Enable `mail_room` on this node. For example, in `/etc/gitlab/gitlab.rb`:
```ruby
mailroom['enabled'] = true
```
1. [Reconfigure GitLab](../../administration/restart_gitlab.md) on this node for the changes to take effect.
## Use Service Desk
You can use Service Desk to [create an issue](#as-an-end-user-issue-creator) or [respond to one](#as-a-responder-to-the-issue).
In these issues, you can also see our friendly neighborhood [Support Bot](#support-bot-user).
### View Service Desk email address
To check what the Service Desk email address is for your project:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Monitor > Service Desk**.
The email address is available at the top of the issue list.
### As an end user (issue creator)
> Support for additional email headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346600) in GitLab 14.6. In earlier versions, the Service Desk email address had to be in the "To" field.
To create a Service Desk issue, an end user does not need to know anything about
the GitLab instance. They just send an email to the address they are given, and
receive an email back confirming receipt:
![Service Desk enabled](img/service_desk_confirmation_email.png)
This also gives the end user an option to unsubscribe.
If they don't choose to unsubscribe, then any new comments added to the issue
are sent as emails:
![Service Desk reply email](img/service_desk_reply.png)
Any responses they send via email are displayed in the issue itself.
For information about headers used for treating email, see
[the incoming email documentation](../../administration/incoming_email.md#accepted-headers).
### As a responder to the issue
For responders to the issue, everything works just like other GitLab issues.
GitLab displays a familiar-looking issue tracker where responders can see
issues created through customer support requests, and filter or interact with them.
![Service Desk Issue tracker](img/service_desk_issue_tracker.png)
Messages from the end user are shown as coming from the special
[Support Bot user](../../subscriptions/self_managed/index.md#billable-users).
You can read and write comments as you usually do in GitLab:
![Service Desk issue thread](img/service_desk_thread.png)
- The project's visibility (private, internal, public) does not affect Service Desk.
- The path to the project, including its group or namespace, is shown in emails.
#### View Service Desk issues
Prerequisites:
- You must have at least the Reporter role for the project.
To view Service Desk issues:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Monitor > Service Desk**.
### Email contents and formatting
#### Special HTML formatting in HTML emails
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109811) in GitLab 15.9 [with a flag](../../administration/feature_flags.md) named `service_desk_html_to_text_email_handler`. Disabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116809) in GitLab 15.11. Feature flag `service_desk_html_to_text_email_handler` removed.
HTML emails show HTML formatting, such as:
- Tables
- Blockquotes
- Images
- Collapsible sections
#### Files attached to comments
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11733) in GitLab 15.8 [with a flag](../../administration/feature_flags.md) named `service_desk_new_note_email_native_attachments`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/386860) in GitLab 15.10.
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature per project or for your entire instance, an administrator can [disable the feature flag](../../administration/feature_flags.md) named `service_desk_new_note_email_native_attachments`.
On GitLab.com, this feature is available.
If a comment contains any attachments and their total size is less than or equal to 10 MB, these
attachments are sent as part of the email. In other cases, the email contains links to the attachments.
In GitLab 15.9 and earlier, uploads to a comment are sent as links in the email.
## Privacy considerations
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108901) the minimum required role to view the creator's and participant's email in GitLab 15.9.
Service Desk issues are [confidential](issues/confidential_issues.md), so they are
only visible to project members. The project owner can
[make an issue public](issues/confidential_issues.md#in-an-existing-issue).
When a Service Desk issue becomes public, the issue creator's and participants' email addresses are
visible to signed-in users with at least the Reporter role for the project.
In GitLab 15.8 and earlier, when a Service Desk issue becomes public, the issue creator's email
address is disclosed to everyone who can view the project.
Anyone in your project can use the Service Desk email address to create an issue in this project, **regardless
of their role** in the project.
The unique internal email address is visible to project members at least
the Reporter role in your GitLab instance.
An external user (issue creator) cannot see the internal email address
displayed in the information note.
### Moving a Service Desk issue
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/372246) in GitLab 15.7: customers continue receiving notifications when a Service Desk issue is moved.
You can move a Service Desk issue the same way you
[move a regular issue](issues/managing_issues.md#move-an-issue) in GitLab.
If a Service Desk issue is moved to a different project with Service Desk enabled,
the customer who created the issue continues to receive email notifications.
Because a moved issue is first closed, then copied, the customer is considered to be a participant
in both issues. They continue to receive any notifications in the old issue and the new one.
## Troubleshooting Service Desk
### Emails to Service Desk do not create issues
Your emails might be ignored because they contain one of the
[email headers that GitLab ignores](../../administration/incoming_email.md#rejected-headers).
<!-- This redirect file can be deleted after <2023-10-24>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -0,0 +1,912 @@
---
stage: Monitor
group: Respond
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Service Desk **(FREE)**
With Service Desk, your customers
can email you bug reports, feature requests, or general feedback.
Service Desk provides a unique email address, so they don't need their own GitLab accounts.
Service Desk emails are created in your GitLab project as new issues.
Your team can respond directly from the project, while customers interact with the thread only
through email.
## Service Desk workflow
For example, let's assume you develop a game for iOS or Android.
The codebase is hosted in your GitLab instance, built and deployed
with GitLab CI/CD.
Here's how Service Desk works for you:
1. You provide a project-specific email address to your paying customers, who can email you directly
from the application.
1. Each email they send creates an issue in the appropriate project.
1. Your team members go to the Service Desk issue tracker, where they can see new support
requests and respond inside associated issues.
1. Your team communicates with the customer to understand the request.
1. Your team starts working on implementing code to solve your customer's problem.
1. When your team finishes the implementation, the merge request is merged and the issue
is closed automatically.
Meanwhile:
- The customer interacts with your team entirely through email, without needing access to your
GitLab instance.
- Your team saves time by not having to leave GitLab (or set up integrations) to follow up with
your customer.
## Configure Service Desk
By default, Service Desk is active in new projects.
If it's not active, you can do it in the project's settings.
Prerequisites:
- You must have at least the Maintainer role for the project.
- On GitLab self-managed, you must [set up incoming email](../../../administration/incoming_email.md#set-it-up)
for the GitLab instance. You should use
[email sub-addressing](../../../administration/incoming_email.md#email-sub-addressing),
but you can also use [catch-all mailboxes](../../../administration/incoming_email.md#catch-all-mailbox).
To do this, you must have administrator access.
- You must have enabled [issue](../settings/index.md#configure-project-visibility-features-and-permissions)
tracker for the project.
To enable Service Desk in your project:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
1. Expand **Service Desk**.
1. Turn on the **Activate Service Desk** toggle.
1. Optional. Complete the fields.
- [Add a suffix](#configure-a-suffix-for-service-desk-alias-email) to your Service Desk email address.
- If the list below **Template to append to all Service Desk issues** is empty, create a
[description template](../description_templates.md) in your repository.
1. Select **Save changes**.
Service Desk is now enabled for this project.
If anyone sends an email to the address available below **Email address to use for Service Desk**,
GitLab creates a confidential issue with the email's content.
### Improve your project's security
To improve your Service Desk project's security, you should:
- Put the Service Desk email address behind an alias on your email system so you can change it later.
- [Enable Akismet](../../../integration/akismet.md) on your GitLab instance to add spam checking to this service.
Unblocked email spam can result in many spam issues being created.
### Customize emails sent to the requester
> - Moved from GitLab Premium to GitLab Free in 13.2.
> - `UNSUBSCRIBE_URL`, `SYSTEM_HEADER`, `SYSTEM_FOOTER`, and `ADDITIONAL_TEXT` placeholders [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285512) in GitLab 15.9.
> - `%{ISSUE_DESCRIPTION}` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/223751) in GitLab 16.0.
> - `%{ISSUE_URL}` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/408793) in GitLab 16.1.
An email is sent to the requester when:
- A requester submits a new ticket by emailing Service Desk.
- A new public comment is added on a Service Desk ticket.
- Editing a comment does not trigger a new email to be sent.
You can customize the body of these email messages with Service Desk email templates. The templates
can include [GitLab Flavored Markdown](../../markdown.md) and [some HTML tags](../../markdown.md#inline-html).
For example, you can format the emails to include a header and footer in accordance with your
organization's brand guidelines. You can also include the following placeholders to display dynamic
content specific to the Service Desk ticket or your GitLab instance.
| Placeholder | `thank_you.md` | `new_note.md` | Description
| ---------------------- | ---------------------- | ---------------------- | -----------
| `%{ISSUE_ID}` | **{check-circle}** Yes | **{check-circle}** Yes | Ticket IID.
| `%{ISSUE_PATH}` | **{check-circle}** Yes | **{check-circle}** Yes | Project path appended with the ticket IID.
| `%{ISSUE_URL}` | **{check-circle}** Yes | **{check-circle}** Yes | URL of the ticket. External participants can only view the ticket if the project is public and ticket is not confidential (Service Desk tickets are confidential by default).
| `%{ISSUE_DESCRIPTION}` | **{check-circle}** Yes | **{check-circle}** Yes | Ticket description. If a user has edited the description, it may contain sensitive information that is not intended to be delivered to external participants. Use this placeholder with care and ideally only if you never modify descriptions or your team is aware of the template design.
| `%{UNSUBSCRIBE_URL}` | **{check-circle}** Yes | **{check-circle}** Yes | Unsubscribe URL.
| `%{NOTE_TEXT}` | **{dotted-circle}** No | **{check-circle}** Yes | The new comment added to the ticket by a user. Take care to include this placeholder in `new_note.md`. Otherwise, the requesters may never see the updates on their Service Desk ticket.
#### Thank you email
When a requester submits an issue through Service Desk, GitLab sends a **thank you email**.
Without additional configuration, GitLab sends the default thank you email.
To create a custom thank you email template:
1. In the `.gitlab/service_desk_templates/` directory of your repository, create a file named `thank_you.md`.
1. Populate the Markdown file with text, [GitLab Flavored Markdown](../../markdown.md),
[some selected HTML tags](../../markdown.md#inline-html), and placeholders to customize the reply
to Service Desk requesters.
#### New note email
When a Service Desk ticket has a new public comment, GitLab sends a **new note email**.
Without additional configuration, GitLab sends the content of the comment.
To keep your emails on brand, you can create a custom new note email template. To do so:
1. In the `.gitlab/service_desk_templates/` directory in your repository, create a file named `new_note.md`.
1. Populate the Markdown file with text, [GitLab Flavored Markdown](../../markdown.md),
[some selected HTML tags](../../markdown.md#inline-html), and placeholders to customize the new note
email. Be sure to include the `%{NOTE_TEXT}` in the template to make sure the email recipient can
read the contents of the comment.
#### Instance-level email header, footer, and additional text **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/344819) in GitLab 15.9.
Instance administrators can add a header, footer or additional text to the GitLab instance and apply
them to all emails sent from GitLab. If you're using a custom `thank_you.md` or `new_note.md`, to include
this content, add `%{SYSTEM_HEADER}`, `%{SYSTEM_FOOTER}`, or `%{ADDITIONAL_TEXT}` to your templates.
For more information, see [System header and footer messages](../../../administration/appearance.md#system-header-and-footer-messages) and [custom additional text](../../../administration/settings/email.md#custom-additional-text).
### Use a custom template for Service Desk tickets
You can select one [description template](../description_templates.md#create-an-issue-template)
**per project** to be appended to every new Service Desk ticket's description.
You can set description templates at various levels:
- The entire [instance](../description_templates.md#set-instance-level-description-templates).
- A specific [group or subgroup](../description_templates.md#set-group-level-description-templates).
- A specific [project](../description_templates.md#set-a-default-template-for-merge-requests-and-issues).
The templates are inherited. For example, in a project, you can also access templates set for the instance, or the project's parent groups.
Prerequisite:
- You must have [created a description template](../description_templates.md#create-an-issue-template).
To use a custom description template with Service Desk:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
1. Expand **Service Desk**.
1. From the dropdown list **Template to append to all Service Desk issues**, search or select your template.
### Support Bot user
Behind the scenes, Service Desk works by the special Support Bot user creating issues.
This user isn't a [billable user](../../../subscriptions/self_managed/index.md#billable-users),
so it does not count toward the license limit count.
In GitLab 16.0 and earlier, comments generated from Service Desk emails show `GitLab Support Bot`
as the author. In [GitLab 16.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/226995),
these comments show the email of the user who sent the email.
This feature only applies to comments made in GitLab 16.1 and later.
#### Change the Support Bot's display name
You can change the display name of the Support Bot user. Emails sent from Service Desk have
this name in the `From` header. The default display name is `GitLab Support Bot`.
To edit the custom email display name:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
1. Expand **Service Desk**.
1. Below **Email display name**, enter a new name.
1. Select **Save changes**.
### Use an additional Service Desk alias email **(FREE SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2201) in GitLab 13.0.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/284656) in GitLab 13.8.
You can use an additional alias email address for Service Desk on an instance level.
To do this, you must configure
a [`service_desk_email`](#configure-service-desk-alias-email) in the instance configuration. You can also configure a
[custom suffix](#configure-a-suffix-for-service-desk-alias-email) that replaces the default `-issue-` portion on the sub-addressing part.
#### Configure Service Desk alias email
NOTE:
On GitLab.com a custom mailbox is already configured with `contact-project+%{key}@incoming.gitlab.com` as the email address. You can still configure the
[custom suffix](#configure-a-suffix-for-service-desk-alias-email) in project settings.
Service Desk uses the [incoming email](../../../administration/incoming_email.md)
configuration by default. However, to have a separate email address for Service Desk,
configure `service_desk_email` with a [custom suffix](#configure-a-suffix-for-service-desk-alias-email)
in project settings.
Prerequisites:
- The `address` must include the `+%{key}` placeholder in the `user` portion of the address,
before the `@`. The placeholder is used to identify the project where the issue should be created.
- The `service_desk_email` and `incoming_email` configurations must always use separate mailboxes
to make sure Service Desk emails are processed correctly.
To configure a custom mailbox for Service Desk with IMAP, add the following snippets to your configuration file in full:
::Tabs
:::TabTitle Linux package (Omnibus)
NOTE:
In GitLab 15.3 and later, Service Desk uses `webhook` (internal API call) by default instead of enqueuing a Sidekiq job.
To use `webhook` on a Linux package installation running GitLab 15.3, you must generate a secret file.
For more information, see [merge request 5927](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5927).
In GitLab 15.4, reconfiguring a Linux package installation generates this secret file automatically, so no
secret file configuration setting is needed.
For more information, see [issue 1462](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1462).
```ruby
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@gmail.com"
gitlab_rails['service_desk_email_email'] = "project_contact@gmail.com"
gitlab_rails['service_desk_email_password'] = "[REDACTED]"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_idle_timeout'] = 60
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
gitlab_rails['service_desk_email_host'] = "imap.gmail.com"
gitlab_rails['service_desk_email_port'] = 993
gitlab_rails['service_desk_email_ssl'] = true
gitlab_rails['service_desk_email_start_tls'] = false
```
:::TabTitle Self-compiled (source)
```yaml
service_desk_email:
enabled: true
address: "project_contact+%{key}@example.com"
user: "project_contact@example.com"
password: "[REDACTED]"
host: "imap.gmail.com"
delivery_method: webhook
secret_file: .gitlab-mailroom-secret
port: 993
ssl: true
start_tls: false
log_path: "log/mailroom.log"
mailbox: "inbox"
idle_timeout: 60
expunge_deleted: true
```
::EndTabs
The configuration options are the same as for configuring
[incoming email](../../../administration/incoming_email.md#set-it-up).
##### Use encrypted credentials
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108279) in GitLab 15.9.
Instead of having the Service Desk email credentials stored in plaintext in the configuration files, you can optionally
use an encrypted file for the incoming email credentials.
Prerequisites:
- To use encrypted credentials, you must first enable the
[encrypted configuration](../../../administration/encrypted_configuration.md).
The supported configuration items for the encrypted file are:
- `user`
- `password`
::Tabs
:::TabTitle Linux package (Omnibus)
1. If initially your Service Desk configuration in `/etc/gitlab/gitlab.rb` looked like:
```ruby
gitlab_rails['service_desk_email_email'] = "service-desk-email@mail.example.com"
gitlab_rails['service_desk_email_password'] = "examplepassword"
```
1. Edit the encrypted secret:
```shell
sudo gitlab-rake gitlab:service_desk_email:secret:edit EDITOR=vim
```
1. Enter the unencrypted contents of the Service Desk email secret:
```yaml
user: 'service-desk-email@mail.example.com'
password: 'examplepassword'
```
1. Edit `/etc/gitlab/gitlab.rb` and remove the `service_desk` settings for `email` and `password`.
1. Save the file and reconfigure GitLab:
```shell
sudo gitlab-ctl reconfigure
```
:::TabTitle Helm chart (Kubernetes)
Use a Kubernetes secret to store the Service Desk email password. For more information,
read about [Helm IMAP secrets](https://docs.gitlab.com/charts/installation/secrets.html#imap-password-for-service-desk-emails).
:::TabTitle Docker
1. If initially your Service Desk configuration in `docker-compose.yml` looked like:
```yaml
version: "3.6"
services:
gitlab:
image: 'gitlab/gitlab-ee:latest'
restart: always
hostname: 'gitlab.example.com'
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['service_desk_email_email'] = "service-desk-email@mail.example.com"
gitlab_rails['service_desk_email_password'] = "examplepassword"
```
1. Get inside the container, and edit the encrypted secret:
```shell
sudo docker exec -t <container_name> bash
gitlab-rake gitlab:service_desk_email:secret:edit EDITOR=editor
```
1. Enter the unencrypted contents of the Service Desk secret:
```yaml
user: 'service-desk-email@mail.example.com'
password: 'examplepassword'
```
1. Edit `docker-compose.yml` and remove the `service_desk` settings for `email` and `password`.
1. Save the file and restart GitLab:
```shell
docker compose up -d
```
:::TabTitle Self-compiled (source)
1. If initially your Service Desk configuration in `/home/git/gitlab/config/gitlab.yml` looked like:
```yaml
production:
service_desk_email:
user: 'service-desk-email@mail.example.com'
password: 'examplepassword'
```
1. Edit the encrypted secret:
```shell
bundle exec rake gitlab:service_desk_email:secret:edit EDITOR=vim RAILS_ENVIRONMENT=production
```
1. Enter the unencrypted contents of the Service Desk secret:
```yaml
user: 'service-desk-email@mail.example.com'
password: 'examplepassword'
```
1. Edit `/home/git/gitlab/config/gitlab.yml` and remove the `service_desk_email:` settings for `user` and `password`.
1. Save the file and restart GitLab and Mailroom
```shell
# For systems running systemd
sudo systemctl restart gitlab.target
# For systems running SysV init
sudo service gitlab restart
```
::EndTabs
##### Microsoft Graph
> - Alternative Azure deployments [introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5978) in GitLab 14.9.
> - [Introduced for self-compiled (source) installs](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116494) in GitLab 15.11.
`service_desk_email` can be configured to read Microsoft Exchange Online mailboxes with the Microsoft
Graph API instead of IMAP. Set up an OAuth 2.0 application for Microsoft Graph
[the same way as for incoming email](../../../administration/incoming_email.md#microsoft-graph).
::Tabs
:::TabTitle Linux package (Omnibus)
1. Edit `/etc/gitlab/gitlab.rb` and add the following lines, substituting
the values you want:
```ruby
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.onmicrosoft.com"
gitlab_rails['service_desk_email_email'] = "project_contact@example.onmicrosoft.com"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
gitlab_rails['service_desk_email_inbox_method'] = 'microsoft_graph'
gitlab_rails['service_desk_email_inbox_options'] = {
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
'poll_interval': 60 # Optional
}
```
For Microsoft Cloud for US Government or [other Azure deployments](https://learn.microsoft.com/en-us/graph/deployments),
configure the `azure_ad_endpoint` and `graph_endpoint` settings. For example:
```ruby
gitlab_rails['service_desk_email_inbox_options'] = {
'azure_ad_endpoint': 'https://login.microsoftonline.us',
'graph_endpoint': 'https://graph.microsoft.us',
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
'poll_interval': 60 # Optional
}
```
:::TabTitle Helm chart (Kubernetes)
1. Create the [Kubernetes Secret containing the OAuth 2.0 application client secret](https://docs.gitlab.com/charts/installation/secrets.html#microsoft-graph-client-secret-for-service-desk-emails):
```shell
kubectl create secret generic service-desk-email-client-secret --from-literal=secret=<YOUR-CLIENT_SECRET>
```
1. Create the [Kubernetes Secret for the GitLab Service Desk email auth token](https://docs.gitlab.com/charts/installation/secrets.html#gitlab-service-desk-email-auth-token).
Replace `<name>` with the name of the [Helm release name](https://helm.sh/docs/intro/using_helm/) for the GitLab installation:
```shell
kubectl create secret generic <name>-service-desk-email-auth-token --from-literal=authToken=$(head -c 512 /dev/urandom | LC_CTYPE=C tr -cd 'a-zA-Z0-9' | head -c 32 | base64)
```
1. Export the Helm values:
```shell
helm get values gitlab > gitlab_values.yaml
```
1. Edit `gitlab_values.yaml`:
```yaml
global:
appConfig:
serviceDeskEmail:
enabled: true
address: "project_contact+%{key}@example.onmicrosoft.com"
user: "project_contact@example.onmicrosoft.com"
mailbox: inbox
inboxMethod: microsoft_graph
azureAdEndpoint: https://login.microsoftonline.com
graphEndpoint: https://graph.microsoft.com
tenantId: "YOUR-TENANT-ID"
clientId: "YOUR-CLIENT-ID"
clientSecret:
secret: service-desk-email-client-secret
key: secret
deliveryMethod: webhook
authToken:
secret: <name>-service-desk-email-auth-token
key: authToken
```
For Microsoft Cloud for US Government or [other Azure deployments](https://learn.microsoft.com/en-us/graph/deployments),
configure the `azureAdEndpoint` and `graphEndpoint` settings. These fields are case-sensitive:
```yaml
global:
appConfig:
serviceDeskEmail:
[..]
azureAdEndpoint: https://login.microsoftonline.us
graphEndpoint: https://graph.microsoft.us
[..]
```
1. Save the file and apply the new values:
```shell
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
```
:::TabTitle Docker
1. Edit `docker-compose.yml`:
```yaml
version: "3.6"
services:
gitlab:
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.onmicrosoft.com"
gitlab_rails['service_desk_email_email'] = "project_contact@example.onmicrosoft.com"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
gitlab_rails['service_desk_email_inbox_method'] = 'microsoft_graph'
gitlab_rails['service_desk_email_inbox_options'] = {
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
'poll_interval': 60 # Optional
}
```
1. Save the file and restart GitLab:
```shell
docker compose up -d
```
For Microsoft Cloud for US Government or [other Azure deployments](https://learn.microsoft.com/en-us/graph/deployments),
configure the `azure_ad_endpoint` and `graph_endpoint` settings:
1. Edit `docker-compose.yml`:
```yaml
version: "3.6"
services:
gitlab:
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.onmicrosoft.com"
gitlab_rails['service_desk_email_email'] = "project_contact@example.onmicrosoft.com"
gitlab_rails['service_desk_email_mailbox_name'] = "inbox"
gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
gitlab_rails['service_desk_email_inbox_method'] = 'microsoft_graph'
gitlab_rails['service_desk_email_inbox_options'] = {
'azure_ad_endpoint': 'https://login.microsoftonline.us',
'graph_endpoint': 'https://graph.microsoft.us',
'tenant_id': '<YOUR-TENANT-ID>',
'client_id': '<YOUR-CLIENT-ID>',
'client_secret': '<YOUR-CLIENT-SECRET>',
'poll_interval': 60 # Optional
}
```
1. Save the file and restart GitLab:
```shell
docker compose up -d
```
:::TabTitle Self-compiled (source)
1. Edit `/home/git/gitlab/config/gitlab.yml`:
```yaml
service_desk_email:
enabled: true
address: "project_contact+%{key}@example.onmicrosoft.com"
user: "project_contact@example.onmicrosoft.com"
mailbox: "inbox"
delivery_method: webhook
log_path: "log/mailroom.log"
secret_file: .gitlab-mailroom-secret
inbox_method: "microsoft_graph"
inbox_options:
tenant_id: "<YOUR-TENANT-ID>"
client_id: "<YOUR-CLIENT-ID>"
client_secret: "<YOUR-CLIENT-SECRET>"
poll_interval: 60 # Optional
```
For Microsoft Cloud for US Government or [other Azure deployments](https://learn.microsoft.com/en-us/graph/deployments),
configure the `azure_ad_endpoint` and `graph_endpoint` settings. For example:
```yaml
service_desk_email:
enabled: true
address: "project_contact+%{key}@example.onmicrosoft.com"
user: "project_contact@example.onmicrosoft.com"
mailbox: "inbox"
delivery_method: webhook
log_path: "log/mailroom.log"
secret_file: .gitlab-mailroom-secret
inbox_method: "microsoft_graph"
inbox_options:
azure_ad_endpoint: "https://login.microsoftonline.us"
graph_endpoint: "https://graph.microsoft.us"
tenant_id: "<YOUR-TENANT-ID>"
client_id: "<YOUR-CLIENT-ID>"
client_secret: "<YOUR-CLIENT-SECRET>"
poll_interval: 60 # Optional
```
::EndTabs
#### Configure a suffix for Service Desk alias email
You can set a custom suffix in your project's Service Desk settings.
A suffix can contain only lowercase letters (`a-z`), numbers (`0-9`), or underscores (`_`).
When configured, the custom suffix creates a new Service Desk email address, consisting of the
`service_desk_email_address` setting and a key of the format: `<project_full_path>-<custom_suffix>`
Prerequisites:
- You must have configured a [Service Desk alias email](#configure-service-desk-alias-email).
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
1. Expand **Service Desk**.
1. Below **Email address suffix**, enter the suffix to use.
1. Select **Save changes**.
For example, suppose the `mygroup/myproject` project Service Desk settings has the following configured:
- Email address suffix is set to `support`.
- Service Desk email address is configured to `contact+%{key}@example.com`.
The Service Desk email address for this project is: `contact+mygroup-myproject-support@example.com`.
The [incoming email](../../../administration/incoming_email.md) address still works.
If you don't configure a custom suffix, the default project identification is used for identifying
the project.
### Configure email ingestion in multi-node environments
A multi-node environment is a setup where GitLab is run across multiple servers
for scalability, fault tolerance, and performance reasons.
GitLab uses a separate process called `mail_room` to ingest new unread emails
from the `incoming_email` and `service_desk_email` mailboxes.
#### Helm chart (Kubernetes)
The [GitLab Helm chart](https://docs.gitlab.com/charts/) is made up of multiple subcharts, and one of them is
the [Mailroom subchart](https://docs.gitlab.com/charts/charts/gitlab/mailroom/index.html). Configure the
[common settings for `incoming_email`](https://docs.gitlab.com/charts/installation/command-line-options.html#incoming-email-configuration)
and the [common settings for `service_desk_email`](https://docs.gitlab.com/charts/installation/command-line-options.html#service-desk-email-configuration).
#### Linux package (Omnibus)
In multi-node Linux package installation environments, run `mail_room` only on one node. Run it either on a single
`rails` node (for example, `application_role`)
or completely separately.
##### Set up all nodes
1. Add basic configuration for `incoming_email` and `service_desk_email` on every node
to render email addresses in the web UI and in generated emails.
Find the `incoming_email` or `service_desk_email` section in `/etc/gitlab/gitlab.rb`:
::Tabs
:::TabTitle `incoming_email`
```ruby
gitlab_rails['incoming_email_enabled'] = true
gitlab_rails['incoming_email_address'] = "incoming+%{key}@example.com"
```
:::TabTitle `service_desk_email`
```ruby
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.com"
```
::EndTabs
1. GitLab offers two methods to transport emails from `mail_room` to the GitLab
application. You can configure the `delivery_method` for each email setting individually:
1. Recommended: `webhook` (default in GitLab 15.3 and later) sends the email payload via an API POST request to your GitLab
application. It uses a shared token to authenticate. If you choose this method,
make sure the `mail_room` process can access the API endpoint and distribute the shared
token across all application nodes.
::Tabs
:::TabTitle `incoming_email`
```ruby
gitlab_rails['incoming_email_delivery_method'] = "webhook"
# The URL that mail_room can contact. You can also use an internal URL or IP,
# just make sure mail_room can access the GitLab API via that address.
# Do not end with "/".
gitlab_rails['incoming_email_gitlab_url'] = "https://gitlab.example.com"
# The shared secret file that should contain a random token. Make sure it's the same on every node.
gitlab_rails['incoming_email_secret_file'] = ".gitlab_mailroom_secret"
```
:::TabTitle `service_desk_email`
```ruby
gitlab_rails['service_desk_email_delivery_method'] = "webhook"
# The URL that mail_room can contact. You can also use an internal URL or IP,
# just make sure mail_room can access the GitLab API via that address.
# Do not end with "/".
gitlab_rails['service_desk_email_gitlab_url'] = "https://gitlab.example.com"
# The shared secret file that should contain a random token. Make sure it's the same on every node.
gitlab_rails['service_desk_email_secret_file'] = ".gitlab_mailroom_secret"
```
::EndTabs
1. [Deprecated in GitLab 16.0 and planned for removal in 17.0)](../../../update/deprecations.md#sidekiq-delivery-method-for-incoming_email-and-service_desk_email-is-deprecated):
If you experience issues with the `webhook` setup, use `sidekiq` to deliver the email payload directly to GitLab Sidekiq using Redis.
::Tabs
:::TabTitle `incoming_email`
```ruby
# It uses the Redis configuration to directly add Sidekiq jobs
gitlab_rails['incoming_email_delivery_method'] = "sidekiq"
```
:::TabTitle `service_desk_email`
```ruby
# It uses the Redis configuration to directly add Sidekiq jobs
gitlab_rails['service_desk_email_delivery_method'] = "sidekiq"
```
::EndTabs
1. Disable `mail_room` on all nodes that should not run email ingestion. For example, in `/etc/gitlab/gitlab.rb`:
```ruby
mailroom['enabled'] = false
```
1. [Reconfigure GitLab](../../../administration/restart_gitlab.md) for the changes to take effect.
##### Set up a single email ingestion node
After setting up all nodes and disabling the `mail_room` process, enable `mail_room` on a single node.
This node polls the mailboxes for `incoming_email` and `service_desk_email` on a regular basis and
move new unread emails to GitLab.
1. Choose an existing node that additionally handles email ingestion.
1. Add [full configuration and credentials](../../../administration/incoming_email.md#configuration-examples)
for `incoming_email` and `service_desk_email`.
1. Enable `mail_room` on this node. For example, in `/etc/gitlab/gitlab.rb`:
```ruby
mailroom['enabled'] = true
```
1. [Reconfigure GitLab](../../../administration/restart_gitlab.md) on this node for the changes to take effect.
## Use Service Desk
You can use Service Desk to [create an issue](#as-an-end-user-issue-creator) or [respond to one](#as-a-responder-to-the-issue).
In these issues, you can also see our friendly neighborhood [Support Bot](#support-bot-user).
### View Service Desk email address
To check what the Service Desk email address is for your project:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Monitor > Service Desk**.
The email address is available at the top of the issue list.
### As an end user (issue creator)
> Support for additional email headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346600) in GitLab 14.6. In earlier versions, the Service Desk email address had to be in the "To" field.
To create a Service Desk issue, an end user does not need to know anything about
the GitLab instance. They just send an email to the address they are given, and
receive an email back confirming receipt:
![Service Desk enabled](img/service_desk_confirmation_email.png)
This also gives the end user an option to unsubscribe.
If they don't choose to unsubscribe, then any new comments added to the issue
are sent as emails:
![Service Desk reply email](img/service_desk_reply.png)
Any responses they send via email are displayed in the issue itself.
For information about headers used for treating email, see
[the incoming email documentation](../../../administration/incoming_email.md#accepted-headers).
### As a responder to the issue
For responders to the issue, everything works just like other GitLab issues.
GitLab displays a familiar-looking issue tracker where responders can see
issues created through customer support requests, and filter or interact with them.
![Service Desk Issue tracker](img/service_desk_issue_tracker.png)
Messages from the end user are shown as coming from the special
[Support Bot user](../../../subscriptions/self_managed/index.md#billable-users).
You can read and write comments as you usually do in GitLab:
![Service Desk issue thread](img/service_desk_thread.png)
- The project's visibility (private, internal, public) does not affect Service Desk.
- The path to the project, including its group or namespace, is shown in emails.
#### View Service Desk issues
Prerequisites:
- You must have at least the Reporter role for the project.
To view Service Desk issues:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Monitor > Service Desk**.
### Email contents and formatting
#### Special HTML formatting in HTML emails
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109811) in GitLab 15.9 [with a flag](../../../administration/feature_flags.md) named `service_desk_html_to_text_email_handler`. Disabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116809) in GitLab 15.11. Feature flag `service_desk_html_to_text_email_handler` removed.
HTML emails show HTML formatting, such as:
- Tables
- Blockquotes
- Images
- Collapsible sections
#### Files attached to comments
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11733) in GitLab 15.8 [with a flag](../../../administration/feature_flags.md) named `service_desk_new_note_email_native_attachments`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/386860) in GitLab 15.10.
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature per project or for your entire instance, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named `service_desk_new_note_email_native_attachments`.
On GitLab.com, this feature is available.
If a comment contains any attachments and their total size is less than or equal to 10 MB, these
attachments are sent as part of the email. In other cases, the email contains links to the attachments.
In GitLab 15.9 and earlier, uploads to a comment are sent as links in the email.
## Privacy considerations
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108901) the minimum required role to view the creator's and participant's email in GitLab 15.9.
Service Desk issues are [confidential](../issues/confidential_issues.md), so they are
only visible to project members. The project owner can
[make an issue public](../issues/confidential_issues.md#in-an-existing-issue).
When a Service Desk issue becomes public, the issue creator's and participants' email addresses are
visible to signed-in users with at least the Reporter role for the project.
In GitLab 15.8 and earlier, when a Service Desk issue becomes public, the issue creator's email
address is disclosed to everyone who can view the project.
Anyone in your project can use the Service Desk email address to create an issue in this project, **regardless
of their role** in the project.
The unique internal email address is visible to project members at least
the Reporter role in your GitLab instance.
An external user (issue creator) cannot see the internal email address
displayed in the information note.
### Moving a Service Desk issue
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/372246) in GitLab 15.7: customers continue receiving notifications when a Service Desk issue is moved.
You can move a Service Desk issue the same way you
[move a regular issue](../issues/managing_issues.md#move-an-issue) in GitLab.
If a Service Desk issue is moved to a different project with Service Desk enabled,
the customer who created the issue continues to receive email notifications.
Because a moved issue is first closed, then copied, the customer is considered to be a participant
in both issues. They continue to receive any notifications in the old issue and the new one.
## Troubleshooting Service Desk
### Emails to Service Desk do not create issues
Your emails might be ignored because they contain one of the
[email headers that GitLab ignores](../../../administration/incoming_email.md#rejected-headers).

View File

@ -175,7 +175,7 @@ Configure your project's merge request settings:
## Service Desk
Enable [Service Desk](../service_desk.md) for your project to offer customer support.
Enable [Service Desk](../service_desk/index.md) for your project to offer customer support.
## Export project

View File

@ -12,7 +12,8 @@ module Gitlab
# Error information from the previous try is in the payload for
# displaying in the Sidekiq UI, but is very confusing in logs!
job = job.except(
'exception.backtrace', 'exception.class', 'exception.message', 'exception.sql'
'exception.backtrace', 'exception.class', 'exception.message', 'exception.sql',
'error_message', 'error_class', 'error_backtrace', 'failed_at'
)
job['class'] = job.delete('wrapped') if job['wrapped'].present?

View File

@ -2825,9 +2825,6 @@ msgstr ""
msgid "Add deploy keys to grant read/write access to this repository. %{link_start}What are deploy keys?%{link_end}"
msgstr ""
msgid "Add email address"
msgstr ""
msgid "Add email participant(s)"
msgstr ""
@ -4634,9 +4631,6 @@ msgstr ""
msgid "All eligible users"
msgstr ""
msgid "All email addresses will be used to identify your commits."
msgstr ""
msgid "All environments"
msgstr ""
@ -11246,15 +11240,6 @@ msgstr ""
msgid "CodeOwner|Pattern"
msgstr ""
msgid "CodeSuggestionsAlert|Code faster and more efficiently with AI-powered code suggestions in VS Code. 13 languages are supported, including JavaScript, Python, Go, Java, and Kotlin. Enable Code Suggestions in your %{preference_link_start}user profile preferences%{link_end} or %{docs_link_start}see the documentation%{link_end} to learn more."
msgstr ""
msgid "CodeSuggestionsAlert|Enable Code Suggestions"
msgstr ""
msgid "CodeSuggestionsAlert|Get started with Code Suggestions, available for free during the beta period."
msgstr ""
msgid "CodeSuggestionsSM|By enabling this feature, you agree to the %{terms_link_start}GitLab Testing Agreement%{link_end} and acknowledge that GitLab will send data from the instance, including personal data, to our %{ai_docs_link_start}AI providers%{link_end} to provide this feature."
msgstr ""
@ -12784,9 +12769,6 @@ msgstr ""
msgid "Contributor statistics"
msgstr ""
msgid "Control emails linked to your account"
msgstr ""
msgid "Control how the CI_JOB_TOKEN CI/CD variable is used for API access between projects."
msgstr ""
@ -13537,6 +13519,9 @@ msgstr ""
msgid "Created %{timeAgo} by %{author}"
msgstr ""
msgid "Created %{time_ago}"
msgstr ""
msgid "Created %{timestamp}"
msgstr ""
@ -15446,7 +15431,7 @@ msgstr ""
msgid "DependencyProxy|Enable Dependency Proxy"
msgstr ""
msgid "DependencyProxy|Enable the Dependency Proxy and settings for clearing the cache."
msgid "DependencyProxy|Enable the Dependency Proxy to cache container images from Docker Hub and automatically clear the cache."
msgstr ""
msgid "DependencyProxy|Image list"
@ -27629,9 +27614,6 @@ msgstr ""
msgid "Link to your Grafana instance."
msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
msgid "Linked epics"
msgstr ""
@ -35382,9 +35364,15 @@ msgstr ""
msgid "Profiles|Active"
msgstr ""
msgid "Profiles|Add email address"
msgstr ""
msgid "Profiles|Add key"
msgstr ""
msgid "Profiles|Add new email"
msgstr ""
msgid "Profiles|An error occurred while updating your username, please try again."
msgstr ""
@ -35427,7 +35415,7 @@ msgstr ""
msgid "Profiles|Connected Accounts"
msgstr ""
msgid "Profiles|Created %{time_ago}"
msgid "Profiles|Control emails linked to your account"
msgstr ""
msgid "Profiles|Created%{time_ago}"
@ -35472,6 +35460,12 @@ msgstr ""
msgid "Profiles|Edit Profile"
msgstr ""
msgid "Profiles|Email"
msgstr ""
msgid "Profiles|Email addresses"
msgstr ""
msgid "Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place."
msgstr ""
@ -35541,6 +35535,9 @@ msgstr ""
msgid "Profiles|Last used:"
msgstr ""
msgid "Profiles|Linked emails"
msgstr ""
msgid "Profiles|Location"
msgstr ""
@ -35556,9 +35553,6 @@ msgstr ""
msgid "Profiles|No file chosen."
msgstr ""
msgid "Profiles|Notification email"
msgstr ""
msgid "Profiles|Optional but recommended. If set, key becomes invalid on the specified date."
msgstr ""
@ -35598,9 +35592,15 @@ msgstr ""
msgid "Profiles|Remove avatar"
msgstr ""
msgid "Profiles|Resend confirmation email"
msgstr ""
msgid "Profiles|Select a service to sign in with."
msgstr ""
msgid "Profiles|Send confirmation email"
msgstr ""
msgid "Profiles|Service sign-in"
msgstr ""
@ -42601,9 +42601,6 @@ msgstr ""
msgid "Send a single email notification to Owners and Maintainers for new alerts."
msgstr ""
msgid "Send confirmation email"
msgstr ""
msgid "Send email"
msgstr ""
@ -44777,7 +44774,7 @@ msgstr ""
msgid "Subject Key Identifier:"
msgstr ""
msgid "Subkeys"
msgid "Subkeys:"
msgstr ""
msgid "Submit"
@ -49997,6 +49994,15 @@ msgstr ""
msgid "Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises."
msgstr ""
msgid "Used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
msgstr ""
msgid "Used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}."
msgstr ""
msgid "Used for web based operations, such as edits and merges."
msgstr ""
msgid "Used programming language"
msgstr ""
@ -53543,7 +53549,7 @@ msgstr ""
msgid "Your Free top-level group, %{group_name}, has more than %{free_users_limit} users and uses more than %{free_storage_limit} of data. After usage limits are applied to Free top-level groups, projects in this group will be in a %{read_only_link_start}read-only state%{link_end}. You should reduce the number of users or upgrade to a paid tier %{strong_start}before%{strong_end} you manage your storage usage. Otherwise, your Free top-level group will become read-only immediately because the 5-user limit applies. For more information, see our %{faq_link_start}FAQ%{link_end}."
msgstr ""
msgid "Your GPG keys (%{count})"
msgid "Your GPG keys"
msgstr ""
msgid "Your GitLab Ultimate free trial lasts for 30 days. After this period, you can maintain a GitLab Free account forever or upgrade to a paid plan."
@ -53681,9 +53687,6 @@ msgstr ""
msgid "Your comment will be discarded."
msgstr ""
msgid "Your commit email is used for web based operations, such as edits and merges."
msgstr ""
msgid "Your current password is required to register a new device."
msgstr ""
@ -53696,9 +53699,6 @@ msgstr ""
msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
msgstr ""
msgid "Your default notification email is used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
msgstr ""
msgid "Your deployment services will be broken, you will need to manually fix the services after renaming."
msgstr ""
@ -53773,9 +53773,6 @@ msgstr ""
msgid "Your personal access tokens will expire in %{days_to_expire} days or less"
msgstr ""
msgid "Your primary email is used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}."
msgstr ""
msgid "Your profile"
msgstr ""

View File

@ -538,6 +538,26 @@ RSpec.describe SessionsController, feature_category: :system_access do
expect(AuthenticationEvent.last.provider).to eq("two-factor-via-webauthn-device")
end
end
context 'when the user is locked and submits a valid verification token' do
let(:user) { create(:user) }
let(:user_params) { { verification_token: 'token' } }
let(:session_params) { { verification_user_id: user.id } }
let(:post_action) { post(:create, params: { user: user_params }, session: session_params) }
before do
encrypted_token = Devise.token_generator.digest(User, user.email, 'token')
user.update!(locked_at: Time.current, unlock_token: encrypted_token)
end
it_behaves_like 'known sign in'
it 'successfully logs in a user' do
post_action
expect(subject.current_user).to eq user
end
end
end
context 'when login fails' do

View File

@ -15,6 +15,7 @@ RSpec.describe 'Profile > GPG Keys', feature_category: :user_profile do
end
it 'saves the new key' do
click_button('Add a GPG key')
fill_in('Key', with: GpgHelpers::User2.public_key)
click_button('Add key')
@ -24,6 +25,7 @@ RSpec.describe 'Profile > GPG Keys', feature_category: :user_profile do
end
it 'with multiple subkeys' do
click_button('Add a GPG key')
fill_in('Key', with: GpgHelpers::User3.public_key)
click_button('Add key')
@ -52,7 +54,10 @@ RSpec.describe 'Profile > GPG Keys', feature_category: :user_profile do
click_link('Remove')
expect(page).to have_content('Your GPG keys (0)')
expect(page).to have_content('Your GPG keys')
page.within('.gl-new-card-count') do
expect(page).to have_content('0')
end
end
it 'user revokes a key via the key index' do
@ -63,7 +68,10 @@ RSpec.describe 'Profile > GPG Keys', feature_category: :user_profile do
click_link('Revoke')
expect(page).to have_content('Your GPG keys (0)')
expect(page).to have_content('Your GPG keys')
page.within('.gl-new-card-count') do
expect(page).to have_content('0')
end
expect(gpg_signature.reload).to have_attributes(
verification_status: 'unknown_key',

View File

@ -22,7 +22,7 @@ RSpec.describe 'User manages emails', feature_category: :user_profile do
it 'adds an email', :aggregate_failures do
fill_in('email_email', with: 'my@email.com')
click_button('Add')
click_button('Add email address')
email = user.emails.find_by(email: 'my@email.com')
@ -37,7 +37,7 @@ RSpec.describe 'User manages emails', feature_category: :user_profile do
it 'does not add an email that is the primary email of another user', :aggregate_failures do
fill_in('email_email', with: other_user.email)
click_button('Add')
click_button('Add email address')
email = user.emails.find_by(email: other_user.email)
@ -51,7 +51,7 @@ RSpec.describe 'User manages emails', feature_category: :user_profile do
it 'removes an email', :aggregate_failures do
fill_in('email_email', with: 'my@email.com')
click_button('Add')
click_button('Add email address')
email = user.emails.find_by(email: 'my@email.com')

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, feature_category: :system_access do
RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, :js, feature_category: :system_access do
include EmailHelpers
let_it_be(:user) { create(:user) }
@ -33,7 +33,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
# Expect to see the verification form on the login page
expect(page).to have_current_path(new_user_session_path)
expect(page).to have_content('Help us protect your account')
expect(page).to have_content(s_('IdentityVerification|Help us protect your account'))
# Expect an instructions email to be sent with a code
code = expect_instructions_email_and_extract_code
@ -41,7 +41,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
# Signing in again prompts for the code and doesn't send a new one
gitlab_sign_in(user)
expect(page).to have_current_path(new_user_session_path)
expect(page).to have_content('Help us protect your account')
expect(page).to have_content(s_('IdentityVerification|Help us protect your account'))
# Verify the code
verify_code(code)
@ -54,7 +54,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
# Expect a confirmation page with a meta refresh tag for 3 seconds to the root
expect(page).to have_current_path(users_successful_verification_path)
expect(page).to have_content('Verification successful')
expect(page).to have_content(s_('IdentityVerification|Verification successful'))
expect(page).to have_selector("meta[http-equiv='refresh'][content='3; url=#{root_path}']", visible: false)
end
end
@ -69,7 +69,8 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
code = expect_instructions_email_and_extract_code
# Request a new code
click_link 'Resend code'
click_button s_('IdentityVerification|Resend code')
expect(page).to have_content(s_('IdentityVerification|A new code has been sent.'))
expect_log_message('Instructions Sent', 2)
new_code = expect_instructions_email_and_extract_code
@ -83,22 +84,16 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
gitlab_sign_in(user)
# It shows a resend button
expect(page).to have_link 'Resend code'
expect(page).to have_button s_('IdentityVerification|Resend code')
# Resend more than the rate limited amount of times
10.times do
click_link 'Resend code'
click_button s_('IdentityVerification|Resend code')
end
# Expect the link to be gone
expect(page).not_to have_link 'Resend code'
# Wait for 1 hour
travel 1.hour
# Now it's visible again
gitlab_sign_in(user)
expect(page).to have_link 'Resend code'
# Expect an error alert
expect(page).to have_content format(s_("IdentityVerification|You've reached the maximum amount of resends. "\
'Wait %{interval} and try again.'), interval: 'about 1 hour')
end
end
@ -118,8 +113,9 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
# Expect an error message
expect_log_message('Failed Attempt', reason: 'rate_limited')
expect(page).to have_content("You've reached the maximum amount of tries. "\
'Wait 10 minutes or send a new code and try again.')
expect(page).to have_content(
format(s_("IdentityVerification|You've reached the maximum amount of tries. "\
'Wait %{interval} or send a new code and try again.'), interval: '10 minutes'))
# Wait for 10 minutes
travel 10.minutes
@ -139,7 +135,8 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
# Expect an error message
expect_log_message('Failed Attempt', reason: 'invalid')
expect(page).to have_content('The code is incorrect. Enter it again, or send a new code.')
expect(page).to have_content(s_('IdentityVerification|The code is incorrect. '\
'Enter it again, or send a new code.'))
end
it 'verifies expired codes' do
@ -156,7 +153,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
# Expect an error message
expect_log_message('Failed Attempt', reason: 'expired')
expect(page).to have_content('The code has expired. Send a new code and try again.')
expect(page).to have_content(s_('IdentityVerification|The code has expired. Send a new code and try again.'))
end
end
end
@ -250,7 +247,8 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
it 'shows an error message on on the login page' do
expect(page).to have_current_path(new_user_session_path)
expect(page).to have_content('Maximum login attempts exceeded. Wait 10 minutes and try again.')
expect(page).to have_content(format(s_('IdentityVerification|Maximum login attempts exceeded. '\
'Wait %{interval} and try again.'), interval: '10 minutes'))
end
end
@ -271,7 +269,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
stub_feature_flags(require_email_verification: false)
# Resending and veryfying the code work as expected
click_link 'Resend code'
click_button s_('IdentityVerification|Resend code')
new_code = expect_instructions_email_and_extract_code
verify_code(code)
@ -283,7 +281,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting,
verify_code(new_code)
expect(page).to have_content(s_('IdentityVerification|The code has expired. Send a new code and try again.'))
click_link 'Resend code'
click_button s_('IdentityVerification|Resend code')
another_code = expect_instructions_email_and_extract_code
verify_code(another_code)

View File

@ -1,56 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Metrics::UsersStarredDashboardsFinder do
describe '#execute' do
subject(:starred_dashboards) { described_class.new(user: user, project: project, params: params).execute }
let_it_be(:user) { create(:user) }
let(:project) { create(:project) }
let(:dashboard_path) { 'config/prometheus/common_metrics.yml' }
let(:params) { {} }
context 'there are no starred dashboard records' do
it 'returns empty array' do
expect(starred_dashboards).to be_empty
end
end
context 'with annotation records' do
let!(:starred_dashboard_1) { create(:metrics_users_starred_dashboard, user: user, project: project) }
let!(:starred_dashboard_2) { create(:metrics_users_starred_dashboard, user: user, project: project, dashboard_path: dashboard_path) }
let!(:other_project_dashboard) { create(:metrics_users_starred_dashboard, user: user, dashboard_path: dashboard_path) }
let!(:other_user_dashboard) { create(:metrics_users_starred_dashboard, project: project, dashboard_path: dashboard_path) }
context 'user without read access to project' do
it 'returns empty relation' do
expect(starred_dashboards).to be_empty
end
end
context 'user with read access to project' do
before do
project.add_reporter(user)
end
it 'loads starred dashboards' do
expect(starred_dashboards).to contain_exactly starred_dashboard_1, starred_dashboard_2
end
context 'when the dashboard_path filter is present' do
let(:params) do
{
dashboard_path: dashboard_path
}
end
it 'loads filtered starred dashboards' do
expect(starred_dashboards).to contain_exactly starred_dashboard_2
end
end
end
end
end
end

View File

@ -18,11 +18,9 @@ describe('ArchivedProjectsService', () => {
const query = 'git';
const sort = 'created_asc';
beforeEach(() => {
Api.groupProjects.mockResolvedValueOnce({ data: projects, headers });
});
it('returns promise the resolves with formatted project', async () => {
Api.groupProjects.mockResolvedValueOnce({ data: projects, headers });
await expect(service.getGroups(undefined, page, query, sort)).resolves.toEqual({
data: projects.map((project) => {
return {
@ -47,7 +45,7 @@ describe('ArchivedProjectsService', () => {
number_users_with_delimiter: 0,
star_count: project.star_count,
updated_at: project.updated_at,
marked_for_deletion: project.marked_for_deletion_at !== null,
marked_for_deletion: false,
last_activity_at: project.last_activity_at,
};
}),
@ -62,6 +60,35 @@ describe('ArchivedProjectsService', () => {
});
});
describe.each`
markedForDeletionAt | expected
${null} | ${false}
${undefined} | ${false}
${'2023-07-21'} | ${true}
`(
'when `marked_for_deletion_at` is $markedForDeletionAt',
({ markedForDeletionAt, expected }) => {
it(`sets marked_for_deletion to ${expected}`, async () => {
Api.groupProjects.mockResolvedValueOnce({
data: projects.map((project) => ({
...project,
marked_for_deletion_at: markedForDeletionAt,
})),
headers,
});
await expect(service.getGroups(undefined, page, query, sort)).resolves.toMatchObject({
data: projects.map(() => {
return {
marked_for_deletion: expected,
};
}),
headers,
});
});
},
);
describe.each`
sortArgument | expectedOrderByParameter | expectedSortParameter
${'name_asc'} | ${'name'} | ${'asc'}
@ -75,6 +102,8 @@ describe('ArchivedProjectsService', () => {
'when the sort argument is $sortArgument',
({ sortArgument, expectedSortParameter, expectedOrderByParameter }) => {
it(`calls the API with sort parameter set to ${expectedSortParameter} and order_by parameter set to ${expectedOrderByParameter}`, () => {
Api.groupProjects.mockResolvedValueOnce({ data: projects, headers });
service.getGroups(undefined, page, query, sortArgument);
expect(Api.groupProjects).toHaveBeenCalledWith(groupId, query, {

View File

@ -1,4 +1,10 @@
import { GlDropdown, GlIcon, GlDropdownItem } from '@gitlab/ui';
import {
GlDisclosureDropdown,
GlDisclosureDropdownItem,
GlButtonGroup,
GlButton,
GlIcon,
} from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import ImportActionsCell from '~/import_entities/import_groups/components/import_actions_cell.vue';
@ -13,6 +19,11 @@ describe('import actions cell', () => {
isInvalid: false,
...props,
},
stubs: {
GlButtonGroup,
GlDisclosureDropdown,
GlDisclosureDropdownItem,
},
});
};
@ -22,9 +33,9 @@ describe('import actions cell', () => {
});
it('renders import dropdown', () => {
const dropdown = wrapper.findComponent(GlDropdown);
expect(dropdown.exists()).toBe(true);
expect(dropdown.props('text')).toBe('Import with projects');
const button = wrapper.findComponent(GlButton);
expect(button.exists()).toBe(true);
expect(button.text()).toBe('Import with projects');
});
it('does not render icon with a hint', () => {
@ -38,9 +49,9 @@ describe('import actions cell', () => {
});
it('renders re-import dropdown', () => {
const dropdown = wrapper.findComponent(GlDropdown);
expect(dropdown.exists()).toBe(true);
expect(dropdown.props('text')).toBe('Re-import with projects');
const button = wrapper.findComponent(GlButton);
expect(button.exists()).toBe(true);
expect(button.text()).toBe('Re-import with projects');
});
it('renders icon with a hint', () => {
@ -55,22 +66,22 @@ describe('import actions cell', () => {
it('does not render import dropdown when group is not available for import', () => {
createComponent({ isAvailableForImport: false });
const dropdown = wrapper.findComponent(GlDropdown);
const dropdown = wrapper.findComponent(GlDisclosureDropdown);
expect(dropdown.exists()).toBe(false);
});
it('renders import dropdown as disabled when group is invalid', () => {
createComponent({ isInvalid: true, isAvailableForImport: true });
const dropdown = wrapper.findComponent(GlDropdown);
const dropdown = wrapper.findComponent(GlDisclosureDropdown);
expect(dropdown.props().disabled).toBe(true);
});
it('emits import-group event when import button is clicked', () => {
createComponent({ isAvailableForImport: true });
const dropdown = wrapper.findComponent(GlDropdown);
dropdown.vm.$emit('click');
const button = wrapper.findComponent(GlButton);
button.vm.$emit('click');
expect(wrapper.emitted('import-group')).toHaveLength(1);
});
@ -87,23 +98,24 @@ describe('import actions cell', () => {
});
it('render import dropdown', () => {
const dropdown = wrapper.findComponent(GlDropdown);
expect(dropdown.props('text')).toBe(`${expectedAction} with projects`);
expect(dropdown.findComponent(GlDropdownItem).text()).toBe(
const button = wrapper.findComponent(GlButton);
const dropdown = wrapper.findComponent(GlDisclosureDropdown);
expect(button.element).toHaveText(`${expectedAction} with projects`);
expect(dropdown.findComponent(GlDisclosureDropdownItem).text()).toBe(
`${expectedAction} without projects`,
);
});
it('request migrate projects by default', () => {
const dropdown = wrapper.findComponent(GlDropdown);
dropdown.vm.$emit('click');
const button = wrapper.findComponent(GlButton);
button.vm.$emit('click');
expect(wrapper.emitted('import-group')[0]).toStrictEqual([{ migrateProjects: true }]);
});
it('request not to migrate projects via dropdown option', () => {
const dropdown = wrapper.findComponent(GlDropdown);
dropdown.findComponent(GlDropdownItem).vm.$emit('click');
const dropdown = wrapper.findComponent(GlDisclosureDropdown);
dropdown.findComponent(GlDisclosureDropdownItem).vm.$emit('action');
expect(wrapper.emitted('import-group')[0]).toStrictEqual([{ migrateProjects: false }]);
});

View File

@ -0,0 +1,205 @@
import { GlForm, GlFormInput } from '@gitlab/ui';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { s__ } from '~/locale';
import { createAlert, VARIANT_SUCCESS } from '~/alert';
import { HTTP_STATUS_NOT_FOUND, HTTP_STATUS_OK } from '~/lib/utils/http_status';
import EmailVerification from '~/sessions/new/components/email_verification.vue';
import { visitUrl } from '~/lib/utils/url_utility';
import {
I18N_EMAIL_EMPTY_CODE,
I18N_EMAIL_INVALID_CODE,
I18N_GENERIC_ERROR,
I18N_RESEND_LINK,
I18N_EMAIL_RESEND_SUCCESS,
} from '~/sessions/new/constants';
jest.mock('~/alert');
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
visitUrl: jest.fn(),
}));
describe('EmailVerification', () => {
let wrapper;
let axiosMock;
const defaultPropsData = {
obfuscatedEmail: 'al**@g*****.com',
verifyPath: '/users/sign_in',
resendPath: '/users/resend_verification_code',
};
const createComponent = () => {
wrapper = mountExtended(EmailVerification, {
propsData: defaultPropsData,
});
};
const findForm = () => wrapper.findComponent(GlForm);
const findCodeInput = () => wrapper.findComponent(GlFormInput);
const findSubmitButton = () => wrapper.find('[type="submit"]');
const findResendLink = () => wrapper.findByText(I18N_RESEND_LINK);
const enterCode = (code) => findCodeInput().setValue(code);
const submitForm = () => findForm().trigger('submit');
beforeEach(() => {
axiosMock = new MockAdapter(axios);
createComponent();
});
afterEach(() => {
createAlert.mockClear();
axiosMock.restore();
});
describe('rendering the form', () => {
it('contains the obfuscated email address', () => {
expect(wrapper.text()).toContain(defaultPropsData.obfuscatedEmail);
});
});
describe('verifying the code', () => {
describe('when successfully verifying the code', () => {
const redirectPath = 'root';
beforeEach(async () => {
enterCode('123456');
axiosMock
.onPost(defaultPropsData.verifyPath)
.reply(HTTP_STATUS_OK, { status: 'success', redirect_path: redirectPath });
await submitForm();
await axios.waitForAll();
});
it('redirects to the returned redirect path', () => {
expect(visitUrl).toHaveBeenCalledWith(redirectPath);
});
});
describe('error messages', () => {
it.each`
scenario | code | submit | codeValid | errorShown | message
${'shows no error messages before submitting the form'} | ${''} | ${false} | ${false} | ${false} | ${null}
${'shows no error messages before submitting the form'} | ${'xxx'} | ${false} | ${false} | ${false} | ${null}
${'shows no error messages before submitting the form'} | ${'123456'} | ${false} | ${true} | ${false} | ${null}
${'shows empty code error message when submitting the form'} | ${''} | ${true} | ${false} | ${true} | ${I18N_EMAIL_EMPTY_CODE}
${'shows invalid error message when submitting the form'} | ${'xxx'} | ${true} | ${false} | ${true} | ${I18N_EMAIL_INVALID_CODE}
${'shows incorrect code error message returned from the server'} | ${'123456'} | ${true} | ${true} | ${true} | ${s__('IdentityVerification|The code is incorrect. Enter it again, or send a new code.')}
`(`$scenario with code $code`, async ({ code, submit, codeValid, errorShown, message }) => {
enterCode(code);
if (submit && codeValid) {
axiosMock
.onPost(defaultPropsData.verifyPath)
.replyOnce(HTTP_STATUS_OK, { status: 'failure', message });
}
if (submit) {
await submitForm();
await axios.waitForAll();
}
expect(findCodeInput().classes('is-invalid')).toBe(errorShown);
expect(findSubmitButton().props('disabled')).toBe(errorShown);
if (message) expect(wrapper.text()).toContain(message);
});
it('keeps showing error messages for invalid codes after submitting the form', async () => {
const serverErrorMessage = 'error message';
enterCode('123456');
axiosMock
.onPost(defaultPropsData.verifyPath)
.replyOnce(HTTP_STATUS_OK, { status: 'failure', message: serverErrorMessage });
await submitForm();
await axios.waitForAll();
expect(wrapper.text()).toContain(serverErrorMessage);
await enterCode('');
expect(wrapper.text()).toContain(I18N_EMAIL_EMPTY_CODE);
await enterCode('xxx');
expect(wrapper.text()).toContain(I18N_EMAIL_INVALID_CODE);
});
it('captures the error and shows an alert message when the request failed', async () => {
enterCode('123456');
axiosMock.onPost(defaultPropsData.verifyPath).replyOnce(HTTP_STATUS_OK, null);
await submitForm();
await axios.waitForAll();
expect(createAlert).toHaveBeenCalledWith({
message: I18N_GENERIC_ERROR,
captureError: true,
error: expect.any(Error),
});
});
it('captures the error and shows an alert message when the request undefined', async () => {
enterCode('123456');
axiosMock.onPost(defaultPropsData.verifyPath).reply(HTTP_STATUS_OK, { status: undefined });
await submitForm();
await axios.waitForAll();
expect(createAlert).toHaveBeenCalledWith({
message: I18N_GENERIC_ERROR,
captureError: true,
error: undefined,
});
});
});
});
describe('resending the code', () => {
const failedMessage = 'Failure sending the code';
const successAlertObject = {
message: I18N_EMAIL_RESEND_SUCCESS,
variant: VARIANT_SUCCESS,
};
const failedAlertObject = {
message: failedMessage,
};
const undefinedAlertObject = {
captureError: true,
error: undefined,
message: I18N_GENERIC_ERROR,
};
const genericAlertObject = {
message: I18N_GENERIC_ERROR,
captureError: true,
error: expect.any(Error),
};
it.each`
scenario | statusCode | response | alertObject
${'the code was successfully resend'} | ${HTTP_STATUS_OK} | ${{ status: 'success' }} | ${successAlertObject}
${'there was a problem resending the code'} | ${HTTP_STATUS_OK} | ${{ status: 'failure', message: failedMessage }} | ${failedAlertObject}
${'when the request is undefined'} | ${HTTP_STATUS_OK} | ${{ status: undefined }} | ${undefinedAlertObject}
${'when the request failed'} | ${HTTP_STATUS_NOT_FOUND} | ${null} | ${genericAlertObject}
`(`shows an alert message when $scenario`, async ({ statusCode, response, alertObject }) => {
enterCode('xxx');
await submitForm();
axiosMock.onPost(defaultPropsData.resendPath).replyOnce(statusCode, response);
findResendLink().trigger('click');
await axios.waitForAll();
expect(createAlert).toHaveBeenCalledWith(alertObject);
expect(findCodeInput().element.value).toBe('');
});
});
});

View File

@ -1,8 +1,13 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import IssuableCreateRoot from '~/vue_shared/issuable/create/components/issuable_create_root.vue';
import IssuableForm from '~/vue_shared/issuable/create/components/issuable_form.vue';
Vue.use(VueApollo);
const createComponent = ({
descriptionPreviewPath = '/gitlab-org/gitlab-shell/preview_markdown',
descriptionHelpPath = '/help/user/markdown',
@ -16,6 +21,7 @@ const createComponent = ({
labelsFetchPath,
labelsManagePath,
},
apolloProvider: createMockApollo(),
slots: {
title: `
<h1 class="js-create-title">New Issuable</h1>

View File

@ -2,8 +2,9 @@ import { GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import IssuableForm from '~/vue_shared/issuable/create/components/issuable_form.vue';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue';
import LabelsSelect from '~/sidebar/components/labels/labels_select_vue/labels_select_root.vue';
import { __ } from '~/locale';
const createComponent = ({
descriptionPreviewPath = '/gitlab-org/gitlab-shell/preview_markdown',
@ -24,7 +25,7 @@ const createComponent = ({
`,
},
stubs: {
MarkdownField,
MarkdownEditor,
},
});
};
@ -71,18 +72,20 @@ describe('IssuableForm', () => {
expect(descriptionFieldEl.exists()).toBe(true);
expect(descriptionFieldEl.find('label').text()).toBe('Description');
expect(descriptionFieldEl.findComponent(MarkdownField).exists()).toBe(true);
expect(descriptionFieldEl.findComponent(MarkdownField).props()).toMatchObject({
markdownPreviewPath: wrapper.vm.descriptionPreviewPath,
expect(descriptionFieldEl.findComponent(MarkdownEditor).exists()).toBe(true);
expect(descriptionFieldEl.findComponent(MarkdownEditor).props()).toMatchObject({
renderMarkdownPath: wrapper.vm.descriptionPreviewPath,
markdownDocsPath: wrapper.vm.descriptionHelpPath,
addSpacingClasses: false,
showSuggestPopover: true,
textareaValue: '',
value: '',
formFieldProps: {
ariaLabel: __('Description'),
class: 'rspec-issuable-form-description',
placeholder: __('Write a comment or drag your files here…'),
dataQaSelector: 'issuable_form_description_field',
id: 'issuable-description',
name: 'issuable-description',
},
});
expect(descriptionFieldEl.find('textarea').exists()).toBe(true);
expect(descriptionFieldEl.find('textarea').attributes('placeholder')).toBe(
'Write a comment or drag your files here…',
);
});
it('renders labels select field', () => {

View File

@ -108,8 +108,8 @@ describe('WorkItemLinks', () => {
describe('add link form', () => {
it('displays add work item form on click add dropdown then add existing button and hides form on cancel', async () => {
await createComponent();
findToggleFormDropdown().vm.$emit('click');
findToggleAddFormButton().vm.$emit('click');
findToggleFormDropdown().vm.$emit('action');
findToggleAddFormButton().vm.$emit('action');
await nextTick();
expect(findAddLinksForm().exists()).toBe(true);
@ -123,8 +123,8 @@ describe('WorkItemLinks', () => {
it('displays create work item form on click add dropdown then create button and hides form on cancel', async () => {
await createComponent();
findToggleFormDropdown().vm.$emit('click');
findToggleCreateFormButton().vm.$emit('click');
findToggleFormDropdown().vm.$emit('action');
findToggleCreateFormButton().vm.$emit('action');
await nextTick();
expect(findAddLinksForm().exists()).toBe(true);
@ -195,8 +195,8 @@ describe('WorkItemLinks', () => {
.fn()
.mockResolvedValue(getIssueDetailsResponse({ confidential: true })),
});
findToggleFormDropdown().vm.$emit('click');
findToggleAddFormButton().vm.$emit('click');
findToggleFormDropdown().vm.$emit('action');
findToggleAddFormButton().vm.$emit('action');
await nextTick();
expect(findAddLinksForm().props('parentConfidential')).toBe(true);

View File

@ -584,6 +584,7 @@ export const workItemResponseFactory = ({
__typename: 'WorkItemWidgetProgress',
type: 'PROGRESS',
progress: 0,
updatedAt: new Date(),
}
: { type: 'MOCK TYPE' },
milestoneWidgetPresent
@ -1145,6 +1146,7 @@ export const workItemObjectiveMetadataWidgets = {
type: 'PROGRESS',
__typename: 'WorkItemWidgetProgress',
progress: 10,
updatedAt: new Date(),
},
};
@ -1213,6 +1215,7 @@ export const workItemObjectiveNoMetadata = {
__typename: 'WorkItemWidgetProgress',
type: 'PROGRESS',
progress: null,
updatedAt: null,
},
{
__typename: 'WorkItemWidgetMilestone',

View File

@ -51,28 +51,15 @@ RSpec.describe SessionsHelper do
end
end
describe '#send_rate_limited?' do
describe '#verification_data' do
let(:user) { build_stubbed(:user) }
subject { helper.send_rate_limited?(user) }
before do
allow(::Gitlab::ApplicationRateLimiter)
.to receive(:peek)
.with(:email_verification_code_send, scope: user)
.and_return(rate_limited)
end
context 'when rate limited' do
let(:rate_limited) { true }
it { is_expected.to eq(true) }
end
context 'when not rate limited' do
let(:rate_limited) { false }
it { is_expected.to eq(false) }
it 'returns the expected data' do
expect(helper.verification_data(user)).to eq({
obfuscated_email: obfuscated_email(user.email),
verify_path: helper.session_path(:user),
resend_path: users_resend_verification_code_path
})
end
end

View File

@ -7028,31 +7028,6 @@ RSpec.describe User, feature_category: :user_profile do
end
end
describe '#dismissed_callout_before?' do
let_it_be(:user, refind: true) { create(:user) }
let_it_be(:feature_name) { Users::Callout.feature_names.each_key.first }
context 'when no callout dismissal record exists' do
it 'returns false' do
expect(user.dismissed_callout_before?(feature_name, 1.day.ago)).to eq false
end
end
context 'when dismissed callout exists' do
before_all do
create(:callout, user: user, feature_name: feature_name, dismissed_at: 4.months.ago)
end
it 'returns false when dismissed_before is earlier than dismissed_at' do
expect(user.dismissed_callout_before?(feature_name, 6.months.ago)).to eq false
end
it 'returns true when dismissed_before is later than dismissed_at' do
expect(user.dismissed_callout_before?(feature_name, 3.months.ago)).to eq true
end
end
end
describe '#find_or_initialize_callout' do
let_it_be(:user, refind: true) { create(:user) }
let_it_be(:feature_name) { Users::Callout.feature_names.each_key.first }

View File

@ -23,15 +23,4 @@ RSpec.describe Users::Calloutable, feature_category: :shared do
expect(callout_dismissed_day_ago.dismissed_after?(15.days.ago)).to eq(true)
end
end
describe '#dismissed_before?' do
let(:some_feature_name) { Users::Callout.feature_names.keys.second }
let(:callout_dismissed_hour_ago) { create(:callout, feature_name: some_feature_name, dismissed_at: 1.hour.ago) }
let(:callout_dismissed_minute_ago) { create(:callout, feature_name: some_feature_name, dismissed_at: 1.minute.ago) }
it 'returns whether a callout dismissed before specified date' do
expect(callout_dismissed_hour_ago.dismissed_before?(30.minutes.ago)).to eq(true)
expect(callout_dismissed_minute_ago.dismissed_before?(30.minutes.ago)).to eq(false)
end
end
end

View File

@ -147,12 +147,10 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
post(user_session_path(user: { verification_token: 'token' }))
end
it_behaves_like 'prompt for email verification'
it 'adds a verification error message' do
expect(response.body)
.to include("You&#39;ve reached the maximum amount of tries. "\
'Wait 10 minutes or send a new code and try again.')
expect(json_response)
.to include('message' => "You've reached the maximum amount of tries. "\
'Wait 10 minutes or send a new code and try again.')
end
end
@ -161,11 +159,10 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
post(user_session_path(user: { verification_token: 'invalid_token' }))
end
it_behaves_like 'prompt for email verification'
it 'adds a verification error message' do
expect(response.body)
.to include((s_('IdentityVerification|The code is incorrect. Enter it again, or send a new code.')))
expect(json_response)
.to include('message' => (s_('IdentityVerification|The code is incorrect. '\
'Enter it again, or send a new code.')))
end
end
@ -175,27 +172,26 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
post(user_session_path(user: { verification_token: 'token' }))
end
it_behaves_like 'prompt for email verification'
it 'adds a verification error message' do
expect(response.body)
.to include((s_('IdentityVerification|The code has expired. Send a new code and try again.')))
expect(json_response)
.to include('message' => (s_('IdentityVerification|The code has expired. Send a new code and try again.')))
end
end
context 'when a valid verification_token param exists' do
before do
post(user_session_path(user: { verification_token: 'token' }))
subject(:submit_token) { post(user_session_path(user: { verification_token: 'token' })) }
it 'unlocks the user, create logs and records the activity', :freeze_time do
expect { submit_token }.to change { user.reload.unlock_token }.to(nil)
.and change { user.locked_at }.to(nil)
.and change { AuditEvent.count }.by(1)
.and change { AuthenticationEvent.count }.by(1)
.and change { user.last_activity_on }.to(Date.today)
end
it 'unlocks the user' do
user.reload
expect(user.unlock_token).to be_nil
expect(user.locked_at).to be_nil
end
it 'redirects to the successful verification path' do
expect(response).to redirect_to(users_successful_verification_path)
it 'returns the success status and a redirect path' do
submit_token
expect(json_response).to eq('status' => 'success', 'redirect_path' => users_successful_verification_path)
end
end
@ -206,8 +202,8 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
post user_session_path, params: { user: { login: another_user.username, password: another_user.password } }
end
it 'does not redirect to the successful verification path' do
expect(response).not_to redirect_to(users_successful_verification_path)
it 'redirects to the root path' do
expect(response).to redirect_to(root_path)
end
end
end
@ -277,7 +273,6 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
end
it_behaves_like 'send verification instructions'
it_behaves_like 'prompt for email verification'
end
context 'when exceeding the rate limit' do
@ -301,8 +296,6 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
mail = find_email_for(user)
expect(mail).to be_nil
end
it_behaves_like 'prompt for email verification'
end
end

View File

@ -14,5 +14,12 @@ RSpec.describe PersonalAccessTokens::RevokeTokenFamilyService, feature_category:
expect(response).to be_success
expect(token_1.reload).to be_revoked
end
it 'does not revoke any active token not in the pat family' do
unrelated_token = create(:personal_access_token)
expect(response).to be_success
expect(unrelated_token.reload).to be_active
end
end
end

View File

@ -9,10 +9,8 @@ RSpec.shared_examples 'known sign in' do
user.update!(current_sign_in_ip: ip)
end
def stub_cookie(value = user.id)
cookies.encrypted[KnownSignIn::KNOWN_SIGN_IN_COOKIE] = {
value: value, expires: KnownSignIn::KNOWN_SIGN_IN_COOKIE_EXPIRY
}
def stub_cookie(value = user.id, expires = KnownSignIn::KNOWN_SIGN_IN_COOKIE_EXPIRY)
cookies.encrypted[KnownSignIn::KNOWN_SIGN_IN_COOKIE] = { value: value, expires: expires }
end
context 'when the remote IP and the last sign in IP match' do
@ -57,15 +55,13 @@ RSpec.shared_examples 'known sign in' do
end
it 'notifies the user when the cookie is expired' do
stub_cookie
stub_cookie(user.id, 1.day.ago)
travel_to((KnownSignIn::KNOWN_SIGN_IN_COOKIE_EXPIRY + 1.day).from_now) do
expect_next_instance_of(NotificationService) do |instance|
expect(instance).to receive(:unknown_sign_in)
end
post_action
expect_next_instance_of(NotificationService) do |instance|
expect(instance).to receive(:unknown_sign_in)
end
post_action
end
context 'when notify_on_unknown_sign_in global setting is false' do