Puppet Function: os_version

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

Overview

os_version()Any

Returns:

  • (Any)


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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'puppet/modules/wmflib/lib/puppet/parser/functions/os_version.rb', line 62

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

      if defined? Puppet::Pops::PuppetStack.stacktrace
        stacktrace = Puppet::Pops::PuppetStack.stacktrace()[0]
        file = stacktrace[0]
        line = stacktrace[1]
        message = "#{message} at #{file}:#{line}"
      end

      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. jessie is all of 8.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