vanagon 0.16.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +48 -23
  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/extras/completions/vanagon.bash +38 -0
  12. data/extras/completions/vanagon.zsh +41 -0
  13. data/lib/vanagon/cli.rb +12 -2
  14. data/lib/vanagon/cli/build.rb +12 -3
  15. data/lib/vanagon/cli/build_host_info.rb +12 -3
  16. data/lib/vanagon/cli/build_requirements.rb +13 -5
  17. data/lib/vanagon/cli/completion.rb +44 -0
  18. data/lib/vanagon/cli/inspect.rb +12 -3
  19. data/lib/vanagon/cli/list.rb +74 -0
  20. data/lib/vanagon/cli/render.rb +11 -2
  21. data/lib/vanagon/cli/ship.rb +6 -5
  22. data/lib/vanagon/cli/sign.rb +3 -2
  23. data/lib/vanagon/component.rb +11 -9
  24. data/lib/vanagon/component/dsl.rb +6 -5
  25. data/lib/vanagon/component/source.rb +2 -1
  26. data/lib/vanagon/component/source/git.rb +7 -6
  27. data/lib/vanagon/component/source/http.rb +3 -2
  28. data/lib/vanagon/component/source/local.rb +2 -1
  29. data/lib/vanagon/component/source/rewrite.rb +3 -2
  30. data/lib/vanagon/driver.rb +35 -34
  31. data/lib/vanagon/engine/always_be_scheduling.rb +272 -1
  32. data/lib/vanagon/engine/docker.rb +2 -1
  33. data/lib/vanagon/engine/ec2.rb +5 -4
  34. data/lib/vanagon/engine/hardware.rb +4 -3
  35. data/lib/vanagon/engine/pooler.rb +13 -8
  36. data/lib/vanagon/environment.rb +3 -2
  37. data/lib/vanagon/logger.rb +31 -0
  38. data/lib/vanagon/platform.rb +6 -5
  39. data/lib/vanagon/platform/deb.rb +2 -0
  40. data/lib/vanagon/platform/dsl.rb +5 -4
  41. data/lib/vanagon/platform/windows.rb +3 -1
  42. data/lib/vanagon/project.rb +20 -14
  43. data/lib/vanagon/project/dsl.rb +6 -5
  44. data/lib/vanagon/utilities.rb +35 -12
  45. data/resources/deb/control.erb +1 -1
  46. data/resources/osx/postinstall.erb +5 -1
  47. data/resources/rpm/project.spec.erb +1 -1
  48. data/resources/solaris/10/depend.erb +2 -2
  49. data/resources/solaris/10/postinstall.erb +10 -2
  50. data/resources/solaris/11/p5m.erb +2 -2
  51. data/spec/lib/vanagon/cli_spec.rb +143 -0
  52. data/spec/lib/vanagon/component/dsl_spec.rb +9 -2
  53. data/spec/lib/vanagon/component_spec.rb +3 -2
  54. data/spec/lib/vanagon/driver_spec.rb +1 -1
  55. data/spec/lib/vanagon/engine/always_be_scheduling_spec.rb +113 -1
  56. data/spec/lib/vanagon/engine/ec2_spec.rb +2 -0
  57. data/spec/lib/vanagon/engine/pooler_spec.rb +1 -1
  58. data/spec/spec_helper.rb +1 -0
  59. metadata +32 -27
@@ -1,4 +1,5 @@
1
1
  require 'docopt'
2
+ require 'vanagon/logger'
2
3
 
3
4
  class Vanagon
4
5
  class CLI
@@ -10,15 +11,23 @@ class Vanagon
10
11
  Options:
11
12
  -h, --help Display help
12
13
  -c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
13
- -e, --engine ENGINE Custom engine to use [base, local, docker, pooler] [default: pooler]
14
+ -e, --engine ENGINE Custom engine to use [default: always_be_scheduling]
14
15
  -w, --workdir DIRECTORY Working directory on the local host
15
16
  -v, --verbose Only here for backwards compatibility. Does nothing.
17
+
18
+ Engines:
19
+ always_be_scheduling: default engine using Puppet's ABS infrastructure
20
+ docker: a docker container on the local host
21
+ ec2: an Amazon EC2 instance
22
+ hardware: a dedicated hardware device
23
+ local: the local machine, cannot be used with a target
24
+ pooler: [deprecated] Puppet's vmpooler
16
25
  DOCOPT
17
26
 
18
27
  def parse(argv)
19
28
  Docopt.docopt(DOCUMENTATION, { argv: argv })
20
29
  rescue Docopt::Exit => e
21
- puts e.message
30
+ VanagonLogger.error e.message
22
31
  exit 1
23
32
  end
24
33
 
@@ -28,7 +37,7 @@ class Vanagon
28
37
 
29
38
  platforms.each do |platform|
30
39
  driver = Vanagon::Driver.new(platform, project, options)
31
- $stdout.puts JSON.generate(driver.build_host_info)
40
+ VanagonLogger.warn JSON.generate(driver.build_host_info)
32
41
  end
33
42
  end
34
43
 
@@ -1,5 +1,6 @@
1
1
  require 'docopt'
2
2
  require 'json'
3
+ require 'vanagon/logger'
3
4
 
4
5
  class Vanagon
5
6
  class CLI
@@ -11,15 +12,23 @@ class Vanagon
11
12
  Options:
12
13
  -h, --help Display help
13
14
  -c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
14
- -e, --engine ENGINE Custom engine to use [base, local, docker, pooler] [default: pooler]
15
+ -e, --engine ENGINE Custom engine to use [default: always_be_scheduling]
15
16
  -w, --workdir DIRECTORY Working directory on the local host
16
17
  -v, --verbose Only here for backwards compatibility. Does nothing.
18
+
19
+ Engines:
20
+ always_be_scheduling: default engine using Puppet's ABS infrastructure
21
+ docker: a docker container on the local host
22
+ ec2: an Amazon EC2 instance
23
+ hardware: a dedicated hardware device
24
+ local: the local machine, cannot be used with a target
25
+ pooler: [deprecated] Puppet's vmpooler
17
26
  DOCOPT
18
27
 
19
28
  def parse(argv)
20
29
  Docopt.docopt(DOCUMENTATION, { argv: argv })
21
30
  rescue Docopt::Exit => e
22
- puts e.message
31
+ VanagonLogger.error e.message
23
32
  exit 1
24
33
  end
25
34
 
@@ -39,9 +48,8 @@ class Vanagon
39
48
  end
40
49
  end
41
50
 
42
- $stdout.puts
43
- $stdout.puts "**** External packages required to build #{project} on #{platform}: ***"
44
- $stdout.puts JSON.pretty_generate(build_requirements.flatten.uniq.sort)
51
+ VanagonLogger.warn "**** External packages required to build #{project} on #{platform}: ***"
52
+ VanagonLogger.warn JSON.pretty_generate(build_requirements.flatten.uniq.sort)
45
53
  end
46
54
 
47
55
  def options_translate(docopt_options)
@@ -0,0 +1,44 @@
1
+ require 'docopt'
2
+ require 'vanagon/logger'
3
+
4
+ class Vanagon
5
+ class CLI
6
+ class Completion < Vanagon::CLI
7
+ DOCUMENTATION = <<~DOCOPT.freeze
8
+ Usage:
9
+ completion [options]
10
+
11
+ Options:
12
+ -h, --help Display help
13
+ -s, --shell SHELL Specify shell for completion script [default: bash]
14
+ DOCOPT
15
+
16
+ def parse(argv)
17
+ Docopt.docopt(DOCUMENTATION, { argv: argv })
18
+ rescue Docopt::Exit => e
19
+ VanagonLogger.error e.message
20
+ exit 1
21
+ end
22
+
23
+ def run(options)
24
+ shell = options[:shell].downcase.strip
25
+ completion_file = File.expand_path(File.join('..', '..', '..', '..', 'extras', 'completions', "vanagon.#{shell}"), __FILE__)
26
+
27
+ if File.exist?(completion_file)
28
+ VanagonLogger.warn completion_file
29
+ exit 0
30
+ else
31
+ VanagonLogger.error "Could not find completion file for '#{shell}': No such file #{completion_file}"
32
+ exit 1
33
+ end
34
+ end
35
+
36
+ def options_translate(docopt_options)
37
+ translations = {
38
+ '--shell' => :shell,
39
+ }
40
+ return docopt_options.map { |k, v| [translations[k], v] }.to_h
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,6 @@
1
1
  require 'docopt'
2
2
  require 'json'
3
+ require 'vanagon/logger'
3
4
 
4
5
  class Vanagon
5
6
  class CLI
@@ -11,18 +12,26 @@ class Vanagon
11
12
  Options:
12
13
  -h, --help Display help
13
14
  -c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
14
- -e, --engine ENGINE Custom engine to use [base, local, docker, pooler] [default: pooler]
15
+ -e, --engine ENGINE Custom engine to use [default: always_be_scheduling]
15
16
 
16
17
  -p, --preserve [RULE] Rule for VM preservation: never, on-failure, always
17
18
  [Default: on-failure]
18
19
  -w, --workdir DIRECTORY Working directory on the local host
19
20
  -v, --verbose Only here for backwards compatibility. Does nothing.
21
+
22
+ Engines:
23
+ always_be_scheduling: default engine using Puppet's ABS infrastructure
24
+ docker: a docker container on the local host
25
+ ec2: an Amazon EC2 instance
26
+ hardware: a dedicated hardware device
27
+ local: the local machine, cannot be used with a target
28
+ pooler: [deprecated] Puppet's vmpooler
20
29
  DOCOPT
21
30
 
22
31
  def parse(argv)
23
32
  Docopt.docopt(DOCUMENTATION, { argv: argv })
24
33
  rescue Docopt::Exit => e
25
- puts e.message
34
+ VanagonLogger.error e.message
26
35
  exit 1
27
36
  end
28
37
 
@@ -33,7 +42,7 @@ class Vanagon
33
42
  platforms.each do |platform|
34
43
  driver = Vanagon::Driver.new(platform, project, options)
35
44
  components = driver.project.components.map(&:to_hash)
36
- $stdout.puts JSON.pretty_generate(components)
45
+ VanagonLogger.warn JSON.pretty_generate(components)
37
46
  end
38
47
  end
39
48
 
@@ -0,0 +1,74 @@
1
+ require 'docopt'
2
+ require 'vanagon/logger'
3
+
4
+ class Vanagon
5
+ class CLI
6
+ class List < Vanagon::CLI
7
+ DOCUMENTATION = <<~DOCOPT.freeze
8
+ Usage:
9
+ list [options]
10
+
11
+ Options:
12
+ -h, --help Display help
13
+ -c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
14
+ -l, --platforms Display a list of platforms
15
+ -r, --projects Display a list of projects
16
+ -s, --use-spaces Displays the list as space separated
17
+ DOCOPT
18
+
19
+ def parse(argv)
20
+ Docopt.docopt(DOCUMENTATION, { argv: argv })
21
+ rescue Docopt::Exit => e
22
+ VanagonLogger.error e.message
23
+ exit 1
24
+ end
25
+
26
+ def output(list, use_spaces)
27
+ return list.join(' ') if use_spaces
28
+ return list
29
+ end
30
+
31
+ def run(options) # rubocop:disable Metrics/AbcSize
32
+ if Dir.exist?(File.join(options[:configdir], 'platforms')) == false ||
33
+ Dir.exist?(File.join(options[:configdir], 'projects')) == false
34
+
35
+ VanagonLogger.error "Path to #{File.join(options[:configdir], 'platforms')} or #{File.join(options[:configdir], 'projects')} not found."
36
+ exit 1
37
+ end
38
+
39
+ platform_list = Dir.children(File.join(options[:configdir], 'platforms')).map do |platform|
40
+ File.basename(platform, File.extname(platform))
41
+ end
42
+
43
+ project_list = Dir.children(File.join(options[:configdir], 'projects')).map do |project|
44
+ File.basename(project, File.extname(project))
45
+ end
46
+
47
+ if options[:projects] == options[:platforms]
48
+ puts "- Projects", output(project_list, options[:use_spaces]), "\n", "- Platforms", output(platform_list, options[:use_spaces])
49
+ return
50
+ end
51
+
52
+ if options[:projects]
53
+ puts "- Projects", output(project_list, options[:use_spaces])
54
+ return
55
+ end
56
+
57
+ if options[:platforms]
58
+ puts "- Platforms", output(platform_list, options[:use_spaces])
59
+ return
60
+ end
61
+ end
62
+
63
+ def options_translate(docopt_options)
64
+ translations = {
65
+ '--configdir' => :configdir,
66
+ '--platforms' => :platforms,
67
+ '--projects' => :projects,
68
+ '--use-spaces' => :use_spaces,
69
+ }
70
+ return docopt_options.map { |k, v| [translations[k], v] }.to_h
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,5 +1,6 @@
1
1
  require 'docopt'
2
2
  require 'json'
3
+ require 'vanagon/logger'
3
4
 
4
5
  class Vanagon
5
6
  class CLI
@@ -11,15 +12,23 @@ class Vanagon
11
12
  Options:
12
13
  -h, --help Display help
13
14
  -c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
14
- -e, --engine ENGINE Custom engine to use [base, local, docker, pooler] [default: pooler]
15
+ -e, --engine ENGINE Custom engine to use [default: always_be_scheduling]
15
16
  -w, --workdir DIRECTORY Working directory on the local host
16
17
  -v, --verbose Only here for backwards compatibility. Does nothing.
18
+
19
+ Engines:
20
+ always_be_scheduling: default engine using Puppet's ABS infrastructure
21
+ docker: a docker container on the local host
22
+ ec2: an Amazon EC2 instance
23
+ hardware: a dedicated hardware device
24
+ local: the local machine, cannot be used with a target
25
+ pooler: [deprecated] Puppet's vmpooler
17
26
  DOCOPT
18
27
 
19
28
  def parse(argv)
20
29
  Docopt.docopt(DOCUMENTATION, { argv: argv })
21
30
  rescue Docopt::Exit => e
22
- puts e.message
31
+ VanagonLogger.error e.message
23
32
  exit 1
24
33
  end
25
34
 
@@ -1,4 +1,5 @@
1
1
  require 'docopt'
2
+ require 'vanagon/logger'
2
3
 
3
4
  class Vanagon
4
5
  class CLI
@@ -11,10 +12,10 @@ class Vanagon
11
12
  -h, --help Display help
12
13
  DOCOPT
13
14
 
14
- def self.parse(argv)
15
+ def parse(argv)
15
16
  Docopt.docopt(DOCUMENTATION, { argv: argv })
16
17
  rescue Docopt::Exit => e
17
- puts e.message
18
+ VanagonLogger.error e.message
18
19
  exit 1
19
20
  end
20
21
 
@@ -32,7 +33,7 @@ class Vanagon
32
33
  DOC
33
34
 
34
35
  if Dir['output/**/*'].select { |entry| File.file?(entry) }.empty?
35
- warn 'vanagon: Error: No packages to ship in the "output" directory. Maybe build some first?'
36
+ VanagonLogger.error 'vanagon: Error: No packages to ship in the "output" directory. Maybe build some first?'
36
37
  exit 1
37
38
  end
38
39
 
@@ -42,9 +43,9 @@ class Vanagon
42
43
  begin
43
44
  Pkg::Util::RakeUtils.invoke_task('pl:jenkins:ship_to_artifactory', 'output')
44
45
  rescue LoadError
45
- warn artifactory_warning
46
+ VanagonLogger.error artifactory_warning
46
47
  rescue StandardError
47
- warn artifactory_warning
48
+ VanagonLogger.error artifactory_warning
48
49
  end
49
50
  end
50
51
  end
@@ -1,4 +1,5 @@
1
1
  require 'docopt'
2
+ require 'vanagon/logger'
2
3
 
3
4
  class Vanagon
4
5
  class CLI
@@ -14,14 +15,14 @@ class Vanagon
14
15
  def parse(argv)
15
16
  Docopt.docopt(DOCUMENTATION, { argv: argv })
16
17
  rescue Docopt::Exit => e
17
- puts e.message
18
+ VanagonLogger.error e.message
18
19
  exit 1
19
20
  end
20
21
 
21
22
  def run(_)
22
23
  ENV['PROJECT_ROOT'] = Dir.pwd
23
24
  if Dir['output/**/*'].select { |entry| File.file?(entry) }.empty?
24
- warn 'sign: Error: No packages to sign in the "output" directory. Maybe build some first?'
25
+ VanagonLogger.error 'sign: Error: No packages to sign in the "output" directory. Maybe build some first?'
25
26
  exit 1
26
27
  end
27
28
 
@@ -3,6 +3,8 @@ require 'vanagon/component/rules'
3
3
  require 'vanagon/component/source'
4
4
  require 'vanagon/component/source/rewrite'
5
5
 
6
+ require 'vanagon/logger'
7
+
6
8
  class Vanagon
7
9
  class Component
8
10
  include Vanagon::Utilities
@@ -138,9 +140,9 @@ class Vanagon
138
140
  dsl.instance_eval(File.read(compfile), compfile, 1)
139
141
  dsl._component
140
142
  rescue StandardError => e
141
- warn "Error loading project '#{name}' using '#{compfile}':"
142
- warn e
143
- warn e.backtrace.join("\n")
143
+ VanagonLogger.error "Error loading project '#{name}' using '#{compfile}':"
144
+ VanagonLogger(e)
145
+ VanagonLogger.error e.backtrace.join("\n")
144
146
  raise e
145
147
  end
146
148
 
@@ -254,18 +256,18 @@ class Vanagon
254
256
  def fetch_mirrors(options)
255
257
  mirrors.to_a.shuffle.each do |mirror|
256
258
  begin
257
- warn %(Attempting to fetch from mirror URL "#{mirror}")
259
+ VanagonLogger.info %(Attempting to fetch from mirror URL "#{mirror}")
258
260
  @source = Vanagon::Component::Source.source(mirror, options)
259
261
  return true if source.fetch
260
262
  rescue SocketError
261
263
  # SocketError means that there was no DNS/name resolution
262
264
  # for whatever remote protocol the mirror tried to use.
263
- warn %(Unable to resolve mirror URL "#{mirror}")
265
+ VanagonLogger.error %(Unable to resolve mirror URL "#{mirror}")
264
266
  rescue RuntimeError
265
267
  # Source retrieval does not consistently return a meaningful
266
268
  # namespaced error message, which means we're brute-force rescuing
267
269
  # RuntimeError. Not a good look, and we should fix this.
268
- warn %(Unable to retrieve mirror URL "#{mirror}")
270
+ VanagonLogger.error %(Unable to retrieve mirror URL "#{mirror}")
269
271
  end
270
272
  end
271
273
  false
@@ -277,7 +279,7 @@ class Vanagon
277
279
  # @return [Boolean] return True if the source can be retrieved,
278
280
  # or False otherwise
279
281
  def fetch_url(options)
280
- warn %(Attempting to fetch from canonical URL "#{url}")
282
+ VanagonLogger.info %(Attempting to fetch from canonical URL "#{url}")
281
283
  @source = Vanagon::Component::Source.source(url, options)
282
284
  # Explicitly coerce the return value of #source.fetch,
283
285
  # because each subclass of Vanagon::Component::Source returns
@@ -319,7 +321,7 @@ class Vanagon
319
321
  @version ||= source.version
320
322
  end
321
323
  else
322
- warn "No source given for component '#{@name}'"
324
+ VanagonLogger.info "No source given for component '#{@name}'"
323
325
 
324
326
  # If there is no source, we don't want to try to change directories, so we just change to the current directory.
325
327
  @dirname = './'
@@ -407,7 +409,7 @@ class Vanagon
407
409
  # @return [String] environment suitable for inclusion in a Makefile
408
410
  # @deprecated
409
411
  def get_environment
410
- warn <<-WARNING.undent
412
+ VanagonLogger.info <<-WARNING.undent
411
413
  #get_environment is deprecated; environment variables have been moved
412
414
  into the Makefile, and should not be used within a Makefile's recipe.
413
415
  The #get_environment method will be removed by Vanagon 1.0.0.
@@ -1,4 +1,5 @@
1
1
  require 'vanagon/component'
2
+ require 'vanagon/logger'
2
3
  require 'vanagon/patch'
3
4
  require 'ostruct'
4
5
  require 'json'
@@ -131,8 +132,8 @@ class Vanagon
131
132
  # component
132
133
  #
133
134
  # @param requirement [String] a package that is required at runtime for this component
134
- def requires(requirement)
135
- @component.requires << requirement
135
+ def requires(requirement, version = nil)
136
+ @component.requires << OpenStruct.new(:requirement => requirement, :version => version)
136
137
  end
137
138
 
138
139
  # Indicates that this component replaces a system level package. Replaces can be collected and used by the project and package.
@@ -237,7 +238,7 @@ class Vanagon
237
238
 
238
239
  if @component.platform.is_windows?
239
240
  unless mode.nil? && owner.nil? && group.nil?
240
- warn "You're trying to set the mode, owner, or group for windows. I don't know how to do that, ignoring!"
241
+ VanagonLogger.info "You're trying to set the mode, owner, or group for windows. I don't know how to do that, ignoring!"
241
242
  end
242
243
  else
243
244
  mode ||= '0644'
@@ -407,7 +408,7 @@ class Vanagon
407
408
  install_flags = ['-d']
408
409
  if @component.platform.is_windows?
409
410
  unless mode.nil? && owner.nil? && group.nil?
410
- warn "You're trying to set the mode, owner, or group for windows. I don't know how to do that, ignoring!"
411
+ VanagonLogger.info "You're trying to set the mode, owner, or group for windows. I don't know how to do that, ignoring!"
411
412
  end
412
413
  else
413
414
  install_flags << "-m '#{mode}'" unless mode.nil?
@@ -422,7 +423,7 @@ class Vanagon
422
423
  # @param env [Hash] mapping of keys to values to add to the environment for the component
423
424
  def environment(*env)
424
425
  if env.size == 1 && env.first.is_a?(Hash)
425
- warn <<-WARNING.undent
426
+ VanagonLogger.info <<-WARNING.undent
426
427
  the component DSL method signature #environment({Key => Value}) is deprecated
427
428
  and will be removed by Vanagon 1.0.0.
428
429