xolo-server 2.3.0 → 2.4.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/data/client/xolo +13 -1
- data/lib/xolo/core/version.rb +1 -1
- data/lib/xolo/server/configuration.rb +1 -0
- data/lib/xolo/server/helpers/autopkg.rb +76 -6
- data/lib/xolo/server/helpers/maintenance.rb +2 -2
- data/lib/xolo/server/mixins/title_jamf_access.rb +2 -7
- data/lib/xolo/server/routes/titles.rb +24 -0
- data/lib/xolo/server/title.rb +22 -0
- data/lib/xolo/server/version.rb +1 -12
- 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: d27f4a3e1656ef59731865488978113bcbeb4a5ebbea8c120585371c49aad335
|
|
4
|
+
data.tar.gz: a006f5ec49ad3cfbad6ae5908e2da17b65cdc2bf8eb0c3a7133fcaa0af6db3f4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c47f0964d7c5f5a42ddb909a0ee6b5d8bb01ead710b6be7fe9087e882081dcf753fc9f783be8bd0e5658b49df36d012f59f956db768026c915faabc8f5d9a4a8
|
|
7
|
+
data.tar.gz: 448ec9e58919ada9612c8651f814d168d4d6117c92b3e76faa2c5bdc74eb7747298f6bdebcc1547b7c662084d97fbbd7fb018331c8424f28b79bf1114cdacba7
|
data/data/client/xolo
CHANGED
|
@@ -97,6 +97,7 @@ be_verbose=
|
|
|
97
97
|
debugging_on=
|
|
98
98
|
no_versions=
|
|
99
99
|
show_xolo_version=
|
|
100
|
+
do_recon=
|
|
100
101
|
|
|
101
102
|
# arguments
|
|
102
103
|
command=
|
|
@@ -155,7 +156,9 @@ Options:
|
|
|
155
156
|
policies, etc, from test xolo server, not the production server.
|
|
156
157
|
Setting the XOLO_TEST_MODE env. variable does the same thing.
|
|
157
158
|
-r, --recon: With 'install' or 'uninstall' run a 'jamf recon' after the
|
|
158
|
-
operation completes successfully.
|
|
159
|
+
operation completes successfully. With 'update', run a 'jamf recon'
|
|
160
|
+
before the checkin. NOTE: With update, the whole process may take
|
|
161
|
+
many minutes.
|
|
159
162
|
-n, --no-versions: With the 'list-titles' and 'list-installed' commands,
|
|
160
163
|
do not show the versions available, or the version
|
|
161
164
|
installed, respectively.
|
|
@@ -190,6 +193,9 @@ Commands:
|
|
|
190
193
|
every time this computer checks in with Jamf Pro.
|
|
191
194
|
Note: this just runs the 'jamf policy' command, which will execute any pending
|
|
192
195
|
Jamf policies triggered by "recurring check-in".
|
|
196
|
+
If --recon is given, a Jamf recon will run first, followed by a 1 minute pause
|
|
197
|
+
for Jamf to process the data before doing the check-in. This helps the Mac to see
|
|
198
|
+
very recently-released versions as patch updates.
|
|
193
199
|
|
|
194
200
|
refresh, r
|
|
195
201
|
Update xolo's information about current titles and versions.
|
|
@@ -1035,6 +1041,12 @@ function run_recon() {
|
|
|
1035
1041
|
function update() {
|
|
1036
1042
|
say "Updating installed titles, or installing newly scoped ones..."
|
|
1037
1043
|
|
|
1044
|
+
if [[ -n "$do_recon" ]] ; then
|
|
1045
|
+
run_recon
|
|
1046
|
+
say "Pausing to let Jamf Pro process recon data..."
|
|
1047
|
+
sleep 60
|
|
1048
|
+
fi
|
|
1049
|
+
|
|
1038
1050
|
debug "Running jamf policy..."
|
|
1039
1051
|
if be_verbose ; then
|
|
1040
1052
|
$JAMF policy -verbose
|
data/lib/xolo/core/version.rb
CHANGED
|
@@ -156,6 +156,7 @@ module Xolo
|
|
|
156
156
|
|
|
157
157
|
# @!attribute server_admin_jamf_group
|
|
158
158
|
# @return [String] The name of a Jamf account-group containing users of 'xadm'
|
|
159
|
+
# who are allowed to manage the xoloserver itself
|
|
159
160
|
server_admin_jamf_group: {
|
|
160
161
|
type: :string,
|
|
161
162
|
desc: <<~ENDDESC
|
|
@@ -35,6 +35,11 @@ module Xolo
|
|
|
35
35
|
AUTOPKG_UPLOADED_BY = 'autopkg'
|
|
36
36
|
FAIL_UNTRUSTED_RECIPES_CLI_OPT = '-k FAIL_RECIPES_WITHOUT_TRUST_INFO=yes'
|
|
37
37
|
|
|
38
|
+
# when we find a .pkg after a recipe has run, it can't be older than this many
|
|
39
|
+
# seconds, or we assume it is from some other run of the recipe, not the one we
|
|
40
|
+
# just did. Currently 20 min
|
|
41
|
+
MAX_PKG_AGE = 1200
|
|
42
|
+
|
|
38
43
|
# Module Methods
|
|
39
44
|
#######################
|
|
40
45
|
#######################
|
|
@@ -127,7 +132,9 @@ module Xolo
|
|
|
127
132
|
clean_old_pkgs pkgdir
|
|
128
133
|
|
|
129
134
|
cmd = autopkg_run_command(title_object)
|
|
130
|
-
progress "Running AutoPkg recipe
|
|
135
|
+
progress "Running AutoPkg recipe '#{recipe}' for #{title_object.title}..."
|
|
136
|
+
|
|
137
|
+
log_info "Running AutoPkg recipe for #{title_object.title} via command: #{cmd.join(' ')}"
|
|
131
138
|
|
|
132
139
|
unlock_autopkg_user_keychain
|
|
133
140
|
|
|
@@ -135,20 +142,83 @@ module Xolo
|
|
|
135
142
|
souterr.strip!
|
|
136
143
|
|
|
137
144
|
if status.success?
|
|
138
|
-
progress "AutoPkg recipe #{recipe} for title '#{title_object.title}' completed successfully.", log: :info, alert: true
|
|
145
|
+
progress "AutoPkg recipe '#{recipe}' for title '#{title_object.title}' completed successfully.", log: :info, alert: true
|
|
139
146
|
log_debug 'AutoPkg output:'
|
|
140
147
|
souterr.lines.each { |l| log_debug "AutoPkg: #{l.chomp}" }
|
|
141
148
|
|
|
142
149
|
pkgs = pkgdir.children.select { |c| c.extname == '.pkg' }
|
|
150
|
+
# the Pathname of the newest .pkg
|
|
143
151
|
pkgs.max_by(&:mtime)
|
|
144
152
|
|
|
153
|
+
# Failure is a option
|
|
145
154
|
else
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
handle_failed_recipe(
|
|
156
|
+
recipe: recipe,
|
|
157
|
+
title_object: title_object,
|
|
158
|
+
status: status,
|
|
159
|
+
souterr: souterr
|
|
160
|
+
)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Deal with a failed recipe run
|
|
165
|
+
#
|
|
166
|
+
###############################
|
|
167
|
+
def handle_failed_recipe(recipe:, title_object:, status:, souterr:)
|
|
168
|
+
errmsg = "ERROR: AutoPkg recipe '#{recipe}' for title '#{title_object.title}' failed with status #{status.exitstatus}. Details logged and emailed to '#{title_object.contact_email}'"
|
|
169
|
+
|
|
170
|
+
progress errmsg, log: :error, alert: true
|
|
171
|
+
|
|
172
|
+
# log the details
|
|
173
|
+
log_error 'AutoPkg output:'
|
|
174
|
+
souterr.lines.each { |l| log_error "AutoPkg: #{l.chomp}" }
|
|
175
|
+
|
|
176
|
+
# email the details to the contact addr for the title
|
|
177
|
+
email_subj = "ERROR: AutoPkg recipe FAILED for title '#{title_object.title}'"
|
|
178
|
+
email_msg = <<~ENDEMAIL
|
|
179
|
+
The autopkg recipe '#{recipe}' for title '#{title_object.title}' failed with status #{status.exitstatus}.
|
|
180
|
+
|
|
181
|
+
Please check that the recipe is up to date. If not, please update the recipe's repo by running this as the autppkg user on the xolo server:
|
|
182
|
+
|
|
183
|
+
autopkg repo-update <repo-name>
|
|
184
|
+
|
|
185
|
+
Then confirm you still trust the recipe.
|
|
186
|
+
If so, run:
|
|
187
|
+
|
|
188
|
+
autopkg update-trust-info '#{recipe}'
|
|
189
|
+
|
|
190
|
+
Then tell xolo the xolo server to re-run the recipe - the .pkg will always be assigned to the latest version.
|
|
191
|
+
|
|
192
|
+
xadm rerun-autopkg-recipe #{title_object.title}
|
|
193
|
+
|
|
194
|
+
If needed, contact your xoloserver administrator to perform the autopkg commands.
|
|
195
|
+
|
|
196
|
+
Here is the output from the failed recipe:
|
|
197
|
+
------------------------------------------
|
|
198
|
+
#{souterr}
|
|
199
|
+
ENDEMAIL
|
|
200
|
+
|
|
201
|
+
send_email to: title_object.contact_email, subject: email_subj, msg: email_msg, html: false
|
|
202
|
+
|
|
203
|
+
raise "AutoPkg recipe #{recipe} failed."
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# confirm a given autopkg package is OK to use after running a recipe
|
|
207
|
+
###########################
|
|
208
|
+
def validate_autopkg_pkg(pkg_src)
|
|
209
|
+
if pkg_src.nil?
|
|
210
|
+
msg = 'AutoPkg recipe is enabled for this title, but no pkg was found after running the recipe. Please check the AutoPkg recipe and the server log for details.'
|
|
211
|
+
progress msg, log: :warn, alert: true
|
|
212
|
+
return false
|
|
213
|
+
end
|
|
149
214
|
|
|
150
|
-
|
|
215
|
+
oldest_allowed = Time.now - MAX_PKG_AGE # 20 minutes ago
|
|
216
|
+
if pkg_src.mtime < oldest_allowed
|
|
217
|
+
msg = "AutoPkg recipe is enabled for this title, and a pkg was found after running the recipe, but it was last modified at #{pkg_src.mtime}, which is more than 20 minutes ago. To avoid accidentally uploading an old pkg, the server will not upload this pkg. Please check the AutoPkg recipe and the server log for details."
|
|
218
|
+
progress msg, log: :warn, alert: true
|
|
219
|
+
return false
|
|
151
220
|
end
|
|
221
|
+
true
|
|
152
222
|
end
|
|
153
223
|
|
|
154
224
|
# remove any existing pkgs from the given autopkg output dir
|
|
@@ -334,13 +334,13 @@ module Xolo
|
|
|
334
334
|
next unless vobj_to_release
|
|
335
335
|
|
|
336
336
|
# release it
|
|
337
|
-
log_debug "Maint: About to auto-release
|
|
337
|
+
log_debug "Maint: About to auto-release '#{title}' version '#{vobj_to_release.version}' which came out #{vobj_to_release.creation_date}"
|
|
338
338
|
|
|
339
339
|
# releasing a version is done via the title obj, since it affects the status
|
|
340
340
|
# of all versions.
|
|
341
341
|
title_obj.release vobj_to_release.version
|
|
342
342
|
|
|
343
|
-
log_info "Maint: Auto-released
|
|
343
|
+
log_info "Maint: Auto-released '#{title}' version '#{vobj_to_release.version}' which came out #{vobj_to_release.creation_date}", alert: true
|
|
344
344
|
|
|
345
345
|
# pause for server to catch up
|
|
346
346
|
sleep 60
|
|
@@ -1808,6 +1808,8 @@ module Xolo
|
|
|
1808
1808
|
pol.self_service_description = new_desc
|
|
1809
1809
|
|
|
1810
1810
|
pol.self_service_install_button_text = Xolo::Server::Title::SELF_SERVICE_INSTALL_BTN_TEXT
|
|
1811
|
+
pol.self_service_reinstall_button_text = Xolo::Server::Title::SELF_SERVICE_REINSTALL_BTN_TEXT
|
|
1812
|
+
|
|
1811
1813
|
# icon already uploaded to jamf
|
|
1812
1814
|
return if ssvc_icon_id
|
|
1813
1815
|
|
|
@@ -1823,13 +1825,6 @@ module Xolo
|
|
|
1823
1825
|
self.ssvc_icon_id = Jamf::Policy.fetch(id: pol.id, cnx: jamf_cnx).icon.id
|
|
1824
1826
|
end
|
|
1825
1827
|
|
|
1826
|
-
# run the autopkg recipe if defined
|
|
1827
|
-
# See Helpers::AutoPkg for more details
|
|
1828
|
-
############################
|
|
1829
|
-
def run_autopkg_recipe
|
|
1830
|
-
server_app_instance.run_autopkg_recipe self
|
|
1831
|
-
end
|
|
1832
|
-
|
|
1833
1828
|
# Methods used by subscription stuff
|
|
1834
1829
|
##############################
|
|
1835
1830
|
|
|
@@ -288,6 +288,30 @@ module Xolo
|
|
|
288
288
|
body data
|
|
289
289
|
end
|
|
290
290
|
|
|
291
|
+
# rerun the titles autopkg recipe
|
|
292
|
+
######################
|
|
293
|
+
post '/titles/:title/rerun_autopkg_recipe' do
|
|
294
|
+
halt_on_missing_title params[:title]
|
|
295
|
+
halt_on_locked_title params[:title]
|
|
296
|
+
title = instantiate_title params[:title]
|
|
297
|
+
|
|
298
|
+
unless title.autopkg_enabled?
|
|
299
|
+
msg = "Title '#{params[:title]}' is not configured to use AutoPkg"
|
|
300
|
+
log_debug "ERROR: #{msg}"
|
|
301
|
+
halt 409, { status: 409, error: msg }
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
unless title.latest_version
|
|
305
|
+
msg = "Title '#{params[:title]}' has no versions, cannot re-run the recipe"
|
|
306
|
+
log_debug "ERROR: #{msg}"
|
|
307
|
+
halt 404, { status: 404, error: msg }
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
with_streaming do
|
|
311
|
+
title.rerun_autopkg_recipe
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
291
315
|
end # Titles
|
|
292
316
|
|
|
293
317
|
end # Routes
|
data/lib/xolo/server/title.rb
CHANGED
|
@@ -120,6 +120,7 @@ module Xolo
|
|
|
120
120
|
JPAPI_PATCH_REPORT_RSRC = 'patch-report'
|
|
121
121
|
|
|
122
122
|
SELF_SERVICE_INSTALL_BTN_TEXT = 'Install'
|
|
123
|
+
SELF_SERVICE_REINSTALL_BTN_TEXT = 'Re-Install'
|
|
123
124
|
|
|
124
125
|
# Class Methods
|
|
125
126
|
######################
|
|
@@ -1144,6 +1145,27 @@ module Xolo
|
|
|
1144
1145
|
unlock
|
|
1145
1146
|
end
|
|
1146
1147
|
|
|
1148
|
+
# run the autopkg recipe if defined
|
|
1149
|
+
# See Helpers::AutoPkg for more details
|
|
1150
|
+
############################
|
|
1151
|
+
def run_autopkg_recipe
|
|
1152
|
+
server_app_instance.run_autopkg_recipe self
|
|
1153
|
+
end
|
|
1154
|
+
|
|
1155
|
+
# Re run the autopkg recipe
|
|
1156
|
+
# and re-upload the pkg
|
|
1157
|
+
############################
|
|
1158
|
+
def rerun_autopkg_recipe
|
|
1159
|
+
pkg_src = server_app_instance.run_autopkg_recipe self
|
|
1160
|
+
|
|
1161
|
+
return unless server_app_instance.validate_autopkg_pkg pkg_src
|
|
1162
|
+
|
|
1163
|
+
latest_version_obj = version_object latest_version
|
|
1164
|
+
latest_version_obj.pkg_is_from_autopkg = true
|
|
1165
|
+
|
|
1166
|
+
server_app_instance.process_and_upload_autopkg_pkg title, latest_version_obj, pkg_src
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1147
1169
|
# Is this title locked for updates?
|
|
1148
1170
|
#############################
|
|
1149
1171
|
def locked?
|
data/lib/xolo/server/version.rb
CHANGED
|
@@ -748,18 +748,7 @@ module Xolo
|
|
|
748
748
|
|
|
749
749
|
pkg_src = title_object.run_autopkg_recipe
|
|
750
750
|
|
|
751
|
-
|
|
752
|
-
msg = 'AutoPkg recipe is enabled for this title, but no pkg was found after running the recipe. Please check the AutoPkg recipe and the server log for details.'
|
|
753
|
-
progress msg, log: :warn, alert: true
|
|
754
|
-
return
|
|
755
|
-
end
|
|
756
|
-
|
|
757
|
-
oldest_allowed = Time.now - 1200 # 20 minutes ago
|
|
758
|
-
if pkg_src.mtime < oldest_allowed
|
|
759
|
-
msg = "AutoPkg recipe is enabled for this title, and a pkg was found after running the recipe, but it was last modified at #{pkg_src.mtime}, which is more than 20 minutes ago. To avoid accidentally uploading an old pkg, the server will not upload this pkg. Please check the AutoPkg recipe and the server log for details."
|
|
760
|
-
progress msg, log: :warn, alert: true
|
|
761
|
-
return
|
|
762
|
-
end
|
|
751
|
+
return unless server_app_instance.validate_autopkg_pkg pkg_src
|
|
763
752
|
|
|
764
753
|
# this lets future code know that the pkg we're working with came from autopkg
|
|
765
754
|
self.pkg_is_from_autopkg = true
|
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.4.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-09-
|
|
11
|
+
date: 2026-09-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|