summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/matching/runner_matcher.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/matching/runner_matcher.rb')
-rw-r--r--lib/gitlab/ci/matching/runner_matcher.rb68
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/gitlab/ci/matching/runner_matcher.rb b/lib/gitlab/ci/matching/runner_matcher.rb
new file mode 100644
index 00000000000..63642674936
--- /dev/null
+++ b/lib/gitlab/ci/matching/runner_matcher.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Matching
+ ###
+ # This class is used to check if a build can be picked by a runner:
+ #
+ # runner = Ci::Runner.find(id)
+ # build = Ci::Build.find(id)
+ # runner.runner_matcher.matches?(build.build_matcher)
+ #
+ # There are also class level methods to build matchers:
+ #
+ # `project.builds.build_matchers(project)` returns a distinct collection
+ # of build matchers.
+ # `Ci::Runner.runner_matchers` returns a distinct collection of runner matchers.
+ #
+ class RunnerMatcher
+ ATTRIBUTES = %i[
+ runner_type
+ public_projects_minutes_cost_factor
+ private_projects_minutes_cost_factor
+ run_untagged
+ access_level
+ tag_list
+ ].freeze
+
+ attr_reader(*ATTRIBUTES)
+
+ def initialize(params)
+ ATTRIBUTES.each do |attribute|
+ instance_variable_set("@#{attribute}", params.fetch(attribute))
+ end
+ end
+
+ def matches?(build_matcher)
+ ensure_build_matcher_instance!(build_matcher)
+ return false if ref_protected? && !build_matcher.protected?
+
+ accepting_tags?(build_matcher)
+ end
+
+ def instance_type?
+ runner_type.to_sym == :instance_type
+ end
+
+ private
+
+ def ref_protected?
+ access_level.to_sym == :ref_protected
+ end
+
+ def accepting_tags?(build_matcher)
+ (run_untagged || build_matcher.has_tags?) && (build_matcher.tag_list - tag_list).empty?
+ end
+
+ def ensure_build_matcher_instance!(build_matcher)
+ return if build_matcher.is_a?(Matching::BuildMatcher)
+
+ raise ArgumentError, 'only Gitlab::Ci::Matching::BuildMatcher are allowed'
+ end
+ end
+ end
+ end
+end
+
+Gitlab::Ci::Matching::RunnerMatcher.prepend_mod_with('Gitlab::Ci::Matching::RunnerMatcher')