Puppet Function: os_version

Defined in:
modules/wmflib/lib/puppet/parser/functions/os_version.rb
Function type:
Ruby 3.x API

Overview

os_version()Any

Returns:

  • (Any)


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'modules/wmflib/lib/puppet/parser/functions/os_version.rb', line 40

newfunction(:os_version, :type => :rvalue, :arity => 1) do |args|
  self_release = lookupvar('lsbdistrelease')
  self_id = lookupvar('lsbdistid')

  if self_release.nil? || self_id.nil?
    fail('os_version(): LSB facts are not set; is lsb-release installed?')
  end

  unless args.first.is_a?(String)
    fail(ArgumentError, 'os_version(): string argument required')
  end

  clauses = args.first.split('||').map(&:strip)
  clauses.any? do |clause|
    unless /^(?<id>\w+) *(?<operator>[<>=]*) *(?<release>[\w\.]+)$/ =~ clause
      fail(ArgumentError, "os_version(): invalid expression '#{clause}'")
    end

    # OS names are in caps, distributions in lowercase
    other_id = id.capitalize
    other_release = release.downcase

    # if a codename was passed, get the numeric release
    if os_versions[other_id].key?(other_release)
      other_release = os_versions[other_id][other_release]
      other_was_codename = true
    elsif /^[\d.]+$/ !~ other_release
      fail(ArgumentError,
           "os_version(): unknown #{other_id} release '#{other_release}'")
    end

    # emit a warning if the release given to compare with is not supported
    min_version = min_supported_versions[other_id]
    # rubocop:disable Style/NumericPredicate
    if Puppet::Util::Package.versioncmp(other_release, min_version) < 0 ||
      (Puppet::Util::Package.versioncmp(other_release, min_version) == 0 &&
          (operator == '<=' || operator == '<'))
      message = "os_version(): obsolete distribution check in #{clause}"
    # rubocop:enable Style/NumericPredicate
      warning(message)
    end

    # skip this clause unless it's matching our operating system
    next unless self_id == other_id

    # special-case Debian point-releases, as e.g. buster is all of 10.x
    if other_id == 'Debian' && other_was_codename
      self_release = self_release.split('.')[0]
    end

    cmp = Puppet::Util::Package.versioncmp(self_release, other_release)
    # rubocop:disable Style/NumericPredicate
    case operator
    when '', '==' then cmp == 0
    when '!=' then cmp != 0
    when '>'  then cmp == 1
    when '<'  then cmp == -1
    when '>=' then cmp >= 0
    when '<=' then cmp <= 0
    else fail(ArgumentError,
              "os_version(): unknown comparison operator '#{operator}'")
    end
    # rubocop:enable Style/NumericPredicate
  end
end