Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-11-24 21:12:47 +00:00
parent 844eb8879a
commit 1f3baf00bf
33 changed files with 461 additions and 310 deletions

View File

@ -46,7 +46,6 @@ export default {
data() {
return {
containerRepository: {},
fetchTagsCount: false,
};
},
apollo: {

View File

@ -9,6 +9,7 @@ query getContainerRepositoryTags(
) {
containerRepository(id: $id) {
id
tagsCount
tags(after: $after, before: $before, first: $first, last: $last) {
nodes {
digest

View File

@ -25,9 +25,11 @@ import {
UNFINISHED_STATUS,
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
ROOT_IMAGE_TEXT,
GRAPHQL_PAGE_SIZE,
} from '../constants/index';
import deleteContainerRepositoryTagsMutation from '../graphql/mutations/delete_container_repository_tags.mutation.graphql';
import getContainerRepositoryDetailsQuery from '../graphql/queries/get_container_repository_details.query.graphql';
import getContainerRepositoryTagsQuery from '../graphql/queries/get_container_repository_tags.query.graphql';
export default {
name: 'RegistryDetailsPage',
@ -133,8 +135,8 @@ export default {
awaitRefetchQueries: true,
refetchQueries: [
{
query: getContainerRepositoryDetailsQuery,
variables: this.queryVariables,
query: getContainerRepositoryTagsQuery,
variables: { ...this.queryVariables, first: GRAPHQL_PAGE_SIZE },
},
],
});

View File

@ -64,7 +64,7 @@ export default {
<gl-button
:loading="loading"
:variant="user.attention_requested ? 'warning' : 'default'"
:icon="user.attention_requested ? 'star' : 'star-o'"
:icon="user.attention_requested ? 'attention-solid' : 'attention'"
:aria-label="tooltipTitle"
size="small"
category="tertiary"

View File

@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338350
milestone: '14.3'
type: development
group: group::memory
default_enabled: false
default_enabled: true

View File

@ -9,6 +9,8 @@ Rails.application.configure do
config.action_cable.worker_pool_size = Gitlab::ActionCable::Config.worker_pool_size
end
ActionCable::SubscriptionAdapter::Base.prepend(Gitlab::Patch::ActionCableSubscriptionAdapterIdentifier)
# https://github.com/rails/rails/blob/bb5ac1623e8de08c1b7b62b1368758f0d3bb6379/actioncable/lib/action_cable/subscription_adapter/redis.rb#L18
ActionCable::SubscriptionAdapter::Redis.redis_connector = lambda do |config|
args = config.except(:adapter, :channel_prefix)

View File

@ -1354,7 +1354,7 @@ PUT /projects/:id
```
For example, to toggle the setting for
[shared runners on a GitLab.com project](../user/gitlab_com/index.md#shared-runner-cloud-runners):
[shared runners on a GitLab.com project](../ci/runners/index.md):
```shell
curl --request PUT --header "PRIVATE-TOKEN: <your-token>" \

View File

@ -1623,6 +1623,7 @@ Returns:
- `201 Created` on success.
- `404 User Not Found` if user cannot be found.
- `403 Forbidden` if the user cannot be approved because they are blocked by an administrator or by LDAP synchronization.
- `409 Conflict` if the user has been deactivated.
Example Responses:

View File

@ -259,5 +259,5 @@ For very active repositories with a large number of references and files, you ca
must be configured per-repository. The pack-objects cache also automatically works for forks. On GitLab.com, where the pack-objects cache is
enabled on all Gitaly servers, we found that we no longer need a pre-clone step for `gitlab-org/gitlab` development.
- Optimize your CI/CD jobs by seeding repository data in a pre-clone step with the
[`pre_clone_script`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section) of GitLab Runner. See the
[Runner Cloud for Linux](../runners/runner_cloud/linux_runner_cloud.md#pre-clone-script) for more details.
[`pre_clone_script`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section) of GitLab Runner. See
[SaaS runners on Linux](../runners/runner_cloud/linux_runner_cloud.md#pre-clone-script) for details.

View File

@ -5,12 +5,12 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
# GitLab Runner Cloud **(FREE)**
# Runner SaaS **(FREE SAAS)**
If you are using self-managed GitLab or you want to use your own runners on GitLab.com, you can
If you are using self-managed GitLab or you use GitLab.com but want to use your own runners, you can
[install and configure your own runners](https://docs.gitlab.com/runner/install/).
If you are using GitLab SaaS (GitLab.com), your CI jobs automatically run on runners in the GitLab Runner Cloud.
If you are using GitLab SaaS (GitLab.com), your CI jobs automatically run on runners provided by GitLab.
No configuration is required. Your jobs can run on:
- [Linux runners](build_cloud/linux_build_cloud.md).

View File

@ -4,9 +4,9 @@ group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Runner Cloud for Linux **(FREE)**
# SaaS runners on Linux **(FREE SAAS)**
Runner Cloud runners for Linux run in autoscale mode and are powered by Google Cloud Platform.
SaaS runners on Linux are autoscaled ephemeral Google Cloud Platform virtual machines.
Autoscaling means reduced queue times to spin up CI/CD jobs, and isolated VMs for each job, thus maximizing security. These shared runners are available on GitLab.com.
@ -38,7 +38,7 @@ These runners share a [distributed cache](https://docs.gitlab.com/runner/configu
## Pre-clone script
Cloud runners for Linux provide a way to run commands in a CI
With SaaS runners on Linux, you can run commands in a CI
job before the runner attempts to run `git init` and `git fetch` to
download a GitLab repository. The
[`pre_clone_script`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section)

View File

@ -4,9 +4,9 @@ group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# VM instances and images for Runner Cloud for macOS **(FREE)**
# VM instances and images for SaaS runners on macOS **(FREE SAAS)**
When you use the Runner Cloud for macOS:
When you use SaaS runners on macOS:
- Each of your jobs runs in a newly provisioned VM, which is dedicated to the specific job.
- The VM is active only for the duration of the job and immediately deleted.

View File

@ -4,19 +4,20 @@ group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Runner Cloud for macOS (Beta) **(FREE SAAS)**
# SaaS runners on macOS (Beta) **(FREE SAAS)**
The Runner Cloud for macOS Beta provides on-demand runners integrated with GitLab SaaS [CI/CD](../../../ci/index.md).
SaaS runners on macOS provide an on-demand macOS build environment integrated with
GitLab SaaS [CI/CD](../../../ci/index.md).
Use these runners to build, test, and deploy apps for the Apple ecosystem (macOS, iOS, tvOS). You can take advantage
of all the capabilities of the GitLab single DevOps platform and not have to manage or operate a
build environment.
Cloud runners for macOS are in [Beta](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta)
SaaS runners on macOS are in [Beta](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta)
and shouldn't be relied upon for mission-critical production jobs.
## Quickstart
To start using Runner Cloud for macOS Beta, you must submit an access request [issue](https://gitlab.com/gitlab-com/macos-buildcloud-runners-beta/-/issues/new?issuable_template=beta_access_request). After your
To start using SaaS runners on macOS, you must submit an access request [issue](https://gitlab.com/gitlab-com/macos-buildcloud-runners-beta/-/issues/new?issuable_template=beta_access_request). After your
access has been granted and your build environment configured, you must configure your
`.gitlab-ci.yml` pipeline file:
@ -28,10 +29,10 @@ The runners automatically run your build.
## Example `.gitlab-ci.yml` file
The following sample `.gitlab-ci.yml` file shows how to start using the runners for macOS:
The following sample `.gitlab-ci.yml` file shows how to start using the SaaS runners on macOS:
```yaml
.macos_buildcloud_runners:
.macos_saas_runners:
tags:
- shared-macos-amd64
image: macos-11-xcode-12
@ -45,14 +46,14 @@ before_script:
build:
extends:
- .macos_buildcloud_runners
- .macos_saas_runners
stage: build
script:
- echo "running scripts in the build job"
test:
extends:
- .macos_buildcloud_runners
- .macos_saas_runners
stage: test
script:
- echo "running scripts in the test job"

View File

@ -4,9 +4,9 @@ group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Runner Cloud for Windows (beta) **(FREE)**
# SaaS runners on Windows (beta) **(FREE SAAS)**
Runner Cloud runners for Windows are in [beta](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta)
SaaS runners on Windows are in [beta](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta)
and shouldn't be used for production workloads.
During this beta period, the [shared runner pipeline quota](../../../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota)

View File

@ -139,8 +139,9 @@ In these cases, use the following workflow:
and approval from the VP of Development, the DRI for Development Guidelines,
@clefelhocz1.
1. After all approvals are complete, assign the merge request to the
Technical Writer for [Development Guidelines](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines)
1. After all approvals are complete, review the page's metadata to
[find a Technical Writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments)
who can help you merge the changes.
for final content review and merge. The Technical Writer may ask for
additional approvals as previously suggested before merging the MR.

View File

@ -342,6 +342,7 @@ end
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69372) in GitLab 14.3.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/338350) in GitLab 14.4.
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/338350) in GitLab 14.6.
The deduplication always take into account the latest binary replication pointer, not the first one.
This happens because we drop the same job scheduled for the second time and the Write-Ahead Log (WAL) is lost.
@ -353,15 +354,11 @@ This way we are always comparing the latest binary replication pointer,
making sure that we read from the replica that is fully caught up.
FLAG:
On self-managed GitLab, by default this feature is not available.
To make it available,
ask an administrator to [enable the preserve_latest_wal_locations_for_idempotent_jobs flag](../administration/feature_flags.md).
FLAG:
On self-managed GitLab, by default this feature is not available.
To make it available,
ask an administrator to [enable the `preserve_latest_wal_locations_for_idempotent_jobs` flag](../administration/feature_flags.md).
On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to
[disable the feature flag](../administration/feature_flags.md) named preserve_latest_wal_locations_for_idempotent_jobs flag.
This feature flag is related to GitLab development and is not intended to be used by GitLab administrators, though.
On GitLab.com, this feature is available but can be configured by GitLab.com administrators only.
On GitLab.com, this feature is available.
## Limited capacity worker

View File

@ -302,7 +302,8 @@ The GitLab Runner server requirements depend on:
Since the nature of the jobs varies for each use case, you need to experiment by adjusting the job concurrency to get the optimum setting.
For reference, the GitLab.com Runner Cloud [auto-scaling runner for Linux](../ci/runners/build_cloud/linux_build_cloud.md) is configured so that a **single job** runs in a **single instance** with:
For reference, the [SaaS runners on Linux](../ci/runners/build_cloud/linux_build_cloud.md)
are configured so that a **single job** runs in a **single instance** with:
- 1 vCPU.
- 3.75 GB of RAM.

View File

@ -42,5 +42,6 @@ Align your work across teams.
- [Epics](../user/group/epics/index.md)
- [Multi-level epics](../user/group/epics/manage_epics.md#multi-level-child-epics)
- [Epic boards](../user/group/epics/epic_boards.md)
- [View heath status](../user/project/issues/managing_issues.md#health-status)
- [View health status](../user/project/issues/managing_issues.md#health-status)
- [Roadmaps](../user/group/roadmap/index.md)
- [Planning hierarchies](../user/group/planning_hierarchy/index.md)

View File

@ -200,11 +200,11 @@ The following limits apply for [Webhooks](../project/integrations/webhooks.md):
| [Number of webhooks](../../administration/instance_limits.md#number-of-webhooks) | `100` per project, `50` per group | `100` per project, `50` per group |
| Maximum payload size | 25 MB | 25 MB |
## Shared Runner Cloud runners
## Runner SaaS
GitLab has shared runners on GitLab.com that you can use to run your CI jobs.
Runner SaaS is the hosted, secure, and managed build environment you can use to run CI/CD jobs for your GitLab.com hosted project.
For more information, see [GitLab Runner Cloud runners](../../ci/runners/index.md).
For more information, see [Runner SaaS](../../ci/runners/index.md).
## Sidekiq

View File

@ -41,6 +41,8 @@ graph TD
Child_epic --> Issue2
```
Also, read more about possible [planning hierarchies](../planning_hierarchy/index.md).
## Roadmap in epics **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7327) in GitLab 11.10.

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,59 @@
---
type: reference
stage: Plan
group: Product Planning
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Planning hierarchies **(PREMIUM)**
Planning hierarchies are an integral part of breaking down your work in GitLab.
To understand how you can use epics and issues together in hierarchies, remember the following:
- [Epics](../epics/index.md) exist in groups.
- [Issues](../../project/issues/index.md) exist in projects.
GitLab is not opinionated on how you structure your work and the hierarchy you can build with multi-level
epics. For example, you can use the hierarchy as a folder of issues for bigger initiatives.
To learn about hierarchies in general, common frameworks, and using GitLab for
portfolio management, see
[How to use GitLab for Agile portfolio planning and project management](https://about.gitlab.com/blog/2020/11/11/gitlab-for-agile-portfolio-planning-project-management/).
## Hierarchies with epics
With epics, you can achieve the following hierarchy:
```mermaid
graph TD
Group_epic --> Project1_Issue1
Group_epic --> Project1_Issue2
Group_epic --> Project2_Issue1
```
### Hierarchies with multi-level epics **(ULTIMATE)**
With the addition of [multi-level epics](../epics/manage_epics.md#multi-level-child-epics) and up to
seven levels of nested epics, you can achieve the following hierarchy:
```mermaid
classDiagram
direction TD
class Epic
class Issue
Epic *-- "0..7" Epic
Epic "1" *-- "0..*" Issue
```
## View ancestry of an epic
In an epic, you can view the ancestors as parents in the right sidebar under **Ancestors**.
![epics state dropdown](img/epic-view-ancestors-in-sidebar_v14_6.png)
## View ancestry of an issue
In an issue, you can view the parented epic above the issue in the right sidebar under **Epic**.
![epics state dropdown](img/issue-view-parent-epic-in-sidebar_v14_6.png)

View File

@ -4,6 +4,7 @@ module Gitlab
module Database
module MigrationHelpers
include Migrations::BackgroundMigrationHelpers
include Migrations::BatchedBackgroundMigrationHelpers
include DynamicModelHelpers
include RenameTableHelpers
include AsyncIndexes::MigrationHelpers

View File

@ -5,11 +5,7 @@ module Gitlab
module Migrations
module BackgroundMigrationHelpers
BATCH_SIZE = 1_000 # Number of rows to process per job
SUB_BATCH_SIZE = 100 # Number of rows to process per sub-batch
JOB_BUFFER_SIZE = 1_000 # Number of jobs to bulk queue at a time
BATCH_CLASS_NAME = 'PrimaryKeyBatchingStrategy' # Default batch class for batched migrations
BATCH_MIN_VALUE = 1 # Default minimum value for batched migrations
BATCH_MIN_DELAY = 2.minutes.freeze # Minimum delay between batched migrations
# Bulk queues background migration jobs for an entire table, batched by ID range.
# "Bulk" meaning many jobs will be pushed at a time for efficiency.
@ -170,102 +166,6 @@ module Gitlab
duration
end
# Creates a batched background migration for the given table. A batched migration runs one job
# at a time, computing the bounds of the next batch based on the current migration settings and the previous
# batch bounds. Each job's execution status is tracked in the database as the migration runs. The given job
# class must be present in the Gitlab::BackgroundMigration module, and the batch class (if specified) must be
# present in the Gitlab::BackgroundMigration::BatchingStrategies module.
#
# If migration with same job_class_name, table_name, column_name, and job_aruments already exists, this helper
# will log an warning and not create a new one.
#
# job_class_name - The background migration job class as a string
# batch_table_name - The name of the table the migration will batch over
# batch_column_name - The name of the column the migration will batch over
# job_arguments - Extra arguments to pass to the job instance when the migration runs
# job_interval - The pause interval between each job's execution, minimum of 2 minutes
# batch_min_value - The value in the column the batching will begin at
# batch_max_value - The value in the column the batching will end at, defaults to `SELECT MAX(batch_column)`
# batch_class_name - The name of the class that will be called to find the range of each next batch
# batch_size - The maximum number of rows per job
# sub_batch_size - The maximum number of rows processed per "iteration" within the job
#
#
# *Returns the created BatchedMigration record*
#
# Example:
#
# queue_batched_background_migration(
# 'CopyColumnUsingBackgroundMigrationJob',
# :events,
# :id,
# job_interval: 2.minutes,
# other_job_arguments: ['column1', 'column2'])
#
# Where the the background migration exists:
#
# class Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJob
# def perform(start_id, end_id, batch_table, batch_column, sub_batch_size, *other_args)
# # do something
# end
# end
def queue_batched_background_migration( # rubocop:disable Metrics/ParameterLists
job_class_name,
batch_table_name,
batch_column_name,
*job_arguments,
job_interval:,
batch_min_value: BATCH_MIN_VALUE,
batch_max_value: nil,
batch_class_name: BATCH_CLASS_NAME,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
if Gitlab::Database::BackgroundMigration::BatchedMigration.for_configuration(job_class_name, batch_table_name, batch_column_name, job_arguments).exists?
Gitlab::AppLogger.warn "Batched background migration not enqueued because it already exists: " \
"job_class_name: #{job_class_name}, table_name: #{batch_table_name}, column_name: #{batch_column_name}, " \
"job_arguments: #{job_arguments.inspect}"
return
end
job_interval = BATCH_MIN_DELAY if job_interval < BATCH_MIN_DELAY
batch_max_value ||= connection.select_value(<<~SQL)
SELECT MAX(#{connection.quote_column_name(batch_column_name)})
FROM #{connection.quote_table_name(batch_table_name)}
SQL
migration_status = batch_max_value.nil? ? :finished : :active
batch_max_value ||= batch_min_value
migration = Gitlab::Database::BackgroundMigration::BatchedMigration.create!(
job_class_name: job_class_name,
table_name: batch_table_name,
column_name: batch_column_name,
job_arguments: job_arguments,
interval: job_interval,
min_value: batch_min_value,
max_value: batch_max_value,
batch_class_name: batch_class_name,
batch_size: batch_size,
sub_batch_size: sub_batch_size,
status: migration_status)
# This guard is necessary since #total_tuple_count was only introduced schema-wise,
# after this migration helper had been used for the first time.
return migration unless migration.respond_to?(:total_tuple_count)
# We keep track of the estimated number of tuples to reason later
# about the overall progress of a migration.
migration.total_tuple_count = Gitlab::Database::SharedModel.using_connection(connection) do
Gitlab::Database::PgClass.for_table(batch_table_name)&.cardinality_estimate
end
migration.save!
migration
end
# Force a background migration to complete.
#
# WARNING: This method will block the caller and move the background migration from an

View File

@ -0,0 +1,118 @@
# frozen_string_literal: true
module Gitlab
module Database
module Migrations
# BatchedBackgroundMigrations are a new approach to scheduling and executing background migrations, which uses
# persistent state in the database to track each migration. This avoids having to batch over an entire table and
# schedule a large number of sidekiq jobs upfront. It also provides for more flexibility as the migration runs,
# as it can be paused and restarted, and have configuration values like the batch size updated dynamically as the
# migration runs.
#
# For now, these migrations are not considered ready for general use, for more information see the tracking epic:
# https://gitlab.com/groups/gitlab-org/-/epics/6751
module BatchedBackgroundMigrationHelpers
BATCH_SIZE = 1_000 # Number of rows to process per job
SUB_BATCH_SIZE = 100 # Number of rows to process per sub-batch
BATCH_CLASS_NAME = 'PrimaryKeyBatchingStrategy' # Default batch class for batched migrations
BATCH_MIN_VALUE = 1 # Default minimum value for batched migrations
BATCH_MIN_DELAY = 2.minutes.freeze # Minimum delay between batched migrations
# Creates a batched background migration for the given table. A batched migration runs one job
# at a time, computing the bounds of the next batch based on the current migration settings and the previous
# batch bounds. Each job's execution status is tracked in the database as the migration runs. The given job
# class must be present in the Gitlab::BackgroundMigration module, and the batch class (if specified) must be
# present in the Gitlab::BackgroundMigration::BatchingStrategies module.
#
# If migration with same job_class_name, table_name, column_name, and job_aruments already exists, this helper
# will log an warning and not create a new one.
#
# job_class_name - The background migration job class as a string
# batch_table_name - The name of the table the migration will batch over
# batch_column_name - The name of the column the migration will batch over
# job_arguments - Extra arguments to pass to the job instance when the migration runs
# job_interval - The pause interval between each job's execution, minimum of 2 minutes
# batch_min_value - The value in the column the batching will begin at
# batch_max_value - The value in the column the batching will end at, defaults to `SELECT MAX(batch_column)`
# batch_class_name - The name of the class that will be called to find the range of each next batch
# batch_size - The maximum number of rows per job
# sub_batch_size - The maximum number of rows processed per "iteration" within the job
#
# *Returns the created BatchedMigration record*
#
# Example:
#
# queue_batched_background_migration(
# 'CopyColumnUsingBackgroundMigrationJob',
# :events,
# :id,
# job_interval: 2.minutes,
# other_job_arguments: ['column1', 'column2'])
#
# Where the the background migration exists:
#
# class Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJob
# def perform(start_id, end_id, batch_table, batch_column, sub_batch_size, *other_args)
# # do something
# end
# end
def queue_batched_background_migration( # rubocop:disable Metrics/ParameterLists
job_class_name,
batch_table_name,
batch_column_name,
*job_arguments,
job_interval:,
batch_min_value: BATCH_MIN_VALUE,
batch_max_value: nil,
batch_class_name: BATCH_CLASS_NAME,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
if Gitlab::Database::BackgroundMigration::BatchedMigration.for_configuration(job_class_name, batch_table_name, batch_column_name, job_arguments).exists?
Gitlab::AppLogger.warn "Batched background migration not enqueued because it already exists: " \
"job_class_name: #{job_class_name}, table_name: #{batch_table_name}, column_name: #{batch_column_name}, " \
"job_arguments: #{job_arguments.inspect}"
return
end
job_interval = BATCH_MIN_DELAY if job_interval < BATCH_MIN_DELAY
batch_max_value ||= connection.select_value(<<~SQL)
SELECT MAX(#{connection.quote_column_name(batch_column_name)})
FROM #{connection.quote_table_name(batch_table_name)}
SQL
migration_status = batch_max_value.nil? ? :finished : :active
batch_max_value ||= batch_min_value
migration = Gitlab::Database::BackgroundMigration::BatchedMigration.create!(
job_class_name: job_class_name,
table_name: batch_table_name,
column_name: batch_column_name,
job_arguments: job_arguments,
interval: job_interval,
min_value: batch_min_value,
max_value: batch_max_value,
batch_class_name: batch_class_name,
batch_size: batch_size,
sub_batch_size: sub_batch_size,
status: migration_status)
# This guard is necessary since #total_tuple_count was only introduced schema-wise,
# after this migration helper had been used for the first time.
return migration unless migration.respond_to?(:total_tuple_count)
# We keep track of the estimated number of tuples to reason later
# about the overall progress of a migration.
migration.total_tuple_count = Gitlab::Database::SharedModel.using_connection(connection) do
Gitlab::Database::PgClass.for_table(batch_table_name)&.cardinality_estimate
end
migration.save!
migration
end
end
end
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
# Modifies https://github.com/rails/rails/blob/v6.1.4.1/actioncable/lib/action_cable/subscription_adapter/base.rb so
# that we do not overwrite an id that was explicitly set to `nil` in cable.yml.
# This is needed to support GCP Memorystore. See https://github.com/rails/rails/issues/38244.
module Gitlab
module Patch
module ActionCableSubscriptionAdapterIdentifier
def identifier
@server.config.cable.has_key?(:id) ? @server.config.cable[:id] : super # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
end
end
end

View File

@ -167,6 +167,7 @@ export const imageTagsMock = (nodes = tagsMock) => ({
data: {
containerRepository: {
id: containerRepositoryMock.id,
tagsCount: nodes.length,
tags: {
nodes,
pageInfo: { ...tagsPageInfo },
@ -191,7 +192,7 @@ export const graphQLImageDetailsMock = (override) => ({
data: {
containerRepository: {
...containerRepositoryMock,
tagsCount: tagsMock.length,
tags: {
nodes: tagsMock,
pageInfo: { ...tagsPageInfo },

View File

@ -1,6 +1,7 @@
import { GlKeysetPagination } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
@ -22,6 +23,7 @@ import {
} from '~/packages_and_registries/container_registry/explorer/constants';
import deleteContainerRepositoryTagsMutation from '~/packages_and_registries/container_registry/explorer/graphql/mutations/delete_container_repository_tags.mutation.graphql';
import getContainerRepositoryDetailsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_details.query.graphql';
import getContainerRepositoryTagsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql';
import component from '~/packages_and_registries/container_registry/explorer/pages/details.vue';
import Tracking from '~/tracking';
@ -32,6 +34,7 @@ import {
containerRepositoryMock,
graphQLEmptyImageDetailsMock,
tagsMock,
imageTagsMock,
} from '../mock_data';
import { DeleteModal } from '../stubs';
@ -67,12 +70,13 @@ describe('Details Page', () => {
const waitForApolloRequestRender = async () => {
await waitForPromises();
await wrapper.vm.$nextTick();
await nextTick();
};
const mountComponent = ({
resolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock()),
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock),
tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock)),
options,
config = {},
} = {}) => {
@ -81,6 +85,7 @@ describe('Details Page', () => {
const requestHandlers = [
[getContainerRepositoryDetailsQuery, resolver],
[deleteContainerRepositoryTagsMutation, mutationResolver],
[getContainerRepositoryTagsQuery, tagsResolver],
];
apolloProvider = createMockApollo(requestHandlers);
@ -242,38 +247,49 @@ describe('Details Page', () => {
describe('confirmDelete event', () => {
let mutationResolver;
let tagsResolver;
beforeEach(() => {
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock);
mountComponent({ mutationResolver });
tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock));
mountComponent({ mutationResolver, tagsResolver });
return waitForApolloRequestRender();
});
describe('when one item is selected to be deleted', () => {
it('calls apollo mutation with the right parameters', async () => {
it('calls apollo mutation with the right parameters and refetches the tags list query', async () => {
findTagsList().vm.$emit('delete', [cleanTags[0]]);
await wrapper.vm.$nextTick();
await nextTick();
findDeleteModal().vm.$emit('confirmDelete');
expect(mutationResolver).toHaveBeenCalledWith(
expect.objectContaining({ tagNames: [cleanTags[0].name] }),
);
await waitForPromises();
expect(tagsResolver).toHaveBeenCalled();
});
});
describe('when more than one item is selected to be deleted', () => {
it('calls apollo mutation with the right parameters', async () => {
it('calls apollo mutation with the right parameters and refetches the tags list query', async () => {
findTagsList().vm.$emit('delete', tagsMock);
await wrapper.vm.$nextTick();
await nextTick();
findDeleteModal().vm.$emit('confirmDelete');
expect(mutationResolver).toHaveBeenCalledWith(
expect.objectContaining({ tagNames: tagsMock.map((t) => t.name) }),
);
await waitForPromises();
expect(tagsResolver).toHaveBeenCalled();
});
});
});
@ -382,7 +398,7 @@ describe('Details Page', () => {
findPartialCleanupAlert().vm.$emit('dismiss');
await wrapper.vm.$nextTick();
await nextTick();
expect(axios.post).toHaveBeenCalledWith(config.userCalloutsPath, {
feature_name: config.userCalloutId,
@ -472,7 +488,7 @@ describe('Details Page', () => {
await waitForApolloRequestRender();
findDetailsHeader().vm.$emit('delete');
await wrapper.vm.$nextTick();
await nextTick();
};
it('on delete event it deletes the image', async () => {
@ -497,13 +513,13 @@ describe('Details Page', () => {
findDeleteImage().vm.$emit('start');
await wrapper.vm.$nextTick();
await nextTick();
expect(findTagsLoader().exists()).toBe(true);
findDeleteImage().vm.$emit('end');
await wrapper.vm.$nextTick();
await nextTick();
expect(findTagsLoader().exists()).toBe(false);
});
@ -513,7 +529,7 @@ describe('Details Page', () => {
findDeleteImage().vm.$emit('error');
await wrapper.vm.$nextTick();
await nextTick();
expect(findDeleteAlert().props('deleteAlertType')).toBe(ALERT_DANGER_IMAGE);
});

View File

@ -23,8 +23,8 @@ describe('Attention require toggle', () => {
it.each`
attentionRequested | icon
${true} | ${'star'}
${false} | ${'star-o'}
${true} | ${'attention-solid'}
${false} | ${'attention'}
`(
'renders $icon icon when attention_requested is $attentionRequested',
({ attentionRequested, icon }) => {

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'ActionCableSubscriptionAdapterIdentifier override' do
describe '#identifier' do
context 'when id key is nil on cable.yml' do
it 'does not override server config id with action cable pid' do
config = {
adapter: 'redis',
url: 'unix:/home/localuser/redis/redis.socket',
channel_prefix: 'test_',
id: nil
}
::ActionCable::Server::Base.config.cable = config
sub = ActionCable.server.pubsub.send(:redis_connection)
expect(sub.connection[:id]).to eq('redis:///home/localuser/redis/redis.socket/0')
expect(ActionCable.server.config.cable[:id]).to be_nil
end
end
end
end

View File

@ -354,161 +354,6 @@ RSpec.describe Gitlab::Database::Migrations::BackgroundMigrationHelpers do
end
end
describe '#queue_batched_background_migration' do
let(:pgclass_info) { instance_double('Gitlab::Database::PgClass', cardinality_estimate: 42) }
before do
allow(Gitlab::Database::PgClass).to receive(:for_table).and_call_original
end
context 'when such migration already exists' do
it 'does not create duplicate migration' do
create(
:batched_background_migration,
job_class_name: 'MyJobClass',
table_name: :projects,
column_name: :id,
interval: 10.minutes,
min_value: 5,
max_value: 1005,
batch_class_name: 'MyBatchClass',
batch_size: 200,
sub_batch_size: 20,
job_arguments: [[:id], [:id_convert_to_bigint]]
)
expect do
model.queue_batched_background_migration(
'MyJobClass',
:projects,
:id,
[:id], [:id_convert_to_bigint],
job_interval: 5.minutes,
batch_min_value: 5,
batch_max_value: 1000,
batch_class_name: 'MyBatchClass',
batch_size: 100,
sub_batch_size: 10)
end.not_to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }
end
end
it 'creates the database record for the migration' do
expect(Gitlab::Database::PgClass).to receive(:for_table).with(:projects).and_return(pgclass_info)
expect do
model.queue_batched_background_migration(
'MyJobClass',
:projects,
:id,
job_interval: 5.minutes,
batch_min_value: 5,
batch_max_value: 1000,
batch_class_name: 'MyBatchClass',
batch_size: 100,
sub_batch_size: 10)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to have_attributes(
job_class_name: 'MyJobClass',
table_name: 'projects',
column_name: 'id',
interval: 300,
min_value: 5,
max_value: 1000,
batch_class_name: 'MyBatchClass',
batch_size: 100,
sub_batch_size: 10,
job_arguments: %w[],
status: 'active',
total_tuple_count: pgclass_info.cardinality_estimate)
end
context 'when the job interval is lower than the minimum' do
let(:minimum_delay) { described_class::BATCH_MIN_DELAY }
it 'sets the job interval to the minimum value' do
expect do
model.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: minimum_delay - 1.minute)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
created_migration = Gitlab::Database::BackgroundMigration::BatchedMigration.last
expect(created_migration.interval).to eq(minimum_delay)
end
end
context 'when additional arguments are passed to the method' do
it 'saves the arguments on the database record' do
expect do
model.queue_batched_background_migration(
'MyJobClass',
:projects,
:id,
'my',
'arguments',
job_interval: 5.minutes,
batch_max_value: 1000)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to have_attributes(
job_class_name: 'MyJobClass',
table_name: 'projects',
column_name: 'id',
interval: 300,
min_value: 1,
max_value: 1000,
job_arguments: %w[my arguments])
end
end
context 'when the max_value is not given' do
context 'when records exist in the database' do
let!(:event1) { create(:event) }
let!(:event2) { create(:event) }
let!(:event3) { create(:event) }
it 'creates the record with the current max value' do
expect do
model.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: 5.minutes)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
created_migration = Gitlab::Database::BackgroundMigration::BatchedMigration.last
expect(created_migration.max_value).to eq(event3.id)
end
it 'creates the record with an active status' do
expect do
model.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: 5.minutes)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to be_active
end
end
context 'when the database is empty' do
it 'sets the max value to the min value' do
expect do
model.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: 5.minutes)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
created_migration = Gitlab::Database::BackgroundMigration::BatchedMigration.last
expect(created_migration.max_value).to eq(created_migration.min_value)
end
it 'creates the record with a finished status' do
expect do
model.queue_batched_background_migration('MyJobClass', :projects, :id, job_interval: 5.minutes)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to be_finished
end
end
end
end
describe '#migrate_async' do
it 'calls BackgroundMigrationWorker.perform_async' do
expect(BackgroundMigrationWorker).to receive(:perform_async).with("Class", "hello", "world")

View File

@ -0,0 +1,164 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers do
let(:migration) do
ActiveRecord::Migration.new.extend(described_class)
end
describe '#queue_batched_background_migration' do
let(:pgclass_info) { instance_double('Gitlab::Database::PgClass', cardinality_estimate: 42) }
before do
allow(Gitlab::Database::PgClass).to receive(:for_table).and_call_original
end
context 'when such migration already exists' do
it 'does not create duplicate migration' do
create(
:batched_background_migration,
job_class_name: 'MyJobClass',
table_name: :projects,
column_name: :id,
interval: 10.minutes,
min_value: 5,
max_value: 1005,
batch_class_name: 'MyBatchClass',
batch_size: 200,
sub_batch_size: 20,
job_arguments: [[:id], [:id_convert_to_bigint]]
)
expect do
migration.queue_batched_background_migration(
'MyJobClass',
:projects,
:id,
[:id], [:id_convert_to_bigint],
job_interval: 5.minutes,
batch_min_value: 5,
batch_max_value: 1000,
batch_class_name: 'MyBatchClass',
batch_size: 100,
sub_batch_size: 10)
end.not_to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }
end
end
it 'creates the database record for the migration' do
expect(Gitlab::Database::PgClass).to receive(:for_table).with(:projects).and_return(pgclass_info)
expect do
migration.queue_batched_background_migration(
'MyJobClass',
:projects,
:id,
job_interval: 5.minutes,
batch_min_value: 5,
batch_max_value: 1000,
batch_class_name: 'MyBatchClass',
batch_size: 100,
sub_batch_size: 10)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to have_attributes(
job_class_name: 'MyJobClass',
table_name: 'projects',
column_name: 'id',
interval: 300,
min_value: 5,
max_value: 1000,
batch_class_name: 'MyBatchClass',
batch_size: 100,
sub_batch_size: 10,
job_arguments: %w[],
status: 'active',
total_tuple_count: pgclass_info.cardinality_estimate)
end
context 'when the job interval is lower than the minimum' do
let(:minimum_delay) { described_class::BATCH_MIN_DELAY }
it 'sets the job interval to the minimum value' do
expect do
migration.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: minimum_delay - 1.minute)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
created_migration = Gitlab::Database::BackgroundMigration::BatchedMigration.last
expect(created_migration.interval).to eq(minimum_delay)
end
end
context 'when additional arguments are passed to the method' do
it 'saves the arguments on the database record' do
expect do
migration.queue_batched_background_migration(
'MyJobClass',
:projects,
:id,
'my',
'arguments',
job_interval: 5.minutes,
batch_max_value: 1000)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to have_attributes(
job_class_name: 'MyJobClass',
table_name: 'projects',
column_name: 'id',
interval: 300,
min_value: 1,
max_value: 1000,
job_arguments: %w[my arguments])
end
end
context 'when the max_value is not given' do
context 'when records exist in the database' do
let!(:event1) { create(:event) }
let!(:event2) { create(:event) }
let!(:event3) { create(:event) }
it 'creates the record with the current max value' do
expect do
migration.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: 5.minutes)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
created_migration = Gitlab::Database::BackgroundMigration::BatchedMigration.last
expect(created_migration.max_value).to eq(event3.id)
end
it 'creates the record with an active status' do
expect do
migration.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: 5.minutes)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to be_active
end
end
context 'when the database is empty' do
it 'sets the max value to the min value' do
expect do
migration.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: 5.minutes)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
created_migration = Gitlab::Database::BackgroundMigration::BatchedMigration.last
expect(created_migration.max_value).to eq(created_migration.min_value)
end
it 'creates the record with a finished status' do
expect do
migration.queue_batched_background_migration('MyJobClass', :projects, :id, job_interval: 5.minutes)
end.to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }.by(1)
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to be_finished
end
end
end
end
end