Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
71722304be
commit
e4503e5d77
37 changed files with 357 additions and 26 deletions
|
@ -63,7 +63,12 @@ Consider adding checkboxes and expectations of users with certain levels of memb
|
||||||
* [ ] Add expected impact to Reporter (20) members
|
* [ ] Add expected impact to Reporter (20) members
|
||||||
* [ ] Add expected impact to Developer (30) members
|
* [ ] Add expected impact to Developer (30) members
|
||||||
* [ ] Add expected impact to Maintainer (40) members
|
* [ ] Add expected impact to Maintainer (40) members
|
||||||
* [ ] Add expected impact to Owner (50) members -->
|
* [ ] Add expected impact to Owner (50) members
|
||||||
|
|
||||||
|
Please consider performing a threat model for the code changes that are introduced as part of this feature. To get started, refer to our Threat Modeling handbook page https://about.gitlab.com/handbook/security/threat_modeling/#threat-modeling.
|
||||||
|
|
||||||
|
Don't hesitate to reach out to the Application Security Team (`@gitlab-com/gl-security/appsec`) to discuss any security concerns.
|
||||||
|
-->
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import {
|
||||||
FilterFields,
|
FilterFields,
|
||||||
ListTypeTitles,
|
ListTypeTitles,
|
||||||
DraggableItemTypes,
|
DraggableItemTypes,
|
||||||
active,
|
|
||||||
} from 'ee_else_ce/boards/constants';
|
} from 'ee_else_ce/boards/constants';
|
||||||
import {
|
import {
|
||||||
formatIssueInput,
|
formatIssueInput,
|
||||||
|
@ -210,7 +209,6 @@ export default {
|
||||||
const variables = {
|
const variables = {
|
||||||
fullPath,
|
fullPath,
|
||||||
searchTerm,
|
searchTerm,
|
||||||
state: active,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let query;
|
let query;
|
||||||
|
|
|
@ -245,7 +245,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<gl-loading-icon v-if="isLoading" size="sm" />
|
<gl-loading-icon v-if="isLoading" size="sm" />
|
||||||
<div v-if="blobInfo && !isLoading" class="file-holder">
|
<div v-if="blobInfo && !isLoading" class="file-holder gl-overflow-hidden">
|
||||||
<blob-header
|
<blob-header
|
||||||
:blob="blobInfo"
|
:blob="blobInfo"
|
||||||
:hide-viewer-switcher="!hasRichViewer || isBinaryFileType || isUsingLfs"
|
:hide-viewer-switcher="!hasRichViewer || isBinaryFileType || isUsingLfs"
|
||||||
|
|
|
@ -51,7 +51,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="file-content code js-syntax-highlight" :class="$options.userColorScheme">
|
<div class="file-content code js-syntax-highlight" :class="$options.userColorScheme">
|
||||||
<div v-if="!hideLineNumbers" class="line-numbers">
|
<div v-if="!hideLineNumbers" class="line-numbers gl-pt-0!">
|
||||||
<a
|
<a
|
||||||
v-for="line in lineNumbers"
|
v-for="line in lineNumbers"
|
||||||
:id="`L${line}`"
|
:id="`L${line}`"
|
||||||
|
@ -67,7 +67,7 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<div class="blob-content">
|
<div class="blob-content">
|
||||||
<pre
|
<pre
|
||||||
class="code highlight"
|
class="code highlight gl-p-0! gl-display-flex"
|
||||||
><code v-safe-html="content" :data-blob-hash="blobHash"></code></pre>
|
><code v-safe-html="content" :data-blob-hash="blobHash"></code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -116,13 +116,13 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="file-content code js-syntax-highlight blob-content"
|
class="file-content code js-syntax-highlight blob-content gl-display-flex"
|
||||||
:class="$options.userColorScheme"
|
:class="$options.userColorScheme"
|
||||||
data-type="simple"
|
data-type="simple"
|
||||||
data-qa-selector="blob_viewer_file_content"
|
data-qa-selector="blob_viewer_file_content"
|
||||||
>
|
>
|
||||||
<line-numbers :lines="lineNumbers" />
|
<line-numbers :lines="lineNumbers" />
|
||||||
<pre class="code"><code v-safe-html="highlightedContent"></code>
|
<pre class="code gl-pb-0!"><code v-safe-html="highlightedContent"></code>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -96,7 +96,7 @@ class ContainerRepository < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
event :abort_import do
|
event :abort_import do
|
||||||
transition %i[pre_importing importing] => :import_aborted
|
transition ACTIVE_MIGRATION_STATES.map(&:to_sym) => :import_aborted
|
||||||
end
|
end
|
||||||
|
|
||||||
event :skip_import do
|
event :skip_import do
|
||||||
|
@ -205,6 +205,11 @@ class ContainerRepository < ApplicationRecord
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def finish_pre_import_and_start_import
|
||||||
|
# nothing to do between those two transitions for now.
|
||||||
|
finish_pre_import && start_import
|
||||||
|
end
|
||||||
|
|
||||||
# rubocop: disable CodeReuse/ServiceClass
|
# rubocop: disable CodeReuse/ServiceClass
|
||||||
def registry
|
def registry
|
||||||
@registry ||= begin
|
@registry ||= begin
|
||||||
|
@ -287,10 +292,18 @@ class ContainerRepository < ApplicationRecord
|
||||||
update!(expiration_policy_started_at: Time.zone.now)
|
update!(expiration_policy_started_at: Time.zone.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def migration_in_active_state?
|
||||||
|
migration_state.in?(ACTIVE_MIGRATION_STATES)
|
||||||
|
end
|
||||||
|
|
||||||
def migration_importing?
|
def migration_importing?
|
||||||
migration_state == 'importing'
|
migration_state == 'importing'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def migration_pre_importing?
|
||||||
|
migration_state == 'pre_importing'
|
||||||
|
end
|
||||||
|
|
||||||
def migration_pre_import
|
def migration_pre_import
|
||||||
return :error unless gitlab_api_client.supports_gitlab_api?
|
return :error unless gitlab_api_client.supports_gitlab_api?
|
||||||
|
|
||||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37195
|
||||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/229841
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/229841
|
||||||
milestone: '13.2'
|
milestone: '13.2'
|
||||||
type: development
|
type: development
|
||||||
group: group::monitor
|
group: group::respond
|
||||||
default_enabled: false
|
default_enabled: false
|
||||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74337
|
||||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345769
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345769
|
||||||
milestone: '14.6'
|
milestone: '14.6'
|
||||||
type: development
|
type: development
|
||||||
group: group::monitor
|
group: group::respond
|
||||||
default_enabled: false
|
default_enabled: false
|
||||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40103
|
||||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/241697
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/241697
|
||||||
milestone: '13.4'
|
milestone: '13.4'
|
||||||
type: development
|
type: development
|
||||||
group: group::apm
|
group: group::respond
|
||||||
default_enabled: false
|
default_enabled: false
|
||||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/13443
|
||||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/255304
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/255304
|
||||||
milestone: '12.0'
|
milestone: '12.0'
|
||||||
type: development
|
type: development
|
||||||
group: group::monitor
|
group: group::respond
|
||||||
default_enabled: false
|
default_enabled: false
|
||||||
|
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343286
|
||||||
milestone: '14.8'
|
milestone: '14.8'
|
||||||
type: development
|
type: development
|
||||||
group: group::pipeline execution
|
group: group::pipeline execution
|
||||||
default_enabled: false
|
default_enabled: true
|
||||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24296
|
||||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/258560
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/258560
|
||||||
milestone: '12.8'
|
milestone: '12.8'
|
||||||
type: development
|
type: development
|
||||||
group: group::monitor
|
group: group::respond
|
||||||
default_enabled: false
|
default_enabled: false
|
||||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58606
|
||||||
rollout_issue_url:
|
rollout_issue_url:
|
||||||
milestone: '13.11'
|
milestone: '13.11'
|
||||||
type: development
|
type: development
|
||||||
group: group::monitor
|
group: group::respond
|
||||||
default_enabled: true
|
default_enabled: true
|
||||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77168
|
||||||
rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6086
|
rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6086
|
||||||
milestone: '14.7'
|
milestone: '14.7'
|
||||||
type: ops
|
type: ops
|
||||||
group: group::monitor
|
group: group::respond
|
||||||
default_enabled: false
|
default_enabled: false
|
||||||
|
|
|
@ -4,6 +4,7 @@ Rails.autoloaders.each do |autoloader|
|
||||||
# We need to ignore these since these are non-Ruby files
|
# We need to ignore these since these are non-Ruby files
|
||||||
# that do not define Ruby classes / modules
|
# that do not define Ruby classes / modules
|
||||||
autoloader.ignore(Rails.root.join('lib/support'))
|
autoloader.ignore(Rails.root.join('lib/support'))
|
||||||
|
autoloader.ignore(Rails.root.join('lib/gitlab/ci/parsers/security/validators/schemas'))
|
||||||
autoloader.ignore(Rails.root.join('ee/lib/ee/gitlab/ci/parsers/security/validators/schemas')) if Gitlab.ee?
|
autoloader.ignore(Rails.root.join('ee/lib/ee/gitlab/ci/parsers/security/validators/schemas')) if Gitlab.ee?
|
||||||
|
|
||||||
# Mailer previews are loaded manually by Rails
|
# Mailer previews are loaded manually by Rails
|
||||||
|
|
|
@ -238,6 +238,7 @@ control over how the Pages daemon runs and serves content in your environment.
|
||||||
| `artifacts_server_url` | API URL to proxy artifact requests to. Defaults to GitLab `external URL` + `/api/v4`, for example `https://gitlab.com/api/v4`. When running a [separate Pages server](#running-gitlab-pages-on-a-separate-server), this URL must point to the main GitLab server's API. |
|
| `artifacts_server_url` | API URL to proxy artifact requests to. Defaults to GitLab `external URL` + `/api/v4`, for example `https://gitlab.com/api/v4`. When running a [separate Pages server](#running-gitlab-pages-on-a-separate-server), this URL must point to the main GitLab server's API. |
|
||||||
| `auth_redirect_uri` | Callback URL for authenticating with GitLab. Defaults to project's subdomain of `pages_external_url` + `/auth`. |
|
| `auth_redirect_uri` | Callback URL for authenticating with GitLab. Defaults to project's subdomain of `pages_external_url` + `/auth`. |
|
||||||
| `auth_secret` | Secret key for signing authentication requests. Leave blank to pull automatically from GitLab during OAuth registration. |
|
| `auth_secret` | Secret key for signing authentication requests. Leave blank to pull automatically from GitLab during OAuth registration. |
|
||||||
|
| `client_cert_key_pairs` | Client certificates and keys used for mutual TLS with the GitLab API. See [Support mutual TLS when calling the GitLab API](#support-mutual-tls-when-calling-the-gitlab-api) for details. |
|
||||||
| `dir` | Working directory for configuration and secrets files. |
|
| `dir` | Working directory for configuration and secrets files. |
|
||||||
| `enable` | Enable or disable GitLab Pages on the current system. |
|
| `enable` | Enable or disable GitLab Pages on the current system. |
|
||||||
| `external_http` | Configure Pages to bind to one or more secondary IP addresses, serving HTTP requests. Multiple addresses can be given as an array, along with exact ports, for example `['1.2.3.4', '1.2.3.5:8063']`. Sets value for `listen_http`. |
|
| `external_http` | Configure Pages to bind to one or more secondary IP addresses, serving HTTP requests. Multiple addresses can be given as an array, along with exact ports, for example `['1.2.3.4', '1.2.3.5:8063']`. Sets value for `listen_http`. |
|
||||||
|
@ -511,6 +512,20 @@ Authority (CA) in the system certificate store.
|
||||||
|
|
||||||
For Omnibus, this is fixed by [installing a custom CA in Omnibus GitLab](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
|
For Omnibus, this is fixed by [installing a custom CA in Omnibus GitLab](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
|
||||||
|
|
||||||
|
### Support mutual TLS when calling the GitLab API
|
||||||
|
|
||||||
|
If GitLab has been [configured to require mutual TLS](https://docs.gitlab.com/omnibus/settings/nginx.html#enable-2-way-ssl-client-authentication), you need to add the client certificates to Pages:
|
||||||
|
|
||||||
|
1. Configure in `/etc/gitlab/gitlab.rb`:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
gitlab_pages['client_cert_key_pairs'] = ['</path/to/cert>:</path/to/key>']
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `</path/to/cert>` and `</path/to/key>` are the file paths to the client certificate and its respective key file.
|
||||||
|
Both of these files must be encoded in PEM format.
|
||||||
|
1. To configure Pages to validate the server certificates, [add the root CA to the system trust store](#using-a-custom-certificate-authority-ca).
|
||||||
|
|
||||||
### ZIP serving and cache configuration
|
### ZIP serving and cache configuration
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/392) in GitLab 13.7.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/392) in GitLab 13.7.
|
||||||
|
@ -688,7 +703,7 @@ To override the global maximum pages size for a specific group:
|
||||||
## Running GitLab Pages on a separate server
|
## Running GitLab Pages on a separate server
|
||||||
|
|
||||||
You can run the GitLab Pages daemon on a separate server to decrease the load on
|
You can run the GitLab Pages daemon on a separate server to decrease the load on
|
||||||
your main application server. This configuration does not support mutual TLS (mTLS). See the [corresponding feature proposal](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/548) for more information.
|
your main application server.
|
||||||
|
|
||||||
To configure GitLab Pages on a separate server:
|
To configure GitLab Pages on a separate server:
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ change when the beta period ends, as discussed in this [related issue](https://g
|
||||||
|
|
||||||
Windows runners on GitLab.com autoscale by launching virtual machines on
|
Windows runners on GitLab.com autoscale by launching virtual machines on
|
||||||
the Google Cloud Platform. This solution uses an
|
the Google Cloud Platform. This solution uses an
|
||||||
[autoscaling driver](https://gitlab.com/gitlab-org/ci-cd/custom-executor-drivers/autoscaler/tree/master/docs/readme.md)
|
[autoscaling driver](https://gitlab.com/gitlab-org/ci-cd/custom-executor-drivers/autoscaler/-/blob/main/docs/README.md)
|
||||||
developed by GitLab for the [custom executor](https://docs.gitlab.com/runner/executors/custom.html).
|
developed by GitLab for the [custom executor](https://docs.gitlab.com/runner/executors/custom.html).
|
||||||
Windows runners execute your CI/CD jobs on `n1-standard-2` instances with
|
Windows runners execute your CI/CD jobs on `n1-standard-2` instances with
|
||||||
2 vCPUs and 7.5 GB RAM. You can find a full list of available Windows packages in
|
2 vCPUs and 7.5 GB RAM. You can find a full list of available Windows packages in
|
||||||
|
|
|
@ -507,7 +507,7 @@ curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" \
|
||||||
|
|
||||||
Called from the GitLab Agent Server (`kas`) to create a security vulnerability
|
Called from the GitLab Agent Server (`kas`) to create a security vulnerability
|
||||||
from a Starboard vulnerability report. This request is idempotent. Multiple requests with the same data
|
from a Starboard vulnerability report. This request is idempotent. Multiple requests with the same data
|
||||||
create a single vulnerability.
|
create a single vulnerability. The response contains the UUID of the created vulnerability finding.
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
| Attribute | Type | Required | Description |
|
||||||
|:----------------|:-------|:---------|:------------|
|
|:----------------|:-------|:---------|:------------|
|
||||||
|
@ -553,6 +553,14 @@ curl --request PUT --header "Gitlab-Kas-Api-Request: <JWT token>" \
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"uuid": "4773b2ee-5ba5-5e9f-b48c-5f7a17f0faac"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Subscriptions
|
## Subscriptions
|
||||||
|
|
||||||
The subscriptions endpoint is used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
|
The subscriptions endpoint is used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
|
||||||
|
|
|
@ -105,7 +105,7 @@ label defined in the [global settings](#configuration) is used.
|
||||||
|
|
||||||
The label is shown on all project pages in the upper right corner.
|
The label is shown on all project pages in the upper right corner.
|
||||||
|
|
||||||
![classification label on project page](img/classification_label_on_project_page.png)
|
![classification label on project page](img/classification_label_on_project_page_v14_8.png)
|
||||||
|
|
||||||
<!-- ## Troubleshooting
|
<!-- ## Troubleshooting
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 19 KiB |
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -343,3 +343,30 @@ run tests:
|
||||||
reports:
|
reports:
|
||||||
cobertura: coverage.xml
|
cobertura: coverage.xml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Ruby example
|
||||||
|
|
||||||
|
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Ruby uses
|
||||||
|
|
||||||
|
- [`rspec`](https://rspec.info/) to run tests.
|
||||||
|
- [`simplecov`](https://github.com/simplecov-ruby/simplecov) and [`simplecov-cobertura`](https://github.com/dashingrocket/simplecov-cobertura)
|
||||||
|
to record the coverage profile and create a report in the Cobertura XML format.
|
||||||
|
|
||||||
|
This example assumes:
|
||||||
|
|
||||||
|
- That [`bundler`](https://bundler.io/) is being used for dependency management.
|
||||||
|
The `rspec`, `simplecov` and `simplecov-cobertura` gems have been added to your `Gemfile`.
|
||||||
|
- The `CoberturaFormatter` has been added to your `SimpleCov.formatters`
|
||||||
|
configuration within the `spec_helper.rb` file.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
run tests:
|
||||||
|
stage: test
|
||||||
|
image: ruby:3.1
|
||||||
|
script:
|
||||||
|
- bundle install
|
||||||
|
- bundle exec rspec
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
cobertura: coverage/coverage.xml
|
||||||
|
```
|
||||||
|
|
|
@ -305,6 +305,7 @@ module API
|
||||||
mount ::API::Internal::Pages
|
mount ::API::Internal::Pages
|
||||||
mount ::API::Internal::Kubernetes
|
mount ::API::Internal::Kubernetes
|
||||||
mount ::API::Internal::MailRoom
|
mount ::API::Internal::MailRoom
|
||||||
|
mount ::API::Internal::ContainerRegistry::Migration
|
||||||
|
|
||||||
version 'v3', using: :path do
|
version 'v3', using: :path do
|
||||||
# Although the following endpoints are kept behind V3 namespace,
|
# Although the following endpoints are kept behind V3 namespace,
|
||||||
|
|
|
@ -6,7 +6,7 @@ module API
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
||||||
rescue_from Faraday::Error, ContainerRegistry::Path::InvalidRegistryPathError do |e|
|
rescue_from Faraday::Error, ::ContainerRegistry::Path::InvalidRegistryPathError do |e|
|
||||||
service_unavailable!('We are having trouble connecting to the Container Registry. If this error persists, please review the troubleshooting documentation.')
|
service_unavailable!('We are having trouble connecting to the Container Registry. If this error persists, please review the troubleshooting documentation.')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
63
lib/api/internal/container_registry/migration.rb
Normal file
63
lib/api/internal/container_registry/migration.rb
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module API
|
||||||
|
module Internal
|
||||||
|
module ContainerRegistry
|
||||||
|
class Migration < ::API::Base
|
||||||
|
feature_category :container_registry
|
||||||
|
|
||||||
|
STATUS_PRE_IMPORT_COMPLETE = 'pre_import_complete'
|
||||||
|
STATUS_PRE_IMPORT_FAILED = 'pre_import_failed'
|
||||||
|
STATUS_IMPORT_COMPLETE = 'import_complete'
|
||||||
|
STATUS_IMPORT_FAILED = 'import_failed'
|
||||||
|
POSSIBLE_VALUES = [
|
||||||
|
STATUS_PRE_IMPORT_COMPLETE,
|
||||||
|
STATUS_PRE_IMPORT_FAILED,
|
||||||
|
STATUS_IMPORT_COMPLETE,
|
||||||
|
STATUS_IMPORT_FAILED
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
before { authenticate! }
|
||||||
|
|
||||||
|
helpers do
|
||||||
|
def authenticate!
|
||||||
|
secret_token = Gitlab.config.registry.notification_secret
|
||||||
|
|
||||||
|
unauthorized! unless Devise.secure_compare(secret_token, headers['Authorization'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_repository!(path)
|
||||||
|
::ContainerRepository.find_by_path!(::ContainerRegistry::Path.new(path))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
params do
|
||||||
|
requires :repository_path, type: String, desc: 'The container repository path'
|
||||||
|
requires :status, type: String, values: POSSIBLE_VALUES, desc: 'The migration step status'
|
||||||
|
end
|
||||||
|
put 'internal/registry/repositories/*repository_path/migration/status' do
|
||||||
|
repository = find_repository!(declared_params[:repository_path])
|
||||||
|
|
||||||
|
unless repository.migration_in_active_state?
|
||||||
|
bad_request!("Wrong migration state (#{repository.migration_state})")
|
||||||
|
end
|
||||||
|
|
||||||
|
case declared_params[:status]
|
||||||
|
when STATUS_PRE_IMPORT_COMPLETE
|
||||||
|
unless repository.finish_pre_import_and_start_import
|
||||||
|
bad_request!("Couldn't transition from pre_importing to importing")
|
||||||
|
end
|
||||||
|
when STATUS_IMPORT_COMPLETE
|
||||||
|
unless repository.finish_import
|
||||||
|
bad_request!("Couldn't transition from importing to import_done")
|
||||||
|
end
|
||||||
|
when STATUS_IMPORT_FAILED, STATUS_PRE_IMPORT_FAILED
|
||||||
|
repository.abort_import
|
||||||
|
end
|
||||||
|
|
||||||
|
status 200
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.0
Symbolic link
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.0
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.0
|
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.1
Symbolic link
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.1
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.1
|
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.2
Symbolic link
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.2
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.2
|
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.3
Symbolic link
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.3
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.3
|
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.4
Symbolic link
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.4
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.4
|
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.5
Symbolic link
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.5
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.5
|
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.6
Symbolic link
1
lib/gitlab/ci/parsers/security/validators/schemas/14.0.6
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.6
|
1
lib/gitlab/ci/parsers/security/validators/schemas/14.1.0
Symbolic link
1
lib/gitlab/ci/parsers/security/validators/schemas/14.1.0
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.1.0
|
|
@ -315,14 +315,14 @@ describe('fetchMilestones', () => {
|
||||||
'project',
|
'project',
|
||||||
{
|
{
|
||||||
query: projectBoardMilestones,
|
query: projectBoardMilestones,
|
||||||
variables: { fullPath: 'gitlab-org/gitlab', state: 'active' },
|
variables: { fullPath: 'gitlab-org/gitlab' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'group',
|
'group',
|
||||||
{
|
{
|
||||||
query: groupBoardMilestones,
|
query: groupBoardMilestones,
|
||||||
variables: { fullPath: 'gitlab-org/gitlab', state: 'active' },
|
variables: { fullPath: 'gitlab-org/gitlab' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
])(
|
])(
|
||||||
|
|
|
@ -6,7 +6,7 @@ exports[`Blob Simple Viewer component rendering matches the snapshot 1`] = `
|
||||||
class="file-content code js-syntax-highlight"
|
class="file-content code js-syntax-highlight"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="line-numbers"
|
class="line-numbers gl-pt-0!"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
class="diff-line-num js-line-number"
|
class="diff-line-num js-line-number"
|
||||||
|
@ -56,7 +56,7 @@ exports[`Blob Simple Viewer component rendering matches the snapshot 1`] = `
|
||||||
class="blob-content"
|
class="blob-content"
|
||||||
>
|
>
|
||||||
<pre
|
<pre
|
||||||
class="code highlight"
|
class="code highlight gl-p-0! gl-display-flex"
|
||||||
>
|
>
|
||||||
<code
|
<code
|
||||||
data-blob-hash="foo-bar"
|
data-blob-hash="foo-bar"
|
||||||
|
|
|
@ -312,6 +312,21 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
||||||
expect { repository.skip_import }.to raise_error(ArgumentError)
|
expect { repository.skip_import }.to raise_error(ArgumentError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#finish_pre_import_and_start_import' do
|
||||||
|
let_it_be_with_reload(:repository) { create(:container_repository, :pre_importing) }
|
||||||
|
|
||||||
|
subject { repository.finish_pre_import_and_start_import }
|
||||||
|
|
||||||
|
before do |example|
|
||||||
|
unless example.metadata[:skip_import_success]
|
||||||
|
allow(repository).to receive(:migration_import).and_return(:ok)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'transitioning from allowed states', %w[pre_importing]
|
||||||
|
it_behaves_like 'transitioning to importing'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#tag' do
|
describe '#tag' do
|
||||||
|
@ -819,6 +834,18 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
||||||
it { is_expected.to eq([repository]) }
|
it { is_expected.to eq([repository]) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#migration_in_active_state?' do
|
||||||
|
subject { container_repository.migration_in_active_state? }
|
||||||
|
|
||||||
|
ContainerRepository::MIGRATION_STATES.each do |state|
|
||||||
|
context "when in #{state} migration_state" do
|
||||||
|
let(:container_repository) { create(:container_repository, state.to_sym)}
|
||||||
|
|
||||||
|
it { is_expected.to eq(state == 'importing' || state == 'pre_importing') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#migration_importing?' do
|
describe '#migration_importing?' do
|
||||||
subject { container_repository.migration_importing? }
|
subject { container_repository.migration_importing? }
|
||||||
|
|
||||||
|
@ -831,6 +858,18 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#migration_pre_importing?' do
|
||||||
|
subject { container_repository.migration_pre_importing? }
|
||||||
|
|
||||||
|
ContainerRepository::MIGRATION_STATES.each do |state|
|
||||||
|
context "when in #{state} migration_state" do
|
||||||
|
let(:container_repository) { create(:container_repository, state.to_sym)}
|
||||||
|
|
||||||
|
it { is_expected.to eq(state == 'pre_importing') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'with repositories' do
|
context 'with repositories' do
|
||||||
let_it_be_with_reload(:repository) { create(:container_repository, :cleanup_unscheduled) }
|
let_it_be_with_reload(:repository) { create(:container_repository, :cleanup_unscheduled) }
|
||||||
let_it_be(:other_repository) { create(:container_repository, :cleanup_unscheduled) }
|
let_it_be(:other_repository) { create(:container_repository, :cleanup_unscheduled) }
|
||||||
|
|
153
spec/requests/api/internal/container_registry/migration_spec.rb
Normal file
153
spec/requests/api/internal/container_registry/migration_spec.rb
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe API::Internal::ContainerRegistry::Migration do
|
||||||
|
let_it_be_with_reload(:repository) { create(:container_repository) }
|
||||||
|
|
||||||
|
let(:secret_token) { 'secret_token' }
|
||||||
|
let(:sent_token) { secret_token }
|
||||||
|
let(:repository_path) { repository.path }
|
||||||
|
let(:status) { 'pre_import_complete' }
|
||||||
|
let(:params) { { path: repository.path, status: status } }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(Gitlab.config.registry).to receive(:notification_secret) { secret_token }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'PUT /internal/registry/repositories/:path/migration/status' do
|
||||||
|
subject do
|
||||||
|
put api("/internal/registry/repositories/#{repository_path}/migration/status"),
|
||||||
|
params: params,
|
||||||
|
headers: { 'Authorization' => sent_token }
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples 'returning an error' do |with_message: nil, returning_status: :bad_request|
|
||||||
|
it "returns bad request response" do
|
||||||
|
expect { subject }
|
||||||
|
.not_to change { repository.reload.migration_state }
|
||||||
|
|
||||||
|
expect(response).to have_gitlab_http_status(returning_status)
|
||||||
|
expect(response.body).to include(with_message) if with_message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a valid sent token' do
|
||||||
|
shared_examples 'updating the repository migration status' do |from:, to:|
|
||||||
|
it "updates the migration status from #{from} to #{to}" do
|
||||||
|
expect { subject }
|
||||||
|
.to change { repository.reload.migration_state }.from(from).to(to)
|
||||||
|
|
||||||
|
expect(response).to have_gitlab_http_status(:ok)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with status pre_import_complete' do
|
||||||
|
let(:status) { 'pre_import_complete' }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', with_message: 'Wrong migration state (default)'
|
||||||
|
|
||||||
|
context 'with repository in pre_importing migration state' do
|
||||||
|
let(:repository) { create(:container_repository, :pre_importing) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow_next_found_instance_of(ContainerRepository) do |found_repository|
|
||||||
|
allow(found_repository).to receive(:migration_import).and_return(:ok)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'updating the repository migration status', from: 'pre_importing', to: 'importing'
|
||||||
|
|
||||||
|
context 'with a failing transition' do
|
||||||
|
before do
|
||||||
|
allow_next_found_instance_of(ContainerRepository) do |found_repository|
|
||||||
|
allow(found_repository).to receive(:finish_pre_import_and_start_import).and_return(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', with_message: "Couldn't transition from pre_importing to importing"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with repository in importing migration state' do
|
||||||
|
let(:repository) { create(:container_repository, :importing) }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', with_message: "Couldn't transition from pre_importing to importing"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with status import_complete' do
|
||||||
|
let(:status) { 'import_complete' }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', with_message: 'Wrong migration state (default)'
|
||||||
|
|
||||||
|
context 'with repository in importing migration state' do
|
||||||
|
let(:repository) { create(:container_repository, :importing) }
|
||||||
|
let(:transition_result) { true }
|
||||||
|
|
||||||
|
it_behaves_like 'updating the repository migration status', from: 'importing', to: 'import_done'
|
||||||
|
|
||||||
|
context 'with a failing transition' do
|
||||||
|
before do
|
||||||
|
allow_next_found_instance_of(ContainerRepository) do |found_repository|
|
||||||
|
allow(found_repository).to receive(:finish_import).and_return(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', with_message: "Couldn't transition from importing to import_done"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with repository in pre_importing migration state' do
|
||||||
|
let(:repository) { create(:container_repository, :pre_importing) }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', with_message: "Couldn't transition from importing to import_done"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%w[pre_import_failed import_failed].each do |status|
|
||||||
|
context 'with status pre_import_failed' do
|
||||||
|
let(:status) { 'pre_import_failed' }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', with_message: 'Wrong migration state (default)'
|
||||||
|
|
||||||
|
context 'with repository in importing migration state' do
|
||||||
|
let(:repository) { create(:container_repository, :importing) }
|
||||||
|
|
||||||
|
it_behaves_like 'updating the repository migration status', from: 'importing', to: 'import_aborted'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with repository in pre_importing migration state' do
|
||||||
|
let(:repository) { create(:container_repository, :pre_importing) }
|
||||||
|
|
||||||
|
it_behaves_like 'updating the repository migration status', from: 'pre_importing', to: 'import_aborted'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a non existing path' do
|
||||||
|
let(:repository_path) { 'this/does/not/exist' }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', returning_status: :not_found
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with invalid status' do
|
||||||
|
let(:params) { super().merge(status: nil).compact }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', returning_status: :bad_request
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with invalid path' do
|
||||||
|
let(:repository_path) { nil }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', returning_status: :not_found
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with an invalid sent token' do
|
||||||
|
let(:sent_token) { 'not_valid' }
|
||||||
|
|
||||||
|
it_behaves_like 'returning an error', returning_status: :unauthorized
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue