Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/runner_upgrade_check.rb')
-rw-r--r--lib/gitlab/ci/runner_upgrade_check.rb101
1 files changed, 48 insertions, 53 deletions
diff --git a/lib/gitlab/ci/runner_upgrade_check.rb b/lib/gitlab/ci/runner_upgrade_check.rb
index 0808290fe5b..10a89bb15d4 100644
--- a/lib/gitlab/ci/runner_upgrade_check.rb
+++ b/lib/gitlab/ci/runner_upgrade_check.rb
@@ -5,76 +5,71 @@ module Gitlab
class RunnerUpgradeCheck
include Singleton
- STATUSES = {
- invalid: 'Runner version is not valid.',
- not_available: 'Upgrade is not available for the runner.',
- available: 'Upgrade is available for the runner.',
- recommended: 'Upgrade is available and recommended for the runner.'
- }.freeze
-
- def initialize
- reset!
- end
-
def check_runner_upgrade_status(runner_version)
- return :invalid unless runner_version
+ runner_version = ::Gitlab::VersionInfo.parse(runner_version, parse_suffix: true)
- releases = RunnerReleases.instance.releases
- orig_runner_version = runner_version
- runner_version = ::Gitlab::VersionInfo.parse(runner_version) unless runner_version.is_a?(::Gitlab::VersionInfo)
+ return { invalid_version: runner_version } unless runner_version.valid?
+ return { error: runner_version } unless runner_releases_store.releases
- raise ArgumentError, "'#{orig_runner_version}' is not a valid version" unless runner_version.valid?
+ # Recommend update if outside of backport window
+ recommended_version = recommendation_if_outside_backport_window(runner_version)
+ return { recommended: recommended_version } if recommended_version
- gitlab_minor_version = version_without_patch(@gitlab_version)
+ # Recommend patch update if there's a newer release in a same minor branch as runner
+ recommended_version = recommended_runner_release_update(runner_version)
+ return { recommended: recommended_version } if recommended_version
- available_releases = releases
- .reject { |release| release.major > @gitlab_version.major }
- .reject do |release|
- release_minor_version = version_without_patch(release)
+ # Consider update if there's a newer release within the currently deployed GitLab version
+ available_version = available_runner_release(runner_version)
+ return { available: available_version } if available_version
- # Do not reject a patch update, even if the runner is ahead of the instance version
- next false if version_without_patch(runner_version) == release_minor_version
+ { not_available: runner_version }
+ end
- release_minor_version > gitlab_minor_version
- end
+ private
- return :recommended if available_releases.any? { |available_rel| patch_update?(available_rel, runner_version) }
- return :recommended if outside_backport_window?(runner_version, releases)
- return :available if available_releases.any? { |available_rel| available_rel > runner_version }
+ def recommended_runner_release_update(runner_version)
+ recommended_release = runner_releases_store.releases_by_minor[runner_version.without_patch]
+ return recommended_release if recommended_release && recommended_release > runner_version
- :not_available
+ # Consider the edge case of pre-release runner versions that get registered, but are never published.
+ # In this case, suggest the latest compatible runner version
+ latest_release = runner_releases_store.releases_by_minor.values.select { |v| v < gitlab_version }.max
+ latest_release if latest_release && latest_release > runner_version
end
- def reset!
- @gitlab_version = ::Gitlab::VersionInfo.parse(::Gitlab::VERSION)
+ def available_runner_release(runner_version)
+ available_release = runner_releases_store.releases_by_minor[gitlab_version.without_patch]
+ available_release if available_release && available_release > runner_version
end
- public_class_method :instance
-
- private
-
- def patch_update?(available_release, runner_version)
- # https://docs.gitlab.com/ee/policy/maintenance.html#patch-releases
- available_release.major == runner_version.major &&
- available_release.minor == runner_version.minor &&
- available_release.patch > runner_version.patch
+ def gitlab_version
+ @gitlab_version ||= ::Gitlab::VersionInfo.parse(::Gitlab::VERSION, parse_suffix: true)
end
- def outside_backport_window?(runner_version, releases)
- return false if runner_version >= releases.last # return early if runner version is too new
-
- latest_minor_releases = releases.map { |r| version_without_patch(r) }.uniq { |v| v.to_s }
- latest_version_position = latest_minor_releases.count - 1
- runner_version_position = latest_minor_releases.index(version_without_patch(runner_version))
-
- return true if runner_version_position.nil? # consider outside if version is too old
-
- # https://docs.gitlab.com/ee/policy/maintenance.html#backporting-to-older-releases
- latest_version_position - runner_version_position > 2
+ def runner_releases_store
+ RunnerReleases.instance
end
- def version_without_patch(version)
- ::Gitlab::VersionInfo.new(version.major, version.minor, 0)
+ def recommendation_if_outside_backport_window(runner_version)
+ return if runner_releases_store.releases.empty?
+ return if runner_version >= runner_releases_store.releases.last # return early if runner version is too new
+
+ minor_releases_with_index = runner_releases_store.releases_by_minor.keys.each_with_index.to_h
+ runner_minor_version_index = minor_releases_with_index[runner_version.without_patch]
+ if runner_minor_version_index
+ # https://docs.gitlab.com/ee/policy/maintenance.html#backporting-to-older-releases
+ outside_window = minor_releases_with_index.count - runner_minor_version_index > 3
+
+ if outside_window
+ recommended_release = runner_releases_store.releases_by_minor[gitlab_version.without_patch]
+
+ recommended_release if recommended_release && recommended_release > runner_version
+ end
+ else
+ # If unknown runner version, then recommend the latest version for the GitLab instance
+ recommended_runner_release_update(gitlab_version)
+ end
end
end
end