beaker 2.13.0 → 2.14.0

Sign up to get free protection for your applications and to get access to all the features.
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