Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
71722304be
commit
e4503e5d77
|
@ -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 Developer (30) 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
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
FilterFields,
|
||||
ListTypeTitles,
|
||||
DraggableItemTypes,
|
||||
active,
|
||||
} from 'ee_else_ce/boards/constants';
|
||||
import {
|
||||
formatIssueInput,
|
||||
|
@ -210,7 +209,6 @@ export default {
|
|||
const variables = {
|
||||
fullPath,
|
||||
searchTerm,
|
||||
state: active,
|
||||
};
|
||||
|
||||
let query;
|
||||
|
|
|
@ -245,7 +245,7 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<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="blobInfo"
|
||||
:hide-viewer-switcher="!hasRichViewer || isBinaryFileType || isUsingLfs"
|
||||
|
|
|
@ -51,7 +51,7 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<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
|
||||
v-for="line in lineNumbers"
|
||||
:id="`L${line}`"
|
||||
|
@ -67,7 +67,7 @@ export default {
|
|||
</div>
|
||||
<div class="blob-content">
|
||||
<pre
|
||||
class="code highlight"
|
||||
class="code highlight gl-p-0! gl-display-flex"
|
||||
><code v-safe-html="content" :data-blob-hash="blobHash"></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -116,13 +116,13 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<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"
|
||||
data-type="simple"
|
||||
data-qa-selector="blob_viewer_file_content"
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -96,7 +96,7 @@ class ContainerRepository < ApplicationRecord
|
|||
end
|
||||
|
||||
event :abort_import do
|
||||
transition %i[pre_importing importing] => :import_aborted
|
||||
transition ACTIVE_MIGRATION_STATES.map(&:to_sym) => :import_aborted
|
||||
end
|
||||
|
||||
event :skip_import do
|
||||
|
@ -205,6 +205,11 @@ class ContainerRepository < ApplicationRecord
|
|||
super
|
||||
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
|
||||
def registry
|
||||
@registry ||= begin
|
||||
|
@ -287,10 +292,18 @@ class ContainerRepository < ApplicationRecord
|
|||
update!(expiration_policy_started_at: Time.zone.now)
|
||||
end
|
||||
|
||||
def migration_in_active_state?
|
||||
migration_state.in?(ACTIVE_MIGRATION_STATES)
|
||||
end
|
||||
|
||||
def migration_importing?
|
||||
migration_state == 'importing'
|
||||
end
|
||||
|
||||
def migration_pre_importing?
|
||||
migration_state == 'pre_importing'
|
||||
end
|
||||
|
||||
def migration_pre_import
|
||||
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
|
||||
milestone: '13.2'
|
||||
type: development
|
||||
group: group::monitor
|
||||
group: group::respond
|
||||
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
|
||||
milestone: '14.6'
|
||||
type: development
|
||||
group: group::monitor
|
||||
group: group::respond
|
||||
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
|
||||
milestone: '13.4'
|
||||
type: development
|
||||
group: group::apm
|
||||
group: group::respond
|
||||
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
|
||||
milestone: '12.0'
|
||||
type: development
|
||||
group: group::monitor
|
||||
group: group::respond
|
||||
default_enabled: false
|
||||
|
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343286
|
|||
milestone: '14.8'
|
||||
type: development
|
||||
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
|
||||
milestone: '12.8'
|
||||
type: development
|
||||
group: group::monitor
|
||||
group: group::respond
|
||||
default_enabled: false
|
||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58606
|
|||
rollout_issue_url:
|
||||
milestone: '13.11'
|
||||
type: development
|
||||
group: group::monitor
|
||||
group: group::respond
|
||||
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
|
||||
milestone: '14.7'
|
||||
type: ops
|
||||
group: group::monitor
|
||||
group: group::respond
|
||||
default_enabled: false
|
||||
|
|
|
@ -4,6 +4,7 @@ Rails.autoloaders.each do |autoloader|
|
|||
# We need to ignore these since these are non-Ruby files
|
||||
# that do not define Ruby classes / modules
|
||||
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?
|
||||
|
||||
# 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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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`. |
|
||||
|
@ -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).
|
||||
|
||||
### 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
|
||||
|
||||
> [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
|
||||
|
||||
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:
|
||||
|
||||
|
|
|
@ -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
|
||||
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).
|
||||
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
|
||||
|
|
|
@ -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
|
||||
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 |
|
||||
|:----------------|:-------|:---------|:------------|
|
||||
|
@ -553,6 +553,14 @@ curl --request PUT --header "Gitlab-Kas-Api-Request: <JWT token>" \
|
|||
}'
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"uuid": "4773b2ee-5ba5-5e9f-b48c-5f7a17f0faac"
|
||||
}
|
||||
```
|
||||
|
||||
## Subscriptions
|
||||
|
||||
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.
|
||||
|
||||
![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
|
||||
|
||||
|
|
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:
|
||||
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::Kubernetes
|
||||
mount ::API::Internal::MailRoom
|
||||
mount ::API::Internal::ContainerRegistry::Migration
|
||||
|
||||
version 'v3', using: :path do
|
||||
# Although the following endpoints are kept behind V3 namespace,
|
||||
|
|
|
@ -6,7 +6,7 @@ module API
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
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.')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.0
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.1
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.2
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.3
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.4
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.5
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.0.6
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../ee/lib/ee/gitlab/ci/parsers/security/validators/schemas/14.1.0
|
|
@ -315,14 +315,14 @@ describe('fetchMilestones', () => {
|
|||
'project',
|
||||
{
|
||||
query: projectBoardMilestones,
|
||||
variables: { fullPath: 'gitlab-org/gitlab', state: 'active' },
|
||||
variables: { fullPath: 'gitlab-org/gitlab' },
|
||||
},
|
||||
],
|
||||
[
|
||||
'group',
|
||||
{
|
||||
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"
|
||||
>
|
||||
<div
|
||||
class="line-numbers"
|
||||
class="line-numbers gl-pt-0!"
|
||||
>
|
||||
<a
|
||||
class="diff-line-num js-line-number"
|
||||
|
@ -56,7 +56,7 @@ exports[`Blob Simple Viewer component rendering matches the snapshot 1`] = `
|
|||
class="blob-content"
|
||||
>
|
||||
<pre
|
||||
class="code highlight"
|
||||
class="code highlight gl-p-0! gl-display-flex"
|
||||
>
|
||||
<code
|
||||
data-blob-hash="foo-bar"
|
||||
|
|
|
@ -312,6 +312,21 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
|||
expect { repository.skip_import }.to raise_error(ArgumentError)
|
||||
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
|
||||
|
||||
describe '#tag' do
|
||||
|
@ -819,6 +834,18 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
|||
it { is_expected.to eq([repository]) }
|
||||
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
|
||||
subject { container_repository.migration_importing? }
|
||||
|
||||
|
@ -831,6 +858,18 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
|||
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
|
||||
let_it_be_with_reload(:repository) { create(:container_repository, :cleanup_unscheduled) }
|
||||
let_it_be(:other_repository) { create(:container_repository, :cleanup_unscheduled) }
|
||||
|
|
|
@ -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 New Issue