depot3 3.0.15 → 3.0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +21 -1
- data/README.md +6 -6
- data/bin/d3 +3 -3
- data/bin/d3admin +257 -293
- data/lib/d3/admin/add.rb +98 -94
- data/lib/d3/admin/interactive.rb +195 -161
- data/lib/d3/admin/options.rb +424 -412
- data/lib/d3/admin/prefs.rb +73 -42
- data/lib/d3/admin/validate.rb +50 -43
- data/lib/d3/client/auth.rb +4 -2
- data/lib/d3/client/class_methods.rb +169 -119
- data/lib/d3/client/receipt.rb +2 -2
- data/lib/d3/database.rb +167 -180
- data/lib/d3/log.rb +2 -3
- data/lib/d3/package/server_actions.rb +2 -3
- data/lib/d3/package/validate.rb +63 -70
- data/lib/d3/version.rb +1 -2
- metadata +2 -2
data/lib/d3/admin/add.rb
CHANGED
@@ -24,6 +24,7 @@
|
|
24
24
|
|
25
25
|
###
|
26
26
|
module D3
|
27
|
+
|
27
28
|
module Admin
|
28
29
|
|
29
30
|
### The Admin::Add modile contains constants and methods related to
|
@@ -34,35 +35,35 @@ module D3
|
|
34
35
|
|
35
36
|
### These are the symbols representing all the possible commandline options
|
36
37
|
### used for defining new packages.
|
37
|
-
NEW_PKG_OPTIONS = %
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
38
|
+
NEW_PKG_OPTIONS = %i(
|
39
|
+
version
|
40
|
+
revision
|
41
|
+
package_name
|
42
|
+
description
|
43
|
+
filename
|
44
|
+
category
|
45
|
+
oses
|
46
|
+
cpu_type
|
47
|
+
reboot
|
48
|
+
removable
|
49
|
+
remove_first
|
50
|
+
prohibiting_processes
|
51
|
+
auto_groups
|
52
|
+
excluded_groups
|
53
|
+
pre_install
|
54
|
+
post_install
|
55
|
+
pre_remove
|
56
|
+
post_remove
|
57
|
+
expiration
|
58
|
+
expiration_paths
|
59
|
+
source_path
|
60
|
+
).freeze
|
60
61
|
|
61
62
|
### If we need to build the pkg, these options are needed
|
62
|
-
BUILD_OPTIONS = [:workspace, :package_build_type]
|
63
|
+
BUILD_OPTIONS = [:workspace, :package_build_type].freeze
|
63
64
|
|
64
65
|
### If we are building a .pkg these options are needed
|
65
|
-
PKG_OPTIONS = [:pkg_identifier, :pkg_preserve_owners]
|
66
|
+
PKG_OPTIONS = [:pkg_identifier, :pkg_preserve_owners, :signing_identity, :signing_options].freeze
|
66
67
|
|
67
68
|
### Continuously loop through displaying the add-package menu, and getting
|
68
69
|
### new values, until the user types 'x'.
|
@@ -71,39 +72,36 @@ module D3
|
|
71
72
|
###
|
72
73
|
### @return [OpenStruct] the new_package_options with validated data
|
73
74
|
###
|
74
|
-
def loop_thru_add_walkthru
|
75
|
-
|
76
|
-
inherited_line = options.inherited_from ? "with values inherited from '#{options.inherited_from}'" : "with global default values"
|
77
|
-
|
78
|
-
|
75
|
+
def loop_thru_add_walkthru(options)
|
76
|
+
inherited_line = options.inherited_from ? "with values inherited from '#{options.inherited_from}'" : 'with global default values'
|
79
77
|
|
80
78
|
choice = nil
|
81
79
|
|
82
80
|
# loop until the user types an x
|
83
|
-
while choice !=
|
81
|
+
while choice != 'x'
|
84
82
|
walkthru_menu_header = <<-END_HEADER
|
85
83
|
------------------------------------
|
86
|
-
Adding pilot d3 package '#{options.edition
|
84
|
+
Adding pilot d3 package '#{options.edition || options.basename}'
|
87
85
|
#{inherited_line}
|
88
86
|
------------------------------------
|
89
87
|
END_HEADER
|
90
88
|
menu_options = NEW_PKG_OPTIONS
|
91
|
-
if options.source_path
|
89
|
+
if options.source_path && get_package_type_from_source(options.source_path) == :root_folder
|
92
90
|
menu_options += BUILD_OPTIONS
|
93
91
|
menu_options += PKG_OPTIONS if options.package_build_type == :pkg
|
94
92
|
end
|
95
93
|
|
96
|
-
choice = D3::Admin::Interactive.get_menu_choice(
|
94
|
+
choice = D3::Admin::Interactive.get_menu_choice(walkthru_menu_header, walkthru_menu_lines(menu_options, options))
|
97
95
|
|
98
96
|
if choice == 'x'
|
99
97
|
(options, errors) = validate_all_new_package_options options
|
100
98
|
if errors.empty?
|
101
99
|
break # while
|
102
100
|
else
|
103
|
-
puts
|
101
|
+
puts '***** ERRORS *****'
|
104
102
|
puts errors.join "\n"
|
105
|
-
puts
|
106
|
-
puts
|
103
|
+
puts '*****'
|
104
|
+
puts 'Type return to continue, ^c to exit'
|
107
105
|
gets
|
108
106
|
choice = 'not x'
|
109
107
|
end # if errors empty
|
@@ -115,10 +113,9 @@ END_HEADER
|
|
115
113
|
# Here the value we're actually editing
|
116
114
|
current_opt_value = options[chosen_opt]
|
117
115
|
|
118
|
-
|
119
116
|
# if we're editing version or revision, and the current pkg or filenames are
|
120
117
|
# based on them then make a note to update the names when we get the new values
|
121
|
-
if chosen_opt == :basename
|
118
|
+
if chosen_opt == :basename || chosen_opt == :version || chosen_opt == :revision
|
122
119
|
update_edition = true
|
123
120
|
update_pkg_name = options.package_name.start_with? options.edition
|
124
121
|
update_filename = options.filename.start_with? options.edition
|
@@ -130,7 +127,7 @@ END_HEADER
|
|
130
127
|
|
131
128
|
# if editing the source or the buildtype, we might have to update the
|
132
129
|
# names as well
|
133
|
-
if chosen_opt == :source_path
|
130
|
+
if chosen_opt == :source_path || chosen_opt == :package_build_type
|
134
131
|
update_pkg_name = options.package_name =~ /\.(m?pkg|dmg)$/
|
135
132
|
update_filename = true
|
136
133
|
end
|
@@ -139,7 +136,7 @@ END_HEADER
|
|
139
136
|
options[chosen_opt] = D3::Admin::Interactive.get_value(chosen_opt, current_opt_value, nil)
|
140
137
|
|
141
138
|
# if we changed the version, reset the revision to 1 and update values as needed
|
142
|
-
if chosen_opt == :version
|
139
|
+
if chosen_opt == :version && options[chosen_opt] != current_opt_value
|
143
140
|
options[:revision] = 1
|
144
141
|
update_edition = true
|
145
142
|
update_pkg_name = options.package_name.start_with? options.edition
|
@@ -152,10 +149,10 @@ END_HEADER
|
|
152
149
|
options.filename = "#{options.edition}.#{options.package_build_type}" if update_filename
|
153
150
|
|
154
151
|
# if we edited the source path, we might need to update the names and the pkg build type
|
155
|
-
if chosen_opt == :source_path
|
152
|
+
if chosen_opt == :source_path && options.source_path.extname =~ /\.(m?pkg|dmg)$/
|
156
153
|
options.package_name.sub(/\.(m?pkg|dmg)$/, options.source_path.extname)
|
157
154
|
options.filename.sub(/\.(m?pkg|dmg)$/, options.source_path.extname)
|
158
|
-
options.package_build_type = options.source_path.extname ==
|
155
|
+
options.package_build_type = options.source_path.extname == '.dmg' ? :dmg : :pkg
|
159
156
|
end
|
160
157
|
|
161
158
|
# ditto if we edited the package_build_type
|
@@ -164,12 +161,11 @@ END_HEADER
|
|
164
161
|
options.filename.sub(/\.(m?pkg|dmg)$/, options.package_build_type.to_s)
|
165
162
|
end
|
166
163
|
|
167
|
-
end #if choice == x
|
164
|
+
end # if choice == x
|
168
165
|
end # while choice not x
|
169
166
|
|
170
167
|
# return the options
|
171
168
|
options
|
172
|
-
|
173
169
|
end # loop_thru_add_walkthru
|
174
170
|
|
175
171
|
### Regenerate the walkthru menu lines
|
@@ -181,12 +177,12 @@ END_HEADER
|
|
181
177
|
###
|
182
178
|
### @return [Array<String>] the lines of the walkthru menu
|
183
179
|
###
|
184
|
-
def walkthru_menu_lines
|
180
|
+
def walkthru_menu_lines(menu_options, current_options)
|
185
181
|
display_lines = []
|
186
182
|
|
187
183
|
menu_options.each_index do |i|
|
188
184
|
# the option symbol, like :reboot
|
189
|
-
#opt = NEW_PKG_OPTIONS[i]
|
185
|
+
# opt = NEW_PKG_OPTIONS[i]
|
190
186
|
opt = menu_options[i]
|
191
187
|
opt_def = D3::Admin::OPTIONS[opt]
|
192
188
|
label = opt_def[:label]
|
@@ -195,7 +191,7 @@ END_HEADER
|
|
195
191
|
value_display = converter ? converter.call(value) : value
|
196
192
|
display_lines[i] = "#{label}: #{value_display}"
|
197
193
|
end
|
198
|
-
|
194
|
+
display_lines
|
199
195
|
end # def walkthru_menu_lines
|
200
196
|
|
201
197
|
### Validate commandline options when adding a package without walkthru
|
@@ -210,17 +206,17 @@ END_HEADER
|
|
210
206
|
###
|
211
207
|
### @return [OpenStruct] the new_package_options with validated data
|
212
208
|
###
|
213
|
-
def add_pilot_cli
|
214
|
-
(new_package_options, errors) = validate_all_new_package_options
|
209
|
+
def add_pilot_cli(cli_options)
|
210
|
+
(new_package_options, errors) = validate_all_new_package_options(cli_options)
|
215
211
|
if errors.empty?
|
216
212
|
return new_package_options
|
217
213
|
else
|
218
|
-
puts
|
214
|
+
puts '***** ERRORS *****'
|
219
215
|
puts errors.join "\n"
|
220
|
-
puts
|
221
|
-
raise ArgumentError,
|
216
|
+
puts '*****'
|
217
|
+
raise ArgumentError, 'Errors in commandline options, see above.'
|
222
218
|
end # if errors empty
|
223
|
-
end #validate_cli_add_pilot
|
219
|
+
end # validate_cli_add_pilot
|
224
220
|
|
225
221
|
### Validate all possible options for making a new pkg.
|
226
222
|
###
|
@@ -235,11 +231,10 @@ END_HEADER
|
|
235
231
|
### @return [Array<OpenStruct, Array>] An array with two items: the possibly-validated options
|
236
232
|
### and an array of error messages, which should be empty if all options are valid.
|
237
233
|
###
|
238
|
-
def validate_all_new_package_options
|
239
|
-
|
234
|
+
def validate_all_new_package_options(options_from_user)
|
240
235
|
# what do we need to check
|
241
236
|
opts_to_check = NEW_PKG_OPTIONS
|
242
|
-
if options_from_user.source_path
|
237
|
+
if options_from_user.source_path && get_package_type_from_source(options_from_user.source_path) == :root_folder
|
243
238
|
opts_to_check += BUILD_OPTIONS
|
244
239
|
opts_to_check += PKG_OPTIONS if options_from_user.package_build_type == :pkg
|
245
240
|
end
|
@@ -273,16 +268,16 @@ END_HEADER
|
|
273
268
|
|
274
269
|
# group overlaps
|
275
270
|
begin
|
276
|
-
|
271
|
+
D3::Package::Validate.validate_non_overlapping_groups options_from_user[:auto_groups], options_from_user[:excluded_groups]
|
277
272
|
rescue JSS::InvalidDataError
|
278
|
-
|
273
|
+
errors << "Auto and Excluded group-lists can't contain groups in common."
|
279
274
|
end
|
280
275
|
|
281
276
|
# expiration path if expiration
|
282
277
|
if options_from_user[:expiration] > 0
|
283
|
-
|
278
|
+
errors << 'expiration path cannot be empty if expiration is > 0 .' unless options_from_user[:expiration_paths]
|
284
279
|
end
|
285
|
-
|
280
|
+
[options_from_user, errors]
|
286
281
|
end # validate_all_new_package_options
|
287
282
|
|
288
283
|
### Figure out the default values for all options for creating a new package
|
@@ -296,7 +291,7 @@ END_HEADER
|
|
296
291
|
dft_opts = OpenStruct.new
|
297
292
|
|
298
293
|
# first populate the opts from the defined defaults for anything that's still nil
|
299
|
-
D3::Admin::OPTIONS.each {|opt, settings| dft_opts[opt] = settings[:default]}
|
294
|
+
D3::Admin::OPTIONS.each { |opt, settings| dft_opts[opt] = settings[:default] }
|
300
295
|
|
301
296
|
dft_opts.basename = basename
|
302
297
|
|
@@ -313,7 +308,7 @@ END_HEADER
|
|
313
308
|
end # if basename
|
314
309
|
|
315
310
|
# edition if available
|
316
|
-
if dft_opts.version
|
311
|
+
if dft_opts.version && dft_opts.revision
|
317
312
|
dft_opts.edition = "#{dft_opts.basename}-#{dft_opts.version}-#{dft_opts.revision}"
|
318
313
|
else
|
319
314
|
dft_opts.edition = nil
|
@@ -330,15 +325,16 @@ END_HEADER
|
|
330
325
|
dft_opts.workspace = D3::Admin::Prefs.prefs[:workspace]
|
331
326
|
dft_opts.workspace ||= D3::Admin::DFT_WORKSPACE
|
332
327
|
|
333
|
-
|
334
328
|
# use the pkg_identifier_prefix from the prefs
|
335
329
|
pfx = D3::Admin::Prefs.prefs[:apple_pkg_id_prefix]
|
336
330
|
pfx ||= D3::Admin::DFT_PKG_ID_PREFIX
|
337
331
|
dft_opts.pkg_identifier ||= "#{pfx}.#{basename}".gsub(/\.+/, '.')
|
338
332
|
|
339
333
|
# We now have our defaults for a new pkg
|
340
|
-
|
334
|
+
dft_opts.signing_identity = D3::Admin::Prefs.prefs[:signing_identity] || ''
|
335
|
+
dft_opts.signing_options = D3::Admin::Prefs.prefs[:signing_options] || ''
|
341
336
|
|
337
|
+
dft_opts
|
342
338
|
end # populate_default_options
|
343
339
|
|
344
340
|
### Get default values from an existing d3 package, and use them to
|
@@ -352,7 +348,6 @@ END_HEADER
|
|
352
348
|
### @return [OpenStruct] an ostruct with the default values
|
353
349
|
###
|
354
350
|
def default_options_from_package(pkg, dft_opts = OpenStruct.new)
|
355
|
-
|
356
351
|
# populate the opts from the pkg, if the pkg has a value
|
357
352
|
D3::Admin::OPTIONS.keys.each do |opt|
|
358
353
|
next unless pkg.respond_to?(opt)
|
@@ -370,7 +365,7 @@ END_HEADER
|
|
370
365
|
|
371
366
|
# grab the first pkg-id if it exists
|
372
367
|
# we might use it to if making a new pkg
|
373
|
-
if pkg.apple_receipt_data
|
368
|
+
if pkg.apple_receipt_data && pkg.apple_receipt_data[0] && pkg.apple_receipt_data[0][:apple_pkg_id]
|
374
369
|
dft_opts.pkg_identifier = pkg.apple_receipt_data[0][:apple_pkg_id]
|
375
370
|
end
|
376
371
|
|
@@ -386,13 +381,13 @@ END_HEADER
|
|
386
381
|
### @return [Symbol] :dmg, :pkg, or :root_folder
|
387
382
|
###
|
388
383
|
def get_package_type_from_source (source_path)
|
389
|
-
if source_path.to_s.end_with?
|
390
|
-
|
384
|
+
if source_path.to_s.end_with? '.dmg'
|
385
|
+
:dmg
|
391
386
|
elsif source_path.to_s =~ /\.m?pkg$/
|
392
|
-
|
387
|
+
:pkg
|
393
388
|
else
|
394
|
-
|
395
|
-
end # if .source_path.to_s.end_with?
|
389
|
+
:root_folder
|
390
|
+
end # if .source_path.to_s.end_with? '.dmg'
|
396
391
|
end
|
397
392
|
|
398
393
|
### Add the new pkg to d3
|
@@ -401,16 +396,17 @@ END_HEADER
|
|
401
396
|
###
|
402
397
|
### @return [Integer] the JSS id of the new package
|
403
398
|
###
|
404
|
-
def add_new_package
|
405
|
-
|
399
|
+
def add_new_package(new_package_options)
|
406
400
|
# new_package_options should now have all the validated data we need to make a new pkg
|
407
|
-
new_pilot = D3::Package.new(
|
408
|
-
:
|
409
|
-
:
|
410
|
-
:
|
411
|
-
:
|
412
|
-
:
|
413
|
-
:
|
401
|
+
new_pilot = D3::Package.new(
|
402
|
+
id: :new,
|
403
|
+
basename: new_package_options.basename,
|
404
|
+
name: new_package_options.package_name,
|
405
|
+
version: new_package_options.version,
|
406
|
+
revision: new_package_options.revision,
|
407
|
+
filename: new_package_options.filename,
|
408
|
+
admin: ENV['USER']
|
409
|
+
)
|
414
410
|
|
415
411
|
D3::Admin::Add::NEW_PKG_OPTIONS.each do |opt|
|
416
412
|
setter = "#{opt}=".to_sym
|
@@ -420,21 +416,28 @@ END_HEADER
|
|
420
416
|
# do we need to build the pkg?
|
421
417
|
unless new_package_options.source_path.extname =~ /\.(m?pkg|dmg)$/
|
422
418
|
if new_package_options.package_build_type == :pkg
|
423
|
-
puts
|
424
|
-
|
419
|
+
puts 'Building .pkg...'
|
420
|
+
|
421
|
+
new_pkg_path = JSS::Composer.mk_pkg(
|
422
|
+
new_package_options.package_name,
|
425
423
|
new_package_options.version,
|
426
424
|
new_package_options.source_path,
|
427
|
-
:
|
428
|
-
:
|
429
|
-
:
|
425
|
+
pkg_id: new_package_options.pkg_identifier,
|
426
|
+
out_dir: new_package_options.workspace,
|
427
|
+
preserve_ownership: new_package_options.pkg_preserve_owners,
|
428
|
+
signing_identity: new_package_options.signing_identity,
|
429
|
+
signing_options: new_package_options.signing_options
|
430
|
+
)
|
430
431
|
|
431
432
|
new_package_options.source_path = new_pkg_path
|
432
433
|
|
433
434
|
elsif new_package_options.package_build_type == :dmg
|
434
|
-
puts
|
435
|
-
new_pkg_path = JSS::Composer.mk_dmg(
|
435
|
+
puts 'Building .dmg...'
|
436
|
+
new_pkg_path = JSS::Composer.mk_dmg(
|
437
|
+
new_package_options.package_name,
|
436
438
|
new_package_options.source_path,
|
437
|
-
new_package_options.workspace
|
439
|
+
new_package_options.workspace
|
440
|
+
)
|
438
441
|
|
439
442
|
new_package_options.source_path = new_pkg_path
|
440
443
|
end # if new_package_options.package_build_type
|
@@ -445,19 +448,20 @@ END_HEADER
|
|
445
448
|
|
446
449
|
new_pkg_id = new_pilot.save
|
447
450
|
|
448
|
-
puts
|
451
|
+
puts 'Indexing...'
|
449
452
|
# make the index - all d3 pkgs are indexed in the JSS
|
450
|
-
new_pilot.mk_index :
|
453
|
+
new_pilot.mk_index local_filepath: new_package_options.source_path
|
451
454
|
|
452
455
|
# upload to dist point
|
453
456
|
# if its a .pkg, the apple rcpt data is updated during the upload
|
454
|
-
puts
|
457
|
+
puts 'Uploading to the Master Distribution Point...'
|
455
458
|
new_pilot.upload_master_file new_package_options.source_path, D3::Admin::Auth.rw_credentials(:dist)[:password]
|
456
459
|
|
457
|
-
|
458
|
-
|
460
|
+
new_pkg_id
|
459
461
|
end # add_new_package
|
460
462
|
|
461
463
|
end # module Add
|
464
|
+
|
462
465
|
end # module Admin
|
466
|
+
|
463
467
|
end # module D3
|
data/lib/d3/admin/interactive.rb
CHANGED
@@ -22,9 +22,9 @@
|
|
22
22
|
###
|
23
23
|
###
|
24
24
|
|
25
|
-
|
26
25
|
###
|
27
26
|
module D3
|
27
|
+
|
28
28
|
module Admin
|
29
29
|
|
30
30
|
### This module contains methods for interacting with the user in the terminal
|
@@ -33,24 +33,24 @@ module D3
|
|
33
33
|
### These methods all return a string of user input, possibly an empty string.
|
34
34
|
###
|
35
35
|
module Interactive
|
36
|
+
|
36
37
|
require 'readline'
|
37
38
|
extend self
|
38
39
|
|
39
40
|
# Set up readline
|
40
41
|
# no spaces at the end of readline completion
|
41
|
-
Readline.completion_append_character =
|
42
|
+
Readline.completion_append_character = ''
|
42
43
|
# names may contain spaces
|
43
|
-
Readline.basic_word_break_characters =
|
44
|
+
Readline.basic_word_break_characters = ''
|
44
45
|
# this appends a / to directories as we auto-complete paths.
|
45
|
-
Readline.completion_proc =
|
46
|
-
files = Dir.glob(str +
|
47
|
-
files.map {|f|
|
46
|
+
Readline.completion_proc = proc do |str|
|
47
|
+
files = Dir.glob(str + '*')
|
48
|
+
files.map { |f| File.directory?(f) ? "#{f}/" : f }
|
48
49
|
end
|
49
50
|
|
51
|
+
UNSET = 'n'.freeze
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
DFT_EDITOR = "/usr/bin/nano -L"
|
53
|
+
DFT_EDITOR = '/usr/bin/nano -L'.freeze
|
54
54
|
|
55
55
|
### Display a menu of numbered choices, and return the user's choice,
|
56
56
|
### or 'x' if the user is done choosing.
|
@@ -61,41 +61,40 @@ module D3
|
|
61
61
|
###
|
62
62
|
### @return [Integer, String] The index of the chosen chosen, or 'x'
|
63
63
|
###
|
64
|
-
def get_menu_choice
|
65
|
-
|
64
|
+
def get_menu_choice(header, items)
|
66
65
|
# add a 1-based number and ) to the start of each line, like 1), and 2)...
|
67
|
-
items.each_index{|i| items[i]
|
66
|
+
items.each_index { |i| items[i] = "#{i + 1}) #{items[i]}" }
|
68
67
|
menu_count = items.count
|
69
68
|
menu_count_display = "(1-#{menu_count}, x=done, ^c=cancel)"
|
70
69
|
|
71
70
|
menu = "#{header}\n#{items.join("\n")}"
|
72
71
|
|
73
72
|
# clear the screen between displays of the menu, so its always at the top.
|
74
|
-
system
|
73
|
+
system 'clear' or system 'cls'
|
75
74
|
puts menu
|
76
|
-
choice =
|
77
|
-
while choice ==
|
75
|
+
choice = ''
|
76
|
+
while choice == ''
|
78
77
|
choice = Readline.readline("Which to change? #{menu_count_display}: ", false)
|
79
78
|
break if choice == 'x'
|
80
79
|
|
81
80
|
# they chose a number..
|
82
81
|
if choice =~ /^\d+$/
|
83
82
|
# map it to one of the editing options
|
84
|
-
choice =
|
83
|
+
choice = choice.to_i - 1
|
85
84
|
# but they might have chosen a higher number than allowws
|
86
|
-
choice =
|
85
|
+
choice = '' unless (0..(menu_count - 1)).cover? choice
|
87
86
|
else
|
88
|
-
choice =
|
87
|
+
choice = ''
|
89
88
|
end
|
90
89
|
|
91
90
|
# tell them they made a bad choice
|
92
|
-
if choice ==
|
91
|
+
if choice == ''
|
93
92
|
puts "\n******* Sorry, invalid choice.\n"
|
94
93
|
next
|
95
94
|
end
|
96
95
|
end # while choice == ""
|
97
96
|
|
98
|
-
|
97
|
+
choice
|
99
98
|
end # get_menu_choice
|
100
99
|
|
101
100
|
### Call one of the get_ methods and do the matching validity check,
|
@@ -114,10 +113,8 @@ module D3
|
|
114
113
|
### @return [Object] the validated data from the user
|
115
114
|
###
|
116
115
|
def get_value(option_or_get_method, default = nil, validate_method = nil)
|
117
|
-
|
118
116
|
# if the option_or_get_method is one of the keys in OPTIONS, then use OPTIONS[get_method][:get] if it exists
|
119
117
|
if D3::Admin::OPTIONS.keys.include?(option_or_get_method)
|
120
|
-
option_to_get = option_or_get_method
|
121
118
|
get_method = D3::Admin::OPTIONS[option_or_get_method][:get]
|
122
119
|
# if we weren't giving a validate method, get it from the OPTIONS
|
123
120
|
validate_method ||= D3::Admin::OPTIONS[option_or_get_method][:validate]
|
@@ -127,7 +124,7 @@ module D3
|
|
127
124
|
|
128
125
|
valid = :start
|
129
126
|
validated = nil
|
130
|
-
until valid === true
|
127
|
+
until valid === true # Keep the ===, trust me. Don't listen to rubocop.
|
131
128
|
puts "\nSorry: #{validated}, Try again.\n" unless valid === :start
|
132
129
|
|
133
130
|
value_input = self.send get_method, default
|
@@ -137,8 +134,8 @@ module D3
|
|
137
134
|
|
138
135
|
(valid, validated) = D3::Admin::Validate.validate(value_input, validate_method)
|
139
136
|
|
140
|
-
end #until valid === true
|
141
|
-
|
137
|
+
end # until valid === true
|
138
|
+
validated
|
142
139
|
end # get value
|
143
140
|
|
144
141
|
### Prompt for user input for an option and return the response.
|
@@ -179,8 +176,7 @@ module D3
|
|
179
176
|
###
|
180
177
|
### @return [String] The data entered by the user, possibly an empty string
|
181
178
|
###
|
182
|
-
def prompt_for_data
|
183
|
-
|
179
|
+
def prompt_for_data(desc: nil, prompt: nil, opt: nil, default: :no_default, required: true)
|
184
180
|
unset_line = nil
|
185
181
|
default_display = default
|
186
182
|
|
@@ -197,26 +193,26 @@ module D3
|
|
197
193
|
|
198
194
|
# some values are special for displaying
|
199
195
|
default_display = case default_display
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
196
|
+
when :no_default then ''
|
197
|
+
when D3::Admin::DFT_REQUIRED then '' # the '---Required---' should only be visible in the menu, not the prompt
|
198
|
+
when D3::Admin::DFT_NONE then UNSET
|
199
|
+
else default_display.to_s
|
200
|
+
end
|
205
201
|
|
206
202
|
data_entered = ''
|
207
203
|
puts "\n#{desc}" if desc
|
208
|
-
prompt ||=
|
209
|
-
hit_return = default_display.empty? ?
|
204
|
+
prompt ||= 'Please enter a value'
|
205
|
+
hit_return = default_display.empty? ? '' : " (Hit return for '#{default_display}' )"
|
210
206
|
prompt_line = "#{prompt}#{hit_return}: "
|
211
207
|
|
212
208
|
while true do
|
213
209
|
data_entered = Readline.readline(prompt_line, false)
|
214
210
|
data_entered = default_display if data_entered == ''
|
215
|
-
break unless required
|
211
|
+
break unless required && data_entered.empty?
|
216
212
|
end
|
217
213
|
# if 'n' was typed for an unsettable option, return nil
|
218
|
-
return nil if opt_def
|
219
|
-
|
214
|
+
return nil if opt_def && opt_def[:unsetable] && data_entered == UNSET
|
215
|
+
data_entered.strip
|
220
216
|
end # prompt_for_data
|
221
217
|
|
222
218
|
### Ask the user for an edition or basename
|
@@ -235,12 +231,12 @@ Enter:
|
|
235
231
|
- 'v' to view a list of all packages with the basenames and editions in d3.
|
236
232
|
END_DESC
|
237
233
|
|
238
|
-
input =
|
239
|
-
while input ==
|
240
|
-
input = prompt_for_data(desc: desc, prompt:
|
241
|
-
D3::Admin::Report.show_all_basenames_and_editions if input ==
|
234
|
+
input = 'v'
|
235
|
+
while input == 'v'
|
236
|
+
input = prompt_for_data(desc: desc, prompt: 'Edition or Basename', default: default, required: true)
|
237
|
+
D3::Admin::Report.show_all_basenames_and_editions if input == 'v'
|
242
238
|
end
|
243
|
-
|
239
|
+
input
|
244
240
|
end # get existing pkg
|
245
241
|
|
246
242
|
### Ask the user for an id or name
|
@@ -248,7 +244,7 @@ Enter:
|
|
248
244
|
###
|
249
245
|
### @return [String] the name or id entered, or nil
|
250
246
|
###
|
251
|
-
def get_jss_package_for_import
|
247
|
+
def get_jss_package_for_import(default = nil)
|
252
248
|
desc = <<-END_DESC
|
253
249
|
IMPORT JSS PACKAGE
|
254
250
|
Enter a package id or display-name for
|
@@ -257,16 +253,16 @@ Enter:
|
|
257
253
|
- 'v' to view a list of all JSS package names not in d3.
|
258
254
|
END_DESC
|
259
255
|
|
260
|
-
input =
|
261
|
-
while input ==
|
262
|
-
input = prompt_for_data(desc: desc, prompt:
|
263
|
-
D3::Admin::Report.show_pkgs_available_for_import if input ==
|
256
|
+
input = 'v'
|
257
|
+
while input == 'v'
|
258
|
+
input = prompt_for_data(desc: desc, prompt: 'JSS id or display name', default: default, required: true)
|
259
|
+
D3::Admin::Report.show_pkgs_available_for_import if input == 'v'
|
264
260
|
end
|
265
|
-
|
261
|
+
input
|
266
262
|
end # get existing pkg
|
267
263
|
|
268
264
|
### get a basename from the user
|
269
|
-
def get_basename
|
265
|
+
def get_basename(default = nil)
|
270
266
|
desc = <<-END_DESC
|
271
267
|
BASENAME
|
272
268
|
Enter a basename.
|
@@ -274,31 +270,31 @@ Enter 'v' to view a list of all basenames in d3 and
|
|
274
270
|
the newest edition for each.
|
275
271
|
END_DESC
|
276
272
|
|
277
|
-
input =
|
278
|
-
while input ==
|
279
|
-
input = prompt_for_data(desc: desc, prompt:
|
280
|
-
D3::Admin::Report.show_all_basenames_and_editions if input ==
|
273
|
+
input = 'v'
|
274
|
+
while input == 'v'
|
275
|
+
input = prompt_for_data(desc: desc, prompt: 'Basename', required: true)
|
276
|
+
D3::Admin::Report.show_all_basenames_and_editions if input == 'v'
|
281
277
|
end
|
282
|
-
|
278
|
+
input
|
283
279
|
end # get basename
|
284
280
|
|
285
281
|
### get a package name from user
|
286
|
-
def get_package_name
|
282
|
+
def get_package_name(default = nil)
|
287
283
|
desc = <<-END_DESC
|
288
284
|
JSS PACKAGE NAME
|
289
285
|
Enter a unique name for this package in d3 and Casper.
|
290
286
|
Enter 'v' to view a list of package names currently in d3.
|
291
287
|
END_DESC
|
292
|
-
input =
|
293
|
-
while input ==
|
288
|
+
input = 'v'
|
289
|
+
while input == 'v'
|
294
290
|
input = prompt_for_data(opt: :package_name, desc: desc, default: default, required: true)
|
295
|
-
D3::Admin::Report.show_existing_package_ids if input ==
|
291
|
+
D3::Admin::Report.show_existing_package_ids if input == 'v'
|
296
292
|
end
|
297
|
-
|
293
|
+
input
|
298
294
|
end # get pkg name
|
299
295
|
|
300
|
-
|
301
|
-
def get_filename
|
296
|
+
### get a package name from user
|
297
|
+
def get_filename(default = nil)
|
302
298
|
desc = <<-END_DESC
|
303
299
|
INSTALLER FILENAME
|
304
300
|
Enter a unique name for this package's installer file
|
@@ -306,12 +302,12 @@ on the master distribution point. The file will be
|
|
306
302
|
renamed to this name on the distribution point.
|
307
303
|
Enter 'v' to see a list of existing pkg filenames in the JSS
|
308
304
|
END_DESC
|
309
|
-
input =
|
310
|
-
while input ==
|
305
|
+
input = 'v'
|
306
|
+
while input == 'v'
|
311
307
|
input = prompt_for_data(opt: :filename, desc: desc, default: default, required: true)
|
312
|
-
D3::Admin::Report.show_existing_package_ids if input ==
|
308
|
+
D3::Admin::Report.show_existing_package_ids if input == 'v'
|
313
309
|
end
|
314
|
-
|
310
|
+
input
|
315
311
|
end # get pkg name
|
316
312
|
|
317
313
|
### Get a version from the user
|
@@ -319,7 +315,7 @@ Enter 'v' to see a list of existing pkg filenames in the JSS
|
|
319
315
|
### @param default[String] the value to use when the user types a return.
|
320
316
|
###
|
321
317
|
### @return [String] the value to use as the version
|
322
|
-
def get_version
|
318
|
+
def get_version(default = nil)
|
323
319
|
desc = <<-END_DESC
|
324
320
|
VERSION
|
325
321
|
Enter a version for this package.
|
@@ -335,7 +331,7 @@ All spaces will be converted to underscores.
|
|
335
331
|
###
|
336
332
|
### @return [String] the value to use as the rev
|
337
333
|
###
|
338
|
-
def get_revision
|
334
|
+
def get_revision(default = nil)
|
339
335
|
desc = <<-END_DESC
|
340
336
|
REVISION
|
341
337
|
Enter a Package revision for this package.
|
@@ -353,16 +349,15 @@ an existing version of a given basename.
|
|
353
349
|
###
|
354
350
|
### @return [String] the desired description
|
355
351
|
###
|
356
|
-
def get_description(current_desc =
|
357
|
-
|
352
|
+
def get_description(current_desc = '')
|
358
353
|
# do we have a current desc to display and possibly keep?
|
359
|
-
current_desc_review =
|
354
|
+
current_desc_review = ''
|
360
355
|
unless current_desc.to_s.empty?
|
361
356
|
current_desc_review = "\n----- Current Description -----\n#{current_desc}\n-------------------------------\n\n"
|
362
357
|
end
|
363
358
|
|
364
359
|
if prefd_editor = D3::Admin::Prefs.prefs[:editor]
|
365
|
-
prefd_editor_choice =
|
360
|
+
prefd_editor_choice = "\n - 'e' to edit using '#{prefd_editor}' "
|
366
361
|
else
|
367
362
|
prefd_editor_choice = ''
|
368
363
|
end
|
@@ -387,26 +382,26 @@ or '#{DFT_EDITOR}' if none is set.
|
|
387
382
|
|
388
383
|
# show it, get response
|
389
384
|
puts input_desc
|
390
|
-
choice = Readline.readline(
|
385
|
+
choice = Readline.readline('Your choice (hit return to keep current desc.): ', false)
|
391
386
|
|
392
387
|
# keep or empty?
|
393
388
|
return current_desc if choice.empty?
|
394
389
|
|
395
|
-
return
|
390
|
+
return '' if choice.casecmp('b').zero?
|
396
391
|
|
397
392
|
# make a tem file, save current into it
|
398
|
-
desc_tmp_file = Pathname.new Tempfile.new(
|
393
|
+
desc_tmp_file = Pathname.new Tempfile.new('d3_description_')
|
399
394
|
desc_tmp_file.jss_save current_desc
|
400
395
|
|
401
396
|
# which editor?
|
402
|
-
if choice.casecmp('e')
|
397
|
+
if choice.casecmp('e').zero?
|
403
398
|
cmd = prefd_editor
|
404
|
-
elsif choice.casecmp('v')
|
405
|
-
cmd =
|
406
|
-
elsif choice.casecmp('m')
|
407
|
-
cmd =
|
408
|
-
elsif choice.casecmp('n')
|
409
|
-
cmd =
|
399
|
+
elsif choice.casecmp('v').zero?
|
400
|
+
cmd = '/usr/bin/vim'
|
401
|
+
elsif choice.casecmp('m').zero?
|
402
|
+
cmd = '/usr/bin/emacs'
|
403
|
+
elsif choice.casecmp('n').zero?
|
404
|
+
cmd = '/usr/bin/nano -L'
|
410
405
|
else
|
411
406
|
cmd = ENV['EDITOR']
|
412
407
|
end
|
@@ -416,7 +411,7 @@ or '#{DFT_EDITOR}' if none is set.
|
|
416
411
|
|
417
412
|
result = desc_tmp_file.read.chomp
|
418
413
|
desc_tmp_file.delete
|
419
|
-
|
414
|
+
result.chomp
|
420
415
|
end # get_description
|
421
416
|
|
422
417
|
### Get the local path to the package being added to d3
|
@@ -424,7 +419,7 @@ or '#{DFT_EDITOR}' if none is set.
|
|
424
419
|
### if the source is a root-folder rather than a .pkg or .dmg
|
425
420
|
###
|
426
421
|
### @return [Pathname] the local path to the pkg source
|
427
|
-
def get_source_path
|
422
|
+
def get_source_path(default = false)
|
428
423
|
desc = <<-END_DESC
|
429
424
|
SOURCE
|
430
425
|
Enter the path to a .pkg or .dmg installer
|
@@ -433,7 +428,7 @@ END_DESC
|
|
433
428
|
|
434
429
|
# dragging in items from the finder will esacpe spaces in the path with \'s
|
435
430
|
# in the shell this is good, but ruby is interpreting the \'s, so lets remove them.
|
436
|
-
prompt_for_data(opt: :source_path, desc: desc, default: default, required: true).strip.gsub(/\\ /,
|
431
|
+
prompt_for_data(opt: :source_path, desc: desc, default: default, required: true).strip.gsub(/\\ /, ' ')
|
437
432
|
end
|
438
433
|
|
439
434
|
### If we're builting a pkg, should we build a .pkg, or a .dmg?
|
@@ -455,8 +450,8 @@ Should we build a .pkg or .dmg? ( p = pkg, d = dmg )
|
|
455
450
|
###
|
456
451
|
### @return [String] the prefix to use
|
457
452
|
###
|
458
|
-
def get_pkg_identifier
|
459
|
-
|
453
|
+
def get_pkg_identifier(default = nil)
|
454
|
+
desc = <<-END_DESC
|
460
455
|
PKG IDENTIFIER
|
461
456
|
Enter the Apple .pkg indentifier for building a .pkg.
|
462
457
|
E.g. com.mycompany.myapp
|
@@ -477,8 +472,8 @@ E.g. com.mycompany.myapp
|
|
477
472
|
###
|
478
473
|
### @return [String] the prefix to use
|
479
474
|
###
|
480
|
-
def get_pkg_identifier_prefix
|
481
|
-
|
475
|
+
def get_pkg_identifier_prefix(default = D3::Admin::DFT_PKG_ID_PREFIX)
|
476
|
+
desc = <<-END_DESC
|
482
477
|
PKG IDENTIFIER PREFIX
|
483
478
|
Enter the prefix to prepend to a basename to create an Apple .pkg indentifier.
|
484
479
|
E.g. If you enter 'com.mycompany', then when you build a .pkg with basename 'foo'
|
@@ -487,6 +482,46 @@ the default .pkg identifier will be 'com.mycompany.foo'
|
|
487
482
|
prompt_for_data(opt: :pkg_identifier_prefix, desc: desc, default: default, required: true)
|
488
483
|
end
|
489
484
|
|
485
|
+
### Get the optional Apple Developer signing ID
|
486
|
+
### .pkgs can be codesigned with a certificate from Apple
|
487
|
+
### The Developer ID Installer certificate must be
|
488
|
+
### in the login.keychain of the user operating d3admin unless
|
489
|
+
### otherwise specified in signing_options
|
490
|
+
###
|
491
|
+
### This value is saved in the admin prefs for future use.
|
492
|
+
###
|
493
|
+
### @param default[String] the default value when hitting return
|
494
|
+
###
|
495
|
+
### @return [String] The Apple Developer signing ID to use
|
496
|
+
###
|
497
|
+
def get_signing_identity(default = D3::Admin::Prefs.prefs[:signing_identity])
|
498
|
+
desc = <<-END_DESC
|
499
|
+
SIGNING IDENTITY
|
500
|
+
Enter the common name of your Apple Developer signing ID to create signed Apple .pkgs.
|
501
|
+
E.g. If you enter 'Developer ID Installer: My Company (A12BC34DE56)', then that string will be passed
|
502
|
+
as the option for pkgbuild --sign. D3 will not attempt to sign unless this option is set.'
|
503
|
+
END_DESC
|
504
|
+
prompt_for_data(opt: :signing_identity, desc: desc, default: default, required: false)
|
505
|
+
end
|
506
|
+
|
507
|
+
### Get any arguments and options to pass to pkgbuild
|
508
|
+
### A signing identity must be defined for these options to be used.
|
509
|
+
###
|
510
|
+
### This value is saved in the admin prefs for future use.
|
511
|
+
###
|
512
|
+
### @param default[String] the default value when hitting return
|
513
|
+
###
|
514
|
+
### @return [String] The string of arguments and options to pass to pkgbuild
|
515
|
+
###
|
516
|
+
def get_signing_options(default = D3::Admin::Prefs.prefs[:signing_options])
|
517
|
+
desc = <<-END_DESC
|
518
|
+
SIGNING OPTIONS
|
519
|
+
Enter optional arguments and options to pass to pkgbuild. These options are ignored unless a signing identity is defined.
|
520
|
+
E.g. --keychain '/Users/d3/Library/Keychain' --cert 'My Awesome Authority' --timestamp
|
521
|
+
END_DESC
|
522
|
+
prompt_for_data(opt: :signing_options, desc: desc, default: default, required: false)
|
523
|
+
end
|
524
|
+
|
490
525
|
### Get the desired local workspace for building pkgs
|
491
526
|
### Defaults to ENV['HOME']
|
492
527
|
###
|
@@ -494,7 +529,7 @@ the default .pkg identifier will be 'com.mycompany.foo'
|
|
494
529
|
###
|
495
530
|
### @return [Pathname] the path to the workspace
|
496
531
|
###
|
497
|
-
def get_workspace
|
532
|
+
def get_workspace(default = ENV['HOME'])
|
498
533
|
desc = <<-END_DESC
|
499
534
|
PACKAGE BUILD WORKSPACE
|
500
535
|
Enter the path to a folder where we can build packages.
|
@@ -510,7 +545,7 @@ This will be stored between uses of d3admin.
|
|
510
545
|
###
|
511
546
|
### @return [String] the users response
|
512
547
|
###
|
513
|
-
def get_pkg_preserve_owners
|
548
|
+
def get_pkg_preserve_owners(default = 'n')
|
514
549
|
desc = <<-END_DESC
|
515
550
|
PRESERVE SOURCE OWNERSHIP
|
516
551
|
When building a .pkg, the OS generally sets the ownership and permissions
|
@@ -524,7 +559,7 @@ Should we override the OS and preserve the ownership on
|
|
524
559
|
the source folder when the item is installed on the client?
|
525
560
|
Enter 'y' or 'n'
|
526
561
|
END_DESC
|
527
|
-
prompt_for_data(desc: desc, prompt:
|
562
|
+
prompt_for_data(desc: desc, prompt: 'Preserve ownership (y/n)', default: default, required: true)
|
528
563
|
end
|
529
564
|
|
530
565
|
### Get a pre-install script, either local file, JSS id, or JSS name
|
@@ -534,8 +569,8 @@ Enter 'y' or 'n'
|
|
534
569
|
### @return [Pathname, Integer, nil] The local script file, or the JSS id of the
|
535
570
|
### chosen script
|
536
571
|
###
|
537
|
-
def get_pre_install_script
|
538
|
-
get_script
|
572
|
+
def get_pre_install_script(default = nil)
|
573
|
+
get_script 'PRE-INSTALL SCRIPT', :pre_install, default
|
539
574
|
end
|
540
575
|
|
541
576
|
### Get a post-install script, either local file, JSS id, or JSS name
|
@@ -545,8 +580,8 @@ Enter 'y' or 'n'
|
|
545
580
|
### @return [Pathname, Integer, nil] The local script file, or the JSS id of the
|
546
581
|
### chosen script
|
547
582
|
###
|
548
|
-
def get_post_install_script
|
549
|
-
get_script
|
583
|
+
def get_post_install_script(default = nil)
|
584
|
+
get_script 'POST-INSTALL SCRIPT', :post_install, default
|
550
585
|
end
|
551
586
|
|
552
587
|
### Get a pre-remove script, either local file, JSS id, or JSS name
|
@@ -556,8 +591,8 @@ Enter 'y' or 'n'
|
|
556
591
|
### @return [Pathname, Integer, nil] The local script file, or the JSS id of the
|
557
592
|
### chosen script
|
558
593
|
###
|
559
|
-
def get_pre_remove_script
|
560
|
-
|
594
|
+
def get_pre_remove_script(default = nil)
|
595
|
+
get_script 'PRE-REMOVE SCRIPT', :pre_remove, default
|
561
596
|
end
|
562
597
|
|
563
598
|
### Get a post-remove script, either local file, JSS id, or JSS name
|
@@ -567,8 +602,8 @@ Enter 'y' or 'n'
|
|
567
602
|
### @return [Pathname, Integer, nil] The local script file, or the JSS id of the
|
568
603
|
### chosen script
|
569
604
|
###
|
570
|
-
def get_post_remove_script
|
571
|
-
get_script
|
605
|
+
def get_post_remove_script(default = nil)
|
606
|
+
get_script 'POST-REMOVE SCRIPT', :post_remove, default
|
572
607
|
end
|
573
608
|
|
574
609
|
### Get a script, either local file, JSS id, or JSS name
|
@@ -578,7 +613,7 @@ Enter 'y' or 'n'
|
|
578
613
|
### @return [Pathname, Integer, nil] The local script file, or the JSS id of the
|
579
614
|
### chosen script
|
580
615
|
###
|
581
|
-
def get_script
|
616
|
+
def get_script(heading, opt, default = nil)
|
582
617
|
desc = <<-END_DESC
|
583
618
|
#{heading}
|
584
619
|
Enter a path to a local file containing the script
|
@@ -586,12 +621,12 @@ or the name or id of an existing script in the JSS.
|
|
586
621
|
Enter 'v' to view a list of scripts in the JSS.
|
587
622
|
END_DESC
|
588
623
|
|
589
|
-
result =
|
590
|
-
while result ==
|
624
|
+
result = 'v'
|
625
|
+
while result == 'v'
|
591
626
|
result = prompt_for_data(opt: opt, desc: desc, default: default, required: true)
|
592
|
-
D3.less_text JSS::Script.all_names.sort_by
|
627
|
+
D3.less_text JSS::Script.all_names.sort_by(&:downcase).join("\n") if result == 'v'
|
593
628
|
end
|
594
|
-
|
629
|
+
result
|
595
630
|
end
|
596
631
|
|
597
632
|
### Prompt the admin for one or more auto-groups for this installer
|
@@ -599,7 +634,7 @@ Enter 'v' to view a list of scripts in the JSS.
|
|
599
634
|
### @param default[nil,String,Array<String>] The groups to use
|
600
635
|
###
|
601
636
|
### @return [String]
|
602
|
-
def get_auto_groups
|
637
|
+
def get_auto_groups(default = nil)
|
603
638
|
desc = <<-END_DESC
|
604
639
|
AUTO-INSTALL GROUPS
|
605
640
|
Enter a comma-separated list of JSS Computer Group names whose members should
|
@@ -613,8 +648,7 @@ Enter '#{D3::STANDARD_AUTO_GROUP}' to install on all machines.
|
|
613
648
|
### Prompt the admin for one or more auto-groups for this installer
|
614
649
|
###
|
615
650
|
### @param default[nil,String,Array<String>] The groups to
|
616
|
-
def get_excluded_groups
|
617
|
-
|
651
|
+
def get_excluded_groups(default = nil)
|
618
652
|
desc = <<-END_PROMPT
|
619
653
|
EXCLUDED GROUPS
|
620
654
|
Enter a comma-separated list of JSS Computer Group names
|
@@ -628,7 +662,7 @@ Enter 'v' to view list of computer groups.
|
|
628
662
|
###
|
629
663
|
### @return [String] whatever the admin typed
|
630
664
|
###
|
631
|
-
def get_search_target
|
665
|
+
def get_search_target(default = false)
|
632
666
|
desc = <<-END_PROMPT
|
633
667
|
SEARCH TEXT
|
634
668
|
Enter text to use in matching basenames or computer group names.
|
@@ -637,26 +671,25 @@ Matching a group name will list all packages auto-installed or
|
|
637
671
|
excluded for the group. (RegExp's OK)
|
638
672
|
Enter 'all' to list all packages in d3.
|
639
673
|
END_PROMPT
|
640
|
-
prompt_for_data(
|
674
|
+
prompt_for_data(desc: desc, prompt: "Text to match or 'all'").chomp
|
641
675
|
end # get auto
|
642
676
|
|
643
|
-
|
644
|
-
def get_status_for_filter (with_frozen = false)
|
677
|
+
def get_status_for_filter(with_frozen = false)
|
645
678
|
if with_frozen
|
646
679
|
frozen_line = "\nUse 'frozen' to limit to frozen receipts"
|
647
|
-
frozen_title =
|
680
|
+
frozen_title = 'OR FROZEN'
|
648
681
|
else
|
649
|
-
frozen_line =
|
650
|
-
frozen_title =
|
682
|
+
frozen_line = ''
|
683
|
+
frozen_title = ''
|
651
684
|
end
|
652
685
|
|
653
686
|
desc = <<-END_PROMPT
|
654
687
|
LIMIT TO STATUS#{frozen_title}
|
655
688
|
Enter a comma-separate list of statuses for limiting the list.
|
656
|
-
Valid Statuses are: #{D3::Basename::STATUSES_FOR_FILTERS.join(
|
689
|
+
Valid Statuses are: #{D3::Basename::STATUSES_FOR_FILTERS.join(', ')}#{frozen_line}
|
657
690
|
Enter 'all' to show all statuses
|
658
691
|
END_PROMPT
|
659
|
-
prompt_for_data(
|
692
|
+
prompt_for_data(desc: desc, prompt: 'Statuses', default: 'all').chomp
|
660
693
|
end
|
661
694
|
|
662
695
|
### Prompt the admin for one or more groups
|
@@ -665,15 +698,13 @@ Enter 'all' to show all statuses
|
|
665
698
|
###
|
666
699
|
### @return [String,nil]
|
667
700
|
###
|
668
|
-
def get_groups
|
669
|
-
|
670
|
-
result
|
671
|
-
|
672
|
-
|
673
|
-
D3.less_text JSS::ComputerGroup.all_names.sort_by{|s| s.downcase}.join("\n") if result == "v"
|
701
|
+
def get_groups(desc, opt, default = nil)
|
702
|
+
result = 'v'
|
703
|
+
while result == 'v'
|
704
|
+
result = prompt_for_data(opt: opt, desc: desc, default: default, required: true)
|
705
|
+
D3.less_text JSS::ComputerGroup.all_names.sort_by(&:downcase).join("\n") if result == 'v'
|
674
706
|
end
|
675
|
-
|
676
|
-
return result
|
707
|
+
result
|
677
708
|
end # get auto
|
678
709
|
|
679
710
|
### Get a list of allowed OSes for this pkg
|
@@ -683,7 +714,7 @@ Enter 'all' to show all statuses
|
|
683
714
|
###
|
684
715
|
### @return [String,nil] A comma-separated list of allowed OSes
|
685
716
|
###
|
686
|
-
def get_oses
|
717
|
+
def get_oses(default = [])
|
687
718
|
desc = <<-END_DESC
|
688
719
|
LIMIT TO OS's
|
689
720
|
Enter a comma-separated list of OS's allowed to
|
@@ -699,7 +730,7 @@ Use '>=' to set a minimum OS, e.g. '>=10.8.5'
|
|
699
730
|
###
|
700
731
|
### @return [Symbol,nil] :ppc, :intel, or nil
|
701
732
|
###
|
702
|
-
def get_cpu_type
|
733
|
+
def get_cpu_type(default = 'x86')
|
703
734
|
desc = <<-END_DESC
|
704
735
|
LIMIT TO CPU TYPE
|
705
736
|
Should this packge be limited to certain CPU types?
|
@@ -714,7 +745,7 @@ Enter 'ppc' or 'x86' or 'none' for neither.
|
|
714
745
|
###
|
715
746
|
### @return [String] the category entered by the user
|
716
747
|
###
|
717
|
-
def get_category
|
748
|
+
def get_category(default = 'n')
|
718
749
|
desc = <<-END_DESC
|
719
750
|
CATEGORY
|
720
751
|
Enter the JSS category name for this package.
|
@@ -723,10 +754,10 @@ Enter:
|
|
723
754
|
- 'n' for no category
|
724
755
|
END_DESC
|
725
756
|
|
726
|
-
result =
|
727
|
-
while result ==
|
728
|
-
result = prompt_for_data(desc: desc, prompt:
|
729
|
-
D3.less_text JSS::Category.all_names.sort_by
|
757
|
+
result = 'v'
|
758
|
+
while result == 'v'
|
759
|
+
result = prompt_for_data(desc: desc, prompt: 'Category', default: default, required: true)
|
760
|
+
D3.less_text JSS::Category.all_names.sort_by(&:downcase).join("\n") if result == 'v'
|
730
761
|
end
|
731
762
|
return nil if result == 'n'
|
732
763
|
result
|
@@ -742,7 +773,7 @@ Enter:
|
|
742
773
|
###
|
743
774
|
### @return [Regexp,nil] the pattern to match
|
744
775
|
###
|
745
|
-
def get_prohibiting_processes
|
776
|
+
def get_prohibiting_processes(default = 'n')
|
746
777
|
desc = <<-END_DESC
|
747
778
|
PROHIBITING PROCESSES
|
748
779
|
Enter a comma separated string of process name(s) as they appear in the
|
@@ -757,7 +788,7 @@ to quit GUI applications gracefully. Matching is case sensitive.
|
|
757
788
|
Enter 'n' for none.
|
758
789
|
END_DESC
|
759
790
|
|
760
|
-
result = prompt_for_data(desc: desc, prompt:
|
791
|
+
result = prompt_for_data(desc: desc, prompt: 'Prohibiting Processes', opt: :prohibiting_processes, default: default, required: true)
|
761
792
|
return nil if result == 'n'
|
762
793
|
result
|
763
794
|
end
|
@@ -768,13 +799,13 @@ Enter 'n' for none.
|
|
768
799
|
###
|
769
800
|
### @return [String] the users response
|
770
801
|
###
|
771
|
-
def get_removable
|
802
|
+
def get_removable(default = 'y')
|
772
803
|
desc = <<-END_DESC
|
773
804
|
REMOVABLE
|
774
805
|
Can this package be uninstalled?
|
775
806
|
Enter 'y' or 'n'
|
776
807
|
END_DESC
|
777
|
-
prompt_for_data(desc: desc, prompt:
|
808
|
+
prompt_for_data(desc: desc, prompt: 'Removable? (y/n)', default: default, required: true)
|
778
809
|
end
|
779
810
|
|
780
811
|
### Ask if we should ininstall older versions of this basename
|
@@ -784,14 +815,14 @@ Enter 'y' or 'n'
|
|
784
815
|
###
|
785
816
|
### @return [String] the users response
|
786
817
|
###
|
787
|
-
def get_remove_first
|
818
|
+
def get_remove_first(default = 'y')
|
788
819
|
desc = <<-END_DESC
|
789
820
|
UNINSTALL OLDER VERSIONS
|
790
821
|
Should older versions of this basename be uninstalled
|
791
822
|
(if they are removable) before attempting to install this package?
|
792
823
|
Enter 'y' or 'n'
|
793
824
|
END_DESC
|
794
|
-
prompt_for_data(desc: desc, prompt:
|
825
|
+
prompt_for_data(desc: desc, prompt: 'Remove older installs first? (y/n)', default: default, required: true)
|
795
826
|
end
|
796
827
|
|
797
828
|
### Ask if this package needs a reboot
|
@@ -800,7 +831,7 @@ Enter 'y' or 'n'
|
|
800
831
|
###
|
801
832
|
### @return [String] the users response
|
802
833
|
###
|
803
|
-
def get_reboot
|
834
|
+
def get_reboot(default = 'n')
|
804
835
|
desc = <<-END_DESC
|
805
836
|
REBOOT REQUIRED (PUPPIES!)
|
806
837
|
Does this package require a reboot after installation?
|
@@ -809,8 +840,7 @@ with 'd3 install', and the user will be notified to log
|
|
809
840
|
out as soon as possible.
|
810
841
|
Enter 'y' or 'n'
|
811
842
|
END_DESC
|
812
|
-
prompt_for_data(desc: desc, prompt:
|
813
|
-
|
843
|
+
prompt_for_data(desc: desc, prompt: 'Requires reboot? (y/n)', default: default, required: true)
|
814
844
|
end
|
815
845
|
|
816
846
|
### Get an expiration period (# of days) from the user
|
@@ -819,7 +849,7 @@ Enter 'y' or 'n'
|
|
819
849
|
###
|
820
850
|
### @return [Integer] the value to use as the expiration
|
821
851
|
###
|
822
|
-
def get_expiration
|
852
|
+
def get_expiration(default = 0)
|
823
853
|
desc = <<-END_DESC
|
824
854
|
EXPIRATION
|
825
855
|
On machines that allow package expiration,
|
@@ -828,7 +858,7 @@ number of days without being used?
|
|
828
858
|
Enter the number of days, or 0 for no expiration.
|
829
859
|
END_DESC
|
830
860
|
|
831
|
-
prompt_for_data(desc: desc, prompt:
|
861
|
+
prompt_for_data(desc: desc, prompt: 'Expiration days', default: default, required: true)
|
832
862
|
end
|
833
863
|
|
834
864
|
### Get the path to the executable(s) to monitor for expiration
|
@@ -837,7 +867,7 @@ Enter the number of days, or 0 for no expiration.
|
|
837
867
|
###
|
838
868
|
### @return [Array<Pathname>] the path(s) to the executable
|
839
869
|
###
|
840
|
-
def get_expiration_paths
|
870
|
+
def get_expiration_paths(default = 'n')
|
841
871
|
desc = <<-END_DESC
|
842
872
|
EXPIRATION PATH(S)
|
843
873
|
Enter the path(s) to the executable(s) that must be used
|
@@ -846,7 +876,7 @@ should not be escaped. E.g.
|
|
846
876
|
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome, /Applications/Firefox.app/Contents/MacOS/firefox
|
847
877
|
Enter 'n' for none
|
848
878
|
END_DESC
|
849
|
-
prompt_for_data(desc: desc, prompt:
|
879
|
+
prompt_for_data(desc: desc, prompt: 'Expiration Path(s)', default: default, required: true)
|
850
880
|
end
|
851
881
|
|
852
882
|
### when deleting a pkg, should its pre- and post- scripts be kept?
|
@@ -855,7 +885,7 @@ Enter 'n' for none
|
|
855
885
|
###
|
856
886
|
### @return [String] the users response
|
857
887
|
###
|
858
|
-
def get_keep_scripts
|
888
|
+
def get_keep_scripts(default = 'n')
|
859
889
|
desc = <<-END_DESC
|
860
890
|
KEEP ASSOCIATED SCRIPTS IN CASPER?
|
861
891
|
When deleting a package, should any associated scripts
|
@@ -865,7 +895,7 @@ NOTE: If any other d3 packages or policies are using the scripts
|
|
865
895
|
they won't be deleted. The other users of the scripts will be reported.
|
866
896
|
Enter 'y' or 'n'
|
867
897
|
END_DESC
|
868
|
-
prompt_for_data(desc: desc, prompt:
|
898
|
+
prompt_for_data(desc: desc, prompt: 'Delete Scripts? (y/n)', default: default, required: true)
|
869
899
|
end
|
870
900
|
|
871
901
|
### when deleting a pkg, should it be kept in the JSS?
|
@@ -874,14 +904,14 @@ Enter 'y' or 'n'
|
|
874
904
|
###
|
875
905
|
### @return [String] the users response
|
876
906
|
###
|
877
|
-
def get_keep_in_jss
|
907
|
+
def get_keep_in_jss(default = 'n')
|
878
908
|
desc = <<-END_DESC
|
879
909
|
KEEP THE PACKAGE IN CASPER?
|
880
910
|
When deleting a package, should it be kept as a Casper package
|
881
911
|
and only deleted from d3?
|
882
912
|
Enter 'y' or 'n'
|
883
913
|
END_DESC
|
884
|
-
prompt_for_data(desc: desc, prompt:
|
914
|
+
prompt_for_data(desc: desc, prompt: 'Keep in JSS? (y/n)', default: default, required: true)
|
885
915
|
end
|
886
916
|
|
887
917
|
### what kind of package list are we showing?
|
@@ -890,7 +920,7 @@ Enter 'y' or 'n'
|
|
890
920
|
###
|
891
921
|
### @return [String] the chosen report type
|
892
922
|
###
|
893
|
-
def get_show_type
|
923
|
+
def get_show_type(default = D3::Admin::Report::DFT_SHOW_TYPE)
|
894
924
|
desc = <<-END_DESC
|
895
925
|
SERVER PACKAGE LIST
|
896
926
|
Enter the type of list you'd like to generate about packages in d3.
|
@@ -905,25 +935,25 @@ One of:
|
|
905
935
|
auto - packages auto-installed for a given computer group
|
906
936
|
excluded - packages not available to a given computer group
|
907
937
|
END_DESC
|
908
|
-
prompt_for_data(desc: desc, prompt:
|
938
|
+
prompt_for_data(desc: desc, prompt: 'Show packages', default: default, required: true)
|
909
939
|
end
|
910
940
|
|
911
941
|
### What computer are we generating a receipt report for?
|
912
942
|
###
|
913
943
|
### @return [String] A computer name in the JSS
|
914
944
|
###
|
915
|
-
def get_computer
|
916
|
-
|
945
|
+
def get_computer(default = nil)
|
946
|
+
desc = <<-END_DESC
|
917
947
|
COMPUTER NAME
|
918
948
|
Enter the name of a computer Casper.
|
919
949
|
Enter 'v' to view a list available computer names.
|
920
950
|
END_DESC
|
921
|
-
input =
|
922
|
-
while input ==
|
923
|
-
input = prompt_for_data(desc: desc, prompt:
|
924
|
-
D3::Admin::Report.show_available_computers_for_reports if input ==
|
951
|
+
input = 'v'
|
952
|
+
while input == 'v'
|
953
|
+
input = prompt_for_data(desc: desc, prompt: 'Computer name', default: nil, required: true)
|
954
|
+
D3::Admin::Report.show_available_computers_for_reports if input == 'v'
|
925
955
|
end
|
926
|
-
|
956
|
+
input
|
927
957
|
end # get computer
|
928
958
|
|
929
959
|
### Get the config target
|
@@ -932,8 +962,8 @@ END_DESC
|
|
932
962
|
###
|
933
963
|
### @return [String] the prefix to use
|
934
964
|
###
|
935
|
-
def get_config_target
|
936
|
-
|
965
|
+
def get_config_target(default = 'all')
|
966
|
+
desc = <<-END_DESC
|
937
967
|
CONFIGURATION
|
938
968
|
Which setting would you like to configure?
|
939
969
|
jss - the JSS and credentials (stored in your keychain)
|
@@ -942,6 +972,8 @@ Which setting would you like to configure?
|
|
942
972
|
workspace - the folder in which to build .pkgs and .dmgs
|
943
973
|
editor - the shell command for editing package descriptions
|
944
974
|
pkg-id-prefix - the prefix for the .pkg identifier when building .pkgs
|
975
|
+
signing-identity - optional Developer ID Installer certificate issued by Apple
|
976
|
+
signing-options - optional string of signing options to pass to pkgbuild.
|
945
977
|
all - all of the above
|
946
978
|
display - show current configuration
|
947
979
|
|
@@ -955,7 +987,7 @@ Which setting would you like to configure?
|
|
955
987
|
###
|
956
988
|
### @return [String] the command to use
|
957
989
|
###
|
958
|
-
def get_editor
|
990
|
+
def get_editor(default = '/usr/bin/nano')
|
959
991
|
desc = <<-END_DESC
|
960
992
|
EDITOR
|
961
993
|
Enter the shell command to use during --walkthru
|
@@ -966,9 +998,11 @@ Note: if the command launches a GUI editor, make sure the
|
|
966
998
|
shell command stays running until the document is closed.
|
967
999
|
Most such editors have an option for that.
|
968
1000
|
END_DESC
|
969
|
-
prompt_for_data(
|
1001
|
+
prompt_for_data(desc: desc, default: default, prompt: 'Command', required: true)
|
970
1002
|
end
|
971
1003
|
|
972
1004
|
end # module
|
1005
|
+
|
973
1006
|
end # module Admin
|
1007
|
+
|
974
1008
|
end # module D3
|