beaker 2.13.0 → 2.14.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 +8 -8
  2. data/Gemfile +19 -0
  3. data/HISTORY.md +335 -2
  4. data/acceptance/pre_suite/puppet_git/install.rb +2 -2
  5. data/lib/beaker/answers.rb +45 -2
  6. data/lib/beaker/answers/version20.rb +9 -9
  7. data/lib/beaker/answers/version28.rb +9 -9
  8. data/lib/beaker/answers/version30.rb +19 -19
  9. data/lib/beaker/answers/version32.rb +1 -1
  10. data/lib/beaker/answers/version34.rb +4 -4
  11. data/lib/beaker/answers/version40.rb +1 -1
  12. data/lib/beaker/cli.rb +11 -4
  13. data/lib/beaker/command.rb +4 -2
  14. data/lib/beaker/command_factory.rb +5 -1
  15. data/lib/beaker/dsl/helpers/host_helpers.rb +17 -5
  16. data/lib/beaker/dsl/install_utils.rb +3 -2
  17. data/lib/beaker/dsl/install_utils/aio_defaults.rb +86 -0
  18. data/lib/beaker/dsl/install_utils/foss_defaults.rb +163 -0
  19. data/lib/beaker/dsl/install_utils/foss_utils.rb +988 -0
  20. data/lib/beaker/dsl/install_utils/pe_defaults.rb +139 -0
  21. data/lib/beaker/dsl/install_utils/pe_utils.rb +140 -38
  22. data/lib/beaker/dsl/install_utils/puppet_utils.rb +26 -751
  23. data/lib/beaker/dsl/structure.rb +7 -1
  24. data/lib/beaker/host.rb +35 -58
  25. data/lib/beaker/host/freebsd.rb +4 -16
  26. data/lib/beaker/host/mac.rb +3 -39
  27. data/lib/beaker/host/mac/pkg.rb +2 -1
  28. data/lib/beaker/host/pswindows.rb +2 -28
  29. data/lib/beaker/host/unix.rb +3 -51
  30. data/lib/beaker/host/unix/pkg.rb +34 -33
  31. data/lib/beaker/host/windows.rb +1 -45
  32. data/lib/beaker/host_prebuilt_steps.rb +11 -24
  33. data/lib/beaker/hypervisor/aixer.rb +1 -1
  34. data/lib/beaker/hypervisor/docker.rb +43 -4
  35. data/lib/beaker/hypervisor/openstack.rb +1 -0
  36. data/lib/beaker/hypervisor/solaris.rb +1 -1
  37. data/lib/beaker/hypervisor/vmpooler.rb +19 -8
  38. data/lib/beaker/network_manager.rb +5 -4
  39. data/lib/beaker/options/command_line_parser.rb +9 -9
  40. data/lib/beaker/options/parser.rb +21 -17
  41. data/lib/beaker/options/presets.rb +0 -33
  42. data/lib/beaker/platform.rb +7 -3
  43. data/lib/beaker/ssh_connection.rb +1 -1
  44. data/lib/beaker/version.rb +1 -1
  45. data/spec/beaker/answers_spec.rb +13 -8
  46. data/spec/beaker/cli_spec.rb +6 -6
  47. data/spec/beaker/command_spec.rb +18 -0
  48. data/spec/beaker/dsl/helpers/puppet_helpers_spec.rb +2 -0
  49. data/spec/beaker/dsl/install_utils/{puppet_utils_spec.rb → foss_utils_spec.rb} +34 -21
  50. data/spec/beaker/dsl/install_utils/pe_utils_spec.rb +2 -0
  51. data/spec/beaker/dsl/structure_spec.rb +8 -0
  52. data/spec/beaker/host/unix/pkg_spec.rb +15 -10
  53. data/spec/beaker/host_prebuilt_steps_spec.rb +1 -1
  54. data/spec/beaker/host_spec.rb +3 -54
  55. data/spec/beaker/hypervisor/docker_spec.rb +2 -0
  56. data/spec/beaker/hypervisor/vmpooler_spec.rb +67 -10
  57. data/spec/beaker/options/command_line_parser_spec.rb +2 -2
  58. data/spec/beaker/options/parser_spec.rb +35 -24
  59. data/spec/beaker/options/presets_spec.rb +0 -26
  60. data/spec/helpers.rb +5 -5
  61. data/spec/mocks.rb +1 -2
  62. metadata +7 -3
@@ -0,0 +1,139 @@
1
+ module Beaker
2
+ module DSL
3
+ module InstallUtils
4
+ #
5
+ # This module contains default values for pe paths and directorys per-platform
6
+ #
7
+ module PEDefaults
8
+
9
+ #Here be the pathing and default values for PE installs
10
+ #
11
+ PE_DEFAULTS = {
12
+ 'mac' => {
13
+ 'puppetserver-confdir' => '/etc/puppetlabs/puppetserver/conf.d',
14
+ 'puppetservice' => 'pe-httpd',
15
+ 'puppetpath' => '/etc/puppetlabs/puppet',
16
+ 'puppetconfdir' => '/etc/puppetlabs/puppet',
17
+ 'puppetcodedir' => '/etc/puppetlabs/puppet',
18
+ 'puppetbin' => '/opt/puppet/bin/puppet',
19
+ 'puppetbindir' => '/opt/puppet/bin',
20
+ 'puppetsbindir' => '/opt/puppet/sbin',
21
+ 'puppetvardir' => '/var/opt/lib/pe-puppet',
22
+ 'hieradatadir' => '/var/lib/hiera',
23
+ 'hieraconf' => '/etc/puppetlabs/puppet/hiera.yaml',
24
+ 'distmoduledir' => '/etc/puppetlabs/puppet/modules',
25
+ 'sitemoduledir' => '/opt/puppet/share/puppet/modules',
26
+ },
27
+ 'unix' => {
28
+ 'puppetserver-confdir' => '/etc/puppetlabs/puppetserver/conf.d',
29
+ 'puppetservice' => 'pe-httpd',
30
+ 'puppetpath' => '/etc/puppetlabs/puppet',
31
+ 'puppetconfdir' => '/etc/puppetlabs/puppet',
32
+ 'puppetbin' => '/opt/puppet/bin/puppet',
33
+ 'puppetbindir' => '/opt/puppet/bin',
34
+ 'puppetsbindir' => '/opt/puppet/sbin',
35
+ 'privatebindir' => '/opt/puppetlabs/puppet/bin',
36
+ 'puppetvardir' => '/var/opt/lib/pe-puppet',
37
+ 'hieradatadir' => '/var/lib/hiera',
38
+ 'hieraconf' => '/etc/puppetlabs/puppet/hiera.yaml',
39
+ 'distmoduledir' => '/etc/puppetlabs/puppet/modules',
40
+ 'sitemoduledir' => '/opt/puppet/share/puppet/modules',
41
+ },
42
+ 'windows' => { #cygwin windows
43
+ 'puppetservice' => 'pe-httpd',
44
+ 'puppetpath' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
45
+ 'puppetconfdir' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
46
+ 'puppetcodedir' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
47
+ 'hieraconf' => '`cygpath -smF 35`/Puppetlabs/puppet/etc/hiera.yaml',
48
+ 'puppetvardir' => '`cygpath -smF 35`/PuppetLabs/puppet/var',
49
+ 'distmoduledir' => '`cygpath -smF 35`/PuppetLabs/puppet/etc/modules',
50
+ 'sitemoduledir' => 'C:/usr/share/puppet/modules',
51
+ #let's just add both potential bin dirs to the path
52
+ 'puppetbindir' => '/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet Enterprise/bin:/cygdrive/c/Program Files/Puppet Labs/Puppet Enterprise/bin',
53
+ 'privatebindir' => '/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet Enterprise/sys/ruby/bin:/cygdrive/c/Program Files/Puppet Labs/Puppet Enterprise/sys/ruby/bin',
54
+ },
55
+ 'pswindows' => { #windows windows
56
+ 'puppetservice' => 'pe-httpd',
57
+ 'puppetpath' => 'C:\\ProgramData\\PuppetLabs\\puppet\\etc',
58
+ 'puppetconfdir' => 'C:\\ProgramData\\PuppetLabs\\puppet\\etc',
59
+ 'puppetcodedir' => 'C:\\ProgramData\\PuppetLabs\\puppet\\etc',
60
+ 'hieraconf' => 'C:\\ProgramData\\PuppetLabs\\puppet\\etc\\hiera.yaml',
61
+ 'distmoduledir' => 'C:\\ProgramData\\PuppetLabs\\puppet\\etc\\modules',
62
+ 'sitemoduledir' => 'C:\\usr\\share\\puppet\\modules',
63
+ 'puppetvardir' => 'C:\\ProgramData\\PuppetLabs\\puppet\\var',
64
+ 'puppetbindir' => '"C:\\Program Files (x86)\\PuppetLabs\\Puppet Enterprise\\bin";"C:\\Program Files\\PuppetLabs\\Puppet Enterprise\\bin"'
65
+ },
66
+ }
67
+
68
+ # Add the appropriate pe defaults to the host object so that they can be accessed using host[option], set host[:type] = pe
69
+ # @param [Host] host A single host to act upon
70
+ # @param [String] platform The platform type of this host, one of windows, pswindows, mac & unix
71
+ def add_platform_pe_defaults(host, platform)
72
+ PE_DEFAULTS[platform].each_pair do |key, val|
73
+ host[key] = val
74
+ end
75
+ # add the type and group here for backwards compatability
76
+ if host['platform'] =~ /windows/
77
+ host['group'] = 'Administrators'
78
+ else
79
+ host['group'] = 'pe-puppet'
80
+ end
81
+ host['type'] = 'pe'
82
+ end
83
+
84
+ # Add the appropriate pe defaults to an array of hosts
85
+ # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
86
+ # or a role (String or Symbol) that identifies one or more hosts.
87
+ def add_pe_defaults_on(hosts)
88
+ block_on hosts do | host |
89
+ case host.class.to_s.downcase
90
+ when /aix|freebsd|unix/
91
+ platform = 'unix'
92
+ when /mac/
93
+ platform = 'mac'
94
+ when /pswindows/
95
+ platform = 'pswindows'
96
+ else
97
+ platform = 'windows'
98
+ end
99
+ add_platform_pe_defaults(host, platform)
100
+ end
101
+ end
102
+
103
+ # Remove the appropriate pe defaults from the host object so that they can no longer be accessed using host[option], set host[:type] = nil
104
+ # @param [Host] host A single host to act upon
105
+ # @param [String] platform The platform type of this host, one of windows, freebsd, mac & unix
106
+ def remove_platform_pe_defaults(host, platform)
107
+ FOSS_DEFAULTS[platform].each_pair do |key, val|
108
+ host.delete(key)
109
+ end
110
+ host['group'] = nil
111
+ host['type'] = nil
112
+ end
113
+
114
+ # Remove the appropriate pe defaults from an array of hosts
115
+ # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
116
+ # or a role (String or Symbol) that identifies one or more hosts.
117
+ def remove_pe_defaults_on(hosts)
118
+ block_on hosts do | host |
119
+ case host.class.to_s.downcase
120
+ when /aix|unix/
121
+ platform = 'unix'
122
+ when /freebsd/
123
+ platform = 'freebsd'
124
+ when /mac/
125
+ platform = 'mac'
126
+ when /pswindows/
127
+ platform = 'pswindows'
128
+ else
129
+ platform = 'windows'
130
+ end
131
+ remove_platform_pe_defaults(host, platform)
132
+ end
133
+ end
134
+
135
+ end
136
+ end
137
+ end
138
+ end
139
+
@@ -1,3 +1,6 @@
1
+ [ 'aio_defaults', 'pe_defaults', 'puppet_utils' ].each do |lib|
2
+ require "beaker/dsl/install_utils/#{lib}"
3
+ end
1
4
  module Beaker
2
5
  module DSL
3
6
  module InstallUtils
@@ -12,6 +15,48 @@ module Beaker
12
15
  # {Beaker::Host}'s interface to act upon
13
16
  # * the module {Beaker::DSL::Wrappers} the provides convenience methods for {Beaker::DSL::Command} creation
14
17
  module PEUtils
18
+ include AIODefaults
19
+ include PEDefaults
20
+ include PuppetUtils
21
+
22
+ # Set defaults and PATH for these hosts to be either pe or aio, have host['type'] == aio for aio settings, defaults
23
+ # to pe.
24
+ #
25
+ # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
26
+ # or a role (String or Symbol) that identifies one or more hosts.
27
+ def configure_pe_defaults_on( hosts )
28
+ block_on hosts do |host|
29
+ if host['type'] && host['type'] =~ /aio/
30
+ # add pe defaults to host
31
+ add_aio_defaults_on(host)
32
+ else
33
+ add_pe_defaults_on(host)
34
+ end
35
+ # add pathing env
36
+ add_puppet_paths_on(host)
37
+ end
38
+ end
39
+
40
+
41
+ # @!macro [new] common_opts
42
+ # @param [Hash{Symbol=>String}] opts Options to alter execution.
43
+ # @option opts [Boolean] :silent (false) Do not produce log output
44
+ # @option opts [Array<Fixnum>] :acceptable_exit_codes ([0]) An array
45
+ # (or range) of integer exit codes that should be considered
46
+ # acceptable. An error will be thrown if the exit code does not
47
+ # match one of the values in this list.
48
+ # @option opts [Boolean] :accept_all_exit_codes (false) Consider all
49
+ # exit codes as passing.
50
+ # @option opts [Boolean] :dry_run (false) Do not actually execute any
51
+ # commands on the SUT
52
+ # @option opts [String] :stdin (nil) Input to be provided during command
53
+ # execution on the SUT.
54
+ # @option opts [Boolean] :pty (false) Execute this command in a pseudoterminal.
55
+ # @option opts [Boolean] :expect_connection_failure (false) Expect this command
56
+ # to result in a connection failure, reconnect and continue execution.
57
+ # @option opts [Hash{String=>String}] :environment ({}) These will be
58
+ # treated as extra environment variables that should be set before
59
+ # running the command.
15
60
 
16
61
  #Sort array of hosts so that it has the correct order for PE installation based upon each host's role
17
62
  # @example
@@ -246,10 +291,40 @@ module Beaker
246
291
  def deploy_frictionless_to_master(host)
247
292
  klass = host['platform'].gsub(/-/, '_').gsub(/\./,'')
248
293
  klass = "pe_repo::platform::#{klass}"
249
- on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake nodeclass:add[#{klass},skip]"
250
- on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake node:add[#{master},,,skip]"
251
- on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake node:addclass[#{master},#{klass}]"
252
- on master, puppet("agent -t"), :acceptable_exit_codes => [0,2]
294
+ if version_is_less(host['pe_ver'], '3.8')
295
+ # use the old rake tasks
296
+ on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake nodeclass:add[#{klass},skip]"
297
+ on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake node:add[#{master},,,skip]"
298
+ on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake node:addclass[#{master},#{klass}]"
299
+ on master, puppet("agent -t"), :acceptable_exit_codes => [0,2]
300
+ else
301
+ # the new hotness
302
+ begin
303
+ require 'scooter'
304
+ rescue LoadError => e
305
+ @logger.notify('WARNING: gem scooter is required for frictionless installation post 3.8')
306
+ raise e
307
+ end
308
+ dispatcher = Scooter::HttpDispatchers::ConsoleDispatcher.new(dashboard)
309
+
310
+ # Check if we've already created a frictionless agent node group
311
+ # to avoid errors creating the same node group when the beaker hosts file contains
312
+ # multiple hosts with the same platform
313
+ node_group = dispatcher.get_node_group_by_name('Beaker Frictionless Agent')
314
+ if node_group.nil? || node_group.empty?
315
+ node_group = {}
316
+ node_group['name'] = "Beaker Frictionless Agent"
317
+ # Pin the master to the node
318
+ node_group['rule'] = [ "and", [ '=', 'name', master.to_s ]]
319
+ node_group['classes'] ||= {}
320
+ end
321
+
322
+ # add the pe_repo platform class
323
+ node_group['classes'][klass] = {}
324
+
325
+ dispatcher.create_new_node_group_model(node_group)
326
+ on master, puppet("agent -t"), :acceptable_exit_codes => [0,2]
327
+ end
253
328
  end
254
329
 
255
330
  #Perform a Puppet Enterprise upgrade or install
@@ -335,6 +410,7 @@ module Beaker
335
410
  install_hosts.each do |host|
336
411
  if host['platform'] =~ /windows/
337
412
  on host, installer_cmd(host, opts)
413
+ configure_pe_defaults_on(host)
338
414
  if not host.is_cygwin?
339
415
  # HACK: for some reason, post install we need to refresh the connection to make puppet available for execution
340
416
  host.close
@@ -345,11 +421,15 @@ module Beaker
345
421
  if host['roles'].include?('frictionless') && (! version_is_less(version, '3.2.0'))
346
422
  # If We're *not* running the classic installer, we want
347
423
  # to make sure the master has packages for us.
348
- deploy_frictionless_to_master(host)
424
+ if host['platform'] != master['platform'] # only need to do this if platform differs
425
+ deploy_frictionless_to_master(host)
426
+ end
349
427
  on host, installer_cmd(host, opts)
428
+ configure_pe_defaults_on(host)
350
429
  elsif host['platform'] =~ /osx|eos/
351
430
  # If we're not frictionless, we need to run the OSX special-case
352
431
  on host, installer_cmd(host, opts)
432
+ configure_pe_defaults_on(host)
353
433
  #set the certname and master
354
434
  on host, puppet("config set server #{master}")
355
435
  on host, puppet("config set certname #{host}")
@@ -360,6 +440,7 @@ module Beaker
360
440
  answers = Beaker::Answers.create(opts[:pe_ver] || host['pe_ver'], hosts, opts)
361
441
  create_remote_file host, "#{host['working_dir']}/answers", answers.answer_string(host)
362
442
  on host, installer_cmd(host, opts)
443
+ configure_pe_defaults_on(host)
363
444
  end
364
445
  end
365
446
 
@@ -406,63 +487,84 @@ module Beaker
406
487
  end
407
488
  end
408
489
 
490
+ #Install PE based on global hosts with global options
491
+ #@see #install_pe_on
492
+ def install_pe
493
+ install_pe_on(hosts, options)
494
+ end
495
+
409
496
  #Install PE based upon host configuration and options
497
+ #
498
+ # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
499
+ # or a role (String or Symbol) that identifies one or more hosts.
500
+ # @!macro common_opts
410
501
  # @example
411
- # install_pe
502
+ # install_pe_on(hosts, {})
412
503
  #
413
504
  # @note Either pe_ver and pe_dir should be set in the ENV or each host should have pe_ver and pe_dir set individually.
414
505
  # Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz)
415
506
  # for Unix like systems and puppet-enterprise-VERSION.msi for Windows systems.
416
507
  #
417
- def install_pe
508
+ def install_pe_on(hosts, opts)
418
509
  #process the version files if necessary
419
- hosts.each do |host|
420
- host['pe_dir'] ||= options[:pe_dir]
421
- if host['platform'] =~ /windows/
422
- host['pe_ver'] = host['pe_ver'] || options['pe_ver'] ||
423
- Beaker::Options::PEVersionScraper.load_pe_version(host[:pe_dir] || options[:pe_dir], options[:pe_version_file_win])
424
- else
425
- host['pe_ver'] = host['pe_ver'] || options['pe_ver'] ||
426
- Beaker::Options::PEVersionScraper.load_pe_version(host[:pe_dir] || options[:pe_dir], options[:pe_version_file])
510
+ confine_block(:to, {}, hosts) do
511
+ hosts.each do |host|
512
+ host['pe_dir'] ||= opts[:pe_dir]
513
+ if host['platform'] =~ /windows/
514
+ host['pe_ver'] = host['pe_ver'] || opts['pe_ver'] ||
515
+ Beaker::Options::PEVersionScraper.load_pe_version(host[:pe_dir] || opts[:pe_dir], opts[:pe_version_file_win])
516
+ else
517
+ host['pe_ver'] = host['pe_ver'] || opts['pe_ver'] ||
518
+ Beaker::Options::PEVersionScraper.load_pe_version(host[:pe_dir] || opts[:pe_dir], opts[:pe_version_file])
519
+ end
427
520
  end
521
+ do_install sorted_hosts, opts
428
522
  end
429
- #send in the global options hash
430
- do_install sorted_hosts, options
523
+ end
524
+
525
+ #Upgrade PE based upon global host configuration and global options
526
+ #@see #upgrade_pe_on
527
+ def upgrade_pe path=nil
528
+ upgrade_pe_on(hosts, options, path)
431
529
  end
432
530
 
433
531
  #Upgrade PE based upon host configuration and options
532
+ # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
533
+ # or a role (String or Symbol) that identifies one or more hosts.
534
+ # @!macro common_opts
434
535
  # @param [String] path A path (either local directory or a URL to a listing of PE builds).
435
536
  # Will contain a LATEST file indicating the latest build to install.
436
537
  # This is ignored if a pe_upgrade_ver and pe_upgrade_dir are specified
437
538
  # in the host configuration file.
438
539
  # @example
439
- # upgrade_pe("http://neptune.puppetlabs.lan/3.0/ci-ready/")
540
+ # upgrade_pe_on(agents, {}, "http://neptune.puppetlabs.lan/3.0/ci-ready/")
440
541
  #
441
542
  # @note Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz)
442
543
  # for Unix like systems and puppet-enterprise-VERSION.msi for Windows systems.
443
- def upgrade_pe path=nil
444
- set_console_password = false
445
- # if we are upgrading from something lower than 3.4 then we need to set the pe console password
446
- if (dashboard[:pe_ver] ? version_is_less(dashboard[:pe_ver], "3.4.0") : true)
447
- set_console_password = true
448
- end
449
- # get new version information
450
- hosts.each do |host|
451
- host['pe_dir'] = host['pe_upgrade_dir'] || path
452
- if host['platform'] =~ /windows/
453
- host['pe_ver'] = host['pe_upgrade_ver'] || options['pe_upgrade_ver'] ||
454
- Options::PEVersionScraper.load_pe_version(host['pe_dir'], options[:pe_version_file_win])
455
- else
456
- host['pe_ver'] = host['pe_upgrade_ver'] || options['pe_upgrade_ver'] ||
457
- Options::PEVersionScraper.load_pe_version(host['pe_dir'], options[:pe_version_file])
544
+ def upgrade_pe_on hosts, opts, path=nil
545
+ confine_block(:to, {}, hosts) do
546
+ set_console_password = false
547
+ # if we are upgrading from something lower than 3.4 then we need to set the pe console password
548
+ if (dashboard[:pe_ver] ? version_is_less(dashboard[:pe_ver], "3.4.0") : true)
549
+ set_console_password = true
458
550
  end
459
- if version_is_less(host['pe_ver'], '3.0')
460
- host['pe_installer'] ||= 'puppet-enterprise-upgrader'
551
+ # get new version information
552
+ hosts.each do |host|
553
+ host['pe_dir'] = host['pe_upgrade_dir'] || path
554
+ if host['platform'] =~ /windows/
555
+ host['pe_ver'] = host['pe_upgrade_ver'] || opts['pe_upgrade_ver'] ||
556
+ Options::PEVersionScraper.load_pe_version(host['pe_dir'], opts[:pe_version_file_win])
557
+ else
558
+ host['pe_ver'] = host['pe_upgrade_ver'] || opts['pe_upgrade_ver'] ||
559
+ Options::PEVersionScraper.load_pe_version(host['pe_dir'], opts[:pe_version_file])
560
+ end
561
+ if version_is_less(host['pe_ver'], '3.0')
562
+ host['pe_installer'] ||= 'puppet-enterprise-upgrader'
563
+ end
461
564
  end
565
+ do_install(sorted_hosts, opts.merge({:type => :upgrade, :set_console_password => set_console_password}))
566
+ opts['upgrade'] = true
462
567
  end
463
- # send in the global options hash
464
- do_install(sorted_hosts, options.merge({:type => :upgrade, :set_console_password => set_console_password}))
465
- options['upgrade'] = true
466
568
  end
467
569
 
468
570
  #Create the Higgs install command string based upon the host and options settings. Installation command will be run as a
@@ -2,771 +2,46 @@ module Beaker
2
2
  module DSL
3
3
  module InstallUtils
4
4
  #
5
- # This module contains methods to install FOSS puppet from various sources
5
+ # This module contains methods useful for both foss and pe installs
6
6
  #
7
- # To mix this is into a class you need the following:
8
- # * a method *hosts* that yields any hosts implementing
9
- # {Beaker::Host}'s interface to act upon.
10
- # * a method *options* that provides an options hash, see {Beaker::Options::OptionsHash}
11
- # * the module {Beaker::DSL::Roles} that provides access to the various hosts implementing
12
- # {Beaker::Host}'s interface to act upon
13
- # * the module {Beaker::DSL::Wrappers} the provides convenience methods for {Beaker::DSL::Command} creation
14
7
  module PuppetUtils
15
8
 
16
- # The default install path
17
- SourcePath = "/opt/puppet-git-repos"
9
+ #Given a host construct a PATH that includes puppetbindir, facterbindir and hierabindir
10
+ # @param [Host] host A single host to construct pathing for
11
+ def construct_puppet_path(host)
12
+ path = (%w(puppetbindir facterbindir hierabindir)).compact.reject(&:empty?)
13
+ #get the PATH defaults
14
+ path.map! { |val| host[val] }
15
+ path = path.compact.reject(&:empty?)
16
+ #run the paths through echo to see if they have any subcommands that need processing
17
+ path.map! { |val| echo_on(host, val) }
18
18
 
19
- # A regex to know if the uri passed is pointing to a git repo
20
- GitURI = %r{^(git|https?|file)://|^git@|^gitmirror@}
21
-
22
- # Github's ssh signature for cloning via ssh
23
- GitHubSig = 'github.com,207.97.227.239 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=='
24
-
25
- # @param [String] uri A uri in the format of <git uri>#<revision>
26
- # the `git://`, `http://`, `https://`, and ssh
27
- # (if cloning as the remote git user) protocols
28
- # are valid for <git uri>
29
- #
30
- # @example Usage
31
- # project = extract_repo_info_from 'git@github.com:puppetlabs/SuperSecretSauce#what_is_justin_doing'
32
- #
33
- # puts project[:name]
34
- # #=> 'SuperSecretSauce'
35
- #
36
- # puts project[:rev]
37
- # #=> 'what_is_justin_doing'
38
- #
39
- # @return [Hash{Symbol=>String}] Returns a hash containing the project
40
- # name, repository path, and revision
41
- # (defaults to HEAD)
42
- #
43
- def extract_repo_info_from uri
44
- require 'pathname'
45
- project = {}
46
- repo, rev = uri.split('#', 2)
47
- project[:name] = Pathname.new(repo).basename('.git').to_s
48
- project[:path] = repo
49
- project[:rev] = rev || 'HEAD'
50
- return project
51
- end
52
-
53
- # Takes an array of package info hashes (like that returned from
54
- # {#extract_repo_info_from}) and sorts the `puppet`, `facter`, `hiera`
55
- # packages so that puppet's dependencies will be installed first.
56
- #
57
- # @!visibility private
58
- def order_packages packages_array
59
- puppet = packages_array.select {|e| e[:name] == 'puppet' }
60
- puppet_depends_on = packages_array.select do |e|
61
- e[:name] == 'hiera' or e[:name] == 'facter'
62
- end
63
- depends_on_puppet = (packages_array - puppet) - puppet_depends_on
64
- [puppet_depends_on, puppet, depends_on_puppet].flatten
65
- end
66
-
67
- # @param [Host] host An object implementing {Beaker::Hosts}'s
68
- # interface.
69
- # @param [String] path The path on the remote [host] to the repository
70
- # @param [Hash{Symbol=>String}] repository A hash representing repo
71
- # info like that emitted by
72
- # {#extract_repo_info_from}
73
- #
74
- # @example Getting multiple project versions
75
- # versions = [puppet_repo, facter_repo, hiera_repo].inject({}) do |vers, repo_info|
76
- # vers.merge(find_git_repo_versions(host, '/opt/git-puppet-repos', repo_info) )
77
- # end
78
- # @return [Hash] Executes git describe on [host] and returns a Hash
79
- # with the key of [repository[:name]] and value of
80
- # the output from git describe.
81
- #
82
- # @note This requires the helper methods:
83
- # * {Beaker::DSL::Structure#step}
84
- # * {Beaker::DSL::Helpers#on}
85
- #
86
- def find_git_repo_versions host, path, repository
87
- version = {}
88
- step "Grab version for #{repository[:name]}" do
89
- on host, "cd #{path}/#{repository[:name]} && " +
90
- "git describe || true" do
91
- version[repository[:name]] = stdout.chomp
92
- end
93
- end
94
- version
95
- end
96
-
97
- #
98
- # @see #find_git_repo_versions
99
- def install_from_git host, path, repository
100
- name = repository[:name]
101
- repo = repository[:path]
102
- rev = repository[:rev]
103
- depth = repository[:depth]
104
- depth_branch = repository[:depth_branch]
105
- target = "#{path}/#{name}"
106
-
107
- if (depth_branch.nil?)
108
- depth_branch = rev
109
- end
110
-
111
- clone_cmd = "git clone #{repo} #{target}"
112
- if (depth)
113
- clone_cmd = "git clone --branch #{depth_branch} --depth #{depth} #{repo} #{target}"
114
- end
115
-
116
- step "Clone #{repo} if needed" do
117
- on host, "test -d #{path} || mkdir -p #{path}"
118
- on host, "test -d #{target} || #{clone_cmd}"
119
- end
120
-
121
- step "Update #{name} and check out revision #{rev}" do
122
- commands = ["cd #{target}",
123
- "remote rm origin",
124
- "remote add origin #{repo}",
125
- "fetch origin +refs/pull/*:refs/remotes/origin/pr/* +refs/heads/*:refs/remotes/origin/*",
126
- "clean -fdx",
127
- "checkout -f #{rev}"]
128
- on host, commands.join(" && git ")
129
- end
130
-
131
- step "Install #{name} on the system" do
132
- # The solaris ruby IPS package has bindir set to /usr/ruby/1.8/bin.
133
- # However, this is not the path to which we want to deliver our
134
- # binaries. So if we are using solaris, we have to pass the bin and
135
- # sbin directories to the install.rb
136
- install_opts = ''
137
- install_opts = '--bindir=/usr/bin --sbindir=/usr/sbin' if
138
- host['platform'].include? 'solaris'
139
-
140
- on host, "cd #{target} && " +
141
- "if [ -f install.rb ]; then " +
142
- "ruby ./install.rb #{install_opts}; " +
143
- "else true; fi"
144
- end
145
- end
146
-
147
- #Install FOSS based upon host configuration and options
148
- # @example will install puppet 3.6.1 from native puppetlabs provided packages wherever possible and will fail over to gem installation when impossible
149
- # install_puppet({
150
- # :version => '3.6.1',
151
- # :facter_version => '2.0.1',
152
- # :hiera_version => '1.3.3',
153
- # :default_action => 'gem_install',
154
- #
155
- # })
156
- #
157
- #
158
- # @example Will install latest packages on Enterprise Linux and Debian based distros and fail hard on all othere platforms.
159
- # install_puppet()
160
- #
161
- # @note This will attempt to add a repository for apt.puppetlabs.com on
162
- # Debian, Ubuntu, or Cumulus machines, or yum.puppetlabs.com on EL or Fedora
163
- # machines, then install the package 'puppet'.
164
- # @param [Hash{Symbol=>String}] opts
165
- # @option opts [String] :version Version of puppet to download
166
- # @option opts [String] :mac_download_url Url to download msi pattern of %url%/puppet-%version%.msi
167
- # @option opts [String] :win_download_url Url to download dmg pattern of %url%/(puppet|hiera|facter)-%version%.msi
168
- #
169
- # @return nil
170
- # @raise [StandardError] When encountering an unsupported platform by default, or if gem cannot be found when default_action => 'gem_install'
171
- # @raise [FailTest] When error occurs during the actual installation process
172
- def install_puppet(opts = {})
173
- default_download_url = 'http://downloads.puppetlabs.com'
174
- opts = {:win_download_url => "#{default_download_url}/windows",
175
- :mac_download_url => "#{default_download_url}/mac"}.merge(opts)
176
- hosts.each do |host|
177
- if host['platform'] =~ /el-(5|6|7)/
178
- relver = $1
179
- install_puppet_from_rpm host, opts.merge(:release => relver, :family => 'el')
180
- elsif host['platform'] =~ /fedora-(\d+)/
181
- relver = $1
182
- install_puppet_from_rpm host, opts.merge(:release => relver, :family => 'fedora')
183
- elsif host['platform'] =~ /(ubuntu|debian|cumulus)/
184
- install_puppet_from_deb host, opts
185
- elsif host['platform'] =~ /windows/
186
- relver = opts[:version]
187
- install_puppet_from_msi host, opts
188
- elsif host['platform'] =~ /osx/
189
- install_puppet_from_dmg host, opts
190
- else
191
- if opts[:default_action] == 'gem_install'
192
- install_puppet_from_gem host, opts
193
- else
194
- raise "install_puppet() called for unsupported platform '#{host['platform']}' on '#{host.name}'"
195
- end
196
- end
197
-
198
- # Certain install paths may not create the config dirs/files needed
199
- on host, "mkdir -p #{host['puppetpath']}" unless host[:type] =~ /aio/
200
- on host, "echo '' >> #{host.puppet['hiera_config']}"
201
- end
202
- nil
203
- end
204
-
205
- # Configure puppet.conf for all hosts based upon a provided Hash
206
- # @param [Hash{Symbol=>String}] opts
207
- # @option opts [Hash{String=>String}] :main configure the main section of puppet.conf
208
- # @option opts [Hash{String=>String}] :agent configure the agent section of puppet.conf
209
- #
210
- # @return nil
211
- def configure_puppet(opts={})
212
- hosts.each do |host|
213
- configure_puppet_on(host,opts)
214
- end
215
- end
216
-
217
- # Configure puppet.conf on the given host based upon a provided hash
218
- # @param [Host] host The host to configure puppet.conf on
219
- # @param [Hash{Symbol=>String}] opts
220
- # @option opts [Hash{String=>String}] :main configure the main section of puppet.conf
221
- # @option opts [Hash{String=>String}] :agent configure the agent section of puppet.conf
222
- #
223
- # @example will configure /etc/puppet.conf on the puppet master.
224
- # config = {
225
- # 'main' => {
226
- # 'server' => 'testbox.test.local',
227
- # 'certname' => 'testbox.test.local',
228
- # 'logdir' => '/var/log/puppet',
229
- # 'vardir' => '/var/lib/puppet',
230
- # 'ssldir' => '/var/lib/puppet/ssl',
231
- # 'rundir' => '/var/run/puppet'
232
- # },
233
- # 'agent' => {
234
- # 'environment' => 'dev'
235
- # }
236
- # }
237
- # configure_puppet(master, config)
238
- #
239
- # @return nil
240
- def configure_puppet_on(host, opts = {})
241
- if host['platform'] =~ /windows/
242
- puppet_conf = host.puppet['config']
243
- conf_data = ''
244
- opts.each do |section,options|
245
- conf_data << "[#{section}]`n"
246
- options.each do |option,value|
247
- conf_data << "#{option}=#{value}`n"
248
- end
249
- conf_data << "`n"
250
- end
251
- on host, powershell("\$text = \\\"#{conf_data}\\\"; Set-Content -path '#{puppet_conf}' -value \$text")
252
- else
253
- puppet_conf = host.puppet['config']
254
- conf_data = ''
255
- opts.each do |section,options|
256
- conf_data << "[#{section}]\n"
257
- options.each do |option,value|
258
- conf_data << "#{option}=#{value}\n"
259
- end
260
- conf_data << "\n"
261
- end
262
- on host, "echo \"#{conf_data}\" > #{puppet_conf}"
263
- end
264
- end
265
-
266
- # Installs Puppet and dependencies using rpm
267
- #
268
- # @param [Host] host The host to install packages on
269
- # @param [Hash{Symbol=>String}] opts An options hash
270
- # @option opts [String] :version The version of Puppet to install, if nil installs latest version
271
- # @option opts [String] :facter_version The version of Facter to install, if nil installs latest version
272
- # @option opts [String] :hiera_version The version of Hiera to install, if nil installs latest version
273
- # @option opts [String] :default_action What to do if we don't know how to install native packages on host.
274
- # Valid value is 'gem_install' or nil. If nil raises an exception when
275
- # on an unsupported platform. When 'gem_install' attempts to install
276
- # Puppet via gem.
277
- # @option opts [String] :release The major release of the OS
278
- # @option opts [String] :family The OS family (one of 'el' or 'fedora')
279
- #
280
- # @return nil
281
- # @api private
282
- def install_puppet_from_rpm( host, opts )
283
- release_package_string = "http://yum.puppetlabs.com/puppetlabs-release-#{opts[:family]}-#{opts[:release]}.noarch.rpm"
284
-
285
- on host, "rpm -q --quiet puppetlabs-release || rpm -ivh #{release_package_string}"
286
-
287
- if opts[:facter_version]
288
- on host, "yum install -y facter-#{opts[:facter_version]}"
289
- end
290
-
291
- if opts[:hiera_version]
292
- on host, "yum install -y hiera-#{opts[:hiera_version]}"
293
- end
294
-
295
- puppet_pkg = opts[:version] ? "puppet-#{opts[:version]}" : 'puppet'
296
- on host, "yum install -y #{puppet_pkg}"
297
- end
298
-
299
- # Installs Puppet and dependencies from deb
300
- #
301
- # @param [Host] host The host to install packages on
302
- # @param [Hash{Symbol=>String}] opts An options hash
303
- # @option opts [String] :version The version of Puppet to install, if nil installs latest version
304
- # @option opts [String] :facter_version The version of Facter to install, if nil installs latest version
305
- # @option opts [String] :hiera_version The version of Hiera to install, if nil installs latest version
306
- #
307
- # @return nil
308
- # @api private
309
- def install_puppet_from_deb( host, opts )
310
- if ! host.check_for_package 'lsb-release'
311
- host.install_package('lsb-release')
312
- end
313
-
314
- if ! host.check_for_command 'curl'
315
- on host, 'apt-get install -y curl'
316
- end
317
-
318
- on host, 'curl -O http://apt.puppetlabs.com/puppetlabs-release-$(lsb_release -c -s).deb'
319
- on host, 'dpkg -i puppetlabs-release-$(lsb_release -c -s).deb'
320
- on host, 'apt-get update'
321
-
322
- if opts[:facter_version]
323
- on host, "apt-get install -y facter=#{opts[:facter_version]}-1puppetlabs1"
324
- end
325
-
326
- if opts[:hiera_version]
327
- on host, "apt-get install -y hiera=#{opts[:hiera_version]}-1puppetlabs1"
328
- end
329
-
330
- if opts[:version]
331
- on host, "apt-get install -y puppet-common=#{opts[:version]}-1puppetlabs1"
332
- on host, "apt-get install -y puppet=#{opts[:version]}-1puppetlabs1"
333
- else
334
- on host, 'apt-get install -y puppet'
335
- end
336
- end
337
-
338
- # Installs Puppet and dependencies from msi
339
- #
340
- # @param [Host] host The host to install packages on
341
- # @param [Hash{Symbol=>String}] opts An options hash
342
- # @option opts [String] :version The version of Puppet to install, required
343
- # @option opts [String] :win_download_url The url to download puppet from
344
- #
345
- # @note on windows, the +:ruby_arch+ host parameter can determine in addition
346
- # to other settings whether the 32 or 64bit install is used
347
- def install_puppet_from_msi( host, opts )
348
- #only install 64bit builds if
349
- # - we are on puppet version 3.7+
350
- # - we do not have install_32 set on host
351
- # - we do not have install_32 set globally
352
- version = opts[:version]
353
- is_config_32 = host['ruby_arch'] == 'x86' || host['install_32'] || opts['install_32']
354
- if !(version_is_less(version, '3.7')) && host.is_x86_64? && !is_config_32
355
- host['dist'] = "puppet-#{version}-x64"
356
- else
357
- host['dist'] = "puppet-#{version}"
358
- end
359
- link = "#{opts[:win_download_url]}/#{host['dist']}.msi"
360
- if not link_exists?( link )
361
- raise "Puppet #{version} at #{link} does not exist!"
362
- end
363
-
364
- if host.is_cygwin?
365
- dest = "#{host['dist']}.msi"
366
- on host, "curl -O #{link}"
367
-
368
- #Because the msi installer doesn't add Puppet to the environment path
369
- #Add both potential paths for simplicity
370
- #NOTE - this is unnecessary if the host has been correctly identified as 'foss' during set up
371
- puppetbin_path = "\"/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/bin\":\"/cygdrive/c/Program Files/Puppet Labs/Puppet/bin\""
372
- on host, %Q{ echo 'export PATH=$PATH:#{puppetbin_path}' > /etc/bash.bashrc }
373
- else
374
- dest = "C:\\Windows\\Temp\\#{host['dist']}.msi"
375
-
376
- on host, powershell("$webclient = New-Object System.Net.WebClient; $webclient.DownloadFile('#{link}','#{dest}')")
377
-
378
- host.mkdir_p host['distmoduledir']
379
- end
380
-
381
- if host.is_cygwin?
382
- on host, "cmd /C 'start /w msiexec.exe /qn /i #{dest}'"
383
- else
384
- on host, "start /w msiexec.exe /qn /i #{dest}"
19
+ separator = host['pathseparator']
20
+ if not host.is_powershell?
21
+ separator = ':'
385
22
  end
23
+ path.join(separator)
386
24
  end
387
25
 
388
- # Installs Puppet and dependencies from dmg
389
- #
390
- # @param [Host] host The host to install packages on
391
- # @param [Hash{Symbol=>String}] opts An options hash
392
- # @option opts [String] :version The version of Puppet to install, required
393
- # @option opts [String] :facter_version The version of Facter to install, required
394
- # @option opts [String] :hiera_version The version of Hiera to install, required
395
- # @option opts [String] :mac_download_url Url to download msi pattern of %url%/puppet-%version%.msi
396
- #
397
- # @return nil
398
- # @api private
399
- def install_puppet_from_dmg( host, opts )
400
-
401
- puppet_ver = opts[:version]
402
- facter_ver = opts[:facter_version]
403
- hiera_ver = opts[:hiera_version]
404
-
405
- if [puppet_ver, facter_ver, hiera_ver].include?(nil)
406
- raise "You need to specify versions for OSX host\n eg. install_puppet({:version => '3.6.2',:facter_version => '2.1.0',:hiera_version => '1.3.4',})"
407
- end
408
-
409
- on host, "curl -O #{opts[:mac_download_url]}/puppet-#{puppet_ver}.dmg"
410
- on host, "curl -O #{opts[:mac_download_url]}/facter-#{facter_ver}.dmg"
411
- on host, "curl -O #{opts[:mac_download_url]}/hiera-#{hiera_ver}.dmg"
412
-
413
- on host, "hdiutil attach puppet-#{puppet_ver}.dmg"
414
- on host, "hdiutil attach facter-#{facter_ver}.dmg"
415
- on host, "hdiutil attach hiera-#{hiera_ver}.dmg"
416
-
417
- on host, "installer -pkg /Volumes/puppet-#{puppet_ver}/puppet-#{puppet_ver}.pkg -target /"
418
- on host, "installer -pkg /Volumes/facter-#{facter_ver}/facter-#{facter_ver}.pkg -target /"
419
- on host, "installer -pkg /Volumes/hiera-#{hiera_ver}/hiera-#{hiera_ver}.pkg -target /"
420
- end
421
-
422
- # Installs Puppet and dependencies from gem
423
- #
424
- # @param [Host] host The host to install packages on
425
- # @param [Hash{Symbol=>String}] opts An options hash
426
- # @option opts [String] :version The version of Puppet to install, if nil installs latest
427
- # @option opts [String] :facter_version The version of Facter to install, if nil installs latest
428
- # @option opts [String] :hiera_version The version of Hiera to install, if nil installs latest
429
- #
430
- # @return nil
431
- # @raise [StandardError] if gem does not exist on target host
432
- # @api private
433
- def install_puppet_from_gem( host, opts )
434
- # There are a lot of special things to do for Solaris and Solaris 10.
435
- # This is easier than checking host['platform'] every time.
436
- is_solaris10 = host['platform'] =~ /solaris-10/
437
- is_solaris = host['platform'] =~ /solaris/
438
-
439
- # Hosts may be provisioned with csw but pkgutil won't be in the
440
- # PATH by default to avoid changing the behavior for Puppet's tests
441
- if is_solaris10
442
- on host, 'ln -s /opt/csw/bin/pkgutil /usr/bin/pkgutil'
443
- end
444
-
445
- # Solaris doesn't necessarily have this, but gem needs it
446
- if is_solaris
447
- on host, 'mkdir -p /var/lib'
448
- end
449
-
450
- unless host.check_for_command( 'gem' )
451
- gempkg = case host['platform']
452
- when /solaris-11/ then 'ruby-18'
453
- when /ubuntu-14/ then 'ruby'
454
- when /solaris-10|ubuntu|debian|el-|cumulus/ then 'rubygems'
455
- else
456
- raise "install_puppet() called with default_action " +
457
- "'gem_install' but program `gem' is " +
458
- "not installed on #{host.name}"
459
- end
460
-
461
- host.install_package gempkg
462
- end
463
-
464
- # Link 'gem' to /usr/bin instead of adding /opt/csw/bin to PATH.
465
- if is_solaris10
466
- on host, 'ln -s /opt/csw/bin/gem /usr/bin/gem'
467
- end
468
-
469
- if host['platform'] =~ /debian|ubuntu|solaris|cumulus/
470
- gem_env = YAML.load( on( host, 'gem environment' ).stdout )
471
- gem_paths_array = gem_env['RubyGems Environment'].find {|h| h['GEM PATHS'] != nil }['GEM PATHS']
472
- path_with_gem = 'export PATH=' + gem_paths_array.join(':') + ':${PATH}'
473
- on host, "echo '#{path_with_gem}' >> ~/.bashrc"
474
- end
475
-
476
- if opts[:facter_version]
477
- on host, "gem install facter -v#{opts[:facter_version]} --no-ri --no-rdoc"
478
- end
479
-
480
- if opts[:hiera_version]
481
- on host, "gem install hiera -v#{opts[:hiera_version]} --no-ri --no-rdoc"
482
- end
483
-
484
- ver_cmd = opts[:version] ? "-v#{opts[:version]}" : ''
485
- on host, "gem install puppet #{ver_cmd} --no-ri --no-rdoc"
486
-
487
- # Similar to the treatment of 'gem' above.
488
- # This avoids adding /opt/csw/bin to PATH.
489
- if is_solaris
490
- gem_env = YAML.load( on( host, 'gem environment' ).stdout )
491
- # This is the section we want - this has the dir where gem executables go.
492
- env_sect = 'EXECUTABLE DIRECTORY'
493
- # Get the directory where 'gem' installs executables.
494
- # On Solaris 10 this is usually /opt/csw/bin
495
- gem_exec_dir = gem_env['RubyGems Environment'].find {|h| h[env_sect] != nil }[env_sect]
496
-
497
- on host, "ln -s #{gem_exec_dir}/hiera /usr/bin/hiera"
498
- on host, "ln -s #{gem_exec_dir}/facter /usr/bin/facter"
499
- on host, "ln -s #{gem_exec_dir}/puppet /usr/bin/puppet"
26
+ #Append puppetbindir, facterbindir and hierabindir to the PATH for each host
27
+ # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
28
+ # or a role (String or Symbol) that identifies one or more hosts.
29
+ def add_puppet_paths_on(hosts)
30
+ block_on hosts do | host |
31
+ host.add_env_var('PATH', construct_puppet_path(host))
500
32
  end
501
33
  end
502
34
 
503
- # Install official puppetlabs release repository configuration on host.
35
+ #Remove puppetbindir, facterbindir and hierabindir to the PATH for each host
504
36
  #
505
- # @param [Host] host An object implementing {Beaker::Hosts}'s
506
- # interface.
507
- #
508
- # @note This method only works on redhat-like and debian-like hosts.
509
- #
510
- def install_puppetlabs_release_repo ( host )
511
- variant, version, arch, codename = host['platform'].to_array
512
-
513
- case variant
514
- when /^(fedora|el|centos)$/
515
- variant = (($1 == 'centos') ? 'el' : $1)
516
-
517
- rpm = options[:release_yum_repo_url] +
518
- "/puppetlabs-release-%s-%s.noarch.rpm" % [variant, version]
519
-
520
- on host, "rpm -ivh #{rpm}"
521
-
522
- when /^(debian|ubuntu|cumulus)$/
523
- deb = URI.join(options[:release_apt_repo_url], "puppetlabs-release-%s.deb" % codename)
524
-
525
- on host, "wget -O /tmp/puppet.deb #{deb}"
526
- on host, "dpkg -i --force-all /tmp/puppet.deb"
527
- on host, "apt-get update"
528
- else
529
- raise "No repository installation step for #{variant} yet..."
37
+ # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
38
+ # or a role (String or Symbol) that identifies one or more hosts.
39
+ def remove_puppet_paths_on(hosts)
40
+ block_on hosts do | host |
41
+ host.delete_env_var('PATH', construct_puppet_path(host))
530
42
  end
531
43
  end
532
44
 
533
- # Install development repository on the given host. This method pushes all
534
- # repository information including package files for the specified
535
- # package_name to the host and modifies the repository configuration file
536
- # to point at the new repository. This is particularly useful for
537
- # installing development packages on hosts that can't access the builds
538
- # server.
539
- #
540
- # @param [Host] host An object implementing {Beaker::Hosts}'s
541
- # interface.
542
- # @param [String] package_name The name of the package whose repository is
543
- # being installed.
544
- # @param [String] build_version A string identifying the output of a
545
- # packaging job for use in looking up
546
- # repository directory information
547
- # @param [String] repo_configs_dir A local directory where repository files will be
548
- # stored as an intermediate step before
549
- # pushing them to the given host.
550
- # @param [Hash{Symbol=>String}] opts Options to alter execution.
551
- # @option opts [String] :dev_builds_url The URL to look for dev builds.
552
- # @option opts [String, Array<String>] :dev_builds_repos The repo(s)
553
- # to check for dev builds in.
554
- #
555
- # @note This method only works on redhat-like and debian-like hosts.
556
- #
557
- def install_puppetlabs_dev_repo ( host, package_name, build_version,
558
- repo_configs_dir = 'tmp/repo_configs',
559
- opts = options )
560
- variant, version, arch, codename = host['platform'].to_array
561
- platform_configs_dir = File.join(repo_configs_dir, variant)
562
-
563
- # some of the uses of dev_builds_url below can't include protocol info,
564
- # plus this opens up possibility of switching the behavior on provided
565
- # url type
566
- _, protocol, hostname = opts[:dev_builds_url].partition /.*:\/\//
567
- dev_builds_url = protocol + hostname
568
-
569
- on host, "mkdir -p /root/#{package_name}"
570
-
571
- case variant
572
- when /^(fedora|el|centos)$/
573
- variant = (($1 == 'centos') ? 'el' : $1)
574
- fedora_prefix = ((variant == 'fedora') ? 'f' : '')
575
-
576
- if host.is_pe?
577
- pattern = "pl-%s-%s-repos-pe-%s-%s%s-%s.repo"
578
- else
579
- pattern = "pl-%s-%s-%s-%s%s-%s.repo"
580
- end
581
-
582
- repo_filename = pattern % [
583
- package_name,
584
- build_version,
585
- variant,
586
- fedora_prefix,
587
- version,
588
- arch
589
- ]
590
-
591
- repo = fetch_http_file( "%s/%s/%s/repo_configs/rpm/" %
592
- [ dev_builds_url, package_name, build_version ],
593
- repo_filename,
594
- platform_configs_dir)
595
-
596
- link = nil
597
- package_repos = opts[:dev_builds_repos].nil? ? [] : [opts[:dev_builds_repos]]
598
- package_repos.push(['products', 'devel']).flatten!
599
- package_repos.each do |repo|
600
- link = "%s/%s/%s/repos/%s/%s%s/%s/%s/" %
601
- [ dev_builds_url, package_name, build_version, variant,
602
- fedora_prefix, version, repo, arch ]
603
-
604
- unless link_exists?( link )
605
- logger.debug("couldn't find link at '#{repo}', falling back to next option...")
606
- else
607
- logger.debug("found link at '#{repo}'")
608
- break
609
- end
610
- end
611
- raise "Unable to reach a repo directory at #{link}" unless link_exists?( link )
612
-
613
- repo_dir = fetch_http_dir( link, platform_configs_dir )
614
-
615
- config_dir = '/etc/yum.repos.d/'
616
- scp_to host, repo, config_dir
617
- scp_to host, repo_dir, "/root/#{package_name}"
618
-
619
- search = "baseurl\\s*=\\s*http:\\/\\/#{hostname}.*$"
620
- replace = "baseurl=file:\\/\\/\\/root\\/#{package_name}\\/#{arch}"
621
- sed_command = "sed -i 's/#{search}/#{replace}/'"
622
- find_and_sed = "find #{config_dir} -name \"*.repo\" -exec #{sed_command} {} \\;"
623
-
624
- on host, find_and_sed
625
-
626
- when /^(debian|ubuntu|cumulus)$/
627
- list = fetch_http_file( "%s/%s/%s/repo_configs/deb/" %
628
- [ dev_builds_url, package_name, build_version ],
629
- "pl-%s-%s-%s.list" %
630
- [ package_name, build_version, codename ],
631
- platform_configs_dir )
632
-
633
- repo_dir = fetch_http_dir( "%s/%s/%s/repos/apt/%s" %
634
- [ dev_builds_url, package_name,
635
- build_version, codename ],
636
- platform_configs_dir )
637
-
638
- config_dir = '/etc/apt/sources.list.d'
639
- scp_to host, list, config_dir
640
- scp_to host, repo_dir, "/root/#{package_name}"
641
-
642
- repo_name = nil
643
- package_repos = opts[:dev_builds_repos].nil? ? [] : [opts[:dev_builds_repos]]
644
- package_repos.flatten!
645
- package_repos.each do |repo|
646
- repo_path = "/root/#{package_name}/#{codename}/#{repo}"
647
- repo_check = on(host, "[[ -d #{repo_path} ]]", :acceptable_exit_codes => [0,1])
648
- if repo_check.exit_code == 0
649
- logger.debug("found repo at '#{repo_path}'")
650
- repo_name = repo
651
- break
652
- else
653
- logger.debug("couldn't find repo at '#{repo_path}', falling back to next option...")
654
- end
655
- end
656
- if repo_name.nil?
657
- repo_name = 'main'
658
- logger.debug("using default repo '#{repo_name}'")
659
- end
660
-
661
- search = "deb\\s\\+http:\\/\\/#{hostname}.*$"
662
- replace = "deb file:\\/\\/\\/root\\/#{package_name}\\/#{codename} #{codename} #{repo_name}"
663
- sed_command = "sed -i 's/#{search}/#{replace}/'"
664
- find_and_sed = "find #{config_dir} -name \"*.list\" -exec #{sed_command} {} \\;"
665
-
666
- on host, find_and_sed
667
- on host, "apt-get update"
668
-
669
- else
670
- raise "No repository installation step for #{variant} yet..."
671
- end
672
- end
673
-
674
- # Installs packages from the local development repository on the given host
675
- #
676
- # @param [Host] host An object implementing {Beaker::Hosts}'s
677
- # interface.
678
- # @param [Regexp] package_name The name of the package whose repository is
679
- # being installed.
680
- #
681
- # @note This method only works on redhat-like and debian-like hosts.
682
- # @note This method is paired to be run directly after {#install_puppetlabs_dev_repo}
683
- #
684
- def install_packages_from_local_dev_repo( host, package_name )
685
- if host['platform'] =~ /debian|ubuntu|cumulus/
686
- find_filename = '*.deb'
687
- find_command = 'dpkg -i'
688
- elsif host['platform'] =~ /fedora|el|centos/
689
- find_filename = '*.rpm'
690
- find_command = 'rpm -ivh'
691
- else
692
- raise "No repository installation step for #{host['platform']} yet..."
693
- end
694
- find_command = "find /root/#{package_name} -type f -name '#{find_filename}' -exec #{find_command} {} \\;"
695
- on host, find_command
696
- end
697
-
698
- # Install development repo of the puppet-agent on the given host
699
- #
700
- # @param [Host] host An object implementing {Beaker::Hosts}'s interface
701
- # @param [Hash{Symbol=>String}] opts An options hash
702
- # @option opts [String] :version The version of puppet-agent to install
703
- # @option opts [String] :copy_base_local Directory where puppet-agent artifact
704
- # will be stored locally
705
- # (default: 'tmp/repo_configs')
706
- # @option opts [String] :copy_dir_external Directory where puppet-agent
707
- # artifact will be pushed to on the external machine
708
- # (default: '/root')
709
- #
710
- # @note on windows, the +:ruby_arch+ host parameter can determine in addition
711
- # to other settings whether the 32 or 64bit install is used
712
- #
713
- # @return nil
714
- def install_puppetagent_dev_repo( host, opts )
715
- opts[:copy_base_local] ||= File.join('tmp', 'repo_configs')
716
- opts[:copy_dir_external] ||= File.join('/', 'root')
717
- variant, version, arch, codename = host['platform'].to_array
718
- release_path = "#{options[:dev_builds_url]}/puppet-agent/#{opts[:version]}/artifacts/"
719
- copy_dir_local = File.join(opts[:copy_base_local], variant)
720
- onhost_copy_base = opts[:copy_dir_external]
721
-
722
- case variant
723
- when /^(fedora|el|centos)$/
724
- release_path << "el/#{version}/products/#{arch}"
725
- release_file = "puppet-agent-#{opts[:version]}-1.#{arch}.rpm"
726
- when /^(debian|ubuntu|cumulus)$/
727
- release_path << "deb/#{codename}"
728
- release_file = "puppet-agent_#{opts[:version]}-1_#{arch}.deb"
729
- when /^windows$/
730
- release_path << 'windows'
731
- onhost_copy_base = '`cygpath -smF 35`/'
732
- is_config_32 = host['ruby_arch'] == 'x86' || host['install_32'] || opts['install_32']
733
- should_install_64bit = host.is_x86_64? && !is_config_32
734
- # only install 64bit builds if
735
- # - we do not have install_32 set on host
736
- # - we do not have install_32 set globally
737
- arch_suffix = should_install_64bit ? '64' : '86'
738
- release_file = "puppet-agent-x#{arch_suffix}.msi"
739
- else
740
- raise "No repository installation step for #{variant} yet..."
741
- end
742
-
743
- onhost_copied_file = File.join(onhost_copy_base, release_file)
744
- fetch_http_file( release_path, release_file, copy_dir_local)
745
- scp_to host, File.join(copy_dir_local, release_file), onhost_copy_base
746
-
747
- case variant
748
- when /^(fedora|el|centos)$/
749
- on host, "rpm -ivh #{onhost_copied_file}"
750
- when /^(debian|ubuntu|cumulus)$/
751
- on host, "dpkg -i --force-all #{onhost_copied_file}"
752
- on host, "apt-get update"
753
- when /^windows$/
754
- result = on host, "echo #{onhost_copied_file}"
755
- onhost_copied_file = result.raw_output.chomp
756
- on host, Command.new("start /w #{onhost_copied_file}", [], { :cmdexe => true })
757
- end
758
- end
759
-
760
- # This method will install a pem file certifcate on a windows host
761
- #
762
- # @param [Host] host A host object
763
- # @param [String] cert_name The name of the pem file
764
- # @param [String] cert The contents of the certificate
765
- #
766
- def install_cert_on_windows(host, cert_name, cert)
767
- create_remote_file(host, "C:\\Windows\\Temp\\#{cert_name}.pem", cert)
768
- on host, "certutil -v -addstore Root C:\\Windows\\Temp\\#{cert_name}.pem"
769
- end
770
45
  end
771
46
  end
772
47
  end