ruby-jss 1.0.2 → 1.0.3b1

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.

Potentially problematic release.


This version of ruby-jss might be problematic. Click here for more details.

@@ -1,95 +1,85 @@
1
- ### Copyright 2018 Pixar
2
-
3
- ###
4
- ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
- ### with the following modification; you may not use this file except in
6
- ### compliance with the Apache License and the following modification to it:
7
- ### Section 6. Trademarks. is deleted and replaced with:
8
- ###
9
- ### 6. Trademarks. This License does not grant permission to use the trade
10
- ### names, trademarks, service marks, or product names of the Licensor
11
- ### and its affiliates, except as required to comply with Section 4(c) of
12
- ### the License and to reproduce the content of the NOTICE file.
13
- ###
14
- ### You may obtain a copy of the Apache License at
15
- ###
16
- ### http://www.apache.org/licenses/LICENSE-2.0
17
- ###
18
- ### Unless required by applicable law or agreed to in writing, software
19
- ### distributed under the Apache License with the above modification is
20
- ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
- ### KIND, either express or implied. See the Apache License for the specific
22
- ### language governing permissions and limitations under the Apache License.
23
- ###
24
- ###
25
-
26
- ###
27
- module JSS
28
-
29
- ### Module Constants
30
- #####################################
31
-
32
- ### Module Variables
33
- #####################################
1
+ # Copyright 2018 Pixar
2
+
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ # with the following modification; you may not use this file except in
6
+ # compliance with the Apache License and the following modification to it:
7
+ # Section 6. Trademarks. is deleted and replaced with:
8
+ #
9
+ # 6. Trademarks. This License does not grant permission to use the trade
10
+ # names, trademarks, service marks, or product names of the Licensor
11
+ # and its affiliates, except as required to comply with Section 4(c) of
12
+ # the License and to reproduce the content of the NOTICE file.
13
+ #
14
+ # You may obtain a copy of the Apache License at
15
+ #
16
+ # http://www.apache.org/licenses/LICENSE-2.0
17
+ #
18
+ # Unless required by applicable law or agreed to in writing, software
19
+ # distributed under the Apache License with the above modification is
20
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ # KIND, either express or implied. See the Apache License for the specific
22
+ # language governing permissions and limitations under the Apache License.
23
+ #
24
+ #
34
25
 
35
- ### Module Methods
36
- #####################################
26
+ module JSS
37
27
 
38
- ### Classes
28
+ # Classes
39
29
  #####################################
40
30
 
41
- ### A Package in the JSS
42
- ###
43
- ### Also the API provides no access to the package's
44
- ### file list (index), so indexing must be done separately (usually via Casper Admin)
45
- ###
31
+ # A Package in the JSS
32
+ #
33
+ # Also the API provides no access to the package's
34
+ # file list (index), so indexing must be done separately (usually via Casper Admin)
35
+ #
46
36
  class Package < JSS::APIObject
47
37
 
48
- ### Mix-Ins
38
+ # Mix-Ins
49
39
  #####################################
50
40
 
51
41
  include JSS::Categorizable
52
42
  include JSS::Creatable
53
43
  include JSS::Updatable
54
44
 
55
- ### Class Methods
45
+ # Class Methods
56
46
  #####################################
57
47
 
58
- ### Class Constants
48
+ # Class Constants
59
49
  #####################################
60
50
 
61
- ### The base for REST resources of this class
51
+ # The base for REST resources of this class
62
52
  RSRC_BASE = 'packages'.freeze
63
53
 
64
- ### the hash key used for the JSON list output of all objects in the JSS
54
+ # the hash key used for the JSON list output of all objects in the JSS
65
55
  RSRC_LIST_KEY = :packages
66
56
 
67
- ### The hash key used for the JSON object output.
68
- ### It's also used in various error messages
57
+ # The hash key used for the JSON object output.
58
+ # It's also used in various error messages
69
59
  RSRC_OBJECT_KEY = :package
70
60
 
71
- ### these keys, as well as :id and :name, are present in valid API JSON data for this class
72
- VALID_DATA_KEYS = [:fill_existing_users, :fill_user_template, :reboot_required].freeze
61
+ # these keys, as well as :id and :name, are present in valid API JSON data for this class
62
+ VALID_DATA_KEYS = %i[fill_existing_users fill_user_template reboot_required].freeze
73
63
 
74
- ### The pkg storage folder on the distribution point
64
+ # The pkg storage folder on the distribution point
75
65
  DIST_POINT_PKGS_FOLDER = 'Packages'.freeze
76
66
 
77
- ### The possible values for cpu_type (required_processor) in a JSS package
78
- CPU_TYPES = %w(None x86 ppc).freeze
67
+ # The possible values for cpu_type (required_processor) in a JSS package
68
+ CPU_TYPES = %w[None x86 ppc].freeze
79
69
 
80
- ### the possible priorities
70
+ # the possible priorities
81
71
  PRIORITIES = (1..20)
82
72
 
83
- ### the default priority, since one is needed for making new pkgs
73
+ # the default priority, since one is needed for making new pkgs
84
74
  DEFAULT_PRIORITY = 10
85
75
 
86
- ### by default, no processor requirement
76
+ # by default, no processor requirement
87
77
  DEFAULT_PROCESSOR = 'None'.freeze
88
78
 
89
- ### When we shouldn't install anything (e.g. switch w/package)
79
+ # When we shouldn't install anything (e.g. switch w/package)
90
80
  DO_NOT_INSTALL = 'Do Not Install'.freeze
91
81
 
92
- ### The table in the database for this object
82
+ # The table in the database for this object
93
83
  DB_TABLE = 'packages'.freeze
94
84
 
95
85
  # the object type for this object in
@@ -103,67 +93,126 @@ module JSS
103
93
  # How is the category stored in the API data?
104
94
  CATEGORY_DATA_TYPE = String
105
95
 
106
-
107
- ### Class Variables
96
+ # Class Methods
108
97
  #####################################
109
98
 
110
- ### Class Methods
111
- #####################################
99
+ # An array of all dist-point filenames used by all JSS packages
100
+ #
101
+ # Slow cuz we have to instantiate every pkg
102
+ #
103
+ # @param api[JSS::APIConnection] an API connection to use
104
+ # Defaults to the corrently active API. See {JSS::APIConnection}
105
+ #
106
+ # @return [Array<String>] The current file names
107
+ #
108
+ def self.all_filenames(api: JSS.api)
109
+ pkgs_in_use = []
110
+ all_ids.each { |pkg_id| pkgs_in_use << fetch(id: pkg_id, api: api).filename }
111
+ pkgs_in_use.compact
112
+ end
113
+
114
+ # An array of String filenames for all files DIST_POINT_PKGS_FOLDER
115
+ # that aren't used by a JSS::Package
116
+ #
117
+ # Slow cuz we have to instantiate every pkg
118
+ #
119
+ # @param ro_pw[String] the password for the readonly account
120
+ # on the master Distribution Point,
121
+ #
122
+ # @param unmount[Boolean] whether or not ot unount the
123
+ # distribution point when finished.
124
+ #
125
+ # @param api[JSS::APIConnection] an API connection to use
126
+ # Defaults to the corrently active API. See {JSS::APIConnection}
127
+ #
128
+ # @return [Array<String>] The orphaned files
129
+ #
130
+ def self.orphaned_files(ro_pw, unmount = true, api: JSS.api)
131
+ mdp = JSS::DistributionPoint.master_distribution_point api: api
132
+ pkgs_dir = mdp.mount(ro_pw, :ro) + DIST_POINT_PKGS_FOLDER
133
+ files_on_mdp = pkgs_dir.children.map { |f| f.basename.to_s }
134
+ mdp.unmount if unmount
135
+ files_on_mdp - all_filenames(api: api)
136
+ end
112
137
 
113
- ### Attributes
138
+ # An array of String filenames for all filenames in any
139
+ # JSS::Package that don't exist on DIST_POINT_PKGS_FOLDER
140
+ #
141
+ # Slow cuz we have to instantiate every pkg
142
+ #
143
+ # @param ro_pw[String] the password for the readonly account
144
+ # on the master Distribution Point,
145
+ #
146
+ # @param unmount[Boolean] whether or not ot unount the
147
+ # distribution point when finished.
148
+ #
149
+ # @param api[JSS::APIConnection] an API connection to use
150
+ # Defaults to the corrently active API. See {JSS::APIConnection}
151
+ #
152
+ # @return [Array<String>] The orphaned files
153
+ #
154
+ def self.missing_files(ro_pw, unmount = true, api: JSS.api)
155
+ mdp = JSS::DistributionPoint.master_distribution_point api: api
156
+ pkgs_dir = mdp.mount(ro_pw, :ro) + DIST_POINT_PKGS_FOLDER
157
+ files_on_mdp = pkgs_dir.children.map { |f| f.basename.to_s }
158
+ mdp.unmount if unmount
159
+ all_filenames(api: api) - files_on_mdp
160
+ end
161
+
162
+ # Attributes
114
163
  #####################################
115
164
 
116
- ### @return [String] the filename of the .pkg, .mpkg, or .dmg on the Casper server
165
+ # @return [String] the filename of the .pkg, .mpkg, or .dmg on the Casper server
117
166
  attr_reader :filename
118
167
 
119
- ### @return [Pathname] the local receipt when this pkg is installed
168
+ # @return [Pathname] the local receipt when this pkg is installed
120
169
  attr_reader :receipt
121
170
 
122
- ### @return [Boolean] does this item 'Fill Existing Users' when jamf installs it?
171
+ # @return [Boolean] does this item 'Fill Existing Users' when jamf installs it?
123
172
  attr_reader :fill_existing_users
124
173
 
125
- ### @return [Boolean] does this pkg also get install in the OS user homedir template
174
+ # @return [Boolean] does this pkg also get install in the OS user homedir template
126
175
  attr_reader :fill_user_template
127
176
 
128
- ### @return [Boolean] does this item require a reboot after installation?
177
+ # @return [Boolean] does this item require a reboot after installation?
129
178
  attr_reader :reboot_required
130
179
 
131
- ### @return [Array<String>] the OS versions this can be installed onto. For all minor versions, the format is 10.5.x
180
+ # @return [Array<String>] the OS versions this can be installed onto. For all minor versions, the format is 10.5.x
132
181
  attr_reader :os_requirements
133
182
 
134
- ### @return [String] limit installation to these architectures: 'x86', 'ppc', 'None'
183
+ # @return [String] limit installation to these architectures: 'x86', 'ppc', 'None'
135
184
  attr_reader :required_processor
136
185
 
137
- ### @return [String] the name of a pkg to install (or "Do Not Install") when this pkg can't be installed
186
+ # @return [String] the name of a pkg to install (or "Do Not Install") when this pkg can't be installed
138
187
  attr_reader :switch_with_package
139
188
 
140
- ### @return [Boolean] can this item be uninstalled? Some, e.g. OS Updates, can't
189
+ # @return [Boolean] can this item be uninstalled? Some, e.g. OS Updates, can't
141
190
  attr_reader :allow_uninstalled
142
191
 
143
- ### @return [String] the info field for this pkg - stores d3's basename & swupdate values
192
+ # @return [String] the info field for this pkg - stores d3's basename & swupdate values
144
193
  attr_reader :info
145
194
 
146
- ### @return [String] the notes field for this pkg
195
+ # @return [String] the notes field for this pkg
147
196
  attr_reader :notes
148
197
 
149
- ### @return [Boolean] only install this pkg if it's available in the commandline softwareupdate.
198
+ # @return [Boolean] only install this pkg if it's available in the commandline softwareupdate.
150
199
  attr_reader :install_if_reported_available
151
200
 
152
- ### @return [Boolean] should this pkg be installed on the boot volume during imaging
201
+ # @return [Boolean] should this pkg be installed on the boot volume during imaging
153
202
  attr_reader :boot_volume_required
154
203
 
155
- ### @return [Integer] Priority to use for deploying or uninstalling the package
204
+ # @return [Integer] Priority to use for deploying or uninstalling the package
156
205
  attr_reader :priority
157
206
 
158
- ### @return [Boolean] does this pkg cause a notification to be sent on self-heal?
207
+ # @return [Boolean] does this pkg cause a notification to be sent on self-heal?
159
208
  attr_reader :send_notification
160
209
 
161
- ### @see JSS::APIObject#initialize
162
- ###
210
+ # @see JSS::APIObject#initialize
211
+ #
163
212
  def initialize(args = {})
164
213
  super
165
214
 
166
- ### now we have pkg_data with something in it, so fill out the instance vars
215
+ # now we have pkg_data with something in it, so fill out the instance vars
167
216
  @allow_uninstalled = @init_data[:allow_uninstalled]
168
217
  @boot_volume_required = @init_data[:boot_volume_required]
169
218
  @filename = @init_data[:filename] || @init_data[:name]
@@ -186,21 +235,21 @@ module JSS
186
235
  @receipt = @filename ? (JSS::Client::RECEIPTS_FOLDER + @filename.to_s.sub(/.zip$/, '')) : nil
187
236
  end # init
188
237
 
189
- ### Change the 'allow to be uninstalled' field in the JSS
190
- ### NOTE The package must be indexed before this works. Right now, that means
191
- ### using CasperAdmin.app
192
- ###
193
- ### @param new_val[Boolean]
194
- ###
195
- ### @return [void]
196
- ###
238
+ # Change the 'allow to be uninstalled' field in the JSS
239
+ # NOTE The package must be indexed before this works. Right now, that means
240
+ # using CasperAdmin.app
241
+ #
242
+ # @param new_val[Boolean]
243
+ #
244
+ # @return [void]
245
+ #
197
246
  def allow_uninstalled=(new_val)
198
247
  return nil if new_val == @allow_uninstalled
199
248
 
200
- ### removable? defaults to false
201
- ### even though we usually want to be able to ununstall things, it would be
202
- ### dangerous to do on things like OS updates, so it must be turned on explicitly.
203
- ### packages must be indexed with Casper Admin in order to be uninstalled.
249
+ # removable? defaults to false
250
+ # even though we usually want to be able to ununstall things, it would be
251
+ # dangerous to do on things like OS updates, so it must be turned on explicitly.
252
+ # packages must be indexed with Casper Admin in order to be uninstalled.
204
253
  new_val = false if new_val.to_s.empty?
205
254
  raise JSS::InvalidDataError, "allow_uninstalled must be boolean 'true' or 'false'" unless JSS::TRUE_FALSE.include? new_val
206
255
 
@@ -208,12 +257,12 @@ module JSS
208
257
  @need_to_update = true
209
258
  end
210
259
 
211
- ### Change the boot volume required field in the JSS
212
- ###
213
- ### @param new_val[Boolean]
214
- ###
215
- ### @return [void]
216
- ###
260
+ # Change the boot volume required field in the JSS
261
+ #
262
+ # @param new_val[Boolean]
263
+ #
264
+ # @return [void]
265
+ #
217
266
  def boot_volume_required=(new_val)
218
267
  return nil if new_val == @boot_volume_required
219
268
  new_val = false if new_val.to_s.empty?
@@ -222,28 +271,28 @@ module JSS
222
271
  @need_to_update = true
223
272
  end
224
273
 
225
- ### Change the package filename.
226
- ### Setting it to nil or empty will make it match the display name
227
- ###
228
- ### @param new_val[String]
229
- ###
230
- ### @return [void]
231
- ###
274
+ # Change the package filename.
275
+ # Setting it to nil or empty will make it match the display name
276
+ #
277
+ # @param new_val[String]
278
+ #
279
+ # @return [void]
280
+ #
232
281
  def filename=(new_val)
233
282
  new_val = nil if new_val == ''
234
283
  new_val ||= @name
235
284
  return nil if new_val == @filename
236
- $stderr.puts 'WARNING: you must change the filename on the master Distribution Point. See JSS::Package.update_master_filename.' if @in_jss
285
+ warn 'WARNING: you must change the filename on the master Distribution Point. See JSS::Package.update_master_filename.' if @in_jss
237
286
  @filename = new_val
238
287
  @need_to_update = true
239
288
  end
240
289
 
241
- ### Change the Fill Existing Users value
242
- ###
243
- ### @param new_val[Boolean]
244
- ###
245
- ### @return [void]
246
- ###
290
+ # Change the Fill Existing Users value
291
+ #
292
+ # @param new_val[Boolean]
293
+ #
294
+ # @return [void]
295
+ #
247
296
  def fill_existing_users=(new_val)
248
297
  return nil if new_val == @fill_existing_users
249
298
  new_val = false if new_val.to_s.empty?
@@ -252,12 +301,12 @@ module JSS
252
301
  @need_to_update = true
253
302
  end
254
303
 
255
- ### Change the fill_user_template value
256
- ###
257
- ### @param new_val[Boolean]
258
- ###
259
- ### @return [void]
260
- ###
304
+ # Change the fill_user_template value
305
+ #
306
+ # @param new_val[Boolean]
307
+ #
308
+ # @return [void]
309
+ #
261
310
  def fill_user_template=(new_val)
262
311
  return nil if new_val == @fill_user_template
263
312
  new_val = false if new_val.to_s.empty?
@@ -266,26 +315,26 @@ module JSS
266
315
  @need_to_update = true
267
316
  end
268
317
 
269
- ### Change the info field in the JSS.
270
- ###
271
- ### @param new_val[String]
272
- ###
273
- ### @return [void]
274
- ###
318
+ # Change the info field in the JSS.
319
+ #
320
+ # @param new_val[String]
321
+ #
322
+ # @return [void]
323
+ #
275
324
  def info=(new_val)
276
325
  return nil if new_val == @info
277
- ### line breaks should be \r
326
+ # line breaks should be \r
278
327
  new_val = new_val.to_s.tr("\n", "\r")
279
328
  @info = new_val
280
329
  @need_to_update = true
281
330
  end
282
331
 
283
- ### Change the if_in_swupdate field in the JSS
284
- ###
285
- ### @param new_val[Boolean]
286
- ###
287
- ### @return [void]
288
- ###
332
+ # Change the if_in_swupdate field in the JSS
333
+ #
334
+ # @param new_val[Boolean]
335
+ #
336
+ # @return [void]
337
+ #
289
338
  def install_if_reported_available=(new_val)
290
339
  return nil if new_val == @install_if_reported_available
291
340
  new_val = false if new_val.to_s.empty?
@@ -294,37 +343,37 @@ module JSS
294
343
  @need_to_update = true
295
344
  end
296
345
 
297
- ### Change the notes field in the JSS.NewLines are converted \r.
298
- ###
299
- ### @param new_val[String]
300
- ###
301
- ### @return [void]
302
- ###
346
+ # Change the notes field in the JSS.NewLines are converted \r.
347
+ #
348
+ # @param new_val[String]
349
+ #
350
+ # @return [void]
351
+ #
303
352
  def notes=(new_val)
304
353
  return nil if new_val == @notes
305
- ### line breaks should be \r
354
+ # line breaks should be \r
306
355
  new_val = new_val.to_s.tr("\n", "\r")
307
356
  @notes = new_val
308
357
  @need_to_update = true
309
358
  end
310
359
 
311
- ### Change the os_requirements field in the JSS
312
- ### E.g. 10.5, 10.5.3, 10.6.x
313
- ###
314
- ### @param new_val[String,Array] comma-separated string, or array of os versions
315
- ###
316
- ### @return [void]
317
- ###
318
- ### Extra feature: Minumum OS's can now be specified as a
319
- ### string using the notation ">=10.6.7".
320
- ###
321
- ### @see JSS.expand_min_os
322
- ###
360
+ # Change the os_requirements field in the JSS
361
+ # E.g. 10.5, 10.5.3, 10.6.x
362
+ #
363
+ # @param new_val[String,Array] comma-separated string, or array of os versions
364
+ #
365
+ # @return [void]
366
+ #
367
+ # Extra feature: Minumum OS's can now be specified as a
368
+ # string using the notation ">=10.6.7".
369
+ #
370
+ # @see JSS.expand_min_os
371
+ #
323
372
  def os_requirements=(new_val)
324
- ### nil should be an empty array
373
+ # nil should be an empty array
325
374
  new_val = [] if new_val.to_s.empty?
326
375
 
327
- ### if any value starts with >=, expand it
376
+ # if any value starts with >=, expand it
328
377
  case new_val
329
378
  when String
330
379
  new_val = JSS.expand_min_os(new_val) if new_val =~ /^>=/
@@ -335,30 +384,30 @@ module JSS
335
384
  else
336
385
  raise JSS::InvalidDataError, 'os_requirements must be a String or an Array of strings'
337
386
  end
338
- ### get the array version
387
+ # get the array version
339
388
  @os_requirements = JSS.to_s_and_a(new_val)[:arrayform]
340
389
  @need_to_update = true
341
390
  end
342
391
 
343
- ### Is a given OS OK for this package based on its
344
- ### @os_requirements?
345
- ###
346
- ### @param os[String] the os to check, defaults to
347
- ### the os of the current machine.
348
- ###
349
- ### @return [Boolean] can this pkg be installed with the os
350
- ### given?
351
- ###
392
+ # Is a given OS OK for this package based on its
393
+ # @os_requirements?
394
+ #
395
+ # @param os[String] the os to check, defaults to
396
+ # the os of the current machine.
397
+ #
398
+ # @return [Boolean] can this pkg be installed with the os
399
+ # given?
400
+ #
352
401
  def os_ok?(os = nil)
353
402
  JSS.os_ok? @os_requirements, os
354
403
  end
355
404
 
356
- ### Change the priority field in the JSS
357
- ###
358
- ### @param new_val[Integer] one of PRIORITIES
359
- ###
360
- ### @return [void]
361
- ###
405
+ # Change the priority field in the JSS
406
+ #
407
+ # @param new_val[Integer] one of PRIORITIES
408
+ #
409
+ # @return [void]
410
+ #
362
411
  def priority=(new_val)
363
412
  return nil if new_val == @priority
364
413
  new_val = DEFAULT_PRIORITY if new_val.to_s.empty?
@@ -367,12 +416,12 @@ module JSS
367
416
  @need_to_update = true
368
417
  end
369
418
 
370
- ### Change the reboot-required field in the JSS
371
- ###
372
- ### @param new_val[Boolean]
373
- ###
374
- ### @return [void]
375
- ###
419
+ # Change the reboot-required field in the JSS
420
+ #
421
+ # @param new_val[Boolean]
422
+ #
423
+ # @return [void]
424
+ #
376
425
  def reboot_required=(new_val)
377
426
  return nil if new_val == @reboot_required
378
427
  new_val = false if new_val.to_s.empty?
@@ -381,12 +430,12 @@ module JSS
381
430
  @need_to_update = true
382
431
  end
383
432
 
384
- ### Change the required processor field in the JSS
385
- ###
386
- ### @param new_val[String] one of {CPU_TYPES}
387
- ###
388
- ### @return [void]
389
- ###
433
+ # Change the required processor field in the JSS
434
+ #
435
+ # @param new_val[String] one of {CPU_TYPES}
436
+ #
437
+ # @return [void]
438
+ #
390
439
  def required_processor=(new_val)
391
440
  return nil if new_val == @required_processor
392
441
 
@@ -397,25 +446,25 @@ module JSS
397
446
  @need_to_update = true
398
447
  end
399
448
 
400
- ### Is a given processor OK for this package based on its
401
- ### @required_processor?
402
- ###
403
- ### @param processor[String] the processor to check, defaults to
404
- ### the processor of the current machine.
405
- ###
406
- ### @return [Boolean] can this pkg be installed with the processor
407
- ### given?
408
- ###
449
+ # Is a given processor OK for this package based on its
450
+ # @required_processor?
451
+ #
452
+ # @param processor[String] the processor to check, defaults to
453
+ # the processor of the current machine.
454
+ #
455
+ # @return [Boolean] can this pkg be installed with the processor
456
+ # given?
457
+ #
409
458
  def processor_ok?(processor = nil)
410
459
  JSS.processor_ok? @required_processor, processor
411
460
  end
412
461
 
413
- ### Change the notify field in the JSS
414
- ###
415
- ### @param new_val[Boolean]
416
- ###
417
- ### @return [void]
418
- ###
462
+ # Change the notify field in the JSS
463
+ #
464
+ # @param new_val[Boolean]
465
+ #
466
+ # @return [void]
467
+ #
419
468
  def send_notification=(new_val)
420
469
  return nil if new_val == @send_notification
421
470
  new_val = false if new_val.to_s.empty?
@@ -424,12 +473,12 @@ module JSS
424
473
  @need_to_update = true
425
474
  end
426
475
 
427
- ### Change which pkg should be installed if this one can't.
428
- ###
429
- ### @param new_val[String] the name of an existing package or "Do Not Install"
430
- ###
431
- ### @return [void]
432
- ###
476
+ # Change which pkg should be installed if this one can't.
477
+ #
478
+ # @param new_val[String] the name of an existing package or "Do Not Install"
479
+ #
480
+ # @return [void]
481
+ #
433
482
  def switch_with_package=(new_val)
434
483
  return nil if new_val == @switch_with_package
435
484
  new_val = nil if new_val.to_s.empty?
@@ -441,34 +490,34 @@ module JSS
441
490
  @need_to_update = true
442
491
  end
443
492
 
444
- ### Is this packaged installed on the current machine (via casper)?
445
- ### We just look for the receipt, which is the @filename less any possible .zip extension.
446
- ###
447
- ### @return [Boolean]
448
- ###
493
+ # Is this packaged installed on the current machine (via casper)?
494
+ # We just look for the receipt, which is the @filename less any possible .zip extension.
495
+ #
496
+ # @return [Boolean]
497
+ #
449
498
  def installed?
450
499
  @receipt.file?
451
500
  end
452
501
 
453
- ### Upload a locally-readable file to the master distribution point.
454
- ### If the file is a directory (like a bundle .pk/.mpkg) it will be zipped before
455
- ### uploading and the @filename will be adjusted accordingly by adding a .zip extension
456
- ###
457
- ### The name of the local file doesn't matter, the file on the dist. point will
458
- ### use the @filename (possibly with .zip)
459
- ###
460
- ### If you'll be uploading several files you can specify unmount as false, and do it manually when all
461
- ### are finished with JSS::DistributionPoint.master_distribution_point.unmount
462
- ###
463
- ### @param local_file_path[String,Pathname] the local path to the file to be uploaded
464
- ###
465
- ### @param rw_pw[String,Symbol] the password for the read/write account on the master Distribution Point,
466
- ### or :prompt, or :stdin# where # is the line of stdin containing the password See {JSS::DistributionPoint#mount}
467
- ###
468
- ### @param unmount[Boolean] whether or not ot unount the distribution point when finished.
469
- ###
470
- ### @return [void]
471
- ###
502
+ # Upload a locally-readable file to the master distribution point.
503
+ # If the file is a directory (like a bundle .pk/.mpkg) it will be zipped before
504
+ # uploading and the @filename will be adjusted accordingly by adding a .zip extension
505
+ #
506
+ # The name of the local file doesn't matter, the file on the dist. point will
507
+ # use the @filename (possibly with .zip)
508
+ #
509
+ # If you'll be uploading several files you can specify unmount as false, and do it manually when all
510
+ # are finished with JSS::DistributionPoint.master_distribution_point.unmount
511
+ #
512
+ # @param local_file_path[String,Pathname] the local path to the file to be uploaded
513
+ #
514
+ # @param rw_pw[String,Symbol] the password for the read/write account on the master Distribution Point,
515
+ # or :prompt, or :stdin# where # is the line of stdin containing the password See {JSS::DistributionPoint#mount}
516
+ #
517
+ # @param unmount[Boolean] whether or not ot unount the distribution point when finished.
518
+ #
519
+ # @return [void]
520
+ #
472
521
  def upload_master_file(local_file_path, rw_pw, unmount = true)
473
522
  raise JSS::NoSuchItemError, 'Please create this package in the JSS before uploading it.' unless @in_jss
474
523
 
@@ -478,15 +527,15 @@ module JSS
478
527
  local_path = Pathname.new local_file_path
479
528
  raise JSS::NoSuchItemError, "Local file '#{@local_file}' doesn't exist" unless local_path.exist?
480
529
 
481
- ### should we zip it?
530
+ # should we zip it?
482
531
  if local_path.directory?
483
532
  begin
484
- ### go to the same dir as the local file
533
+ # go to the same dir as the local file
485
534
  wd = Dir.pwd
486
535
  Dir.chdir local_path.parent
487
536
 
488
- ### the contents of the zip file have to have the same name as the zip file itself (minus the .zip)
489
- ### so temporarily rename the source
537
+ # the contents of the zip file have to have the same name as the zip file itself (minus the .zip)
538
+ # so temporarily rename the source
490
539
  local_path_to_upload = local_path.parent + @filename
491
540
  local_path.rename local_path_to_upload unless local_path_to_upload == local_path
492
541
 
@@ -496,15 +545,14 @@ module JSS
496
545
  zipfile = zipdir + (local_path_to_upload.basename.to_s + '.zip')
497
546
 
498
547
  raise 'There was a problem zipping the pkg bundle' unless system "/usr/bin/zip -qr '#{zipfile}' '#{local_path_to_upload}'"
499
-
500
548
  ensure
501
- ### rename the source to the original name
549
+ # rename the source to the original name
502
550
  local_path_to_upload.rename local_path if local_path_to_upload.exist? && local_path_to_upload != local_path
503
- ### go back where we started
551
+ # go back where we started
504
552
  Dir.chdir wd
505
553
  end # begin
506
554
 
507
- ### update our info
555
+ # update our info
508
556
  local_path = zipfile
509
557
  destination = destination.to_s + '.zip'
510
558
  @filename = zipfile.basename.to_s
@@ -517,19 +565,19 @@ module JSS
517
565
  mdp.unmount if unmount
518
566
  end # upload
519
567
 
520
- ### Change the name of a package file on the master distribution point.
521
- ###
522
- ### @param new_file_name[String]
523
- ###
524
- ### @param old_file_name[default: @filename, String]
525
- ###
526
- ### @param unmount[Boolean] whether or not ot unount the distribution point when finished.
527
- ###
528
- ### @param rw_pw[String,Symbol] the password for the read/write account on the master Distribution Point,
529
- ### or :prompt, or :stdin# where # is the line of stdin containing the password See {JSS::DistributionPoint#mount}
530
- ###
531
- ### @return [nil]
532
- ###
568
+ # Change the name of a package file on the master distribution point.
569
+ #
570
+ # @param new_file_name[String]
571
+ #
572
+ # @param old_file_name[default: @filename, String]
573
+ #
574
+ # @param unmount[Boolean] whether or not ot unount the distribution point when finished.
575
+ #
576
+ # @param rw_pw[String,Symbol] the password for the read/write account on the master Distribution Point,
577
+ # or :prompt, or :stdin# where # is the line of stdin containing the password See {JSS::DistributionPoint#mount}
578
+ #
579
+ # @return [nil]
580
+ #
533
581
  def update_master_filename(old_file_name, new_file_name, rw_pw, unmount = true)
534
582
  raise JSS::NoSuchItemError, "#{old_file_name} does not exist in the jss." unless @in_jss
535
583
  mdp = JSS::DistributionPoint.master_distribution_point api: @api
@@ -539,7 +587,7 @@ module JSS
539
587
  old_file.exist?
540
588
 
541
589
  new_file = pkgs_dir + new_file_name
542
- ### use the extension of the original file.
590
+ # use the extension of the original file.
543
591
  new_file = pkgs_dir + (new_file_name + old_file.extname) if new_file.extname.empty?
544
592
 
545
593
  old_file.rename new_file
@@ -547,18 +595,18 @@ module JSS
547
595
  nil
548
596
  end # update_master_filename
549
597
 
550
- ### Delete the filename from the master distribution point, if it exists.
551
- ###
552
- ### If you'll be uploading several files you can specify unmount as false, and do it manually when all
553
- ### are finished.
554
- ###
555
- ### @param rw_pw[String] the password for the read/write account on the master Distribution Point
556
- ### or :prompt, or :stdin# where # is the line of stdin containing the password. See {JSS::DistributionPoint#mount}
557
- ###
558
- ### @param unmount[Boolean] whether or not ot unount the distribution point when finished.
559
- ###
560
- ### @return [Boolean] was the file deleted?
561
- ###
598
+ # Delete the filename from the master distribution point, if it exists.
599
+ #
600
+ # If you'll be uploading several files you can specify unmount as false, and do it manually when all
601
+ # are finished.
602
+ #
603
+ # @param rw_pw[String] the password for the read/write account on the master Distribution Point
604
+ # or :prompt, or :stdin# where # is the line of stdin containing the password. See {JSS::DistributionPoint#mount}
605
+ #
606
+ # @param unmount[Boolean] whether or not ot unount the distribution point when finished.
607
+ #
608
+ # @return [Boolean] was the file deleted?
609
+ #
562
610
  def delete_master_file(rw_pw, unmount = true)
563
611
  mdp = JSS::DistributionPoint.master_distribution_point api: @api
564
612
  file = mdp.mount(rw_pw, :rw) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}"
@@ -572,61 +620,61 @@ module JSS
572
620
  did_it
573
621
  end # delete master file
574
622
 
575
- ### Delete this package from the JSS, optionally
576
- ### deleting the master dist point file also.
577
- ###
578
- ### @param delete_file[Boolean] should the master dist point file be deleted?
579
- ###
580
- ### @param rw_pw[String] the password for the read/write account on the master Distribution Point
581
- ### or :prompt, or :stdin# where # is the line of stdin containing the password. See {JSS::DistributionPoint#mount}
582
- ###
583
- ### @param unmount[Boolean] whether or not ot unount the distribution point when finished.
584
- ###
623
+ # Delete this package from the JSS, optionally
624
+ # deleting the master dist point file also.
625
+ #
626
+ # @param delete_file[Boolean] should the master dist point file be deleted?
627
+ #
628
+ # @param rw_pw[String] the password for the read/write account on the master Distribution Point
629
+ # or :prompt, or :stdin# where # is the line of stdin containing the password. See {JSS::DistributionPoint#mount}
630
+ #
631
+ # @param unmount[Boolean] whether or not ot unount the distribution point when finished.
632
+ #
585
633
  def delete(delete_file: false, rw_pw: nil, unmount: true)
586
634
  super()
587
635
  delete_master_file(rw_pw, unmount) if delete_file
588
636
  end
589
637
 
590
- ### Install this package via the jamf binary 'install' command from the
591
- ### distribution point for this machine.
592
- ### See {JSS::DistributionPoint.my_distribution_point}
593
- ###
594
- ### @note This code must be run as root to install packages
595
- ###
596
- ### The read-only or http passwd for the dist. point must be provided,
597
- ### except for non-authenticated http downloads)
598
- ###
599
- ### @param args[Hash] the arguments for installation
600
- ###
601
- ### @option args :ro_pw[String] the read-only or http password for the
602
- ### distribution point for the local machine
603
- ### (http will be used if available, and may not need a pw)
604
- ###
605
- ### @option args :target[String,Pathname] The drive on which to install
606
- ### the package, defaults to '/'
607
- ###
608
- ### @option args :verbose [Boolean] be verbose to stdout, defaults to false
609
- ###
610
- ### @option args :feu[Boolean] fill existing users, defaults to false
611
- ###
612
- ### @option args :fut[Boolean] fill user template, defaults to false
613
- ###
614
- ### @option args :unmount[Boolean] unmount the distribution point when
615
- ### finished?(if we mounted it), defaults to false
616
- ###
617
- ### @option args :no_http[Boolean] don't use http downloads even if they
618
- ### are enabled for the dist. point.
619
- ###
620
- ### @option args :alt_download_url [String] Use this url for an http
621
- ### download, regardless of distribution point settings. This can be used
622
- ### to access Cloud Distribution Points if the fileshare isn't available.
623
- ### The URL should already be ur
624
- ### The package filename will be removed or appended as needed.
625
- ###
626
- ### @return [Boolean] did the jamf install succeed?
627
- ###
628
- ### @todo deal with cert-based https authentication in dist points
629
- ###
638
+ # Install this package via the jamf binary 'install' command from the
639
+ # distribution point for this machine.
640
+ # See {JSS::DistributionPoint.my_distribution_point}
641
+ #
642
+ # @note This code must be run as root to install packages
643
+ #
644
+ # The read-only or http passwd for the dist. point must be provided,
645
+ # except for non-authenticated http downloads)
646
+ #
647
+ # @param args[Hash] the arguments for installation
648
+ #
649
+ # @option args :ro_pw[String] the read-only or http password for the
650
+ # distribution point for the local machine
651
+ # (http will be used if available, and may not need a pw)
652
+ #
653
+ # @option args :target[String,Pathname] The drive on which to install
654
+ # the package, defaults to '/'
655
+ #
656
+ # @option args :verbose [Boolean] be verbose to stdout, defaults to false
657
+ #
658
+ # @option args :feu[Boolean] fill existing users, defaults to false
659
+ #
660
+ # @option args :fut[Boolean] fill user template, defaults to false
661
+ #
662
+ # @option args :unmount[Boolean] unmount the distribution point when
663
+ # finished?(if we mounted it), defaults to false
664
+ #
665
+ # @option args :no_http[Boolean] don't use http downloads even if they
666
+ # are enabled for the dist. point.
667
+ #
668
+ # @option args :alt_download_url [String] Use this url for an http
669
+ # download, regardless of distribution point settings. This can be used
670
+ # to access Cloud Distribution Points if the fileshare isn't available.
671
+ # The URL should already be ur
672
+ # The package filename will be removed or appended as needed.
673
+ #
674
+ # @return [Boolean] did the jamf install succeed?
675
+ #
676
+ # @todo deal with cert-based https authentication in dist points
677
+ #
630
678
  def install(args = {})
631
679
  raise JSS::UnsupportedError, 'You must have root privileges to install packages' unless JSS.superuser?
632
680
 
@@ -656,7 +704,7 @@ module JSS
656
704
  else
657
705
  mdp = JSS::DistributionPoint.my_distribution_point api: @api
658
706
 
659
- ### how do we access our dist. point? with http?
707
+ # how do we access our dist. point? with http?
660
708
  if mdp.http_downloads_enabled && !(args[:no_http])
661
709
  using_http = true
662
710
  src_path = mdp.http_url
@@ -682,14 +730,14 @@ module JSS
682
730
  src_path += @filename.to_s unless no_filename_in_url
683
731
  end
684
732
 
685
- ### are we doing "fill existing users" or "fill user template"?
733
+ # are we doing "fill existing users" or "fill user template"?
686
734
  do_feu = args[:feu] ? '-feu' : ''
687
735
  do_fut = args[:fut] ? '-fut' : ''
688
736
 
689
- ### the install args for jamf
737
+ # the install args for jamf
690
738
  command_args = "-package '#{@filename}' -path '#{src_path}' -target '#{args[:target]}' #{do_feu} #{do_fut} -showProgress -verbose"
691
739
 
692
- ### run it via a client cmd
740
+ # run it via a client cmd
693
741
  install_out = JSS::Client.run_jamf :install, command_args, args[:verbose]
694
742
 
695
743
  install_out =~ %r{<exitCode>(\d+)</exitCode>}
@@ -703,22 +751,22 @@ module JSS
703
751
  install_exit.zero? ? true : false
704
752
  end
705
753
 
706
- ### Uninstall this pkg via the jamf command.
707
- ###
708
- ### @param args[Hash] the arguments for installation
709
- ###
710
- ### @option args :target[String,Pathname] The drive from which to uninstall the package, defaults to '/'
711
- ###
712
- ### @option args :verbose[Boolean] be verbose to stdout, defaults to false
713
- ###
714
- ### @option args :feu[Boolean] fill existing users, defaults to false
715
- ###
716
- ### @option args :fut[Boolean] fill user template, defaults to false
717
- ###
718
- ### @return [Process::Status] the result of the 'jamf uninstall' command
719
- ###
720
- ### @note This code must be run as root to uninstall packages
721
- ###
754
+ # Uninstall this pkg via the jamf command.
755
+ #
756
+ # @param args[Hash] the arguments for installation
757
+ #
758
+ # @option args :target[String,Pathname] The drive from which to uninstall the package, defaults to '/'
759
+ #
760
+ # @option args :verbose[Boolean] be verbose to stdout, defaults to false
761
+ #
762
+ # @option args :feu[Boolean] fill existing users, defaults to false
763
+ #
764
+ # @option args :fut[Boolean] fill user template, defaults to false
765
+ #
766
+ # @return [Process::Status] the result of the 'jamf uninstall' command
767
+ #
768
+ # @note This code must be run as root to uninstall packages
769
+ #
722
770
  def uninstall(args = {})
723
771
  unless removable?
724
772
  raise JSS::UnsupportedError, \
@@ -727,23 +775,23 @@ module JSS
727
775
  raise JSS::UnsupportedError, 'You must have root privileges to uninstall packages' unless JSS.superuser?
728
776
  args[:target] ||= '/'
729
777
 
730
- ### are we doing "fill existing users" or "fill user template"?
778
+ # are we doing "fill existing users" or "fill user template"?
731
779
  do_feu = args[:feu] ? '-feu' : ''
732
780
  do_fut = args[:fut] ? '-fut' : ''
733
781
 
734
- ### use jamf binary to uninstall the pkg
782
+ # use jamf binary to uninstall the pkg
735
783
  jamf_opts = "-target '#{args[:target]}' -id '#{@id}' #{do_feu} #{do_fut}"
736
784
 
737
- ### run it via a client
785
+ # run it via a client
738
786
  JSS::Client.run_jamf 'uninstall', jamf_opts, args[:verbose]
739
787
 
740
788
  $CHILD_STATUS
741
789
  end
742
790
 
743
- ### What type of package is this?
744
- ###
745
- ### @return [Symbol] :pkg or :dmg or:unknown
746
- ###
791
+ # What type of package is this?
792
+ #
793
+ # @return [Symbol] :pkg or :dmg or:unknown
794
+ #
747
795
  def type
748
796
  case @filename
749
797
  when /\.m?pkg(\.zip)?$/ then :pkg
@@ -752,7 +800,7 @@ module JSS
752
800
  end
753
801
  end
754
802
 
755
- ### Aliases
803
+ # Aliases
756
804
  ################################
757
805
 
758
806
  # aliases under their methods seem to confuse the YARD documenter, so I'm putting them all here.
@@ -782,14 +830,14 @@ module JSS
782
830
  alias cpu_type= required_processor=
783
831
  alias notify= send_notification=
784
832
 
785
- ### Private Instance Methods
833
+ # Private Instance Methods
786
834
  ################################
787
835
 
788
836
  private
789
837
 
790
- ### Return the REST XML for this pkg, with the current values,
791
- ### for saving or updating
792
- ###
838
+ # Return the REST XML for this pkg, with the current values,
839
+ # for saving or updating
840
+ #
793
841
  def rest_xml
794
842
  doc = REXML::Document.new APIConnection::XML_HEADER
795
843
  pkg = doc.add_element 'package'