depot3 3.0.11 → 3.0.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dd0846668a4adffcd65b2f18acb90ea9e2d358fc
4
- data.tar.gz: 536dd741fc281d3a85f734338e9212c65c41c50f
3
+ metadata.gz: 80cce63be708933a3cc95c8c04130c7305f62821
4
+ data.tar.gz: 3b09f20666c177968106da0cb9a40d6f81c32528
5
5
  SHA512:
6
- metadata.gz: d4bfebc0d804c371cae8e11a2e83acd62c5407a8165c55a7269dd0aa7ccf2370d27a56eb137c6c602d5ecbbb69aa9404a36d875e687fb8276594aacb8f31531f
7
- data.tar.gz: cafd61d158574ebc192b34f0d8e3102e0929e28310cebccf75c870c21e1ef35019e217df45f3df6ace3f23a39d7e13b2f57f18e126702bd5e3096125e200f65b
6
+ metadata.gz: 43c2311387719eabfd9bf835d53e2582b637a8717baef425e19d9efb6140ba097bbfa5a4384cc53d5d0b92731893c008f823e1d7896135fd67a95357c2084d66
7
+ data.tar.gz: 3b3eeab2492cda0b170fe223a059fe5b434187fec73fd8c817f253a5ddd6ae03a3ef9350a1998046e4863e8d5e54b112fed8a99a9aafbbd37d375763b12501c9
data/CHANGES.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Change History
2
2
 
3
+ ## v3.0.13 - 2016-12-07
4
+
5
+ - Change: Updated CHANGES.md
6
+ - Change: Updated depot3.gemspec to require ruby-jss v0.6.6
7
+
8
+ ## v3.0.12 - 2016-12-07
9
+
10
+ - Change: Packages can how have multiple 'prohibiting proceses', which are entered as a comma-separated string of process names. If any one of them is running at install or uninstall, an error is raised. Use --force to override.
11
+
12
+
13
+ ## v3.0.11 - 2016-08-10
14
+
15
+ - Change: Eliminate DEFAULT_CPU_TYPE constant in favor of DEFAULT_PROCESSOR
16
+ - Fix: Prevent debug logging before it's asked for
17
+ - Change: added 'forget' action to d3, removes local receipt without attempting uninstall
18
+ - Fix: Client.update_receipts is more efficient now, only updating a rcpt once per run if needed
19
+ - Change: Client.sync now does "clean_missing_receipts" - after doing updates,to remove rcpts that are missing from d3
20
+ - Change: github issue #25 expiration path is now 'expiration paths' and can take a comma-separated list of paths. Any one of them coming to the foreground counts as 'being used' and will prevent expiration of the package. This is useful for single packages that install multiple apps, such as Microsoft Office.
21
+
22
+ ## v3.0.10 - 2016-07-25 (unreleased)
23
+
24
+ - Fix: github issue #14 Don't crash when there's no rcpt file.
25
+ - Fix: github issue #21 d3: ArgumentError: Unknown d3 action: list_queue
26
+ - Change: remove hard-coded client timeout, use whatever is in ruby-jss.conf
27
+ - Fix: github issue #13 when adding pkgs with new version, revision resets to 1 by default.
28
+ - Fix: github issue #12allow 'n' or 'none' to unset expiration path
29
+ - Added: method D3::Admin::Auth.connected?
30
+ - Fix: no attempt to write log if it isn't writable to the user
31
+ - Change: bump max DB schema version to 9.93
32
+ - Change: remove 2-line log entries
33
+ - Change: d3admin: default to deleting unused scripts whe deleting packages
34
+ - Fix: d3 & d3admin: don't check the TTY unless there is one
35
+
3
36
  ## v3.0.9 - 2016-04-11
4
37
 
5
38
  - d3: better text feedback during manual installs.
data/bin/d3admin CHANGED
@@ -71,7 +71,7 @@ class App
71
71
  end
72
72
 
73
73
  # run config if it hasn't ever run
74
- unless D3::Admin::Prefs.prefs[:last_config]
74
+ unless D3::Admin::Prefs.prefs[:last_config] || JSS.superuser?
75
75
  puts
76
76
  puts "******** INITIAL D3ADMIN CONFIGURATION ********"
77
77
  puts
@@ -81,7 +81,7 @@ class App
81
81
  end
82
82
 
83
83
  ### our admin is us
84
- @admin = ENV['USER']
84
+ @admin = @options.admin || ENV['USER']
85
85
 
86
86
  # admin can't be a badmin
87
87
  if D3.badmins.include? @admin and D3::Admin::ACTIONS_NEEDING_ADMIN.include? @action
@@ -89,13 +89,17 @@ class App
89
89
  end
90
90
 
91
91
  # config before connecting
92
- if @action =~ /^c/
92
+ if @action =~ /^c/ and !JSS.superuser?
93
93
  config
94
94
  return
95
95
  end
96
96
 
97
97
  ### connect to the server, prompting for info as needed
98
- D3::Admin::Auth.connect
98
+ if @admin == 'root'
99
+ D3::Client.connect
100
+ else
101
+ D3::Admin::Auth.connect
102
+ end
99
103
 
100
104
  case @action
101
105
 
@@ -177,6 +181,9 @@ class App
177
181
  when '--auto-confirm'
178
182
  @options.auto_confirm = true
179
183
 
184
+ when '--admin'
185
+ @options.admin = arg
186
+
180
187
  # search and report
181
188
  when '--status'
182
189
  @options.status += arg.split(/,\s*/)
@@ -230,8 +237,8 @@ class App
230
237
  @options.auto_groups = arg
231
238
  when '--excluded-groups'
232
239
  @options.excluded_groups = arg
233
- when '--prohibiting-process'
234
- @options.prohibiting_process = arg
240
+ when '--prohibiting-processes'
241
+ @options.prohibiting_processes = arg
235
242
  when '--cpu_type'
236
243
  @options.cpu_type = arg
237
244
  when '--category'
data/bin/d3helper CHANGED
@@ -326,7 +326,7 @@ Watch a parade of cute puppies while these items are installed:
326
326
  :removable => d3_pkg.removable,
327
327
  :expiration => d3_pkg.expiration,
328
328
  :expiration_paths => d3_pkg.expiration_paths,
329
- :prohibiting_process => d3_pkg.prohibiting_process,
329
+ :prohibiting_processes => d3_pkg.prohibiting_processes,
330
330
  :pre_remove_script_id => d3_pkg.pre_remove_script_id,
331
331
  :post_remove_script_id => d3_pkg.post_remove_script_id
332
332
  )
@@ -379,6 +379,20 @@ jss_default_pkg_category:
379
379
  ###
380
380
  jss_default_script_category:
381
381
 
382
+ ### - notification_image_path
383
+ ### the path to a directory of images that can be randomly selected
384
+ ### for various jamf_helper prompts from d3.
385
+ ###
386
+ ### If you leave this blank:
387
+ ###
388
+ ### the default is
389
+ ### /Library/Application Support/d3/notification_images/
390
+ ###
391
+ ### If this folder is empty, do not fret.
392
+ ### jamf_helper prompts will still function without images.
393
+ ###
394
+ notification_image_path:
395
+
382
396
  ### - admin_make_live_script
383
397
  ### The id or name of an existing Casper script to execute when
384
398
  ### a package is made live.
@@ -1 +1 @@
1
- slideshow/Beagle_puppy_Cadet.jpg
1
+ data/d3/puppytime/slideshow/Beagle_puppy_Cadet.jpg
@@ -1 +1 @@
1
- slideshow/Alert_Pug_Puppy.jpg
1
+ data/d3/puppytime/slideshow/Alert_Pug_Puppy.jpg
data/lib/d3/admin/add.rb CHANGED
@@ -46,7 +46,7 @@ module D3
46
46
  reboot
47
47
  removable
48
48
  remove_first
49
- prohibiting_process
49
+ prohibiting_processes
50
50
  auto_groups
51
51
  excluded_groups
52
52
  pre_install
@@ -461,4 +461,3 @@ END_HEADER
461
461
  end # module Add
462
462
  end # module Admin
463
463
  end # module D3
464
-
data/lib/d3/admin/edit.rb CHANGED
@@ -45,7 +45,7 @@ module D3
45
45
  reboot
46
46
  removable
47
47
  remove_first
48
- prohibiting_process
48
+ prohibiting_processes
49
49
  auto_groups
50
50
  excluded_groups
51
51
  pre_install
@@ -295,4 +295,3 @@ Current Settings => New Settings
295
295
  end # module edit
296
296
  end # module Admin
297
297
  end # module D3
298
-
data/lib/d3/admin/help.rb CHANGED
@@ -84,7 +84,7 @@ Action add and edit:
84
84
  -T, --post-remove <script> Name, id, or path to post-remove script
85
85
  -g, --auto-groups <groups> Computer groups to get this pkg automatically
86
86
  -G, --excluded-groups <groups> Computer groups that can't see this pkg
87
- -x, --prohibiting-process <proc> Process name that prevents installation
87
+ -x, --prohibiting-processes <proc> Process name(s) that prevent installation
88
88
  -R, --reboot <y/n> Reboot required after install, puppies!
89
89
  -F, --remove-first <y/n> Uninstall older versions before installing
90
90
  -u, --removable <y/n> Can this package be uninstalled?
@@ -314,10 +314,10 @@ Action add and edit:
314
314
  without using force.
315
315
  Use "n" for 'none'.
316
316
 
317
- -x, --prohibiting-process <proc> Specify a name to match with process names
317
+ -x, --prohibiting-processes <proc> Specify name(s) to match with process names
318
318
  as output by `/bin/ps -A -c -o comm`.
319
319
  If a match is found at install time,
320
- prevents installation. Use "n" for 'none'
320
+ graceful quit will be attempted. Use "n" for 'none'
321
321
 
322
322
  -R, --reboot <y/n> Reboot is required after install.
323
323
  (PuppyTime!)
@@ -145,7 +145,7 @@ module D3
145
145
  ###
146
146
  ### A Description of the option is displayed, followed by a prompt.
147
147
  ### If a default value is provided, the prompt includes the text
148
- ### (Hit return for '#{default_value}')
148
+ ### (Hit return for #{default_value})
149
149
  ###
150
150
  ### If the option is defined in D3::Admin::OPTIONS, the data for
151
151
  ### the option is used, if not provided in the args.
@@ -205,9 +205,8 @@ module D3
205
205
 
206
206
  data_entered = ''
207
207
  puts "\n#{desc}" if desc
208
- puts unset_line if unset_line
209
208
  prompt ||= "Please enter a value"
210
- hit_return = default_display.empty? ? "" : " (Hit return for '#{default_display}')"
209
+ hit_return = default_display.empty? ? "" : " (Hit return for '#{default_display}' )"
211
210
  prompt_line = "#{prompt}#{hit_return}: "
212
211
 
213
212
  while true do
@@ -733,30 +732,32 @@ Enter:
733
732
  result
734
733
  end
735
734
 
736
- ### Get a pattern to match for the prohibiting process
735
+ ### Get a pattern to match for the prohibiting processes
737
736
  ### If this matches a line of output from `/bin/ps -A -c -o comm`
738
- ### at install time, then the install won't happen.
737
+ ### at install time, then graceful quit will be attempted.
739
738
  ### Strings must match a whole line, Regexps will work with
740
739
  ### any match.
741
740
  ###
742
- ### @param default[String,Regexp] the default pattern when hitting return
741
+ ### @param default[String,Array<String>,Regexp] the default pattern when hitting return
743
742
  ###
744
743
  ### @return [Regexp,nil] the pattern to match
745
744
  ###
746
- def get_prohibiting_process (default = 'n')
745
+ def get_prohibiting_processes (default = 'n')
747
746
  desc = <<-END_DESC
748
- PROHIBITING PROCESS
749
- Enter the name of a process as it appears on one line
750
- of the output of `/bin/ps -A -c -o comm`
747
+ PROHIBITING PROCESSES
748
+ Enter a comma separated string of process name(s) as they appear in the
749
+ of the output of `/bin/ps -A -c -o comm`.
751
750
 
752
- If this process is running at install time,
753
- the installation will be skipped.
754
- Matching is case-insensitive
751
+ Example: Safari, Google Chrome, cfprefsd
752
+
753
+ If a process is running at install time, the installer will
754
+ quit any background processes automatically, and may prompt the user
755
+ to quit GUI applications gracefully. Matching is case sensitive.
755
756
 
756
757
  Enter 'n' for none.
757
758
  END_DESC
758
759
 
759
- result = prompt_for_data(desc: desc, prompt: "Prohibiting Process", default: default, required: true)
760
+ result = prompt_for_data(desc: desc, prompt: "Prohibiting Processes", opt: :prohibiting_processes, default: default, required: true)
760
761
  return nil if result == 'n'
761
762
  result
762
763
  end
@@ -127,6 +127,11 @@ module D3
127
127
  :get => nil,
128
128
  :validate => nil
129
129
  },
130
+ admin: {
131
+ :cli => ['--admin', GetoptLong::REQUIRED_ARGUMENT ],
132
+ :arg => 'admin',
133
+ :help => "who is doing something with d3?"
134
+ },
130
135
 
131
136
  # Package Identification: Add/Edit/Info/Delete
132
137
 
@@ -274,14 +279,15 @@ module D3
274
279
  :get => :get_remove_first,
275
280
  :validate => :validate_yes_no
276
281
  },
277
- prohibiting_process: {
282
+ prohibiting_processes: {
278
283
  :default => nil,
279
- :cli => [ '--prohibiting-process', '-x', GetoptLong::REQUIRED_ARGUMENT ],
284
+ :cli => [ '--prohibiting-processes', '--prohibiting-process', '-x', GetoptLong::REQUIRED_ARGUMENT ],
280
285
  :label => "Installation prohibited by processes matching",
281
- :display_conversion => DISPLAY_DFT_NONE,
282
- :get => :get_prohibiting_process,
286
+ :display_conversion => DISPLAY_COMMA_SEP_LIST,
287
+ :get => :get_prohibiting_processes,
283
288
  :unsetable => true,
284
- :validate => :validate_prohibiting_process
289
+ :validate => :validate_prohibiting_processes,
290
+ :compare => Proc.new{|o,n| o.to_a.sort == n.to_a.sort}
285
291
  },
286
292
  auto_groups: {
287
293
  :default => nil,
@@ -355,7 +361,8 @@ module D3
355
361
  :display_conversion => D3::Database::ARRAY_OF_PATHNAMES_TO_COMMA_STRING ,
356
362
  :get => :get_expiration_paths,
357
363
  :unsetable => true,
358
- :validate => :validate_expiration_paths
364
+ :validate => :validate_expiration_paths,
365
+ :compare => Proc.new{|o,n| o.to_a.sort == n.to_a.sort}
359
366
  },
360
367
  description: {
361
368
  :default => '',
@@ -366,14 +366,16 @@ module D3
366
366
  D3::Package::Validate.validate_category cat
367
367
  end
368
368
 
369
- ### Check the offered prohibiting process
369
+ ### Check multiple prohibiting_processes for validity
370
370
  ###
371
- ### @param match_string[String] the data entered by the user
371
+ ### @param process_names[String,Array<String>] A comma-separated String, or an Array of process names to be validated.
372
372
  ###
373
- ### @return [String, nil] the regexp used to do the match
373
+ ### @return [Array<String>]
374
374
  ###
375
- def validate_prohibiting_process (match_string)
376
- D3::Package::Validate.validate_prohibiting_process match_string
375
+ def validate_prohibiting_processes (process_names)
376
+ process_names = [] if process_names.to_s =~ /^n(one)?$/i
377
+ names_as_array = JSS.to_s_and_a(process_names)[:arrayform]
378
+ names_as_array.map { |procname| D3::Package::Validate.validate_prohibiting_process(procname) }.compact
377
379
  end
378
380
 
379
381
  ### check the validity of a yes/no true/false reply
data/lib/d3/basename.rb CHANGED
@@ -112,10 +112,10 @@ module D3
112
112
  # @return [Symbol] Is this package a .dmg or .pkg?
113
113
  attr_reader :package_type
114
114
 
115
- ### @return [String] a string for matching to the output lines
115
+ ### @return [Array<String>] an array of Strings for matching to the output lines
116
116
  ### of '/bin/ps -A -c -o comm'. If there's a match, this pkg won't be
117
- ### installed or uninstalled
118
- attr_reader :prohibiting_process
117
+ ### installed or uninstalled without a graceful quit
118
+ attr_reader :prohibiting_processes
119
119
 
120
120
  # @return [Integer] the days of disuse before an expirable edition expires. 0=never
121
121
  attr_reader :expiration
@@ -201,19 +201,6 @@ module D3
201
201
  @status == :deleted
202
202
  end
203
203
 
204
- private
205
-
206
- ### set the status
207
- ###
208
- ### @param new_status[Symnol] one of the valid STATUSES
209
- ###
210
- ### @return [Symbol] the new status
211
- ###
212
- def status= (new_status)
213
- raise JSS::InvalidDataError, "status must be one of :#{STATUSES.join(', :')}" unless STATUSES.include? new_status
214
- @status = new_status
215
- end
216
-
217
204
  ### Does a given array of pathnames have the same elements as
218
205
  ### @expiration_paths regardless of order?
219
206
  ###
@@ -225,9 +212,22 @@ module D3
225
212
  ### @return [Boolean] Are they the same aside from order?
226
213
  ###
227
214
  def expiration_paths_match?(other_exp_paths)
228
- return false unless @expiration_paths.length == other_exp_paths.length
215
+ return false unless @expiration_paths and @expiration_paths.length == other_exp_paths.length
229
216
  (@expiration_paths - other_exp_paths).empty?
230
217
  end
231
218
 
219
+ private
220
+
221
+ ### set the status
222
+ ###
223
+ ### @param new_status[Symbol] one of the valid STATUSES
224
+ ###
225
+ ### @return [Symbol] the new status
226
+ ###
227
+ def status= (new_status)
228
+ raise JSS::InvalidDataError, "status must be one of :#{STATUSES.join(', :')}" unless STATUSES.include? new_status
229
+ @status = new_status
230
+ end
231
+
232
232
  end # module Basename
233
233
  end # module PixD3
data/lib/d3/client.rb CHANGED
@@ -32,6 +32,13 @@ module D3
32
32
  ###
33
33
  class Client < JSS::Client
34
34
 
35
+ ### Default notification_image_path
36
+ ### Unless otherwise specified in /etc/d3.conf,
37
+ ### this is the default directory that can be populated
38
+ ### with image(s) to display randomly alongside user notifications.
39
+
40
+ DFT_NOTIFICATION_IMAGE_PATH = D3::SUPPORT_DIR + "notification_images"
41
+
35
42
  end # class Client
36
43
  end # module D3
37
44
 
@@ -43,4 +50,3 @@ require "d3/client/auth"
43
50
  require "d3/client/cli"
44
51
  require "d3/client/lists"
45
52
  require "d3/client/help"
46
-
@@ -244,7 +244,7 @@ module D3
244
244
  ### - status
245
245
  ### - pre- or post-remove scripts
246
246
  ### - removability
247
- ### - prohibiting process
247
+ ### - prohibiting processes
248
248
  ### - expiration details
249
249
  ###
250
250
  ### Also update
@@ -316,7 +316,7 @@ module D3
316
316
  D3.log "Updating expiration path(s) for #{rcpt.edition}", :info
317
317
  need_update = true
318
318
  end # if
319
-
319
+
320
320
  if (rcpt.expiration != pkgdata[:expiration].to_i) and (not rcpt.custom_expiration)
321
321
  rcpt.expiration = pkgdata[:expiration].to_i
322
322
  D3.log "Updating expiration for #{rcpt.edition}", :info
@@ -324,17 +324,17 @@ module D3
324
324
  end # if
325
325
  end # if removable
326
326
 
327
- # prohibiting_process
328
- if rcpt.prohibiting_process.to_s != pkgdata[:prohibiting_process].to_s
329
- rcpt.prohibiting_process = pkgdata[:prohibiting_process]
330
- D3.log "Updating prohibiting_process for #{rcpt.edition}", :info
327
+ # prohibiting_processes
328
+ if rcpt.prohibiting_processes.sort != pkgdata[:prohibiting_processes].sort
329
+ rcpt.prohibiting_processes = pkgdata[:prohibiting_processes]
330
+ D3.log "Updating prohibiting_processes for #{rcpt.edition}", :info
331
331
  need_update = true
332
332
  end # if
333
333
 
334
334
 
335
335
  rcpt.update if need_update
336
336
  end # each do basename, rcpt
337
- end # update
337
+ end # update_rcpts
338
338
 
339
339
  ### remove any invalid puppies from the queue
340
340
  ### invalid = id is no longer in d3, or status is missing
@@ -807,4 +807,3 @@ module D3
807
807
  end
808
808
  end # class
809
809
  end # module D3
810
-
@@ -132,4 +132,3 @@ module D3
132
132
  end
133
133
  end # class Client
134
134
  end # module D3
135
-
@@ -106,7 +106,7 @@ module D3
106
106
  :post_remove_script_id,
107
107
  :expiration,
108
108
  :expiration_paths,
109
- :prohibiting_process
109
+ :prohibiting_processes
110
110
  ]
111
111
 
112
112
  ################## Class Variables #################
@@ -575,7 +575,7 @@ module D3
575
575
  @installed_at = args[:installed_at]
576
576
 
577
577
  @removable = args[:removable]
578
- @prohibiting_process = args[:prohibiting_process]
578
+ @prohibiting_processes = args[:prohibiting_processes]
579
579
  @frozen = args[:frozen]
580
580
  @pre_remove_script_id = args[:pre_remove_script_id]
581
581
  @post_remove_script_id = args[:post_remove_script_id]
@@ -622,7 +622,7 @@ module D3
622
622
 
623
623
  begin # ...ensure...
624
624
  if uninstall_prohibited_by_process? and (not force)
625
- raise D3::InstallError, "#{edition} cannot be uninstalled now because '#{@prohibiting_process}' is running."
625
+ raise D3::InstallError, "#{edition} cannot be uninstalled now because one or more of the following processes is running: #{D3::Admin::OPTIONS[:prohibiting_processes][:display_conversion].call @prohibiting_processes}"
626
626
  end
627
627
  D3::Client.set_env :removing, edition
628
628
  D3.log "Uninstalling #{edition}", :warn
@@ -760,10 +760,11 @@ module D3
760
760
  begin
761
761
  installed_apple_rcpts = `#{JSS::Composer::PKG_UTIL} --pkgs`.split("\n")
762
762
  @apple_pkg_ids.each do |pkgid|
763
-
764
763
  unless installed_apple_rcpts.include? pkgid
765
- raise D3::UninstallError, "No local Apple receipt for '#{pkgid}'"
764
+ D3.log "No local Apple receipt for '#{pkgid}', ignoring", :warn
765
+ next
766
766
  end
767
+
767
768
  # this gets them in reverse order, so we can
768
769
  # delete files and then test for and delete empty dirs on the way
769
770
  to_delete[pkgid] = `#{JSS::Composer::PKG_UTIL} --files '#{pkgid}' 2>/dev/null`.split("\n").reverse
@@ -866,9 +867,9 @@ module D3
866
867
  @expiration_paths = new_val
867
868
  end
868
869
 
869
- ### Set a new prohibiting process
870
- def prohibiting_process=(new_val)
871
- @prohibiting_process = new_val
870
+ ### Set new prohibiting process(es)
871
+ def prohibiting_processes=(new_val)
872
+ @prohibiting_processes = new_val
872
873
  end
873
874
 
874
875
  ### Update the current receipt in the receipt store
@@ -1134,6 +1135,9 @@ Last brought to foreground: #{last_usage_display}
1134
1135
  # if never been used, last usage is the install date
1135
1136
  @last_usage ||= @installed_at
1136
1137
 
1138
+ # prohibiting_processes should always be an array
1139
+ @prohibiting_processes ||= []
1140
+
1137
1141
  # if the install time is newer than the last usage,
1138
1142
  # use the install time.
1139
1143
  # this basically "resets the timer" when
@@ -1151,7 +1155,7 @@ Last brought to foreground: #{last_usage_display}
1151
1155
 
1152
1156
  ### set the status - for rcpts, this can't be a private method
1153
1157
  ###
1154
- ### @param new_status[Symnol] one of the valid STATUSES
1158
+ ### @param new_status[Symbol] one of the valid STATUSES
1155
1159
  ###
1156
1160
  ### @return [Symbol] the new status
1157
1161
  ###
@@ -1162,7 +1166,7 @@ Last brought to foreground: #{last_usage_display}
1162
1166
  end
1163
1167
 
1164
1168
 
1165
- ################# Provate Instance Methods #################
1169
+ ################# Private Instance Methods #################
1166
1170
 
1167
1171
  private
1168
1172
 
@@ -1171,8 +1175,7 @@ Last brought to foreground: #{last_usage_display}
1171
1175
  ### @return [Boolean]
1172
1176
  ###
1173
1177
  def uninstall_prohibited_by_process?
1174
- return false unless @prohibiting_process
1175
- D3.prohibited_by_process_running? @prohibiting_process
1178
+ D3.prohibited_by_process_running? @prohibiting_processes
1176
1179
  end #
1177
1180
 
1178
1181
  end # class Receipt
@@ -115,6 +115,8 @@ module D3
115
115
  :puppy_title => :to_s,
116
116
  :puppy_display_secs => :to_i,
117
117
 
118
+ :notification_image_path => :jss_to_pathname,
119
+
118
120
  :admin_make_live_script => :to_s,
119
121
  :admin_auto_clean => :jss_to_bool,
120
122
  :admin_auto_clean_keep_deprecated => :to_i,
data/lib/d3/database.rb CHANGED
@@ -42,7 +42,7 @@ module D3
42
42
  MIN_SCHEMA_VERSION = "9.4"
43
43
 
44
44
  # the minimum JSS schema version allower
45
- MAX_SCHEMA_VERSION = "9.93"
45
+ MAX_SCHEMA_VERSION = "9.97"
46
46
 
47
47
  ### these Proc objects allow us to encapsulate and pass around various
48
48
  ### blocks of code more easily for converting data between their mysql
@@ -59,10 +59,10 @@ module D3
59
59
 
60
60
  ### Some values are stored as comma-separated strings, but used as Arrays
61
61
  COMMA_STRING_TO_ARRAY = Proc.new{|v| JSS.to_s_and_a(v)[:arrayform] }
62
-
62
+
63
63
  ### Some values are stored as comma-separated strings, but used as Arrays of Pathnames
64
64
  COMMA_STRING_TO_ARRAY_OF_PATHNAMES = Proc.new{|v| JSS.to_s_and_a(v)[:arrayform].map{|p| Pathname.new(p)} }
65
- ARRAY_OF_PATHNAMES_TO_COMMA_STRING = Proc.new{|v| v.join(", ")}
65
+ ARRAY_OF_PATHNAMES_TO_COMMA_STRING = Proc.new{|v| v.is_a?(Array) ? v.join(", ") : "" }
66
66
 
67
67
  ### Some values are used as Arrays but stored as comma-separated strings
68
68
  ARRAY_TO_COMMA_STRING = Proc.new{|v| JSS.to_s_and_a(v)[:stringform] }
@@ -157,7 +157,7 @@ module D3
157
157
  ### - :triggers_swu [Boolean] when installed, will this package trigger a GUI software update check,
158
158
  ### either immediately if there's a console user, or at the next console login?
159
159
  ###
160
- ### - :prohibiting_process [String] a string for matching to the output lines
160
+ ### - :prohibiting_processes [Array<String>] An array of strings for matching to the output lines
161
161
  ### of '/bin/ps -A -c -o comm'. If there's a matching line, this pkg won't be installed
162
162
  ###
163
163
  ### - :remove_first [Boolean] should any currently installed versions of this basename
@@ -273,12 +273,12 @@ module D3
273
273
  :to_ruby => COMMA_STRING_TO_ARRAY
274
274
  },
275
275
 
276
- :prohibiting_process => {
276
+ :prohibiting_processes => {
277
277
  :field_name => "prohibiting_process",
278
278
  :sql_type => 'varchar(100)',
279
279
  :index => nil,
280
- :to_sql => nil,
281
- :to_ruby => nil
280
+ :to_sql => ARRAY_TO_COMMA_STRING,
281
+ :to_ruby => COMMA_STRING_TO_ARRAY
282
282
  },
283
283
 
284
284
  :remove_first => {
@@ -490,5 +490,3 @@ module D3
490
490
 
491
491
  end # module Database
492
492
  end # module D3
493
-
494
-
@@ -158,7 +158,7 @@ module D3
158
158
  else
159
159
 
160
160
  unless forced
161
- raise D3::InstallError, "#{edition} cannot be installed now because '#{@prohibiting_process}' is running." if install_prohibited_by_process?
161
+ raise D3::InstallError, "#{edition} cannot be installed now because one or more of the following processes is running: #{D3::Admin::OPTIONS[:prohibiting_processes][:display_conversion].call @prohibiting_processes}." if install_prohibited_by_process?
162
162
  end # unless forced
163
163
 
164
164
  remove_previous_installs_if_needed (args[:verbose])
@@ -175,10 +175,13 @@ module D3
175
175
  # some nil-values shouldn't be nil
176
176
  @auto_groups ||= []
177
177
  @excluded_groups ||= []
178
-
178
+
179
179
  # expiration_paths should always be an array
180
180
  @expiration_paths ||= []
181
181
 
182
+ # prohibiting_processes should always be an array
183
+ @prohibiting_processes ||= []
184
+
182
185
  # these don't come from the table def.
183
186
  @admin = args[:admin]
184
187
 
@@ -106,11 +106,11 @@ Post-remove script: #{post_remove_script_name or 'None'}
106
106
  CPU limitation: #{@required_processor or 'None'}
107
107
  OS limitations: #{os_disp.empty? ? 'None' : os_disp}
108
108
  Uninstalls older versions: #{@remove_first or 'false'}
109
- Installation prohibited by process: #{@prohibiting_process or 'None'}
109
+ Installation prohibited by process(es): #{D3::Admin::OPTIONS[:prohibiting_processes][:display_conversion].call @prohibiting_processes or 'None'}
110
110
  Auto installed for groups: #{auto_disp.empty? ? 'None' : auto_disp}
111
111
  Excluded for groups: #{excl_disp.empty? ? 'None' : excl_disp}
112
112
  Expiration period: #{@expiration.to_i} days
113
- Expiration path(s): #{D3::Database::ARRAY_OF_PATHNAMES_TO_COMMA_STRING.call @expiration_paths}
113
+ Expiration path(s): #{D3::Admin::OPTIONS[:expiration_paths][:display_conversion].call @expiration_paths}
114
114
  Released by: #{@released_by or '-'}
115
115
  Release date: #{@release_date ? @release_date.strftime('%Y-%m-%d') : '-'}
116
116
  END_DEETS
@@ -35,8 +35,9 @@ module D3
35
35
  ### @return [Boolean]
36
36
  ###
37
37
  def install_prohibited_by_process?
38
- return false unless @prohibiting_process
39
- D3.prohibited_by_process_running? @prohibiting_process
38
+ return false unless @prohibiting_processes
39
+ return false if @prohibiting_processes.empty?
40
+ D3.prohibited_by_process_running? @prohibiting_processes
40
41
  end #
41
42
 
42
43
  ### If needed, uninstall any previously installed versions of this basename
@@ -79,7 +80,7 @@ module D3
79
80
  :expiration => @expiration_to_apply.to_i,
80
81
  :expiration_paths => @expiration_paths,
81
82
  :custom_expiration => @custom_expiration,
82
- :prohibiting_process => @prohibiting_process)
83
+ :prohibiting_processes => @prohibiting_processes)
83
84
 
84
85
  D3::Client::Receipt.add_receipt new_rcpt, :replace
85
86
 
@@ -123,15 +123,15 @@ module D3
123
123
  ### The paths are those recorded in d3RepoMan's timestamp plists.
124
124
  ### @example "/Applications/FileMaker Pro 11/FileMaker Pro.app/Contents/MacOS/Filemaker Pro"
125
125
  ###
126
- ### @param new_val[String,Pathname,Array<String,Pathname>] The expiration paths.
127
- ### A Pathname for a single path, a String for single, or multiple
126
+ ### @param new_val[String,Pathname,Array<String,Pathname>] The expiration paths.
127
+ ### A Pathname for a single path, a String for single, or multiple
128
128
  ### (comma-separated) or an Array of Strings or Pathnames for single paths.
129
129
  ### Each path must be an absolute path starting with a /
130
130
  ###
131
131
  ### @return [void]
132
132
  ###
133
133
  def expiration_paths= (new_val = @expiration_paths)
134
- return @expiration_paths if new_val == @expiration_paths
134
+ return @expiration_paths if D3::Admin::OPTIONS[:expiration_paths][:compare].call(@expiration_paths, new_val)
135
135
  @expiration_paths = validate_expiration_paths (new_val)
136
136
  @need_to_update_d3 = true unless @initializing
137
137
  end # expiration =
@@ -147,7 +147,7 @@ module D3
147
147
  @expiration_paths << path
148
148
  @need_to_update_d3 = true unless @initializing
149
149
  end # add_expiration_path
150
-
150
+
151
151
  ### Remove a path from expiration_paths
152
152
  ### @param new_val[String,Pathname]
153
153
  ###
@@ -158,35 +158,38 @@ module D3
158
158
  @expiration_paths.delete Pathname.new(path)
159
159
  @need_to_update_d3 = true unless @initializing
160
160
  end # remove_expiration_path
161
-
162
-
163
- ### Set the prohibiting process for this installer.
161
+
162
+
163
+ ### Set the prohibiting processes for this installer.
164
164
  ###
165
165
  ### The value of this attribute is compared at install time to the lines output
166
166
  ### by the command 'ps -A -c -o comm' (case insensitive)
167
167
  ###
168
- ### If any line matches, an exception will be raised and the package will not be installed.
168
+ ### If any line matches, d3 will attempt to quit the process (or prompt the user
169
+ ### to quit the Application) to proceed with installation.
169
170
  ###
170
- ### @param new_val[String] the process name that will prohibit installation
171
+ ### @param new_val[Array<String>] the process name(s) that should not be running during installation.
171
172
  ###
172
173
  ### @return [void]
173
174
  ###
174
- def prohibiting_process= (new_val = @prohibiting_process)
175
- return @prohibiting_process if new_val == @prohibiting_process
176
- @prohibiting_process = validate_prohibiting_process (new_val)
175
+ def prohibiting_processes= (new_val = @prohibiting_processes)
176
+ new_val = JSS.to_s_and_a(new_val)[:arrayform]
177
+ return @prohibiting_processes if D3::Admin::OPTIONS[:prohibiting_processes][:compare].call(@prohibiting_processes, new_val)
178
+ @prohibiting_processes = new_val.each {|process| validate_prohibiting_process process}
177
179
  @need_to_update_d3 = true unless @initializing
178
180
  end
179
181
 
180
182
  ### Set the automatic-install groups for this package.
181
183
  ### See also {#add_auto_group} and {#remove_auto_group}
182
184
  ###
183
- ### @param new_val [String,Array<String>] The group names as a comma-separated string or an array of strings
185
+ ### @param new_val[String,Array<String>] The group names as a comma-separated string or an array of strings
184
186
  ###
185
187
  ### @return [void]
186
188
  ###
187
189
  def auto_groups= (new_val = @auto_groups)
188
190
  @auto_groups ||= []
189
191
  new_val ||= []
192
+ return @auto_groups if D3::Admin::OPTIONS[:auto_groups][:compare].call(@auto_groups, new_val)
190
193
  new_groups = validate_auto_groups (new_val)
191
194
  validate_non_overlapping_groups new_groups, @excluded_groups
192
195
  @auto_groups = new_groups
@@ -236,6 +239,7 @@ module D3
236
239
  @excluded_groups ||= []
237
240
  new_val ||= []
238
241
  new_groups = validate_auto_groups (new_val)
242
+ return @excluded_groups if D3::Admin::OPTIONS[:excluded_groups][:compare].call(@excluded_groups, new_val)
239
243
  validate_non_overlapping_groups @auto_groups, new_groups
240
244
  @excluded_groups = new_groups
241
245
  @need_to_update_d3 = true unless @initializing
@@ -371,16 +371,16 @@ module D3
371
371
  cat
372
372
  end
373
373
 
374
- ### Check the offered prohibiting process pattern
374
+ ### Check a single prohibiting process for validity
375
375
  ###
376
- ### @param match_string[String] the data entered by the user
376
+ ### @param process_name[String] the process to be validated.
377
377
  ###
378
- ### @return [String, nil] the regexp used to do the match
378
+ ### @return [String]
379
379
  ###
380
- def validate_prohibiting_process (match_string)
381
- match_string = nil if match_string.to_s =~ /^n(one)?$/i
382
- return nil if match_string.nil? or match_string.empty?
383
- match_string.to_s
380
+ def validate_prohibiting_process (process_name)
381
+ process_name = nil if process_name.to_s =~ /^n(one)?$/i
382
+ return nil if process_name.nil? or process_name.empty?
383
+ process_name.to_s
384
384
  end
385
385
 
386
386
  ### check the validity of a yes/no,true/false,1/0 input value
data/lib/d3/utility.rb CHANGED
@@ -31,11 +31,10 @@ module D3
31
31
  ###
32
32
  ### @return [Boolean]
33
33
  ###
34
- def self.prohibited_by_process_running? (xproc)
35
- `/bin/ps -A -c -o comm`.lines.each do |ps_line|
36
- return true if ps_line.strip.casecmp(xproc) == 0
37
- end
38
- return false
34
+ def self.prohibited_by_process_running? (xprocs)
35
+ processes = `/bin/ps -A -c -o comm`.split("\n")
36
+ current_prohibiting = processes & xprocs
37
+ return true unless current_prohibiting.empty?
39
38
  end #
40
39
 
41
40
  ### Try to figure out the login name of the admin running this code
data/lib/d3/version.rb CHANGED
@@ -25,5 +25,5 @@
25
25
 
26
26
  ###
27
27
  module D3
28
- VERSION = '3.0.11'
28
+ VERSION = '3.0.13'.freeze
29
29
  end # module
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: depot3
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.11
4
+ version: 3.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Lasell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-11 00:00:00.000000000 Z
11
+ date: 2016-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-keychain
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.2'
20
- - - '>'
20
+ - - ">"
21
21
  - !ruby/object:Gem::Version
22
22
  version: 0.2.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0.2'
30
- - - '>'
30
+ - - ">"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 0.2.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: ruby-jss
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ~>
37
+ - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0.6'
40
- - - '>='
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 0.6.2
42
+ version: 0.6.6
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
49
  version: '0.6'
50
- - - '>='
50
+ - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 0.6.2
52
+ version: 0.6.6
53
53
  description: |
54
54
  d3 extends the package-deployment capabilities of the Casper Suite, an enterprise/education
55
55
  tool for managing Apple devices, from JAMF Software LLC.
@@ -67,7 +67,7 @@ extra_rdoc_files:
67
67
  - CHANGES.md
68
68
  - THANKS.md
69
69
  files:
70
- - .yardopts
70
+ - ".yardopts"
71
71
  - CHANGES.md
72
72
  - LICENSE.txt
73
73
  - README.md
@@ -189,29 +189,28 @@ licenses:
189
189
  metadata: {}
190
190
  post_install_message:
191
191
  rdoc_options:
192
- - --title
192
+ - "--title"
193
193
  - Depot3
194
- - --line-numbers
195
- - --main
194
+ - "--line-numbers"
195
+ - "--main"
196
196
  - README.md
197
197
  require_paths:
198
198
  - lib
199
199
  required_ruby_version: !ruby/object:Gem::Requirement
200
200
  requirements:
201
- - - '>='
201
+ - - ">="
202
202
  - !ruby/object:Gem::Version
203
203
  version: 2.0.0
204
204
  required_rubygems_version: !ruby/object:Gem::Requirement
205
205
  requirements:
206
- - - '>='
206
+ - - ">="
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
209
  requirements: []
210
210
  rubyforge_project:
211
- rubygems_version: 2.6.1
211
+ rubygems_version: 2.6.8
212
212
  signing_key:
213
213
  specification_version: 4
214
214
  summary: A package/patch management system for OS X which extends the capabilites
215
215
  of the Casper Suite.
216
216
  test_files: []
217
- has_rdoc: true