Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-04-12 09:13:20 +00:00
parent de92b67d77
commit 62cf14d9de
131 changed files with 1982 additions and 1556 deletions

View File

@ -1 +1 @@
6abde2303696a63f9eec85365b144c3b208d8043
2bde9ceaa35d824fa4a22cc04488da02f7522197

View File

@ -1,57 +0,0 @@
<script>
import { GlFilteredSearch } from '@gitlab/ui';
import { setUrlParams, visitUrl } from '~/lib/utils/url_utility';
import { TOKENS, TOKEN_TYPES } from '../constants';
import { initializeValues } from '../utils';
export default {
name: 'AdminUsersFilterApp',
components: {
GlFilteredSearch,
},
data() {
return {
values: initializeValues(),
};
},
computed: {
availableTokens() {
// Once a token is selected, discard the rest
const tokenType = this.values.find(({ type }) => TOKEN_TYPES.includes(type))?.type;
if (tokenType) {
return TOKENS.filter(({ type }) => type === tokenType);
}
return TOKENS;
},
},
methods: {
handleSearch(filters) {
const newParams = {};
filters?.forEach((filter) => {
if (typeof filter === 'string') {
newParams.search_query = filter;
} else {
newParams.filter = filter.value.data;
}
});
const newUrl = setUrlParams(newParams, window.location.href, true);
visitUrl(newUrl);
},
},
};
</script>
<template>
<gl-filtered-search
v-model="values"
:placeholder="s__('AdminUsers|Search by name, email, or username')"
:available-tokens="availableTokens"
class="gl-mb-4"
terms-as-tokens
@submit="handleSearch"
/>
</template>

View File

@ -1,6 +1,3 @@
import { GlFilteredSearchToken } from '@gitlab/ui';
import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/constants';
import { s__, __ } from '~/locale';
export const I18N_USER_ACTIONS = {
@ -21,63 +18,3 @@ export const I18N_USER_ACTIONS = {
trust: s__('AdminUsers|Trust user'),
untrust: s__('AdminUsers|Untrust user'),
};
const OPTION_ADMINS = 'admins';
const OPTION_2FA_ENABLED = 'two_factor_enabled';
const OPTION_2FA_DISABLED = 'two_factor_disabled';
const OPTION_EXTERNAL = 'external';
const OPTION_BLOCKED = 'blocked';
const OPTION_BANNED = 'banned';
const OPTION_BLOCKED_PENDING_APPROVAL = 'blocked_pending_approval';
const OPTION_DEACTIVATED = 'deactivated';
const OPTION_WOP = 'wop';
const OPTION_TRUSTED = 'trusted';
export const TOKEN_ACCESS_LEVEL = 'access_level';
export const TOKEN_STATE = 'state';
export const TOKEN_2FA = '2fa';
export const TOKEN_TYPES = [TOKEN_ACCESS_LEVEL, TOKEN_STATE, TOKEN_2FA];
export const TOKENS = [
{
title: s__('AdminUsers|Access level'),
type: TOKEN_ACCESS_LEVEL,
token: GlFilteredSearchToken,
operators: OPERATORS_IS,
unique: true,
options: [
{ value: OPTION_ADMINS, title: s__('AdminUsers|Administrator') },
{ value: OPTION_EXTERNAL, title: s__('AdminUsers|External') },
],
},
{
title: __('State'),
type: TOKEN_STATE,
token: GlFilteredSearchToken,
operators: OPERATORS_IS,
unique: true,
options: [
{ value: OPTION_BANNED, title: s__('AdminUsers|Banned') },
{ value: OPTION_BLOCKED, title: s__('AdminUsers|Blocked') },
{ value: OPTION_DEACTIVATED, title: s__('AdminUsers|Deactivated') },
{
value: OPTION_BLOCKED_PENDING_APPROVAL,
title: s__('AdminUsers|Pending approval'),
},
{ value: OPTION_TRUSTED, title: s__('AdminUsers|Trusted') },
{ value: OPTION_WOP, title: s__('AdminUsers|Without projects') },
],
},
{
title: s__('AdminUsers|Two-factor authentication'),
type: TOKEN_2FA,
token: GlFilteredSearchToken,
operators: OPERATORS_IS,
unique: true,
options: [
{ value: OPTION_2FA_ENABLED, title: __('On') },
{ value: OPTION_2FA_DISABLED, title: __('Off') },
],
},
];

View File

@ -4,7 +4,6 @@ import createDefaultClient from '~/lib/graphql';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import csrf from '~/lib/utils/csrf';
import AdminUsersApp from './components/app.vue';
import AdminUsersFilterApp from './components/admin_users_filter_app.vue';
import DeleteUserModal from './components/modals/delete_user_modal.vue';
import UserActions from './components/user_actions.vue';
@ -35,19 +34,12 @@ const initApp = (el, component, userPropKey, props = {}) => {
});
};
export const initAdminUsersFilterApp = () => {
return new Vue({
el: document.querySelector('#js-admin-users-filter-app'),
render: (createElement) => createElement(AdminUsersFilterApp),
});
};
export const initAdminUsersApp = (el = document.querySelector('#js-admin-users-app')) =>
initApp(el, AdminUsersApp, 'users');
export const initAdminUserActions = (el = document.querySelector('#js-admin-user-actions')) =>
initApp(el, UserActions, 'user', { showButtonLabels: true });
export const initAdminUsersApp = (el = document.querySelector('#js-admin-users-app')) =>
initApp(el, AdminUsersApp, 'users');
export const initDeleteUserModals = () => {
return new Vue({
functional: true,

View File

@ -1,6 +1,3 @@
import { queryToObject } from '~/lib/utils/url_utility';
import { TOKENS } from './constants';
export const generateUserPaths = (paths, id) => {
return Object.fromEntries(
Object.entries(paths).map(([action, genericPath]) => {
@ -8,33 +5,3 @@ export const generateUserPaths = (paths, id) => {
}),
);
};
/**
* Initialize values based on the URL parameters
* @param {string} query
*/
export function initializeValues(query = document.location.search) {
const values = [];
const { filter, search_query: searchQuery } = queryToObject(query);
if (filter) {
const token = TOKENS.find(({ options }) => options.some(({ value }) => value === filter));
if (token) {
values.push({
type: token.type,
value: {
data: filter,
operator: token.operators[0].value,
},
});
}
}
if (searchQuery) {
values.push(searchQuery);
}
return values;
}

View File

@ -4,6 +4,7 @@ import {
GlForm,
GlFormGroup,
GlFormInput,
GlFormText,
GlCollapsibleListbox,
GlLink,
GlSprintf,
@ -28,6 +29,7 @@ export default {
GlForm,
GlFormGroup,
GlFormInput,
GlFormText,
GlCollapsibleListbox,
GlLink,
GlSprintf,
@ -60,6 +62,10 @@ export default {
},
},
i18n: {
agentSelectorHelp: s__(
'Environments|Select an agent with Kubernetes access to the project or group.',
),
agentSelectorLinkText: s__('Environments|How do I grant Kubernetes access?'),
header: __('Environments'),
helpNewMessage: ENVIRONMENT_NEW_HELP_TEXT,
helpEditMessage: ENVIRONMENT_EDIT_HELP_TEXT,
@ -75,6 +81,7 @@ export default {
cancel: __('Cancel'),
reset: __('Reset'),
},
agentSelectorHelpPagePath: helpPagePath('user/clusters/agent/user_access.md'),
environmentsHelpPagePath: helpPagePath('ci/environments/index.md'),
renamingDisabledHelpPagePath: helpPagePath('ci/environments/index.md', {
anchor: 'rename-an-environment',
@ -283,6 +290,12 @@ export default {
@select="onAgentChange"
@reset="onChange({ ...environment, clusterAgentId: null })"
/>
<gl-form-text>
{{ $options.i18n.agentSelectorHelp }}
<gl-link :href="$options.agentSelectorHelpPagePath" target="_blank"
>{{ $options.i18n.agentSelectorLinkText }}
</gl-link>
</gl-form-text>
</gl-form-group>
<environment-namespace-selector

View File

@ -77,7 +77,7 @@ export default {
</script>
<template>
<section>
<h4 class="gl-mt-0">
<h4 v-if="section.title" class="gl-mt-0">
{{ section.title
}}<gl-badge
v-if="section.plan"

View File

@ -48,10 +48,7 @@ export default {
<template>
<div class="discussion-with-resolve-btn clearfix">
<discussion-reply-placeholder
data-testid="discussion-reply-tab"
@focus="$emit('showReplyForm')"
/>
<discussion-reply-placeholder @focus="$emit('showReplyForm')" />
<div v-if="userCanResolveDiscussion" class="btn-group discussion-actions" role="group">
<div class="btn-group">

View File

@ -1,8 +1,12 @@
<script>
import { GlFormInput } from '@gitlab/ui';
import { __ } from '~/locale';
export default {
name: 'ReplyPlaceholder',
components: {
GlFormInput,
},
props: {
placeholderText: {
type: String,
@ -19,12 +23,11 @@ export default {
</script>
<template>
<textarea
ref="textarea"
rows="1"
class="reply-placeholder-text-field js-vue-discussion-reply"
<gl-form-input
class="reply-placeholder-input-field"
data-testid="discussion-reply-tab"
:placeholder="placeholderText"
:aria-label="labelText"
@focus="$emit('focus')"
></textarea>
/>
</template>

View File

@ -78,7 +78,9 @@ export default {
<template>
<div data-testid="container-expiration-policy-project-settings">
<h4 data-testid="title">{{ $options.i18n.CONTAINER_CLEANUP_POLICY_TITLE }}</h4>
<h3 data-testid="title" class="gl-heading-3 gl-mt-3!">
{{ $options.i18n.CONTAINER_CLEANUP_POLICY_TITLE }}
</h3>
<p data-testid="description">
<gl-sprintf :message="$options.i18n.CONTAINER_CLEANUP_POLICY_DESCRIPTION">
<template #link="{ content }">

View File

@ -2,9 +2,9 @@
<section class="settings-section">
<div class="settings-sticky-header">
<div class="settings-sticky-header-inner">
<h4 class="gl-my-0">
<h3 class="gl-heading-3 gl-mb-0!">
<slot name="title"></slot>
</h4>
</h3>
</div>
</div>
<p class="gl-text-secondary">

View File

@ -1,13 +1,7 @@
import {
initAdminUsersApp,
initAdminUsersFilterApp,
initDeleteUserModals,
initAdminUserActions,
} from '~/admin/users';
import { initAdminUsersApp, initDeleteUserModals, initAdminUserActions } from '~/admin/users';
import initConfirmModal from '~/confirm_modal';
initAdminUsersApp();
initAdminUsersFilterApp();
initAdminUserActions();
initDeleteUserModals();
initConfirmModal();

View File

@ -81,6 +81,11 @@ export default {
'ProjectSettings|Highlight the usage of hidden unicode characters. These have innocent uses for right-to-left languages, but can also be used in potential exploits.',
),
confirmButtonText: __('Save changes'),
emailsLabel: s__('ProjectSettings|Email notifications'),
showDiffPreviewLabel: s__('ProjectSettings|Include diff previews'),
showDiffPreviewHelpText: s__(
'ProjectSettings|Emails are not encrypted. Concerned administrators may want to disable diff previews.',
),
},
VISIBILITY_LEVEL_PRIVATE_INTEGER,
VISIBILITY_LEVEL_INTERNAL_INTEGER,
@ -125,6 +130,11 @@ export default {
required: false,
default: false,
},
canSetDiffPreviewInEmail: {
type: Boolean,
required: false,
default: false,
},
canChangeVisibilityLevel: {
type: Boolean,
required: false,
@ -282,6 +292,7 @@ export default {
enforceAuthChecksOnUploads: true,
highlightChangesClass: false,
emailsEnabled: true,
showDiffPreviewInEmail: true,
cveIdRequestEnabled: true,
featureAccessLevelEveryone,
featureAccessLevelMembers,
@ -382,6 +393,14 @@ export default {
monitorOperationsFeatureAccessLevelOptions() {
return this.featureAccessLevelOptions.filter(([value]) => value <= this.monitorAccessLevel);
},
findDiffPreviewValue: {
get() {
return this.emailsEnabled && this.showDiffPreviewInEmail;
},
set(newValue) {
this.showDiffPreviewInEmail = newValue;
},
},
},
watch: {
@ -1021,8 +1040,10 @@ export default {
/>
</project-setting-row>
</div>
<project-setting-row v-if="canDisableEmails" ref="email-settings" class="mb-3">
<label class="js-emails-enabled">
<h5>{{ $options.i18n.emailsLabel }}</h5>
<input
:value="emailsEnabled"
type="hidden"
@ -1035,6 +1056,21 @@ export default {
}}</template>
</gl-form-checkbox>
</label>
<project-setting-row
v-if="canSetDiffPreviewInEmail"
ref="enable-diff-preview-settings"
class="gl-px-7"
>
<input
:value="findDiffPreviewValue"
type="hidden"
name="project[project_setting_attributes][show_diff_preview_in_email]"
/>
<gl-form-checkbox v-model="findDiffPreviewValue" :disabled="!emailsEnabled">
{{ $options.i18n.showDiffPreviewLabel }}
<template #help>{{ $options.i18n.showDiffPreviewHelpText }}</template>
</gl-form-checkbox>
</project-setting-row>
</project-setting-row>
<project-setting-row class="mb-3">
<input

View File

@ -387,11 +387,3 @@ input[type='search'] {
}
}
/* stylelint-enable property-no-vendor-prefix */
.admin-users-search {
grid-template-columns: 1fr auto;
.gl-filtered-search-term-input {
width: 100%;
}
}

View File

@ -358,6 +358,12 @@ table {
border: 1px solid $gray-500;
}
}
.reply-placeholder-input-field {
@include media-breakpoint-down(xs) {
margin-bottom: $gl-padding-8;
}
}
}
.comment-toolbar {

View File

@ -49,9 +49,6 @@ class Import::BitbucketServerController < Import::BaseController
session[bitbucket_server_username_key] = params[:bitbucket_server_username]
session[bitbucket_server_url_key] = params[:bitbucket_server_url]
experiment(:default_to_import_tab, actor: current_user)
.track(:authentication, property: provider_name)
redirect_to status_import_bitbucket_server_path(namespace_id: params[:namespace_id])
end

View File

@ -22,9 +22,6 @@ class Import::FogbugzController < Import::BaseController
session[:fogbugz_token] = res.get_token.to_s
session[:fogbugz_uri] = params[:uri]
experiment(:default_to_import_tab, actor: current_user)
.track(:successfully_authenticated, property: provider_name)
redirect_to new_user_map_import_fogbugz_path(namespace_id: params[:namespace_id])
end

View File

@ -43,9 +43,6 @@ class Import::GithubController < Import::BaseController
end
def personal_access_token
experiment(:default_to_import_tab, actor: current_user)
.track(:authentication, property: provider_name)
session[access_token_key] = params[:personal_access_token]&.strip
redirect_to status_import_url
end

View File

@ -21,9 +21,6 @@ class Import::GitlabProjectsController < Import::BaseController
@project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute
if @project.saved?
experiment(:default_to_import_tab, actor: current_user)
.track(:successfully_imported, property: 'gitlab_export')
redirect_to(
project_path(@project),
notice: _("Project '%{project_name}' is being imported.") % { project_name: @project.name }

View File

@ -31,9 +31,6 @@ class Import::ManifestController < Import::BaseController
if manifest.valid?
manifest_import_metadata.save(manifest.projects, group.id)
experiment(:default_to_import_tab, actor: current_user)
.track(:successfully_imported, property: provider_name)
redirect_to status_import_manifest_path
else
@errors = manifest.errors

View File

@ -469,6 +469,7 @@ class ProjectsController < Projects::ApplicationController
def project_setting_attributes
%i[
show_default_award_emojis
show_diff_preview_in_email
squash_option
mr_default_target_self
warn_about_potentially_unwanted_characters

View File

@ -74,3 +74,5 @@ module UserSettings
end
end
end
UserSettings::PersonalAccessTokensController.prepend_mod

View File

@ -21,6 +21,7 @@
# label_name: string
# sort: string
# non_archived: boolean
# merged_without_event_source: boolean
# my_reaction_emoji: string
# source_branch: string
# target_branch: string
@ -78,6 +79,7 @@ class MergeRequestsFinder < IssuableFinder
items = by_deployments(items)
items = by_reviewer(items)
items = by_source_project_id(items)
items = by_resource_event_state(items)
by_approved(items)
end
@ -164,6 +166,12 @@ class MergeRequestsFinder < IssuableFinder
end
# rubocop: enable CodeReuse/ActiveRecord
def by_resource_event_state(items)
return items unless params[:merged_without_event_source].present?
items.merged_without_state_event_source
end
# rubocop: disable CodeReuse/ActiveRecord
def by_draft(items)
draft_param = Gitlab::Utils.to_boolean(params.fetch(:draft) { params.fetch(:wip, nil) })

View File

@ -21,6 +21,13 @@ module GroupsHelper
can?(current_user, :set_emails_disabled, group) && !group.parent&.emails_disabled?
end
def can_set_group_diff_preview_in_email?(group)
return false unless Feature.enabled?(:diff_preview_in_email, group)
return false if group.parent&.show_diff_preview_in_email?.equal?(false)
can?(current_user, :set_show_diff_preview_in_email, group)
end
def can_admin_group_member?(group)
Ability.allowed?(current_user, :admin_group_member, group)
end

View File

@ -59,7 +59,7 @@ module MarkupHelper
# as Markdown. HTML tags in the parsed output are not counted toward the
# +max_chars+ limit. If the length limit falls within a tag's contents, then
# the tag contents are truncated without removing the closing tag.
def first_line_in_markdown(object, attribute, max_chars = nil, is_todo: false, **options)
def first_line_in_markdown(object, attribute, max_chars = nil, **options)
md = markdown_field(object, attribute, options.merge(post_process: false))
return unless md.present?

View File

@ -194,6 +194,13 @@ module ProjectsHelper
can?(current_user, :set_emails_disabled, project)
end
def can_set_diff_preview_in_email?(project, current_user)
return false unless Feature.enabled?(:diff_preview_in_email, project.group)
return false if project.group&.show_diff_preview_in_email?.equal?(false)
can?(current_user, :set_show_diff_preview_in_email, project)
end
def last_push_event
current_user&.recent_push(@project)
end
@ -387,6 +394,7 @@ module ProjectsHelper
packagesHelpPath: help_page_path('user/packages/index'),
currentSettings: project_permissions_settings(project),
canAddCatalogResource: can_add_catalog_resource?(project),
canSetDiffPreviewInEmail: can_set_diff_preview_in_email?(project, current_user),
canChangeVisibilityLevel: can_change_visibility_level?(project, current_user),
canDisableEmails: can_disable_emails?(project, current_user),
allowedVisibilityOptions: project_allowed_visibility_levels(project),
@ -767,6 +775,7 @@ module ProjectsHelper
containerRegistryEnabled: !!project.container_registry_enabled,
lfsEnabled: !!project.lfs_enabled,
emailsEnabled: project.emails_enabled?,
showDiffPreviewInEmail: project.show_diff_preview_in_email?,
monitorAccessLevel: feature.monitor_access_level,
showDefaultAwardEmojis: project.show_default_award_emojis?,
warnAboutPotentiallyUnwantedCharacters: project.warn_about_potentially_unwanted_characters?,

View File

@ -350,12 +350,6 @@ module UsersHelper
def preload_project_associations(_)
# Overridden in EE
end
def admin_user_tab_classes
return 'js-users-tabs gl-w-full' unless request.path == admin_users_path
'js-users-tabs gl-w-full gl-border-0'
end
end
UsersHelper.prepend_mod_with('UsersHelper')

View File

@ -481,6 +481,11 @@ class MergeRequest < ApplicationRecord
end
}
scope :merged_without_state_event_source, -> {
joins(:resource_state_events)
.merge(ResourceStateEvent.merged_with_no_event_source)
}
def self.total_time_to_merge
join_metrics
.where(

View File

@ -73,6 +73,7 @@ class NamespaceSetting < ApplicationRecord
all_ancestors_have_emails_enabled?
end
# Where this function is used, a returned "nil" is considered a truthy value
def show_diff_preview_in_email?
return show_diff_preview_in_email unless namespace.has_parent?

View File

@ -13,6 +13,10 @@ class ResourceStateEvent < ResourceEvent
after_create :issue_usage_metrics
scope :merged_with_no_event_source, -> do
where(state: :merged, source_merge_request: nil, source_commit: nil)
end
def self.issuable_attrs
%i[issue merge_request].freeze
end

View File

@ -28,6 +28,8 @@ class StateNote < SyntheticNote
end
end
return "merged manually" if event.state == 'merged' && event_source.is_a?(Commit)
body = event.state.dup
body << " via #{event_source.gfm_reference(project)}" if event_source
body

View File

@ -349,12 +349,7 @@ class IssuableBaseService < ::BaseContainerService
issuable.updated_by = current_user if should_touch
# `issuable` could create a ghost user when updating `last_edited_by`.
# Users::Internal.ghost will obtain an ExclusiveLease within this transaction.
# See issue: https://gitlab.com/gitlab-org/gitlab/-/issues/441526
Gitlab::ExclusiveLease.skipping_transaction_check do
transaction_update(issuable, { save_with_touch: should_touch })
end
transaction_update(issuable, { save_with_touch: should_touch })
end
if issuable_saved

View File

@ -11,7 +11,7 @@ module MergeRequests
MAX_RETARGET_MERGE_REQUESTS = 4
def execute(merge_request)
def execute(merge_request, source = nil)
return if merge_request.merged?
# Mark the merge request as merged, everything that happens afterwards is
@ -23,7 +23,7 @@ module MergeRequests
merge_request_activity_counter.track_merge_mr_action(user: current_user)
create_note(merge_request)
create_note(merge_request, source)
close_issues(merge_request)
notification_service.merge_mr(merge_request, current_user)
invalidate_cache_counts(merge_request, users: merge_request.assignees | merge_request.reviewers)
@ -37,6 +37,16 @@ module MergeRequests
execute_hooks(merge_request, 'merge')
end
def create_note(merge_request, source)
SystemNoteService.change_status(
merge_request,
merge_request.target_project,
current_user,
merge_request.state,
source
)
end
private
def close_issues(merge_request)

View File

@ -98,9 +98,24 @@ module MergeRequests
merge_request.merge_commit_sha = sha
merge_request.merged_commit_sha = sha
# Look for a merged MR that includes the SHA to associate it with
# the MR we're about to mark as merged.
# Only the merged MRs without the event source would be considered
# to avoid associating it with other MRs that we may have marked as merged here.
source_merge_request = MergeRequestsFinder.new(
@current_user,
project_id: @project.id,
merged_without_event_source: true,
state: 'merged',
sort: 'merged_at',
commit_sha: sha
).execute.first
source = source_merge_request || @project.commit(sha)
MergeRequests::PostMergeService
.new(project: merge_request.target_project, current_user: @current_user)
.execute(merge_request)
.execute(merge_request, source)
end
end
# rubocop: enable CodeReuse/ActiveRecord

View File

@ -1,3 +1,3 @@
= gl_tabs_nav({ class: admin_user_tab_classes }) do
= gl_tabs_nav({ class: 'js-users-tabs' }) do
= gl_tab_link_to s_('AdminUsers|Users'), admin_users_path
= gl_tab_link_to s_('AdminUsers|Cohorts'), admin_cohorts_path

View File

@ -7,11 +7,66 @@
- c.with_body do
= render 'shared/registration_features_discovery_message', feature_title: s_('RegistrationFeatures|send emails to users')
.admin-users-search.row-content-block.gl-lg-display-grid.gl-border-bottom-0.gl-border-top-0{ data: { testid: "filtered-search-block" } }
#js-admin-users-filter-app.gl-mb-4
.dropdown.gl-lg-ml-3
= label_tag s_('AdminUsers|Sort by')
= gl_redirect_listbox_tag admin_users_sort_options(filter: params[:filter], search_query: params[:search_query]), @sort, data: { placement: 'right' }
.top-area
.scrolling-tabs-container.inner-page-scroll-tabs.gl-flex-grow-1.gl-min-w-0.gl-w-full
%button.fade-left{ type: 'button', title: _('Scroll left'), 'aria-label': _('Scroll left') }
= sprite_icon('chevron-lg-left', size: 12)
%button.fade-right{ type: 'button', title: _('Scroll right'), 'aria-label': _('Scroll right') }
= sprite_icon('chevron-lg-right', size: 12)
= gl_tabs_nav({ class: 'scrolling-tabs nav-links gl-display-flex gl-flex-grow-1 gl-w-full' }) do
= gl_tab_link_to admin_users_path, { item_active: active_when(params[:filter].nil?), class: 'gl-border-0!' } do
= s_('AdminUsers|Active')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.active_without_ghosts))
= gl_tab_link_to admin_users_path(filter: "admins"), { item_active: active_when(params[:filter] == 'admins'), class: 'gl-border-0!' } do
= s_('AdminUsers|Admins')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.admins))
= gl_tab_link_to admin_users_path(filter: 'two_factor_enabled'), { item_active: active_when(params[:filter] == 'two_factor_enabled'), class: 'filter-two-factor-enabled gl-border-0!' } do
= s_('AdminUsers|2FA Enabled')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.with_two_factor))
= gl_tab_link_to admin_users_path(filter: 'two_factor_disabled'), { item_active: active_when(params[:filter] == 'two_factor_disabled'), class: 'filter-two-factor-disabled gl-border-0!' } do
= s_('AdminUsers|2FA Disabled')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.without_two_factor))
= gl_tab_link_to admin_users_path(filter: 'external'), { item_active: active_when(params[:filter] == 'external'), class: 'gl-border-0!' } do
= s_('AdminUsers|External')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.external))
= gl_tab_link_to admin_users_path(filter: "blocked"), { item_active: active_when(params[:filter] == 'blocked'), class: 'gl-border-0!' } do
= s_('AdminUsers|Blocked')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.blocked))
= gl_tab_link_to admin_users_path(filter: "banned"), { item_active: active_when(params[:filter] == 'banned'), class: 'gl-border-0!' } do
= s_('AdminUsers|Banned')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.banned))
= gl_tab_link_to admin_users_path(filter: "blocked_pending_approval"), { item_active: active_when(params[:filter] == 'blocked_pending_approval'), class: 'filter-blocked-pending-approval gl-border-0!', data: { testid: 'pending-approval-tab' } } do
= s_('AdminUsers|Pending approval')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.blocked_pending_approval))
= gl_tab_link_to admin_users_path(filter: "deactivated"), { item_active: active_when(params[:filter] == 'deactivated'), class: 'gl-border-0!' } do
= s_('AdminUsers|Deactivated')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.deactivated))
= gl_tab_link_to admin_users_path(filter: "wop"), { item_active: active_when(params[:filter] == 'wop'), class: 'gl-border-0!' } do
= s_('AdminUsers|Without projects')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.without_projects))
= gl_tab_link_to admin_users_path(filter: "trusted"), { item_active: active_when(params[:filter] == 'trusted'), class: 'gl-border-0!' } do
= s_('AdminUsers|Trusted')
= gl_tab_counter_badge(limited_counter_with_delimiter(User.trusted))
.nav-controls
= render_if_exists 'admin/users/admin_email_users'
= render_if_exists 'admin/users/admin_export_user_permissions'
= render Pajamas::ButtonComponent.new(variant: :confirm, href: new_admin_user_path) do
= s_('AdminUsers|New user')
.row-content-block.gl-border-0{ data: { testid: "filtered-search-block" } }
= form_tag admin_users_path, method: :get do
- if params[:filter].present?
= hidden_field_tag "filter", h(params[:filter])
.search-holder
.search-field-holder
= search_field_tag :search_query, params[:search_query], placeholder: s_('AdminUsers|Search by name, email, or username'), class: 'form-control search-text-input js-search-input', spellcheck: false, data: { testid: 'user-search-field' }
- if @sort.present?
= hidden_field_tag :sort, @sort
= sprite_icon('search', css_class: 'search-icon')
= button_tag s_('AdminUsers|Search users') if Rails.env.test?
.dropdown.gl-sm-ml-3
= label_tag s_('AdminUsers|Sort by')
= gl_redirect_listbox_tag admin_users_sort_options(filter: params[:filter], search_query: params[:search_query]), @sort, data: { placement: 'right' }
#js-admin-users-app{ data: admin_users_data_attributes(@users) }
= render Pajamas::SpinnerComponent.new(size: :lg, class: 'gl-my-7')

View File

@ -1,12 +1,6 @@
- page_title _("Users")
.top-area.gl-display-flex.justify-content-between
= render 'tabs'
.nav-controls.gl-mt-3
= render_if_exists 'admin/users/admin_email_users'
= render_if_exists 'admin/users/admin_export_user_permissions'
= render Pajamas::ButtonComponent.new(variant: :confirm, href: new_admin_user_path) do
= s_('AdminUsers|New user')
= render 'tabs'
.tab-content
.tab-pane.active

View File

@ -45,7 +45,7 @@
\.
- if todo.note.present?
%span.action-description<
= first_line_in_markdown(todo, :body, 125, is_todo: true, project: todo.project, group: todo.group)
= first_line_in_markdown(todo, :body, 125, project: todo.project, group: todo.group)
= render_if_exists "dashboard/todos/review_summary", local_assigns: { todo: todo }

View File

@ -0,0 +1,14 @@
%h5= _('Email notifications')
.form-group.gl-mb-3
= f.gitlab_ui_checkbox_component :emails_enabled,
s_('GroupSettings|Enable email notifications'),
checkbox_options: { checked: @group.emails_enabled?, disabled: !can_disable_group_emails?(@group) },
help_text: s_('GroupSettings|Enable sending email notifications for this group and all its subgroups and projects')
- if Feature.enabled?(:diff_preview_in_email, @group)
.gl-px-7
= f.gitlab_ui_checkbox_component :show_diff_preview_in_email,
s_('GroupSettings|Include diff previews'),
checkbox_options: { checked: @group.show_diff_preview_in_email? & @group.emails_enabled?,
disabled: !@group.emails_enabled? || !can_set_group_diff_preview_in_email?(@group) },
help_text: s_('GroupSettings|Emails are not encrypted. Concerned administrators may want to disable diff previews.')

View File

@ -17,12 +17,6 @@
checkbox_options: { disabled: !can_change_share_with_group_lock?(@group) },
help_text: share_with_group_lock_help_text(@group)
.form-group.gl-mb-3
= f.gitlab_ui_checkbox_component :emails_enabled,
s_('GroupSettings|Enable email notifications'),
checkbox_options: { checked: @group.emails_enabled?, disabled: !can_disable_group_emails?(@group) },
help_text: s_('GroupSettings|Enable sending email notifications for this group and all its subgroups and projects')
.form-group.gl-mb-3
= f.gitlab_ui_checkbox_component :mentions_disabled,
s_('GroupSettings|Group mentions are disabled'),
@ -30,6 +24,7 @@
help_text: s_('GroupSettings|Group members are not notified if the group is mentioned.')
= render 'groups/settings/resource_access_token_creation', f: f, group: @group
= render 'groups/settings/email_settings', f: f, group: @group
= render 'groups/settings/ip_restriction_registration_features_cta', f: f
= render_if_exists 'groups/settings/ip_restriction', f: f, group: @group
= render_if_exists 'groups/settings/allowed_email_domain', f: f, group: @group
@ -50,6 +45,7 @@
= render 'groups/settings/two_factor_auth', f: f, group: @group
= render_if_exists 'groups/personal_access_token_expiration_policy', f: f, group: @group
= render 'groups/settings/membership', f: f, group: @group
= render_if_exists 'groups/settings/personal_access_tokens', f: f, group: @group
%h5= _('Customer relations')
.form-group.gl-mb-3

View File

@ -1,3 +1,10 @@
- note = local_assigns.fetch(:note, @note)
- show_no_diff_preview_message = true
- unless note.nil?
- discussion = local_assigns.fetch(:discussion) { note.discussion } if note.part_of_discussion?
- project = local_assigns.fetch(:project, @project)
- show_no_diff_preview_message = discussion&.diff_discussion? && discussion.on_text? && !project.show_diff_preview_in_email?
%html{ lang: I18n.locale }
%head
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
@ -20,6 +27,9 @@
%p
&mdash;
%br
- if show_no_diff_preview_message
= _('This project does not include diff previews in email notifications.')
%br
- if @target_url
- if @reply_by_email
= _('Reply to this email directly or %{view_it_on_gitlab}.').html_safe % { view_it_on_gitlab: link_to(_("view it on GitLab"), @target_url) }

View File

@ -1,8 +1,18 @@
<% note = local_assigns.fetch(:note, @note) -%>
<% show_no_diff_preview_message = true -%>
<% unless @note.nil? -%>
<% discussion = local_assigns.fetch(:discussion) { note.discussion } if note.part_of_discussion? -%>
<% project = local_assigns.fetch(:project, @project) -%>
<% show_no_diff_preview_message = discussion&.diff_discussion? && discussion.on_text? && !project.show_diff_preview_in_email? -%>
<% end -%>
<%= text_header_message %>
<%= yield -%>
-- <%# signature marker %>
<% if show_no_diff_preview_message -%>
<%= "This project does not include diff previews in email notifications.\n" -%>
<% end -%>
<% if @target_url -%>
<% if @reply_by_email -%>
<%= "Reply to this email directly or view it on GitLab: #{@target_url}" -%>

View File

@ -6,6 +6,7 @@
- author = local_assigns.fetch(:author) { note.author }
- discussion = local_assigns.fetch(:discussion) { note.discussion } if note.part_of_discussion?
- project = local_assigns.fetch(:project, @project)
%p{ style: "color: #777777;" }
= succeed ':' do
@ -23,7 +24,7 @@
- else
= link_to 'discussion', target_url
- if discussion&.diff_discussion? && discussion.on_text?
- if discussion&.diff_discussion? && discussion.on_text? && project.show_diff_preview_in_email?
- if include_stylesheet_link
= content_for :head do
= stylesheet_link_tag 'mailers/highlighted_diff_email'

View File

@ -3,6 +3,7 @@
<% target_url = local_assigns.fetch(:target_url, @target_url) -%>
<% author = local_assigns.fetch(:author) { note.author } -%>
<% discussion = local_assigns.fetch(:discussion) { note.discussion } if note.part_of_discussion? -%>
<% project = local_assigns.fetch(:project, @project) -%>
<%= sanitize_name(author.name) -%>
<% if discussion.nil? -%>
@ -21,10 +22,10 @@
<%= " #{target_url}" -%>
<% if discussion&.diff_discussion? && discussion.on_text? -%>
<% if discussion&.diff_discussion? && discussion.on_text? && project.show_diff_preview_in_email? -%>
<% discussion.truncated_diff_lines(highlight: false, diff_limit: diff_limit).each do |line| -%>
<%= "> #{line.text}\n" -%>
<% end -%>
<%= "> #{line.text}\n" -%>
<% end -%>
<% end -%>
<%= note.note -%>

View File

@ -1,5 +1,4 @@
- active_tab = local_assigns.fetch(:active_tab, 'blank')
- track_label = local_assigns.fetch(:track_label, 'import_project')
- namespace_id = local_assigns.fetch(:destination_namespace_id, nil)
.project-import
@ -18,45 +17,45 @@
.import-buttons
- if gitlab_project_import_enabled?
.import_gitlab_project.has-tooltip{ data: { container: 'body', testid: 'gitlab-import-button' } }
= render Pajamas::ButtonComponent.new(href: '#', icon: 'tanuki', button_options: { class: 'btn_import_gitlab_project js-import-project-btn', data: { href: new_import_gitlab_project_path, platform: 'gitlab_export', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'gitlab_export') } }) do
= render Pajamas::ButtonComponent.new(href: '#', icon: 'tanuki', button_options: { class: 'btn_import_gitlab_project js-import-project-btn', data: { href: new_import_gitlab_project_path, platform: 'gitlab_export', **tracking_attrs_data('import_project', 'click_button', 'gitlab_export') } }) do
= _('GitLab export')
- if github_import_enabled?
%div
= render Pajamas::ButtonComponent.new(href: new_import_github_path(namespace_id: namespace_id), icon: 'github', button_options: { class: 'js-import-github js-import-project-btn', data: { platform: 'github', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'github') } }) do
= render Pajamas::ButtonComponent.new(href: new_import_github_path(namespace_id: namespace_id), icon: 'github', button_options: { class: 'js-import-github js-import-project-btn', data: { platform: 'github', **tracking_attrs_data('import_project', 'click_button', 'github') } }) do
GitHub
- if bitbucket_import_enabled?
%div
= render Pajamas::ButtonComponent.new(href: status_import_bitbucket_path(namespace_id: namespace_id), icon: 'bitbucket', button_options: { class: "import_bitbucket js-import-project-btn #{'js-how-to-import-link' unless bitbucket_import_configured?}", data: { modal_title: _("Import projects from Bitbucket"), modal_message: import_from_bitbucket_message, platform: 'bitbucket_cloud', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'bitbucket_cloud') } }) do
= render Pajamas::ButtonComponent.new(href: status_import_bitbucket_path(namespace_id: namespace_id), icon: 'bitbucket', button_options: { class: "import_bitbucket js-import-project-btn #{'js-how-to-import-link' unless bitbucket_import_configured?}", data: { modal_title: _("Import projects from Bitbucket"), modal_message: import_from_bitbucket_message, platform: 'bitbucket_cloud', **tracking_attrs_data('import_project', 'click_button', 'bitbucket_cloud') } }) do
Bitbucket Cloud
- if bitbucket_server_import_enabled?
%div
= render Pajamas::ButtonComponent.new(href: status_import_bitbucket_server_path(namespace_id: namespace_id), icon: 'bitbucket', button_options: { class: 'import_bitbucket js-import-project-btn', data: { platform: 'bitbucket_server', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'bitbucket_server') } }) do
= render Pajamas::ButtonComponent.new(href: status_import_bitbucket_server_path(namespace_id: namespace_id), icon: 'bitbucket', button_options: { class: 'import_bitbucket js-import-project-btn', data: { platform: 'bitbucket_server', **tracking_attrs_data('import_project', 'click_button', 'bitbucket_server') } }) do
Bitbucket Server
- if fogbugz_import_enabled?
%div
= render Pajamas::ButtonComponent.new(href: new_import_fogbugz_path(namespace_id: namespace_id), icon: 'bug', button_options: { class: 'import_fogbugz js-import-project-btn', data: { platform: 'fogbugz', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'fogbugz') } }) do
= render Pajamas::ButtonComponent.new(href: new_import_fogbugz_path(namespace_id: namespace_id), icon: 'bug', button_options: { class: 'import_fogbugz js-import-project-btn', data: { platform: 'fogbugz', **tracking_attrs_data('import_project', 'click_button', 'fogbugz') } }) do
FogBugz
- if gitea_import_enabled?
%div
= render Pajamas::ButtonComponent.new(href: new_import_gitea_path(namespace_id: namespace_id), icon: 'gitea', button_options: { class: 'import_gitea js-import-project-btn', data: { platform: 'gitea', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'gitea') } }) do
= render Pajamas::ButtonComponent.new(href: new_import_gitea_path(namespace_id: namespace_id), icon: 'gitea', button_options: { class: 'import_gitea js-import-project-btn', data: { platform: 'gitea', **tracking_attrs_data('import_project', 'click_button', 'gitea') } }) do
Gitea
- if git_import_enabled?
%div
= render Pajamas::ButtonComponent.new(icon: 'link', button_options: { class: 'js-toggle-button js-import-git-toggle-button js-import-project-btn', data: { platform: 'repo_url', toggle_open_class: 'active', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'repo_url') } }) do
= render Pajamas::ButtonComponent.new(icon: 'link', button_options: { class: 'js-toggle-button js-import-git-toggle-button js-import-project-btn', data: { platform: 'repo_url', toggle_open_class: 'active', **tracking_attrs_data('import_project', 'click_button', 'repo_url') } }) do
= _('Repository by URL')
- if manifest_import_enabled?
%div
= render Pajamas::ButtonComponent.new(href: new_import_manifest_path(namespace_id: namespace_id), icon: 'doc-text', button_options: { class: 'import_manifest js-import-project-btn', data: { platform: 'manifest_file', track_experiment: local_assigns[:track_experiment], **tracking_attrs_data(track_label, 'click_button', 'manifest_file') } }) do
= render Pajamas::ButtonComponent.new(href: new_import_manifest_path(namespace_id: namespace_id), icon: 'doc-text', button_options: { class: 'import_manifest js-import-project-btn', data: { platform: 'manifest_file', **tracking_attrs_data('import_project', 'click_button', 'manifest_file') } }) do
= _('Manifest file')
= render_if_exists "projects/gitee_import_button", namespace_id: namespace_id, track_label: track_label
= render_if_exists "projects/gitee_import_button", namespace_id: namespace_id, track_label: 'import_project'
.js-toggle-content.toggle-import-form{ class: ('hide' if active_tab != 'import') }

View File

@ -1,8 +1,8 @@
---
name: default_to_import_tab
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139681
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/435211
milestone: '16.8'
type: experiment
group: group::activation
name: diff_preview_in_email
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60007
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382055
milestone: '15.6'
type: gitlab_com_derisk
group: group::code review
default_enabled: false

View File

@ -1,9 +0,0 @@
---
name: sync_epic_to_work_item
feature_issue_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140232
rollout_issue_url:
milestone: '16.9'
group: group::product planning
type: wip
default_enabled: false

View File

@ -7,4 +7,13 @@ feature_categories:
description: Used to track the generation status of export files for groups or projects
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59976
milestone: '13.12'
gitlab_schema: gitlab_main
gitlab_schema: gitlab_main_cell
allow_cross_joins:
- gitlab_main_clusterwide
allow_cross_transactions:
- gitlab_main_clusterwide
allow_cross_foreign_keys:
- gitlab_main_clusterwide
sharding_key:
project_id: projects
group_id: namespaces

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddDisablePersonalAccessTokensToNamespaceSettings < Gitlab::Database::Migration[2.2]
milestone '16.11'
def change
add_column :namespace_settings, :disable_personal_access_tokens, :boolean, default: false, null: false
end
end

View File

@ -0,0 +1 @@
bd1e2bdc4fda7c033a3407516450f15b45bfab4d6600a7bc940d10ca38f3e491

View File

@ -11882,6 +11882,7 @@ CREATE TABLE namespace_settings (
lock_math_rendering_limits_enabled boolean DEFAULT false NOT NULL,
duo_features_enabled boolean,
lock_duo_features_enabled boolean DEFAULT false NOT NULL,
disable_personal_access_tokens boolean DEFAULT false NOT NULL,
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255)),
CONSTRAINT namespace_settings_unique_project_download_limit_alertlist_size CHECK ((cardinality(unique_project_download_limit_alertlist) <= 100)),
CONSTRAINT namespace_settings_unique_project_download_limit_allowlist_size CHECK ((cardinality(unique_project_download_limit_allowlist) <= 100))

View File

@ -94,35 +94,33 @@ You can combine the filter options. For example, to list only public projects wi
## Administering users
> - Filtering users [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238183) in GitLab 16.11.
You can administer all users in the GitLab instance from the Admin Area's Users page:
1. On the left sidebar, at the bottom, select **Admin Area**.
1. Select **Overview > Users**.
You can use the user search box to search and filter users by:
To list users matching a specific criteria, select one of the following tabs on the **Users** page:
- User **access level**.
- Whether **two-factor authentication** is enabled or disabled.
- User **state**.
You can also type text into the search box. For example, the name of a specific user.
This text search is case insensitive, and applies partial matching to name and username.
To search for an email address, you must provide the complete email address.
- **Active**
- **Admins**
- **2FA Enabled**
- **2FA Disabled**
- **External**
- **[Blocked](../administration/moderate_users.md#block-a-user)**
- **[Deactivated](../administration/moderate_users.md#deactivate-a-user)**
- **Without projects**
For each user, the following are listed:
- Username.
- Email address.
- Project membership count.
- Group membership count.
- Date of account creation.
- Date of last activity.
1. Username
1. Email address
1. Project membership count
1. Group membership count ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276215) in GitLab 13.12)
1. Date of account creation
1. Date of last activity
To edit a user, in the user's row, select **Edit**. To delete the user, or delete
the user and their contributions, select the cog dropdown list in that user's row,
and select the desired option.
To edit a user, in the user's row, select **Edit**. To delete the user, or delete the user and their contributions, select the cog dropdown list in
that user's row, and select the desired option.
To change the sort order:
@ -131,6 +129,10 @@ To change the sort order:
By default the sort dropdown list shows **Name**.
To search for users, enter your criteria in the search field. The user search is case
insensitive, and applies partial matching to name and username. To search for an email address,
you must provide the complete email address.
### User impersonation
An administrator can "impersonate" any other user, including other administrators.

View File

@ -123,7 +123,7 @@ The following are required to run Geo:
- [Ubuntu](https://ubuntu.com) 16.04 or later
- Where possible, you should also use the same operating system version on all
Geo sites. If using different operating system versions between Geo sites, you
**must** [check OS locale data compatibility](replication/troubleshooting/index.md#check-os-locale-data-compatibility)
**must** [check OS locale data compatibility](replication/troubleshooting/common.md#check-os-locale-data-compatibility)
across Geo sites to avoid silent corruption of database indexes.
- [Supported PostgreSQL versions](https://handbook.gitlab.com/handbook/engineering/infrastructure/core-platform/data_stores/database/postgresql-upgrade-cadence/) for your GitLab releases with [Streaming Replication](https://wiki.postgresql.org/wiki/Streaming_Replication).
- [PostgreSQL Logical replication](https://www.postgresql.org/docs/current/logical-replication.html) is not supported.

View File

@ -148,8 +148,8 @@ You can run the Geo tracking database on a single node as follows:
```shell
gitlab-ctl pg-password-md5 gitlab_geo
# Enter password: <your_password_here>
# Confirm password: <your_password_here>
# Enter password: <your_tracking_db_password_here>
# Confirm password: <your_tracking_db_password_here>
# fca0b89a972d69f00eb3ec98a5838484
```

View File

@ -0,0 +1,154 @@
---
stage: Systems
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Troubleshooting Geo client and HTTP response code errors
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** Self-managed
## Fixing client errors
### Authorization errors from LFS HTTP(S) client requests
You may have problems if you're running a version of [Git LFS](https://git-lfs.com/) before 2.4.2.
As noted in [this authentication issue](https://github.com/git-lfs/git-lfs/issues/3025),
requests redirected from the secondary to the primary site do not properly send the
Authorization header. This may result in either an infinite `Authorization <-> Redirect`
loop, or Authorization error messages.
### Error: Net::ReadTimeout when pushing through SSH on a Geo secondary
When you push large repositories through SSH on a Geo secondary site, you may encounter a timeout.
This is because Rails proxies the push to the primary and has a 60 second default timeout,
[as described in this Geo issue](https://gitlab.com/gitlab-org/gitlab/-/issues/7405).
Current workarounds are:
- Push through HTTP instead, where Workhorse proxies the request to the primary (or redirects to the primary if Geo proxying is not enabled).
- Push directly to the primary.
Example log (`gitlab-shell.log`):
```plaintext
Failed to contact primary https://primary.domain.com/namespace/push_test.git\\nError: Net::ReadTimeout\",\"result\":null}" code=500 method=POST pid=5483 url="http://127.0.0.1:3000/api/v4/geo/proxy_git_push_ssh/push"
```
### Repair OAuth authorization between Geo sites
When upgrading a Geo site, you might not be able to log in into a secondary site that only uses OAuth for authentication. In that case, start a [Rails console](../../../operations/rails_console.md) session on your primary site and perform the following steps:
1. To find the affected node, first list all the Geo Nodes you have:
```ruby
GeoNode.all
```
1. Repair the affected Geo node by specifying the ID:
```ruby
GeoNode.find(<id>).repair
```
## HTTP response code errors
### Secondary site returns 502 errors with Geo proxying
When [Geo proxying for secondary sites](../../secondary_proxy/index.md) is enabled, and the secondary site user interface returns
502 errors, it is possible that the response header proxied from the primary site is too large.
Check the NGINX logs for errors similar to this example:
```plaintext
2022/01/26 00:02:13 [error] 26641#0: *829148 upstream sent too big header while reading response header from upstream, client: 10.0.2.2, server: geo.staging.gitlab.com, request: "POST /users/sign_in HTTP/2.0", upstream: "http://unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket:/users/sign_in", host: "geo.staging.gitlab.com", referrer: "https://geo.staging.gitlab.com/users/sign_in"
```
To resolve this issue:
1. Set `nginx['proxy_custom_buffer_size'] = '8k'` in `/etc/gitlab.rb` on all web nodes on the secondary site.
1. Reconfigure the **secondary** using `sudo gitlab-ctl reconfigure`.
If you still get this error, you can further increase the buffer size by repeating the steps above
and changing the `8k` size, for example by doubling it to `16k`.
### Geo Admin Area shows 'Unknown' for health status and 'Request failed with status code 401'
If using a load balancer, ensure that the load balancer's URL is set as the `external_url` in the
`/etc/gitlab/gitlab.rb` of the nodes behind the load balancer.
### Primary site returns 500 error when accessing `/admin/geo/replication/projects`
Navigating to **Admin > Geo > Replication** (or `/admin/geo/replication/projects`) on a primary Geo site, shows a 500 error, while that same link on the secondary works fine. The primary's `production.log` has a similar entry to the following:
```plaintext
Geo::TrackingBase::SecondaryNotConfigured: Geo secondary database is not configured
from ee/app/models/geo/tracking_base.rb:26:in `connection'
[..]
from ee/app/views/admin/geo/projects/_all.html.haml:1
```
On a Geo primary site this error can be ignored.
This happens because GitLab is attempting to display registries from the [Geo tracking database](../../../../administration/geo/index.md#geo-tracking-database) which doesn't exist on the primary site (only the original projects exist on the primary; no replicated projects are present, therefore no tracking database exists).
### Secondary site returns 400 error "Request header or cookie too large"
This error can happen when the internal URL of the primary site is incorrect.
For example, when you use a unified URL and the primary site's internal URL is also equal to the external URL. This causes a loop when a secondary site proxies requests to the primary site's internal URL.
To fix this issue, set the primary site's internal URL to a URL that is:
- Unique to the primary site.
- Accessible from all secondary sites.
1. Visit the primary site.
1. [Set up the internal URLs](../../../../administration/geo_sites.md#set-up-the-internal-urls).
### Secondary site returns `Received HTTP code 403 from proxy after CONNECT`
If you have installed GitLab using the Linux package (Omnibus) and have configured the `no_proxy` [custom environment variable](https://docs.gitlab.com/omnibus/settings/environment-variables.html) for Gitaly, you may experience this issue. Affected versions:
- `15.4.6`
- `15.5.0`-`15.5.6`
- `15.6.0`-`15.6.3`
- `15.7.0`-`15.7.1`
This is due to [a bug introduced in the included version of cURL](https://github.com/curl/curl/issues/10122) shipped with
the Linux package 15.4.6 and later. You should upgrade to a later version where this has been
[fixed](https://about.gitlab.com/releases/2023/01/09/security-release-gitlab-15-7-2-released/).
The bug causes all wildcard domains (`.example.com`) to be ignored except for the last on in the `no_proxy` environment variable list. Therefore, if for any reason you cannot upgrade to a newer version, you can work around the issue by moving your wildcard domain to the end of the list:
1. Edit `/etc/gitlab/gitlab.rb`:
```ruby
gitaly['env'] = {
"no_proxy" => "sever.yourdomain.org, .yourdomain.com",
}
```
1. Reconfigure GitLab:
```shell
sudo gitlab-ctl reconfigure
```
You can have only one wildcard domain in the `no_proxy` list.
### Geo Admin Area returns 404 error for a secondary site
Sometimes `sudo gitlab-rake gitlab:geo:check` indicates that **Rails nodes of the secondary** sites are
healthy, but a 404 Not Found error message for the **secondary** site is returned in the Geo Admin Area on the web interface for
the **primary** site.
To resolve this issue:
- Try restarting **each Rails, Sidekiq and Gitaly nodes on your secondary site** using `sudo gitlab-ctl restart`.
- Check `/var/log/gitlab/gitlab-rails/geo.log` on Sidekiq nodes to see if the **secondary** site is
using IPv6 to send its status to the **primary** site. If it is, add an entry to
the **primary** site using IPv4 in the `/etc/hosts` file. Alternatively, you should
[enable IPv6 on the **primary** site](https://docs.gitlab.com/omnibus/settings/nginx.html#setting-the-nginx-listen-address-or-addresses).

View File

@ -0,0 +1,633 @@
---
stage: Systems
group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Troubleshooting common Geo errors
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** Self-managed
## Basic troubleshooting
Before attempting more advanced troubleshooting:
- Check [the health of the Geo sites](#check-the-health-of-the-geo-sites).
- Check [if PostgreSQL replication is working](#check-if-postgresql-replication-is-working).
### Check the health of the Geo sites
On the **primary** site:
1. On the left sidebar, at the bottom, select **Admin Area**.
1. Select **Geo > Sites**.
We perform the following health checks on each **secondary** site
to help identify if something is wrong:
- Is the site running?
- Is the secondary site's database configured for streaming replication?
- Is the secondary site's tracking database configured?
- Is the secondary site's tracking database connected?
- Is the secondary site's tracking database up-to-date?
- Is the secondary site's status less than 10 minutes old?
A site shows as "Unhealthy" if the site's status is more than 10 minutes old. In that case, try running the following in the [Rails console](../../../operations/rails_console.md) on the affected secondary site:
```ruby
Geo::MetricsUpdateWorker.new.perform
```
If it raises an error, then the error is probably also preventing the jobs from completing. If it takes longer than 10 minutes, then there may be a performance issue, and the UI may always show "Unhealthy" even if the status eventually does get updated.
If it successfully updates the status, then something may be wrong with Sidekiq. Is it running? Do the logs show errors? This job is supposed to be enqueued every minute and might not run if a [job deduplication idempotency](../../../sidekiq/sidekiq_troubleshooting.md#clearing-a-sidekiq-job-deduplication-idempotency-key) key was not cleared properly. It takes an exclusive lease in Redis to ensure that only one of these jobs can run at a time. The primary site updates its status directly in the PostgreSQL database. Secondary sites send an HTTP Post request to the primary site with their status data.
A site also shows as "Unhealthy" if certain health checks fail. You can reveal the failure by running the following in the [Rails console](../../../operations/rails_console.md) on the affected secondary site:
```ruby
Gitlab::Geo::HealthCheck.new.perform_checks
```
If it returns `""` (an empty string) or `"Healthy"`, then the checks succeeded. If it returns anything else, then the message should explain what failed, or show the exception message.
For information about how to resolve common error messages reported from the user interface,
see [Fixing Common Errors](#fixing-common-errors).
If the user interface is not working, or you are unable to sign in, you can run the Geo
health check manually to get this information and a few more details.
#### Health check Rake task
> - The use of a custom NTP server was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105514) in GitLab 15.7.
This Rake task can be run on a **Rails** node in the **primary** or **secondary**
Geo sites:
```shell
sudo gitlab-rake gitlab:geo:check
```
Example output:
```plaintext
Checking Geo ...
GitLab Geo is available ... yes
GitLab Geo is enabled ... yes
This machine's Geo node name matches a database record ... yes, found a secondary node named "Shanghai"
GitLab Geo tracking database is correctly configured ... yes
Database replication enabled? ... yes
Database replication working? ... yes
GitLab Geo HTTP(S) connectivity ...
* Can connect to the primary node ... yes
HTTP/HTTPS repository cloning is enabled ... yes
Machine clock is synchronized ... yes
Git user has default SSH configuration? ... yes
OpenSSH configured to use AuthorizedKeysCommand ... yes
GitLab configured to disable writing to authorized_keys file ... yes
GitLab configured to store new projects in hashed storage? ... yes
All projects are in hashed storage? ... yes
Checking Geo ... Finished
```
You can also specify a custom NTP server using environment variables. For example:
```shell
sudo gitlab-rake gitlab:geo:check NTP_HOST="ntp.ubuntu.com" NTP_TIMEOUT="30"
```
The following environment variables are supported.
| Variable | Description | Default value |
| ----------- | ----------- | ------------- |
|`NTP_HOST` | The NTP host. | `pool.ntp.org` |
|`NTP_PORT` | The NTP port the host listens on. |`ntp`|
|`NTP_TIMEOUT`| The NTP timeout in seconds. | The value defined in the `net-ntp` Ruby library ([60 seconds](https://github.com/zencoder/net-ntp/blob/3d0990214f439a5127782e0f50faeaf2c8ca7023/lib/net/ntp/ntp.rb#L6)). |
If the Rake task skips the `OpenSSH configured to use AuthorizedKeysCommand` check, the
following output displays:
```plaintext
OpenSSH configured to use AuthorizedKeysCommand ... skipped
Reason:
Cannot access OpenSSH configuration file
Try fixing it:
This is expected if you are using SELinux. You may want to check configuration manually
For more information see:
doc/administration/operations/fast_ssh_key_lookup.md
```
This issue may occur if:
- You [use SELinux](../../../operations/fast_ssh_key_lookup.md#selinux-support-and-limitations).
- You don't use SELinux, and the `git` user cannot access the OpenSSH configuration file due to restricted file permissions.
In the latter case, the following output shows that only the `root` user can read this file:
```plaintext
sudo stat -c '%G:%U %A %a %n' /etc/ssh/sshd_config
root:root -rw------- 600 /etc/ssh/sshd_config
```
To allow the `git` user to read the OpenSSH configuration file, without changing the file owner or permissions, use `acl`:
```plaintext
sudo setfacl -m u:git:r /etc/ssh/sshd_config
```
#### Sync status Rake task
Current sync information can be found manually by running this Rake task on any
node running Rails (Puma, Sidekiq, or Geo Log Cursor) on the Geo **secondary** site.
GitLab does **not** verify objects that are stored in Object Storage. If you are using Object Storage, you will see all of the "verified" checks showing 0 successes. This is expected and not a cause for concern.
```shell
sudo gitlab-rake geo:status
```
The output includes:
- a count of "failed" items if any failures occurred
- the percentage of "succeeded" items, relative to the "total"
Example:
```plaintext
http://secondary.example.com/
-----------------------------------------------------
GitLab Version: 14.9.2-ee
Geo Role: Secondary
Health Status: Healthy
Project Repositories: succeeded 12345 / total 12345 (100%)
Project Wiki Repositories: succeeded 6789 / total 6789 (100%)
Attachments: succeeded 4 / total 4 (100%)
CI job artifacts: succeeded 0 / total 0 (0%)
Design management repositories: succeeded 1 / total 1 (100%)
LFS Objects: failed 1 / succeeded 2 / total 3 (67%)
Merge Request Diffs: succeeded 0 / total 0 (0%)
Package Files: failed 1 / succeeded 2 / total 3 (67%)
Terraform State Versions: failed 1 / succeeded 2 / total 3 (67%)
Snippet Repositories: failed 1 / succeeded 2 / total 3 (67%)
Group Wiki Repositories: succeeded 4 / total 4 (100%)
Pipeline Artifacts: failed 3 / succeeded 0 / total 3 (0%)
Pages Deployments: succeeded 0 / total 0 (0%)
Repositories Checked: failed 5 / succeeded 0 / total 5 (0%)
Package Files Verified: succeeded 0 / total 10 (0%)
Terraform State Versions Verified: succeeded 0 / total 10 (0%)
Snippet Repositories Verified: succeeded 99 / total 100 (99%)
Pipeline Artifacts Verified: succeeded 0 / total 10 (0%)
Project Repositories Verified: succeeded 12345 / total 12345 (100%)
Project Wiki Repositories Verified: succeeded 6789 / total 6789 (100%)
Sync Settings: Full
Database replication lag: 0 seconds
Last event ID seen from primary: 12345 (about 2 minutes ago)
Last event ID processed: 12345 (about 2 minutes ago)
Last status report was: 1 minute ago
```
Each item can have up to three statuses. For example, for `Project Repositories`, you see the following lines:
```plaintext
Project Repositories: succeeded 12345 / total 12345 (100%)
Project Repositories Verified: succeeded 12345 / total 12345 (100%)
Repositories Checked: failed 5 / succeeded 0 / total 5 (0%)
```
The 3 status items are defined as follows:
- The `Project Repositories` output shows how many project repositories are synced from the primary to the secondary.
- The `Project Verified Repositories` output shows how many project repositories on this secondary have a matching repository checksum with the Primary.
- The `Repositories Checked` output shows how many project repositories have passed a local Git repository check (`git fsck`) on the secondary.
To find more details about failed items, check
[the `gitlab-rails/geo.log` file](../../../logs/log_parsing.md#find-most-common-geo-sync-errors)
If you notice replication or verification failures, you can try to [resolve them](replication.md#fixing-non-postgresql-replication-failures).
If there are Repository check failures, you can try to [resolve them](synchronization.md#find-repository-check-failures-in-a-geo-secondary-site).
##### Fixing errors found when running the Geo check Rake task
When running this Rake task, you may see error messages if the nodes are not properly configured:
```shell
sudo gitlab-rake gitlab:geo:check
```
- Rails did not provide a password when connecting to the database.
```plaintext
Checking Geo ...
GitLab Geo is available ... Exception: fe_sendauth: no password supplied
GitLab Geo is enabled ... Exception: fe_sendauth: no password supplied
...
Checking Geo ... Finished
```
Ensure you have the `gitlab_rails['db_password']` set to the plain-text
password used when creating the hash for `postgresql['sql_user_password']`.
- Rails is unable to connect to the database.
```plaintext
Checking Geo ...
GitLab Geo is available ... Exception: FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
GitLab Geo is enabled ... Exception: FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
...
Checking Geo ... Finished
```
Ensure you have the IP address of the rails node included in `postgresql['md5_auth_cidr_addresses']`.
Also, ensure you have included the subnet mask on the IP address: `postgresql['md5_auth_cidr_addresses'] = ['1.1.1.1/32']`.
- Rails has supplied the incorrect password.
```plaintext
Checking Geo ...
GitLab Geo is available ... Exception: FATAL: password authentication failed for user "gitlab"
FATAL: password authentication failed for user "gitlab"
GitLab Geo is enabled ... Exception: FATAL: password authentication failed for user "gitlab"
FATAL: password authentication failed for user "gitlab"
...
Checking Geo ... Finished
```
Verify the correct password is set for `gitlab_rails['db_password']` that was
used when creating the hash in `postgresql['sql_user_password']` by running
`gitlab-ctl pg-password-md5 gitlab` and entering the password.
- Check returns `not a secondary node`.
```plaintext
Checking Geo ...
GitLab Geo is available ... yes
GitLab Geo is enabled ... yes
GitLab Geo tracking database is correctly configured ... not a secondary node
Database replication enabled? ... not a secondary node
...
Checking Geo ... Finished
```
Ensure you have added the secondary site in the Admin Area under **Geo > Sites** on the web interface for the **primary** site.
Also ensure you entered the `gitlab_rails['geo_node_name']`
when adding the secondary site in the Admin Area of the **primary** site.
In GitLab 12.3 and earlier, edit the secondary site in the Admin Area of the **primary**
site and ensure that there is a trailing `/` in the `Name` field.
- Check returns `Exception: PG::UndefinedTable: ERROR: relation "geo_nodes" does not exist`.
```plaintext
Checking Geo ...
GitLab Geo is available ... no
Try fixing it:
Add a new license that includes the GitLab Geo feature
For more information see:
https://about.gitlab.com/features/gitlab-geo/
GitLab Geo is enabled ... Exception: PG::UndefinedTable: ERROR: relation "geo_nodes" does not exist
LINE 8: WHERE a.attrelid = '"geo_nodes"'::regclass
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
c.collname, col_description(a.attrelid, a.attnum) AS comment
FROM pg_attribute a
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
LEFT JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
WHERE a.attrelid = '"geo_nodes"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
...
Checking Geo ... Finished
```
When performing a PostgreSQL major version (9 > 10), update this is expected. Follow
the [initiate-the-replication-process](../../setup/database.md#step-3-initiate-the-replication-process).
- Rails does not appear to have the configuration necessary to connect to the Geo tracking database.
```plaintext
Checking Geo ...
GitLab Geo is available ... yes
GitLab Geo is enabled ... yes
GitLab Geo tracking database is correctly configured ... no
Try fixing it:
Rails does not appear to have the configuration necessary to connect to the Geo tracking database. If the tracking database is running on a node other than this one, then you may need to add configuration.
...
Checking Geo ... Finished
```
- If you are running the secondary site on a single node for all services, then follow [Geo database replication - Configure the secondary server](../../setup/database.md#step-2-configure-the-secondary-server).
- If you are running the secondary site's tracking database on its own node, then follow [Geo for multiple servers - Configure the Geo tracking database on the Geo secondary site](../multiple_servers.md#step-2-configure-the-geo-tracking-database-on-the-geo-secondary-site)
- If you are running the secondary site's tracking database in a Patroni cluster, then follow [Geo database replication - Configuring Patroni cluster for the tracking PostgreSQL database](../../setup/database.md#configuring-patroni-cluster-for-the-tracking-postgresql-database)
- If you are running the secondary site's tracking database in an external database, then follow [Geo with external PostgreSQL instances](../../setup/external_database.md#configure-the-tracking-database)
- If the Geo check task was run on a node which is not running a service which runs the GitLab Rails app (Puma, Sidekiq, or Geo Log Cursor), then this error can be ignored. The node does not need Rails to be configured.
##### Message: Machine clock is synchronized ... Exception
The Rake task attempts to verify that the server clock is synchronized with NTP. Synchronized clocks
are required for Geo to function correctly. As an example, for security, when the server time on the
primary site and secondary site differ by about a minute or more, requests between Geo sites
fail. If this check task fails to complete due to a reason other than mismatching times, it
does not necessarily mean that Geo will not work.
The Ruby gem which performs the check is hard coded with `pool.ntp.org` as its reference time source.
- Exception message `Machine clock is synchronized ... Exception: Timeout::Error`
This issue occurs when your server cannot access the host `pool.ntp.org`.
- Exception message `Machine clock is synchronized ... Exception: No route to host - recvfrom(2)`
This issue occurs when the hostname `pool.ntp.org` resolves to a server which does not provide a time service.
In this case, in GitLab 15.7 and later, [specify a custom NTP server using environment variables](#health-check-rake-task).
In GitLab 15.6 and earlier, use one of the following workarounds:
- Add entries in `/etc/hosts` for `pool.ntp.org` to direct the request to valid local time servers.
This fixes the long timeout and the timeout error.
- Direct the check to any valid IP address. This resolves the timeout issue, but the check fails
with the `No route to host` error, as noted above.
[Cloud native GitLab deployments](https://docs.gitlab.com/charts/advanced/geo/#set-the-geo-primary-site)
generate an error because containers in Kubernetes do not have access to the host clock:
```plaintext
Machine clock is synchronized ... Exception: getaddrinfo: Servname not supported for ai_socktype
```
##### Message: `ActiveRecord::StatementInvalid: PG::ReadOnlySqlTransaction: ERROR: cannot execute INSERT in a read-only transaction`
When this error is encountered on a secondary site, it likely affects all usages of GitLab Rails such as `gitlab-rails` or `gitlab-rake` commands, as well the Puma, Sidekiq, and Geo Log Cursor services.
```plaintext
ActiveRecord::StatementInvalid: PG::ReadOnlySqlTransaction: ERROR: cannot execute INSERT in a read-only transaction
/opt/gitlab/embedded/service/gitlab-rails/app/models/application_record.rb:86:in `block in safe_find_or_create_by'
/opt/gitlab/embedded/service/gitlab-rails/app/models/concerns/cross_database_modification.rb:92:in `block in transaction'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database.rb:332:in `block in transaction'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database.rb:331:in `transaction'
/opt/gitlab/embedded/service/gitlab-rails/app/models/concerns/cross_database_modification.rb:83:in `transaction'
/opt/gitlab/embedded/service/gitlab-rails/app/models/application_record.rb:86:in `safe_find_or_create_by'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:21:in `by_name'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `block in populate!'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `map'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `populate!'
/opt/gitlab/embedded/service/gitlab-rails/config/initializers/fill_shards.rb:9:in `<top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/config/environment.rb:7:in `<top (required)>'
/opt/gitlab/embedded/bin/bundle:23:in `load'
/opt/gitlab/embedded/bin/bundle:23:in `<main>'
```
The PostgreSQL read-replica database would be producing these errors:
```plaintext
2023-01-17_17:44:54.64268 ERROR: cannot execute INSERT in a read-only transaction
2023-01-17_17:44:54.64271 STATEMENT: /*application:web,db_config_name:main*/ INSERT INTO "shards" ("name") VALUES ('storage1') RETURNING "id"
```
This situation can occur during initial configuration when a secondary site is not yet aware that it is a secondary site.
To resolve the error, follow [Step 3. Add the secondary site](../configuration.md#step-3-add-the-secondary-site).
### Check if PostgreSQL replication is working
To check if PostgreSQL replication is working, check if:
- [Sites are pointing to the correct database node](#are-sites-pointing-to-the-correct-database-node).
- [Geo can detect the current site correctly](#can-geo-detect-the-current-site-correctly).
If you're still having problems, see the [advanced replication troubleshooting](replication.md).
#### Are sites pointing to the correct database node?
You should make sure your **primary** Geo [site](../../glossary.md) points to
the database node that has write permissions.
Any **secondary** sites should point only to read-only database nodes.
#### Can Geo detect the current site correctly?
Geo finds the current Puma or Sidekiq node's Geo [site](../../glossary.md) name in
`/etc/gitlab/gitlab.rb` with the following logic:
1. Get the "Geo node name" (there is
[an issue to rename the settings to "Geo site name"](https://gitlab.com/gitlab-org/gitlab/-/issues/335944)):
- Linux package: get the `gitlab_rails['geo_node_name']` setting.
- GitLab Helm charts: get the `global.geo.nodeName` setting (see [Charts with GitLab Geo](https://docs.gitlab.com/charts/advanced/geo/index.html)).
1. If that is not defined, then get the `external_url` setting.
This name is used to look up the Geo site with the same **Name** in the **Geo Sites**
dashboard.
To check if the current machine has a site name that matches a site in the
database, run the check task:
```shell
sudo gitlab-rake gitlab:geo:check
```
It displays the current machine's site name and whether the matching database
record is a **primary** or **secondary** site.
```plaintext
This machine's Geo node name matches a database record ... yes, found a secondary node named "Shanghai"
```
```plaintext
This machine's Geo node name matches a database record ... no
Try fixing it:
You could add or update a Geo node database record, setting the name to "https://example.com/".
Or you could set this machine's Geo node name to match the name of an existing database record: "London", "Shanghai"
For more information see:
doc/administration/geo/replication/troubleshooting/index.md#can-geo-detect-the-current-node-correctly
```
For more information about recommended site names in the description of the Name field, see
[Geo Admin Area Common Settings](../../../../administration/geo_sites.md#common-settings).
### Check OS locale data compatibility
If different operating systems or different operating system versions are deployed across Geo sites, you **must** perform a locale data compatibility check before setting up Geo.
Geo uses PostgreSQL and Streaming Replication to replicate data across Geo sites. PostgreSQL uses locale data provided by the operating system's C library for sorting text. If the locale data in the C library is incompatible across Geo sites, it causes erroneous query results that lead to [incorrect behavior on secondary sites](https://gitlab.com/gitlab-org/gitlab/-/issues/360723).
For example, Ubuntu 18.04 (and earlier) and RHEL/Centos7 (and earlier) are incompatible with their later releases.
See the [PostgreSQL wiki for more details](https://wiki.postgresql.org/wiki/Locale_data_changes).
On all hosts running PostgreSQL, across all Geo sites, run the following shell command:
```shell
( echo "1-1"; echo "11" ) | LC_COLLATE=en_US.UTF-8 sort
```
The output looks like either:
```plaintext
1-1
11
```
or the reverse order:
```plaintext
11
1-1
```
If the output is **identical** on all hosts, then they running compatible versions of locale data and you may proceed with Geo configuration.
If the output **differs** on any hosts, PostgreSQL replication will not work properly: indexes will become corrupted on the database replicas. You **must** select operating system versions that are compatible.
A full index rebuild is required if the on-disk data is transferred 'at rest' to an operating system with an incompatible locale, or through replication.
This check is also required when using a mixture of GitLab deployments. The locale might be different between an Linux package install, a GitLab Docker container, a Helm chart deployment, or external database services.
## Fixing common errors
This section documents common error messages reported in the Admin Area on the web interface, and how to fix them.
### Geo database configuration file is missing
GitLab cannot find or doesn't have permission to access the `database_geo.yml` configuration file.
In a Linux package installation, the file should be in `/var/opt/gitlab/gitlab-rails/etc`.
If it doesn't exist or inadvertent changes have been made to it, run `sudo gitlab-ctl reconfigure` to restore it to its correct state.
If this path is mounted on a remote volume, ensure your volume configuration
has the correct permissions.
### An existing tracking database cannot be reused
Geo cannot reuse an existing tracking database.
It is safest to use a fresh secondary, or reset the whole secondary by following
[Resetting Geo secondary site replication](replication.md#resetting-geo-secondary-site-replication).
It is risky to reuse a secondary site without resetting it because the secondary site may have missed some Geo events. For example, missed deletion events lead to the secondary site permanently having data that should be deleted. Similarly, losing an event which physically moves the location of data leads to data permanently orphaned in one location, and missing in the other location until it is re-verified. This is why GitLab switched to hashed storage, since it makes moving data unnecessary. There may be other unknown problems due to lost events.
If these kinds of risks do not apply, for example in a test environment, or if you know that the main Postgres database still contains all Geo events since the Geo site was added, then you can bypass this health check:
1. Get the last processed event time. In Rails console in the secondary site, run:
```ruby
Geo::EventLogState.last.created_at.utc
```
1. Copy the output, for example `2024-02-21 23:50:50.676918 UTC`.
1. Update the created time of the secondary site to make it appear older. In Rails console in the primary site, run:
```ruby
GeoNode.secondary_nodes.last.update_column(:created_at, DateTime.parse('2024-02-21 23:50:50.676918 UTC') - 1.second)
```
This command assumes that the affected secondary site is the one that was created last.
1. Update the secondary site's status in **Admin > Geo > Sites**. In Rails console in the secondary site, run:
```ruby
Geo::MetricsUpdateWorker.new.perform
```
1. The secondary site should appear healthy. If it does not, run `gitlab-rake gitlab:geo:check` on the secondary site, or try restarting Rails if you haven't done so since re-adding the secondary site.
1. To resync missing or out-of-date data, go to **Admin > Geo > Sites**.
1. Under the secondary site select **Replication Details**.
1. Select **Reverify all** for every data type.
### Geo site has a database that is writable which is an indication it is not configured for replication with the primary site
This error message refers to a problem with the database replica on a **secondary** site,
which Geo expects to have access to. It usually means, either:
- An unsupported replication method was used (for example, logical replication).
- The instructions to set up a [Geo database replication](../../setup/database.md) were not followed correctly.
- Your database connection details are incorrect, that is you have specified the wrong
user in your `/etc/gitlab/gitlab.rb` file.
Geo **secondary** sites require two separate PostgreSQL instances:
- A read-only replica of the **primary** site.
- A regular, writable instance that holds replication metadata. That is, the Geo tracking database.
This error message indicates that the replica database in the **secondary** site is misconfigured and replication has stopped.
To restore the database and resume replication, you can do one of the following:
- [Reset the Geo secondary site replication](replication.md#resetting-geo-secondary-site-replication).
- [Set up a new Geo secondary using the Linux package](../../setup/index.md#using-linux-package-installations).
If you set up a new secondary from scratch, you must also [remove the old site from the Geo cluster](../remove_geo_site.md#removing-secondary-geo-sites).
### Geo site does not appear to be replicating the database from the primary site
The most common problems that prevent the database from replicating correctly are:
- **Secondary** sites cannot reach the **primary** site. Check credentials and
[firewall rules](../../index.md#firewall-rules).
- SSL certificate problems. Make sure you copied `/etc/gitlab/gitlab-secrets.json` from the **primary** site.
- Database storage disk is full.
- Database replication slot is misconfigured.
- Database is not using a replication slot or another alternative and cannot catch-up because WAL files were purged.
Make sure you follow the [Geo database replication](../../setup/database.md) instructions for supported configuration.
### Geo database version (...) does not match latest migration (...)
If you are using the Linux package installation, something might have failed during upgrade. You can:
- Run `sudo gitlab-ctl reconfigure`.
- Manually trigger the database migration by running: `sudo gitlab-rake db:migrate:geo` as root on the **secondary** site.
### GitLab indicates that more than 100% of repositories were synced
This can be caused by orphaned records in the project registry. They are being cleaned
periodically using a registry worker, so give it some time to fix it itself.
### Secondary site shows "Unhealthy" in UI after changing the value of `external_url` for the primary site
If you have updated the value of `external_url` in `/etc/gitlab/gitlab.rb` for the primary site or changed the protocol from `http` to `https`, you may see that secondary sites are shown as `Unhealthy`. You may also find the following error in `geo.log`:
```plaintext
"class": "Geo::NodeStatusRequestService",
...
"message": "Failed to Net::HTTP::Post to primary url: http://primary-site.gitlab.tld/api/v4/geo/status",
"error": "Failed to open TCP connection to <PRIMARY_IP_ADDRESS>:80 (Connection refused - connect(2) for \"<PRIMARY_ID_ADDRESS>\" port 80)"
```
In this case, make sure to update the changed URL on all your sites:
1. On the left sidebar, at the bottom, select **Admin Area**.
1. Select **Geo > Sites**.
1. Change the URL and save the change.
### Message: `ERROR: canceling statement due to conflict with recovery` during backup
Running a backup on a Geo **secondary** [is not supported](https://gitlab.com/gitlab-org/gitlab/-/issues/211668).
When running a backup on a **secondary** you might encounter the following error message:
```plaintext
Dumping PostgreSQL database gitlabhq_production ...
pg_dump: error: Dumping the contents of table "notes" failed: PQgetResult() failed.
pg_dump: error: Error message from server: ERROR: canceling statement due to conflict with recovery
DETAIL: User query might have needed to see row versions that must be removed.
pg_dump: error: The command was: COPY public.notes (id, note, [...], last_edited_at) TO stdout;
```
To prevent a database backup being made automatically during GitLab upgrades on your Geo **secondaries**,
create the following empty file:
```shell
sudo touch /etc/gitlab/skip-auto-backup
```

View File

@ -10,787 +10,10 @@ DETAILS:
**Tier:** Premium, Ultimate
**Offering:** Self-managed
Setting up Geo requires careful attention to details, and sometimes it's easy to
miss a step.
When working with Geo, you might encounter the following issues:
Here is a list of steps you should take to attempt to fix problem:
1. Perform [basic troubleshooting](#basic-troubleshooting).
1. Fix any [PostgreSQL database replication errors](replication.md#fixing-postgresql-database-replication-errors).
1. Fix any [common](#fixing-common-errors) errors.
1. Fix any [non-PostgreSQL replication failures](replication.md#fixing-non-postgresql-replication-failures).
## Basic troubleshooting
Before attempting more advanced troubleshooting:
- Check [the health of the Geo sites](#check-the-health-of-the-geo-sites).
- Check [if PostgreSQL replication is working](#check-if-postgresql-replication-is-working).
### Check the health of the Geo sites
On the **primary** site:
1. On the left sidebar, at the bottom, select **Admin Area**.
1. Select **Geo > Sites**.
We perform the following health checks on each **secondary** site
to help identify if something is wrong:
- Is the site running?
- Is the secondary site's database configured for streaming replication?
- Is the secondary site's tracking database configured?
- Is the secondary site's tracking database connected?
- Is the secondary site's tracking database up-to-date?
- Is the secondary site's status less than 10 minutes old?
A site shows as "Unhealthy" if the site's status is more than 10 minutes old. In that case, try running the following in the [Rails console](../../../operations/rails_console.md) on the affected secondary site:
```ruby
Geo::MetricsUpdateWorker.new.perform
```
If it raises an error, then the error is probably also preventing the jobs from completing. If it takes longer than 10 minutes, then there may be a performance issue, and the UI may always show "Unhealthy" even if the status eventually does get updated.
If it successfully updates the status, then something may be wrong with Sidekiq. Is it running? Do the logs show errors? This job is supposed to be enqueued every minute and might not run if a [job deduplication idempotency](../../../sidekiq/sidekiq_troubleshooting.md#clearing-a-sidekiq-job-deduplication-idempotency-key) key was not cleared properly. It takes an exclusive lease in Redis to ensure that only one of these jobs can run at a time. The primary site updates its status directly in the PostgreSQL database. Secondary sites send an HTTP Post request to the primary site with their status data.
A site also shows as "Unhealthy" if certain health checks fail. You can reveal the failure by running the following in the [Rails console](../../../operations/rails_console.md) on the affected secondary site:
```ruby
Gitlab::Geo::HealthCheck.new.perform_checks
```
If it returns `""` (an empty string) or `"Healthy"`, then the checks succeeded. If it returns anything else, then the message should explain what failed, or show the exception message.
For information about how to resolve common error messages reported from the user interface,
see [Fixing Common Errors](#fixing-common-errors).
If the user interface is not working, or you are unable to sign in, you can run the Geo
health check manually to get this information and a few more details.
#### Health check Rake task
> - The use of a custom NTP server was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105514) in GitLab 15.7.
This Rake task can be run on a **Rails** node in the **primary** or **secondary**
Geo sites:
```shell
sudo gitlab-rake gitlab:geo:check
```
Example output:
```plaintext
Checking Geo ...
GitLab Geo is available ... yes
GitLab Geo is enabled ... yes
This machine's Geo node name matches a database record ... yes, found a secondary node named "Shanghai"
GitLab Geo tracking database is correctly configured ... yes
Database replication enabled? ... yes
Database replication working? ... yes
GitLab Geo HTTP(S) connectivity ...
* Can connect to the primary node ... yes
HTTP/HTTPS repository cloning is enabled ... yes
Machine clock is synchronized ... yes
Git user has default SSH configuration? ... yes
OpenSSH configured to use AuthorizedKeysCommand ... yes
GitLab configured to disable writing to authorized_keys file ... yes
GitLab configured to store new projects in hashed storage? ... yes
All projects are in hashed storage? ... yes
Checking Geo ... Finished
```
You can also specify a custom NTP server using environment variables. For example:
```shell
sudo gitlab-rake gitlab:geo:check NTP_HOST="ntp.ubuntu.com" NTP_TIMEOUT="30"
```
The following environment variables are supported.
| Variable | Description | Default value |
| ----------- | ----------- | ------------- |
|`NTP_HOST` | The NTP host. | `pool.ntp.org` |
|`NTP_PORT` | The NTP port the host listens on. |`ntp`|
|`NTP_TIMEOUT`| The NTP timeout in seconds. | The value defined in the `net-ntp` Ruby library ([60 seconds](https://github.com/zencoder/net-ntp/blob/3d0990214f439a5127782e0f50faeaf2c8ca7023/lib/net/ntp/ntp.rb#L6)). |
If the Rake task skips the `OpenSSH configured to use AuthorizedKeysCommand` check, the
following output displays:
```plaintext
OpenSSH configured to use AuthorizedKeysCommand ... skipped
Reason:
Cannot access OpenSSH configuration file
Try fixing it:
This is expected if you are using SELinux. You may want to check configuration manually
For more information see:
doc/administration/operations/fast_ssh_key_lookup.md
```
This issue may occur if:
- You [use SELinux](../../../operations/fast_ssh_key_lookup.md#selinux-support-and-limitations).
- You don't use SELinux, and the `git` user cannot access the OpenSSH configuration file due to restricted file permissions.
In the latter case, the following output shows that only the `root` user can read this file:
```plaintext
sudo stat -c '%G:%U %A %a %n' /etc/ssh/sshd_config
root:root -rw------- 600 /etc/ssh/sshd_config
```
To allow the `git` user to read the OpenSSH configuration file, without changing the file owner or permissions, use `acl`:
```plaintext
sudo setfacl -m u:git:r /etc/ssh/sshd_config
```
#### Sync status Rake task
Current sync information can be found manually by running this Rake task on any
node running Rails (Puma, Sidekiq, or Geo Log Cursor) on the Geo **secondary** site.
GitLab does **not** verify objects that are stored in Object Storage. If you are using Object Storage, you will see all of the "verified" checks showing 0 successes. This is expected and not a cause for concern.
```shell
sudo gitlab-rake geo:status
```
The output includes:
- a count of "failed" items if any failures occurred
- the percentage of "succeeded" items, relative to the "total"
Example:
```plaintext
http://secondary.example.com/
-----------------------------------------------------
GitLab Version: 14.9.2-ee
Geo Role: Secondary
Health Status: Healthy
Project Repositories: succeeded 12345 / total 12345 (100%)
Project Wiki Repositories: succeeded 6789 / total 6789 (100%)
Attachments: succeeded 4 / total 4 (100%)
CI job artifacts: succeeded 0 / total 0 (0%)
Design management repositories: succeeded 1 / total 1 (100%)
LFS Objects: failed 1 / succeeded 2 / total 3 (67%)
Merge Request Diffs: succeeded 0 / total 0 (0%)
Package Files: failed 1 / succeeded 2 / total 3 (67%)
Terraform State Versions: failed 1 / succeeded 2 / total 3 (67%)
Snippet Repositories: failed 1 / succeeded 2 / total 3 (67%)
Group Wiki Repositories: succeeded 4 / total 4 (100%)
Pipeline Artifacts: failed 3 / succeeded 0 / total 3 (0%)
Pages Deployments: succeeded 0 / total 0 (0%)
Repositories Checked: failed 5 / succeeded 0 / total 5 (0%)
Package Files Verified: succeeded 0 / total 10 (0%)
Terraform State Versions Verified: succeeded 0 / total 10 (0%)
Snippet Repositories Verified: succeeded 99 / total 100 (99%)
Pipeline Artifacts Verified: succeeded 0 / total 10 (0%)
Project Repositories Verified: succeeded 12345 / total 12345 (100%)
Project Wiki Repositories Verified: succeeded 6789 / total 6789 (100%)
Sync Settings: Full
Database replication lag: 0 seconds
Last event ID seen from primary: 12345 (about 2 minutes ago)
Last event ID processed: 12345 (about 2 minutes ago)
Last status report was: 1 minute ago
```
Each item can have up to three statuses. For example, for `Project Repositories`, you see the following lines:
```plaintext
Project Repositories: succeeded 12345 / total 12345 (100%)
Project Repositories Verified: succeeded 12345 / total 12345 (100%)
Repositories Checked: failed 5 / succeeded 0 / total 5 (0%)
```
The 3 status items are defined as follows:
- The `Project Repositories` output shows how many project repositories are synced from the primary to the secondary.
- The `Project Verified Repositories` output shows how many project repositories on this secondary have a matching repository checksum with the Primary.
- The `Repositories Checked` output shows how many project repositories have passed a local Git repository check (`git fsck`) on the secondary.
To find more details about failed items, check
[the `gitlab-rails/geo.log` file](../../../logs/log_parsing.md#find-most-common-geo-sync-errors)
If you notice replication or verification failures, you can try to [resolve them](replication.md#fixing-non-postgresql-replication-failures).
If there are Repository check failures, you can try to [resolve them](synchronization.md#find-repository-check-failures-in-a-geo-secondary-site).
##### Fixing errors found when running the Geo check Rake task
When running this Rake task, you may see error messages if the nodes are not properly configured:
```shell
sudo gitlab-rake gitlab:geo:check
```
- Rails did not provide a password when connecting to the database.
```plaintext
Checking Geo ...
GitLab Geo is available ... Exception: fe_sendauth: no password supplied
GitLab Geo is enabled ... Exception: fe_sendauth: no password supplied
...
Checking Geo ... Finished
```
Ensure you have the `gitlab_rails['db_password']` set to the plain-text
password used when creating the hash for `postgresql['sql_user_password']`.
- Rails is unable to connect to the database.
```plaintext
Checking Geo ...
GitLab Geo is available ... Exception: FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
GitLab Geo is enabled ... Exception: FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
FATAL: no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
...
Checking Geo ... Finished
```
Ensure you have the IP address of the rails node included in `postgresql['md5_auth_cidr_addresses']`.
Also, ensure you have included the subnet mask on the IP address: `postgresql['md5_auth_cidr_addresses'] = ['1.1.1.1/32']`.
- Rails has supplied the incorrect password.
```plaintext
Checking Geo ...
GitLab Geo is available ... Exception: FATAL: password authentication failed for user "gitlab"
FATAL: password authentication failed for user "gitlab"
GitLab Geo is enabled ... Exception: FATAL: password authentication failed for user "gitlab"
FATAL: password authentication failed for user "gitlab"
...
Checking Geo ... Finished
```
Verify the correct password is set for `gitlab_rails['db_password']` that was
used when creating the hash in `postgresql['sql_user_password']` by running
`gitlab-ctl pg-password-md5 gitlab` and entering the password.
- Check returns `not a secondary node`.
```plaintext
Checking Geo ...
GitLab Geo is available ... yes
GitLab Geo is enabled ... yes
GitLab Geo tracking database is correctly configured ... not a secondary node
Database replication enabled? ... not a secondary node
...
Checking Geo ... Finished
```
Ensure you have added the secondary site in the Admin Area under **Geo > Sites** on the web interface for the **primary** site.
Also ensure you entered the `gitlab_rails['geo_node_name']`
when adding the secondary site in the Admin Area of the **primary** site.
In GitLab 12.3 and earlier, edit the secondary site in the Admin Area of the **primary**
site and ensure that there is a trailing `/` in the `Name` field.
- Check returns `Exception: PG::UndefinedTable: ERROR: relation "geo_nodes" does not exist`.
```plaintext
Checking Geo ...
GitLab Geo is available ... no
Try fixing it:
Add a new license that includes the GitLab Geo feature
For more information see:
https://about.gitlab.com/features/gitlab-geo/
GitLab Geo is enabled ... Exception: PG::UndefinedTable: ERROR: relation "geo_nodes" does not exist
LINE 8: WHERE a.attrelid = '"geo_nodes"'::regclass
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
c.collname, col_description(a.attrelid, a.attnum) AS comment
FROM pg_attribute a
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
LEFT JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
WHERE a.attrelid = '"geo_nodes"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
...
Checking Geo ... Finished
```
When performing a PostgreSQL major version (9 > 10), update this is expected. Follow
the [initiate-the-replication-process](../../setup/database.md#step-3-initiate-the-replication-process).
- Rails does not appear to have the configuration necessary to connect to the Geo tracking database.
```plaintext
Checking Geo ...
GitLab Geo is available ... yes
GitLab Geo is enabled ... yes
GitLab Geo tracking database is correctly configured ... no
Try fixing it:
Rails does not appear to have the configuration necessary to connect to the Geo tracking database. If the tracking database is running on a node other than this one, then you may need to add configuration.
...
Checking Geo ... Finished
```
- If you are running the secondary site on a single node for all services, then follow [Geo database replication - Configure the secondary server](../../setup/database.md#step-2-configure-the-secondary-server).
- If you are running the secondary site's tracking database on its own node, then follow [Geo for multiple servers - Configure the Geo tracking database on the Geo secondary site](../multiple_servers.md#step-2-configure-the-geo-tracking-database-on-the-geo-secondary-site)
- If you are running the secondary site's tracking database in a Patroni cluster, then follow [Geo database replication - Configuring Patroni cluster for the tracking PostgreSQL database](../../setup/database.md#configuring-patroni-cluster-for-the-tracking-postgresql-database)
- If you are running the secondary site's tracking database in an external database, then follow [Geo with external PostgreSQL instances](../../setup/external_database.md#configure-the-tracking-database)
- If the Geo check task was run on a node which is not running a service which runs the GitLab Rails app (Puma, Sidekiq, or Geo Log Cursor), then this error can be ignored. The node does not need Rails to be configured.
##### Message: Machine clock is synchronized ... Exception
The Rake task attempts to verify that the server clock is synchronized with NTP. Synchronized clocks
are required for Geo to function correctly. As an example, for security, when the server time on the
primary site and secondary site differ by about a minute or more, requests between Geo sites
fail. If this check task fails to complete due to a reason other than mismatching times, it
does not necessarily mean that Geo will not work.
The Ruby gem which performs the check is hard coded with `pool.ntp.org` as its reference time source.
- Exception message `Machine clock is synchronized ... Exception: Timeout::Error`
This issue occurs when your server cannot access the host `pool.ntp.org`.
- Exception message `Machine clock is synchronized ... Exception: No route to host - recvfrom(2)`
This issue occurs when the hostname `pool.ntp.org` resolves to a server which does not provide a time service.
In this case, in GitLab 15.7 and later, [specify a custom NTP server using environment variables](#health-check-rake-task).
In GitLab 15.6 and earlier, use one of the following workarounds:
- Add entries in `/etc/hosts` for `pool.ntp.org` to direct the request to valid local time servers.
This fixes the long timeout and the timeout error.
- Direct the check to any valid IP address. This resolves the timeout issue, but the check fails
with the `No route to host` error, as noted above.
[Cloud native GitLab deployments](https://docs.gitlab.com/charts/advanced/geo/#set-the-geo-primary-site)
generate an error because containers in Kubernetes do not have access to the host clock:
```plaintext
Machine clock is synchronized ... Exception: getaddrinfo: Servname not supported for ai_socktype
```
##### Message: `ActiveRecord::StatementInvalid: PG::ReadOnlySqlTransaction: ERROR: cannot execute INSERT in a read-only transaction`
When this error is encountered on a secondary site, it likely affects all usages of GitLab Rails such as `gitlab-rails` or `gitlab-rake` commands, as well the Puma, Sidekiq, and Geo Log Cursor services.
```plaintext
ActiveRecord::StatementInvalid: PG::ReadOnlySqlTransaction: ERROR: cannot execute INSERT in a read-only transaction
/opt/gitlab/embedded/service/gitlab-rails/app/models/application_record.rb:86:in `block in safe_find_or_create_by'
/opt/gitlab/embedded/service/gitlab-rails/app/models/concerns/cross_database_modification.rb:92:in `block in transaction'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database.rb:332:in `block in transaction'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database.rb:331:in `transaction'
/opt/gitlab/embedded/service/gitlab-rails/app/models/concerns/cross_database_modification.rb:83:in `transaction'
/opt/gitlab/embedded/service/gitlab-rails/app/models/application_record.rb:86:in `safe_find_or_create_by'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:21:in `by_name'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `block in populate!'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `map'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `populate!'
/opt/gitlab/embedded/service/gitlab-rails/config/initializers/fill_shards.rb:9:in `<top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/config/environment.rb:7:in `<top (required)>'
/opt/gitlab/embedded/bin/bundle:23:in `load'
/opt/gitlab/embedded/bin/bundle:23:in `<main>'
```
The PostgreSQL read-replica database would be producing these errors:
```plaintext
2023-01-17_17:44:54.64268 ERROR: cannot execute INSERT in a read-only transaction
2023-01-17_17:44:54.64271 STATEMENT: /*application:web,db_config_name:main*/ INSERT INTO "shards" ("name") VALUES ('storage1') RETURNING "id"
```
This situation can occur during initial configuration when a secondary site is not yet aware that it is a secondary site.
To resolve the error, follow [Step 3. Add the secondary site](../configuration.md#step-3-add-the-secondary-site).
### Check if PostgreSQL replication is working
To check if PostgreSQL replication is working, check if:
- [Sites are pointing to the correct database node](#are-sites-pointing-to-the-correct-database-node).
- [Geo can detect the current site correctly](#can-geo-detect-the-current-site-correctly).
#### Are sites pointing to the correct database node?
You should make sure your **primary** Geo [site](../../glossary.md) points to
the database node that has write permissions.
Any **secondary** sites should point only to read-only database nodes.
#### Can Geo detect the current site correctly?
Geo finds the current Puma or Sidekiq node's Geo [site](../../glossary.md) name in
`/etc/gitlab/gitlab.rb` with the following logic:
1. Get the "Geo node name" (there is
[an issue to rename the settings to "Geo site name"](https://gitlab.com/gitlab-org/gitlab/-/issues/335944)):
- Linux package: get the `gitlab_rails['geo_node_name']` setting.
- GitLab Helm charts: get the `global.geo.nodeName` setting (see [Charts with GitLab Geo](https://docs.gitlab.com/charts/advanced/geo/index.html)).
1. If that is not defined, then get the `external_url` setting.
This name is used to look up the Geo site with the same **Name** in the **Geo Sites**
dashboard.
To check if the current machine has a site name that matches a site in the
database, run the check task:
```shell
sudo gitlab-rake gitlab:geo:check
```
It displays the current machine's site name and whether the matching database
record is a **primary** or **secondary** site.
```plaintext
This machine's Geo node name matches a database record ... yes, found a secondary node named "Shanghai"
```
```plaintext
This machine's Geo node name matches a database record ... no
Try fixing it:
You could add or update a Geo node database record, setting the name to "https://example.com/".
Or you could set this machine's Geo node name to match the name of an existing database record: "London", "Shanghai"
For more information see:
doc/administration/geo/replication/troubleshooting/index.md#can-geo-detect-the-current-node-correctly
```
For more information about recommended site names in the description of the Name field, see
[Geo Admin Area Common Settings](../../../../administration/geo_sites.md#common-settings).
### Check OS locale data compatibility
If different operating systems or different operating system versions are deployed across Geo sites, you **must** perform a locale data compatibility check before setting up Geo.
Geo uses PostgreSQL and Streaming Replication to replicate data across Geo sites. PostgreSQL uses locale data provided by the operating system's C library for sorting text. If the locale data in the C library is incompatible across Geo sites, it causes erroneous query results that lead to [incorrect behavior on secondary sites](https://gitlab.com/gitlab-org/gitlab/-/issues/360723).
For example, Ubuntu 18.04 (and earlier) and RHEL/Centos7 (and earlier) are incompatible with their later releases.
See the [PostgreSQL wiki for more details](https://wiki.postgresql.org/wiki/Locale_data_changes).
On all hosts running PostgreSQL, across all Geo sites, run the following shell command:
```shell
( echo "1-1"; echo "11" ) | LC_COLLATE=en_US.UTF-8 sort
```
The output looks like either:
```plaintext
1-1
11
```
or the reverse order:
```plaintext
11
1-1
```
If the output is **identical** on all hosts, then they running compatible versions of locale data and you may proceed with Geo configuration.
If the output **differs** on any hosts, PostgreSQL replication will not work properly: indexes will become corrupted on the database replicas. You **must** select operating system versions that are compatible.
A full index rebuild is required if the on-disk data is transferred 'at rest' to an operating system with an incompatible locale, or through replication.
This check is also required when using a mixture of GitLab deployments. The locale might be different between an Linux package install, a GitLab Docker container, a Helm chart deployment, or external database services.
## Replication errors
See [replication troubleshooting](replication.md).
## Synchronization errors
See [synchronization troubleshooting](synchronization.md).
## Failover errors
See [failover troubleshooting](failover.md).
## HTTP response code errors
### Secondary site returns 502 errors with Geo proxying
When [Geo proxying for secondary sites](../../secondary_proxy/index.md) is enabled, and the secondary site user interface returns
502 errors, it is possible that the response header proxied from the primary site is too large.
Check the NGINX logs for errors similar to this example:
```plaintext
2022/01/26 00:02:13 [error] 26641#0: *829148 upstream sent too big header while reading response header from upstream, client: 10.0.2.2, server: geo.staging.gitlab.com, request: "POST /users/sign_in HTTP/2.0", upstream: "http://unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket:/users/sign_in", host: "geo.staging.gitlab.com", referrer: "https://geo.staging.gitlab.com/users/sign_in"
```
To resolve this issue:
1. Set `nginx['proxy_custom_buffer_size'] = '8k'` in `/etc/gitlab.rb` on all web nodes on the secondary site.
1. Reconfigure the **secondary** using `sudo gitlab-ctl reconfigure`.
If you still get this error, you can further increase the buffer size by repeating the steps above
and changing the `8k` size, for example by doubling it to `16k`.
### Geo Admin Area shows 'Unknown' for health status and 'Request failed with status code 401'
If using a load balancer, ensure that the load balancer's URL is set as the `external_url` in the
`/etc/gitlab/gitlab.rb` of the nodes behind the load balancer.
### Primary site returns 500 error when accessing `/admin/geo/replication/projects`
Navigating to **Admin > Geo > Replication** (or `/admin/geo/replication/projects`) on a primary Geo site, shows a 500 error, while that same link on the secondary works fine. The primary's `production.log` has a similar entry to the following:
```plaintext
Geo::TrackingBase::SecondaryNotConfigured: Geo secondary database is not configured
from ee/app/models/geo/tracking_base.rb:26:in `connection'
[..]
from ee/app/views/admin/geo/projects/_all.html.haml:1
```
On a Geo primary site this error can be ignored.
This happens because GitLab is attempting to display registries from the [Geo tracking database](../../../../administration/geo/index.md#geo-tracking-database) which doesn't exist on the primary site (only the original projects exist on the primary; no replicated projects are present, therefore no tracking database exists).
### Secondary site returns 400 error "Request header or cookie too large"
This error can happen when the internal URL of the primary site is incorrect.
For example, when you use a unified URL and the primary site's internal URL is also equal to the external URL. This causes a loop when a secondary site proxies requests to the primary site's internal URL.
To fix this issue, set the primary site's internal URL to a URL that is:
- Unique to the primary site.
- Accessible from all secondary sites.
1. Visit the primary site.
1. [Set up the internal URLs](../../../../administration/geo_sites.md#set-up-the-internal-urls).
### Secondary site returns `Received HTTP code 403 from proxy after CONNECT`
If you have installed GitLab using the Linux package (Omnibus) and have configured the `no_proxy` [custom environment variable](https://docs.gitlab.com/omnibus/settings/environment-variables.html) for Gitaly, you may experience this issue. Affected versions:
- `15.4.6`
- `15.5.0`-`15.5.6`
- `15.6.0`-`15.6.3`
- `15.7.0`-`15.7.1`
This is due to [a bug introduced in the included version of cURL](https://github.com/curl/curl/issues/10122) shipped with
the Linux package 15.4.6 and later. You should upgrade to a later version where this has been
[fixed](https://about.gitlab.com/releases/2023/01/09/security-release-gitlab-15-7-2-released/).
The bug causes all wildcard domains (`.example.com`) to be ignored except for the last on in the `no_proxy` environment variable list. Therefore, if for any reason you cannot upgrade to a newer version, you can work around the issue by moving your wildcard domain to the end of the list:
1. Edit `/etc/gitlab/gitlab.rb`:
```ruby
gitaly['env'] = {
"no_proxy" => "sever.yourdomain.org, .yourdomain.com",
}
```
1. Reconfigure GitLab:
```shell
sudo gitlab-ctl reconfigure
```
You can have only one wildcard domain in the `no_proxy` list.
### Geo Admin Area returns 404 error for a secondary site
Sometimes `sudo gitlab-rake gitlab:geo:check` indicates that **Rails nodes of the secondary** sites are
healthy, but a 404 Not Found error message for the **secondary** site is returned in the Geo Admin Area on the web interface for
the **primary** site.
To resolve this issue:
- Try restarting **each Rails, Sidekiq and Gitaly nodes on your secondary site** using `sudo gitlab-ctl restart`.
- Check `/var/log/gitlab/gitlab-rails/geo.log` on Sidekiq nodes to see if the **secondary** site is
using IPv6 to send its status to the **primary** site. If it is, add an entry to
the **primary** site using IPv4 in the `/etc/hosts` file. Alternatively, you should
[enable IPv6 on the **primary** site](https://docs.gitlab.com/omnibus/settings/nginx.html#setting-the-nginx-listen-address-or-addresses).
## Fixing common errors
This section documents common error messages reported in the Admin Area on the web interface, and how to fix them.
### Geo database configuration file is missing
GitLab cannot find or doesn't have permission to access the `database_geo.yml` configuration file.
In a Linux package installation, the file should be in `/var/opt/gitlab/gitlab-rails/etc`.
If it doesn't exist or inadvertent changes have been made to it, run `sudo gitlab-ctl reconfigure` to restore it to its correct state.
If this path is mounted on a remote volume, ensure your volume configuration
has the correct permissions.
### An existing tracking database cannot be reused
Geo cannot reuse an existing tracking database.
It is safest to use a fresh secondary, or reset the whole secondary by following
[Resetting Geo secondary site replication](replication.md#resetting-geo-secondary-site-replication).
It is risky to reuse a secondary site without resetting it because the secondary site may have missed some Geo events. For example, missed deletion events lead to the secondary site permanently having data that should be deleted. Similarly, losing an event which physically moves the location of data leads to data permanently orphaned in one location, and missing in the other location until it is re-verified. This is why GitLab switched to hashed storage, since it makes moving data unnecessary. There may be other unknown problems due to lost events.
If these kinds of risks do not apply, for example in a test environment, or if you know that the main Postgres database still contains all Geo events since the Geo site was added, then you can bypass this health check:
1. Get the last processed event time. In Rails console in the secondary site, run:
```ruby
Geo::EventLogState.last.created_at.utc
```
1. Copy the output, for example `2024-02-21 23:50:50.676918 UTC`.
1. Update the created time of the secondary site to make it appear older. In Rails console in the primary site, run:
```ruby
GeoNode.secondary_nodes.last.update_column(:created_at, DateTime.parse('2024-02-21 23:50:50.676918 UTC') - 1.second)
```
This command assumes that the affected secondary site is the one that was created last.
1. Update the secondary site's status in **Admin > Geo > Sites**. In Rails console in the secondary site, run:
```ruby
Geo::MetricsUpdateWorker.new.perform
```
1. The secondary site should appear healthy. If it does not, run `gitlab-rake gitlab:geo:check` on the secondary site, or try restarting Rails if you haven't done so since re-adding the secondary site.
1. To resync missing or out-of-date data, go to **Admin > Geo > Sites**.
1. Under the secondary site select **Replication Details**.
1. Select **Reverify all** for every data type.
### Geo site has a database that is writable which is an indication it is not configured for replication with the primary site
This error message refers to a problem with the database replica on a **secondary** site,
which Geo expects to have access to. It usually means, either:
- An unsupported replication method was used (for example, logical replication).
- The instructions to set up a [Geo database replication](../../setup/database.md) were not followed correctly.
- Your database connection details are incorrect, that is you have specified the wrong
user in your `/etc/gitlab/gitlab.rb` file.
Geo **secondary** sites require two separate PostgreSQL instances:
- A read-only replica of the **primary** site.
- A regular, writable instance that holds replication metadata. That is, the Geo tracking database.
This error message indicates that the replica database in the **secondary** site is misconfigured and replication has stopped.
To restore the database and resume replication, you can do one of the following:
- [Reset the Geo secondary site replication](replication.md#resetting-geo-secondary-site-replication).
- [Set up a new Geo secondary using the Linux package](../../setup/index.md#using-linux-package-installations).
If you set up a new secondary from scratch, you must also [remove the old site from the Geo cluster](../remove_geo_site.md#removing-secondary-geo-sites).
### Geo site does not appear to be replicating the database from the primary site
The most common problems that prevent the database from replicating correctly are:
- **Secondary** sites cannot reach the **primary** site. Check credentials and
[firewall rules](../../index.md#firewall-rules).
- SSL certificate problems. Make sure you copied `/etc/gitlab/gitlab-secrets.json` from the **primary** site.
- Database storage disk is full.
- Database replication slot is misconfigured.
- Database is not using a replication slot or another alternative and cannot catch-up because WAL files were purged.
Make sure you follow the [Geo database replication](../../setup/database.md) instructions for supported configuration.
### Geo database version (...) does not match latest migration (...)
If you are using the Linux package installation, something might have failed during upgrade. You can:
- Run `sudo gitlab-ctl reconfigure`.
- Manually trigger the database migration by running: `sudo gitlab-rake db:migrate:geo` as root on the **secondary** site.
### GitLab indicates that more than 100% of repositories were synced
This can be caused by orphaned records in the project registry. They are being cleaned
periodically using a registry worker, so give it some time to fix it itself.
### Secondary site shows "Unhealthy" in UI after changing the value of `external_url` for the primary site
If you have updated the value of `external_url` in `/etc/gitlab/gitlab.rb` for the primary site or changed the protocol from `http` to `https`, you may see that secondary sites are shown as `Unhealthy`. You may also find the following error in `geo.log`:
```plaintext
"class": "Geo::NodeStatusRequestService",
...
"message": "Failed to Net::HTTP::Post to primary url: http://primary-site.gitlab.tld/api/v4/geo/status",
"error": "Failed to open TCP connection to <PRIMARY_IP_ADDRESS>:80 (Connection refused - connect(2) for \"<PRIMARY_ID_ADDRESS>\" port 80)"
```
In this case, make sure to update the changed URL on all your sites:
1. On the left sidebar, at the bottom, select **Admin Area**.
1. Select **Geo > Sites**.
1. Change the URL and save the change.
### Message: `ERROR: canceling statement due to conflict with recovery` during backup
Running a backup on a Geo **secondary** [is not supported](https://gitlab.com/gitlab-org/gitlab/-/issues/211668).
When running a backup on a **secondary** you might encounter the following error message:
```plaintext
Dumping PostgreSQL database gitlabhq_production ...
pg_dump: error: Dumping the contents of table "notes" failed: PQgetResult() failed.
pg_dump: error: Error message from server: ERROR: canceling statement due to conflict with recovery
DETAIL: User query might have needed to see row versions that must be removed.
pg_dump: error: The command was: COPY public.notes (id, note, [...], last_edited_at) TO stdout;
```
To prevent a database backup being made automatically during GitLab upgrades on your Geo **secondaries**,
create the following empty file:
```shell
sudo touch /etc/gitlab/skip-auto-backup
```
## Fixing client errors
### Authorization errors from LFS HTTP(S) client requests
You may have problems if you're running a version of [Git LFS](https://git-lfs.com/) before 2.4.2.
As noted in [this authentication issue](https://github.com/git-lfs/git-lfs/issues/3025),
requests redirected from the secondary to the primary site do not properly send the
Authorization header. This may result in either an infinite `Authorization <-> Redirect`
loop, or Authorization error messages.
### Error: Net::ReadTimeout when pushing through SSH on a Geo secondary
When you push large repositories through SSH on a Geo secondary site, you may encounter a timeout.
This is because Rails proxies the push to the primary and has a 60 second default timeout,
[as described in this Geo issue](https://gitlab.com/gitlab-org/gitlab/-/issues/7405).
Current workarounds are:
- Push through HTTP instead, where Workhorse proxies the request to the primary (or redirects to the primary if Geo proxying is not enabled).
- Push directly to the primary.
Example log (`gitlab-shell.log`):
```plaintext
Failed to contact primary https://primary.domain.com/namespace/push_test.git\\nError: Net::ReadTimeout\",\"result\":null}" code=500 method=POST pid=5483 url="http://127.0.0.1:3000/api/v4/geo/proxy_git_push_ssh/push"
```
### Repair OAuth authorization between Geo sites
When upgrading a Geo site, you might not be able to log in into a secondary site that only uses OAuth for authentication. In that case, start a [Rails console](../../../operations/rails_console.md) session on your primary site and perform the following steps:
1. To find the affected node, first list all the Geo Nodes you have:
```ruby
GeoNode.all
```
1. Repair the affected Geo node by specifying the ID:
```ruby
GeoNode.find(<id>).repair
```
- Basic troubleshooting and [common errors](common.md)
- [Client and HTTP response code errors](client_http.md)
- [Replication errors](replication.md)
- [Synchronization errors](synchronization.md)
- [Failover errors](failover.md)

View File

@ -13,7 +13,7 @@ DETAILS:
## Fixing PostgreSQL database replication errors
The following sections outline troubleshooting steps for fixing replication error messages (indicated by `Database replication working? ... no` in the
[`geo:check` output](index.md#health-check-rake-task).
[`geo:check` output](common.md#health-check-rake-task).
The instructions present here mostly assume a single-node Geo Linux package deployment, and might need to be adapted to different environments.
### Removing an inactive replication slot
@ -206,7 +206,7 @@ The workaround is to increase the memory available to the secondary site's Postg
## Fixing non-PostgreSQL replication failures
If you notice replication failures in `Admin > Geo > Sites` or the [Sync status Rake task](index.md#sync-status-rake-task), you can try to resolve the failures with the following general steps:
If you notice replication failures in `Admin > Geo > Sites` or the [Sync status Rake task](common.md#sync-status-rake-task), you can try to resolve the failures with the following general steps:
1. Geo automatically retries failures. If the failures are new and few in number, or if you suspect the root cause is already resolved, then you can wait to see if the failures go away.
1. If failures were present for a long time, then many retries have already occurred, and the interval between automatic retries has increased to up to 4 hours depending on the type of failure. If you suspect the root cause is already resolved, you can [manually retry replication or verification](#manually-retry-replication-or-verification).

View File

@ -103,8 +103,8 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
```shell
gitlab-ctl pg-password-md5 gitlab
# Enter password: <your_password_here>
# Confirm password: <your_password_here>
# Enter password: <your_db_password_here>
# Confirm password: <your_db_password_here>
# fca0b89a972d69f00eb3ec98a5838484
```
@ -112,12 +112,12 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
```ruby
# Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab`
postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>'
# Every node that runs Puma or Sidekiq needs to have the database
# password specified as below. If you have a high-availability setup, this
# must be present in all application nodes.
gitlab_rails['db_password'] = '<your_password_here>'
gitlab_rails['db_password'] = '<your_db_password_here>'
```
1. Define a password for the database [replication user](https://wiki.postgresql.org/wiki/Streaming_Replication).
@ -130,8 +130,8 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
```shell
gitlab-ctl pg-password-md5 gitlab_replicator
# Enter password: <your_password_here>
# Confirm password: <your_password_here>
# Enter password: <your_replication_password_here>
# Confirm password: <your_replication_password_here>
# 950233c0dfc2f39c64cf30457c3b7f1e
```
@ -139,7 +139,7 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
```ruby
# Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator`
postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
```
If you are using an external database not managed by your Linux package installation, you need
@ -432,9 +432,9 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
## Database credentials password (defined previously in primary site)
## - replicate same values here as defined in primary site
##
postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
gitlab_rails['db_password'] = '<your_password_here>'
postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>'
gitlab_rails['db_password'] = '<your_db_password_here>'
```
For external PostgreSQL instances, see [additional instructions](external_database.md).
@ -557,8 +557,8 @@ On the GitLab Geo **primary** site:
```shell
sudo gitlab-ctl pg-password-md5 gitlab_replicator
# Enter password: <your_password_here>
# Confirm password: <your_password_here>
# Enter password: <your_replication_password_here>
# Confirm password: <your_replication_password_here>
# 950233c0dfc2f39c64cf30457c3b7f1e
```
@ -566,7 +566,7 @@ On the GitLab Geo **primary** site:
```ruby
# Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator`
postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
```
1. Save the file and reconfigure GitLab to change the replication user's password in PostgreSQL:
@ -598,7 +598,7 @@ On all GitLab Geo **secondary** sites:
```ruby
# Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator` on the Geo primary
postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
```
1. During the initial replication setup, the `gitlab-ctl replicate-geo-database` command writes the plaintext

View File

@ -180,7 +180,7 @@ To configure the connection to the external read-replica database and enable Log
# note this is shared between both databases,
# make sure you define the same password in both
gitlab_rails['db_password'] = '<your_password_here>'
gitlab_rails['db_password'] = '<your_primary_db_password_here>'
gitlab_rails['db_username'] = 'gitlab'
gitlab_rails['db_host'] = '<database_read_replica_host>'
@ -257,7 +257,7 @@ Configure GitLab to use this database. These steps are for Linux package and Doc
```ruby
geo_secondary['db_username'] = 'gitlab_geo'
geo_secondary['db_password'] = '<your_password_here>'
geo_secondary['db_password'] = '<your_tracking_db_password_here>'
geo_secondary['db_host'] = '<tracking_database_host>'
geo_secondary['db_port'] = <tracking_database_port> # change to the correct port

View File

@ -112,7 +112,7 @@ To configure the connection to the external read-replica database:
# note this is shared between both databases,
# make sure you define the same password in both
gitlab_rails['db_password'] = '<your_password_here>'
gitlab_rails['db_password'] = '<your_db_password_here>'
gitlab_rails['db_username'] = 'gitlab'
gitlab_rails['db_host'] = '<database_read_replica_host>'
@ -459,7 +459,7 @@ Configure GitLab to use this database. These steps are for Linux package and Doc
```ruby
geo_secondary['db_username'] = 'gitlab_geo'
geo_secondary['db_password'] = '<your_password_here>'
geo_secondary['db_password'] = '<your_tracking_db_password_here>'
geo_secondary['db_host'] = '<tracking_database_host>'
geo_secondary['db_port'] = <tracking_database_port> # change to the correct port

View File

@ -61,14 +61,19 @@ Prerequisites:
This command uses the `external_url` defined in `/etc/gitlab/gitlab.rb`.
1. Create a password for the `gitlab` database user.
1. Create a password for the `gitlab` database user and update Rail to use the new password.
NOTE:
The values configured for the `gitlab_rails['db_password']` and `postgresql['sql_user_password']` settings need to match.
However, only the `postgresql['sql_user_password']` value should be the MD5 encrypted password.
Changes to this are being discussed in [Rethink how we handle PostgreSQL passwords in cookbooks](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5713).
1. Generate a MD5 hash of the desired password:
```shell
gitlab-ctl pg-password-md5 gitlab
# Enter password: <your_password_here>
# Confirm password: <your_password_here>
# Enter password: <your_db_password_here>
# Confirm password: <your_db_password_here>
# fca0b89a972d69f00eb3ec98a5838484
```
@ -76,12 +81,12 @@ Prerequisites:
```ruby
# Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab`
postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>'
# Every node that runs Puma or Sidekiq needs to have the database
# password specified as below. If you have a high-availability setup, this
# must be present in all application nodes.
gitlab_rails['db_password'] = '<your_password_here>'
gitlab_rails['db_password'] = '<your_db_password_here>'
```
1. Define a password for the database [replication user](https://wiki.postgresql.org/wiki/Streaming_Replication).
@ -93,8 +98,8 @@ Prerequisites:
```shell
gitlab-ctl pg-password-md5 gitlab_replicator
# Enter password: <your_password_here>
# Confirm password: <your_password_here>
# Enter password: <your_replication_password_here>
# Confirm password: <your_replication_password_here>
# 950233c0dfc2f39c64cf30457c3b7f1e
```
@ -102,7 +107,7 @@ Prerequisites:
```ruby
# Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator`
postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
```
1. Optional. If you use an external database not managed by the Linux package, you must
@ -320,9 +325,9 @@ Prerequisites:
## Database credentials password (defined previously in primary site)
## - replicate same values here as defined in primary site
##
postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
gitlab_rails['db_password'] = '<your_password_here>'
postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>'
gitlab_rails['db_password'] = '<your_db_password_here>'
```
Be sure to replace the IP addresses with addresses appropriate to your network configuration.

View File

@ -229,7 +229,7 @@ for example.
#### Find most common Geo sync errors
If [the `geo:status` Rake task](../geo/replication/troubleshooting/index.md#sync-status-rake-task)
If [the `geo:status` Rake task](../geo/replication/troubleshooting/common.md#sync-status-rake-task)
repeatedly reports that some items never reach 100%,
the following command helps to focus on the most common errors.

View File

@ -130,7 +130,7 @@ The `gitlab:check` Rake task runs the following Rake tasks:
It checks that each component was set up according to the installation guide and suggest fixes
for issues found. This command must be run from your application server and doesn't work correctly on
component servers like [Gitaly](../gitaly/configure_gitaly.md#run-gitaly-on-its-own-server).
If you're running Geo, see also the [Geo Health check Rake task](../geo/replication/troubleshooting/index.md#health-check-rake-task).
If you're running Geo, see also the [Geo Health check Rake task](../geo/replication/troubleshooting/common.md#health-check-rake-task).
You may also have a look at our troubleshooting guides for:

View File

@ -313,7 +313,7 @@ PANIC: could not write to file 'pg_xlog/xlogtemp.123': No space left on device
When troubleshooting problems with Geo, you should:
- Review [common Geo errors](../geo/replication/troubleshooting/index.md#fixing-common-errors).
- Review [common Geo errors](../geo/replication/troubleshooting/common.md#fixing-common-errors).
- [Review your Geo configuration](../geo/replication/troubleshooting/index.md), including:
- Reconfiguring hosts and ports.
- Reviewing and fixing the user and password mappings.

View File

@ -92,6 +92,10 @@ Most secrets are pushed into HashiCorp Vault and various chunks of our infrastru
**What will GitLab.com Cells do:**
The provisioning secrets and shared infrastructure secrets will be managed in Hashicorp Vault, both to be used strictly for management of tenants (Amp, CI, ...).
Each cell will have their own set of unique secrets which will be managed in Google Secret Manager.
The Kubernetes secrets will be synced from Google Secret Manager by the [External Secrets operator](https://external-secrets.io/).
[Being discussed](https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/issues/25076).
### HAProxy

View File

@ -190,15 +190,11 @@ For a deeper exploration of the impact on select features, see the [list of feat
### Alignment between Organization and Fulfillment
Fulfillment is supportive of an entity above top-level groups. Their perspective is outlined in issue [#1138](https://gitlab.com/gitlab-org/fulfillment-meta/-/issues/1138).
Fulfillment enhancements for Organizations will happen in a different timeline to the [Cells](../cells/index.md) project and should not be seen as blockers to any Cells timelines.
#### Goals of Fulfillment
For Cells 1.0, Billing remains at the top-level Group. Said otherwise, Billing will not occur at the Organization level. The guidance for Cells 1.0 is for GitLab.com SaaS customers to use a single top-level Group to keep Billing consolidated.
- Fulfillment has a longstanding plan to move billing from the top-level Group to a level above. This would mean that a license applies to an Organization and all its top-level Groups.
- Fulfillment uses Zuora for billing and would like to have a 1-to-1 relationship between an Organization and their Zuora entity called BillingAccount. They want to move away from tying a license to a single top-level Group.
- If a customer needs multiple Organizations, they will need to have a separate BillingAccount per each.
- Ideally, a self-managed instance has a single Organization by default, which should be enough for most customers.
- Fulfillment prefers only one additional entity.
We are currently [evaluating future architecture designs](https://gitlab.com/gitlab-org/gitlab/-/issues/443708) (e.g. Zuora Billing Accounts being aligned to Organizations) but have yet to determine the North star direction and how/if it aligns to the Cells iterations.
### Open-source Contributions in Organizations

View File

@ -6,82 +6,189 @@ info: "To determine the technical writer assigned to the Stage/Group associated
# Contribute to built-in project templates
## Adding a new built-in project template
GitLab provides some
[built-in project templates](../user/project/index.md#create-a-project-from-a-built-in-template)
that you can use when creating a new project.
If you'd like to contribute a new built-in project template to be distributed with GitLab, do the following:
Built-in templates are sourced from the following groups:
1. Create a new public project with the project content you'd like to contribute in a namespace of your choosing. You can view a working example [here](https://gitlab.com/gitlab-org/project-templates/dotnetcore).
- [`gitlab-org/project-templates`](https://gitlab.com/gitlab-org/project-templates)
- [`pages`](https://gitlab.com/pages)
Prerequisites:
- You must have a working [GitLab Development Kit (GDK) environment](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/index.md).
In particular, PostgreSQL, Praefect, and `sshd` must be working.
- `wget` should be installed.
## Add a new built-in project template
If you'd like to contribute a new built-in project template to be distributed
with GitLab, there are a few steps to follow.
### Create the project
1. Create a new public project with the project content you'd like to contribute in a namespace of your choosing. You can view a [working example](https://gitlab.com/gitlab-org/project-templates/dotnetcore).
- Projects should be as simple as possible and free of any unnecessary assets or dependencies.
1. When the project is ready for review, create a new issue in [GitLab](https://gitlab.com/gitlab-org/gitlab/issues) with a link to your project.
1. When the project is ready for review, [create a new issue](https://gitlab.com/gitlab-org/gitlab/issues/new) with a link to your project.
- In your issue, `@` mention the relevant Backend Engineering Manager and Product Manager for the [Create:Source Code group](https://handbook.gitlab.com/handbook/product/categories/#source-code-group).
To make the project template available when creating a new project, the vendoring process will have to be completed:
### Add the logo in `gitlab-svgs`
1. Create a working template ([example](https://gitlab.com/gitlab-org/project-templates/dotnetcore))
- 2 types of built-in templates are available within GitLab:
- **Standard templates**: Available in GitLab Core, Starter and above (this is the most common type of built-in template).
- To contribute a standard template:
- Add details of the template in the `localized_templates_table` method in `gitlab/lib/gitlab/project_template.rb`,
- Add details of the template in `spec/lib/gitlab/project_template_spec.rb`, in the test for the `all` method, and
- Add details of the template in `gitlab/app/assets/javascripts/projects/default_project_templates.js`.
- See MR [!25318](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25318) for an example
- **Enterprise templates**: Introduced in GitLab 12.10, that are available only in GitLab Gold & Ultimate.
- To contribute an Enterprise template:
- Add details of the template in the `localized_ee_templates_table` method in `gitlab/ee/lib/ee/gitlab/project_template.rb`,
- Add details of the template in `gitlab/ee/spec/lib/gitlab/project_template_spec.rb`, in the `enterprise_templates` method, and
- Add details of the template in `gitlab/ee/app/assets/javascripts/projects/default_project_templates.js`.
- See MR [!28187](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28187) for an example.
All templates fetch their icons from the
[`gitlab-svgs`](https://gitlab.com/gitlab-org/gitlab-svgs) library, so if the
icon of the template you add is not present, you have to submit one.
1. Run the following in the `gitlab` project, where `$name` is the name you gave the template in `gitlab/project_template.rb`:
See how to add a [third-party logo](https://gitlab.com/gitlab-org/gitlab-svgs/-/tree/main#adding-third-party-logos-or-trademarks).
```shell
bin/rake gitlab:update_project_templates[$name]
After the logo is added to the `main` branch,
[the bot](https://gitlab.com/gitlab-org/frontend/renovate-gitlab-bot/) will pick the
new release up and create an MR in `gitlab-org/gitlab`. You can now proceed to
the next step.
### Add the template details
Two types of built-in templates are available within GitLab:
- **Standard templates**: Available in all GitLab tiers.
- **Enterprise templates**: Available only in GitLab Premium and Ultimate.
To make the project template available when creating a new project, you must
follow the vendoring process to create a working template.
#### Standard template
NOTE:
See merge request [25318](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25318) for an example.
To contribute a standard template:
1. Add the details of the template in the `localized_templates_table` method in [`lib/gitlab/project_template.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/project_template.rb) using the following scheme:
```ruby
ProjectTemplate.new('<template_name>', '<template_short_description>', _('<template_long_description>'), '<template_project_link>', 'illustrations/logos/<template_logo_name>.svg'),
```
1. Add the details of the template in [`app/assets/javascripts/projects/default_project_templates.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/projects/default_project_templates.js).
#### Enterprise template
NOTE:
See merge request [28187](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28187) for an example.
To contribute an Enterprise template:
1. Add details of the template in the `localized_ee_templates_table` method in [`ee/lib/ee/gitlab/project_template.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/ee/gitlab/project_template.rb) using the following scheme:
```ruby
ProjectTemplate.new('<template_name>', '<template_short_description>', _('<template_long_description>'), '<template_project_link>', 'illustrations/logos/<template_logo_name>.svg'),
```
1. Add the template name in the list of `let(:enterprise_templates)` in [`ee/spec/lib/gitlab/project_template_spec.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/spec/lib/gitlab/project_template_spec.rb).
1. Add details of the template in [`ee/app/assets/javascripts/projects/default_project_templates.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/assets/javascripts/projects/default_project_templates.js).
### Populate the template details
1. Start GDK:
```shell
gdk start
```
1. Run the following in the `gitlab` project, where `<template_name>` is the name you
gave the template in `gitlab/project_template.rb`:
```shell
bin/rake "gitlab:update_project_templates[<template_name>]"
```
1. Regenerate the localization file in the `gitlab` project and commit the new `.pot` file:
```shell
bin/rake gettext:regenerate
```
1. Run the `bundle_repo` script. Make sure to pass the correct arguments, or the script may damage the folder structure.
1. Add exported project (`$name.tar.gz`) to `gitlab/vendor/project_templates` and remove the resulting build folders `tar-base` and `project`.
1. Run `tooling/bin/gettext_extractor locale/gitlab.pot` in the `gitlab` project and commit new `.pot` file.
1. Add a changelog entry in the commit message (for example, `Changelog: added`).
For more information, see [Changelog entries](changelog.md).
1. Add an icon to [`gitlab-svgs`](https://gitlab.com/gitlab-org/gitlab-svgs), as shown in
[this example](https://gitlab.com/gitlab-org/gitlab-svgs/merge_requests/195). If a logo
is not available for the project, use the default 'Tanuki' logo instead.
1. Run `yarn run svgs` on `gitlab-svgs` project and commit result.
1. Forward changes in `gitlab-svgs` project to the `main` branch. This involves:
- Merging your MR in `gitlab-svgs`
- [The bot](https://gitlab.com/gitlab-org/frontend/renovate-gitlab-bot/)
will pick the new release up and create an MR in `gitlab-org/gitlab`.
1. After the bot-created MR created above is merged, you can rebase your template MR onto the updated `master` to pick up the new SVGs.
1. Test everything is working.
### Contributing an improvement to an existing template
## Update an existing built-in project template
Existing templates are available in the [project-templates](https://gitlab.com/gitlab-org/project-templates)
group.
To contribute a change:
To contribute a change, open a merge request in the relevant project
and mention `@gitlab-org/manage/import/backend` when you are ready for a review.
1. Open a merge request in the relevant project, and leave the following comment
when you are ready for a review:
Then, if your merge request gets accepted, either open an issue on
`gitlab` to ask for it to get updated, or open a merge request updating
the vendored template using [these instructions](rake_tasks.md#update-project-templates).
```plaintext
@gitlab-org/manage/import/backend this is a contribution to update the project
template and is ready for review!
### Test your built-in project with the GitLab Development Kit
@gitlab-bot ready
```
Complete the following steps to test the project template in your own GitLab Development Kit instance:
1. If your merge request gets accepted:
1. Run the following Rake task, where `<path>/<name>` is the
name you gave the template in `lib/gitlab/project_template.rb`:
- Either [open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new)
to ask for it to get updated.
- Or update the vendored template and open a merge request:
```shell
bin/rake "gitlab:update_project_templates[<template_name>]"
```
## Test your built-in project with the GitLab Development Kit
Complete the following steps to test the project template in your own
GDK instance:
1. Start GDK:
```shell
bin/rake gitlab:update_project_templates\[<path>/<name>\]
gdk start
```
1. Run the following Rake task, where `<template_name>` is the
name of the template in `lib/gitlab/project_template.rb`:
```shell
bin/rake "gitlab:update_project_templates[<template_name>]"
```
1. Visit GitLab in your browser and create a new project by selecting the
project template.
## For GitLab team members
Ensure the merge request has been reviewed by the Security Counterpart before merging.
Ensure all merge requests have been reviewed by the Security counterpart before merging.
To review a merge request which changes a vendored project template, run the `check-template-changes` script:
### Update all templates
Starting a project from a template needs this project to be exported. On a
up to date default branch run:
```shell
gdk start # postgres, praefect, and sshd are required
bin/rake gitlab:update_project_templates
git checkout -b update-project-templates
git add vendor/project_templates
git commit
git push -u origin update-project-templates
```
Now create a merge request and assign to a Security counterpart to merge.
### Update a single template
To update just a single template instead of all of them, specify the template name
between square brackets. For example, for the `jekyll` template, run:
```shell
bin/rake "gitlab:update_project_templates[jekyll]"
```
### Review a template merge request
To review a merge request which changes one or more vendored project templates,
run the `check-template-changes` script:
```shell
scripts/check-template-changes vendor/project_templates/<template_name>.tar.gz

View File

@ -401,26 +401,7 @@ task, then check the dimensions of the new sprite sheet and update the
## Update project templates
Starting a project from a template needs this project to be exported. On a
up to date main branch run:
```shell
gdk start
bundle exec rake gitlab:update_project_templates
git checkout -b update-project-templates
git add vendor/project_templates
git commit
git push -u origin update-project-templates
```
Now create a merge request and merge that to main.
To update just a single template instead of all of them, specify the template name
between square brackets. For example, for the `cluster_management` template, run:
```shell
bundle exec rake gitlab:update_project_templates\[cluster_management\]
```
See [contributing to project templates for GitLab team members](project_templates.md#for-gitlab-team-members).
## Generate route lists

View File

@ -132,7 +132,7 @@ It is recommended to review the [full requirements for running Geo](../administr
Changes to locale data in `glibc` means that PostgreSQL database files are not fully compatible
between different OS releases.
To avoid index corruption, [check for locale compatibility](../administration/geo/replication/troubleshooting/index.md#check-os-locale-data-compatibility)
To avoid index corruption, [check for locale compatibility](../administration/geo/replication/troubleshooting/common.md#check-os-locale-data-compatibility)
when:
- Moving binary PostgreSQL data between servers.

View File

@ -20,26 +20,18 @@ Sign in to DingTalk Open Platform and create an application on it. DingTalk gene
1. On the top bar, select **Application development > Enterprise internal development** and then select **Create Application**.
![DingTalk menu](img/ding_talk_menu.png)
1. Fill in the application details:
- **Application Name**: This can be anything. Consider something like `<Organization>'s GitLab`, `<Your Name>'s GitLab`, or something else descriptive.
- **Application Description**: Create a description.
- **Application icon**: Upload qualified icons if needed.
![DingTalk create application](img/ding_talk_create_application.png)
1. Select **Confirm and create**.
1. On the left sidebar, select **DingTalk Application** and find your application. Select it and go to the application information page.
![DingTalk your application](img/ding_talk_your_application.png)
1. In the **Application Credentials** section, note the **AppKey** and **AppSecret** as you use these values later.
![DingTalk credentials](img/ding_talk_credentials.png)
1. On your GitLab server, open the configuration file.
For Linux package installations:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

View File

@ -215,9 +215,9 @@ For more information, see [Enable or disable service ping](../../administration/
In GitLab 15.4 and 15.5, Gitaly Cluster assumes `pool.ntp.org` is accessible. If `pool.ntp.org` is not accessible, [customize the time server setting](../../administration/gitaly/praefect.md#customize-time-server-setting) on the Gitaly
and Praefect servers so they can use an accessible NTP server.
On offline instances, the [GitLab Geo check Rake task](../../administration/geo/replication/troubleshooting/index.md#can-geo-detect-the-current-site-correctly)
On offline instances, the [GitLab Geo check Rake task](../../administration/geo/replication/troubleshooting/common.md#can-geo-detect-the-current-site-correctly)
always fails because it uses `pool.ntp.org`. This error can be ignored but you can
[read more about how to work around it](../../administration/geo/replication/troubleshooting/index.md#message-machine-clock-is-synchronized--exception).
[read more about how to work around it](../../administration/geo/replication/troubleshooting/common.md#message-machine-clock-is-synchronized--exception).
## Enabling the Package Metadata Database

View File

@ -620,7 +620,7 @@ DETAILS:
## 15.4.6
- Due to a [bug introduced in curl in GitLab 15.4.6](https://github.com/curl/curl/issues/10122), the [`no_proxy` environment variable may not work properly](../../administration/geo/replication/troubleshooting/index.md#secondary-site-returns-received-http-code-403-from-proxy-after-connect). Either downgrade to GitLab 15.4.5, or upgrade to GitLab 15.5.7 or a later version.
- Due to a [bug introduced in curl in GitLab 15.4.6](https://github.com/curl/curl/issues/10122), the [`no_proxy` environment variable may not work properly](../../administration/geo/replication/troubleshooting/client_http.md#secondary-site-returns-received-http-code-403-from-proxy-after-connect). Either downgrade to GitLab 15.4.5, or upgrade to GitLab 15.5.7 or a later version.
- Due to [a bug introduced in GitLab 15.4](https://gitlab.com/gitlab-org/gitlab/-/issues/390155), if one or more Git repositories in Gitaly Cluster is [unavailable](../../administration/gitaly/recovery.md#unavailable-repositories), then [Repository checks](../../administration/repository_checks.md#repository-checks) and [Geo replication and verification](../../administration/geo/index.md) stop running for all project or project wiki repositories in the affected Gitaly Cluster. The bug was fixed by [reverting the change in GitLab 15.9.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110823). Before upgrading to this version, check if you have any "unavailable" repositories. See [the bug issue](https://gitlab.com/gitlab-org/gitlab/-/issues/390155) for more information.
## 15.4.5

View File

@ -11,8 +11,8 @@ DETAILS:
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
The following troubleshooting scenarios have been collected from customer support cases. If you
experience a problem not addressed here, or the information here does not fix your problem, create a
support ticket. For more details, see the [GitLab Support](https://about.gitlab.com/support/) page.
experience a problem not addressed here, or the information here does not fix your problem, see the
[GitLab Support](https://about.gitlab.com/support/) page for ways to get help.
## Debugging DAST jobs

View File

@ -4,7 +4,7 @@ group: Security Policies
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Merge request approval policies (Previously: Scan result policies)
# Merge request approval policies
DETAILS:
**Tier:** Ultimate

View File

@ -11,8 +11,8 @@ DETAILS:
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
The following troubleshooting scenarios have been collected from customer support cases. If you
experience a problem not addressed here, or the information here does not fix your problem, create a
support ticket. For more details, see the [GitLab Support](https://about.gitlab.com/support/) page.
experience a problem not addressed here, or the information here does not fix your problem, see the
[GitLab Support](https://about.gitlab.com/support/) page for ways to get help.
## Debug-level logging

View File

@ -75,3 +75,26 @@ To delete a compliance framework from the compliance frameworks report:
1. On the page, select the **Frameworks** tab.
1. Hover over framework and select **Edit the framework**.
1. Select the **Delete framework** to delete compliance framework.
## Export a report of compliance frameworks in a group
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/413736) in GitLab 16.11 [with a flag](../../../administration/feature_flags.md) named `compliance_frameworks_report_csv_export`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../../../administration/feature_flags.md)
named `compliance_frameworks_report_csv_export`. On GitLab.com, this feature is not available. The feature is not ready for production use.
Exports the contents of a compliance frameworks report in a group. Reports are truncated at 15 MB to avoid a large email attachment.
Prerequisites:
- You must be an administrator or have the Owner role for the group.
To export the standards adherence report for projects in a group:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Secure > Compliance center**.
1. In the top-right corner, select **Export**.
1. Select **Export framework report**.
A report is compiled and delivered to your email inbox as an attachment.

View File

@ -15,6 +15,10 @@ module Gitlab
# )
# ```
class Keep
def initialize(logger: nil)
@logger = logger || Logger.new(nil)
end
# The each_change method must update local working copy files and yield a Change object which describes the
# specific changed files and other data that will be used to generate a merge request. This is the core
# implementation details for a specific housekeeper keep. This does not need to commit the changes or create the

View File

@ -9,13 +9,15 @@ module Gitlab
LIMIT_FIXES = 20
RUBOCOP_TODO_DIR_PATTERN = ".rubocop_todo/**/*.yml"
def initialize(todo_dir_pattern: RUBOCOP_TODO_DIR_PATTERN, limit_fixes: LIMIT_FIXES)
def initialize(logger: nil, todo_dir_pattern: RUBOCOP_TODO_DIR_PATTERN, limit_fixes: LIMIT_FIXES)
super(logger: logger)
@todo_dir_pattern = todo_dir_pattern
@limit_fixes = limit_fixes
end
def each_change
each_allowed_rubocop_rule do |rule, rule_file_path, violating_files|
@logger.puts "RubopCop rule #{rule}"
remove_allow_rule = true
if violating_files.count > @limit_fixes
@ -41,6 +43,7 @@ module Gitlab
begin
::Gitlab::Housekeeper::Shell.execute('rubocop', '--autocorrect', *violating_files)
rescue ::Gitlab::Housekeeper::Shell::Error
@logger.warn "Failed to autocorrect files. Reverting"
# Ignore when it cannot be automatically fixed. But we need to checkout any files we might have updated.
::Gitlab::Housekeeper::Shell.execute('git', 'checkout', rule_file_path, *violating_files)
next

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
module Gitlab
module Housekeeper
class Logger < ::Logger
def initialize(...)
super
self.formatter = Formatter.new
end
def puts(*args)
args = [nil] if args.empty?
args.each { |arg| self << "#{arg}\n" }
end
class Formatter < ::Logger::Formatter
def call(severity, _time, _progname, msg)
format("%s: %s\n", severity, msg2str(msg))
end
end
end
end
end

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'active_support/core_ext/string'
require 'gitlab/housekeeper/logger'
require 'gitlab/housekeeper/keep'
require 'gitlab/housekeeper/keeps/rubocop_fixer'
require 'gitlab/housekeeper/gitlab_client'
@ -34,10 +35,11 @@ module Gitlab
git.with_clean_state do
@keeps.each do |keep_class|
keep = keep_class.new
@logger.puts "Running keep #{keep_class}"
keep = keep_class.new(logger: @logger)
keep.each_change do |change|
unless change.valid?
puts "Ignoring invalid change from: #{keep_class}"
@logger.warn "Ignoring invalid change from: #{keep_class}"
next
end
@ -56,9 +58,10 @@ module Gitlab
git.create_commit(change)
end
puts "Skipping change: #{change.identifiers} due to not matching filter."
puts "Modified files have been committed to branch #{branch_name.yellowish}, but will not be pushed."
puts
@logger.puts "Skipping change: #{change.identifiers} due to not matching filter."
@logger.puts "Modified files have been committed to branch #{branch_name.yellowish}," \
"but will not be pushed."
@logger.puts
next
end
@ -99,8 +102,8 @@ module Gitlab
"Housekeeper created #{mr_count_string}."
end
puts completion_message.yellowish
puts
@logger.puts completion_message.yellowish
@logger.puts
end
def add_standard_change_data(change)
@ -122,28 +125,28 @@ module Gitlab
base_message = "Merge request URL: #{change.mr_web_url || '(known after create)'}, on branch #{branch_name}."
base_message << " CI skipped." if change.push_options.ci_skip
puts base_message.yellowish
puts "=> #{change.identifiers.join(': ')}".purple
@logger.puts base_message.yellowish
@logger.puts "=> #{change.identifiers.join(': ')}".purple
puts '=> Title:'.purple
puts change.title.purple
puts
@logger.puts '=> Title:'.purple
@logger.puts change.title.purple
@logger.puts
puts '=> Description:'
puts change.description
puts
@logger.puts '=> Description:'
@logger.puts change.description
@logger.puts
if change.labels.present? || change.reviewers.present?
puts '=> Attributes:'
puts "Labels: #{change.labels.join(', ')}"
puts "Reviewers: #{change.reviewers.join(', ')}"
puts
@logger.puts '=> Attributes:'
@logger.puts "Labels: #{change.labels.join(', ')}"
@logger.puts "Reviewers: #{change.reviewers.join(', ')}"
@logger.puts
end
puts '=> Diff:'
puts Shell.execute('git', '--no-pager', 'diff', '--color=always', @target_branch, branch_name, '--',
@logger.puts '=> Diff:'
@logger.puts Shell.execute('git', '--no-pager', 'diff', '--color=always', @target_branch, branch_name, '--',
*change.changed_files)
puts
@logger.puts
end
def create(change, branch_name)

View File

@ -0,0 +1,55 @@
# frozen_string_literal: true
require 'spec_helper'
require 'stringio'
require 'gitlab/housekeeper/logger'
RSpec.describe ::Gitlab::Housekeeper::Logger do
let(:output) { StringIO.new }
let(:logged) { output.string }
subject(:logger) { described_class.new(output) }
describe 'formatting' do
it 'only prints severity and message' do
logger.info
logger.debug 42
logger.error RuntimeError.new('test')
logger.warn :hello
expect(logged).to eq(<<~OUTPUT)
INFO: nil
DEBUG: 42
ERROR: test (RuntimeError)
WARN: :hello
OUTPUT
end
end
describe '#puts' do
it 'mimics Kernel#puts and logs without any tags' do
logger.puts
logger.puts :hello
logger.puts "world"
expect(logged).to eq(<<~OUTPUT)
hello
world
OUTPUT
end
end
%i[debug info warn error fatal].each do |severity|
describe "##{severity}" do
it 'tags message with severity only' do
tag = severity.to_s.upcase
logger.public_send(severity, :hello)
expect(logged).to eq("#{tag}: :hello\n")
end
end
end
end

View File

@ -40,7 +40,7 @@ module Keeps
def prepare_change(feature_flag)
if feature_flag.milestone.nil?
puts "#{feature_flag.name} has no milestone set!"
@logger.puts "#{feature_flag.name} has no milestone set!"
return
end

View File

@ -25,8 +25,6 @@ module Keeps
class OverdueFinalizeBackgroundMigration < ::Gitlab::Housekeeper::Keep
CUTOFF_MILESTONE = '16.8' # Only finalize migrations added before this
def initialize; end
def each_change
each_batched_background_migration do |migration_yaml_file, migration|
next unless before_cuttoff_milestone?(migration['milestone'])

View File

@ -15,7 +15,7 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
expose :release, using: Entities::TagRelease, if: ->(*) { can_read_release? } do |repo_tag, options|
options[:project].releases.find_by(tag: repo_tag.name)
options[:releases]&.find { |r| r.tag == repo_tag.name }
end
# rubocop: enable CodeReuse/ActiveRecord

View File

@ -20,6 +20,7 @@ module API
optional :subgroup_creation_level, type: String, values: ::Gitlab::Access.subgroup_creation_string_values, desc: 'Allowed to create subgroups', as: :subgroup_creation_level_str
optional :emails_disabled, type: Boolean, desc: '_(Deprecated)_ Disable email notifications. Use: emails_enabled'
optional :emails_enabled, type: Boolean, desc: 'Enable email notifications'
optional :show_diff_preview_in_email, type: Boolean, desc: 'Include the code diff preview in merge request notification emails'
optional :mentions_disabled, type: Boolean, desc: 'Disable a group from getting mentioned'
optional :lfs_enabled, type: Boolean, desc: 'Enable/disable LFS for the projects in this group'
optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access'

View File

@ -12,6 +12,14 @@ module API
not_found! unless user_project.repo_exists?
end
helpers do
def find_releases(tags)
tag_names = [tags].flatten.map(&:name)
user_project.releases.by_tag(tag_names)
end
end
params do
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end
@ -48,6 +56,7 @@ module API
present_cached paginated_tags,
with: Entities::Tag,
project: user_project,
releases: find_releases(paginated_tags),
current_user: current_user,
cache_context: -> (_tag) do
[user_project.cache_key, can?(current_user, :read_release, user_project)].join(':')
@ -74,7 +83,7 @@ module API
tag = user_project.repository.find_tag(params[:tag_name])
not_found!('Tag') unless tag
present tag, with: Entities::Tag, project: user_project, current_user: current_user
present tag, with: Entities::Tag, project: user_project, releases: find_releases(tag), current_user: current_user
end
desc 'Create a new repository tag' do
@ -100,7 +109,8 @@ module API
if result[:status] == :success
present result[:tag],
with: Entities::Tag,
project: user_project
project: user_project,
releases: find_releases(result[:tag])
else
render_api_error!(result[:message], 400)
end

View File

@ -21,7 +21,10 @@ module Sidebars
override :render?
def render?
!!context.current_user && !Gitlab::CurrentSettings.personal_access_tokens_disabled?
return false unless context.current_user
return false if Gitlab::CurrentSettings.personal_access_tokens_disabled?
true
end
override :active_routes
@ -37,3 +40,5 @@ module Sidebars
end
end
end
Sidebars::UserSettings::Menus::AccessTokensMenu.prepend_mod

View File

@ -4018,6 +4018,12 @@ msgstr ""
msgid "AdminUsers|(Pending approval)"
msgstr ""
msgid "AdminUsers|2FA Disabled"
msgstr ""
msgid "AdminUsers|2FA Enabled"
msgstr ""
msgid "AdminUsers|A user can validate themselves by inputting a credit/debit card, or an admin can manually validate a user. Validated users can use free CI minutes on instance runners."
msgstr ""
@ -4039,6 +4045,9 @@ msgstr ""
msgid "AdminUsers|Activate user %{username}?"
msgstr ""
msgid "AdminUsers|Active"
msgstr ""
msgid "AdminUsers|Adjust the user cap setting on your instance"
msgstr ""
@ -4048,6 +4057,9 @@ msgstr ""
msgid "AdminUsers|Administrator"
msgstr ""
msgid "AdminUsers|Admins"
msgstr ""
msgid "AdminUsers|An error occurred while fetching this user's contributions, and the request cannot return the number of issues, merge requests, groups, and projects linked to this user. If you proceed with deleting the user, all their contributions will still be deleted."
msgstr ""
@ -4252,6 +4264,9 @@ msgstr ""
msgid "AdminUsers|Search by name, email, or username"
msgstr ""
msgid "AdminUsers|Search users"
msgstr ""
msgid "AdminUsers|Send email to users"
msgstr ""
@ -4306,9 +4321,6 @@ msgstr ""
msgid "AdminUsers|Trusted"
msgstr ""
msgid "AdminUsers|Two-factor authentication"
msgstr ""
msgid "AdminUsers|Unban user"
msgstr ""
@ -12956,6 +12968,9 @@ msgstr ""
msgid "Compliance Center Export|Example: 2dc6aa3"
msgstr ""
msgid "Compliance Center Export|Export a list of compliance frameworks for a project as a CSV file."
msgstr ""
msgid "Compliance Center Export|Export chain of custody report"
msgstr ""
@ -12965,6 +12980,9 @@ msgstr ""
msgid "Compliance Center Export|Export chain of custody report of a specific commit as a CSV file (limited to 15MB)."
msgstr ""
msgid "Compliance Center Export|Export contents of the compliance frameworks report as a CSV file."
msgstr ""
msgid "Compliance Center Export|Export contents of the standards adherence report as a CSV file."
msgstr ""
@ -12974,10 +12992,10 @@ msgstr ""
msgid "Compliance Center Export|Export custody report of a specific commit"
msgstr ""
msgid "Compliance Center Export|Export list of project frameworks"
msgid "Compliance Center Export|Export frameworks report"
msgstr ""
msgid "Compliance Center Export|Export list of project frameworks as a CSV file."
msgid "Compliance Center Export|Export list of project frameworks"
msgstr ""
msgid "Compliance Center Export|Export merge request violations as a CSV file."
@ -13028,6 +13046,9 @@ msgstr ""
msgid "ComplianceFrameworksReport|Edit framework"
msgstr ""
msgid "ComplianceFrameworksReport|Policies"
msgstr ""
msgid "ComplianceFrameworks| Frameworks export"
msgstr ""
@ -19296,6 +19317,9 @@ msgstr ""
msgid "Email notification for unknown sign-ins"
msgstr ""
msgid "Email notifications"
msgstr ""
msgid "Email patch"
msgstr ""
@ -19920,6 +19944,9 @@ msgstr ""
msgid "Environments|HelmReleases"
msgstr ""
msgid "Environments|How do I grant Kubernetes access?"
msgstr ""
msgid "Environments|Job"
msgstr ""
@ -19995,6 +20022,9 @@ msgstr ""
msgid "Environments|Select agent"
msgstr ""
msgid "Environments|Select an agent with Kubernetes access to the project or group."
msgstr ""
msgid "Environments|Select namespace"
msgstr ""
@ -24782,9 +24812,15 @@ msgstr ""
msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group"
msgstr ""
msgid "GroupSettings|Disable personal access tokens"
msgstr ""
msgid "GroupSettings|Duo features"
msgstr ""
msgid "GroupSettings|Emails are not encrypted. Concerned administrators may want to disable diff previews."
msgstr ""
msgid "GroupSettings|Enable GitLab Duo features for this group %{link_start}Learn more%{link_end}."
msgstr ""
@ -24830,6 +24866,9 @@ msgstr ""
msgid "GroupSettings|How do I manage group SSH certificates?"
msgstr ""
msgid "GroupSettings|If enabled, enterprise user accounts will not be able to use personal access tokens."
msgstr ""
msgid "GroupSettings|If enabled, individual user accounts will be able to use only issued SSH certificates for Git access. It doesn't apply to service accounts, deploy keys, and other types of internal accounts."
msgstr ""
@ -24839,6 +24878,9 @@ msgstr ""
msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|Include diff previews"
msgstr ""
msgid "GroupSettings|Members cannot invite groups outside of %{group} and its subgroups"
msgstr ""
@ -36858,6 +36900,9 @@ msgstr ""
msgid "Personal access token"
msgstr ""
msgid "Personal access tokens"
msgstr ""
msgid "Personal projects"
msgstr ""
@ -40023,6 +40068,12 @@ msgstr ""
msgid "ProjectSettings|Do not allow"
msgstr ""
msgid "ProjectSettings|Email notifications"
msgstr ""
msgid "ProjectSettings|Emails are not encrypted. Concerned administrators may want to disable diff previews."
msgstr ""
msgid "ProjectSettings|Enable \"Delete source branch\" option by default"
msgstr ""
@ -40110,6 +40161,9 @@ msgstr ""
msgid "ProjectSettings|If merge trains are enabled, merging is only possible if the branch can be rebased without conflicts."
msgstr ""
msgid "ProjectSettings|Include diff previews"
msgstr ""
msgid "ProjectSettings|Infrastructure"
msgstr ""
@ -49434,9 +49488,6 @@ msgstr ""
msgid "Starts: %{startsAt}"
msgstr ""
msgid "State"
msgstr ""
msgid "State your message to activate"
msgstr ""
@ -52623,6 +52674,9 @@ msgstr ""
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not include diff previews in email notifications."
msgstr ""
msgid "This project has no active access tokens."
msgstr ""

View File

@ -62,7 +62,7 @@
"@gitlab/cluster-client": "^2.1.0",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/fonts": "^1.3.0",
"@gitlab/svgs": "3.95.0",
"@gitlab/svgs": "3.96.0",
"@gitlab/ui": "78.12.0",
"@gitlab/visual-review-tools": "1.7.3",
"@gitlab/web-ide": "^0.0.1-dev-20240411155529",

View File

@ -6,16 +6,21 @@ module QA
module Overview
module Users
class Index < QA::Page::Base
view 'app/views/admin/users/_users.html.haml' do
element 'user-search-field'
element 'pending-approval-tab'
end
view 'app/assets/javascripts/vue_shared/components/users_table/users_table.vue' do
element 'user-row-content'
end
def search_user(username)
submit_search_term(username)
find_element('user-search-field').set(username).send_keys(:return)
end
def choose_pending_approval_filter
select_tokens('state', '=', 'Pending approval', submit: true)
def click_pending_approval_tab
click_element 'pending-approval-tab'
end
def click_user(username)

View File

@ -23,7 +23,6 @@ module QA
end
base.view 'app/assets/javascripts/notes/components/discussion_actions.vue' do
element 'discussion-reply-tab'
element 'resolve-discussion-button'
end
@ -36,6 +35,10 @@ module QA
element 'discussion-filter-container'
end
base.view 'app/assets/javascripts/notes/components/discussion_reply_placeholder.vue' do
element 'discussion-reply-tab'
end
base.view 'app/assets/javascripts/notes/components/noteable_discussion.vue' do
element 'discussion-content'
end

View File

@ -1,7 +1,5 @@
# frozen_string_literal: true
require 'spec_helper'
module QA
RSpec.shared_examples 'registration and login' do
it 'allows the user to register and login' do
@ -159,7 +157,7 @@ module QA
Page::Main::Menu.perform(&:go_to_admin_area)
Page::Admin::Menu.perform(&:go_to_users_overview)
Page::Admin::Overview::Users::Index.perform do |index|
index.choose_pending_approval_filter
index.click_pending_approval_tab
index.search_user(user.username)
index.click_user(user.name)
end

View File

@ -24,6 +24,7 @@ module QA
tags_for_rspec = []
return tags_for_rspec if Runtime::Scenario.attributes[:test_metadata_only]
return tags_for_rspec if Runtime::Env.rspec_retried?
if tags.any?
tags.each { |tag| tags_for_rspec.push(['--tag', tag.to_s]) }

View File

@ -112,7 +112,6 @@ RSpec.describe Import::BitbucketServerController, feature_category: :importers d
let(:token) { 'token' }
let(:username) { 'bitbucket-user' }
let(:url) { 'http://localhost:7990/bitbucket' }
let(:experiment) { instance_double(ApplicationExperiment) }
it 'clears out existing session' do
post :configure
@ -125,17 +124,6 @@ RSpec.describe Import::BitbucketServerController, feature_category: :importers d
expect(response).to redirect_to(status_import_bitbucket_server_path)
end
it 'tracks default_to_import_tab experiment' do
allow(controller)
.to receive(:experiment)
.with(:default_to_import_tab, actor: user)
.and_return(experiment)
expect(experiment).to receive(:track).with(:authentication, property: :bitbucket_server)
post :configure
end
it 'sets the session variables' do
allow(controller).to receive(:allow_local_requests?).and_return(true)

View File

@ -17,7 +17,6 @@ RSpec.describe Import::FogbugzController, feature_category: :importers do
end
describe 'POST #callback' do
let(:experiment) { instance_double(ApplicationExperiment) }
let(:xml_response) { %(<?xml version=\"1.0\" encoding=\"UTF-8\"?><response><token><![CDATA[#{token}]]></token></response>) }
before do
@ -32,17 +31,6 @@ RSpec.describe Import::FogbugzController, feature_category: :importers do
expect(response).to redirect_to(new_user_map_import_fogbugz_path)
end
it 'tracks default_to_import_tab experiment' do
allow(controller)
.to receive(:experiment)
.with(:default_to_import_tab, actor: user)
.and_return(experiment)
expect(experiment).to receive(:track).with(:successfully_authenticated, property: :fogbugz)
post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword' }
end
it 'preserves namespace_id query param on success' do
post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword', namespace_id: namespace_id }
@ -68,17 +56,6 @@ RSpec.describe Import::FogbugzController, feature_category: :importers do
expect(response).to redirect_to(new_import_fogbugz_url)
end
it 'does not track default_to_import_tab experiment when client raises authentication exception' do
allow(controller)
.to receive(:experiment)
.with(:default_to_import_tab, actor: user)
.and_return(experiment)
expect(experiment).not_to receive(:track)
post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword' }
end
end
context 'verify url' do

Some files were not shown because too many files have changed in this diff Show More