xolo-server 2.2.0 → 2.2.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84bf8381f9806f22096c6404f36e62cb49d418384cf8a9cd722bbb4afbfc60d1
4
- data.tar.gz: 22e325e7e124104589c946006531cad9e5ab3b8db047b8403e66d5bb83166d0f
3
+ metadata.gz: 52595d7268e2f989402fd60e3c8c992b993a1342d4a5f4436953a025493d2409
4
+ data.tar.gz: 39ecea967112210302c3242d7c0f9f53da34ffa8a803c71cf4edced97b26113a
5
5
  SHA512:
6
- metadata.gz: 8dde7e538db3e32619b7828057e7671c8eef1460a60df222f63754624d98093b66b6badf78b8834ef4517343b0464e965471cd1bbb841ec66886b20d5ca98d0a
7
- data.tar.gz: 738fdb9b8c7cd66cb82c1efe39cbc00aafa011a0adc6b4936f6a2fcaadf1733f64fa88a2648a8a7d8639d4866203328be8ce8baee86103d9982e83b4cf144841
6
+ metadata.gz: be740aa47014789519e5d167bda8fa19d517331945c6e5520403e59643620cf660a09f142031e65e385a254b427362b9e78c459dfde20b1ecf3c0835e6fc030b
7
+ data.tar.gz: 7c4792d23e49b5d486c3f24aab9b51d35f510d303597d5d1ce84b7eb5dfb4723a5bf07b357d1429b6c99c0d85737df75c04b3cd6f70967277088faa40db76145
@@ -12,7 +12,7 @@ module Xolo
12
12
 
13
13
  module Version
14
14
 
15
- VERSION = '2.2.0'.freeze
15
+ VERSION = '2.2.2'.freeze
16
16
 
17
17
  end
18
18
 
@@ -13,9 +13,10 @@ module Xolo
13
13
  module Helpers
14
14
 
15
15
  # Nightly maintenance tasks
16
- # - accept TEd EAs
16
+ # - accept lingering TEd EAs, if configured to
17
17
  # - autorelease versions
18
18
  # - clean up old versions
19
+ # - notify title maintainers of old unreleased pilots
19
20
  #
20
21
  # Also, alerts will be posted, and Emails will be sent to the
21
22
  # admins who added versions that have been in pilot for more than
@@ -32,8 +33,24 @@ module Xolo
32
33
  # Constants
33
34
  #####################################
34
35
 
36
+ # TODO: ? use the next 3 values as defaults, and
37
+ # set them in the server config
38
+
39
+ # how often does our maint timer check to see if it should run maintenance?
40
+ # Slightly less than an hour means there will always be at least one check every
41
+ # hour, sometimes two.
42
+ MAINT_CHECK_INTERVAL = 3500
43
+ # MAINT_CHECK_INTERVAL = 600
44
+
35
45
  # At what hour should the nightly maintenance run?
36
46
  MAINT_HOUR = 2
47
+ # MAINT_HOUR = 10
48
+
49
+ # Maint won't run unless the last run was at least this many
50
+ # seconds ago.
51
+ # 23 hrs ago means that even if we check twice within the
52
+ # MAINT_HOUR, only the first one will run.
53
+ MAINT_MAX_FREQ_SECS = 23 * 3600
37
54
 
38
55
  # the route we POST to, to start the nightly process.
39
56
  TIMED_MAINT_TRIGGER_ROUTE = '/maint/maint-internal'
@@ -84,9 +101,10 @@ module Xolo
84
101
  return @maint_timer_task if @maint_timer_task
85
102
 
86
103
  @maint_timer_task =
87
- Concurrent::TimerTask.new(execution_interval: 3600) { post_to_start_maint }
104
+ Concurrent::TimerTask.new(execution_interval: MAINT_CHECK_INTERVAL) { post_to_start_maint }
105
+
106
+ Xolo::Server.logger.info "Created Concurrent::TimerTask for nightly maintenance. Will check every #{MAINT_CHECK_INTERVAL} secs, and run during the hour of: #{MAINT_HOUR}"
88
107
 
89
- Xolo::Server.logger.info 'Created Concurrent::TimerTask for nightly maintenance.'
90
108
  @maint_timer_task
91
109
  end
92
110
 
@@ -118,10 +136,18 @@ module Xolo
118
136
  return
119
137
  end
120
138
 
121
- # only run the maintenance if it's between 2am and 3am
122
- # and the last one was more than 23 hrs ago
123
- last_maint_hrs_ago = (Time.now - last_maint) / 3600
124
- return unless force || (Time.now.hour == MAINT_HOUR && last_maint_hrs_ago > 23)
139
+ # only run the maintenance if it's during the MAINT_HOUR
140
+ # and the last one was more than MAINT_MAX_FREQ_SECS ago
141
+ if force
142
+ Xolo::Server.logger.info 'Maint: Starting now due to force'
143
+
144
+ elsif Time.now.hour == MAINT_HOUR && (Time.now - last_maint) > MAINT_MAX_FREQ_SECS
145
+ Xolo::Server.logger.info 'Maint: Starting nightly run now'
146
+
147
+ else
148
+ Xolo::Server.logger.info "Maint: Not starting, it isn't time"
149
+ return
150
+ end
125
151
 
126
152
  uri = URI.parse "https://#{Xolo::Server::Helpers::Auth::IPV4_LOOPBACK}#{TIMED_MAINT_TRIGGER_ROUTE}"
127
153
  https = Net::HTTP.new(uri.host, uri.port)
@@ -155,11 +181,16 @@ module Xolo
155
181
  mutex.lock
156
182
  log_info 'Maint: starting'
157
183
 
184
+ # instantiate all the titles once now, rather than in all the task methods
185
+ title_objects_for_maint = Xolo::Server::Title.all_titles.map { |t| instantiate_title t }
186
+
158
187
  # add new maintenance tasks/methods here
159
- accept_title_editor_eas
160
- auto_release_versions
161
- cleanup_versions
188
+ accept_title_editor_eas title_objects_for_maint
189
+ auto_release_versions title_objects_for_maint
190
+ cleanup_versions title_objects_for_maint
191
+ notify_admins_of_unreleased_pilots title_objects_for_maint
162
192
 
193
+ Xolo::Server::Helpers::Maintenance.last_maint = Time.now
163
194
  log_info 'Maint: complete'
164
195
  ensure
165
196
  mutex&.unlock
@@ -169,17 +200,16 @@ module Xolo
169
200
  # and auto accept them if we need to
170
201
  # @return [void]
171
202
  ######################################
172
- def accept_title_editor_eas
203
+ def accept_title_editor_eas(title_objects)
173
204
  unless Xolo::Server.config.jamf_auto_accept_xolo_eas
174
- log_info 'Maint: The xolo server is not configured to auto-accept Title Editor EAs'
205
+ log_debug 'Maint: The xolo server is not configured to auto-accept Title Editor EAs'
175
206
  return
176
207
  end
177
208
 
178
209
  log_info 'Maint: Looking for Title Editor EAs to auto-accept'
179
210
 
180
- # TODO: Be DRY with this stuff and similar in title_jamf_access.rb
181
- Xolo::Server::Title.all_titles.each do |title|
182
- title_obj = instantiate_title title
211
+ title_objects.each do |title_obj|
212
+ title = title_obj.title
183
213
  next if title_obj.subscribed?
184
214
  next unless title_obj.jamf_patch_ea_awaiting_acceptance?
185
215
 
@@ -195,14 +225,17 @@ module Xolo
195
225
  # Do any pending auto-releases
196
226
  # @return [void]
197
227
  ##############################
198
- def auto_release_versions
228
+ def auto_release_versions(title_objects)
199
229
  log_info 'Maint: Auto-releasing appropriate versions'
200
230
 
201
231
  today = Date.today
202
232
 
203
233
  # Loop thru the titles
204
- Xolo::Server::Title.all_titles.each do |title|
205
- title_obj = instantiate_title title
234
+ title_objects.each do |title_obj|
235
+ title = title_obj.title
236
+
237
+ # nothing to do if its nil or 'none'
238
+ next if title_obj.auto_release_delay.nil? || title_obj.auto_release_delay == Xolo::NONE
206
239
 
207
240
  # title must be subscribed and autopkg
208
241
  # (enforced in xadm)
@@ -214,19 +247,22 @@ module Xolo
214
247
  # NOTE: it is stored as a string because it might be 'none'
215
248
  # TODO: store none as nil, so we don't have to do the pix_integer check??
216
249
  delay = title_obj.auto_release_delay.to_i
217
- next unless title_obj.auto_release_delay.pix_integer? && !delay.negative?
250
+ next unless title_obj.auto_release_delay&.pix_integer? && !delay.negative?
218
251
 
219
252
  # Any version with this creation date should be released now, skip if not
220
253
  # So if the auto_release_delay is 7, its today - 7 days.
221
254
  # if the auto_release_delay is 0, its today - 0 days, aka today
222
255
  creation_date_to_be_released_today = today - delay
223
256
 
224
- # Find the newest pilot version whose creation date is creation_date_to_be_released_today
257
+ # Find the newest pilot version whose creation date is
258
+ # creation_date_to_be_released_today or earlier
225
259
  # That one should be released now.
226
260
  vobj_to_release = nil
261
+
262
+ # version objects are in order of newest to oldest
227
263
  title_obj.version_objects.each do |vobj|
228
264
  next unless vobj.pilot?
229
- next unless vobj.creation_date.to_date == creation_date_to_be_released_today
265
+ next unless vobj.creation_date.to_date <= creation_date_to_be_released_today
230
266
 
231
267
  vobj_to_release = vobj
232
268
  break
@@ -251,12 +287,11 @@ module Xolo
251
287
  # Cleanup versions.
252
288
  # @return [void]
253
289
  ################################
254
- def cleanup_versions
255
- log_info 'Maint: cleaning up deprecated and skipped versions'
256
-
257
- Xolo::Server::Title.all_titles.each do |title|
258
- title_obj = instantiate_title title
290
+ def cleanup_versions(title_objects)
291
+ log_info 'Maint: Cleaning up deprecated and skipped versions'
259
292
 
293
+ # Loop thru the titles
294
+ title_objects.each do |title_obj|
260
295
  title_obj.version_objects.each do |version|
261
296
  if version.deprecated?
262
297
  cleanup_deprecated_version version
@@ -264,12 +299,8 @@ module Xolo
264
299
  cleanup_skipped_version version
265
300
  end # case
266
301
  end # each version
267
-
268
- notify_admins_of_unreleased_pilots(title_obj)
269
302
  end # each title
270
-
271
- Xolo::Server::Helpers::Maintenance.last_maint = Time.now
272
- log_info 'Maint: versions cleanup complete'
303
+ log_info 'Maint: Version cleanup complete'
273
304
  end
274
305
 
275
306
  # Cleanup a deprecated version.
@@ -284,7 +315,7 @@ module Xolo
284
315
  days_deprecated = (Time.now - version.deprecation_date) / 86_400
285
316
  return unless days_deprecated > deprecated_lifetime_days
286
317
 
287
- log_info "Cleanup: Deleting deprecated version '#{version.version}' of title '#{version.title}'"
318
+ log_info "Maint: Deleting deprecated version '#{version.version}' of title '#{version.title}'"
288
319
  version.delete
289
320
  end
290
321
 
@@ -295,38 +326,50 @@ module Xolo
295
326
  def cleanup_skipped_version(version)
296
327
  return if Xolo::Server.config.keep_skipped_versions
297
328
 
298
- log_info "Cleanup: Deleting skipped version '#{version.version}' of title '#{version.title}'"
329
+ log_info "Maint: Deleting skipped version '#{version.version}' of title '#{version.title}'"
299
330
  version.delete
300
331
  end
301
332
 
302
333
  # Notify the admins about unreleased pilots if needed
303
334
  # @return [void]
304
335
  ################################
305
- def notify_admins_of_unreleased_pilots(title_obj)
306
- return unless Time.now.day == UNRELEASED_PILOTS_NOTIFICATION_DAY
307
- return unless unreleased_pilots_notification_days.positive?
308
- return unless title_obj.latest_version
336
+ def notify_admins_of_unreleased_pilots(title_objects)
337
+ unless Time.now.day == UNRELEASED_PILOTS_NOTIFICATION_DAY
338
+ log_debug 'Maint: Not notifying admins of old pilots, wrong day of the month.'
339
+ return
340
+ end
341
+ unless unreleased_pilots_notification_days&.positive?
342
+ log_debug 'Maint: Not notifying admins of old pilots, unreleased_pilots_notification_days is not a positive integer'
343
+ return
344
+ end
309
345
 
310
- latest_vers_obj = instantiate_version title: title_obj, version: title_obj.latest_version
311
- return unless latest_vers_obj.pilot?
346
+ log_info 'Maint: Notifying admins about old unreleased pilots'
312
347
 
313
- days_in_pilot = ((Time.now - latest_vers_obj.creation_date) / 86_400).to_i
348
+ title_objects.each do |title_obj|
349
+ next unless title_obj.latest_version
314
350
 
315
- return unless days_in_pilot > unreleased_pilots_notification_days
351
+ latest_vers_obj = instantiate_version title: title_obj, version: title_obj.latest_version
352
+ next unless latest_vers_obj.pilot?
316
353
 
317
- alert_msg = "Cleanup: Notifying #{title_obj.contact_email} about unreleased pilot '#{latest_vers}' of title '#{title_obj.title}', in pilot for #{days_in_pilot} days"
354
+ days_in_pilot = ((Time.now - latest_vers_obj.creation_date) / 86_400).to_i
318
355
 
319
- log_info alert_msg
320
- send_alert alert_msg
356
+ next unless days_in_pilot > unreleased_pilots_notification_days
321
357
 
322
- email_msg = <<~MSG
358
+ alert_msg = "Maint: Notifying #{title_obj.contact_email} about unreleased pilot '#{latest_vers}' of title '#{title_obj.title}', in pilot for #{days_in_pilot} days"
359
+
360
+ log_info alert_msg
361
+ send_alert alert_msg
362
+
363
+ email_msg = <<~MSG
323
364
  The newest version '#{latest_vers_obj.version}' of title '#{title_obj.title}' has been in pilot for #{days_in_pilot} days, which makes it seem like it's not going to be released.
324
365
 
325
366
  To reduce clutter, please consider releasing it, deleting it, or deleting the whole title if it's no longer needed.
326
367
 
327
368
  If this is intentional, you can ignore this monthly message.
328
- MSG
329
- send_email to: title_obj.contact_email, subject: 'Unreleased Pilot Notification', msg: email_msg
369
+ MSG
370
+ send_email to: title_obj.contact_email, subject: 'Unreleased Pilot Notification', msg: email_msg
371
+ end # each title
372
+ log_info 'Maint: Done notifying admins about old unreleased pilots'
330
373
  end
331
374
 
332
375
  # how many days can a version be deprecated?
@@ -1450,7 +1450,7 @@ module Xolo
1450
1450
  jamf_patch_title.category = Xolo::Server::JAMF_XOLO_CATEGORY
1451
1451
  self.jamf_patch_title_id = jamf_patch_title.save
1452
1452
 
1453
- log_debug "Activated Jamf Patch Title '#{display_name}' (#{title}) with id #{jamf_patch_title_id}"
1453
+ log_debug "Jamf: Activated Jamf Patch Title '#{display_name}' (#{title}) with id #{jamf_patch_title_id}"
1454
1454
 
1455
1455
  jamf_patch_title
1456
1456
  end
@@ -51,6 +51,7 @@ module Xolo
51
51
  start_time: Xolo::Server.start_time,
52
52
  uptime: uptime_secs.pix_humanize_secs,
53
53
  uptime_secs: uptime_secs,
54
+ last_maint: Xolo::Server::Helpers::Maintenance.last_maint,
54
55
  app_env: Xolo::Server.app_env,
55
56
  test_server: Xolo::Server.test_server?,
56
57
  data_dir: Xolo::Server::DATA_DIR,
@@ -435,7 +435,7 @@ module Xolo
435
435
  def jamf_patch_title_id
436
436
  return @jamf_patch_title_id if @jamf_patch_title_id
437
437
 
438
- log_debug "Getting jamf_patch_title_id for title '#{title}'"
438
+ log_debug "Jamf: Getting jamf_patch_title_id for title '#{title}'"
439
439
 
440
440
  self.jamf_patch_title_id =
441
441
  if managed?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xolo-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Lasell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-14 00:00:00.000000000 Z
11
+ date: 2026-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday