puppet_metadata 5.3.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -109,6 +109,79 @@ module PuppetMetadata
109
109
  unsupported.compact.to_h
110
110
  end
111
111
 
112
+ # @param [Date] at The date to check the EOL time. Today is used when nil.
113
+ # @param [String] desired_os the name of the operating system from metadata.json we want to update
114
+ # @return [Hash[String, Array[String]]]
115
+ # All added releases for each operating system
116
+ def add_supported_operatingsystems(at = nil, desired_os = nil)
117
+ added = {}
118
+
119
+ metadata['operatingsystem_support'] = operatingsystems.map do |os, releases|
120
+ result = {
121
+ 'operatingsystem' => os,
122
+ }
123
+
124
+ # desired_os is a filter
125
+ # if set, we only care about this OS, otherwise we want all OSes from metadata.json
126
+ if desired_os && desired_os != os
127
+ # Preserve the original entry unchanged
128
+ result['operatingsystemrelease'] = releases unless releases.nil?
129
+ next result
130
+ end
131
+
132
+ unless releases.nil?
133
+ supported = OperatingSystem.supported_releases(os, at)
134
+ releases_added = supported - releases
135
+ added[os] = releases_added if releases_added.any?
136
+ result['operatingsystemrelease'] = releases | supported
137
+ end
138
+ result
139
+ end
140
+
141
+ # Clear the memoized operatingsystems so it gets recalculated
142
+ @operatingsystems = nil
143
+
144
+ added
145
+ end
146
+
147
+ # @param [Date, nil] at The date to check the EOL time. Today is used when nil.
148
+ # @param [String, nil] desired_os the name of the operating system from metadata.json we want to update. All OSes are processed when nil.
149
+ # @return [Hash[String, Array[String]]]
150
+ # All removed EOL releases for each operating system
151
+ def remove_eol_operatingsystems(at = nil, desired_os = nil)
152
+ removed = {}
153
+
154
+ metadata['operatingsystem_support'] = operatingsystems.map do |os, releases|
155
+ result = {
156
+ 'operatingsystem' => os,
157
+ }
158
+
159
+ # desired_os is a filter
160
+ # if set, we only care about this OS, otherwise we want all OSes from metadata.json
161
+ if desired_os && desired_os != os
162
+ # Preserve the original entry unchanged
163
+ result['operatingsystemrelease'] = releases unless releases.nil?
164
+ next result
165
+ end
166
+
167
+ unless releases.nil?
168
+ eol = releases.select { |rel| OperatingSystem.eol?(os, rel, at) }
169
+ if eol.any?
170
+ removed[os] = eol
171
+ result['operatingsystemrelease'] = releases - eol
172
+ else
173
+ result['operatingsystemrelease'] = releases
174
+ end
175
+ end
176
+ result
177
+ end
178
+
179
+ # Clear the memoized operatingsystems so it gets recalculated
180
+ @operatingsystems = nil
181
+
182
+ removed
183
+ end
184
+
112
185
  # A hash representation of the requirements
113
186
  #
114
187
  # Every element in the original array is converted. The name is used as a
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'date'
4
+ require 'json'
4
5
 
5
6
  module PuppetMetadata
6
7
  # An abstraction layer over operating systems. Mostly to determine End Of
@@ -10,207 +11,38 @@ module PuppetMetadata
10
11
  class OperatingSystem
11
12
  # please add new OSes sorted alphabetically
12
13
 
13
- # The EOL dates for the various operating systems
14
- # @see .eol_date
15
- EOL_DATES = {
16
- # https://wiki.almalinux.org/release-notes/
17
- 'AlmaLinux' => {
18
- '9' => '2032-05-31',
19
- '8' => '2029-05-31',
20
- },
21
- 'Amazon' => {
22
- # Amazon Linux AMI
23
- # https://aws.amazon.com/amazon-linux-ami/
24
- '2018.03' => '2023-12-31',
25
- '2017.09' => '2023-12-31',
26
- '2017.03' => '2023-12-31',
27
- '2016.09' => '2023-12-31',
28
- '2016.03' => '2023-12-31',
29
- '2015.09' => '2023-12-31',
30
- '2015.03' => '2023-12-31',
31
- '2014.09' => '2023-12-31',
32
- '2014.03' => '2023-12-31',
33
- '2013.09' => '2023-12-31',
34
- '2013.03' => '2023-12-31',
35
- '2012.09' => '2023-12-31',
36
- '2012.03' => '2023-12-31',
37
- '2011.09' => '2023-12-31',
38
- '2010.11' => '2023-12-31',
39
- # Amazon Linux 2
40
- # https://aws.amazon.com/amazon-linux-2/faqs/
41
- '2.0' => '2026-06-30',
42
- # Amazon Linux 2023
43
- # https://docs.aws.amazon.com/linux/al2023/ug/release-cadence.html
44
- '2023' => '2027-06-30',
45
- },
46
- # https://endoflife.software/operating-systems/linux/centos
47
- # https://endoflife.date/centos-stream
48
- 'CentOS' => {
49
- '10' => '2030-01-01',
50
- '9' => '2027-05-31',
51
- '8' => '2024-05-31',
52
- '7' => '2024-06-30',
53
- '6' => '2020-11-30',
54
- '5' => '2017-03-31',
55
- '4' => '2012-02-29',
56
- '3' => '2010-10-30',
57
- },
58
- # https://wiki.debian.org/DebianReleases
59
- 'Debian' => {
60
- # EOL is extended life cycle, not standard support
61
- # https://github.com/voxpupuli/voxpupuli.github.io/pull/386
62
- '13' => '2030-08-09',
63
- '12' => '2028-06-30',
64
- '11' => '2026-08-31',
65
- '10' => '2022-09-10',
66
- '9' => '2020-07-06',
67
- '8' => '2018-06-17',
68
- '7' => '2016-04-26',
69
- '6' => '2015-05-31',
70
- '5' => '2012-02-06',
71
- '4' => '2010-02-15',
72
- '3.1' => '2008-03-31',
73
- '3.0' => '2006-06-30',
74
- '2.2' => '2003-06-30',
75
- '2.1' => '2000-09-30',
76
- },
77
- # https://endoflife.date/oraclelinux
78
- 'OracleLinux' => {
79
- '10' => '2032-06-30', # I didn't find an EoL date yet, so I used the one from OL9
80
- '9' => '2032-06-30',
81
- '8' => '2029-07-01',
82
- '7' => '2024-12-31',
83
- },
84
- # https://docs.fedoraproject.org/en-US/releases/eol/
85
- 'Fedora' => {
86
- '41' => nil,
87
- '40' => '2025-05-13',
88
- '39' => '2024-11-26',
89
- '38' => '2024-05-21',
90
- '37' => '2023-12-05',
91
- '36' => '2023-05-16',
92
- '35' => '2022-12-13',
93
- '34' => '2022-06-07',
94
- '33' => '2021-11-30',
95
- '32' => '2021-05-25',
96
- '31' => '2020-11-24',
97
- '30' => '2020-05-26',
98
- '29' => '2019-11-26',
99
- '28' => '2019-05-28',
100
- '27' => '2018-11-30',
101
- '26' => '2018-05-29',
102
- '25' => '2017-12-12',
103
- '24' => '2017-08-08',
104
- '23' => '2016-12-20',
105
- '22' => '2016-07-19',
106
- '21' => '2015-12-01',
107
- '20' => '2015-06-23',
108
- '19' => '2015-01-06',
109
- '18' => '2014-01-14',
110
- '17' => '2013-07-30',
111
- '16' => '2013-02-12',
112
- '15' => '2012-06-26',
113
- '14' => '2011-12-08',
114
- '13' => '2011-06-24',
115
- '12' => '2010-12-02',
116
- '11' => '2010-06-25',
117
- '10' => '2009-12-18',
118
- '9' => '2009-07-10',
119
- '8' => '2009-01-07',
120
- '7' => '2008-06-13',
121
- '6' => '2007-12-07',
122
- '5' => '2007-07-02',
123
- '4' => '2006-08-07',
124
- '3' => '2006-01-16',
125
- '2' => '2005-04-11',
126
- '1' => '2004-09-20',
127
- },
128
- # https://endoflife.software/operating-systems/unix-like-bsd/freebsd
129
- 'FreeBSD' => {
130
- '13' => '2026-01-31',
131
- '12' => '2024-06-30',
132
- '11' => '2021-09-30',
133
- '10' => '2018-10-31',
134
- '9' => '2016-12-31',
135
- '8' => '2015-08-01',
136
- '7' => '2013-02-28',
137
- '6' => '2010-11-30',
138
- '5' => '2008-05-31',
139
- '4' => '2007-01-31',
140
- },
141
- # https://endoflife.software/operating-systems/linux/red-hat-enterprise-linux-rhel
142
- 'RedHat' => {
143
- # TODO: EOL is standard support, not the extended life cycle
144
- '8' => '2029-05-31',
145
- '7' => '2024-06-30',
146
- '6' => '2020-11-30',
147
- '5' => '2017-03-31',
148
- '4' => '2012-02-29',
149
- '3' => '2010-10-31',
150
- },
151
- # https://wiki.rockylinux.org/rocky/version/
152
- 'Rocky' => {
153
- '9' => '2032-05-31',
154
- '8' => '2029-05-31',
155
- },
156
- # https://scientificlinux.org/category/uncategorized/scientific-linux-end-of-life/
157
- 'Scientific' => {
158
- '8' => '2024-06-30', # This is not really a Scientific release, but I have seen it in module metadata ..
159
- '7' => '2024-06-30',
160
- '6' => '2020-11-30',
161
- '5' => '2017-03-31',
162
- '4' => '2012-02-29',
163
- '3' => '2010-10-30',
164
- },
165
- # https://www.suse.com/lifecycle/#product-suse-linux-enterprise-server
166
- # General support end dates, not LTSS
167
- 'SLES' => {
168
- '15' => '2031-07-31',
169
- '12' => '2024-10-31',
170
- '11' => '2019-03-31',
171
- '10' => '2013-07-31',
172
- },
173
- # https://endoflife.software/operating-systems/linux/ubuntu
174
- 'Ubuntu' => {
175
- '24.04' => '2029-04-30',
176
- '22.04' => '2027-04-15',
177
- '21.10' => '2022-07-15',
178
- '20.10' => '2021-07-15',
179
- '20.04' => '2025-04-15',
180
- '19.10' => '2020-07-15',
181
- '19.04' => '2020-01-15',
182
- '18.10' => '2019-07-15',
183
- '18.04' => '2023-05-31',
184
- '17.10' => '2018-07-15',
185
- '17.04' => '2018-01-15',
186
- '16.10' => '2017-07-20',
187
- '16.04' => '2021-04-15',
188
- '15.10' => '2016-07-28',
189
- '15.04' => '2016-02-04',
190
- '14.10' => '2015-07-23',
191
- '14.04' => '2019-04-15',
192
- '13.10' => '2014-07-17',
193
- '13.04' => '2014-01-27',
194
- '12.04' => '2017-04-28',
195
- '11.10' => '2013-05-09',
196
- '11.04' => '2012-10-28',
197
- '10.10' => '2012-04-10',
198
- '10.04' => '2015-04-30',
199
- '9.10' => '2011-04-30',
200
- '9.04' => '2010-10-23',
201
- '8.10' => '2010-04-30',
202
- '8.04' => '2013-05-09',
203
- '7.10' => '2009-04-18',
204
- '7.04' => '2008-10-19',
205
- '6.10' => '2008-04-26',
206
- '6.06' => '2011-06-01',
207
- '5.10' => '2007-04-13',
208
- '5.04' => '2006-10-31',
209
- '4.10' => '2006-04-30',
210
- },
211
- }.freeze
14
+ # The EOL dates are maintained in data/eol_dates.json and can be updated
15
+ # automatically using the bin/update_eol_dates script.
16
+ #
17
+ # Lazy load the JSON data to minimize disk I/O and JSON parsing.
18
+ EOL_DATES_FILE = File.expand_path('../../data/eol_dates.json', __dir__).freeze
19
+
20
+ def self.const_missing(name)
21
+ return super unless name == :EOL_DATES
22
+
23
+ dates = JSON.parse(File.read(EOL_DATES_FILE)).freeze
24
+ const_set(:EOL_DATES, dates)
25
+ end
26
+
27
+ def self.reset_eol_dates_cache!
28
+ remove_const(:EOL_DATES) if const_defined?(:EOL_DATES, false)
29
+ nil
30
+ end
212
31
 
213
32
  class << self
33
+ def ubuntu_lts_version?(release)
34
+ # Ubuntu LTS releases are even-year April releases (e.g. 22.04, 24.04).
35
+ match = release.match(/^([0-9]+)\.04$/)
36
+ return false unless match
37
+
38
+ year = match[1].to_i
39
+ year.even?
40
+ end
41
+
42
+ def sles_major_version?(release)
43
+ release.match?(/^\d+$/)
44
+ end
45
+
214
46
  # Return the EOL date for the given operating system release
215
47
  # @param [String] operatingsystem
216
48
  # The operating system
@@ -220,7 +52,7 @@ module PuppetMetadata
220
52
  # The EOL date for the given operating system release. Nil is returned
221
53
  # when the either when the OS, the release or the EOL date is unknown
222
54
  def eol_date(operatingsystem, release)
223
- releases = EOL_DATES[operatingsystem]
55
+ releases = OperatingSystem::EOL_DATES[operatingsystem]
224
56
  return unless releases
225
57
 
226
58
  date = releases[release]
@@ -250,17 +82,31 @@ module PuppetMetadata
250
82
  # The latest major release for the given operating system, if any is
251
83
  # known
252
84
  def latest_release(operatingsystem)
253
- releases = EOL_DATES[operatingsystem]
254
- releases&.keys&.max_by { |release| Gem::Version.new(release) }
85
+ releases = OperatingSystem::EOL_DATES[operatingsystem]
86
+ return unless releases
87
+
88
+ keys = releases.keys
89
+ keys = keys.select { |release| ubuntu_lts_version?(release) } if operatingsystem == 'Ubuntu'
90
+ keys = keys.select { |release| sles_major_version?(release) } if operatingsystem == 'SLES'
91
+ keys.max_by { |release| Gem::Version.new(release) }
255
92
  end
256
93
 
257
94
  # Return an array of all Operating System versions that aren't EoL
258
95
  # @param [String] operatingsystem The operating system
259
- # @return [Array] All Operating System versions that aren't EoL today
260
- def supported_releases(operatingsystem)
261
- releases = EOL_DATES[operatingsystem]
262
- today = Date.today
263
- releases.select { |_release, eol_date| !eol_date || Date.parse(eol_date) > today }.keys
96
+ # @param [Date] at The date to check the EOL time. Today is used when nil.
97
+ # @return [Array] All Operating System versions that aren't EoL
98
+ def supported_releases(operatingsystem, at = nil)
99
+ releases = OperatingSystem::EOL_DATES[operatingsystem]
100
+
101
+ # return an empty array if one OS has zero dates
102
+ # Happens for esoteric distros like windows, where we currently don't have any data in EOL_DATES
103
+ return [] unless releases
104
+
105
+ releases = releases.select { |release, _eol_date| ubuntu_lts_version?(release) } if operatingsystem == 'Ubuntu'
106
+ releases = releases.select { |release, _eol_date| sles_major_version?(release) } if operatingsystem == 'SLES'
107
+
108
+ at ||= Date.today
109
+ releases.select { |_release, eol_date| !eol_date || Date.parse(eol_date) > at }.keys
264
110
  .sort_by { |release| Gem::Version.new(release) }
265
111
  end
266
112
 
@@ -3,7 +3,9 @@
3
3
  # A module that provides abstractions around Puppet's metadata format.
4
4
  module PuppetMetadata
5
5
  autoload :AIO, 'puppet_metadata/aio'
6
+ autoload :BaseCommand, 'puppet_metadata/base_command'
6
7
  autoload :Beaker, 'puppet_metadata/beaker'
8
+ autoload :Command, 'puppet_metadata/command'
7
9
  autoload :GithubActions, 'puppet_metadata/github_actions'
8
10
  autoload :Metadata, 'puppet_metadata/metadata'
9
11
  autoload :OperatingSystem, 'puppet_metadata/operatingsystem'
@@ -21,4 +23,11 @@ module PuppetMetadata
21
23
  def self.read(path)
22
24
  parse(File.read(path))
23
25
  end
26
+
27
+ # Write metadata back to disk
28
+ # @param path The path metadata.json
29
+ # @param [PuppetMetadata::Metadata] A Metadata object
30
+ def self.write(path, metadata)
31
+ File.write(path, "#{JSON.pretty_generate(metadata.metadata)}\n")
32
+ end
24
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet_metadata
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vox Pupuli
@@ -62,16 +62,22 @@ dependencies:
62
62
  name: rdoc
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - "~>"
65
+ - - ">="
66
66
  - !ruby/object:Gem::Version
67
67
  version: '6.0'
68
+ - - "<"
69
+ - !ruby/object:Gem::Version
70
+ version: '8'
68
71
  type: :development
69
72
  prerelease: false
70
73
  version_requirements: !ruby/object:Gem::Requirement
71
74
  requirements:
72
- - - "~>"
75
+ - - ">="
73
76
  - !ruby/object:Gem::Version
74
77
  version: '6.0'
78
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: '8'
75
81
  - !ruby/object:Gem::Dependency
76
82
  name: rspec
77
83
  requirement: !ruby/object:Gem::Requirement
@@ -112,14 +118,14 @@ dependencies:
112
118
  requirements:
113
119
  - - "~>"
114
120
  - !ruby/object:Gem::Version
115
- version: 3.1.0
121
+ version: 5.1.0
116
122
  type: :development
117
123
  prerelease: false
118
124
  version_requirements: !ruby/object:Gem::Requirement
119
125
  requirements:
120
126
  - - "~>"
121
127
  - !ruby/object:Gem::Version
122
- version: 3.1.0
128
+ version: 5.1.0
123
129
  - !ruby/object:Gem::Dependency
124
130
  name: yard
125
131
  requirement: !ruby/object:Gem::Requirement
@@ -139,17 +145,26 @@ email:
139
145
  - voxpupuli@groups.io
140
146
  executables:
141
147
  - metadata2gha
148
+ - puppet-metadata
142
149
  - setfiles
150
+ - update_eol_dates
143
151
  extensions: []
144
152
  extra_rdoc_files:
145
153
  - README.md
146
154
  files:
147
155
  - README.md
148
156
  - bin/metadata2gha
157
+ - bin/puppet-metadata
149
158
  - bin/setfiles
159
+ - bin/update_eol_dates
160
+ - data/eol_dates.json
150
161
  - lib/puppet_metadata.rb
151
162
  - lib/puppet_metadata/aio.rb
163
+ - lib/puppet_metadata/base_command.rb
152
164
  - lib/puppet_metadata/beaker.rb
165
+ - lib/puppet_metadata/command.rb
166
+ - lib/puppet_metadata/command/os_versions.rb
167
+ - lib/puppet_metadata/command/setfiles.rb
153
168
  - lib/puppet_metadata/github_actions.rb
154
169
  - lib/puppet_metadata/metadata.rb
155
170
  - lib/puppet_metadata/operatingsystem.rb
@@ -166,17 +181,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
181
  requirements:
167
182
  - - ">="
168
183
  - !ruby/object:Gem::Version
169
- version: '2.7'
184
+ version: '3.2'
170
185
  - - "<"
171
186
  - !ruby/object:Gem::Version
172
- version: '4'
187
+ version: '5'
173
188
  required_rubygems_version: !ruby/object:Gem::Requirement
174
189
  requirements:
175
190
  - - ">="
176
191
  - !ruby/object:Gem::Version
177
192
  version: '0'
178
193
  requirements: []
179
- rubygems_version: 3.6.9
194
+ rubygems_version: 4.0.3
180
195
  specification_version: 4
181
196
  summary: Data structures for the Puppet Metadata
182
197
  test_files: []