summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-24 12:09:00 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-24 12:09:00 +0000
commitae78b85a25cb0c19c3d6a2e4e6c7ca91ed50787d (patch)
treec53ad0fcdab26725814f1dc5267f6a04ebe4cf73 /lib
parent38149afcf95e7669a7a99828c579d185b70c04dc (diff)
downloadgitlab-ce-ae78b85a25cb0c19c3d6a2e4e6c7ca91ed50787d.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r--lib/api/entities/internal/pages/lookup_path.rb (renamed from lib/api/entities/internal.rb)5
-rw-r--r--lib/api/entities/internal/pages/virtual_domain.rb14
-rw-r--r--lib/api/entities/internal/serverless/lookup_path.rb13
-rw-r--r--lib/api/entities/internal/serverless/virtual_domain.rb14
-rw-r--r--lib/api/internal/pages.rb23
-rw-r--r--lib/gitlab/ci/config/entry/bridge.rb90
-rw-r--r--lib/gitlab/ci/config/entry/job.rb102
-rw-r--r--lib/gitlab/ci/config/entry/processable.rb102
-rw-r--r--lib/gitlab/ci/config/entry/root.rb4
-rw-r--r--lib/gitlab/config/entry/configurable.rb12
-rw-r--r--lib/gitlab/danger/helper.rb3
-rw-r--r--lib/gitlab/gon_helper.rb1
-rw-r--r--lib/gitlab/import_export/members_mapper.rb12
-rw-r--r--lib/gitlab/kubernetes/helm.rb2
-rw-r--r--lib/gitlab/reference_counter.rb55
15 files changed, 269 insertions, 183 deletions
diff --git a/lib/api/entities/internal.rb b/lib/api/entities/internal/pages/lookup_path.rb
index 8f79bd14833..1bf94f74fb4 100644
--- a/lib/api/entities/internal.rb
+++ b/lib/api/entities/internal/pages/lookup_path.rb
@@ -8,11 +8,6 @@ module API
expose :project_id, :access_control,
:source, :https_only, :prefix
end
-
- class VirtualDomain < Grape::Entity
- expose :certificate, :key
- expose :lookup_paths, using: LookupPath
- end
end
end
end
diff --git a/lib/api/entities/internal/pages/virtual_domain.rb b/lib/api/entities/internal/pages/virtual_domain.rb
new file mode 100644
index 00000000000..27eb7571368
--- /dev/null
+++ b/lib/api/entities/internal/pages/virtual_domain.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ module Internal
+ module Pages
+ class VirtualDomain < Grape::Entity
+ expose :certificate, :key
+ expose :lookup_paths, using: LookupPath
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/entities/internal/serverless/lookup_path.rb b/lib/api/entities/internal/serverless/lookup_path.rb
new file mode 100644
index 00000000000..8ca40b4f128
--- /dev/null
+++ b/lib/api/entities/internal/serverless/lookup_path.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ module Internal
+ module Serverless
+ class LookupPath < Grape::Entity
+ expose :source
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/entities/internal/serverless/virtual_domain.rb b/lib/api/entities/internal/serverless/virtual_domain.rb
new file mode 100644
index 00000000000..8b53aa51bf5
--- /dev/null
+++ b/lib/api/entities/internal/serverless/virtual_domain.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ module Internal
+ module Serverless
+ class VirtualDomain < Grape::Entity
+ expose :certificate, :key
+ expose :lookup_paths, using: LookupPath
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/internal/pages.rb b/lib/api/internal/pages.rb
index a2fe3e09df8..e2e1351c939 100644
--- a/lib/api/internal/pages.rb
+++ b/lib/api/internal/pages.rb
@@ -24,13 +24,26 @@ module API
requires :host, type: String, desc: 'The host to query for'
end
get "/" do
- host = Namespace.find_by_pages_host(params[:host]) || PagesDomain.find_by_domain(params[:host])
- no_content! unless host
+ serverless_domain_finder = ServerlessDomainFinder.new(params[:host])
+ if serverless_domain_finder.serverless?
+ # Handle Serverless domains
+ serverless_domain = serverless_domain_finder.execute
+ no_content! unless serverless_domain
- virtual_domain = host.pages_virtual_domain
- no_content! unless virtual_domain
+ virtual_domain = Serverless::VirtualDomain.new(serverless_domain)
+ no_content! unless virtual_domain
- present virtual_domain, with: Entities::Internal::Pages::VirtualDomain
+ present virtual_domain, with: Entities::Internal::Serverless::VirtualDomain
+ else
+ # Handle Pages domains
+ host = Namespace.find_by_pages_host(params[:host]) || PagesDomain.find_by_domain(params[:host])
+ no_content! unless host
+
+ virtual_domain = host.pages_virtual_domain
+ no_content! unless virtual_domain
+
+ present virtual_domain, with: Entities::Internal::Pages::VirtualDomain
+ end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/bridge.rb b/lib/gitlab/ci/config/entry/bridge.rb
index c0247dca73d..721c7c8b6d7 100644
--- a/lib/gitlab/ci/config/entry/bridge.rb
+++ b/lib/gitlab/ci/config/entry/bridge.rb
@@ -9,34 +9,21 @@ module Gitlab
# defining a downstream project trigger.
#
class Bridge < ::Gitlab::Config::Entry::Node
- include ::Gitlab::Config::Entry::Configurable
- include ::Gitlab::Config::Entry::Attributable
- include ::Gitlab::Config::Entry::Inheritable
+ include ::Gitlab::Ci::Config::Entry::Processable
- ALLOWED_KEYS = %i[trigger stage allow_failure only except
- when extends variables needs rules].freeze
+ ALLOWED_KEYS = %i[trigger allow_failure when variables needs].freeze
validations do
- validates :config, allowed_keys: ALLOWED_KEYS
- validates :config, presence: true
- validates :name, presence: true
- validates :name, type: Symbol
- validates :config, disallowed_keys: {
- in: %i[only except when start_in],
- message: 'key may not be used with `rules`'
- },
- if: :has_rules?
+ validates :config, allowed_keys: ALLOWED_KEYS + PROCESSABLE_ALLOWED_KEYS
with_options allow_nil: true do
validates :when,
inclusion: { in: %w[on_success on_failure always],
message: 'should be on_success, on_failure or always' }
- validates :extends, type: String
- validates :rules, array_of_hashes: true
end
validate on: :composed do
- unless trigger.present? || bridge_needs.present?
+ unless trigger_defined? || bridge_needs.present?
errors.add(:config, 'should contain either a trigger or a needs:pipeline')
end
end
@@ -58,32 +45,13 @@ module Gitlab
inherit: false,
metadata: { allowed_needs: %i[job bridge] }
- entry :stage, ::Gitlab::Ci::Config::Entry::Stage,
- description: 'Pipeline stage this job will be executed into.',
- inherit: false
-
- entry :only, ::Gitlab::Ci::Config::Entry::Policy,
- description: 'Refs policy this job will be executed for.',
- default: ::Gitlab::Ci::Config::Entry::Policy::DEFAULT_ONLY,
- inherit: false
-
- entry :except, ::Gitlab::Ci::Config::Entry::Policy,
- description: 'Refs policy this job will be executed for.',
- inherit: false
-
- entry :rules, ::Gitlab::Ci::Config::Entry::Rules,
- description: 'List of evaluable Rules to determine job inclusion.',
- inherit: false,
- metadata: {
- allowed_when: %w[on_success on_failure always never manual delayed].freeze
- }
-
entry :variables, ::Gitlab::Ci::Config::Entry::Variables,
description: 'Environment variables available for this job.',
inherit: false
- helpers(*ALLOWED_KEYS)
- attributes(*ALLOWED_KEYS)
+ helpers :trigger, :needs, :variables
+
+ attributes :when, :allow_failure
def self.matching?(name, config)
!name.to_s.start_with?('.') &&
@@ -95,56 +63,20 @@ module Gitlab
true
end
- def compose!(deps = nil)
- super do
- has_workflow_rules = deps&.workflow&.has_rules?
-
- # If workflow:rules: or rules: are used
- # they are considered not compatible
- # with `only/except` defaults
- #
- # Context: https://gitlab.com/gitlab-org/gitlab/merge_requests/21742
- if has_rules? || has_workflow_rules
- # Remove only/except defaults
- # defaults are not considered as defined
- @entries.delete(:only) unless only_defined?
- @entries.delete(:except) unless except_defined?
- end
- end
- end
-
- def has_rules?
- @config&.key?(:rules)
- end
-
- def name
- @metadata[:name]
- end
-
def value
- { name: name,
+ super.merge(
trigger: (trigger_value if trigger_defined?),
needs: (needs_value if needs_defined?),
ignore: !!allow_failure,
- stage: stage_value,
- when: when_value,
- extends: extends_value,
+ when: self.when,
variables: (variables_value if variables_defined?),
- rules: (rules_value if has_rules?),
- only: only_value,
- except: except_value,
- scheduling_type: needs_defined? && !bridge_needs ? :dag : :stage }.compact
+ scheduling_type: needs_defined? && !bridge_needs ? :dag : :stage
+ ).compact
end
def bridge_needs
needs_value[:bridge] if needs_value
end
-
- private
-
- def overwrite_entry(deps, key, current_entry)
- deps.default[key] unless current_entry.specified?
- end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index 666c6e23eb4..931f769e920 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -8,33 +8,21 @@ module Gitlab
# Entry that represents a concrete CI/CD job.
#
class Job < ::Gitlab::Config::Entry::Node
- include ::Gitlab::Config::Entry::Configurable
- include ::Gitlab::Config::Entry::Attributable
- include ::Gitlab::Config::Entry::Inheritable
+ include ::Gitlab::Ci::Config::Entry::Processable
ALLOWED_WHEN = %w[on_success on_failure always manual delayed].freeze
- ALLOWED_KEYS = %i[tags script only except rules type image services
- allow_failure type stage when start_in artifacts cache
+ ALLOWED_KEYS = %i[tags script type image services
+ allow_failure type when start_in artifacts cache
dependencies before_script needs after_script variables
- environment coverage retry parallel extends interruptible timeout
+ environment coverage retry parallel interruptible timeout
resource_group release].freeze
REQUIRED_BY_NEEDS = %i[stage].freeze
validations do
- validates :config, type: Hash
- validates :config, allowed_keys: ALLOWED_KEYS
+ validates :config, allowed_keys: ALLOWED_KEYS + PROCESSABLE_ALLOWED_KEYS
validates :config, required_keys: REQUIRED_BY_NEEDS, if: :has_needs?
- validates :config, presence: true
validates :script, presence: true
- validates :name, presence: true
- validates :name, type: Symbol
- validates :config,
- disallowed_keys: {
- in: %i[only except when start_in],
- message: 'key may not be used with `rules`'
- },
- if: :has_rules?
validates :config,
disallowed_keys: {
in: %i[release],
@@ -53,8 +41,6 @@ module Gitlab
}
validates :dependencies, array_of_strings: true
- validates :extends, array_of_strings_or_string: true
- validates :rules, array_of_hashes: true
validates :resource_group, type: String
end
@@ -81,10 +67,6 @@ module Gitlab
description: 'Commands that will be executed in this job.',
inherit: false
- entry :stage, Entry::Stage,
- description: 'Pipeline stage this job will be executed into.',
- inherit: false
-
entry :type, Entry::Stage,
description: 'Deprecated: stage this job will be executed into.',
inherit: false
@@ -125,22 +107,6 @@ module Gitlab
description: 'Artifacts configuration for this job.',
inherit: true
- entry :only, Entry::Policy,
- description: 'Refs policy this job will be executed for.',
- default: ::Gitlab::Ci::Config::Entry::Policy::DEFAULT_ONLY,
- inherit: false
-
- entry :except, Entry::Policy,
- description: 'Refs policy this job will be executed for.',
- inherit: false
-
- entry :rules, Entry::Rules,
- description: 'List of evaluable Rules to determine job inclusion.',
- inherit: false,
- metadata: {
- allowed_when: %w[on_success on_failure always never manual delayed].freeze
- }
-
entry :needs, Entry::Needs,
description: 'Needs configuration for this job.',
metadata: { allowed_needs: %i[job cross_dependency] },
@@ -162,13 +128,13 @@ module Gitlab
description: 'This job will produce a release.',
inherit: false
- helpers :before_script, :script, :stage, :type, :after_script,
- :cache, :image, :services, :only, :except, :variables,
- :artifacts, :environment, :coverage, :retry, :rules,
- :parallel, :needs, :interruptible, :release, :tags
+ helpers :before_script, :script, :type, :after_script,
+ :cache, :image, :services, :variables,
+ :artifacts, :environment, :coverage, :retry,
+ :needs, :interruptible, :release, :tags
attributes :script, :tags, :allow_failure, :when, :dependencies,
- :needs, :retry, :parallel, :extends, :start_in, :rules,
+ :needs, :retry, :parallel, :start_in,
:interruptible, :timeout, :resource_group, :release
def self.matching?(name, config)
@@ -187,31 +153,9 @@ module Gitlab
end
@entries.delete(:type)
-
- has_workflow_rules = deps&.workflow&.has_rules?
-
- # If workflow:rules: or rules: are used
- # they are considered not compatible
- # with `only/except` defaults
- #
- # Context: https://gitlab.com/gitlab-org/gitlab/merge_requests/21742
- if has_rules? || has_workflow_rules
- # Remove only/except defaults
- # defaults are not considered as defined
- @entries.delete(:only) unless only_defined?
- @entries.delete(:except) unless except_defined?
- end
end
end
- def name
- @metadata[:name]
- end
-
- def value
- @config.merge(to_hash.compact)
- end
-
def manual_action?
self.when == 'manual'
end
@@ -220,38 +164,27 @@ module Gitlab
self.when == 'delayed'
end
- def has_rules?
- @config.try(:key?, :rules)
- end
-
def ignored?
allow_failure.nil? ? manual_action? : allow_failure
end
- private
-
- def overwrite_entry(deps, key, current_entry)
- deps.default[key] unless current_entry.specified?
- end
-
- def to_hash
- { name: name,
+ def value
+ super.merge(
before_script: before_script_value,
script: script_value,
image: image_value,
services: services_value,
- stage: stage_value,
cache: cache_value,
tags: tags_value,
- only: only_value,
- except: except_value,
- rules: has_rules? ? rules_value : nil,
+ when: self.when,
+ start_in: self.start_in,
+ dependencies: dependencies,
variables: variables_defined? ? variables_value : {},
environment: environment_defined? ? environment_value : nil,
environment_name: environment_defined? ? environment_value[:name] : nil,
coverage: coverage_defined? ? coverage_value : nil,
retry: retry_defined? ? retry_value : nil,
- parallel: parallel_defined? ? parallel_value.to_i : nil,
+ parallel: has_parallel? ? parallel.to_i : nil,
interruptible: interruptible_defined? ? interruptible_value : nil,
timeout: has_timeout? ? ChronicDuration.parse(timeout.to_s) : nil,
artifacts: artifacts_value,
@@ -260,7 +193,8 @@ module Gitlab
ignore: ignored?,
needs: needs_defined? ? needs_value : nil,
resource_group: resource_group,
- scheduling_type: needs_defined? ? :dag : :stage }
+ scheduling_type: needs_defined? ? :dag : :stage
+ ).compact
end
end
end
diff --git a/lib/gitlab/ci/config/entry/processable.rb b/lib/gitlab/ci/config/entry/processable.rb
new file mode 100644
index 00000000000..19e6601e31f
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/processable.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # Entry that represents a CI/CD Processable (a job)
+ #
+ module Processable
+ extend ActiveSupport::Concern
+
+ include ::Gitlab::Config::Entry::Configurable
+ include ::Gitlab::Config::Entry::Attributable
+ include ::Gitlab::Config::Entry::Inheritable
+
+ PROCESSABLE_ALLOWED_KEYS = %i[extends stage only except rules].freeze
+
+ included do
+ validations do
+ validates :config, presence: true
+ validates :name, presence: true
+ validates :name, type: Symbol
+
+ validates :config, disallowed_keys: {
+ in: %i[only except when start_in],
+ message: 'key may not be used with `rules`'
+ },
+ if: :has_rules?
+
+ with_options allow_nil: true do
+ validates :extends, array_of_strings_or_string: true
+ validates :rules, array_of_hashes: true
+ end
+ end
+
+ entry :stage, Entry::Stage,
+ description: 'Pipeline stage this job will be executed into.',
+ inherit: false
+
+ entry :only, ::Gitlab::Ci::Config::Entry::Policy,
+ description: 'Refs policy this job will be executed for.',
+ default: ::Gitlab::Ci::Config::Entry::Policy::DEFAULT_ONLY,
+ inherit: false
+
+ entry :except, ::Gitlab::Ci::Config::Entry::Policy,
+ description: 'Refs policy this job will be executed for.',
+ inherit: false
+
+ entry :rules, ::Gitlab::Ci::Config::Entry::Rules,
+ description: 'List of evaluable Rules to determine job inclusion.',
+ inherit: false,
+ metadata: {
+ allowed_when: %w[on_success on_failure always never manual delayed].freeze
+ }
+
+ helpers :stage, :only, :except, :rules
+
+ attributes :extends, :rules
+ end
+
+ def compose!(deps = nil)
+ super do
+ has_workflow_rules = deps&.workflow&.has_rules?
+
+ # If workflow:rules: or rules: are used
+ # they are considered not compatible
+ # with `only/except` defaults
+ #
+ # Context: https://gitlab.com/gitlab-org/gitlab/merge_requests/21742
+ if has_rules? || has_workflow_rules
+ # Remove only/except defaults
+ # defaults are not considered as defined
+ @entries.delete(:only) unless only_defined? # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ @entries.delete(:except) unless except_defined? # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ end
+
+ yield if block_given?
+ end
+ end
+
+ def name
+ metadata[:name]
+ end
+
+ def overwrite_entry(deps, key, current_entry)
+ deps.default[key] unless current_entry.specified?
+ end
+
+ def value
+ { name: name,
+ stage: stage_value,
+ extends: extends,
+ rules: rules_value,
+ only: only_value,
+ except: except_value }.compact
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb
index 12dd942fc1c..620f6a95e9d 100644
--- a/lib/gitlab/ci/config/entry/root.rb
+++ b/lib/gitlab/ci/config/entry/root.rb
@@ -67,7 +67,9 @@ module Gitlab
entry :workflow, Entry::Workflow,
description: 'List of evaluable rules to determine Pipeline status'
- helpers :default, :jobs, :stages, :types, :variables, :workflow
+ helpers :default, :stages, :types, :variables, :workflow
+
+ helpers :jobs, dynamic: true
delegate :before_script_value,
:image_value,
diff --git a/lib/gitlab/config/entry/configurable.rb b/lib/gitlab/config/entry/configurable.rb
index e7d441bb21c..75e15cd8cb1 100644
--- a/lib/gitlab/config/entry/configurable.rb
+++ b/lib/gitlab/config/entry/configurable.rb
@@ -75,6 +75,8 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def entry(key, entry, description: nil, default: nil, inherit: nil, reserved: nil, metadata: {})
+ raise ArgumentError, "Entry #{key} already defined" if @nodes.to_h[key.to_sym]
+
factory = ::Gitlab::Config::Entry::Factory.new(entry)
.with(description: description)
.with(default: default)
@@ -86,8 +88,16 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
- def helpers(*nodes)
+ def helpers(*nodes, dynamic: false)
nodes.each do |symbol|
+ if method_defined?("#{symbol}_defined?") || method_defined?("#{symbol}_value")
+ raise ArgumentError, "Method #{symbol}_defined? or #{symbol}_value already defined"
+ end
+
+ unless @nodes.to_h[symbol]
+ raise ArgumentError, "Entry for #{symbol} is undefined" unless dynamic
+ end
+
define_method("#{symbol}_defined?") do
entries[symbol]&.specified?
end
diff --git a/lib/gitlab/danger/helper.rb b/lib/gitlab/danger/helper.rb
index 5363533ace5..3c3f95e5b78 100644
--- a/lib/gitlab/danger/helper.rb
+++ b/lib/gitlab/danger/helper.rb
@@ -128,9 +128,12 @@ module Gitlab
%r{\A(ee/)?db/(?!fixtures)[^/]+} => :database,
%r{\A(ee/)?lib/gitlab/(database|background_migration|sql|github_import)(/|\.rb)} => :database,
%r{\A(app/models/project_authorization|app/services/users/refresh_authorized_projects_service)(/|\.rb)} => :database,
+ %r{\A(ee/)?app/finders/} => :database,
%r{\Arubocop/cop/migration(/|\.rb)} => :database,
%r{\A(\.gitlab-ci\.yml\z|\.gitlab\/ci)} => :engineering_productivity,
+ %r{\A\.overcommit\.yml\.example\z} => :engineering_productivity,
+ %r{\Atooling/overcommit/} => :engineering_productivity,
%r{Dangerfile\z} => :engineering_productivity,
%r{\A(ee/)?(danger/|lib/gitlab/danger/)} => :engineering_productivity,
%r{\A(ee/)?scripts/} => :engineering_productivity,
diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb
index 3db6c3b51c0..e4e69241bd9 100644
--- a/lib/gitlab/gon_helper.rb
+++ b/lib/gitlab/gon_helper.rb
@@ -46,6 +46,7 @@ module Gitlab
push_frontend_feature_flag(:monaco_snippets, default_enabled: false)
push_frontend_feature_flag(:monaco_blobs, default_enabled: false)
push_frontend_feature_flag(:monaco_ci, default_enabled: false)
+ push_frontend_feature_flag(:snippets_edit_vue, default_enabled: false)
end
# Exposes the state of a feature flag to the frontend code.
diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb
index 2a70344374b..e7eae0a8c31 100644
--- a/lib/gitlab/import_export/members_mapper.rb
+++ b/lib/gitlab/import_export/members_mapper.rb
@@ -51,7 +51,7 @@ module Gitlab
@importable.members.destroy_all # rubocop: disable DestroyAll
- relation_class.create!(user: @user, access_level: relation_class::MAINTAINER, source_id: @importable.id, importing: true)
+ relation_class.create!(user: @user, access_level: highest_access_level, source_id: @importable.id, importing: true)
rescue => e
raise e, "Error adding importer user to #{@importable.class} members. #{e.message}"
end
@@ -59,7 +59,7 @@ module Gitlab
def user_already_member?
member = @importable.members&.first
- member&.user == @user && member.access_level >= relation_class::MAINTAINER
+ member&.user == @user && member.access_level >= highest_access_level
end
def add_team_member(member, existing_user = nil)
@@ -72,7 +72,7 @@ module Gitlab
parsed_hash(member).merge(
'source_id' => @importable.id,
'importing' => true,
- 'access_level' => [member['access_level'], relation_class::MAINTAINER].min
+ 'access_level' => [member['access_level'], highest_access_level].min
).except('user_id')
end
@@ -97,6 +97,12 @@ module Gitlab
GroupMember
end
end
+
+ def highest_access_level
+ return relation_class::OWNER if relation_class == GroupMember
+
+ relation_class::MAINTAINER
+ end
end
end
end
diff --git a/lib/gitlab/kubernetes/helm.rb b/lib/gitlab/kubernetes/helm.rb
index 9f66f35b5ab..3e201d68297 100644
--- a/lib/gitlab/kubernetes/helm.rb
+++ b/lib/gitlab/kubernetes/helm.rb
@@ -3,7 +3,7 @@
module Gitlab
module Kubernetes
module Helm
- HELM_VERSION = '2.16.1'
+ HELM_VERSION = '2.16.3'
KUBECTL_VERSION = '1.13.12'
NAMESPACE = 'gitlab-managed-apps'
NAMESPACE_LABELS = { 'app.gitlab.com/managed_by' => :gitlab }.freeze
diff --git a/lib/gitlab/reference_counter.rb b/lib/gitlab/reference_counter.rb
index 1c43de35816..5fdfa5e75ed 100644
--- a/lib/gitlab/reference_counter.rb
+++ b/lib/gitlab/reference_counter.rb
@@ -1,20 +1,42 @@
# frozen_string_literal: true
module Gitlab
+ # Reference Counter
+ #
+ # A reference counter is used as a mechanism to identify when
+ # a repository is being accessed by a writable operation.
+ #
+ # Maintenance operations would use this as a clue to when it should
+ # execute significant changes in order to avoid disrupting running traffic
class ReferenceCounter
REFERENCE_EXPIRE_TIME = 600
attr_reader :gl_repository, :key
+ # Reference Counter instance
+ #
+ # @example
+ # Gitlab::ReferenceCounter.new('project-1')
+ #
+ # @see Gitlab::GlRepository::RepoType.identifier_for_repositorable
+ # @param [String] gl_repository repository identifier
def initialize(gl_repository)
@gl_repository = gl_repository
@key = "git-receive-pack-reference-counter:#{gl_repository}"
end
+ # Return the actual counter value
+ #
+ # @return [Integer] value
def value
- Gitlab::Redis::SharedState.with { |redis| (redis.get(key) || 0).to_i }
+ Gitlab::Redis::SharedState.with do |redis|
+ (redis.get(key) || 0).to_i
+ end
end
+ # Increase the counter
+ #
+ # @return [Boolean] whether operation was a success
def increase
redis_cmd do |redis|
redis.incr(key)
@@ -22,26 +44,51 @@ module Gitlab
end
end
- # rubocop:disable Gitlab/RailsLogger
+ # Decrease the counter
+ #
+ # @return [Boolean] whether operation was a success
def decrease
redis_cmd do |redis|
current_value = redis.decr(key)
if current_value < 0
+ # rubocop:disable Gitlab/RailsLogger
Rails.logger.warn("Reference counter for #{gl_repository} decreased" \
- " when its value was less than 1. Reseting the counter.")
+ " when its value was less than 1. Resetting the counter.")
+ # rubocop:enable Gitlab/RailsLogger
redis.del(key)
end
end
end
- # rubocop:enable Gitlab/RailsLogger
+
+ # Reset the reference counter
+ #
+ # @private Used internally by SRE and debugging purpose
+ # @return [Boolean] whether reset was a success
+ def reset!
+ redis_cmd do |redis|
+ redis.del(key)
+ end
+ end
+
+ # When the reference counter would expire
+ #
+ # @api private Used internally by SRE and debugging purpose
+ # @return [Integer] Number in seconds until expiration or false if never
+ def expires_in
+ Gitlab::Redis::SharedState.with do |redis|
+ redis.ttl(key)
+ end
+ end
private
def redis_cmd
Gitlab::Redis::SharedState.with { |redis| yield(redis) }
+
true
rescue => e
Rails.logger.warn("GitLab: An unexpected error occurred in writing to Redis: #{e}") # rubocop:disable Gitlab/RailsLogger
+
false
end
end