vanagon 0.17.0 → 0.20.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 (62) 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/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 +5 -4
  22. data/lib/vanagon/cli/sign.rb +3 -2
  23. data/lib/vanagon/component.rb +13 -10
  24. data/lib/vanagon/component/dsl.rb +27 -20
  25. data/lib/vanagon/component/source.rb +2 -1
  26. data/lib/vanagon/component/source/git.rb +35 -10
  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 +12 -11
  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 +6 -5
  36. data/lib/vanagon/environment.rb +3 -2
  37. data/lib/vanagon/logger.rb +31 -0
  38. data/lib/vanagon/platform.rb +38 -5
  39. data/lib/vanagon/platform/deb.rb +2 -0
  40. data/lib/vanagon/platform/dsl.rb +23 -6
  41. data/lib/vanagon/platform/windows.rb +3 -1
  42. data/lib/vanagon/project.rb +25 -15
  43. data/lib/vanagon/project/dsl.rb +6 -5
  44. data/lib/vanagon/utilities.rb +5 -4
  45. data/resources/deb/control.erb +1 -1
  46. data/resources/deb/postinst.erb +24 -13
  47. data/resources/deb/postrm.erb +9 -6
  48. data/resources/deb/prerm.erb +18 -8
  49. data/resources/osx/postinstall.erb +5 -1
  50. data/resources/rpm/project.spec.erb +12 -12
  51. data/resources/solaris/10/depend.erb +2 -2
  52. data/resources/solaris/10/postinstall.erb +10 -2
  53. data/resources/solaris/11/p5m.erb +2 -2
  54. data/spec/lib/vanagon/cli_spec.rb +143 -0
  55. data/spec/lib/vanagon/component/dsl_spec.rb +54 -10
  56. data/spec/lib/vanagon/component/source/git_spec.rb +4 -4
  57. data/spec/lib/vanagon/component_spec.rb +15 -2
  58. data/spec/lib/vanagon/driver_spec.rb +1 -1
  59. data/spec/lib/vanagon/engine/always_be_scheduling_spec.rb +4 -4
  60. data/spec/lib/vanagon/platform_spec.rb +80 -0
  61. data/spec/lib/vanagon/utilities_spec.rb +4 -1
  62. metadata +37 -32
@@ -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
@@ -14,7 +15,7 @@ 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
 
@@ -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.error e
145
+ VanagonLogger.error e.backtrace.join("\n")
144
146
  raise e
145
147
  end
146
148
 
@@ -178,6 +180,7 @@ class Vanagon
178
180
  @preremove_actions = []
179
181
  @postremove_actions = []
180
182
  @install_only = false
183
+ @service = []
181
184
  end
182
185
 
183
186
  # Adds the given file to the list of files and returns @files.
@@ -254,18 +257,18 @@ class Vanagon
254
257
  def fetch_mirrors(options)
255
258
  mirrors.to_a.shuffle.each do |mirror|
256
259
  begin
257
- warn %(Attempting to fetch from mirror URL "#{mirror}")
260
+ VanagonLogger.info %(Attempting to fetch from mirror URL "#{mirror}")
258
261
  @source = Vanagon::Component::Source.source(mirror, options)
259
262
  return true if source.fetch
260
263
  rescue SocketError
261
264
  # SocketError means that there was no DNS/name resolution
262
265
  # for whatever remote protocol the mirror tried to use.
263
- warn %(Unable to resolve mirror URL "#{mirror}")
266
+ VanagonLogger.error %(Unable to resolve mirror URL "#{mirror}")
264
267
  rescue RuntimeError
265
268
  # Source retrieval does not consistently return a meaningful
266
269
  # namespaced error message, which means we're brute-force rescuing
267
270
  # RuntimeError. Not a good look, and we should fix this.
268
- warn %(Unable to retrieve mirror URL "#{mirror}")
271
+ VanagonLogger.error %(Unable to retrieve mirror URL "#{mirror}")
269
272
  end
270
273
  end
271
274
  false
@@ -277,7 +280,7 @@ class Vanagon
277
280
  # @return [Boolean] return True if the source can be retrieved,
278
281
  # or False otherwise
279
282
  def fetch_url(options)
280
- warn %(Attempting to fetch from canonical URL "#{url}")
283
+ VanagonLogger.info %(Attempting to fetch from canonical URL "#{url}")
281
284
  @source = Vanagon::Component::Source.source(url, options)
282
285
  # Explicitly coerce the return value of #source.fetch,
283
286
  # because each subclass of Vanagon::Component::Source returns
@@ -303,7 +306,7 @@ class Vanagon
303
306
  def get_source(workdir) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
304
307
  opts = options.merge({ workdir: workdir })
305
308
  if url || !mirrors.empty?
306
- if ENV['VANAGON_USE_MIRRORS'] == 'n'
309
+ if ENV['VANAGON_USE_MIRRORS'] == 'n' or ENV['VANAGON_USE_MIRRORS'] == 'false'
307
310
  fetch_url(opts)
308
311
  else
309
312
  fetch_mirrors(opts) || fetch_url(opts)
@@ -319,7 +322,7 @@ class Vanagon
319
322
  @version ||= source.version
320
323
  end
321
324
  else
322
- warn "No source given for component '#{@name}'"
325
+ VanagonLogger.info "No source given for component '#{@name}'"
323
326
 
324
327
  # If there is no source, we don't want to try to change directories, so we just change to the current directory.
325
328
  @dirname = './'
@@ -407,7 +410,7 @@ class Vanagon
407
410
  # @return [String] environment suitable for inclusion in a Makefile
408
411
  # @deprecated
409
412
  def get_environment
410
- warn <<-WARNING.undent
413
+ VanagonLogger.info <<-WARNING.undent
411
414
  #get_environment is deprecated; environment variables have been moved
412
415
  into the Makefile, and should not be used within a Makefile's recipe.
413
416
  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.
@@ -167,37 +168,42 @@ class Vanagon
167
168
  # @param service_file [String] path to the service file relative to the source
168
169
  # @param default_file [String] path to the default file relative to the source
169
170
  # @param service_name [String] name of the service
170
- # @param service_type [String] type of the service (network, application, system, etc)
171
- # @param link_target [String] executable service file should be linked to
172
- def install_service(service_file, default_file = nil, service_name = @component.name, service_type: nil, link_target: nil) # rubocop:disable Metrics/AbcSize
173
- case @component.platform.servicetype
171
+ # @param options optional extra parameters
172
+ # service_type [String] type of the service (network, application, system, etc)
173
+ # init_system [String] the init system on which to install service (sysv, systemd)
174
+ # link_target [String] executable service file should be linked to
175
+ def install_service(service_file, default_file = nil, service_name = @component.name, **options) # rubocop:disable Metrics/AbcSize
176
+ init_system = options[:init_system] || @component.platform.servicetype
177
+ servicedir = @component.platform.get_service_dir(init_system)
178
+
179
+ case init_system
174
180
  when "sysv"
175
- target_service_file = File.join(@component.platform.servicedir, service_name)
181
+ target_service_file = File.join(servicedir, service_name)
176
182
  target_default_file = File.join(@component.platform.defaultdir, service_name)
177
183
  target_mode = '0755'
178
184
  default_mode = '0644'
179
185
  when "systemd"
180
- target_service_file = File.join(@component.platform.servicedir, "#{service_name}.service")
186
+ target_service_file = File.join(servicedir, "#{service_name}.service")
181
187
  target_default_file = File.join(@component.platform.defaultdir, service_name)
182
188
  target_mode = '0644'
183
189
  default_mode = '0644'
184
190
  when "launchd"
185
- target_service_file = File.join(@component.platform.servicedir, "#{service_name}.plist")
191
+ target_service_file = File.join(servicedir, "#{service_name}.plist")
186
192
  target_mode = '0644'
187
193
  default_mode = '0644'
188
194
  when "smf"
189
195
  # modify version in smf manifest so service gets restarted after package upgrade
190
196
  @component.install << %{#{@component.platform.sed} -ri 's/(<service.*version=)(".*")/\\1"#{Time.now.to_i}"/' #{service_file}}
191
- target_service_file = File.join(@component.platform.servicedir, service_type.to_s, "#{service_name}.xml")
197
+ target_service_file = File.join(servicedir, options[:service_type].to_s, "#{service_name}.xml")
192
198
  target_default_file = File.join(@component.platform.defaultdir, service_name)
193
199
  target_mode = '0644'
194
200
  default_mode = '0755'
195
201
  when "aix"
196
- @component.service = OpenStruct.new(:name => service_name, :service_command => File.read(service_file).chomp)
202
+ @component.service << OpenStruct.new(:name => service_name, :service_command => File.read(service_file).chomp)
197
203
  # Return here because there is no file to install, just a string read in
198
204
  return
199
205
  when "windows"
200
- @component.service = OpenStruct.new(\
206
+ @component.service << OpenStruct.new(\
201
207
  :bindir_id => "#{service_name.gsub(/[^A-Za-z0-9]/, '').upcase}BINDIR", \
202
208
  :service_file => service_file, \
203
209
  :component_group_id => "#{service_name.gsub(/[^A-Za-z0-9]/, '')}Component"\
@@ -205,13 +211,13 @@ class Vanagon
205
211
  # return here as we are just collecting the name of the service file to put into the harvest filter list.
206
212
  return
207
213
  else
208
- fail "Don't know how to install the #{@component.platform.servicetype}. Please teach #install_service how to do this."
214
+ fail "Don't know how to install the #{init_system}. Please teach #install_service how to do this."
209
215
  end
210
216
 
211
217
  # Install the service and default files
212
- if link_target
213
- install_file(service_file, link_target, mode: target_mode)
214
- link link_target, target_service_file
218
+ if options[:link_target]
219
+ install_file(service_file, options[:link_target], mode: target_mode)
220
+ link options[:link_target], target_service_file
215
221
  else
216
222
  install_file(service_file, target_service_file, mode: target_mode)
217
223
  end
@@ -222,7 +228,8 @@ class Vanagon
222
228
  end
223
229
 
224
230
  # Register the service for use in packaging
225
- @component.service = OpenStruct.new(:name => service_name, :service_file => target_service_file, :type => service_type)
231
+ @component.service << OpenStruct.new(:name => service_name, :service_file => target_service_file,
232
+ :type => options[:service_type], :init_system => init_system)
226
233
  end
227
234
 
228
235
  # Copies a file from source to target during the install phase of the component
@@ -237,7 +244,7 @@ class Vanagon
237
244
 
238
245
  if @component.platform.is_windows?
239
246
  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!"
247
+ VanagonLogger.info "You're trying to set the mode, owner, or group for windows. I don't know how to do that, ignoring!"
241
248
  end
242
249
  else
243
250
  mode ||= '0644'
@@ -407,7 +414,7 @@ class Vanagon
407
414
  install_flags = ['-d']
408
415
  if @component.platform.is_windows?
409
416
  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!"
417
+ VanagonLogger.info "You're trying to set the mode, owner, or group for windows. I don't know how to do that, ignoring!"
411
418
  end
412
419
  else
413
420
  install_flags << "-m '#{mode}'" unless mode.nil?
@@ -422,7 +429,7 @@ class Vanagon
422
429
  # @param env [Hash] mapping of keys to values to add to the environment for the component
423
430
  def environment(*env)
424
431
  if env.size == 1 && env.first.is_a?(Hash)
425
- warn <<-WARNING.undent
432
+ VanagonLogger.info <<-WARNING.undent
426
433
  the component DSL method signature #environment({Key => Value}) is deprecated
427
434
  and will be removed by Vanagon 1.0.0.
428
435
 
@@ -1,4 +1,5 @@
1
1
  require 'fustigit'
2
+ require 'vanagon/logger'
2
3
  require 'vanagon/component/source/http'
3
4
  require 'vanagon/component/source/git'
4
5
  require 'vanagon/component/source/local'
@@ -66,7 +67,7 @@ class Vanagon
66
67
  timeout = 5
67
68
  if Vanagon::Component::Source::Git.valid_remote?(uri, timeout)
68
69
  if uri =~ /^http/
69
- warn "Passing git URLs as http(s) addresses is deprecated! Please prefix your source URL with `git:`"
70
+ VanagonLogger.info "Passing git URLs as http(s) addresses is deprecated! Please prefix your source URL with `git:`"
70
71
  end
71
72
  return :git
72
73
  end
@@ -1,5 +1,6 @@
1
1
  require 'vanagon/utilities'
2
2
  require 'vanagon/errors'
3
+ require 'vanagon/logger'
3
4
  # This stupid library requires a capital 'E' in its name
4
5
  # but it provides a wealth of useful constants
5
6
  require 'English'
@@ -25,14 +26,38 @@ class Vanagon
25
26
  # git command has failed. Useful in instances where a URL
26
27
  # prompts for credentials despite not being a git remote
27
28
  # @return [Boolean] whether #url is a valid Git repo or not
29
+
30
+ # [RE-13837] This ought to be the way to do this. Unfortunately,
31
+ # there's a bug in Git.ls_remote that when ssh prints something like
32
+ # Warning: Permanently added 'github.com,192.30.255.113' (RSA)
33
+ # Git.ls_remote attempts to parse it as actual git output and fails
34
+ # with: NoMethodError: undefined method `split' for nil:NilClass
35
+ #
36
+ # We'll work around that case by calling 'git ls-remote' directly ourselves.
37
+ #
38
+ # I'm leaving in the broken version here for a time when the ruby-git library
39
+ # is fixed.
40
+
41
+ #def valid_remote?(url, timeout = 0)
42
+ # Timeout.timeout(timeout) do
43
+ # !!::Git.ls_remote(url)
44
+ # end
45
+ #rescue ::Git::GitExecuteError
46
+ # false
47
+ #rescue Timeout::Error
48
+ # false
49
+ #end
50
+
28
51
  def valid_remote?(url, timeout = 0)
29
52
  Timeout.timeout(timeout) do
30
- !!::Git.ls_remote(url)
53
+ Vanagon::Utilities.local_command("git ls-remote #{url} > /dev/null 2>&1")
54
+ return false unless $?.exitstatus.zero?
55
+ return true
31
56
  end
32
- rescue ::Git::GitExecuteError
33
- false
34
57
  rescue Timeout::Error
35
- false
58
+ return false
59
+ rescue RuntimeError
60
+ return false
36
61
  end
37
62
  end
38
63
 
@@ -81,7 +106,7 @@ class Vanagon
81
106
  # There is no md5 to manually verify here, so this is a noop.
82
107
  def verify
83
108
  # nothing to do here, so just tell users that and return
84
- warn "Nothing to verify for '#{dirname}' (using Git reference '#{ref}')"
109
+ VanagonLogger.info "Nothing to verify for '#{dirname}' (using Git reference '#{ref}')"
85
110
  end
86
111
 
87
112
  # The dirname to reference when building from the repo
@@ -131,8 +156,8 @@ class Vanagon
131
156
  # Clone a remote repo, make noise about it, and fail entirely
132
157
  # if we're unable to retrieve the remote repo
133
158
  def clone!
134
- warn "Cloning Git repo '#{url}'"
135
- warn "Successfully cloned '#{dirname}'" if clone
159
+ VanagonLogger.info "Cloning Git repo '#{url}'"
160
+ VanagonLogger.info "Successfully cloned '#{dirname}'" if clone
136
161
  rescue ::Git::GitExecuteError
137
162
  raise Vanagon::InvalidRepo, "Unable to clone from '#{url}'"
138
163
  end
@@ -141,7 +166,7 @@ class Vanagon
141
166
  # Checkout desired ref/sha, make noise about it, and fail
142
167
  # entirely if we're unable to checkout that given ref/sha
143
168
  def checkout!
144
- warn "Checking out '#{ref}' from Git repo '#{dirname}'"
169
+ VanagonLogger.info "Checking out '#{ref}' from Git repo '#{dirname}'"
145
170
  clone.checkout(ref)
146
171
  rescue ::Git::GitExecuteError
147
172
  raise Vanagon::CheckoutFailed, "unable to checkout #{ref} from '#{url}'"
@@ -151,7 +176,7 @@ class Vanagon
151
176
  # Attempt to update submodules, and do not panic
152
177
  # if there are no submodules to initialize
153
178
  def update_submodules
154
- warn "Attempting to update submodules for repo '#{dirname}'"
179
+ VanagonLogger.info "Attempting to update submodules for repo '#{dirname}'"
155
180
  clone.update_submodules(init: true)
156
181
  end
157
182
  private :update_submodules
@@ -163,7 +188,7 @@ class Vanagon
163
188
  def describe
164
189
  clone.describe(ref, tags: true)
165
190
  rescue ::Git::GitExecuteError
166
- warn "Directory '#{dirname}' cannot be versioned by Git. Maybe it hasn't been tagged yet?"
191
+ VanagonLogger.info "Directory '#{dirname}' cannot be versioned by Git. Maybe it hasn't been tagged yet?"
167
192
  end
168
193
  private :describe
169
194
  end