Commit bd497e35 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 0388886f
......@@ -24,9 +24,6 @@ variables:
ES_JAVA_OPTS: "-Xms256m -Xmx256m"
ELASTIC_URL: "http://elastic:changeme@elasticsearch:9200"
after_script:
- date
include:
- local: .gitlab/ci/cache-repo.gitlab-ci.yml
- local: .gitlab/ci/cng.gitlab-ci.yml
......
---
.releases:rules:canonical-dot-com-gitlab-stable-branch-only:
rules:
- if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAME == "gitlab-org/gitlab" && $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable-ee$/'
.releases:rules:canonical-dot-com-security-gitlab-stable-branch-only:
rules:
- if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAME == "gitlab-org/security/gitlab" && $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable-ee$/'
# Syncs any changes pushed to a stable branch to the corresponding
# gitlab-foss/CE stable branch. We run this prior to any tests so that random
......@@ -10,27 +16,21 @@
stage: sync
before_script:
- apk add --no-cache --update curl bash jq
after_script: []
script:
- bash scripts/sync-stable-branch.sh
only:
variables:
- $CI_SERVER_HOST == "gitlab.com"
sync-stable-branch:
extends: .merge-train-sync
extends:
- .releases:rules:canonical-dot-com-gitlab-stable-branch-only
- .merge-train-sync
variables:
SOURCE_PROJECT: gitlab-org/gitlab
TARGET_PROJECT: gitlab-org/gitlab-foss
only:
refs:
- /^[\d-]+-stable-ee$/@gitlab-org/gitlab
sync-security-branch:
extends: .merge-train-sync
extends:
- .releases:rules:canonical-dot-com-security-gitlab-stable-branch-only
- .merge-train-sync
variables:
SOURCE_PROJECT: gitlab-org/security/gitlab
TARGET_PROJECT: gitlab-org/security/gitlab-foss
only:
refs:
- /^[\d-]+-stable-ee$/@gitlab-org/security/gitlab
---
title: 'Geo: Fix GeoNode name in geo:update_primary_node_url rake task'
merge_request: 24649
author:
type: fixed
# frozen_string_literal: true
class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
return if column_exists? :services, :template
# The migration to drop the template column never actually shipped
# to production, so we should be okay to re-add it without worrying
# about doing a data migration. If we needed to restore the value
# of `template`, we would look for entries with `project_id IS NULL`.
add_column_with_default :services, :template, :boolean, default: false, allow_null: true
end
def down
# NOP since the column is expected to exist
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_02_11_152410) do
ActiveRecord::Schema.define(version: 2020_02_12_052620) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
......
......@@ -205,6 +205,25 @@ secondary domain, like changing Git remotes and API URLs.
This command will use the changed `external_url` configuration defined
in `/etc/gitlab/gitlab.rb`.
1. For GitLab 11.11 through 12.7 only, you may need to update the primary
node's name in the database. This bug has been fixed in GitLab 12.8.
To determine if you need to do this, search for the
`gitlab_rails["geo_node_name"]` setting in your `/etc/gitlab/gitlab.rb`
file. If it is commented out with `#` or not found at all, then you will
need to update the primary node's name in the database. You can search for it
like so:
```shell
grep "geo_node_name" /etc/gitlab/gitlab.rb
```
To update the primary node's name in the database:
```shell
gitlab-rails runner 'Gitlab::Geo.primary_node.update!(name: GeoNode.current_node_name)'
```
1. Verify you can connect to the newly promoted **primary** using its URL.
If you updated the DNS records for the primary domain, these changes may
not have yet propagated depending on the previous DNS records TTL.
......
......@@ -298,27 +298,12 @@ Here are the steps to gate a new feature in Gitaly behind a feature flag.
### GitLab Rails
1. In GitLab Rails:
1. Add the feature flag to `SERVER_FEATURE_FLAGS` in `lib/feature/gitaly.rb`:
```ruby
SERVER_FEATURE_FLAGS = %w[go-find-all-tags].freeze
```
1. Search for `["gitaly"]["features"]` (currently in `spec/requests/api/internal/base_spec.rb`)
and fix the expected results for the tests by adding the new feature flag into it:
```ruby
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-get-all-lfs-pointers-go' => 'true', 'gitaly-feature-go-find-all-tags' => 'true')
```
1. Test in a Rails console by setting the feature flag:
NOTE: **Note:**
Pay attention to the name of the flag and the one used in the Rails console.
There is a difference between them (dashes replaced by underscores and name
prefix is changed).
prefix is changed). Make sure to prefix all flags with `gitaly_`.
```ruby
Feature.enable('gitaly_go_find_all_tags')
......
......@@ -25,7 +25,7 @@ module Banzai
# Regular expression matching metrics urls
def link_pattern
Gitlab::Metrics::Dashboard::Url.regex
Gitlab::Metrics::Dashboard::Url.metrics_regex
end
private
......
......@@ -59,7 +59,7 @@ module Banzai
embed = Embed.new
url = node.attribute('data-dashboard-url').to_s
set_path_and_permission(embed, url, URL.regex, :read_environment)
set_path_and_permission(embed, url, URL.metrics_regex, :read_environment)
set_path_and_permission(embed, url, URL.grafana_regex, :read_project) unless embed.permission
embeds[node] = embed if embed.permission
......
......@@ -32,6 +32,8 @@ class Feature
end
def persisted_names
return [] unless Gitlab::Database.exists?
Gitlab::SafeRequestStore[:flipper_persisted_names] ||=
begin
# We saw on GitLab.com, this database request was called 2300
......
# frozen_string_literal: true
require 'set'
class Feature
class Gitaly
# Server feature flags should use '_' to separate words.
SERVER_FEATURE_FLAGS =
%w[
cache_invalidator
inforef_uploadpack_cache
commit_without_batch_check
use_core_delta_islands
use_git_protocol_v2
].freeze
DEFAULT_ON_FLAGS = Set.new([]).freeze
PREFIX = "gitaly_"
class << self
def enabled?(feature_flag)
return false unless Feature::FlipperFeature.table_exists?
default_on = DEFAULT_ON_FLAGS.include?(feature_flag)
Feature.enabled?("gitaly_#{feature_flag}", default_enabled: default_on)
Feature.enabled?("#{PREFIX}#{feature_flag}")
rescue ActiveRecord::NoDatabaseError, PG::ConnectionBad
false
end
def server_feature_flags
SERVER_FEATURE_FLAGS.map do |f|
["gitaly-feature-#{f.tr('_', '-')}", enabled?(f).to_s]
Feature.persisted_names
.select { |f| f.start_with?(PREFIX) }
.map do |f|
flag = f.delete_prefix(PREFIX)
["gitaly-feature-#{flag.tr('_', '-')}", enabled?(flag).to_s]
end.to_h
end
end
......
......@@ -203,36 +203,6 @@ module Gitlab
start_repository: start_repository)
end
# DEPRECATED: https://gitlab.com/gitlab-org/gitaly/issues/1628
def user_rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:)
request = Gitaly::UserRebaseRequest.new(
repository: @gitaly_repo,
user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
rebase_id: rebase_id.to_s,
branch: encode_binary(branch),
branch_sha: branch_sha,
remote_repository: remote_repository.gitaly_repository,
remote_branch: encode_binary(remote_branch)
)
response = GitalyClient.call(
@repository.storage,
:operation_service,
:user_rebase,
request,
timeout: GitalyClient.long_timeout,
remote_storage: remote_repository.storage
)
if response.pre_receive_error.presence
raise Gitlab::Git::PreReceiveError, response.pre_receive_error
elsif response.git_error.presence
raise Gitlab::Git::Repository::GitError, response.git_error
else
response.rebase_sha
end
end
def rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:, push_options: [])
request_enum = QueueEnumerator.new
rebase_sha = nil
......
......@@ -6,41 +6,36 @@ module Gitlab
module Dashboard
class Url
class << self
include Gitlab::Utils::StrongMemoize
# Matches urls for a metrics dashboard. This could be
# either the /metrics endpoint or the /metrics_dashboard
# endpoint.
#
# EX - https://<host>/<namespace>/<project>/environments/<env_id>/metrics
def regex
def metrics_regex
strong_memoize(:metrics_regex) do
regex_for_project_metrics(
%r{
(?<url>
#{gitlab_pattern}
#{project_pattern}
(?:\/\-)?
\/environments
\/(?<environment>\d+)
\/metrics
#{query_pattern}
#{anchor_pattern}
)
/environments
/(?<environment>\d+)
/metrics
}x
)
end
end
# Matches dashboard urls for a Grafana embed.
#
# EX - https://<host>/<namespace>/<project>/grafana/metrics_dashboard
def grafana_regex
strong_memoize(:grafana_regex) do
regex_for_project_metrics(
%r{
(?<url>
#{gitlab_pattern}
#{project_pattern}
(?:\/\-)?
\/grafana
\/metrics_dashboard
#{query_pattern}
#{anchor_pattern}
)
/grafana
/metrics_dashboard
}x
)
end
end
# Parses query params out from full url string into hash.
......@@ -62,11 +57,24 @@ module Gitlab
private
def gitlab_pattern
def regex_for_project_metrics(path_suffix_pattern)
%r{
(?<url>
#{gitlab_host_pattern}
#{project_path_pattern}
(?:/-)?
#{path_suffix_pattern}
#{query_pattern}
#{anchor_pattern}
)
}x
end
def gitlab_host_pattern
Regexp.escape(Gitlab.config.gitlab.url)
end
def project_pattern
def project_path_pattern
"\/#{Project.reference_pattern}"
end
......@@ -82,3 +90,5 @@ module Gitlab
end
end
end
Gitlab::Metrics::Dashboard::Url.extend_if_ee('::EE::Gitlab::Metrics::Dashboard::Url')
# frozen_string_literal: true
module QA
context 'Verify', :docker, quarantine: 'https://gitlab.com/gitlab-org/gitlab/issues/202149' do
context 'Verify', :docker, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/issues/202149', type: :flaky } do
describe 'Pipeline creation and processing' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:max_wait) { 30 }
......
......@@ -5,10 +5,6 @@ require 'spec_helper'
describe Feature::Gitaly do
let(:feature_flag) { "mep_mep" }
before do
stub_const("#{described_class}::SERVER_FEATURE_FLAGS", [feature_flag])
end
describe ".enabled?" do
context 'when the gate is closed' do
before do
......@@ -28,15 +24,13 @@ describe Feature::Gitaly do
end
describe ".server_feature_flags" do
context 'when one flag is disabled' do
before do
stub_feature_flags(gitaly_mep_mep: false)
allow(Feature).to receive(:persisted_names).and_return(%w[gitaly_mep_mep foo])
end
subject { described_class.server_feature_flags }
it { is_expected.to be_a(Hash) }
it { is_expected.to eq("gitaly-feature-mep-mep" => "false") }
end
it { is_expected.to eq("gitaly-feature-mep-mep" => "true") }
end
end
......@@ -3,38 +3,6 @@
require 'spec_helper'
describe Gitlab::Metrics::Dashboard::Url do
shared_examples_for 'a regex which matches the expected url' do
it { is_expected.to be_a Regexp }
it 'matches a metrics dashboard link with named params' do
expect(subject).to match url
subject.match(url) do |m|
expect(m.named_captures).to eq expected_params
end
end
end
shared_examples_for 'does not match non-matching urls' do
it 'does not match other gitlab urls that contain the term metrics' do
url = Gitlab::Routing.url_helpers.active_common_namespace_project_prometheus_metrics_url('foo', 'bar', :json)
expect(subject).not_to match url
end
it 'does not match other gitlab urls' do
url = Gitlab.config.gitlab.url
expect(subject).not_to match url
end
it 'does not match non-gitlab urls' do
url = 'https://www.super_awesome_site.com/'
expect(subject).not_to match url
end
end
describe '#regex' do
let(:url) do
Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(
......@@ -59,10 +27,9 @@ describe Gitlab::Metrics::Dashboard::Url do
}
end
subject { described_class.regex }
subject { described_class.metrics_regex }
it_behaves_like 'a regex which matches the expected url'
it_behaves_like 'does not match non-matching urls'
it_behaves_like 'regex which matches url when expected'
end
describe '#grafana_regex' do
......@@ -89,15 +56,14 @@ describe Gitlab::Metrics::Dashboard::Url do
subject { described_class.grafana_regex }
it_behaves_like 'a regex which matches the expected url'
it_behaves_like 'does not match non-matching urls'
it_behaves_like 'regex which matches url when expected'
end
describe '#build_dashboard_url' do
it 'builds the url for the dashboard endpoint' do
url = described_class.build_dashboard_url('foo', 'bar', 1)
expect(url).to match described_class.regex
expect(url).to match described_class.metrics_regex
end
end
end
......@@ -1622,7 +1622,6 @@ describe Repository do
it 'executes the new Gitaly RPC' do
expect_any_instance_of(Gitlab::GitalyClient::OperationService).to receive(:rebase)
expect_any_instance_of(Gitlab::GitalyClient::OperationService).not_to receive(:user_rebase)
repository.rebase(user, merge_request)
end
......
......@@ -313,6 +313,10 @@ describe API::Internal::Base do
end
context "git pull" do
before do
allow(Feature).to receive(:persisted_names).and_return(%w[gitaly_mep_mep])
end
it "has the correct payload" do
pull(key, project)
......@@ -326,7 +330,7 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true', 'gitaly-feature-use-git-protocol-v2' => 'true')
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-mep-mep' => 'true')
expect(user.reload.last_activity_on).to eql(Date.today)
end
end
......@@ -346,7 +350,6 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true', 'gitaly-feature-use-git-protocol-v2' => 'true')
expect(user.reload.last_activity_on).to be_nil
end
end
......@@ -594,7 +597,6 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true', 'gitaly-feature-use-git-protocol-v2' => 'true')
end
end
......
# frozen_string_literal: true
RSpec.shared_examples 'regex which matches url when expected' do
it { is_expected.to be_a Regexp }
it 'matches a metrics dashboard link with named params' do
expect(subject).to match url
subject.match(url) do |m|
expect(m.named_captures).to eq expected_params
end
end
it 'does not match other gitlab urls that contain the term metrics' do
url = Gitlab::Routing.url_helpers.active_common_namespace_project_prometheus_metrics_url('foo', 'bar', :json)
expect(subject).not_to match url
end
it 'does not match other gitlab urls' do
url = Gitlab.config.gitlab.url
expect(subject).not_to match url
end
it 'does not match non-gitlab urls' do
url = 'https://www.super_awesome_site.com/'
expect(subject).not_to match url
end
end
# frozen_string_literal: true
require 'spec_helper'
describe 'shared/projects/_list' do
let(:group) { create(:group) }
before do
allow(view).to receive(:projects).and_return(projects)
allow(view).to receive(:project_list_cache_key).and_return('fake_cache_key')
end
context 'with projects' do
let(:projects) { build_stubbed_list(:project, 1) }
it 'renders the list of projects' do
render
projects.each do |project|
expect(rendered).to have_content(project.name)
end
end
end
context 'without projects' do
let(:projects) { [] }
context 'when @contributed_projects is set' do
context 'and is empty' do
before do
@contributed_projects = []
end
it 'renders a no-content message' do
render
expect(rendered).to have_content(s_('UserProfile|This user hasn\'t contributed to any projects'))
end
end
end
context 'when @starred_projects is set' do
context 'and is empty' do
before do
@starred_projects = []
end
it 'renders a no-content message' do
render
expect(rendered).to have_content(s_('UserProfile|This user hasn\'t starred any projects'))
end
end
end
context 'and without a special instance variable' do
context 'for an explore_page' do
before do
allow(view).to receive(:explore_page).and_return(true)
end
it 'renders a no-content message' do
render
expect(rendered).to have_content(s_('UserProfile|Explore public groups to find projects to contribute to.'))
end
end
context 'for a non-explore page' do
it 'renders a no-content message' do
render
expect(rendered).to have_content(s_('UserProfile|This user doesn\'t have any personal projects'))
end
end
end
end
end
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