Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-05-06 00:09:23 +00:00
parent 055dceef99
commit 49f3210443
18 changed files with 284 additions and 143 deletions

View File

@ -489,6 +489,7 @@ export default {
:project-namespace="projectNamespace"
:can-attach-file="canAttachFile"
:enable-autocomplete="enableAutocomplete"
:issue-id="issueId"
:issuable-type="issuableType"
@updateForm="setFormState"
/>

View File

@ -60,7 +60,7 @@ export default {
:data-project-path="projectPath"
:data-project-id="projectId"
:data-data="issuableTemplatesJson"
class="dropdown-menu-toggle js-issuable-selector gl-button"
class="dropdown-menu-toggle js-issuable-selector gl-button gl-py-3!"
type="button"
data-field-name="issuable_template"
data-selected="null"

View File

@ -1,7 +1,11 @@
<script>
import { GlAlert } from '@gitlab/ui';
import ConvertDescriptionModal from 'ee_component/issues/show/components/convert_description_modal.vue';
import { getDraft, updateDraft, getLockVersion, clearDraft } from '~/lib/utils/autosave';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_ISSUE, TYPENAME_USER } from '~/graphql_shared/constants';
import { TYPE_ISSUE } from '~/issues/constants';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import eventHub from '../event_hub';
import EditActions from './edit_actions.vue';
import DescriptionField from './fields/description.vue';
@ -12,6 +16,7 @@ import LockedWarning from './locked_warning.vue';
export default {
components: {
ConvertDescriptionModal,
DescriptionField,
DescriptionTemplateField,
EditActions,
@ -20,6 +25,7 @@ export default {
IssuableTypeField,
LockedWarning,
},
mixins: [glFeatureFlagMixin()],
props: {
endpoint: {
type: String,
@ -73,6 +79,11 @@ export default {
required: false,
default: '',
},
issueId: {
type: Number,
required: false,
default: null,
},
},
data() {
const autosaveKey = [document.location.pathname, document.location.search];
@ -100,6 +111,12 @@ export default {
isIssueType() {
return this.issuableType === TYPE_ISSUE;
},
resourceId() {
return this.issueId && convertToGraphQLId(TYPENAME_ISSUE, this.issueId);
},
userId() {
return convertToGraphQLId(TYPENAME_USER, gon.current_user_id);
},
},
watch: {
formData: {
@ -158,6 +175,9 @@ export default {
updateDraft(this.descriptionAutosaveKey, description, this.formState.lock_version);
}
},
setDescription(desc) {
this.formData.description = desc;
},
},
};
</script>
@ -185,12 +205,12 @@ export default {
<issuable-title-field ref="title" v-model="formData.title" @input="updateTitleDraft" />
</div>
</div>
<div class="row">
<div class="row gl-gap-3">
<div v-if="isIssueType" class="col-12 col-md-4 pr-md-0">
<issuable-type-field ref="issue-type" />
</div>
<div v-if="hasIssuableTemplates" class="col-12 col-md-4 pl-md-2">
<div v-if="hasIssuableTemplates" class="col-12 col-md-4 gl-md-pl-0 gl-md-pr-0">
<description-template-field
v-model="formData.description"
:issuable-templates="issuableTemplates"
@ -199,6 +219,14 @@ export default {
:project-namespace="projectNamespace"
/>
</div>
<convert-description-modal
v-if="issueId && glFeatures.generateDescriptionAi"
class="gl-pl-5 gl-sm-pl-0"
:resource-id="resourceId"
:user-id="userId"
@contentGenerated="setDescription"
/>
</div>
<description-field

View File

@ -100,6 +100,9 @@ export default {
iid: {
default: '',
},
issuableId: {
default: '',
},
isIssueAuthor: {
default: false,
},
@ -323,7 +326,7 @@ export default {
</script>
<template>
<div class="detail-page-header-actions gl-display-flex gl-align-self-start">
<div class="detail-page-header-actions gl-display-flex gl-align-self-start gl-gap-3">
<gl-dropdown
v-if="hasMobileDropdown"
class="gl-sm-display-none! w-100"
@ -420,7 +423,7 @@ export default {
<gl-button
v-if="showToggleIssueStateButton"
class="gl-display-none gl-sm-display-inline-flex! gl-sm-ml-3"
class="gl-display-none gl-sm-display-inline-flex!"
:data-qa-selector="qaSelector"
:loading="isToggleStateButtonLoading"
data-testid="toggle-button"
@ -433,7 +436,7 @@ export default {
v-if="hasDesktopDropdown"
id="new-actions-header-dropdown"
v-gl-tooltip.hover
class="gl-display-none gl-sm-display-inline-flex! gl-sm-ml-3"
class="gl-display-none gl-sm-display-inline-flex!"
icon="ellipsis_v"
category="tertiary"
data-qa-selector="issue_actions_ellipsis_dropdown"

View File

@ -164,6 +164,7 @@ export function initHeaderActions(store, type = '') {
canReportSpam: parseBoolean(el.dataset.canReportSpam),
canUpdateIssue: parseBoolean(el.dataset.canUpdateIssue),
iid: el.dataset.iid,
issuableId: el.dataset.issuableId,
isIssueAuthor: parseBoolean(el.dataset.isIssueAuthor),
issuePath: el.dataset.issuePath,
issueType: el.dataset.issueType,

View File

@ -223,6 +223,9 @@ module Types
null: true,
description: 'List of award emojis associated with the merge request.'
field :prepared_at, Types::TimeType, null: true,
description: 'Timestamp of when the merge request was prepared.'
markdown_field :title_html, null: true
markdown_field :description_html, null: true

View File

@ -45,6 +45,9 @@ module Types
value 'EXTERNAL_STATUS_CHECKS',
value: :status_checks_must_pass,
description: 'Status checks must pass.'
value 'PREPARING',
value: :preparing,
description: 'Merge request diff is being created.'
end
end
end

View File

@ -10,6 +10,7 @@ module MergeRequests
end
def execute
return :preparing if preparing?
return :checking if checking?
return :unchecked if unchecked?
@ -31,8 +32,12 @@ module MergeRequests
attr_reader :merge_request, :checks, :ci_check
def preparing?
merge_request.preparing? && !merge_request.merge_request_diff.persisted?
end
def checking?
merge_request.cannot_be_merged_rechecking? || merge_request.preparing? || merge_request.checking?
merge_request.cannot_be_merged_rechecking? || merge_request.checking?
end
def unchecked?

View File

@ -18,14 +18,14 @@ production:
# port: 8600
# record: secondary.postgresql.service.consul
# interval: 300
# ci:
# adapter: postgresql
# encoding: unicode
# database: gitlabhq_production
# database_tasks: false
# username: git
# password: "secure password"
# host: localhost
ci:
adapter: postgresql
encoding: unicode
database: gitlabhq_production
database_tasks: false
username: git
password: "secure password"
host: localhost
geo:
adapter: postgresql
encoding: unicode
@ -47,16 +47,16 @@ development:
host: localhost
variables:
statement_timeout: 15s
# ci:
# adapter: postgresql
# encoding: unicode
# database: gitlabhq_development
# database_tasks: false
# username: postgres
# password: "secure password"
# host: localhost
# variables:
# statement_timeout: 15s
ci:
adapter: postgresql
encoding: unicode
database: gitlabhq_development
database_tasks: false
username: postgres
password: "secure password"
host: localhost
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
@ -76,14 +76,14 @@ staging:
username: git
password: "secure password"
host: localhost
# ci:
# adapter: postgresql
# encoding: unicode
# database: gitlabhq_staging
# database_tasks: false
# username: git
# password: "secure password"
# host: localhost
ci:
adapter: postgresql
encoding: unicode
database: gitlabhq_staging
database_tasks: false
username: git
password: "secure password"
host: localhost
geo:
adapter: postgresql
encoding: unicode
@ -106,17 +106,17 @@ test: &test
prepared_statements: false
variables:
statement_timeout: 15s
# ci:
# adapter: postgresql
# encoding: unicode
# database: gitlabhq_test
# database_tasks: false
# username: postgres
# password:
# host: localhost
# prepared_statements: false
# variables:
# statement_timeout: 15s
ci:
adapter: postgresql
encoding: unicode
database: gitlabhq_test
database_tasks: false
username: postgres
password:
host: localhost
prepared_statements: false
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode

View File

@ -16366,6 +16366,7 @@ Defines which user roles, users, or groups can merge into a protected branch.
| <a id="mergerequestmilestone"></a>`milestone` | [`Milestone`](#milestone) | Milestone of the merge request. |
| <a id="mergerequestnotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
| <a id="mergerequestparticipants"></a>`participants` | [`MergeRequestParticipantConnection`](#mergerequestparticipantconnection) | Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes. (see [Connections](#connections)) |
| <a id="mergerequestpreparedat"></a>`preparedAt` | [`Time`](#time) | Timestamp of when the merge request was prepared. |
| <a id="mergerequestproject"></a>`project` | [`Project!`](#project) | Alias for target_project. |
| <a id="mergerequestprojectid"></a>`projectId` | [`Int!`](#int) | ID of the merge request project. |
| <a id="mergerequestrebasecommitsha"></a>`rebaseCommitSha` | [`String`](#string) | Rebase commit SHA of the merge request. |
@ -23725,6 +23726,7 @@ Detailed representation of whether a GitLab merge request can be merged.
| <a id="detailedmergestatusnot_approved"></a>`NOT_APPROVED` | Merge request must be approved before merging. |
| <a id="detailedmergestatusnot_open"></a>`NOT_OPEN` | Merge request must be open before merging. |
| <a id="detailedmergestatuspolicies_denied"></a>`POLICIES_DENIED` | There are denied policies for the merge request. |
| <a id="detailedmergestatuspreparing"></a>`PREPARING` | Merge request diff is being created. |
| <a id="detailedmergestatusunchecked"></a>`UNCHECKED` | Merge status has not been checked. |
### `DiffPositionType`

View File

@ -580,6 +580,10 @@ If you want to use HTTPS, see [Using HTTPS](#using-https) for the additional ste
### Configure GitLab DB Settings
NOTE:
From [GitLab 15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/387898), `database.yml` with only a section: `main:` is deprecated.
In GitLab 17.0 and later, you must have the two `main:` and `ci:` sections in your `database.yml`.
```shell
sudo -u git cp config/database.yml.postgresql config/database.yml
@ -591,6 +595,11 @@ sudo -u git cp config/database.yml.postgresql config/database.yml
# adapter: postgresql
# encoding: unicode
# database: gitlabhq_production
# ci:
# adapter: postgresql
# encoding: unicode
# database: gitlabhq_production
# database_tasks: false
#
sudo -u git -H editor config/database.yml
@ -609,10 +618,10 @@ sudo -u git -H editor config/database.yml
sudo -u git -H chmod o-rwx config/database.yml
```
NOTE:
From GitLab 15.9, `database.yml` with only a section: `main:` is deprecated.
In GitLab 15.10 and later, you should have two sections in your `database.yml`, `main:` and `ci:`. The `ci`: connection [must be to the same database](../administration/postgresql/multiple_databases.md).
In GitLab 17.0 and later, you must have the two `main:` and `ci:` sections in your `database.yml`.
You should have two sections in your `database.yml`: `main:` and `ci:`. The `ci`:
connection [must be to the same database](../administration/postgresql/multiple_databases.md).
If, for any reason, you wish to remain on a single database connection, remove the `ci:`
section from `config/database.yml`.
### Install Gems

View File

@ -182,6 +182,8 @@ git diff origin/PREVIOUS_BRANCH:config/gitlab.yml.example origin/BRANCH:config/g
#### New configuration options for `database.yml`
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119139) in GitLab 16.0 to have `ci:` section in `config/database.yml.postgresql`.
There might be configuration options available for [`database.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/database.yml.postgresql).
View them with the command below and apply them manually to your current `database.yml`:

View File

@ -1,173 +1,181 @@
# frozen_string_literal: true
module Tasks
module Gitlab
module Backup
PID = Process.pid.freeze
PID_FILE = "#{Rails.application.root}/tmp/backup_restore.pid"
end
end
end
namespace :gitlab do
require 'active_record/fixtures'
namespace :backup do
PID = Process.pid.freeze
PID_FILE = "#{Rails.application.root}/tmp/backup_restore.pid"
# Create backup of GitLab system
desc 'GitLab | Backup | Create a backup of the GitLab system'
task create: :gitlab_environment do
lock do
lock_backup do
warn_user_is_not_gitlab
Backup::Manager.new(progress).create
Backup::Manager.new(backup_progress).create
end
end
# Restore backup of GitLab system
desc 'GitLab | Backup | Restore a previously created backup'
task restore: :gitlab_environment do
lock do
lock_backup do
warn_user_is_not_gitlab
Backup::Manager.new(progress).restore
Backup::Manager.new(backup_progress).restore
end
end
namespace :repo do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('repositories')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('repositories')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('repositories')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('repositories')
end
end
end
namespace :db do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('db')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('db')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('db')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('db')
end
end
end
namespace :builds do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('builds')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('builds')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('builds')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('builds')
end
end
end
namespace :uploads do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('uploads')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('uploads')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('uploads')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('uploads')
end
end
end
namespace :artifacts do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('artifacts')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('artifacts')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('artifacts')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('artifacts')
end
end
end
namespace :pages do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('pages')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('pages')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('pages')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('pages')
end
end
end
namespace :lfs do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('lfs')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('lfs')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('lfs')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('lfs')
end
end
end
namespace :terraform_state do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('terraform_state')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('terraform_state')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('terraform_state')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('terraform_state')
end
end
end
namespace :registry do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('registry')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('registry')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('registry')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('registry')
end
end
end
namespace :packages do
task create: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_create_task('packages')
lock_backup do
Backup::Manager.new(backup_progress).run_create_task('packages')
end
end
task restore: :gitlab_environment do
lock do
Backup::Manager.new(progress).run_restore_task('packages')
lock_backup do
Backup::Manager.new(backup_progress).run_restore_task('packages')
end
end
end
def progress
private
def backup_progress
if ENV['CRON']
# We need an object we can say 'puts' and 'print' to; let's use a
# StringIO.
@ -178,22 +186,16 @@ namespace :gitlab do
end
end
def lock
File.open(PID_FILE, File::RDWR | File::CREAT, 0644) do |f|
def lock_backup
File.open(Tasks::Gitlab::Backup::PID_FILE, File::RDWR | File::CREAT) do |f|
f.flock(File::LOCK_EX)
unless f.read.empty?
# There is a PID inside so the process fails
progress.puts(<<~HEREDOC.color(:red))
Backup and restore in progress:
There is a backup and restore task in progress. Please, try to run the current task once the previous one ends.
If there is no other process running, please remove the PID file manually: rm #{PID_FILE}
HEREDOC
file_content = f.read
exit 1
end
read_pid(file_content) unless file_content.blank?
f.write(PID)
f.rewind
f.write(Tasks::Gitlab::Backup::PID)
f.flush
ensure
f.flock(File::LOCK_UN)
@ -202,10 +204,28 @@ namespace :gitlab do
begin
yield
ensure
progress.puts "#{Time.now} " + "-- Deleting backup and restore lock file".color(:blue)
File.delete(PID_FILE)
backup_progress.puts(
"#{Time.current} " + '-- Deleting backup and restore PID file ... '.color(:blue) + 'done'.color(:green)
)
File.delete(Tasks::Gitlab::Backup::PID_FILE)
end
end
def read_pid(file_content)
Process.getpgid(file_content.to_i)
backup_progress.puts(<<~MESSAGE.color(:red))
Backup and restore in progress:
There is a backup and restore task in progress (PID #{file_content}). Try to run the current task once the previous one ends.
MESSAGE
exit 1
rescue Errno::ESRCH
backup_progress.puts(<<~MESSAGE.color(:blue))
The PID file #{Tasks::Gitlab::Backup::PID_FILE} exists and contains #{file_content}, but the process is not running.
The PID file will be rewritten with the current process ID #{Tasks::Gitlab::Backup::PID}.
MESSAGE
end
end
# namespace end: backup
end

View File

@ -1865,12 +1865,18 @@ msgstr ""
msgid "AI| %{link_start}What are experiment features?%{link_end}"
msgstr ""
msgid "AI|Autocomplete"
msgstr ""
msgid "AI|Close the Code Explanation"
msgstr ""
msgid "AI|Code Explanation"
msgstr ""
msgid "AI|Describe the issue"
msgstr ""
msgid "AI|Enabling these features is your acceptance of the %{link_start}GitLab Testing Agreement%{link_end}."
msgstr ""
@ -1886,6 +1892,9 @@ msgstr ""
msgid "AI|Features that use third-party AI services require transmission of data, including personal data."
msgstr ""
msgid "AI|For example: It should be possible to forecast into the future using our value stream analytics charts. This would allow organizations to better understand how they are trending on important metrics."
msgstr ""
msgid "AI|Helpful"
msgstr ""
@ -1919,6 +1928,9 @@ msgstr ""
msgid "AI|What does the selected code mean?"
msgstr ""
msgid "AI|Write a summary to fill out the selected issue template"
msgstr ""
msgid "AI|Wrong"
msgstr ""
@ -18138,6 +18150,9 @@ msgstr ""
msgid "Failed to find users for %{missing}"
msgstr ""
msgid "Failed to generate description"
msgstr ""
msgid "Failed to generate export, please try again later."
msgstr ""

View File

@ -17,9 +17,9 @@ else
echo "Using decomposed database config (config/database.yml.postgresql)"
cp config/database.yml.postgresql config/database.yml
if [ "$CI_CONNECTION_DB" == "true" ]; then
echo "Enabling ci connection (database_tasks: false) in config/database.yml"
sed -i '/ci:/,/geo:/''s/^ # / /g' config/database.yml
if [ "$CI_CONNECTION_DB" != "true" ]; then
echo "Disabling ci connection in config/database.yml"
sed -i "/ci:$/, /geo:$/ {s|^|#|;s|# geo:| geo:|;}" config/database.yml
fi
fi

View File

@ -36,7 +36,7 @@ RSpec.describe GitlabSchema.types['MergeRequest'], feature_category: :code_revie
commit_count current_user_todos conflicts auto_merge_enabled approved_by source_branch_protected
squash_on_merge available_auto_merge_strategies
has_ci mergeable commits committers commits_without_merge_commits squash security_auto_fix default_squash_commit_message
auto_merge_strategy merge_user award_emoji
auto_merge_strategy merge_user award_emoji prepared_at
]
expect(described_class).to have_graphql_fields(*expected_fields).at_least

View File

@ -17,7 +17,19 @@ RSpec.describe ::MergeRequests::Mergeability::DetailedMergeStatusService, featur
let(:merge_request) { create(:merge_request, merge_status: :preparing) }
it 'returns :checking' do
expect(detailed_merge_status).to eq(:checking)
allow(merge_request.merge_request_diff).to receive(:persisted?).and_return(false)
expect(detailed_merge_status).to eq(:preparing)
end
end
context 'when merge status is preparing and merge request diff is persisted' do
let(:merge_request) { create(:merge_request, merge_status: :preparing) }
it 'returns :checking' do
allow(merge_request.merge_request_diff).to receive(:persisted?).and_return(true)
expect(detailed_merge_status).to eq(:mergeable)
end
end

View File

@ -55,6 +55,7 @@ RSpec.describe 'gitlab:backup namespace rake tasks', :delete, feature_category:
after do
FileUtils.rm(tars_glob, force: true)
FileUtils.rm(backup_files, force: true)
FileUtils.rm(backup_restore_pid_path, force: true)
FileUtils.rm_rf(backup_directories, secure: true)
FileUtils.rm_rf('tmp/tests/public/uploads', secure: true)
end
@ -66,32 +67,79 @@ RSpec.describe 'gitlab:backup namespace rake tasks', :delete, feature_category:
end
describe 'lock parallel backups' do
using RSpec::Parameterized::TableSyntax
let(:progress) { $stdout }
let(:delete_message) { /-- Deleting backup and restore PID file/ }
let(:pid_file) do
File.open(backup_restore_pid_path, File::RDWR | File::CREAT)
end
context 'when a process is running' do
let(:pid_file) { instance_double(File) }
before do
allow(Kernel).to receive(:system).and_return(true)
allow(YAML).to receive(:safe_load_file).and_return({ gitlab_version: Gitlab::VERSION })
end
context 'when a process is running in parallel' do
before do
File.open(backup_restore_pid_path, 'wb') do |file|
file.write('123456')
file.close
end
end
it 'exits the new process' do
allow(File).to receive(:open).and_call_original
allow(File).to receive(:open).with(backup_restore_pid_path, any_args).and_yield(pid_file)
allow(pid_file).to receive(:read).and_return('123456')
allow(pid_file).to receive(:flock).with(any_args)
allow(Process).to receive(:getpgid).with(123456).and_return(123456)
expect { run_rake_task('gitlab:backup:create') }.to raise_error(SystemExit).and output(
<<~HEREDOC
<<~MESSAGE
Backup and restore in progress:
There is a backup and restore task in progress. Please, try to run the current task once the previous one ends.
If there is no other process running, please remove the PID file manually: rm #{backup_restore_pid_path}
HEREDOC
There is a backup and restore task in progress (PID 123456). Try to run the current task once the previous one ends.
MESSAGE
).to_stdout
end
end
context 'when no processes are running' do
let(:progress) { $stdout }
let(:pid_file) { instance_double(File, write: 12345) }
context 'when no process is running in parallel but a PID file exists' do
let(:rewritten_message) do
<<~MESSAGE
The PID file #{backup_restore_pid_path} exists and contains 123456, but the process is not running.
The PID file will be rewritten with the current process ID #{Process.pid}.
MESSAGE
end
where(:tasks_name, :rake_task) do
before do
File.open(backup_restore_pid_path, 'wb') do |file|
file.write('123456')
file.close
end
end
it 'rewrites, locks and deletes the PID file while logging a message' do
allow(File).to receive(:open).and_call_original
allow(File).to receive(:open).with(backup_restore_pid_path, any_args).and_yield(pid_file)
allow(Process).to receive(:getpgid).with(123456).and_raise(Errno::ESRCH)
allow(progress).to receive(:puts).with(delete_message).once
allow(progress).to receive(:puts).with(rewritten_message).once
allow_next_instance_of(::Backup::Manager) do |instance|
allow(instance).to receive(:run_restore_task).with('db')
end
expect(pid_file).to receive(:flock).with(File::LOCK_EX)
expect(pid_file).to receive(:flock).with(File::LOCK_UN)
expect(File).to receive(:delete).with(backup_restore_pid_path)
expect(progress).to receive(:puts).with(rewritten_message).once
expect(progress).to receive(:puts).with(delete_message).once
run_rake_task('gitlab:backup:db:restore')
end
end
context 'when no process is running in parallel' do
using RSpec::Parameterized::TableSyntax
where(:task_name, :rake_task) do
'db' | 'gitlab:backup:db:restore'
'repositories' | 'gitlab:backup:repo:restore'
'builds' | 'gitlab:backup:builds:restore'
@ -106,34 +154,23 @@ RSpec.describe 'gitlab:backup namespace rake tasks', :delete, feature_category:
with_them do
before do
allow(Kernel).to receive(:system).and_return(true)
allow(YAML).to receive(:safe_load_file).and_return({ gitlab_version: Gitlab::VERSION })
allow(File).to receive(:delete).with(backup_restore_pid_path).and_return(1)
allow(File).to receive(:open).and_call_original
allow(File).to receive(:open).with(backup_restore_pid_path, any_args).and_yield(pid_file)
allow(pid_file).to receive(:read).and_return('')
allow(pid_file).to receive(:flock).with(any_args)
allow(pid_file).to receive(:write).with(12345).and_return(true)
allow(pid_file).to receive(:flush)
allow(File).to receive(:delete).with(backup_restore_pid_path)
allow(progress).to receive(:puts).at_least(:once)
allow_next_instance_of(::Backup::Manager) do |instance|
Array(tasks_name).each do |task|
Array(task_name).each do |task|
allow(instance).to receive(:run_restore_task).with(task)
end
end
end
it 'locks the PID file' do
it 'locks and deletes the PID file while logging a message' do
expect(pid_file).to receive(:flock).with(File::LOCK_EX)
expect(pid_file).to receive(:flock).with(File::LOCK_UN)
run_rake_task(rake_task)
end
it 'deletes the PID file and logs a message' do
expect(File).to receive(:delete).with(backup_restore_pid_path)
expect(progress).to receive(:puts).with(/-- Deleting backup and restore lock file/)
expect(progress).to receive(:puts).with(delete_message)
run_rake_task(rake_task)
end