Add latest changes from gitlab-org/gitlab@master
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 #
|
||||
###############
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = [
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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';
|
||||
|
|
@ -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 },
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`:
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
- 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 -->
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
|
@ -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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
- 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).
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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, {
|
||||
|
|
|
|||
|
|
@ -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 }]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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', () => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||