diff --git a/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js b/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js index 191221a48cd..8d2d5d41f6a 100644 --- a/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js +++ b/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js @@ -5,13 +5,12 @@ import { mergeUrlParams, removeParams } from '~/lib/utils/url_utility'; * OAuth-based login buttons have a separate "remember me" checkbox. * * Toggling this checkbox adds/removes a `remember_me` parameter to the - * login buttons' href, which is passed on to the omniauth callback. + * login buttons' parent form action, which is passed on to the omniauth callback. */ export default class OAuthRememberMe { constructor(opts = {}) { this.container = opts.container || ''; - this.loginLinkSelector = '.oauth-login'; } bindEvents() { @@ -22,12 +21,13 @@ export default class OAuthRememberMe { const rememberMe = $(event.target).is(':checked'); $('.oauth-login', this.container).each((i, element) => { - const href = $(element).attr('href'); + const $form = $(element).parent('form'); + const href = $form.attr('action'); if (rememberMe) { - $(element).attr('href', mergeUrlParams({ remember_me: 1 }, href)); + $form.attr('action', mergeUrlParams({ remember_me: 1 }, href)); } else { - $(element).attr('href', removeParams(['remember_me'], href)); + $form.attr('action', removeParams(['remember_me'], href)); } }); } diff --git a/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js b/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js index e617fecaa0f..1d47a9aed47 100644 --- a/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js +++ b/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js @@ -12,7 +12,7 @@ export default function preserveUrlFragment(fragment = '') { // Append the fragment to all sign-in/sign-up form actions so it is preserved when the user is // eventually redirected back to the originally requested URL. - const forms = document.querySelectorAll('#signin-container form'); + const forms = document.querySelectorAll('#signin-container .tab-content form'); Array.prototype.forEach.call(forms, form => { const actionWithFragment = setUrlFragment(form.getAttribute('action'), `#${normalFragment}`); form.setAttribute('action', actionWithFragment); @@ -20,13 +20,13 @@ export default function preserveUrlFragment(fragment = '') { // Append a redirect_fragment query param to all oauth provider links. The redirect_fragment // query param will be available in the omniauth callback upon successful authentication - const anchors = document.querySelectorAll('#signin-container a.oauth-login'); - Array.prototype.forEach.call(anchors, anchor => { + const oauthForms = document.querySelectorAll('#signin-container .omniauth-container form'); + Array.prototype.forEach.call(oauthForms, oauthForm => { const newHref = mergeUrlParams( { redirect_fragment: normalFragment }, - anchor.getAttribute('href'), + oauthForm.getAttribute('action'), ); - anchor.setAttribute('href', newHref); + oauthForm.setAttribute('action', newHref); }); } } diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index 67a8f689e9d..81a70470c65 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -96,14 +96,21 @@ margin: 0; } - .omniauth-btn { - margin-bottom: $gl-padding; + form { width: 48%; - padding: $gl-padding-8; + padding: 0; + border: 0; + background: none; + margin-bottom: $gl-padding; @include media-breakpoint-down(md) { width: 100%; } + } + + .omniauth-btn { + width: 100%; + padding: $gl-padding-8; img { width: $default-icon-size; diff --git a/app/models/group_import_state.rb b/app/models/group_import_state.rb index 7773b887249..a4c7092b80f 100644 --- a/app/models/group_import_state.rb +++ b/app/models/group_import_state.rb @@ -5,7 +5,8 @@ class GroupImportState < ApplicationRecord belongs_to :group, inverse_of: :import_state - validates :group, :status, :jid, presence: true + validates :group, :status, presence: true + validates :jid, presence: true, if: -> { started? || finished? } state_machine :status, initial: :created do state :created, value: 0 diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml index 5c3e4ccbfe5..e99d0ac1105 100644 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ b/app/views/devise/shared/_omniauth_box.html.haml @@ -7,7 +7,7 @@ .d-flex.justify-content-between.flex-wrap - providers.each do |provider| - has_icon = provider_has_icon?(provider) - = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do + = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}" do - if has_icon = provider_image_tag(provider) %span diff --git a/changelogs/unreleased/fix-omniauth-buttons-js.yml b/changelogs/unreleased/fix-omniauth-buttons-js.yml new file mode 100644 index 00000000000..9350af2cdd0 --- /dev/null +++ b/changelogs/unreleased/fix-omniauth-buttons-js.yml @@ -0,0 +1,5 @@ +--- +title: Avoid javascript for omniauth logins +merge_request: 33459 +author: Diego Louzán +type: other diff --git a/changelogs/unreleased/jh-drop_jid_null_constraint.yml b/changelogs/unreleased/jh-drop_jid_null_constraint.yml new file mode 100644 index 00000000000..ef1637c814e --- /dev/null +++ b/changelogs/unreleased/jh-drop_jid_null_constraint.yml @@ -0,0 +1,5 @@ +--- +title: Remove null constraint for JID in GroupImportState +merge_request: 33181 +author: +type: changed diff --git a/db/migrate/20200526142550_drop_null_constraint_on_group_import_state_jid.rb b/db/migrate/20200526142550_drop_null_constraint_on_group_import_state_jid.rb new file mode 100644 index 00000000000..d0dfa126455 --- /dev/null +++ b/db/migrate/20200526142550_drop_null_constraint_on_group_import_state_jid.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class DropNullConstraintOnGroupImportStateJid < ActiveRecord::Migration[6.0] + DOWNTIME = false + + def up + change_column_null :group_import_states, :jid, true + end + + def down + # No-op -- null values could have been added after this this constraint was removed. + end +end diff --git a/db/structure.sql b/db/structure.sql index 861544f2550..70458df2126 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -3187,7 +3187,7 @@ CREATE TABLE public.group_import_states ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, status smallint DEFAULT 0 NOT NULL, - jid text NOT NULL, + jid text, last_error text, CONSTRAINT check_87b58f6b30 CHECK ((char_length(last_error) <= 255)), CONSTRAINT check_96558fff96 CHECK ((char_length(jid) <= 100)) @@ -13816,6 +13816,7 @@ COPY "schema_migrations" (version) FROM STDIN; 20200526000407 20200526013844 20200526120714 +20200526142550 20200526153844 20200526164946 20200526164947 diff --git a/doc/.vale/gitlab/Acronyms.yml b/doc/.vale/gitlab/Acronyms.yml index 652c461940a..859ce4417c3 100644 --- a/doc/.vale/gitlab/Acronyms.yml +++ b/doc/.vale/gitlab/Acronyms.yml @@ -36,6 +36,7 @@ exceptions: - LDAPS - LESS - LFS + - NFS - NGINX - NOTE - ONLY @@ -43,6 +44,7 @@ exceptions: - PHP - POST - PUT + - RPC - RSA - RSS - SAML @@ -56,6 +58,7 @@ exceptions: - TIP - TLS - TODO + - TOML - UNIX - URI - URL diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md index 2b737d76302..1469ed64004 100644 --- a/doc/administration/gitaly/index.md +++ b/doc/administration/gitaly/index.md @@ -32,7 +32,7 @@ The following is a high-level architecture overview of how Gitaly is used. ![Gitaly architecture diagram](img/architecture_v12_4.png) -## Configuring Gitaly +## Configure Gitaly The Gitaly service itself is configured via a [TOML configuration file](reference.md). @@ -40,7 +40,8 @@ To change Gitaly settings: **For Omnibus GitLab** -1. Edit `/etc/gitlab/gitlab.rb` and add or change the [Gitaly settings](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/1dd07197c7e5ae23626aad5a4a070a800b670380/files/gitlab-config-template/gitlab.rb.template#L1622-1676). +1. Edit `/etc/gitlab/gitlab.rb` and add or change the + [Gitaly settings](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/1dd07197c7e5ae23626aad5a4a070a800b670380/files/gitlab-config-template/gitlab.rb.template#L1622-1676). 1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure). **For installations from source** @@ -48,10 +49,10 @@ To change Gitaly settings: 1. Edit `/home/git/gitaly/config.toml` and add or change the [Gitaly settings](https://gitlab.com/gitlab-org/gitaly/blob/master/config.toml.example). 1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source). -## Running Gitaly on its own server +## Run Gitaly on its own server By default, Gitaly is run on the same server as Gitaly clients and is -[configured as above](#configuring-gitaly). Single-server installations are best served by +[configured as above](#configure-gitaly). Single-server installations are best served by this default configuration used by: - [Omnibus GitLab](https://docs.gitlab.com/omnibus/). @@ -65,71 +66,92 @@ When configured to run on their own servers, Gitaly servers [must be upgraded](https://docs.gitlab.com/omnibus/update/#upgrading-gitaly-servers) before Gitaly clients in your cluster. -Starting with GitLab 11.4, Gitaly is able to serve all Git requests without -requiring a shared NFS mount for Git repository data. -Between 11.4 and 11.8 the exception was the -[Elasticsearch indexer](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer). -But since 11.8 the indexer uses Gitaly for data access as well. NFS can still -be leveraged for redundancy on block level of the Git data. But only has to -be mounted on the Gitaly servers. +The process for setting up Gitaly on its own server is: -From GitLab v11.8 to v12.2, it is possible to use Elasticsearch in conjunction with -a Gitaly setup that isn't utilising NFS. In order to use Elasticsearch in this -scenario, the [new repository indexer](../../integration/elasticsearch.md#elasticsearch-repository-indexer) -needs to be enabled in your GitLab configuration. [Since GitLab v12.3](https://gitlab.com/gitlab-org/gitlab/-/issues/6481), -the new indexer becomes the default and no configuration is required. +1. [Install Gitaly](#install-gitaly). +1. [Configure authentication](#configure-authentication). +1. [Configure Gitaly servers](#configure-gitaly-servers). +1. [Configure Gitaly clients](#configure-gitaly-clients). + +When running Gitaly on its own server, note the following regarding GitLab versions: + +- From GitLab 11.4, Gitaly was able to serve all Git requests without requiring a shared NFS mount + for Git repository data, except for the + [Elasticsearch indexer](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer). +- From GitLab 11.8, the Elasticsearch indexer uses Gitaly for data access as well. NFS can still be + leveraged for redundancy on block-level Git data, but only has to be mounted on the Gitaly + servers. +- From GitLab 11.8 to 12.2, it is possible to use Elasticsearch in a Gitaly setup that doesn't use + NFS. In order to use Elasticsearch in these versions, the + [repository indexer](../../integration/elasticsearch.md#elasticsearch-repository-indexer) + must be enabled in your GitLab configuration. +- [Since GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/-/issues/6481), the new indexer is + the default and no configuration is required. ### Network architecture -The following list depicts what the network architecture of Gitaly is: +The following list depicts the network architecture of Gitaly: - GitLab Rails shards repositories into [repository storages](../repository_storage_paths.md). -- `/config/gitlab.yml` contains a map from storage names to - `(Gitaly address, Gitaly token)` pairs. -- the `storage name` -\> `(Gitaly address, Gitaly token)` map in - `/config/gitlab.yml` is the single source of truth for the Gitaly network - topology. +- `/config/gitlab.yml` contains a map from storage names to `(Gitaly address, Gitaly token)` pairs. +- The `storage name` -\> `(Gitaly address, Gitaly token)` map in `/config/gitlab.yml` is the single + source of truth for the Gitaly network topology. - A `(Gitaly address, Gitaly token)` corresponds to a Gitaly server. - A Gitaly server hosts one or more storages. - A Gitaly client can use one or more Gitaly servers. -- Gitaly addresses must be specified in such a way that they resolve - correctly for ALL Gitaly clients. -- Gitaly clients are: Puma/Unicorn, Sidekiq, GitLab Workhorse, - GitLab Shell, Elasticsearch Indexer, and Gitaly itself. +- Gitaly addresses must be specified in such a way that they resolve correctly for **all** Gitaly + clients. +- Gitaly clients are: + - Puma or Unicorn. + - Sidekiq. + - GitLab Workhorse. + - GitLab Shell. + - Elasticsearch indexer. + - Gitaly itself. - A Gitaly server must be able to make RPC calls **to itself** via its own `(Gitaly address, Gitaly token)` pair as specified in `/config/gitlab.yml`. -- Gitaly servers must not be exposed to the public internet as Gitaly's network - traffic is unencrypted by default. The use of firewall is highly recommended - to restrict access to the Gitaly server. Another option is to - [use TLS](#tls-support). -- Authentication is done through a static token which is shared among the Gitaly - and GitLab Rails nodes. +- Authentication is done through a static token which is shared among the Gitaly and GitLab Rails + nodes. -Below we describe how to configure two Gitaly servers one at -`gitaly1.internal` and the other at `gitaly2.internal` -with secret token `abc123secret`. We assume -your GitLab installation has three repository storages: `default`, -`storage1` and `storage2`. You can use as little as just one server with one -repository storage if desired. +DANGER: **Danger:** +Gitaly servers must not be exposed to the public internet as Gitaly's network traffic is unencrypted +by default. The use of firewall is highly recommended to restrict access to the Gitaly server. +Another option is to [use TLS](#tls-support). -Note: **Note:** The token referred to throughout the Gitaly documentation is -just an arbitrary password selected by the administrator. It is unrelated to -tokens created for the GitLab API or other similar web API tokens. +In the following sections, we describe how to configure two Gitaly servers with secret token +`abc123secret`: -### 1. Installation +- `gitaly1.internal`. +- `gitaly2.internal`. -First install Gitaly on each Gitaly server using either -Omnibus GitLab or install it from source: +We assume your GitLab installation has three repository storages: -- For Omnibus GitLab: [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab - package you want using **steps 1 and 2** from the GitLab downloads page but - **_do not_** provide the `EXTERNAL_URL=` value. -- From source: [Install Gitaly](../../install/installation.md#install-gitaly). +- `default`. +- `storage1`. +- `storage2`. -### 2. Authentication +You can use as few as one server with one repository storage if desired. -Gitaly and GitLab use two shared secrets for authentication, one to authenticate gRPC requests -to Gitaly, and a second for authentication callbacks from GitLab Shell to the GitLab internal API. +NOTE: **Note:** +The token referred to throughout the Gitaly documentation is just an arbitrary password selected by +the administrator. It is unrelated to tokens created for the GitLab API or other similar web API +tokens. + +### Install Gitaly + +Install Gitaly on each Gitaly server using either Omnibus GitLab or install it from source: + +- For Omnibus GitLab, [download and install](https://about.gitlab.com/install/) the Omnibus GitLab + package you want but **do not** provide the `EXTERNAL_URL=` value. +- To install from source, follow the steps at + [Install Gitaly](../../install/installation.md#install-gitaly). + +### Configure authentication + +Gitaly and GitLab use two shared secrets for authentication: + +- One to authenticate gRPC requests to Gitaly. +- A second for authentication callbacks from GitLab Shell to the GitLab internal API. **For Omnibus GitLab** @@ -150,12 +172,15 @@ To configure the Gitaly token: 1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure). -There are two ways to configure the GitLab Shell token: +There are two ways to configure the GitLab Shell token. -1. Copy `/etc/gitlab/gitlab-secrets.json` from the Gitaly client to same path on the Gitaly servers (and any other Gitaly clients). +Method 1: + +1. Copy `/etc/gitlab/gitlab-secrets.json` from the Gitaly client to same path on the Gitaly servers + (and any other Gitaly clients). 1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) on Gitaly servers. -**OR** +Method 2: 1. On the Gitaly clients, edit `/etc/gitlab/gitlab.rb`: @@ -174,8 +199,8 @@ There are two ways to configure the GitLab Shell token: **For installations from source** -1. Copy `/home/git/gitlab/.gitlab_shell_secret` from the Gitaly client to the same path on the Gitaly -servers (and any other Gitaly clients). +1. Copy `/home/git/gitlab/.gitlab_shell_secret` from the Gitaly client to the same path on the + Gitaly servers (and any other Gitaly clients). 1. On the Gitaly clients, edit `/home/git/gitlab/config/gitlab.yml`: ```yaml @@ -194,16 +219,13 @@ servers (and any other Gitaly clients). 1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source). -### 3. Gitaly server configuration +### Configure Gitaly servers -Next, on the Gitaly servers, you need to configure storage paths and enable -the network listener. +On the Gitaly servers, you must configure storage paths and enable the network listener. -NOTE: **Note:** If you want to reduce the risk of downtime when you enable -authentication you can temporarily disable enforcement, see [the -documentation on configuring Gitaly -authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md#authentication) -. +If you want to reduce the risk of downtime when you enable authentication, you can temporarily +disable enforcement. For more information, see the documentation on configuring +[Gitaly authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md#authentication). **For Omnibus GitLab** @@ -288,7 +310,7 @@ authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configurati 1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure). 1. Run `sudo /opt/gitlab/embedded/service/gitlab-shell/bin/check -config /opt/gitlab/embedded/service/gitlab-shell/config.yml` -to confirm that Gitaly can perform callbacks to the GitLab internal API. + to confirm that Gitaly can perform callbacks to the GitLab internal API. **For installations from source** @@ -335,35 +357,35 @@ to confirm that Gitaly can perform callbacks to the GitLab internal API. 1. Save the files and [restart GitLab](../restart_gitlab.md#installations-from-source). 1. Run `sudo -u git /home/git/gitlab-shell/bin/check -config /home/git/gitlab-shell/config.yml` -to confirm that Gitaly can perform callbacks to the GitLab internal API. + to confirm that Gitaly can perform callbacks to the GitLab internal API. -### 4. Converting Gitaly clients to use the Gitaly servers +### Configure Gitaly clients -As the final step, you need to update Gitaly clients to switch from using -local Gitaly service to use the Gitaly servers you just configured. This -is a risky step because if there is any sort of network, firewall, or name -resolution problem preventing your Gitaly clients from reaching the Gitaly servers, -then all Gitaly requests will fail. +As the final step, you must update Gitaly clients to switch from using local Gitaly service to use +the Gitaly servers you just configured. -Additionally, you need to -[disable Rugged if previously manually enabled](../high_availability/nfs.md#improving-nfs-performance-with-gitlab). +This can be risky because anything that prevents your Gitaly clients from reaching the Gitaly +servers will cause all Gitaly requests to fail. For example, any sort of network, firewall, or name +resolution problems. + +Additionally, you must [disable Rugged](../high_availability/nfs.md#improving-nfs-performance-with-gitlab) +if previously enabled manually. Gitaly makes the following assumptions: -- Your `gitaly1.internal` Gitaly server can be reached at `gitaly1.internal:8075` - from your Gitaly clients, and that Gitaly server can read and write to - `/mnt/gitlab/default` and `/mnt/gitlab/storage1`. -- Your `gitaly2.internal` Gitaly server can be reached at `gitaly2.internal:8075` - from your Gitaly clients, and that Gitaly server can read and write to - `/mnt/gitlab/storage2`. +- Your `gitaly1.internal` Gitaly server can be reached at `gitaly1.internal:8075` from your Gitaly + clients, and that Gitaly server can read and write to `/mnt/gitlab/default` and + `/mnt/gitlab/storage1`. +- Your `gitaly2.internal` Gitaly server can be reached at `gitaly2.internal:8075` from your Gitaly + clients, and that Gitaly server can read and write to `/mnt/gitlab/storage2`. - Your `gitaly1.internal` and `gitaly2.internal` Gitaly servers can reach each other. -Note that you can't use mixed installation setup when at least one of your -Gitaly servers is configured as a local server with the `path` setting -provided, because other Gitaly instances can't communicate with it. -The following setup is _incorrect_, because you must replace `path` with -`gitaly_address` containing a proper value, and the -address must be reachable from the other two addresses provided: +Note you can't a use mixed setup, with at least one of your Gitaly servers configured as a local +server with the `path` setting provided. This is because other Gitaly instances can't communicate +with it. The following setup is _incorrect_, because: + +- You must replace `path` with `gitaly_address` containing a proper value. +- The address must be reachable from the other two addresses provided. ```ruby git_data_dirs({ @@ -386,7 +408,8 @@ git_data_dirs({ ``` 1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure). -1. Run `sudo gitlab-rake gitlab:gitaly:check` to confirm the Gitaly client can connect to Gitaly servers. +1. Run `sudo gitlab-rake gitlab:gitaly:check` to confirm the Gitaly client can connect to Gitaly + servers. 1. Tail the logs to see the requests: ```shell @@ -413,32 +436,31 @@ git_data_dirs({ ``` NOTE: **Note:** - `/some/dummy/path` should be set to a local folder that exists, however no - data will be stored in this folder. This will no longer be necessary after + `/some/dummy/path` should be set to a local folder that exists, however no data will be stored in + this folder. This will no longer be necessary after [this issue](https://gitlab.com/gitlab-org/gitaly/-/issues/1282) is resolved. 1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source). -1. Run `sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=production` to -confirm the Gitaly client can connect to Gitaly servers. +1. Run `sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=production` to confirm the + Gitaly client can connect to Gitaly servers. 1. Tail the logs to see the requests: ```shell tail -f /home/git/gitlab/log/gitaly.log ``` -When you tail the Gitaly logs on your Gitaly server you should see requests -coming in. One sure way to trigger a Gitaly request is to clone a repository -from GitLab over HTTP or HTTPS. +When you tail the Gitaly logs on your Gitaly server, you should see requests coming in. One sure way +to trigger a Gitaly request is to clone a repository from GitLab over HTTP or HTTPS. DANGER: **Danger:** -If you have [Server hooks](../server_hooks.md) configured, -either per repository or globally, you must move these to the Gitaly servers. -If you have multiple Gitaly servers, copy your server hooks to all Gitaly servers. +If you have [server hooks](../server_hooks.md) configured, either per repository or globally, you +must move these to the Gitaly servers. If you have multiple Gitaly servers, copy your server hooks +to all Gitaly servers. ### Disabling the Gitaly service in a cluster environment If you are running Gitaly [as a remote -service](#running-gitaly-on-its-own-server) you may want to disable +service](#run-gitaly-on-its-own-server) you may want to disable the local Gitaly service that runs on your GitLab server by default. Disabling Gitaly only makes sense when you run GitLab in a custom cluster configuration, where different services run on different @@ -1007,7 +1029,7 @@ If you're running Gitaly on its own server and notice that users can successfully clone and fetch repositories (via both SSH and HTTPS), but can't push to them or make changes to the repository in the web UI without getting a `401 Unauthorized` message, then it's possible Gitaly is failing to authenticate -with the Gitaly client due to having the [wrong secrets file](#3-gitaly-server-configuration). +with the Gitaly client due to having the [wrong secrets file](#configure-gitaly-servers). Confirm the following are all true: @@ -1088,7 +1110,7 @@ Confirm the following are all true: [IP] - - [18/Jul/2019:00:30:14 +0000] "POST /api/v4/internal/allowed HTTP/1.1" 401 30 "" "Ruby" ``` -To fix this problem, confirm that your [`gitlab-secrets.json` file](#3-gitaly-server-configuration) +To fix this problem, confirm that your [`gitlab-secrets.json` file](#configure-gitaly-servers) on the Gitaly server matches the one on Gitaly client. If it doesn't match, update the secrets file on the Gitaly server to match the Gitaly client, then [reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure). diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md index 3c2812d8b52..d3aad67f3cc 100644 --- a/doc/administration/gitaly/praefect.md +++ b/doc/administration/gitaly/praefect.md @@ -381,7 +381,7 @@ Particular attention should be shown to: `gitaly-2`, and `gitaly-3` as Gitaly storage names. For more information on Gitaly server configuration, see our [Gitaly -documentation](index.md#3-gitaly-server-configuration). +documentation](index.md#configure-gitaly-servers). 1. SSH into the **Gitaly** node and login as root: diff --git a/doc/administration/high_availability/gitaly.md b/doc/administration/high_availability/gitaly.md index fd7d5365a2a..74033575216 100644 --- a/doc/administration/high_availability/gitaly.md +++ b/doc/administration/high_availability/gitaly.md @@ -14,7 +14,7 @@ This document is relevant for [scalable and highly available setups](../referenc ## Running Gitaly on its own server -See [Running Gitaly on its own server](../gitaly/index.md#running-gitaly-on-its-own-server) +See [Run Gitaly on its own server](../gitaly/index.md#run-gitaly-on-its-own-server) in Gitaly documentation. Continue configuration of other components by going back to the diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md index 23186b17faa..0b332087080 100644 --- a/doc/administration/raketasks/maintenance.md +++ b/doc/administration/raketasks/maintenance.md @@ -62,7 +62,7 @@ The `gitlab:check` Rake task runs the following Rake tasks: It will check 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 will not work correctly on -component servers like [Gitaly](../gitaly/index.md#running-gitaly-on-its-own-server). +component servers like [Gitaly](../gitaly/index.md#run-gitaly-on-its-own-server). You may also have a look at our troubleshooting guides for: diff --git a/doc/administration/reference_architectures/2k_users.md b/doc/administration/reference_architectures/2k_users.md index 5a803dac739..55f3ac8a624 100644 --- a/doc/administration/reference_architectures/2k_users.md +++ b/doc/administration/reference_architectures/2k_users.md @@ -30,7 +30,7 @@ For a full list of reference architectures, see NFS is required for GitLab Pages, you can skip this step if you're not using that feature. 1. [Configure PostgreSQL](../high_availability/load_balancer.md), the database for GitLab. 1. [Configure Redis](../high_availability/redis.md). -1. [Configure Gitaly](../gitaly/index.md#running-gitaly-on-its-own-server), +1. [Configure Gitaly](../gitaly/index.md#run-gitaly-on-its-own-server), which is used to provide access to the Git repositories. 1. [Configure the main GitLab Rails application](../high_availability/gitlab.md) to run Puma/Unicorn, Workhorse, GitLab Shell, and to serve all diff --git a/doc/administration/reference_architectures/index.md b/doc/administration/reference_architectures/index.md index 7784bc9f89d..ae0a4742423 100644 --- a/doc/administration/reference_architectures/index.md +++ b/doc/administration/reference_architectures/index.md @@ -166,7 +166,7 @@ column. | Repmgr | PostgreSQL cluster management and failover | [PostgreSQL and Repmgr configuration](../high_availability/database.md) | Yes | | [Redis](../../development/architecture.md#redis) ([3](#footnotes)) | Key/value store for fast data lookup and caching | [Redis configuration](../high_availability/redis.md) | Yes | | Redis Sentinel | Redis | [Redis Sentinel configuration](../high_availability/redis.md) | Yes | -| [Gitaly](../../development/architecture.md#gitaly) ([2](#footnotes)) ([7](#footnotes)) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#running-gitaly-on-its-own-server) | Yes | +| [Gitaly](../../development/architecture.md#gitaly) ([2](#footnotes)) ([7](#footnotes)) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#run-gitaly-on-its-own-server) | Yes | | [Sidekiq](../../development/architecture.md#sidekiq) | Asynchronous/background jobs | [Sidekiq configuration](../high_availability/sidekiq.md) | Yes | | [GitLab application services](../../development/architecture.md#unicorn)([1](#footnotes)) | Puma/Unicorn, Workhorse, GitLab Shell - serves front-end requests (UI, API, Git over HTTP/SSH) | [GitLab app scaling configuration](../high_availability/gitlab.md) | Yes | | [Prometheus](../../development/architecture.md#prometheus) and [Grafana](../../development/architecture.md#grafana) | GitLab environment monitoring | [Monitoring node for scaling](../high_availability/monitoring_node.md) | Yes | diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md index b6b5c045467..813e343f2cc 100644 --- a/doc/install/aws/index.md +++ b/doc/install/aws/index.md @@ -568,7 +568,7 @@ Let's create an EC2 instance where we'll install Gitaly: NOTE: **Optional:** Instead of storing configuration _and_ repository data on the root volume, you can also choose to add an additional EBS volume for repository storage. Follow the same guidance as above. See the [Amazon EBS pricing](https://aws.amazon.com/ebs/pricing/). We do not recommend using EFS as it may negatively impact GitLab’s performance. You can review the [relevant documentation](../../administration/high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs) for more details. -Now that we have our EC2 instance ready, follow the [documentation to install GitLab and set up Gitaly on its own server](../../administration/gitaly/index.md#running-gitaly-on-its-own-server). Perform the client setup steps from that document on the [GitLab instance we created](#install-gitlab) above. +Now that we have our EC2 instance ready, follow the [documentation to install GitLab and set up Gitaly on its own server](../../administration/gitaly/index.md#run-gitaly-on-its-own-server). Perform the client setup steps from that document on the [GitLab instance we created](#install-gitlab) above. #### Add Support for Proxied SSL diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md index c5638a8a3cd..161780ef102 100644 --- a/doc/user/packages/container_registry/index.md +++ b/doc/user/packages/container_registry/index.md @@ -555,11 +555,11 @@ run the policy may get backed up or fail completely. It is recommended you only policies for projects that were created before GitLab 12.8 if you are confident the amount of tags being cleaned up will be minimal. -### Regex patterns +### Regex pattern examples -The patterns that define which tags should be preserved or removed are defined using regular expressions, both for the UI and the API. +Expiration policies use regex patterns to determine which tags should be preserved or removed, both in the UI and the API. -Examples: +Here are examples of regex patterns you may want to use: - Match all tags: diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e36decd3c00..6a19d69ca6c 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -27393,6 +27393,9 @@ msgstr "" msgid "uses Kubernetes clusters to deploy your code!" msgstr "" +msgid "v%{version} published %{timeAgo}" +msgstr "" + msgid "verify ownership" msgstr "" diff --git a/package.json b/package.json index eb4476b5c24..ed756dddc1c 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@babel/preset-env": "^7.8.4", "@gitlab/at.js": "1.5.5", "@gitlab/svgs": "1.138.0", - "@gitlab/ui": "16.4.1", + "@gitlab/ui": "16.5.0", "@gitlab/visual-review-tools": "1.6.1", "@rails/actioncable": "^6.0.3-1", "@sentry/browser": "^5.10.2", diff --git a/spec/factories/group_import_states.rb b/spec/factories/group_import_states.rb new file mode 100644 index 00000000000..0b491d444fa --- /dev/null +++ b/spec/factories/group_import_states.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :group_import_state, class: 'GroupImportState', traits: %i[created] do + association :group, factory: :group + + trait :created do + status { 0 } + end + + trait :started do + status { 1 } + sequence(:jid) { |n| "group_import_state_#{n}" } + end + + trait :finished do + status { 2 } + sequence(:jid) { |n| "group_import_state_#{n}" } + end + + trait :failed do + status { -1 } + end + end +end diff --git a/spec/frontend/fixtures/static/oauth_remember_me.html b/spec/frontend/fixtures/static/oauth_remember_me.html index 9ba1ffc72fe..c6af8129b4d 100644 --- a/spec/frontend/fixtures/static/oauth_remember_me.html +++ b/spec/frontend/fixtures/static/oauth_remember_me.html @@ -1,6 +1,22 @@
- - - + +
+ +
+ +
+ +
+ +
+ +
+
diff --git a/spec/frontend/oauth_remember_me_spec.js b/spec/frontend/oauth_remember_me_spec.js index 381be82697e..e12db05ac43 100644 --- a/spec/frontend/oauth_remember_me_spec.js +++ b/spec/frontend/oauth_remember_me_spec.js @@ -2,6 +2,12 @@ import $ from 'jquery'; import OAuthRememberMe from '~/pages/sessions/new/oauth_remember_me'; describe('OAuthRememberMe', () => { + const findFormAction = selector => { + return $(`#oauth-container .oauth-login${selector}`) + .parent('form') + .attr('action'); + }; + preloadFixtures('static/oauth_remember_me.html'); beforeEach(() => { @@ -13,15 +19,9 @@ describe('OAuthRememberMe', () => { it('adds the "remember_me" query parameter to all OAuth login buttons', () => { $('#oauth-container #remember_me').click(); - expect($('#oauth-container .oauth-login.twitter').attr('href')).toBe( - 'http://example.com/?remember_me=1', - ); - - expect($('#oauth-container .oauth-login.github').attr('href')).toBe( - 'http://example.com/?remember_me=1', - ); - - expect($('#oauth-container .oauth-login.facebook').attr('href')).toBe( + expect(findFormAction('.twitter')).toBe('http://example.com/?remember_me=1'); + expect(findFormAction('.github')).toBe('http://example.com/?remember_me=1'); + expect(findFormAction('.facebook')).toBe( 'http://example.com/?redirect_fragment=L1&remember_me=1', ); }); @@ -30,10 +30,8 @@ describe('OAuthRememberMe', () => { $('#oauth-container #remember_me').click(); $('#oauth-container #remember_me').click(); - expect($('#oauth-container .oauth-login.twitter').attr('href')).toBe('http://example.com/'); - expect($('#oauth-container .oauth-login.github').attr('href')).toBe('http://example.com/'); - expect($('#oauth-container .oauth-login.facebook').attr('href')).toBe( - 'http://example.com/?redirect_fragment=L1', - ); + expect(findFormAction('.twitter')).toBe('http://example.com/'); + expect(findFormAction('.github')).toBe('http://example.com/'); + expect(findFormAction('.facebook')).toBe('http://example.com/?redirect_fragment=L1'); }); }); diff --git a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js index 1809e92e1d9..0d9af0cb856 100644 --- a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js +++ b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js @@ -2,6 +2,12 @@ import $ from 'jquery'; import preserveUrlFragment from '~/pages/sessions/new/preserve_url_fragment'; describe('preserve_url_fragment', () => { + const findFormAction = selector => { + return $(`.omniauth-container ${selector}`) + .parent('form') + .attr('action'); + }; + preloadFixtures('sessions/new.html'); beforeEach(() => { @@ -25,35 +31,36 @@ describe('preserve_url_fragment', () => { it('does not add an empty query parameter to OmniAuth login buttons', () => { preserveUrlFragment(); - expect($('#oauth-login-cas3').attr('href')).toBe('http://test.host/users/auth/cas3'); + expect(findFormAction('#oauth-login-cas3')).toBe('http://test.host/users/auth/cas3'); - expect($('.omniauth-container #oauth-login-auth0').attr('href')).toBe( - 'http://test.host/users/auth/auth0', - ); + expect(findFormAction('#oauth-login-auth0')).toBe('http://test.host/users/auth/auth0'); }); describe('adds "redirect_fragment" query parameter to OmniAuth login buttons', () => { it('when "remember_me" is not present', () => { preserveUrlFragment('#L65'); - expect($('#oauth-login-cas3').attr('href')).toBe( + expect(findFormAction('#oauth-login-cas3')).toBe( 'http://test.host/users/auth/cas3?redirect_fragment=L65', ); - expect($('.omniauth-container #oauth-login-auth0').attr('href')).toBe( + expect(findFormAction('#oauth-login-auth0')).toBe( 'http://test.host/users/auth/auth0?redirect_fragment=L65', ); }); it('when "remember-me" is present', () => { - $('a.omniauth-btn').attr('href', (i, href) => `${href}?remember_me=1`); + $('.omniauth-btn') + .parent('form') + .attr('action', (i, href) => `${href}?remember_me=1`); + preserveUrlFragment('#L65'); - expect($('#oauth-login-cas3').attr('href')).toBe( + expect(findFormAction('#oauth-login-cas3')).toBe( 'http://test.host/users/auth/cas3?remember_me=1&redirect_fragment=L65', ); - expect($('#oauth-login-auth0').attr('href')).toBe( + expect(findFormAction('#oauth-login-auth0')).toBe( 'http://test.host/users/auth/auth0?remember_me=1&redirect_fragment=L65', ); }); diff --git a/spec/models/group_import_state_spec.rb b/spec/models/group_import_state_spec.rb new file mode 100644 index 00000000000..70884bf420e --- /dev/null +++ b/spec/models/group_import_state_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe GroupImportState do + describe 'validations' do + let_it_be(:group) { create(:group) } + + it { is_expected.to validate_presence_of(:group) } + it { is_expected.to validate_presence_of(:status) } + + it 'can be created without a jid' do + import_state = build(:group_import_state, :created, group: group, jid: nil) + + expect(import_state).to be_valid + end + + it 'cannot be started without a jid' do + import_state = build(:group_import_state, :started, group: group, jid: nil) + + expect(import_state).not_to be_valid + expect(import_state.errors[:jid]).to include "can't be blank" + end + + it 'cannot be finished without a jid' do + import_state = build(:group_import_state, :finished, group: group, jid: nil) + + expect(import_state).not_to be_valid + expect(import_state.errors[:jid]).to include "can't be blank" + end + + it 'can fail without a jid' do + import_state = build(:group_import_state, :failed, group: group, jid: nil) + + expect(import_state).to be_valid + end + end +end diff --git a/spec/support/helpers/login_helpers.rb b/spec/support/helpers/login_helpers.rb index cb880939b1c..92f6d673255 100644 --- a/spec/support/helpers/login_helpers.rb +++ b/spec/support/helpers/login_helpers.rb @@ -57,13 +57,13 @@ module LoginHelpers def gitlab_sign_in_via(provider, user, uid, saml_response = nil) mock_auth_hash_with_saml_xml(provider, uid, user.email, saml_response) visit new_user_session_path - click_link provider + click_button provider end def gitlab_enable_admin_mode_sign_in_via(provider, user, uid, saml_response = nil) mock_auth_hash_with_saml_xml(provider, uid, user.email, saml_response) visit new_admin_session_path - click_link provider + click_button provider end # Requires Javascript driver. @@ -103,7 +103,7 @@ module LoginHelpers check 'remember_me' if remember_me - click_link "oauth-login-#{provider}" + click_button "oauth-login-#{provider}" end def fake_successful_u2f_authentication diff --git a/vendor/project_templates/learn_gitlab.tar.gz b/vendor/project_templates/learn_gitlab.tar.gz index c04ab4227af..1f60a36639b 100644 Binary files a/vendor/project_templates/learn_gitlab.tar.gz and b/vendor/project_templates/learn_gitlab.tar.gz differ diff --git a/yarn.lock b/yarn.lock index 301e90fa89b..3dbfa4e6e59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -787,10 +787,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.138.0.tgz#440c304d1d4b4a6cfd80b26cfac0d0b95dae0cf6" integrity sha512-qLukIpaJHF8uHRNIPGhhO5Bq1056e4cV3I51wI4PsxJLi5bkX1bXLbBlKXhQJgIknK39+1/MYpYOg2A19xbBdw== -"@gitlab/ui@16.4.1": - version "16.4.1" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-16.4.1.tgz#fd27e9f8bd0bcaf7bb4d28f0ab658d6cdc2ffc89" - integrity sha512-RMtPQM1YPtsQNlTfrnRAbl05BcLym6DH0Hi7df2G1h4gQbzfyy3Y7bBYTmg2OXO1nFOlIuMyjOIwS6v5yOTu4w== +"@gitlab/ui@16.5.0": + version "16.5.0" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-16.5.0.tgz#424d71edbaf08dd670c2319dd33151b615b001b8" + integrity sha512-YtLKxO1J2/RtEepeIEipzdyIwzrYKAAkF1yiN50j6vUKWxZpQAnrOsvLav4LPxIyRNsmLR7zssjEqSTRnbI8hA== dependencies: "@babel/standalone" "^7.0.0" "@gitlab/vue-toasted" "^1.3.0"