vanagon 0.18.0 → 0.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/bin/build +3 -1
  4. data/bin/build_host_info +3 -1
  5. data/bin/build_requirements +3 -1
  6. data/bin/inspect +3 -1
  7. data/bin/render +3 -1
  8. data/bin/repo +3 -1
  9. data/bin/ship +3 -1
  10. data/bin/sign +3 -1
  11. data/lib/vanagon/cli.rb +4 -2
  12. data/lib/vanagon/cli/build.rb +2 -1
  13. data/lib/vanagon/cli/build_host_info.rb +3 -2
  14. data/lib/vanagon/cli/build_requirements.rb +4 -4
  15. data/lib/vanagon/cli/completion.rb +4 -3
  16. data/lib/vanagon/cli/inspect.rb +3 -2
  17. data/lib/vanagon/cli/list.rb +5 -6
  18. data/lib/vanagon/cli/render.rb +2 -1
  19. data/lib/vanagon/cli/ship.rb +4 -19
  20. data/lib/vanagon/cli/sign.rb +3 -2
  21. data/lib/vanagon/component.rb +13 -10
  22. data/lib/vanagon/component/dsl.rb +27 -20
  23. data/lib/vanagon/component/source.rb +2 -1
  24. data/lib/vanagon/component/source/git.rb +35 -10
  25. data/lib/vanagon/component/source/http.rb +3 -2
  26. data/lib/vanagon/component/source/local.rb +2 -1
  27. data/lib/vanagon/component/source/rewrite.rb +3 -2
  28. data/lib/vanagon/driver.rb +20 -21
  29. data/lib/vanagon/engine/always_be_scheduling.rb +12 -11
  30. data/lib/vanagon/engine/docker.rb +2 -1
  31. data/lib/vanagon/engine/ec2.rb +5 -4
  32. data/lib/vanagon/engine/hardware.rb +4 -3
  33. data/lib/vanagon/engine/pooler.rb +6 -5
  34. data/lib/vanagon/environment.rb +3 -2
  35. data/lib/vanagon/logger.rb +31 -0
  36. data/lib/vanagon/platform.rb +38 -5
  37. data/lib/vanagon/platform/dsl.rb +23 -6
  38. data/lib/vanagon/platform/windows.rb +3 -1
  39. data/lib/vanagon/project.rb +25 -15
  40. data/lib/vanagon/project/dsl.rb +6 -5
  41. data/lib/vanagon/utilities.rb +5 -4
  42. data/resources/deb/control.erb +1 -1
  43. data/resources/deb/postinst.erb +24 -13
  44. data/resources/deb/postrm.erb +9 -6
  45. data/resources/deb/prerm.erb +18 -8
  46. data/resources/osx/postinstall.erb +6 -2
  47. data/resources/rpm/project.spec.erb +12 -12
  48. data/resources/solaris/10/depend.erb +2 -2
  49. data/resources/solaris/10/postinstall.erb +11 -3
  50. data/resources/solaris/11/p5m.erb +2 -2
  51. data/spec/lib/vanagon/cli_spec.rb +1 -4
  52. data/spec/lib/vanagon/component/dsl_spec.rb +54 -10
  53. data/spec/lib/vanagon/component/source/git_spec.rb +4 -4
  54. data/spec/lib/vanagon/component_spec.rb +15 -2
  55. data/spec/lib/vanagon/engine/always_be_scheduling_spec.rb +4 -4
  56. data/spec/lib/vanagon/platform_spec.rb +80 -0
  57. data/spec/lib/vanagon/utilities_spec.rb +4 -1
  58. metadata +32 -31
@@ -1,4 +1,5 @@
1
1
  require 'vanagon/engine/base'
2
+ require 'vanagon/logger'
2
3
 
3
4
  class Vanagon
4
5
  class Engine
@@ -52,7 +53,7 @@ class Vanagon
52
53
  Vanagon::Utilities.ex("#{@docker_cmd} stop #{build_host_name}-builder")
53
54
  Vanagon::Utilities.ex("#{@docker_cmd} rm #{build_host_name}-builder")
54
55
  rescue Vanagon::Error => e
55
- warn "There was a problem tearing down the docker container #{build_host_name}-builder (#{e.message})."
56
+ VanagonLogger.error "There was a problem tearing down the docker container #{build_host_name}-builder (#{e.message})."
56
57
  end
57
58
 
58
59
  def dispatch(command, return_output = false)
@@ -2,6 +2,7 @@ require 'aws-sdk'
2
2
  require 'erb'
3
3
  require 'base64'
4
4
  require 'vanagon/engine/base'
5
+ require 'vanagon/logger'
5
6
 
6
7
  class Vanagon
7
8
  class Engine
@@ -57,17 +58,17 @@ class Vanagon
57
58
  end
58
59
 
59
60
  def select_target
60
- warn "Instance created id: #{instance.id}"
61
- warn "Created instance waiting for status ok"
61
+ VanagonLogger.info "Instance created id: #{instance.id}"
62
+ VanagonLogger.info "Created instance waiting for status ok"
62
63
  @ec2.wait_until(:instance_status_ok, instance_ids: [instance.id])
63
- warn "Instance running"
64
+ VanagonLogger.info "Instance running"
64
65
  @target = instance.private_ip_address
65
66
  rescue ::Aws::Waiters::Errors::WaiterFailed => error
66
67
  fail "Failed to wait for ec2 instance to start got error #{error}"
67
68
  end
68
69
 
69
70
  def teardown
70
- warn "Destroying instance on AWS id: #{instance.id}"
71
+ VanagonLogger.info "Destroying instance on AWS id: #{instance.id}"
71
72
  instances.batch_terminate!
72
73
  end
73
74
  end
@@ -1,4 +1,5 @@
1
1
  require 'vanagon/engine/base'
2
+ require 'vanagon/logger'
2
3
  require 'json'
3
4
  require 'lock_manager'
4
5
 
@@ -23,7 +24,7 @@ class Vanagon
23
24
  Vanagon::Driver.logger.info "Polling for a lock on #{host}."
24
25
  @lockman.polling_lock(host, VANAGON_LOCK_USER, "Vanagon automated lock")
25
26
  Vanagon::Driver.logger.info "Lock acquired on #{host}."
26
- warn "Lock acquired on #{host} for #{VANAGON_LOCK_USER}."
27
+ VanagonLogger.info "Lock acquired on #{host} for #{VANAGON_LOCK_USER}."
27
28
  host
28
29
  end
29
30
 
@@ -33,7 +34,7 @@ class Vanagon
33
34
  Vanagon::Driver.logger.info "Attempting to lock #{h}."
34
35
  if @lockman.lock(h, VANAGON_LOCK_USER, "Vanagon automated lock")
35
36
  Vanagon::Driver.logger.info "Lock acquired on #{h}."
36
- warn "Lock acquired on #{h} for #{VANAGON_LOCK_USER}."
37
+ VanagonLogger.info "Lock acquired on #{h} for #{VANAGON_LOCK_USER}."
37
38
  return h
38
39
  end
39
40
  end
@@ -45,7 +46,7 @@ class Vanagon
45
46
  # complete. In this case, we'll attempt to unlock the hardware
46
47
  def teardown
47
48
  Vanagon::Driver.logger.info "Removing lock on #{@target}."
48
- warn "Removing lock on #{@target}."
49
+ VanagonLogger.info "Removing lock on #{@target}."
49
50
  @lockman.unlock(@target, VANAGON_LOCK_USER)
50
51
  end
51
52
 
@@ -1,4 +1,5 @@
1
1
  require 'vanagon/engine/base'
2
+ require 'vanagon/logger'
2
3
  require 'yaml'
3
4
 
4
5
  ### Note this class is deprecated in favor of using the ABS Engine. The pooler has changed it's API with regards to
@@ -60,7 +61,7 @@ class Vanagon
60
61
  absolute_path = File.expand_path(path)
61
62
  return nil unless File.exist?(absolute_path)
62
63
 
63
- warn "Reading vmpooler token from: #{path}"
64
+ VanagonLogger.info "Reading vmpooler token from: #{path}"
64
65
  File.read(absolute_path).chomp
65
66
  end
66
67
  private :read_vanagon_token
@@ -74,7 +75,7 @@ class Vanagon
74
75
  absolute_path = File.expand_path(path)
75
76
  return nil unless File.exist?(absolute_path)
76
77
 
77
- warn "Reading vmpooler token from: #{path}"
78
+ VanagonLogger.info "Reading vmpooler token from: #{path}"
78
79
  YAML.load_file(absolute_path)['token']
79
80
  end
80
81
  private :read_vmfloaty_token
@@ -145,14 +146,14 @@ class Vanagon
145
146
  )
146
147
  if response and response["ok"]
147
148
  Vanagon::Driver.logger.info "#{@target} has been destroyed"
148
- warn "#{@target} has been destroyed"
149
+ VanagonLogger.info "#{@target} has been destroyed"
149
150
  else
150
151
  Vanagon::Driver.logger.info "#{@target} could not be destroyed"
151
- warn "#{@target} could not be destroyed"
152
+ VanagonLogger.info "#{@target} could not be destroyed"
152
153
  end
153
154
  rescue Vanagon::Error => e
154
155
  Vanagon::Driver.logger.info "#{@target} could not be destroyed (#{e.message})"
155
- warn "#{@target} could not be destroyed (#{e.message})"
156
+ VanagonLogger.error "#{@target} could not be destroyed (#{e.message})"
156
157
  end
157
158
  end
158
159
  end
@@ -1,5 +1,6 @@
1
1
  require 'forwardable'
2
2
  require 'vanagon/extensions/string'
3
+ require 'vanagon/logger'
3
4
 
4
5
  class Vanagon
5
6
  # Environment is a validating wrapper around a delegated Hash,
@@ -147,7 +148,7 @@ class Vanagon
147
148
  update your project's parameters.
148
149
  WARNING
149
150
 
150
- warn warning.join("\n")
151
+ VanagonLogger.info warning.join("\n")
151
152
  str.gsub(pattern, '$(shell \1)')
152
153
  end
153
154
  private :sanitize_subshells
@@ -165,7 +166,7 @@ class Vanagon
165
166
  update your project's parameters.
166
167
  WARNING
167
168
 
168
- warn warning.join("\n")
169
+ VanagonLogger.info warning.join("\n")
169
170
  str.gsub(pattern, '$(\1)')
170
171
  end
171
172
  private :sanitize_variables
@@ -0,0 +1,31 @@
1
+ require 'logger'
2
+
3
+ class VanagonLogger < ::Logger
4
+ def self.logger
5
+ @@logger ||= VanagonLogger.new
6
+ end
7
+
8
+ def self.debug_logger
9
+ @@debug_logger ||= VanagonLogger.new(STDERR)
10
+ end
11
+
12
+ def self.info(msg)
13
+ VanagonLogger.debug_logger.info msg
14
+ end
15
+
16
+ def self.warn(msg)
17
+ VanagonLogger.logger.warn msg
18
+ end
19
+
20
+ def self.error(msg)
21
+ VanagonLogger.logger.error msg
22
+ end
23
+
24
+ def initialize(output = STDOUT)
25
+ super(output)
26
+ self.level = ::Logger::INFO
27
+ self.formatter = proc do |severity, datetime, progname, msg|
28
+ "#{msg}\n"
29
+ end
30
+ end
31
+ end
@@ -1,6 +1,7 @@
1
1
  require 'vanagon/environment'
2
2
  require 'vanagon/platform/dsl'
3
3
  require 'vanagon/utilities'
4
+ require 'vanagon/logger'
4
5
 
5
6
  class Vanagon
6
7
  class Platform
@@ -32,6 +33,9 @@ class Vanagon
32
33
  # Where does a given platform expect to find init scripts/service files?
33
34
  # e.g. /etc/init.d, /usr/lib/systemd/system
34
35
  attr_accessor :servicedir
36
+ # Array of OpenStructs containing the servicetype and the corresponding
37
+ # servicedir
38
+ attr_accessor :servicetypes
35
39
  # Where does a given platform's init system expect to find
36
40
  # something resembling 'defaults' files. Most likely to apply
37
41
  # to Linux systems that use SysV-ish, upstart, or systemd init systems.
@@ -152,9 +156,9 @@ class Vanagon
152
156
  dsl.instance_eval(File.read(platfile), platfile, 1)
153
157
  dsl._platform
154
158
  rescue StandardError => e
155
- warn "Error loading platform '#{name}' using '#{platfile}':"
156
- warn e
157
- warn e.backtrace.join("\n")
159
+ VanagonLogger.error "Error loading platform '#{name}' using '#{platfile}':"
160
+ VanagonLogger.error(e)
161
+ VanagonLogger.error e.backtrace.join("\n")
158
162
  raise e
159
163
  end
160
164
 
@@ -244,6 +248,7 @@ class Vanagon
244
248
  # Our first attempt at defining metadata about a platform
245
249
  @cross_compiled ||= false
246
250
  @valid_operators ||= ['<', '>', '<=', '>=', '=']
251
+ @servicetypes = []
247
252
  end
248
253
 
249
254
  def shell # rubocop:disable Lint/DuplicateMethods
@@ -401,7 +406,7 @@ class Vanagon
401
406
  # @deprecated Please use is_macos? instead
402
407
  # @return [true, false] true if it is an osx variety, false otherwise
403
408
  def is_osx?
404
- warn "is_osx? is a deprecated method, please use #is_macos? instead."
409
+ VanagonLogger.info "is_osx? is a deprecated method, please use #is_macos? instead."
405
410
  is_macos?
406
411
  end
407
412
 
@@ -539,7 +544,7 @@ class Vanagon
539
544
  match = version_string.match(VERSION_REGEX)
540
545
 
541
546
  if match.nil?
542
- warn "Passing a version without an operator is deprecated!"
547
+ VanagonLogger.info "Passing a version without an operator is deprecated!"
543
548
  operator = default
544
549
  version = version_string
545
550
  end
@@ -552,5 +557,33 @@ class Vanagon
552
557
  def validate_operator(operator_string)
553
558
  valid_operators.include?(operator_string)
554
559
  end
560
+
561
+ # Get all configured service types (added through plat.servicetype)
562
+ # @return array of service types, empty array if none have been configured
563
+ def get_service_types
564
+ if @servicetypes.any?
565
+ @servicetypes.flat_map(&:servicetype).compact
566
+ elsif @servicetype
567
+ [@servicetype]
568
+ else
569
+ []
570
+ end
571
+ end
572
+
573
+ # Get configured service dir (added through plat.servicedir, or plat.servicetype 'foo', servicedir: 'bar')
574
+ # @param servicetype the service type you want the service dir for (optional)
575
+ # @raises VanagonError if more than one service dir is found
576
+ def get_service_dir(servicetype = '')
577
+ if @servicetypes.empty?
578
+ return @servicedir
579
+ end
580
+ servicedir = @servicetypes.select { |s| s.servicetype.include?(servicetype) }.flat_map(&:servicedir).compact
581
+
582
+ if servicedir.size > 1
583
+ raise Vanagon::Error, "You can only have one service dir for each service type. Found '#{servicedir.join(',')}' for service type #{servicetype}"
584
+ end
585
+
586
+ servicedir.first
587
+ end
555
588
  end
556
589
  end
@@ -8,7 +8,9 @@ require 'vanagon/platform/osx'
8
8
  require 'vanagon/platform/solaris_10'
9
9
  require 'vanagon/platform/solaris_11'
10
10
  require 'vanagon/platform/windows'
11
+ require 'vanagon/logger'
11
12
  require 'securerandom'
13
+ require 'ostruct'
12
14
  require 'uri'
13
15
 
14
16
  class Vanagon
@@ -218,6 +220,11 @@ class Vanagon
218
220
  # @param dir [String] Directory where service files live on the platform
219
221
  def servicedir(dir)
220
222
  @platform.servicedir = dir
223
+
224
+ # Add to the servicetypes array if we haven't already
225
+ if @platform.servicetype && @platform.servicedir && @platform.servicetypes.select { |s| s.servicetype == @platform.servicetype }.empty?
226
+ @platform.servicetypes << OpenStruct.new(:servicetype => @platform.servicetype, :servicedir => @platform.servicedir)
227
+ end
221
228
  end
222
229
 
223
230
  # Set the directory where default or sysconfig files live for the platform
@@ -230,8 +237,18 @@ class Vanagon
230
237
  # Set the servicetype for the platform so that services can be installed correctly.
231
238
  #
232
239
  # @param type [String] service type for the platform ('sysv' for example)
233
- def servicetype(type)
234
- @platform.servicetype = type
240
+ # @param servicedir [String] service dir for this platform and service type ('/etc/init.d' for example). Optional.
241
+ def servicetype(type, servicedir: nil) # rubocop:disable Metrics/AbcSize
242
+ if servicedir
243
+ @platform.servicetypes << OpenStruct.new(:servicetype => type, :servicedir => servicedir)
244
+ else
245
+ @platform.servicetype = type
246
+ end
247
+
248
+ # Add to the servicetypes array if we haven't already
249
+ if @platform.servicetype && @platform.servicedir && @platform.servicetypes.select { |s| s.servicetype == @platform.servicetype }.empty?
250
+ @platform.servicetypes << OpenStruct.new(:servicetype => @platform.servicetype, :servicedir => @platform.servicedir)
251
+ end
235
252
  end
236
253
 
237
254
  # Set the list of possible host to perform a build on (when not using
@@ -259,7 +276,7 @@ class Vanagon
259
276
  # @param name [String] name that the pooler uses for this platform
260
277
  # @deprecated Please use vmpooler_template instead, this will be removed in a future vanagon release.
261
278
  def vcloud_name(cloud_name)
262
- warn "vcloud_name is a deprecated platform DSL method, and will be removed in a future vanagon release. Please use vmpooler_template instead."
279
+ VanagonLogger.info "vcloud_name is a deprecated platform DSL method, and will be removed in a future vanagon release. Please use vmpooler_template instead."
263
280
  self.vmpooler_template(cloud_name)
264
281
  end
265
282
 
@@ -394,7 +411,7 @@ class Vanagon
394
411
  # @param gpg_key [String] optional gpg key to be fetched via curl and installed
395
412
  # @deprecated Please use the add_build_repository DSL method instead. apt_repo will be removed in a future vanagon release.
396
413
  def apt_repo(definition, gpg_key = nil)
397
- warn "Please use the add_build_repository DSL method instead. apt_repo will be removed in a future vanagon release."
414
+ VanagonLogger.info "Please use the add_build_repository DSL method instead. apt_repo will be removed in a future vanagon release."
398
415
  self.add_build_repository(definition, gpg_key)
399
416
  end
400
417
 
@@ -403,7 +420,7 @@ class Vanagon
403
420
  # @param definition [String] the repo setup URI or RPM file
404
421
  # @deprecated Please use the add_build_repository DSL method instead. yum_repo will be removed in a future vanagon release.
405
422
  def yum_repo(definition)
406
- warn "Please use the add_build_repository DSL method instead. yum_repo will be removed in a future vanagon release."
423
+ VanagonLogger.info "Please use the add_build_repository DSL method instead. yum_repo will be removed in a future vanagon release."
407
424
  self.add_build_repository(definition)
408
425
  end
409
426
 
@@ -412,7 +429,7 @@ class Vanagon
412
429
  # @param definition [String] the repo setup URI or RPM file
413
430
  # @deprecated Please use the add_build_repository DSL method instead. zypper_repo will be removed in a future vanagon release.
414
431
  def zypper_repo(definition)
415
- warn "Please use the add_build_repository DSL method instead. zypper_repo will be removed in a future vanagon release."
432
+ VanagonLogger.info "Please use the add_build_repository DSL method instead. zypper_repo will be removed in a future vanagon release."
416
433
  self.add_build_repository(definition)
417
434
  end
418
435
 
@@ -1,3 +1,5 @@
1
+ require 'vanagon/logger'
2
+
1
3
  class Vanagon
2
4
  class Platform
3
5
  class Windows < Vanagon::Platform
@@ -231,7 +233,7 @@ class Vanagon
231
233
  ]
232
234
  end
233
235
  rescue RuntimeError
234
- warn "Unable to connect to #{project.signing_username}@#{project.signing_hostname}, skipping signing extra files: #{project.extra_files_to_sign.join(',')}"
236
+ VanagonLogger.error "Unable to connect to #{project.signing_username}@#{project.signing_hostname}, skipping signing extra files: #{project.extra_files_to_sign.join(',')}"
235
237
  end
236
238
  end
237
239
  make_commands << [
@@ -1,5 +1,6 @@
1
1
  require 'vanagon/component'
2
2
  require 'vanagon/environment'
3
+ require 'vanagon/logger'
3
4
  require 'vanagon/platform'
4
5
  require 'vanagon/project/dsl'
5
6
  require 'vanagon/utilities'
@@ -130,9 +131,9 @@ class Vanagon
130
131
  dsl.instance_eval(File.read(projfile), projfile, 1)
131
132
  dsl._project
132
133
  rescue StandardError => e
133
- warn "Error loading project '#{name}' using '#{projfile}':"
134
- warn e
135
- warn e.backtrace.join("\n")
134
+ VanagonLogger.error "Error loading project '#{name}' using '#{projfile}':"
135
+ VanagonLogger.error(e)
136
+ VanagonLogger.error e.backtrace.join("\n")
136
137
  raise e
137
138
  end
138
139
 
@@ -296,10 +297,14 @@ class Vanagon
296
297
  #
297
298
  # @return [Array] array of runtime requirements for the project
298
299
  def get_requires
299
- req = []
300
- req << components.flat_map(&:requires)
301
- req << @requires
302
- req.flatten.uniq
300
+ requires = []
301
+ requires << @requires.flatten
302
+ requires << components.flat_map(&:requires)
303
+ requires.flatten!
304
+ requires.each do |requirement|
305
+ requirement.version = @platform.version_munger(requirement.version, default: '<') if requirement.version
306
+ end
307
+ requires.uniq
303
308
  end
304
309
 
305
310
  # Collects all of the replacements for the project and its components
@@ -307,8 +312,8 @@ class Vanagon
307
312
  # @return [Array] array of package level replacements for the project
308
313
  def get_replaces
309
314
  replaces = []
310
- replaces.push @replaces.flatten
311
- replaces.push components.flat_map(&:replaces)
315
+ replaces << @replaces.flatten
316
+ replaces << components.flat_map(&:replaces)
312
317
  replaces.flatten!
313
318
  replaces.each do |replace|
314
319
  # TODO: Make this a more reasonable default before 1.0.0
@@ -324,8 +329,9 @@ class Vanagon
324
329
 
325
330
  # Collects all of the conflicts for the project and its components
326
331
  def get_conflicts
327
- conflicts = components.flat_map(&:conflicts) + @conflicts
328
- # Mash the whole thing down into a flat Array
332
+ conflicts = []
333
+ conflicts << @conflicts.flatten
334
+ conflicts << components.flat_map(&:conflicts)
329
335
  conflicts.flatten!
330
336
  conflicts.each do |conflict|
331
337
  # TODO: Make this a more reasonable default before 1.0.0
@@ -345,10 +351,14 @@ class Vanagon
345
351
  # will return nil
346
352
  #
347
353
  # @param [string] name of service to grab
348
- # @return [@component.service obj] specific service
354
+ # @return [@component.service obj] specific service, or array of services
355
+ # if there's more than one
349
356
  def get_service(name)
350
357
  components.each do |component|
351
358
  if component.name == name
359
+ if component.service.size == 1
360
+ return component.service.first
361
+ end
352
362
  return component.service
353
363
  end
354
364
  end
@@ -360,8 +370,8 @@ class Vanagon
360
370
  # @return [Array] array of package level provides for the project
361
371
  def get_provides
362
372
  provides = []
363
- provides.push @provides.flatten
364
- provides.push components.flat_map(&:provides)
373
+ provides << @provides.flatten
374
+ provides << components.flat_map(&:provides)
365
375
  provides.flatten!
366
376
  provides.each do |provide|
367
377
  # TODO: Make this a more reasonable default before 1.0.0
@@ -841,7 +851,7 @@ class Vanagon
841
851
  end
842
852
 
843
853
  def load_upstream_metadata(metadata_uri)
844
- warn "Loading metadata from #{metadata_uri}"
854
+ VanagonLogger.info "Loading metadata from #{metadata_uri}"
845
855
  case metadata_uri
846
856
  when /^http/
847
857
  @upstream_metadata = JSON.parse(Net::HTTP.get(URI(metadata_uri)))