summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue2
-rw-r--r--app/assets/stylesheets/framework/typography.scss135
-rw-r--r--app/views/groups/_create_chat_team.html.haml2
-rw-r--r--app/views/groups/edit.html.haml4
-rw-r--r--app/views/groups/new.html.haml4
-rw-r--r--app/views/groups/settings/_advanced.html.haml24
-rw-r--r--app/views/shared/_confirm_modal.html.haml5
-rw-r--r--app/views/shared/_group_form.html.haml4
-rw-r--r--changelogs/unreleased/30839-asciidoc-table-styles.yml5
-rw-r--r--changelogs/unreleased/fix-set-status-emoji-button.yml5
-rw-r--r--db/post_migrate/20191004134055_drop_unused_analytics_repository_file_edits.rb32
-rw-r--r--db/schema.rb13
-rw-r--r--doc/administration/index.md1
-rw-r--r--doc/administration/troubleshooting/postgresql.md146
-rw-r--r--doc/development/documentation/site_architecture/index.md2
-rw-r--r--doc/development/gotchas.md4
-rw-r--r--lib/backup/repository.rb10
-rw-r--r--lib/banzai/filter/ascii_doc_sanitization_filter.rb8
-rw-r--r--lib/gitlab/gitaly_client/storage_service.rb17
-rw-r--r--locale/gitlab.pot33
-rw-r--r--qa/qa/page/group/new.rb2
-rw-r--r--spec/finders/todos_finder_spec.rb22
-rw-r--r--spec/lib/backup/repository_spec.rb24
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb14
-rw-r--r--spec/lib/gitlab/gitaly_client/storage_service_spec.rb13
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb39
26 files changed, 448 insertions, 122 deletions
diff --git a/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue b/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
index 396ecc3e291..df950e79690 100644
--- a/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
+++ b/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
@@ -163,7 +163,7 @@ export default {
:ok-title="s__('SetStatusModal|Set status')"
:cancel-title="s__('SetStatusModal|Remove status')"
ok-variant="success"
- class="set-user-status-modal"
+ modal-class="set-user-status-modal"
@shown="setupEmojiListAndAutocomplete"
@hide="hideEmojiMenu"
@ok="setStatus"
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index e36307f4f29..9028bfa8ec9 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -194,6 +194,141 @@
border-color: $gl-gray-200;
}
}
+
+ &.grid-none {
+ > thead > tr {
+ > th {
+ border-bottom-width: 0;
+ border-right-width: 0;
+ border-left-width: 0;
+
+ &:first-child {
+ border-left-width: 1px;
+ }
+
+ &:last-child {
+ border-right-width: 1px;
+ }
+ }
+ }
+
+ > tbody {
+ > tr > td {
+ border-width: 0;
+
+ &:first-child {
+ border-left-width: 1px;
+ }
+
+ &:last-child {
+ border-right-width: 1px;
+ }
+ }
+
+ > tr:last-child > td {
+ border-bottom-width: 1px;
+ }
+ }
+ }
+
+
+ &.grid-rows {
+ > thead > tr > th,
+ > tbody > tr > td {
+ border-right-width: 0;
+ border-left-width: 0;
+ }
+
+ > thead > tr {
+ > th:first-child {
+ border-left-width: 1px;
+ }
+
+ > th:last-child {
+ border-right-width: 1px;
+ }
+ }
+
+ > tbody > tr {
+ > td {
+ border-left-width: 0;
+ border-right-width: 0;
+ }
+
+ > td:first-child {
+ border-left-width: 1px;
+ }
+
+ > td:last-child {
+ border-right-width: 1px;
+ }
+ }
+ }
+
+ &.grid-cols {
+ > thead > tr > th {
+ border-bottom-width: 0;
+ }
+
+ > tbody > tr > td {
+ border-top-width: 0;
+ border-bottom-width: 0;
+ }
+
+ > tbody > tr:last-child > td {
+ border-bottom-width: 1px;
+ }
+ }
+
+ &.frame-sides {
+ > thead > tr > th {
+ border-top-width: 0;
+ }
+
+ > tbody > tr:last-child > td {
+ border-bottom-width: 0;
+ }
+ }
+
+ &.frame-topbot,
+ &.frame-ends {
+ > thead > tr > th:first-child,
+ > tbody > tr > td:first-child {
+ border-left-width: 0;
+ }
+
+ > thead > tr > th:last-child,
+ > tbody > tr > td:last-child {
+ border-right-width: 0;
+ }
+ }
+
+ &.frame-none {
+ > thead > tr > th {
+ border-top-width: 0;
+ }
+
+ > tbody > tr:last-child > td {
+ border-bottom-width: 0;
+ }
+
+ > thead > tr > th:first-child,
+ > tbody > tr > td:first-child {
+ border-left-width: 0;
+ }
+
+ > thead > tr > th:last-child,
+ > tbody > tr > td:last-child {
+ border-right-width: 0;
+ }
+ }
+
+ &.stripes-all tr,
+ &.stripes-odd tr:nth-of-type(odd),
+ &.stripes-even tr:nth-of-type(even),
+ &.stripes-hover tr:hover {
+ background: $gray-light;
+ }
}
table:dir(rtl) th {
diff --git a/app/views/groups/_create_chat_team.html.haml b/app/views/groups/_create_chat_team.html.haml
index 561e68a9155..2531993a095 100644
--- a/app/views/groups/_create_chat_team.html.haml
+++ b/app/views/groups/_create_chat_team.html.haml
@@ -8,7 +8,7 @@
.form-check.js-toggle-container
.js-toggle-button.form-check-input= f.check_box(:create_chat_team, { checked: true }, true, false)
= f.label :create_chat_team, class: 'form-check-label' do
- Create a Mattermost team for this group
+ = _('Create a Mattermost team for this group')
%br
%small.light.js-toggle-content
Mattermost URL:
diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml
index 6d06bb246cb..0e78ce9f656 100644
--- a/app/views/groups/edit.html.haml
+++ b/app/views/groups/edit.html.haml
@@ -1,4 +1,4 @@
-- breadcrumb_title "General Settings"
+- breadcrumb_title _("General Settings")
- @content_class = "limit-container-width" unless fluid_layout
- expanded = expanded_by_default?
@@ -32,7 +32,7 @@
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only{ role: 'button' }
= s_('GroupSettings|Badges')
%button.btn.js-settings-toggle{ type: 'button' }
- = expanded ? 'Collapse' : 'Expand'
+ = expanded ? _('Collapse') : _('Expand')
%p
= s_('GroupSettings|Customize your group badges.')
= link_to s_('GroupSettings|Learn more about badges.'), help_page_path('user/project/badges')
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 06e05d898d6..376624f4786 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -40,5 +40,5 @@
= render 'create_chat_team', f: f if Gitlab.config.mattermost.enabled
.form-actions
- = f.submit 'Create group', class: "btn btn-success"
- = link_to 'Cancel', dashboard_groups_path, class: 'btn btn-cancel'
+ = f.submit _('Create group'), class: "btn btn-success"
+ = link_to _('Cancel'), dashboard_groups_path, class: 'btn btn-cancel'
diff --git a/app/views/groups/settings/_advanced.html.haml b/app/views/groups/settings/_advanced.html.haml
index 64fec260f3b..307309c6ca3 100644
--- a/app/views/groups/settings/_advanced.html.haml
+++ b/app/views/groups/settings/_advanced.html.haml
@@ -1,12 +1,12 @@
.sub-section
- %h4.warning-title Change group path
+ %h4.warning-title= s_('GroupSettings|Change group path')
= form_for @group, html: { multipart: true, class: 'gl-show-field-errors' }, authenticity_token: true do |f|
= form_errors(@group)
.form-group
%p
- Changing group path can have unintended side effects.
+ = s_('GroupSettings|Changing group path can have unintended side effects.')
= succeed '.' do
- = link_to 'Learn more', help_page_path('user/group/index', anchor: 'changing-a-groups-path'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/group/index', anchor: 'changing-a-groups-path'), target: '_blank'
.input-group.gl-field-error-anchor
.group-root-path.input-group-prepend.has-tooltip{ title: group_path(@group), :'data-placement' => 'bottom' }
@@ -18,24 +18,26 @@
= f.text_field :path, placeholder: 'open-source', class: 'form-control',
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
- title: 'Please choose a group path with no special characters.',
+ title: s_('GroupSettings|Please choose a group path with no special characters.'),
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
- = f.submit 'Change group path', class: 'btn btn-warning'
+ = f.submit s_('GroupSettings|Change group path'), class: 'btn btn-warning'
.sub-section
- %h4.warning-title Transfer group
+ %h4.warning-title= s_('GroupSettings|Transfer group')
= form_for @group, url: transfer_group_path(@group), method: :put, html: { class: 'js-group-transfer-form' } do |f|
.form-group
= dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', data: { data: parent_group_options(@group) } })
= hidden_field_tag 'new_parent_group_id'
%ul
- %li Be careful. Changing a group's parent can have unintended #{link_to 'side effects', 'https://docs.gitlab.com/ce/user/project/index.html#redirects-when-changing-repository-paths', target: 'blank'}.
- %li You can only transfer the group to a group you manage.
- %li You will need to update your local repositories to point to the new location.
- %li If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.
- = f.submit 'Transfer group', class: 'btn btn-warning'
+ - side_effects_link_start = '<a href="https://docs.gitlab.com/ce/user/project/index.html#redirects-when-changing-repository-paths" target="_blank">'
+ - warning_text = s_("GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}.") % { side_effects_link_start: side_effects_link_start, side_effects_link_end:'</a>' }
+ %li= warning_text.html_safe
+ %li= s_('GroupSettings|You can only transfer the group to a group you manage.')
+ %li= s_('GroupSettings|You will need to update your local repositories to point to the new location.')
+ %li= s_("GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.")
+ = f.submit s_('GroupSettings|Transfer group'), class: 'btn btn-warning'
.sub-section
%h4.danger-title= _('Remove group')
diff --git a/app/views/shared/_confirm_modal.html.haml b/app/views/shared/_confirm_modal.html.haml
index 8e3b482e27d..ecb462205b0 100644
--- a/app/views/shared/_confirm_modal.html.haml
+++ b/app/views/shared/_confirm_modal.html.haml
@@ -12,9 +12,8 @@
%p
%span.js-warning-text= _('This action can lead to data loss. To prevent accidental actions we ask you to confirm your intention.')
%br
- Please type
- %code.js-confirm-danger-match= phrase
- to proceed or close this modal to cancel.
+ - phrase_code = '<code class="js-confirm-danger-match">%{phrase_name}</code>'.html_safe % { phrase_name: phrase }
+ = _('Please type %{phrase_code} to proceed or close this modal to cancel.').html_safe % { phrase_code: phrase_code }
.form-group
= text_field_tag 'confirm_name_input', '', class: 'form-control js-confirm-danger-input qa-confirm-input'
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index 973c756f496..959792718ca 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -30,9 +30,9 @@
- if @group.persisted?
.alert.alert-warning.prepend-top-10
- Changing group path can have unintended side effects.
+ = _('Changing group path can have unintended side effects.')
= succeed '.' do
- = link_to 'Learn more', help_page_path('user/group/index', anchor: 'changing-a-groups-path'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/group/index', anchor: 'changing-a-groups-path'), target: '_blank'
- if @group.persisted?
.row
diff --git a/changelogs/unreleased/30839-asciidoc-table-styles.yml b/changelogs/unreleased/30839-asciidoc-table-styles.yml
new file mode 100644
index 00000000000..11960f3620d
--- /dev/null
+++ b/changelogs/unreleased/30839-asciidoc-table-styles.yml
@@ -0,0 +1,5 @@
+---
+title: Enable grid, frame and stripes styling on AsciiDoc tables
+merge_request: 18165
+author: Guillaume Grossetie
+type: fixed
diff --git a/changelogs/unreleased/fix-set-status-emoji-button.yml b/changelogs/unreleased/fix-set-status-emoji-button.yml
new file mode 100644
index 00000000000..e7a8c119c91
--- /dev/null
+++ b/changelogs/unreleased/fix-set-status-emoji-button.yml
@@ -0,0 +1,5 @@
+---
+title: Fix styling of set status emoji picker
+merge_request: 18509
+author:
+type: fixed
diff --git a/db/post_migrate/20191004134055_drop_unused_analytics_repository_file_edits.rb b/db/post_migrate/20191004134055_drop_unused_analytics_repository_file_edits.rb
deleted file mode 100644
index 7bf92080fe6..00000000000
--- a/db/post_migrate/20191004134055_drop_unused_analytics_repository_file_edits.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class DropUnusedAnalyticsRepositoryFileEdits < ActiveRecord::Migration[5.2]
- DOWNTIME = false
-
- def up
- # The table was never used, there is no app code that writes or reads the table. Safe to remove.
- drop_table :analytics_repository_file_edits
- end
-
- def down
- create_table :analytics_repository_file_edits do |t|
- t.references :project,
- index: true,
- foreign_key: { on_delete: :cascade }, null: false
- t.references :analytics_repository_file,
- index: false,
- foreign_key: { on_delete: :cascade },
- null: false
- t.date :committed_date,
- null: false
- t.integer :num_edits,
- null: false,
- default: 0
- end
-
- add_index :analytics_repository_file_edits,
- [:analytics_repository_file_id, :committed_date, :project_id],
- name: 'index_file_edits_on_committed_date_file_id_and_project_id',
- unique: true
- end
-end
diff --git a/db/schema.rb b/db/schema.rb
index 1b1a6773c14..b9952cfc12d 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2019_10_04_134055) do
+ActiveRecord::Schema.define(version: 2019_10_04_133612) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
@@ -102,6 +102,15 @@ ActiveRecord::Schema.define(version: 2019_10_04_134055) do
t.index ["project_id", "committed_date", "analytics_repository_file_id"], name: "index_file_commits_on_committed_date_file_id_and_project_id", unique: true
end
+ create_table "analytics_repository_file_edits", force: :cascade do |t|
+ t.bigint "project_id", null: false
+ t.bigint "analytics_repository_file_id", null: false
+ t.date "committed_date", null: false
+ t.integer "num_edits", default: 0, null: false
+ t.index ["analytics_repository_file_id", "committed_date", "project_id"], name: "index_file_edits_on_committed_date_file_id_and_project_id", unique: true
+ t.index ["project_id"], name: "index_analytics_repository_file_edits_on_project_id"
+ end
+
create_table "analytics_repository_files", force: :cascade do |t|
t.bigint "project_id", null: false
t.string "file_path", limit: 4096, null: false
@@ -3900,6 +3909,8 @@ ActiveRecord::Schema.define(version: 2019_10_04_134055) do
add_foreign_key "analytics_language_trend_repository_languages", "projects", on_delete: :cascade
add_foreign_key "analytics_repository_file_commits", "analytics_repository_files", on_delete: :cascade
add_foreign_key "analytics_repository_file_commits", "projects", on_delete: :cascade
+ add_foreign_key "analytics_repository_file_edits", "analytics_repository_files", on_delete: :cascade
+ add_foreign_key "analytics_repository_file_edits", "projects", on_delete: :cascade
add_foreign_key "analytics_repository_files", "projects", on_delete: :cascade
add_foreign_key "application_settings", "namespaces", column: "custom_project_templates_group_id", on_delete: :nullify
add_foreign_key "application_settings", "projects", column: "file_template_project_id", name: "fk_ec757bd087", on_delete: :nullify
diff --git a/doc/administration/index.md b/doc/administration/index.md
index f79719e1d3e..fb6c1af991b 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -212,6 +212,7 @@ who are aware of the risks.
- [Useful diagnostics tools](troubleshooting/diagnostics_tools.md)
- [Useful Linux commands](troubleshooting/linux_cheat_sheet.md)
- [Troubleshooting Kubernetes](troubleshooting/kubernetes_cheat_sheet.md)
+- [Troubleshooting PostgreSQL](troubleshooting/postgresql.md)
- [Guide to test environments](troubleshooting/test_environments.md) (for Support Engineers)
- [GitLab Rails console commands](troubleshooting/gitlab_rails_cheat_sheet.md) (for Support Engineers)
- Useful links:
diff --git a/doc/administration/troubleshooting/postgresql.md b/doc/administration/troubleshooting/postgresql.md
new file mode 100644
index 00000000000..3bbc3f23d83
--- /dev/null
+++ b/doc/administration/troubleshooting/postgresql.md
@@ -0,0 +1,146 @@
+---
+type: reference
+---
+
+# PostgreSQL
+
+This page is useful information about PostgreSQL that the GitLab Support
+Team sometimes uses while troubleshooting. GitLab is making this public, so that anyone
+can make use of the Support team's collected knowledge.
+
+CAUTION: **Caution:** Some procedures documented here may break your GitLab instance. Use at your own risk.
+
+If you are on a [paid tier](https://about.gitlab.com/pricing/) and are not sure how
+to use these commands, it is best to [contact Support](https://about.gitlab.com/support/)
+and they will assist you with any issues you are having.
+
+## Other GitLab PostgreSQL documentation
+
+This section is for links to information elsewhere in the GitLab documentation.
+
+### Procedures
+
+- [Connect to the PostgreSQL console.](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database)
+
+- [Omnibus database procedures](https://docs.gitlab.com/omnibus/settings/database.html) including
+ - SSL: enabling, disabling, and verifying.
+ - Enabling Write Ahead Log (WAL) archiving.
+ - Using an external (non-Omnibus) PostgreSQL installation; and backing it up.
+ - Listening on TCP/IP as well as or instead of sockets.
+ - Storing data in another location.
+ - Destructively reseeding the GitLab database.
+ - Guidance around updating packaged PostgreSQL, including how to stop it happening automatically.
+
+- [More about external PostgreSQL](/ee/administration/external_database.html)
+
+- [Running GEO with external PostgreSQL](/ee/administration/geo/replication/external_database.html)
+
+- [Upgrades when running PostgreSQL configured for HA.](https://docs.gitlab.com/omnibus/settings/database.html#upgrading-a-gitlab-ha-cluster)
+
+- Consuming PostgreSQL from [within CI runners](/ee/ci/services/postgres.html)
+
+- [Using Slony to update PostgreSQL](/ee/update/upgrading_postgresql_using_slony.html)
+ - Uses replication to handle PostgreSQL upgrades - providing the schemas are the same.
+ - Reduces downtime to a short window for swinging over to the newer vewrsion.
+
+- Managing Omnibus PostgreSQL versions [from the development docs](https://docs.gitlab.com/omnibus/development/managing-postgresql-versions.html)
+
+- [PostgreSQL scaling and HA](/ee/administration/high_availability/database.html)
+ - including [troubleshooting](/ee/administration/high_availability/database.html#troubleshooting) gitlab-ctl repmgr-check-master and pgbouncer errors
+
+- [Developer database documentation](/ee/development/README.html#database-guides) - some of which is absolutely not for production use. Including:
+ - understanding EXPLAIN plans
+
+### Troubleshooting/Fixes
+
+- [GitLab database requirements](/ee/install/requirements.html#database) including
+ - Support for MySQL was removed in GitLab 12.1; [migrate to PostgreSQL](/ee/update/mysql_to_postgresql.html)
+ - required extension pg_trgm
+ - required extension postgres_fdw for Geo
+
+- Errors like this in the production/sidekiq log; see: [Set default_transaction_isolation into read committed](https://docs.gitlab.com/omnibus/settings/database.html#set-default_transaction_isolation-into-read-committed)
+
+```
+ActiveRecord::StatementInvalid PG::TRSerializationFailure: ERROR: could not serialize access due to concurrent update
+```
+
+- PostgreSQL HA - [replication slot errors](https://docs.gitlab.com/omnibus/settings/database.html#troubleshooting-upgrades-in-an-ha-cluster)
+
+```
+pg_basebackup: could not create temporary replication slot "pg_basebackup_12345": ERROR: all replication slots are in use
+HINT: Free one or increase max_replication_slots.
+```
+
+- GEO [replication errors](/ee/administration/geo/replication/troubleshooting.html#fixing-replication-errors) including:
+
+```
+ERROR: replication slots can only be used if max_replication_slots > 0
+
+FATAL: could not start WAL streaming: ERROR: replication slot “geo_secondary_my_domain_com” does not exist
+
+Command exceeded allowed execution time
+
+PANIC: could not write to file ‘pg_xlog/xlogtemp.123’: No space left on device
+```
+
+- [Checking GEO configuration](/ee/administration/geo/replication/troubleshooting.html#checking-configuration) including
+ - reconfiguring hosts/ports
+ - checking and fixing user/password mappings
+
+- [Common GEO errors](/ee/administration/geo/replication/troubleshooting.html#fixing-common-errors)
+
+## Support topics
+
+### Database deadlocks
+
+References:
+
+- [Issue #1 Deadlocks with GitLab 12.1, PostgreSQL 10.7](https://gitlab.com/gitlab-org/gitlab/issues/30528)
+- [Customer ticket (internal) GitLab 12.1.6](https://gitlab.zendesk.com/agent/tickets/134307) and [google doc (internal)](https://docs.google.com/document/d/19xw2d_D1ChLiU-MO1QzWab-4-QXgsIUcN5e_04WTKy4)
+- [Issue #2 deadlocks can occur if an instance is flooded with pushes](https://gitlab.com/gitlab-org/gitlab/issues/33650). Provided for context about how GitLab code can have this sort of unanticipated effect in unusual situations.
+
+```
+ERROR: deadlock detected
+```
+
+Three applicable timeouts are identified in the issue [#1](https://gitlab.com/gitlab-org/gitlab/issues/30528); our recommended settings are as follows:
+
+```
+deadlock_timeout = 5s
+statement_timeout = 15s
+idle_in_transaction_session_timeout = 60s
+```
+
+Quoting from from issue [#1](https://gitlab.com/gitlab-org/gitlab/issues/30528):
+
+> "If a deadlock is hit, and we resolve it through aborting the transaction after a short period, then the retry mechanisms we already have will make the deadlocked piece of work try again, and it's unlikely we'll deadlock multiple times in a row."
+
+TIP: **Tip:** In support, our general approach to reconfiguring timeouts (applies also to the HTTP stack as well) is that it's acceptable to do it temporarily as a workaround. If it makes GitLab usable for the customer, then it buys time to understand the problem more completely, implement a hot fix, or make some other change that addresses the root cause. Generally, the timeouts should be put back to reasonable defaults once the root cause is resolved.
+
+In this case, the guidance we had from development was to drop deadlock_timeout and/or statement_timeout but to leave the third setting at 60s. Setting idle_in_transaction protects the database from sessions potentially hanging for days. There's more discussion in [the issue relating to introducing this timeout on gitlab.com.](https://gitlab.com/gitlab-com/gl-infra/production/issues/1053)
+
+PostgresSQL defaults:
+
+- statement_timeout = 0 (never)
+- idle_in_transaction_session_timeout = 0 (never)
+
+Comments in issue [#1](https://gitlab.com/gitlab-org/gitlab/issues/30528) indicate that these should both be set to at least a number of minutes for all Omnibus installations (so they don't hang indefinitely). However, 15s for statement_timeout is very short, and will only be effective if the underlying infrastructure is very performant.
+
+See current settings with:
+
+```
+sudo gitlab-rails runner "c = ApplicationRecord.connection ; puts c.execute('SHOW statement_timeout').to_a ;
+puts c.execute('SHOW lock_timeout').to_a ;
+puts c.execute('SHOW idle_in_transaction_session_timeout').to_a ;"
+```
+
+It may take a little while to respond.
+
+```
+{"statement_timeout"=>"1min"}
+{"lock_timeout"=>"0"}
+{"idle_in_transaction_session_timeout"=>"1min"}
+```
+
+NOTE: **Note:**
+These are Omnibus settings. If an external database, such as a customer's PostgreSQL installation or Amazon RDS is being used, these values don't get set, and would have to be set externally.
diff --git a/doc/development/documentation/site_architecture/index.md b/doc/development/documentation/site_architecture/index.md
index f8d63a54053..f5a12e9c216 100644
--- a/doc/development/documentation/site_architecture/index.md
+++ b/doc/development/documentation/site_architecture/index.md
@@ -68,7 +68,7 @@ the GitLab Documentation website.
## Global navigation
-Read through the global navigation](global_nav.md) documentation to understand:
+Read through [the global navigation documentation](global_nav.md) to understand:
- How the global navigation is built.
- How to add new navigation items.
diff --git a/doc/development/gotchas.md b/doc/development/gotchas.md
index 5557a113d05..c7eed880554 100644
--- a/doc/development/gotchas.md
+++ b/doc/development/gotchas.md
@@ -114,6 +114,7 @@ Instead of writing:
# Don't do this:
expect_any_instance_of(Project).to receive(:add_import_job)
+# Don't do this:
allow_any_instance_of(Project).to receive(:add_import_job)
```
@@ -125,12 +126,13 @@ expect_next_instance_of(Project) do |project|
expect(project).to receive(:add_import_job)
end
+# Do this:
allow_next_instance_of(Project) do |project|
allow(project).to receive(:add_import_job)
end
```
-If we also want to initialized the instance with some particular arguments, we
+If we also want to initialize the instance with some particular arguments, we
could also pass it like:
```ruby
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
index c87466de357..974e32ce17c 100644
--- a/lib/backup/repository.rb
+++ b/lib/backup/repository.rb
@@ -41,12 +41,6 @@ module Backup
end
end
- def prepare_directories
- Gitlab.config.repositories.storages.each do |name, _repository_storage|
- Gitlab::GitalyClient::StorageService.new(name).delete_all_repositories
- end
- end
-
def backup_project(project)
path_to_project_bundle = path_to_bundle(project)
Gitlab::GitalyClient::RepositoryService.new(project.repository)
@@ -75,13 +69,13 @@ module Backup
end
def restore
- prepare_directories
-
Project.find_each(batch_size: 1000) do |project|
progress.print " * #{project.full_path} ... "
path_to_project_bundle = path_to_bundle(project)
+ project.repository.remove rescue nil
restore_repo_success = nil
+
if File.exist?(path_to_project_bundle)
begin
project.repository.create_from_bundle(path_to_project_bundle)
diff --git a/lib/banzai/filter/ascii_doc_sanitization_filter.rb b/lib/banzai/filter/ascii_doc_sanitization_filter.rb
index 9105e86ad04..e41f7d8488a 100644
--- a/lib/banzai/filter/ascii_doc_sanitization_filter.rb
+++ b/lib/banzai/filter/ascii_doc_sanitization_filter.rb
@@ -22,6 +22,10 @@ module Banzai
CHECKLIST_CLASSES = %w(fa fa-check-square-o fa-square-o).freeze
LIST_CLASSES = %w(checklist none no-bullet unnumbered unstyled).freeze
+ TABLE_FRAME_CLASSES = %w(frame-all frame-topbot frame-sides frame-ends frame-none).freeze
+ TABLE_GRID_CLASSES = %w(grid-all grid-rows grid-cols grid-none).freeze
+ TABLE_STRIPES_CLASSES = %w(stripes-all stripes-odd stripes-even stripes-hover stripes-none).freeze
+
ELEMENT_CLASSES_WHITELIST = {
span: %w(big small underline overline line-through).freeze,
div: ['admonitionblock'].freeze,
@@ -29,7 +33,8 @@ module Banzai
i: ADMONITION_CLASSES + CALLOUT_CLASSES + CHECKLIST_CLASSES,
ul: LIST_CLASSES,
ol: LIST_CLASSES,
- a: ['anchor'].freeze
+ a: ['anchor'].freeze,
+ table: TABLE_FRAME_CLASSES + TABLE_GRID_CLASSES + TABLE_STRIPES_CLASSES
}.freeze
def customize_whitelist(whitelist)
@@ -45,6 +50,7 @@ module Banzai
whitelist[:attributes]['ul'] = %w(class)
whitelist[:attributes]['ol'] = %w(class)
whitelist[:attributes]['a'].push('class')
+ whitelist[:attributes]['table'] = %w(class)
whitelist[:transformers].push(self.class.remove_element_classes)
# Allow `id` in heading elements for section anchors
diff --git a/lib/gitlab/gitaly_client/storage_service.rb b/lib/gitlab/gitaly_client/storage_service.rb
index c7fcef6ddc5..e69de29bb2d 100644
--- a/lib/gitlab/gitaly_client/storage_service.rb
+++ b/lib/gitlab/gitaly_client/storage_service.rb
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module GitalyClient
- class StorageService
- def initialize(storage)
- @storage = storage
- end
-
- # Delete all repositories in the storage. This is a slow and VERY DESTRUCTIVE operation.
- def delete_all_repositories
- request = Gitaly::DeleteAllRepositoriesRequest.new(storage_name: @storage)
- GitalyClient.call(@storage, :storage_service, :delete_all_repositories, request, timeout: GitalyClient.long_timeout)
- end
- end
- end
-end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b5ffe1bc28a..3b3eb4d649e 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2946,6 +2946,9 @@ msgstr ""
msgid "Changes won't take place until the index is %{link_start}recreated%{link_end}."
msgstr ""
+msgid "Changing group path can have unintended side effects."
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -4618,6 +4621,9 @@ msgstr ""
msgid "Create a GitLab account first, and then connect it to your %{label} account."
msgstr ""
+msgid "Create a Mattermost team for this group"
+msgstr ""
+
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -8249,6 +8255,15 @@ msgstr ""
msgid "GroupSettings|Badges"
msgstr ""
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgstr ""
+
+msgid "GroupSettings|Change group path"
+msgstr ""
+
+msgid "GroupSettings|Changing group path can have unintended side effects."
+msgstr ""
+
msgid "GroupSettings|Custom project templates"
msgstr ""
@@ -8261,6 +8276,9 @@ msgstr ""
msgid "GroupSettings|Disable email notifications"
msgstr ""
+msgid "GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgstr ""
+
msgid "GroupSettings|Learn more about badges."
msgstr ""
@@ -8273,6 +8291,9 @@ msgstr ""
msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr ""
+msgid "GroupSettings|Please choose a group path with no special characters."
+msgstr ""
+
msgid "GroupSettings|Prevent sharing a project within %{group} with other groups"
msgstr ""
@@ -8303,6 +8324,15 @@ msgstr ""
msgid "GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
+msgid "GroupSettings|Transfer group"
+msgstr ""
+
+msgid "GroupSettings|You can only transfer the group to a group you manage."
+msgstr ""
+
+msgid "GroupSettings|You will need to update your local repositories to point to the new location."
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11906,6 +11936,9 @@ msgstr ""
msgid "Please try again"
msgstr ""
+msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
+msgstr ""
+
msgid "Please upgrade PostgreSQL to version 9.6 or greater. The status of the replication cannot be determined reliably with the current version."
msgstr ""
diff --git a/qa/qa/page/group/new.rb b/qa/qa/page/group/new.rb
index 9e37d14fbf3..e01b8754d55 100644
--- a/qa/qa/page/group/new.rb
+++ b/qa/qa/page/group/new.rb
@@ -11,7 +11,7 @@ module QA
end
view 'app/views/groups/new.html.haml' do
- element :create_group_button, "submit 'Create group'" # rubocop:disable QA/ElementWithPattern
+ element :create_group_button, "submit _('Create group')" # rubocop:disable QA/ElementWithPattern
element :visibility_radios, 'visibility_level:' # rubocop:disable QA/ElementWithPattern
end
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index a0bf48f218a..9a3ffffb3f2 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -73,6 +73,28 @@ describe TodosFinder do
end
end
+ context 'when filtering by author' do
+ let(:author1) { create(:user) }
+ let(:author2) { create(:user) }
+
+ let!(:todo1) { create(:todo, user: user, author: author1) }
+ let!(:todo2) { create(:todo, user: user, author: author2) }
+
+ it 'returns correct todos when filtering by an author' do
+ todos = finder.new(user, { author_id: author1.id }).execute
+
+ expect(todos).to match_array([todo1])
+ end
+
+ context 'querying for multiple authors' do
+ it 'returns the correct todo items' do
+ todos = finder.new(user, { author_id: [author2.id, author1.id] }).execute
+
+ expect(todos).to match_array([todo2, todo1])
+ end
+ end
+ end
+
context 'with subgroups' do
let(:subgroup) { create(:group, parent: group) }
let!(:todo3) { create(:todo, user: user, group: subgroup, target: issue) }
diff --git a/spec/lib/backup/repository_spec.rb b/spec/lib/backup/repository_spec.rb
index 582effcc303..bf827fb3914 100644
--- a/spec/lib/backup/repository_spec.rb
+++ b/spec/lib/backup/repository_spec.rb
@@ -83,30 +83,6 @@ describe Backup::Repository do
end
end
- describe '#prepare_directories', :seed_helper do
- before do
- allow(FileUtils).to receive(:mkdir_p).and_call_original
- allow(FileUtils).to receive(:mv).and_call_original
- end
-
- after(:all) do
- ensure_seeds
- end
-
- it' removes all repositories' do
- # Sanity check: there should be something for us to delete
- expect(list_repositories).to include(File.join(SEED_STORAGE_PATH, TEST_REPO_PATH))
-
- subject.prepare_directories
-
- expect(list_repositories).to be_empty
- end
-
- def list_repositories
- Dir[File.join(SEED_STORAGE_PATH, '*.git')]
- end
- end
-
describe '#empty_repo?' do
context 'for a wiki' do
let(:wiki) { create(:project_wiki) }
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 354260f23f6..04a648a0da0 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -2254,7 +2254,7 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe '#remove' do
- let(:project) { create(:project, :repository)}
+ let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
it 'removes the repository' do
@@ -2264,5 +2264,17 @@ describe Gitlab::Git::Repository, :seed_helper do
expect(repository.raw_repository.exists?).to be false
end
+
+ context 'when the repository does not exist' do
+ let(:repository) { create(:project).repository }
+
+ it 'is idempotent' do
+ expect(repository.exists?).to be false
+
+ repository.remove
+
+ expect(repository.raw_repository.exists?).to be false
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/gitaly_client/storage_service_spec.rb b/spec/lib/gitlab/gitaly_client/storage_service_spec.rb
deleted file mode 100644
index 6c25e2d6ebd..00000000000
--- a/spec/lib/gitlab/gitaly_client/storage_service_spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::GitalyClient::StorageService do
- describe '#delete_all_repositories' do
- let!(:project) { create(:project, :repository) }
-
- it 'removes all repositories' do
- described_class.new(project.repository_storage).delete_all_repositories
-
- expect(project.repository.exists?).to be(false)
- end
- end
-end
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index b307453f078..e58919c8688 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -117,6 +117,45 @@ describe 'gitlab:app namespace rake task' do
expect(raw_repo.empty?).to be(true)
end
end
+
+ context 'when the backup is restored' do
+ let!(:included_project) { create(:project, :repository) }
+
+ before do
+ expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout
+
+ backup_tar = Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar')).last
+ allow(Dir).to receive(:glob).and_return([backup_tar])
+ allow(File).to receive(:exist?).and_return(true)
+ allow(Kernel).to receive(:system).and_return(true)
+ allow(FileUtils).to receive(:cp_r).and_return(true)
+ allow(FileUtils).to receive(:mv).and_return(true)
+ allow(YAML).to receive(:load_file)
+ .and_return({ gitlab_version: Gitlab::VERSION })
+
+ expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:db:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:repo:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:builds:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:uploads:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:artifacts:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:pages:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:lfs:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:backup:registry:restore']).to receive(:invoke)
+ expect(Rake::Task['gitlab:shell:setup']).to receive(:invoke)
+
+ # We only need a backup of the repositories for this test
+ stub_env('SKIP', 'db,uploads,builds,artifacts,lfs,registry')
+ end
+
+ it 'restores the data' do
+ expect { run_rake_task('gitlab:backup:restore') }.to output.to_stdout
+
+ raw_repo = included_project.repository.raw
+
+ expect(raw_repo.empty?).to be(false)
+ end
+ end
end # backup_restore task
describe 'backup' do