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 '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,6 +1,11 @@
1
1
  require 'vanagon/engine/base'
2
+ require 'vanagon/logger'
2
3
  require 'yaml'
3
4
 
5
+ ### Note this class is deprecated in favor of using the ABS Engine. The pooler has changed it's API with regards to
6
+ # getting VMs for ondemand provisioning and would need to be updated here.
7
+ # See DIO-1066
8
+
4
9
  class Vanagon
5
10
  class Engine
6
11
  class Pooler < Base
@@ -10,7 +15,7 @@ class Vanagon
10
15
  def initialize(platform, target = nil, **opts)
11
16
  super
12
17
 
13
- @available_poolers = ["http://vmpooler.delivery.puppetlabs.net", "https://nspooler-service-prod-1.delivery.puppetlabs.net"]
18
+ @available_poolers = ["https://vmpooler.delivery.puppetlabs.net", "https://nspooler-service-prod-1.delivery.puppetlabs.net"]
14
19
  @token = load_token
15
20
  @required_attributes << "vmpooler_template"
16
21
  end
@@ -56,26 +61,26 @@ class Vanagon
56
61
  absolute_path = File.expand_path(path)
57
62
  return nil unless File.exist?(absolute_path)
58
63
 
59
- warn "Reading vmpooler token from: #{path}"
64
+ VanagonLogger.info "Reading vmpooler token from: #{path}"
60
65
  File.read(absolute_path).chomp
61
66
  end
62
67
  private :read_vanagon_token
63
68
 
64
69
  # Read a vmpooler token from the yaml formatted vmfloaty config,
65
70
  # as outlined by the vmfloaty project:
66
- # https://github.com/briancain/vmfloaty
71
+ # https://github.com/puppetlabs/vmfloaty
67
72
  #
68
73
  # @return [String, nil] the vmfloaty vmpooler token value
69
74
  def read_vmfloaty_token(path = "~/.vmfloaty.yml")
70
75
  absolute_path = File.expand_path(path)
71
76
  return nil unless File.exist?(absolute_path)
72
77
 
73
- warn "Reading vmpooler token from: #{path}"
78
+ VanagonLogger.info "Reading vmpooler token from: #{path}"
74
79
  YAML.load_file(absolute_path)['token']
75
80
  end
76
81
  private :read_vmfloaty_token
77
82
 
78
- # This method is used to obtain a vm to build upon using the Puppet Labs'
83
+ # This method is used to obtain a vm to build upon using Puppet's internal
79
84
  # vmpooler (https://github.com/puppetlabs/vmpooler) or other pooler technologies
80
85
  # leveraging the same API
81
86
  # @raise [Vanagon::Error] if a target cannot be obtained
@@ -141,14 +146,14 @@ class Vanagon
141
146
  )
142
147
  if response and response["ok"]
143
148
  Vanagon::Driver.logger.info "#{@target} has been destroyed"
144
- warn "#{@target} has been destroyed"
149
+ VanagonLogger.info "#{@target} has been destroyed"
145
150
  else
146
151
  Vanagon::Driver.logger.info "#{@target} could not be destroyed"
147
- warn "#{@target} could not be destroyed"
152
+ VanagonLogger.info "#{@target} could not be destroyed"
148
153
  end
149
154
  rescue Vanagon::Error => e
150
155
  Vanagon::Driver.logger.info "#{@target} could not be destroyed (#{e.message})"
151
- warn "#{@target} could not be destroyed (#{e.message})"
156
+ VanagonLogger.error "#{@target} could not be destroyed (#{e.message})"
152
157
  end
153
158
  end
154
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
@@ -152,9 +153,9 @@ class Vanagon
152
153
  dsl.instance_eval(File.read(platfile), platfile, 1)
153
154
  dsl._platform
154
155
  rescue StandardError => e
155
- warn "Error loading platform '#{name}' using '#{platfile}':"
156
- warn e
157
- warn e.backtrace.join("\n")
156
+ VanagonLogger.error "Error loading platform '#{name}' using '#{platfile}':"
157
+ VanagonLogger.error(e)
158
+ VanagonLogger.error e.backtrace.join("\n")
158
159
  raise e
159
160
  end
160
161
 
@@ -401,7 +402,7 @@ class Vanagon
401
402
  # @deprecated Please use is_macos? instead
402
403
  # @return [true, false] true if it is an osx variety, false otherwise
403
404
  def is_osx?
404
- warn "is_osx? is a deprecated method, please use #is_macos? instead."
405
+ VanagonLogger.info "is_osx? is a deprecated method, please use #is_macos? instead."
405
406
  is_macos?
406
407
  end
407
408
 
@@ -539,7 +540,7 @@ class Vanagon
539
540
  match = version_string.match(VERSION_REGEX)
540
541
 
541
542
  if match.nil?
542
- warn "Passing a version without an operator is deprecated!"
543
+ VanagonLogger.info "Passing a version without an operator is deprecated!"
543
544
  operator = default
544
545
  version = version_string
545
546
  end
@@ -13,6 +13,8 @@ class Vanagon
13
13
  copy_extensions = '*.deb'
14
14
  end
15
15
  pkg_arch_opt = project.noarch ? "" : "-a#{@architecture}"
16
+ pkg_arch_opt = '-aarm64' if pkg_arch_opt == '-aaarch64'
17
+
16
18
  ["mkdir -p output/#{target_dir}",
17
19
  "mkdir -p $(tempdir)/#{project.name}-#{project.version}",
18
20
  "cp #{project.name}-#{project.version}.tar.gz $(tempdir)/#{project.name}_#{project.version}.orig.tar.gz",
@@ -8,6 +8,7 @@ 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'
12
13
  require 'uri'
13
14
 
@@ -259,7 +260,7 @@ class Vanagon
259
260
  # @param name [String] name that the pooler uses for this platform
260
261
  # @deprecated Please use vmpooler_template instead, this will be removed in a future vanagon release.
261
262
  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."
263
+ 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
264
  self.vmpooler_template(cloud_name)
264
265
  end
265
266
 
@@ -394,7 +395,7 @@ class Vanagon
394
395
  # @param gpg_key [String] optional gpg key to be fetched via curl and installed
395
396
  # @deprecated Please use the add_build_repository DSL method instead. apt_repo will be removed in a future vanagon release.
396
397
  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."
398
+ VanagonLogger.info "Please use the add_build_repository DSL method instead. apt_repo will be removed in a future vanagon release."
398
399
  self.add_build_repository(definition, gpg_key)
399
400
  end
400
401
 
@@ -403,7 +404,7 @@ class Vanagon
403
404
  # @param definition [String] the repo setup URI or RPM file
404
405
  # @deprecated Please use the add_build_repository DSL method instead. yum_repo will be removed in a future vanagon release.
405
406
  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."
407
+ VanagonLogger.info "Please use the add_build_repository DSL method instead. yum_repo will be removed in a future vanagon release."
407
408
  self.add_build_repository(definition)
408
409
  end
409
410
 
@@ -412,7 +413,7 @@ class Vanagon
412
413
  # @param definition [String] the repo setup URI or RPM file
413
414
  # @deprecated Please use the add_build_repository DSL method instead. zypper_repo will be removed in a future vanagon release.
414
415
  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."
416
+ VanagonLogger.info "Please use the add_build_repository DSL method instead. zypper_repo will be removed in a future vanagon release."
416
417
  self.add_build_repository(definition)
417
418
  end
418
419
 
@@ -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
@@ -360,8 +366,8 @@ class Vanagon
360
366
  # @return [Array] array of package level provides for the project
361
367
  def get_provides
362
368
  provides = []
363
- provides.push @provides.flatten
364
- provides.push components.flat_map(&:provides)
369
+ provides << @provides.flatten
370
+ provides << components.flat_map(&:provides)
365
371
  provides.flatten!
366
372
  provides.each do |provide|
367
373
  # TODO: Make this a more reasonable default before 1.0.0
@@ -841,7 +847,7 @@ class Vanagon
841
847
  end
842
848
 
843
849
  def load_upstream_metadata(metadata_uri)
844
- warn "Loading metadata from #{metadata_uri}"
850
+ VanagonLogger.info "Loading metadata from #{metadata_uri}"
845
851
  case metadata_uri
846
852
  when /^http/
847
853
  @upstream_metadata = JSON.parse(Net::HTTP.get(URI(metadata_uri)))
@@ -1,4 +1,5 @@
1
1
  require 'vanagon/errors'
2
+ require 'vanagon/logger'
2
3
  require 'vanagon/project'
3
4
  require 'vanagon/utilities'
4
5
  require 'vanagon/component/source'
@@ -109,8 +110,8 @@ class Vanagon
109
110
  # Sets the run time requirements for the project. Mainly for use in packaging.
110
111
  #
111
112
  # @param req [String] of requirements of the project
112
- def requires(req)
113
- @project.requires << req
113
+ def requires(requirement, version = nil)
114
+ @project.requires << OpenStruct.new(:requirement => requirement, :version => version)
114
115
  end
115
116
 
116
117
  # Indicates that this component replaces a system level package. Replaces can be collected and used by the project and package.
@@ -185,7 +186,7 @@ class Vanagon
185
186
  last_tag = repo_object.describe('HEAD', { :abbrev => 0 })
186
187
  release(repo_object.rev_list("#{last_tag}..HEAD", { :count => true }))
187
188
  rescue Git::GitExecuteError
188
- warn "Directory '#{File.expand_path('..', @configdir)}' cannot be versioned by git. Maybe it hasn't been tagged yet?"
189
+ VanagonLogger.error "Directory '#{File.expand_path('..', @configdir)}' cannot be versioned by git. Maybe it hasn't been tagged yet?"
189
190
  end
190
191
 
191
192
  # Sets the version for the project based on a git describe of the
@@ -196,7 +197,7 @@ class Vanagon
196
197
  git_version = Git.open(File.expand_path("..", @configdir)).describe('HEAD', tags: true)
197
198
  version(git_version.split('-').reject(&:empty?).join('.'))
198
199
  rescue Git::GitExecuteError
199
- warn "Directory '#{File.expand_path('..', @configdir)}' cannot be versioned by git. Maybe it hasn't been tagged yet?"
200
+ VanagonLogger.error "Directory '#{File.expand_path('..', @configdir)}' cannot be versioned by git. Maybe it hasn't been tagged yet?"
200
201
  end
201
202
 
202
203
  # Get the version string from a git branch name. This will look for a '.'
@@ -268,7 +269,7 @@ class Vanagon
268
269
  #
269
270
  # @param name [String] name of component to add. must be present in configdir/components and named $name.rb currently
270
271
  def component(name)
271
- warn "Loading #{name}" if @project.settings[:verbose]
272
+ VanagonLogger.info "Loading #{name}" if @project.settings[:verbose]
272
273
  if @include_components.empty? or @include_components.include?(name)
273
274
  component = Vanagon::Component.load_component(name, File.join(@configdir, "components"), @project.settings, @project.platform)
274
275
  @project.components << component
@@ -9,6 +9,7 @@ require 'timeout'
9
9
  # but it provides a wealth of useful constants
10
10
  require 'English'
11
11
  require 'vanagon/extensions/string'
12
+ require 'vanagon/logger'
12
13
 
13
14
  class Vanagon
14
15
  module Utilities
@@ -39,17 +40,16 @@ class Vanagon
39
40
  end
40
41
 
41
42
  # Simple wrapper around Net::HTTP. Will make a request of the given type to
42
- # the given url and return the body as parsed by JSON.
43
+ # the given url and return the response object
43
44
  #
44
45
  # @param url [String] The url to make the request against (needs to be parsable by URI
45
46
  # @param type [String] One of the supported request types (currently 'get', 'post', 'delete')
46
47
  # @param payload [String] The request body data payload used for POST and PUT
47
48
  # @param header [Hash] Send additional information in the HTTP request header
48
- # @return [Hash] The response body is parsed by JSON and returned
49
+ # @return [Net::HTTPAccepted] The response object
49
50
  # @raise [RuntimeError, Vanagon::Error] an exception is raised if the
50
- # action is not supported, or if there is a problem with the http request,
51
- # or if the response is not JSON
52
- def http_request(url, type, payload = {}.to_json, header = nil) # rubocop:disable Metrics/AbcSize
51
+ # action is not supported, or if there is a problem with the http request
52
+ def http_request_generic(url, type, payload = {}.to_json, header = nil) # rubocop:disable Metrics/AbcSize
53
53
  uri = URI.parse(url)
54
54
  http = Net::HTTP.new(uri.host, uri.port)
55
55
  http.use_ssl = true if uri.scheme == 'https'
@@ -77,14 +77,37 @@ class Vanagon
77
77
  end
78
78
 
79
79
  response = http.request(request)
80
-
81
- JSON.parse(response.body)
80
+ response
82
81
  rescue Errno::ETIMEDOUT, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
83
82
  EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
84
83
  Net::ProtocolError => e
85
84
  raise Vanagon::Error.wrap(e, "Problem reaching #{url}. Is #{uri.host} down?")
85
+ end
86
+
87
+ # uses http_request_generic and returns the body as parsed by JSON.
88
+ # @param url [String] The url to make the request against (needs to be parsable by URI
89
+ # @param type [String] One of the supported request types (currently 'get', 'post', 'delete')
90
+ # @param payload [String] The request body data payload used for POST and PUT
91
+ # @param header [Hash] Send additional information in the HTTP request header
92
+ # @return [Hash] The response in JSON format
93
+ # @raise [RuntimeError, Vanagon::Error] an exception is raised if the response
94
+ # body cannot be parsed as JSON
95
+ def http_request(url, type, payload = {}.to_json, header = nil)
96
+ response = http_request_generic(url, type, payload, header)
97
+ JSON.parse(response.body)
86
98
  rescue JSON::ParserError => e
87
- raise Vanagon::Error.wrap(e, "#{uri.host} handed us a response that doesn't look like JSON.")
99
+ raise Vanagon::Error.wrap(e, "#{url} handed us a response that doesn't look like JSON.")
100
+ end
101
+
102
+ # uses http_request_generic and returns the response code.
103
+ # @param url [String] The url to make the request against (needs to be parsable by URI
104
+ # @param type [String] One of the supported request types (currently 'get', 'post', 'delete')
105
+ # @param payload [String] The request body data payload used for POST and PUT
106
+ # @param header [Hash] Send additional information in the HTTP request header
107
+ # @return [String] The response code eg 202, 200 etc
108
+ def http_request_code(url, type, payload = {}.to_json, header = nil)
109
+ response = http_request_generic(url, type, payload, header)
110
+ response.code
88
111
  end
89
112
 
90
113
  # Similar to rake's sh, the passed command will be executed and an
@@ -143,7 +166,7 @@ class Vanagon
143
166
  yield
144
167
  return true
145
168
  rescue StandardError => e
146
- warn 'An error was encountered evaluating block. Retrying..'
169
+ VanagonLogger.error 'An error was encountered evaluating block. Retrying..'
147
170
  error = e
148
171
  end
149
172
  end
@@ -216,7 +239,7 @@ class Vanagon
216
239
  # output of the command if return_command_output is true
217
240
  # @raise [RuntimeError] If there is no target given or the command fails an exception is raised
218
241
  def remote_ssh_command(target, command, port = 22, return_command_output: false)
219
- warn "Executing '#{command}' on '#{target}'"
242
+ VanagonLogger.info "Executing '#{command}' on '#{target}'"
220
243
  if return_command_output
221
244
  ret = %x(#{ssh_command(port)} -T #{target} '#{command.gsub("'", "'\\\\''")}').chomp
222
245
  if $CHILD_STATUS.success?
@@ -239,7 +262,7 @@ class Vanagon
239
262
  # @raise [RuntimeError] If the command fails an exception is raised
240
263
  def local_command(command, return_command_output: false)
241
264
  clean_environment do
242
- warn "Executing '#{command}' locally"
265
+ VanagonLogger.info "Executing '#{command}' locally"
243
266
  if return_command_output
244
267
  ret = %x(#{command}).chomp
245
268
  if $CHILD_STATUS.success?
@@ -283,7 +306,7 @@ class Vanagon
283
306
  outfile ||= File.join(Dir.mktmpdir, File.basename(erbfile).sub(File.extname(erbfile), ""))
284
307
  output = erb_string(erbfile, opts[:binding])
285
308
  File.open(outfile, 'w') { |f| f.write output }
286
- warn "Generated: #{outfile}"
309
+ VanagonLogger.info "Generated: #{outfile}"
287
310
  FileUtils.rm_rf erbfile if remove_orig
288
311
  outfile
289
312
  end