xolo-server 2.5.0 → 2.6.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.
- checksums.yaml +4 -4
- data/lib/xolo/core/base_classes/title.rb +19 -0
- data/lib/xolo/core/version.rb +1 -1
- data/lib/xolo/server/constants.rb +8 -3
- data/lib/xolo/server/helpers/maintenance.rb +15 -7
- data/lib/xolo/server/mixins/title_jamf_access.rb +54 -9
- data/lib/xolo/server/mixins/title_ted_access.rb +24 -6
- data/lib/xolo/server/mixins/version_jamf_access.rb +84 -19
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 584212a83456feefa7f2a08d3f1522093515767e5ca1e61a00335d0141c370fe
|
|
4
|
+
data.tar.gz: 0b73315cb10ee4b87d476ebba60ca3021a5d81080175d9b954bef88daaee047a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f3fdc24942ff7f08bbe1205c19823359be852cc240f3ab818ea6b44a59d7c7fdeb3a207527d26a20dd4d9e2eab1fd5fd9547e93350be1c14c7e5f6d6b4eee3e1
|
|
7
|
+
data.tar.gz: f800c804e3fe669a99f4e51e2a36e8a5dd3393479094387f8998bec0c9d4ed320a2f7486569f31225f60823722835dd4854cf5d7be4f2ee6a30376eb6f30af4d
|
|
@@ -726,6 +726,25 @@ module Xolo
|
|
|
726
726
|
ENDDESC
|
|
727
727
|
},
|
|
728
728
|
|
|
729
|
+
# @!attribute deprecated_lifetime
|
|
730
|
+
# @return [Integer] How many days after deprecation before a version is automatically deleted from Xolo?
|
|
731
|
+
#
|
|
732
|
+
deprecated_lifetime: {
|
|
733
|
+
label: 'Deprecated Lifetime',
|
|
734
|
+
cli: :L,
|
|
735
|
+
validate: true,
|
|
736
|
+
type: :string,
|
|
737
|
+
changelog: true,
|
|
738
|
+
invalid_msg: "Invalid value. Must be a positive integer or 'none'",
|
|
739
|
+
desc: <<~ENDDESC
|
|
740
|
+
When a version is deprecated, it will be automatically deleted by the nightly maintenance this many days later. If set to 'none', deprecated versions will be auto-deleted based on the Xolo server settings.
|
|
741
|
+
|
|
742
|
+
Deprecated versions are those that have been released, but a newer version has been released since then.
|
|
743
|
+
|
|
744
|
+
This setting is especially useful for titles that have frequent versions, to avoid cluttering the xolo and Jamf servers with old versions.
|
|
745
|
+
ENDDESC
|
|
746
|
+
},
|
|
747
|
+
|
|
729
748
|
# @!attribute self_service
|
|
730
749
|
# @return [Boolean] Does this title appear in Self Service?
|
|
731
750
|
self_service: {
|
data/lib/xolo/core/version.rb
CHANGED
|
@@ -44,11 +44,16 @@ module Xolo
|
|
|
44
44
|
PROGRESS_COMPLETE = 'PROGRESS_COMPLETE'
|
|
45
45
|
|
|
46
46
|
# The max time (in seconds) to wait for a the Jamf server to
|
|
47
|
-
# see a change in the Title Editor, e.g.
|
|
48
|
-
# a new version appearing or an EA needing acceptance.
|
|
47
|
+
# see a change in the Title Editor, e.g. an EA needing acceptance.
|
|
49
48
|
# Normally the Jamf server will check in with the Title Editor
|
|
50
49
|
# every 5 minutes.
|
|
51
|
-
|
|
50
|
+
#
|
|
51
|
+
# TEMPORARY: Checks for new versions/patches and Patch EAs happen
|
|
52
|
+
# over 9+ hours.
|
|
53
|
+
# See the method activate_managed_patch_version_in_jamf in
|
|
54
|
+
# version_jamf_access.rb
|
|
55
|
+
# and method auto_accept_patch_ea_in_thread in title_jamf_access.rb.
|
|
56
|
+
MAX_JAMF_WAIT_FOR_TITLE_EDITOR = 3600 * 9
|
|
52
57
|
|
|
53
58
|
# The max time (in seconds) to wait for a the Jamf server to
|
|
54
59
|
# stop the pkg deletion thread pool. It will wait until the
|
|
@@ -457,7 +457,7 @@ module Xolo
|
|
|
457
457
|
title_objects.each do |title_obj|
|
|
458
458
|
title_obj.version_objects.each do |version|
|
|
459
459
|
if version.deprecated?
|
|
460
|
-
cleanup_deprecated_version version
|
|
460
|
+
cleanup_deprecated_version title_obj, version
|
|
461
461
|
elsif version.skipped?
|
|
462
462
|
cleanup_skipped_version version
|
|
463
463
|
end # case
|
|
@@ -470,13 +470,21 @@ module Xolo
|
|
|
470
470
|
# @param version [Xolo::Server::Version] the version to cleanup
|
|
471
471
|
# @return [void]
|
|
472
472
|
################################
|
|
473
|
-
def cleanup_deprecated_version(version)
|
|
474
|
-
#
|
|
475
|
-
|
|
473
|
+
def cleanup_deprecated_version(title_obj, version)
|
|
474
|
+
# does this version's title have a custom deprecated lifetime?
|
|
475
|
+
# title_obj.deprecated_lifetime should be a positive integer or nil
|
|
476
|
+
# if nil, use the server's setting
|
|
477
|
+
deprecated_lifetime_to_use = title_obj.deprecated_lifetime || server_deprecated_lifetime_days
|
|
478
|
+
|
|
479
|
+
# do nothing if the deprecated_lifetime_to_use is 0 or less
|
|
480
|
+
# which will only come from the server.
|
|
481
|
+
return unless deprecated_lifetime_to_use.positive?
|
|
482
|
+
|
|
483
|
+
# deprecation_lifetime_to_use is now a positive integer
|
|
476
484
|
|
|
477
485
|
# how many days has this version been deprecated?
|
|
478
486
|
days_deprecated = (Time.now - version.deprecation_date) / 86_400
|
|
479
|
-
return unless days_deprecated >
|
|
487
|
+
return unless days_deprecated > deprecated_lifetime_to_use
|
|
480
488
|
|
|
481
489
|
log_info "Maint: Deleting deprecated version '#{version.version}' of title '#{version.title}'"
|
|
482
490
|
version.delete
|
|
@@ -538,8 +546,8 @@ module Xolo
|
|
|
538
546
|
# how many days can a version be deprecated?
|
|
539
547
|
# @return [Integer] the number of days a version can be deprecated
|
|
540
548
|
################################
|
|
541
|
-
def
|
|
542
|
-
@
|
|
549
|
+
def server_deprecated_lifetime_days
|
|
550
|
+
@server_deprecated_lifetime_days ||= Xolo::Server.config.deprecated_lifetime_days || DFT_DEPRECATED_LIFETIME_DAYS
|
|
543
551
|
end
|
|
544
552
|
|
|
545
553
|
# Notify the admins about unreleased pilots when the newest one is older than
|
|
@@ -418,8 +418,21 @@ module Xolo
|
|
|
418
418
|
auto_accept_patch_ea_in_thread
|
|
419
419
|
end
|
|
420
420
|
|
|
421
|
-
# Wait for up to
|
|
422
|
-
# accepted, and then do it
|
|
421
|
+
# Wait for up to 9 hours for Jamf to notice that our TEd EA needs to be
|
|
422
|
+
# accepted, and then do it.
|
|
423
|
+
#
|
|
424
|
+
# Normally we'd wait only 1 hour (Xolo::Server::MAX_JAMF_WAIT_FOR_TITLE_EDITOR)
|
|
425
|
+
# But Jamf Cloud instances have a bug where sometimes they'll stop being
|
|
426
|
+
# able to talk to Patch Sources for many hours.
|
|
427
|
+
#
|
|
428
|
+
# We start by checking every 30 seconds
|
|
429
|
+
# After 10 min we check every 2 minutes
|
|
430
|
+
# After an hour, we check every 5 minutes
|
|
431
|
+
# After 3 hours we check every 15 minutes
|
|
432
|
+
#
|
|
433
|
+
# The activate_managed_patch_version_in_jamf method (in version_jamf_access.rb)
|
|
434
|
+
# has also been modified to wait up to 9+hrs.
|
|
435
|
+
#
|
|
423
436
|
#####################
|
|
424
437
|
def auto_accept_patch_ea_in_thread
|
|
425
438
|
# don't do this if there's already one running for this instance
|
|
@@ -438,20 +451,52 @@ module Xolo
|
|
|
438
451
|
start_time = start_time.strftime '%F %T'
|
|
439
452
|
did_it = false
|
|
440
453
|
|
|
441
|
-
|
|
442
|
-
|
|
454
|
+
# start at 30 secs
|
|
455
|
+
sleep_time = 30
|
|
456
|
+
loop_start = Time.now
|
|
457
|
+
|
|
458
|
+
while loop_start < max_time
|
|
459
|
+
sleep sleep_time
|
|
443
460
|
|
|
444
461
|
# refresh our jamf connection cuz it might expire if this takes a while, esp if using
|
|
445
462
|
# an APIClient
|
|
446
463
|
jamf_cnx(refresh: true) if jamf_cnx.token.secs_remaining < 90
|
|
447
464
|
|
|
448
465
|
log_debug "Jamf: checking for expected (re)acceptance of version-script ExtensionAttribute '#{ted_ea_key}' since #{start_time}"
|
|
449
|
-
next unless jamf_patch_ea_awaiting_acceptance?
|
|
450
466
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
467
|
+
if jamf_patch_ea_awaiting_acceptance?
|
|
468
|
+
accept_jamf_patch_ea_via_api
|
|
469
|
+
log_info "Jamf: Auto-accepted use of version-script ExtensionAttribute '#{ted_ea_key}'"
|
|
470
|
+
did_it = true
|
|
471
|
+
break
|
|
472
|
+
|
|
473
|
+
end # if jamf_patch_ea_awaiting_acceptance?
|
|
474
|
+
|
|
475
|
+
# prep for the next loop
|
|
476
|
+
loop_start = Time.now
|
|
477
|
+
waiting_time = loop_start - start_time
|
|
478
|
+
|
|
479
|
+
sleep_time =
|
|
480
|
+
# if we've been waiting 10 min or less,
|
|
481
|
+
# sleep 30 secs between checks
|
|
482
|
+
if waiting_time <= 600
|
|
483
|
+
30
|
|
484
|
+
|
|
485
|
+
# if we've been waiting an hour or less
|
|
486
|
+
# sleep 2 min between checks
|
|
487
|
+
elsif waiting_time <= 3600
|
|
488
|
+
120
|
|
489
|
+
|
|
490
|
+
# if we've been waiting 3 hours or less
|
|
491
|
+
# sleep 5 min between checks
|
|
492
|
+
elsif waiting_time <= 10_800
|
|
493
|
+
300
|
|
494
|
+
|
|
495
|
+
# if longer than 3 hours, sleep 15 min between checks
|
|
496
|
+
else
|
|
497
|
+
900
|
|
498
|
+
end # sleep_time = if waiting_time
|
|
499
|
+
|
|
455
500
|
end # while
|
|
456
501
|
|
|
457
502
|
unless did_it
|
|
@@ -315,11 +315,14 @@ module Xolo
|
|
|
315
315
|
# The key is jamf_obj_name_pfx on the title
|
|
316
316
|
# so for title 'foobar', it is 'xolo-foobar' or 'xolotest-foobar' for test servers
|
|
317
317
|
# That value is also used as the display name
|
|
318
|
-
#
|
|
319
|
-
#
|
|
318
|
+
#
|
|
319
|
+
# @return [String, nil] The key and display name of a version script stored
|
|
320
|
+
# in the title editor as the ExtAttr for this title, IF the title uses an ExtAttr
|
|
320
321
|
#####################
|
|
321
322
|
def ted_ea_key
|
|
322
|
-
@ted_ea_key
|
|
323
|
+
return @ted_ea_key if defined? @ted_ea_key
|
|
324
|
+
|
|
325
|
+
@ted_ea_key = version_script.pix_empty? ? nil : "#{jamf_obj_name_pfx_base}#{title}"
|
|
323
326
|
end
|
|
324
327
|
|
|
325
328
|
# Create the EA in the Title Editor
|
|
@@ -566,11 +569,26 @@ module Xolo
|
|
|
566
569
|
# we've already done the known version objects, above
|
|
567
570
|
next if version_order.include? ted_patch.version
|
|
568
571
|
|
|
572
|
+
# progress "DEBUG: app_name: #{app_name}... app_bundle_id: #{app_bundle_id}.... ted_ea_key: #{ted_ea_key}", log: :debug
|
|
573
|
+
# progress "DEBUG: version_script: #{version_script}", log: :debug
|
|
574
|
+
|
|
575
|
+
# ea_name/ted_ea_key was getting passed
|
|
576
|
+
# even when no ea was used, causing windoo errors.
|
|
577
|
+
if app_name
|
|
578
|
+
aname = app_name
|
|
579
|
+
aid = app_bundle_id
|
|
580
|
+
ea_name = nil
|
|
581
|
+
else
|
|
582
|
+
aname = nil
|
|
583
|
+
aid = nil
|
|
584
|
+
ea_name = ted_ea_key
|
|
585
|
+
end
|
|
586
|
+
|
|
569
587
|
Xolo::Server::Helpers::TitleEditor.set_patch_component_criteria(
|
|
570
588
|
ted_patch,
|
|
571
|
-
app_name:
|
|
572
|
-
app_bundle_id:
|
|
573
|
-
ea_name:
|
|
589
|
+
app_name: aname,
|
|
590
|
+
app_bundle_id: aid,
|
|
591
|
+
ea_name: ea_name
|
|
574
592
|
)
|
|
575
593
|
ted_patch.enable
|
|
576
594
|
end
|
|
@@ -356,6 +356,9 @@ module Xolo
|
|
|
356
356
|
self.jamf_pkg_id = pkg.save
|
|
357
357
|
# save the data now so the pkg_id is available for immeadiate use, e.g. by pkg upload
|
|
358
358
|
save_local_data
|
|
359
|
+
log_debug 'TEMP: Pausing 65 secs for server cluster to see new pkg'
|
|
360
|
+
sleep 65
|
|
361
|
+
|
|
359
362
|
pkg
|
|
360
363
|
rescue => e
|
|
361
364
|
msg = "Jamf: Failed to create Jamf::JPackage '#{jamf_pkg_name}': #{e.class}: #{e}"
|
|
@@ -1378,11 +1381,29 @@ module Xolo
|
|
|
1378
1381
|
raise Xolo::NoSuchItemError, msg
|
|
1379
1382
|
end
|
|
1380
1383
|
|
|
1381
|
-
#
|
|
1382
|
-
#
|
|
1383
|
-
#
|
|
1384
|
+
# Pkg assignment and patch pol. creation cannot happen until the version
|
|
1385
|
+
# becomes visible from the Title Editor.
|
|
1386
|
+
#
|
|
1387
|
+
# This method starts a thread that waits until then, then assigns the pkg to it
|
|
1388
|
+
# in Jamf Patch, and creates the patch policy.
|
|
1389
|
+
#
|
|
1390
|
+
# Normally Jamf Pro will poll its Patch Sources every 5 minutes, so it _shouldn't_
|
|
1391
|
+
# take more than that for a new version to appear.
|
|
1392
|
+
# But sometime, esp. in Jamf Cloud instances, it may be hours before the version
|
|
1393
|
+
# shows up.
|
|
1394
|
+
#
|
|
1395
|
+
# To deal with this, we check to see if it has appeared every minute for the first 10 min.
|
|
1396
|
+
#
|
|
1397
|
+
# If it hasn't happened by then, we send a notification that we're still waiting
|
|
1398
|
+
# and will check every 10 min for the next 3 hrs.
|
|
1399
|
+
#
|
|
1400
|
+
# If still nothing, send another notification that we'll check every 30 min for
|
|
1401
|
+
# the next 6 hrs
|
|
1402
|
+
#
|
|
1403
|
+
# If still nothing after 9hrs and 10 min, send a final notification that we
|
|
1404
|
+
# are giving up, and please investigate manually. Once Jamf actually sees the version
|
|
1405
|
+
# from the title editor,
|
|
1384
1406
|
#
|
|
1385
|
-
# Do this in a thread so the xadm user doesn't wait up to ?? minutes.
|
|
1386
1407
|
#
|
|
1387
1408
|
# @return [void]
|
|
1388
1409
|
#########################
|
|
@@ -1399,36 +1420,80 @@ module Xolo
|
|
|
1399
1420
|
@activate_patch_version_thread = Thread.new do
|
|
1400
1421
|
log_debug "Jamf: Starting activate_patch_version_thread waiting for version #{version} of title #{title} to become visible from the title editor"
|
|
1401
1422
|
|
|
1402
|
-
start_time = Time.now
|
|
1403
|
-
|
|
1404
|
-
start_time = start_time.strftime '%F %T'
|
|
1405
|
-
|
|
1406
|
-
did_it = false
|
|
1423
|
+
start_time = Time.now.strftime '%F %T'
|
|
1424
|
+
version_visible = false
|
|
1407
1425
|
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1426
|
+
# Check every minute for the first 10 minutes
|
|
1427
|
+
#####
|
|
1428
|
+
10.times do
|
|
1429
|
+
sleep 60
|
|
1430
|
+
log_debug "Jamf: checking for version #{version} of title #{title} to become visible from the Title Editor since #{start_time}"
|
|
1431
|
+
next unless patch_version_visible_in_jamf?(title_object, version)
|
|
1411
1432
|
|
|
1412
|
-
|
|
1413
|
-
# if the title was deleted while this was happening.
|
|
1414
|
-
next unless title_object.jamf_patch_title(refresh: true) && title_object.jamf_patch_title.versions.key?(version)
|
|
1415
|
-
|
|
1416
|
-
did_it = true
|
|
1433
|
+
version_visible = true
|
|
1417
1434
|
break
|
|
1435
|
+
end # 10 times
|
|
1436
|
+
|
|
1437
|
+
# warn, and then check every 10 min for the next 3 hours
|
|
1438
|
+
#####
|
|
1439
|
+
unless version_visible
|
|
1440
|
+
msg = "Jamf: Version '#{version}' of title '#{title}' is still NOT visible from the Title Editor since #{start_time}. Will check every 10 minutes for the next 3 hours."
|
|
1441
|
+
log_warn msg, alert: true
|
|
1442
|
+
|
|
1443
|
+
# every 10 min for 3 hrs = 18 times
|
|
1444
|
+
18.times do
|
|
1445
|
+
sleep 600
|
|
1446
|
+
log_debug "Jamf: Still checking for version #{version} of title #{title} to become visible from the Title Editor since #{start_time}"
|
|
1447
|
+
next unless patch_version_visible_in_jamf?(title_object, version)
|
|
1448
|
+
|
|
1449
|
+
version_visible = true
|
|
1450
|
+
break
|
|
1451
|
+
end # 18 times
|
|
1452
|
+
end
|
|
1453
|
+
|
|
1454
|
+
# warn, and then check every 30 min for the next 6 hours
|
|
1455
|
+
#####
|
|
1456
|
+
unless version_visible
|
|
1457
|
+
msg = "Jamf: Version '#{version}' of title '#{title}' is STILL NOT visible from the Title Editor since #{start_time}. Will check every 30 minutes for the next 6 hours before giving up."
|
|
1458
|
+
log_warn msg, alert: true
|
|
1459
|
+
|
|
1460
|
+
# every 30 min for 6 hrs = 12 times
|
|
1461
|
+
12.times do
|
|
1462
|
+
sleep 1800
|
|
1463
|
+
log_debug "Jamf: STILL checking for version #{version} of title #{title} to become visible from the Title Editor since #{start_time}"
|
|
1464
|
+
next unless patch_version_visible_in_jamf?(title_object, version)
|
|
1465
|
+
|
|
1466
|
+
version_visible = true
|
|
1467
|
+
break
|
|
1468
|
+
end # 12 times
|
|
1418
1469
|
end
|
|
1419
1470
|
|
|
1420
|
-
|
|
1471
|
+
#### did we do it?
|
|
1472
|
+
if version_visible
|
|
1421
1473
|
activate_patch_version_in_jamf
|
|
1422
1474
|
msg = "Jamf: Version '#{version}' of title '#{title}' is now visible in Jamf Pro. Package assigned and Patch policy created."
|
|
1423
1475
|
log_info msg, alert: true
|
|
1424
1476
|
else
|
|
1425
|
-
msg = "Jamf: ERROR: Version '#{version}' of title '#{title}' has not become visible from the Title Editor in over
|
|
1477
|
+
msg = "Jamf: ERROR: Version '#{version}' of title '#{title}' has not become visible from the Title Editor in over 9 hours. The package has not been assigned, and no patch policy was created. When the version appears in Jamf Patch, run \"xadm repair #{title} '#{version}'\" to assign the pkg and create the patch policy."
|
|
1426
1478
|
log_error msg, alert: true
|
|
1427
1479
|
end
|
|
1480
|
+
rescue => e
|
|
1481
|
+
msg = "Error in thread while waiting for version '#{version}' of title '#{title}' to appear from the Title Editor: #{e.class}: #{e}"
|
|
1482
|
+
log_error msg, alert: true
|
|
1483
|
+
e.backtrace.each { |l| log_error "...#{l}" }
|
|
1428
1484
|
end # thread
|
|
1485
|
+
|
|
1429
1486
|
@activate_patch_version_thread.name = "activate_patch_version_thread-#{title}-#{version}"
|
|
1430
1487
|
end
|
|
1431
1488
|
|
|
1489
|
+
# @return [Boolean] is a given version/patch of a title visible in Jamf Patch from
|
|
1490
|
+
# its patch source?
|
|
1491
|
+
#################################
|
|
1492
|
+
def patch_version_visible_in_jamf?(title_object, version)
|
|
1493
|
+
title_object.jamf_patch_title(refresh: true) && \
|
|
1494
|
+
title_object.jamf_patch_title.versions.key?(version)
|
|
1495
|
+
end
|
|
1496
|
+
|
|
1432
1497
|
# Patches for subscribed titles are already visible in Jamf Patch Management
|
|
1433
1498
|
# So we just need to assign the pkg to the patch version, and create the patch policy.
|
|
1434
1499
|
##########################
|
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.
|
|
4
|
+
version: 2.6.0
|
|
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-
|
|
11
|
+
date: 2026-11-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|