Commit b539ac1d authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 4c016ad0
......@@ -4,7 +4,11 @@ export const serializeFormEntries = entries =>
export const serializeForm = form => {
const fdata = new FormData(form);
const entries = Array.from(fdata.keys()).map(key => {
const val = fdata.getAll(key);
let val = fdata.getAll(key);
// Microsoft Edge has a bug in FormData.getAll() that returns an undefined
// value for each form element that does not match the given key:
// https://github.com/jimmywarting/FormData/issues/80
val = val.filter(n => n);
return { name: key, value: val.length === 1 ? val[0] : val };
});
......
......@@ -13,7 +13,7 @@ module Boards
requires_cross_project_access if: -> { board&.group_board? }
before_action :whitelist_query_limiting, only: [:index, :update, :bulk_move]
before_action :whitelist_query_limiting, only: [:bulk_move]
before_action :authorize_read_issue, only: [:index]
before_action :authorize_create_issue, only: [:create]
before_action :authorize_update_issue, only: [:update]
......@@ -130,8 +130,7 @@ module Boards
end
def whitelist_query_limiting
# Also see https://gitlab.com/gitlab-org/gitlab-foss/issues/42439
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42428')
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/35174')
end
def validate_id_list
......
......@@ -2,7 +2,6 @@
class IssueBoardEntity < Grape::Entity
include RequestAwareEntity
include TimeTrackableEntity
expose :id
expose :iid
......
......@@ -12,8 +12,8 @@
= clipboard_button(target: "pre#merge-info-1", title: _("Copy commands"))
%pre.dark#merge-info-1
- if @merge_request.for_fork?
-# All repo/branch refs have been quoted to allow support for special characters (such as #my-branch)
:preserve
-# All repo/branch refs have been quoted to allow support for special characters (such as #my-branch)
git fetch "#{h default_url_to_repo(@merge_request.source_project)}" "#{h @merge_request.source_branch}"
git checkout -b "#{h @merge_request.source_project_path}-#{h @merge_request.source_branch}" FETCH_HEAD
- else
......
---
title: Rename Vulnerabilities API to Vulnerability Findings API
merge_request: 19029
author:
type: changed
---
title: Prevents console warning on design upload
merge_request: 19297
author:
type: fixed
---
title: Fix Prometheus duplicate metrics
merge_request: 19327
author:
type: fixed
---
title: Fix ref switcher not working on Microsoft Edge
merge_request: 19335
author:
type: fixed
......@@ -70,8 +70,8 @@ if defined?(::Unicorn) || defined?(::Puma)
Gitlab::Metrics::Exporter::WebExporter.instance.start
end
Gitlab::Cluster::LifecycleEvents.on_before_phased_restart do
# We need to ensure that before we re-exec server
Gitlab::Cluster::LifecycleEvents.on_before_graceful_shutdown do
# We need to ensure that before we re-exec or shutdown server
# we do stop the exporter
Gitlab::Metrics::Exporter::WebExporter.instance.stop
end
......
# frozen_string_literal: true
if defined?(::Puma) && ::Puma.cli_config.options[:workers].to_i.zero?
raise 'Puma is only supported in Cluster-mode: workers > 0'
end
......@@ -67,8 +67,9 @@ The following API resources are available in the project context:
| [Search](search.md) | `/projects/:id/search` (also available for groups and standalone) |
| [Services](services.md) | `/projects/:id/services` |
| [Tags](tags.md) | `/projects/:id/repository/tags` |
| [Visual Review discussions](visual_review_discussions.md) **(STARTER**) | `/projects/:id/merge_requests/:merge_request_id/visual_review_discussions` |
| [Vulnerabilities](vulnerabilities.md) **(ULTIMATE)** | `/projects/:id/vulnerabilities` |
| [Visual Review discussions](visual_review_discussions.md) **(STARTER**) | `/projects/:id/merge_requests/:merge_request_id/visual_review_discussions` |
| [Vulnerability Findings](vulnerability_findings.md) **(ULTIMATE)** | `/projects/:id/vulnerability_findings` |
| [Wikis](wikis.md) | `/projects/:id/wikis` |
## Group resources
......
# Vulnerabilities API **(ULTIMATE)**
Every API call to vulnerabilities must be authenticated.
If a user is not a member of a project and the project is private, a `GET`
request on that project will result in a `404` status code.
CAUTION: **Caution:**
This API is in an alpha stage and considered unstable.
The response payload may be subject to change or breakage
across GitLab releases.
## Vulnerabilities pagination
By default, `GET` requests return 20 results at a time because the API results
are paginated.
Read more on [pagination](README.md#pagination).
## List project vulnerabilities
List all of a project's vulnerabilities.
```
GET /projects/:id/vulnerabilities
GET /projects/:id/vulnerabilities?report_type=sast
GET /projects/:id/vulnerabilities?report_type=container_scanning
GET /projects/:id/vulnerabilities?report_type=sast,dast
GET /projects/:id/vulnerabilities?scope=all
GET /projects/:id/vulnerabilities?scope=dismissed
GET /projects/:id/vulnerabilities?severity=high
GET /projects/:id/vulnerabilities?confidence=unknown,experimental
GET /projects/:id/vulnerabilities?pipeline_id=42
```
| Attribute | Type | Required | Description |
| ------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
| `report_type` | string array | no | Returns vulnerabilities belonging to specified report type. Valid values: `sast`, `dast`, `dependency_scanning`, or `container_scanning`. |
| `scope` | string | no | Returns vulnerabilities for the given scope: `all` or `dismissed`. Defaults to `dismissed` |
| `severity` | string array | no | Returns vulnerabilities belonging to specified severity level: `undefined`, `info`, `unknown`, `low`, `medium`, `high`, or `critical`. Defaults to all' |
| `confidence` | string array | no | Returns vulnerabilities belonging to specified confidence level: `undefined`, `ignore`, `unknown`, `experimental`, `low`, `medium`, `high`, or `confirmed`. Defaults to all |
| `pipeline_id` | integer/string | no | Returns vulnerabilities belonging to specified pipeline. |
```bash
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/vulnerabilities
```
Example response:
```json
[
{
"id": null,
"report_type": "dependency_scanning",
"name": "Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js",
"severity": "unknown",
"confidence": "undefined",
"scanner": {
"external_id": "gemnasium",
"name": "Gemnasium"
},
"identifiers": [
{
"external_type": "gemnasium",
"external_id": "9952e574-7b5b-46fa-a270-aeb694198a98",
"name": "Gemnasium-9952e574-7b5b-46fa-a270-aeb694198a98",
"url": "https://deps.sec.gitlab.com/packages/npm/saml2-js/versions/1.5.0/advisories"
},
{
"external_type": "cve",
"external_id": "CVE-2017-11429",
"name": "CVE-2017-11429",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11429"
}
],
"project_fingerprint": "fa6f5b6c5d240b834ac5e901dc69f9484cef89ec",
"create_vulnerability_feedback_issue_path": "/tests/yarn-remediation-test/vulnerability_feedback",
"create_vulnerability_feedback_merge_request_path": "/tests/yarn-remediation-test/vulnerability_feedback",
"create_vulnerability_feedback_dismissal_path": "/tests/yarn-remediation-test/vulnerability_feedback",
"project": {
"id": 31,
"name": "yarn-remediation-test",
"full_path": "/tests/yarn-remediation-test",
"full_name": "tests / yarn-remediation-test"
},
"dismissal_feedback": null,
"issue_feedback": null,
"merge_request_feedback": null,
"description": "Some XML DOM traversal and canonicalization APIs may be inconsistent in handling of comments within XML nodes. Incorrect use of these APIs by some SAML libraries results in incorrect parsing of the inner text of XML nodes such that any inner text after the comment is lost prior to cryptographically signing the SAML message. Text after the comment therefore has no impact on the signature on the SAML message.\r\n\r\nA remote attacker can modify SAML content for a SAML service provider without invalidating the cryptographic signature, which may allow attackers to bypass primary authentication for the affected SAML service provider.",
"links": [
{
"url": "https://github.com/Clever/saml2/commit/3546cb61fd541f219abda364c5b919633609ef3d#diff-af730f9f738de1c9ad87596df3f6de84R279"
},
{
"url": "https://www.kb.cert.org/vuls/id/475445"
},
{
"url": "https://github.com/Clever/saml2/issues/127"
}
],
"location": {
"file": "yarn.lock",
"dependency": {
"package": {
"name": "saml2-js"
},
"version": "1.5.0"
}
},
"solution": "Upgrade to fixed version.\r\n",
"blob_path": "/tests/yarn-remediation-test/blob/cc6c4a0778460455ae5d16ca7025ca9ca1ca75ac/yarn.lock"
}
]
```
This document was moved to [another location](vulnerability_findings.md).
# Vulnerability Findings API **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/19029) in GitLab Ultimate 12.5.
NOTE: **Note:**
This API resource is renamed from Vulnerabilities to Vulnerability Findings because the Vulnerabilities are reserved
for serving the upcoming [Standalone Vulnerability objects](https://gitlab.com/gitlab-org/gitlab/issues/13561).
To fix any broken integrations with the former Vulnerabilities API, change the `vulnerabilities` URL part to be
`vulnerability_findings`.
Every API call to vulnerability findings must be [authenticated](README.md#authentication).
Vulnerability findings are project-bound entities. If a user is not
a member of a project and the project is private, a request on
that project will result in a `404` status code.
If a user is able to access the project but does not have permission to
[use the Project Security Dashboard](../user/permissions.md#project-members-permissions),
any request for vulnerability findings of this project will result in a `403` status code.
CAUTION: **Caution:**
This API is in an alpha stage and considered unstable.
The response payload may be subject to change or breakage
across GitLab releases.
## Vulnerability findings pagination
By default, `GET` requests return 20 results at a time because the API results
are paginated.
Read more on [pagination](README.md#pagination).
## List project vulnerability findings
List all of a project's vulnerability findings.
```
GET /projects/:id/vulnerability_findings
GET /projects/:id/vulnerability_findings?report_type=sast
GET /projects/:id/vulnerability_findings?report_type=container_scanning
GET /projects/:id/vulnerability_findings?report_type=sast,dast
GET /projects/:id/vulnerability_findings?scope=all
GET /projects/:id/vulnerability_findings?scope=dismissed
GET /projects/:id/vulnerability_findings?severity=high
GET /projects/:id/vulnerability_findings?confidence=unknown,experimental
GET /projects/:id/vulnerability_findings?pipeline_id=42
```
| Attribute | Type | Required | Description |
| ------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) which the authenticated user is a member of. |
| `report_type` | string array | no | Returns vulnerability findings belonging to specified report type. Valid values: `sast`, `dast`, `dependency_scanning`, or `container_scanning`. Defaults to all. |
| `scope` | string | no | Returns vulnerability findings for the given scope: `all` or `dismissed`. Defaults to `dismissed`. |
| `severity` | string array | no | Returns vulnerability findings belonging to specified severity level: `undefined`, `info`, `unknown`, `low`, `medium`, `high`, or `critical`. Defaults to all. |
| `confidence` | string array | no | Returns vulnerability findings belonging to specified confidence level: `undefined`, `ignore`, `unknown`, `experimental`, `low`, `medium`, `high`, or `confirmed`. Defaults to all. |
| `pipeline_id` | integer/string | no | Returns vulnerability findings belonging to specified pipeline. |
```bash
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/vulnerability_findings
```
Example response:
```json
[
{
"id": null,
"report_type": "dependency_scanning",
"name": "Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js",
"severity": "unknown",
"confidence": "undefined",
"scanner": {
"external_id": "gemnasium",
"name": "Gemnasium"
},
"identifiers": [
{
"external_type": "gemnasium",
"external_id": "9952e574-7b5b-46fa-a270-aeb694198a98",
"name": "Gemnasium-9952e574-7b5b-46fa-a270-aeb694198a98",
"url": "https://deps.sec.gitlab.com/packages/npm/saml2-js/versions/1.5.0/advisories"
},
{
"external_type": "cve",
"external_id": "CVE-2017-11429",
"name": "CVE-2017-11429",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11429"
}
],
"project_fingerprint": "fa6f5b6c5d240b834ac5e901dc69f9484cef89ec",
"create_vulnerability_feedback_issue_path": "/tests/yarn-remediation-test/vulnerability_feedback",
"create_vulnerability_feedback_merge_request_path": "/tests/yarn-remediation-test/vulnerability_feedback",
"create_vulnerability_feedback_dismissal_path": "/tests/yarn-remediation-test/vulnerability_feedback",
"project": {
"id": 31,
"name": "yarn-remediation-test",
"full_path": "/tests/yarn-remediation-test",
"full_name": "tests / yarn-remediation-test"
},
"dismissal_feedback": null,
"issue_feedback": null,
"merge_request_feedback": null,
"description": "Some XML DOM traversal and canonicalization APIs may be inconsistent in handling of comments within XML nodes. Incorrect use of these APIs by some SAML libraries results in incorrect parsing of the inner text of XML nodes such that any inner text after the comment is lost prior to cryptographically signing the SAML message. Text after the comment therefore has no impact on the signature on the SAML message.\r\n\r\nA remote attacker can modify SAML content for a SAML service provider without invalidating the cryptographic signature, which may allow attackers to bypass primary authentication for the affected SAML service provider.",
"links": [
{
"url": "https://github.com/Clever/saml2/commit/3546cb61fd541f219abda364c5b919633609ef3d#diff-af730f9f738de1c9ad87596df3f6de84R279"
},
{
"url": "https://www.kb.cert.org/vuls/id/475445"
},
{
"url": "https://github.com/Clever/saml2/issues/127"
}
],
"location": {
"file": "yarn.lock",
"dependency": {
"package": {
"name": "saml2-js"
},
"version": "1.5.0"
}
},
"solution": "Upgrade to fixed version.\r\n",
"blob_path": "/tests/yarn-remediation-test/blob/cc6c4a0778460455ae5d16ca7025ca9ca1ca75ac/yarn.lock"
}
]
```
......@@ -113,9 +113,9 @@ promoteBeta:
promoteProduction:
extends: .promote_job
stage: production
# We only allow production promotion on the default branch because
# We only allow production promotion on `master` because
# it has its own production scoped secret variables
only:
- $CI_DEFAULT_BRANCH
- master
script:
- bundle exec fastlane promote_beta_to_production
......@@ -10,7 +10,7 @@ docker-build-master:
- docker build --pull -t "$CI_REGISTRY_IMAGE" .
- docker push "$CI_REGISTRY_IMAGE"
only:
- $CI_DEFAULT_BRANCH
- master
docker-build:
# Official docker image.
......@@ -24,4 +24,4 @@ docker-build:
- docker build --pull -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
except:
- $CI_DEFAULT_BRANCH
- master
......@@ -25,7 +25,7 @@ review:
kubernetes: active
except:
refs:
- $CI_DEFAULT_BRANCH
- master
variables:
- $REVIEW_DISABLED
......@@ -49,7 +49,7 @@ stop_review:
kubernetes: active
except:
refs:
- $CI_DEFAULT_BRANCH
- master
variables:
- $REVIEW_DISABLED
......@@ -74,7 +74,7 @@ staging:
url: http://$CI_PROJECT_PATH_SLUG-staging.$KUBE_INGRESS_BASE_DOMAIN
only:
refs:
- $CI_DEFAULT_BRANCH
- master
kubernetes: active
variables:
- $STAGING_ENABLED
......@@ -99,7 +99,7 @@ canary:
when: manual
only:
refs:
- $CI_DEFAULT_BRANCH
- master
kubernetes: active
variables:
- $CANARY_ENABLED
......@@ -127,7 +127,7 @@ production:
<<: *production_template
only:
refs:
- $CI_DEFAULT_BRANCH
- master
kubernetes: active
except:
variables:
......@@ -142,7 +142,7 @@ production_manual:
allow_failure: false
only:
refs:
- $CI_DEFAULT_BRANCH
- master
kubernetes: active
variables:
- $STAGING_ENABLED
......@@ -152,7 +152,7 @@ production_manual:
- $INCREMENTAL_ROLLOUT_ENABLED
- $INCREMENTAL_ROLLOUT_MODE
# This job implements incremental rollout for every push to the default branch.
# This job implements incremental rollout on for every push to `master`.
.rollout: &rollout_template
extends: .auto-deploy
......@@ -179,7 +179,7 @@ production_manual:
# This selectors are backward compatible mode with $INCREMENTAL_ROLLOUT_ENABLED (before 11.4)
only:
refs:
- $CI_DEFAULT_BRANCH
- master
kubernetes: active
variables:
- $INCREMENTAL_ROLLOUT_MODE == "manual"
......@@ -194,7 +194,7 @@ production_manual:
start_in: 5 minutes
only:
refs:
- $CI_DEFAULT_BRANCH
- master
kubernetes: active
variables:
- $INCREMENTAL_ROLLOUT_MODE == "timed"
......
......@@ -64,7 +64,7 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
# WARNING: This template is using the `julia` images from [Docker
# Hub][3]. One can use custom Julia images and/or the official ones found
......
......@@ -6,7 +6,7 @@
# This template will build and test your projects
# * Caches downloaded dependencies and plugins between invocation.
# * Verify but don't deploy merge requests.
# * Deploy built artifacts from the default branch only.
# * Deploy built artifacts from master branch only.
variables:
# This will suppress any download for dependencies and plugins or upload messages which would clutter the console log.
......@@ -33,7 +33,7 @@ cache:
script:
- 'mvn $MAVEN_CLI_OPTS verify'
except:
- $CI_DEFAULT_BRANCH
- master
# Verify merge requests using JDK8
verify:jdk8:
......@@ -42,7 +42,7 @@ verify:jdk8:
# To deploy packages from CI, create a ci_settings.xml file
# For deploying packages to GitLab's Maven Repository: See https://docs.gitlab.com/ee/user/project/packages/maven_repository.html#creating-maven-packages-with-gitlab-cicd for more details.
# Please note: The GitLab Maven Repository is currently only available in GitLab Premium / Ultimate.
# For the default branch run `mvn deploy` automatically.
# For `master` branch run `mvn deploy` automatically.
deploy:jdk8:
stage: deploy
script:
......@@ -51,4 +51,4 @@ deploy:jdk8:
fi
- 'mvn $MAVEN_CLI_OPTS deploy -s ci_settings.xml'
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -25,7 +25,7 @@ before_script:
release:
stage: deploy
only:
- $CI_DEFAULT_BRANCH
- master
artifacts:
paths:
- build/release/MyProject.exe
......
......@@ -49,7 +49,7 @@ review:
only:
- branches
except:
- $CI_DEFAULT_BRANCH
- master
stop-review:
<<: *deploy
......@@ -66,7 +66,7 @@ stop-review:
only:
- branches
except:
- $CI_DEFAULT_BRANCH
- master
staging:
<<: *deploy
......@@ -78,7 +78,7 @@ staging:
name: staging
url: http://$CI_PROJECT_NAME-staging.$OPENSHIFT_DOMAIN
only:
- $CI_DEFAULT_BRANCH
- master
production:
<<: *deploy
......@@ -91,4 +91,4 @@ production:
name: production
url: http://$CI_PROJECT_NAME.$OPENSHIFT_DOMAIN
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -25,4 +25,4 @@ build:
- find . -maxdepth 1 -name '*.json' -print0 | xargs -t0n1 packer build
when: manual
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -12,4 +12,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -10,4 +10,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -14,4 +14,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -9,4 +9,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -12,4 +12,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -14,4 +14,4 @@ pages:
- node_modules
key: project
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -8,10 +8,10 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
test:
script:
- hugo
except:
- $CI_DEFAULT_BRANCH
- master
......@@ -11,7 +11,7 @@ test:
- pip install hyde
- hyde gen
except:
- $CI_DEFAULT_BRANCH
- master
pages:
stage: deploy
......@@ -22,4 +22,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -17,7 +17,7 @@ test:
paths:
- test
except:
- $CI_DEFAULT_BRANCH
- master
pages:
stage: deploy
......@@ -27,4 +27,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -34,4 +34,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -9,4 +9,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -13,4 +13,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -12,7 +12,7 @@ test:
- bundle install --path vendor
- bundle exec middleman build
except:
- $CI_DEFAULT_BRANCH
- master
pages:
script:
......@@ -24,4 +24,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -9,4 +9,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -12,4 +12,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -26,4 +26,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -48,4 +48,4 @@ pages:
paths:
- public
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -22,7 +22,7 @@ archive_project:
- xcodebuild clean archive -archivePath build/ProjectName -scheme SchemeName
- xcodebuild -exportArchive -exportFormat ipa -archivePath "build/ProjectName.xcarchive" -exportPath "build/ProjectName.ipa" -exportProvisioningProfile "ProvisioningProfileName"
only:
- $CI_DEFAULT_BRANCH
- master
artifacts:
paths:
- build/ProjectName.ipa
......
......@@ -53,4 +53,4 @@ apply:
- plan
when: manual
only:
- $CI_DEFAULT_BRANCH
- master
......@@ -33,7 +33,7 @@ module Gitlab
#
# Sidekiq/Puma Single: This is called immediately.
#
# - on_before_phased_restart:
# - on_before_graceful_shutdown:
#
# Unicorn/Puma Cluster: This will be called before a graceful
# shutdown of workers starts happening.
......@@ -75,9 +75,9 @@ module Gitlab
end
# Read the config/initializers/cluster_events_before_phased_restart.rb
def on_before_phased_restart(&block)
def on_before_graceful_shutdown(&block)
# Defer block execution
(@master_phased_restart ||= []) << block
(@master_graceful_shutdown ||= []) << block
end
def on_before_master_restart(&block)
......@@ -108,8 +108,8 @@ module Gitlab
end
end
def do_before_phased_restart
@master_phased_restart&.each do |block|
def do_before_graceful_shutdown
@master_graceful_shutdown&.each do |block|
block.call
end
end
......
......@@ -8,8 +8,12 @@ module Gitlab
raise 'missing method Puma::Cluster#stop_workers' unless base.method_defined?(:stop_workers)
end
# This looks at internal status of `Puma::Cluster`
# https://github.com/puma/puma/blob/v3.12.1/lib/puma/cluster.rb#L333
def stop_workers
Gitlab::Cluster::LifecycleEvents.do_before_phased_restart
if @status == :stop # rubocop:disable Gitlab/ModuleWithInstanceVariables
Gitlab::Cluster::LifecycleEvents.do_before_graceful_shutdown
end
super
end
......
......@@ -5,11 +5,26 @@ module Gitlab
module Mixins
module UnicornHttpServer
def self.prepended(base)
raise 'missing method Unicorn::HttpServer#reexec' unless base.method_defined?(:reexec)
unless base.method_defined?(:reexec) && base.method_defined?(:stop)
raise 'missing method Unicorn::HttpServer#reexec or Unicorn::HttpServer#stop'
end
end
def reexec
Gitlab::Cluster::LifecycleEvents.do_before_phased_restart
Gitlab::Cluster::LifecycleEvents.do_before_graceful_shutdown
super
end
# The stop on non-graceful shutdown is executed twice:
# `#stop(false)` and `#stop`.
#
# The first stop will wipe-out all workers, so we need to check
# the flag and a list of workers
def stop(graceful = true)
if graceful && @workers.any? # rubocop:disable Gitlab/ModuleWithInstanceVariables
Gitlab::Cluster::LifecycleEvents.do_before_graceful_shutdown
end
super
end
......
......@@ -35,7 +35,7 @@ module Gitlab
def self.initialize_http_request_duration_seconds
HTTP_METHODS.each do |method, statuses|
statuses.each do |status|
http_request_duration_seconds.get({ method: method, status: status })
http_request_duration_seconds.get({ method: method, status: status.to_i })
end
end
end
......
......@@ -6,6 +6,7 @@ FactoryBot.define do
project
author { project.creator }
updated_by { author }
relative_position { RelativePositioning::START_POSITION }
trait :confidential do
confidential { true }
......
......@@ -70,5 +70,27 @@ describe('lib/utils/forms', () => {
bar: ['bar-value2', 'bar-value1'],
});
});
it('handles Microsoft Edge FormData.getAll() bug', () => {
const formData = [
{ type: 'checkbox', name: 'foo', value: 'foo-value1' },
{ type: 'text', name: 'bar', value: 'bar-value2' },
];
const form = createDummyForm(formData);
jest
.spyOn(FormData.prototype, 'getAll')
.mockImplementation(name =>
formData.map(elem => (elem.name === name ? elem.value : undefined)),
);
const data = serializeForm(form);
expect(data).toEqual({
foo: 'foo-value1',
bar: 'bar-value2',
});
});
});
});
......@@ -8,15 +8,28 @@ describe Gitlab::Cluster::Mixins::PumaCluster do
PUMA_STARTUP_TIMEOUT = 30
context 'when running Puma in Cluster-mode' do
%i[USR1 USR2 INT HUP].each do |signal|
it "for #{signal} does execute phased restart block" do
using RSpec::Parameterized::TableSyntax
where(:signal, :exitstatus, :termsig) do
# executes phased restart block
:USR1 | 140 | nil
:USR2 | 140 | nil
:INT | 140 | nil
:HUP | 140 | nil
# does not execute phased restart block
:TERM | nil | 15
end
with_them do
it 'properly handles process lifecycle' do
with_puma(workers: 1) do |pid|
Process.kill(signal, pid)
child_pid, child_status = Process.wait2(pid)
expect(child_pid).to eq(pid)
expect(child_status).to be_exited
expect(child_status.exitstatus).to eq(140)
expect(child_status.exitstatus).to eq(exitstatus)
expect(child_status.termsig).to eq(termsig)
end
end
end
......@@ -62,8 +75,12 @@ describe Gitlab::Cluster::Mixins::PumaCluster do
Puma::Cluster.prepend(#{described_class})
Gitlab::Cluster::LifecycleEvents.on_before_phased_restart do
exit(140)
mutex = Mutex.new
Gitlab::Cluster::LifecycleEvents.on_before_graceful_shutdown do
mutex.synchronize do
exit(140)
end
end
# redirect stderr to stdout
......
......@@ -5,31 +5,30 @@ require 'spec_helper'
# For easier debugging set `UNICORN_DEBUG=1`
describe Gitlab::Cluster::Mixins::UnicornHttpServer do
UNICORN_STARTUP_TIMEOUT = 10
UNICORN_STARTUP_TIMEOUT = 30
context 'when running Unicorn' do
%i[USR2].each do |signal|
it "for #{signal} does execute phased restart block" do
with_unicorn(workers: 1) do |pid|
Process.kill(signal, pid)
using RSpec::Parameterized::TableSyntax
child_pid, child_status = Process.wait2(pid)
expect(child_pid).to eq(pid)
expect(child_status).to be_exited
expect(child_status.exitstatus).to eq(140)
end
end
where(:signal, :exitstatus, :termsig) do
# executes phased restart block
:USR2 | 140 | nil
:QUIT | 140 | nil
# does not execute phased restart block
:INT | 0 | nil
:TERM | 0 | nil
end
%i[QUIT TERM INT].each do |signal|
it "for #{signal} does not execute phased restart block" do
with_them do
it 'properly handles process lifecycle' do
with_unicorn(workers: 1) do |pid|
Process.kill(signal, pid)
child_pid, child_status = Process.wait2(pid)
expect(child_pid).to eq(pid)
expect(child_status).to be_exited
expect(child_status.exitstatus).to eq(0)
expect(child_status.exitstatus).to eq(exitstatus)
expect(child_status.termsig).to eq(termsig)
end
end
end
......@@ -74,8 +73,12 @@ describe Gitlab::Cluster::Mixins::UnicornHttpServer do
Unicorn::HttpServer.prepend(#{described_class})
Gitlab::Cluster::LifecycleEvents.on_before_phased_restart do
exit(140)
mutex = Mutex.new
Gitlab::Cluster::LifecycleEvents.on_before_graceful_shutdown do
mutex.synchronize do
exit(140)
end
end
# redirect stderr to stdout
......
......@@ -69,7 +69,7 @@ describe Gitlab::Metrics::RequestsRackMiddleware do
expected_labels = []
described_class::HTTP_METHODS.each do |method, statuses|
statuses.each do |status|
expected_labels << { method: method, status: status }
expected_labels << { method: method, status: status.to_i }
end
end
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment