beaker 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +8 -0
  3. data/README.md +6 -6
  4. data/beaker.gemspec +6 -2
  5. data/lib/beaker.rb +1 -1
  6. data/lib/beaker/answers.rb +34 -7
  7. data/lib/beaker/answers/version20.rb +124 -0
  8. data/lib/beaker/answers/version28.rb +21 -0
  9. data/lib/beaker/answers/version30.rb +24 -5
  10. data/lib/beaker/cli.rb +55 -41
  11. data/lib/beaker/command.rb +2 -2
  12. data/lib/beaker/dsl/helpers.rb +320 -106
  13. data/lib/beaker/dsl/install_utils.rb +202 -81
  14. data/lib/beaker/dsl/roles.rb +40 -0
  15. data/lib/beaker/host.rb +28 -20
  16. data/lib/beaker/host/unix.rb +7 -4
  17. data/lib/beaker/host/unix/pkg.rb +42 -12
  18. data/lib/beaker/host/windows.rb +9 -5
  19. data/lib/beaker/host/windows/group.rb +1 -1
  20. data/lib/beaker/host/windows/pkg.rb +41 -8
  21. data/lib/beaker/hypervisor.rb +23 -10
  22. data/lib/beaker/hypervisor/aixer.rb +15 -19
  23. data/lib/beaker/hypervisor/blimper.rb +71 -72
  24. data/lib/beaker/hypervisor/fusion.rb +11 -10
  25. data/lib/beaker/hypervisor/solaris.rb +17 -23
  26. data/lib/beaker/hypervisor/vagrant.rb +27 -12
  27. data/lib/beaker/hypervisor/vcloud.rb +154 -138
  28. data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
  29. data/lib/beaker/hypervisor/vsphere.rb +8 -5
  30. data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
  31. data/lib/beaker/network_manager.rb +16 -12
  32. data/lib/beaker/options/command_line_parser.rb +199 -0
  33. data/lib/beaker/options/hosts_file_parser.rb +39 -0
  34. data/lib/beaker/options/options_file_parser.rb +45 -0
  35. data/lib/beaker/options/options_hash.rb +294 -0
  36. data/lib/beaker/options/parser.rb +288 -0
  37. data/lib/beaker/options/pe_version_scraper.rb +35 -0
  38. data/lib/beaker/options/presets.rb +70 -0
  39. data/lib/beaker/shared.rb +2 -1
  40. data/lib/beaker/shared/host_handler.rb +7 -2
  41. data/lib/beaker/shared/repetition.rb +1 -0
  42. data/lib/beaker/shared/timed.rb +14 -0
  43. data/lib/beaker/test_case.rb +2 -38
  44. data/lib/beaker/test_suite.rb +11 -25
  45. data/lib/beaker/utils/repo_control.rb +6 -8
  46. data/lib/beaker/utils/setup_helper.rb +9 -20
  47. data/spec/beaker/answers_spec.rb +109 -0
  48. data/spec/beaker/command_spec.rb +2 -2
  49. data/spec/beaker/dsl/assertions_spec.rb +1 -3
  50. data/spec/beaker/dsl/helpers_spec.rb +519 -84
  51. data/spec/beaker/dsl/install_utils_spec.rb +265 -16
  52. data/spec/beaker/dsl/roles_spec.rb +31 -10
  53. data/spec/beaker/host/windows/group_spec.rb +55 -0
  54. data/spec/beaker/host_spec.rb +130 -40
  55. data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
  56. data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
  57. data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
  58. data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
  59. data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
  60. data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
  61. data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
  62. data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
  63. data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
  64. data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
  65. data/spec/beaker/options/command_line_parser_spec.rb +25 -0
  66. data/spec/beaker/options/data/LATEST +1 -0
  67. data/spec/beaker/options/data/badyaml.cfg +21 -0
  68. data/spec/beaker/options/data/hosts.cfg +21 -0
  69. data/spec/beaker/options/data/opts.txt +6 -0
  70. data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
  71. data/spec/beaker/options/options_file_parser_spec.rb +23 -0
  72. data/spec/beaker/options/options_hash_spec.rb +111 -0
  73. data/spec/beaker/options/parser_spec.rb +172 -0
  74. data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
  75. data/spec/beaker/options/presets_spec.rb +24 -0
  76. data/spec/beaker/puppet_command_spec.rb +54 -21
  77. data/spec/beaker/shared/error_handler_spec.rb +40 -0
  78. data/spec/beaker/shared/host_handler_spec.rb +104 -0
  79. data/spec/beaker/shared/repetition_spec.rb +72 -0
  80. data/spec/beaker/test_suite_spec.rb +3 -16
  81. data/spec/beaker/utils/ntp_control_spec.rb +42 -0
  82. data/spec/beaker/utils/repo_control_spec.rb +168 -0
  83. data/spec/beaker/utils/setup_helper_spec.rb +82 -0
  84. data/spec/beaker/utils/validator_spec.rb +58 -0
  85. data/spec/helpers.rb +97 -0
  86. data/spec/matchers.rb +39 -0
  87. data/spec/mock_blimpy.rb +48 -0
  88. data/spec/mock_fission.rb +60 -0
  89. data/spec/mock_vsphere.rb +310 -0
  90. data/spec/mock_vsphere_helper.rb +183 -0
  91. data/spec/mocks.rb +83 -0
  92. data/spec/spec_helper.rb +8 -1
  93. metadata +106 -13
  94. data/beaker.rb +0 -10
  95. data/lib/beaker/options_parsing.rb +0 -323
  96. data/lib/beaker/test_config.rb +0 -148
  97. data/spec/beaker/options_parsing_spec.rb +0 -37
  98. data/spec/mocks_and_helpers.rb +0 -34
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- M2IyYWFiMWQxN2RhMTU1NTlmY2FjNDFhNjYzNDFiNmZiMDMyYzc1YQ==
4
+ ZWQyZDI5MDhjOTdlYjFmMWM0NmMyNzVjYWYyZTMxMjZkNjViMTk1Mg==
5
5
  data.tar.gz: !binary |-
6
- YmIyMWI4NDYwZDkyZTRmNjJmMTFiODgyYzkxMjZmNTllYTFkY2Q0Ng==
6
+ ODYxMGI2Y2E3NDc3NTViMzBhYjRhMGNlNDkxNDljMmYyMDcwNmZjYw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZGQ0YjUxZWU5YzAzZjFjZDhmNzBmYWEyNjdkZDE3NTIwNDRlYjMxNmFkYmEy
10
- ODc3ZmI0ZjU5MzI1NmQ2MjFiY2ZhNDczYjEyNGE1ZDA4OGYzYTk5ZTU2YmMy
11
- NWVhOTMyMmZlYTg1NzRlYTU5YWZmNTk5MTNlODgzMDcwNWI2Mjk=
9
+ YmViMDgxMTgwZjQ3NDk5M2NhZDkwYzAwMDA0MDNlMGE4NDA1NDI4YjM4ZTkw
10
+ NTFhMDBhMTczMzZmMTgzMmE2YmIxNzlhMDY3MzAyMGVkY2YyMGVmMmU0Njdh
11
+ ZThlYWE5NzY2MDZiZTg1ZTk1OTZhZmFiZDcwZTk3ZDdlOGJiYjA=
12
12
  data.tar.gz: !binary |-
13
- NTBlYjdiMjJmM2YyZWI2NDk1ZDZkYjEyYTdhNDc1OTkyYjhkMTI0MGViNTZi
14
- N2NmNzAzZTU4MmE4N2ZjYTBkMzM0YzNlOWEyM2M1MTQ3YTYyNTA0MGFiNmNh
15
- MTZhYTYyZTEyM2YwZGNhMjcwZWE3ODdjOTMwMWRjZTE3NzhmNzA=
13
+ ZDFiODE1ZjRlNjkzNDE5ODA4NmUxYmU3MmExZTQ4NDA4MTNjYzg3NjY1MmI3
14
+ YWNhYmJmZDcyNjM3ZGRiNDJlOGFmYzNmNTI1YjY5NWIwNDAyMzJhNjMwYjVk
15
+ MzUyMmI2YWQ3ODFjNWMyOTRkNjJmOTUwNjBmMDgwMzY5NmI5Mjg=
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ script: "bundle exec rspec"
3
+ notifications:
4
+ email: false
5
+ rvm:
6
+ - 2.0.0
7
+ - 1.9.3
8
+ - 1.8.7
data/README.md CHANGED
@@ -34,7 +34,7 @@ Running Systest requires at least one 'System Under Test' (SUT) upon which to ru
34
34
  ## Prepare a Test Configuration File ##
35
35
  - The test harness is configuration driven
36
36
  - The config file is yaml formatted
37
- - The type of insallation and configuration is dictated by the config file, especialy for PE
37
+ - The type of insallation and configuration is dictated by the config file, especially for PE
38
38
 
39
39
  Here we have the host 'ubuntu-1004-64', a 64 bit Ubuntu box, serving as Puppet Master,
40
40
  Dashboard, and Agent; the host "ubuntu-1004-32", a 32-bit Ubunutu node, will be a
@@ -119,11 +119,11 @@ For example:
119
119
 
120
120
 
121
121
  ## VMWare Fusion support ##
122
- Pre-requisite: Fission gem installed and configured, including a ~/.fissionrc
123
- that points to the `vmrun` executable and where VMs can be found.
122
+ Pre-requisite: Fission gem installed and configured, including a `~/.fissionrc`
123
+ that points to the `vmrun` executable and where virtual machines can be found.
124
124
  Example `.fissionrc` file (it's YAML):
125
- ---
126
- vm_dir: "/Directory/containing/my/.VMX/files"
125
+
126
+ vm_dir: "/Directory/containing/my/.vmwarevm/files/"
127
127
  vmrun_bin: "/Applications/VMware Fusion.app/Contents/Library/vmrun"
128
128
 
129
129
  You can then use the following arguments in the node configuration:
@@ -136,7 +136,7 @@ There are a few additional options available in your configuration file. Each ho
136
136
  section can now use:
137
137
 
138
138
  - `vmname`: This is useful if the hostname of the VM doesn't match the name of
139
- the .VMX file on disk. The alias should be something fission can load.
139
+ the `.vmwarevm` file on disk. The alias should be something fission can load.
140
140
 
141
141
 
142
142
  Example:
data/beaker.gemspec CHANGED
@@ -6,7 +6,7 @@ less_than_one_nine = ruby_conf['MAJOR'].to_i == 1 && ruby_conf['MINOR'].to_i < 9
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "beaker"
9
- s.version = '0.0.0'
9
+ s.version = '1.0.0'
10
10
  s.authors = ["Puppetlabs"]
11
11
  s.email = ["delivery@puppetlabs.com"]
12
12
  s.homepage = "https://github.com/puppetlabs/beaker"
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  # Testing dependencies
23
- s.add_development_dependency 'rspec', '2.11.0'
23
+ s.add_development_dependency 'rspec', '~> 2.14.0'
24
24
  s.add_development_dependency 'fakefs', '0.4'
25
25
  s.add_development_dependency 'rake'
26
26
  s.add_development_dependency 'simplecov' unless less_than_one_nine
@@ -37,6 +37,10 @@ Gem::Specification.new do |s|
37
37
  s.add_runtime_dependency 'rbvmomi'
38
38
  s.add_runtime_dependency 'blimpy'
39
39
  s.add_runtime_dependency 'nokogiri', '1.5.10'
40
+ s.add_runtime_dependency 'mime-types', '1.25' if RUBY_VERSION < "1.9"
40
41
  s.add_runtime_dependency 'fission' if RUBY_PLATFORM =~ /darwin/i
41
42
  s.add_runtime_dependency 'inifile'
43
+ #unf is an 'optional' fog dependency, but it warns when it is missing
44
+ # see https://github.com/fog/fog/pull/2320/commits
45
+ s.add_runtime_dependency 'unf'
42
46
  end
data/lib/beaker.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rubygems' unless defined?(Gem)
2
2
  module Beaker
3
3
 
4
- %w( utils test_suite test_config result command options_parsing network_manager cli ).each do |lib|
4
+ %w( utils test_suite result command options network_manager cli ).each do |lib|
5
5
  begin
6
6
  require "beaker/#{lib}"
7
7
  rescue LoadError
@@ -1,4 +1,4 @@
1
- [ 'version30', 'version28' ].each do |file|
1
+ [ 'version30', 'version28', 'version20' ].each do |file|
2
2
  begin
3
3
  require "beaker/answers/#{file}"
4
4
  rescue LoadError
@@ -7,20 +7,47 @@
7
7
  end
8
8
 
9
9
  module Beaker
10
+ # This module provides static methods for accessing PE answer file
11
+ # information.
10
12
  module Answers
11
13
 
14
+ # When given a Puppet Enterprise version, a list of hosts and other
15
+ # qualifying data this method will return a hash (keyed from the hosts)
16
+ # of default Puppet Enterprise answer file data hashes.
17
+ #
18
+ # @param [String] version Puppet Enterprise version to generate answer data for
19
+ # @param [Array<Beaker::Host>] hosts An array of host objects.
20
+ # @param [String] master_certname Hostname of the puppet master.
21
+ # @param [Hash] options options for answer files
22
+ # @option options [Symbol] :type Should be one of :upgrade or :install.
23
+ # @return [Hash] A hash (keyed from hosts) containing hashes of answer file
24
+ # data.
12
25
  def self.answers(version, hosts, master_certname, options)
13
26
 
14
27
  case version
15
- when /\A3\.0/
16
- Version30.answers(hosts, master_certname, options)
17
- when /\A2\.8/
18
- Version28.answers(hosts, master_certname, options)
19
- else
20
- raise NotImplementedError, "Don't know how to generate answers for #{version}"
28
+ when /\A3\.[[:digit:]]/ # All 3.x so far have the same answers
29
+ Version30.answers(hosts, master_certname, options)
30
+ when /\A2\.8/
31
+ Version28.answers(hosts, master_certname, options)
32
+ when /\A2\.0/
33
+ Version20.answers(hosts, master_certname, options)
34
+ else
35
+ raise NotImplementedError, "Don't know how to generate answers for #{version}"
21
36
  end
22
37
  end
23
38
 
39
+ # This converts a data hash provided by answers, and returns a Puppet
40
+ # Enterprise compatible answer file ready for use.
41
+ #
42
+ # @param [Beaker::Host] host Host object in question to generate the answer
43
+ # file for.
44
+ # @param [Hash] answers Answers hash as returned by #answers
45
+ # @return [String] a string of answers
46
+ # @example Generating an answer file for a series of hosts
47
+ # hosts.each do |host|
48
+ # answers = Beaker::Answers.answers("2.0", hosts, "master")
49
+ # create_remote_file host, "/mypath/answer", Beaker::Answers.answer_string(host, answers)
50
+ # end
24
51
  def self.answer_string(host, answers)
25
52
  answers[host.name].map { |k,v| "#{k}=#{v}" }.join("\n")
26
53
  end
@@ -0,0 +1,124 @@
1
+ module Beaker
2
+ module Answers
3
+ # This class provides answer file information for PE version 2.0
4
+ #
5
+ # @api private
6
+ module Version20
7
+ # Return answer data for a host
8
+ #
9
+ # @param [Beaker::Host] host Host to return data for
10
+ # @param [String] master_certname Hostname of the puppet master.
11
+ # @param [Beaker::Host] master Host object representing the master
12
+ # @param [Beaker::Host] dashboard Host object representing the dashboard
13
+ # @param [Hash] options options for answer files
14
+ # @option options [Symbol] :type Should be one of :upgrade or :install.
15
+ # @return [Hash] A hash (keyed from hosts) containing hashes of answer file
16
+ # data.
17
+ def self.host_answers(host, master_certname, master, dashboard, options)
18
+ return nil if host['platform'] =~ /windows/
19
+
20
+ agent_a = {
21
+ :q_install => 'y',
22
+ :q_puppetagent_install => 'y',
23
+ :q_puppet_cloud_install => 'y',
24
+ :q_puppet_symlinks_install => 'y',
25
+ :q_vendor_packages_install => 'y',
26
+ :q_puppetagent_certname => host,
27
+ :q_puppetagent_server => master,
28
+
29
+ # Disable console and master by default
30
+ # This will be overridden by other blocks being merged in
31
+ :q_puppetmaster_install => 'n',
32
+ :q_puppet_enterpriseconsole_install => 'n',
33
+ }
34
+
35
+ master_a = {
36
+ :q_puppetmaster_install => 'y',
37
+ :q_puppetmaster_certname => master_certname,
38
+ :q_puppetmaster_install => 'y',
39
+ :q_puppetmaster_dnsaltnames => master_certname+",puppet",
40
+ :q_puppetmaster_enterpriseconsole_hostname => dashboard,
41
+ :q_puppetmaster_enterpriseconsole_port => 443,
42
+ :q_puppetmaster_forward_facts => 'y',
43
+ }
44
+
45
+ if master['ip']
46
+ master_a[:q_puppetmaster_dnsaltnames]+=","+master['ip']
47
+ end
48
+
49
+ dashboard_user = "'#{ENV['q_puppet_enterpriseconsole_auth_user_email'] || 'admin@example.com'}'"
50
+ smtp_host = "'#{ENV['q_puppet_enterpriseconsole_smtp_host'] || dashboard}'"
51
+ dashboard_password = ENV['q_puppet_enterpriseconsole_auth_password'] || '~!@#$%^*-/ aZ'
52
+ smtp_port = "'#{ENV['q_puppet_enterpriseconsole_smtp_port'] || 25}'"
53
+ smtp_username = ENV['q_puppet_enterpriseconsole_smtp_username']
54
+ smtp_password = ENV['q_puppet_enterpriseconsole_smtp_password']
55
+ smtp_use_tls = "'#{ENV['q_puppet_enterpriseconsole_smtp_use_tls'] || 'n'}'"
56
+
57
+ console_a = {
58
+ :q_puppet_enterpriseconsole_install => 'y',
59
+ :q_puppet_enterpriseconsole_database_install => 'y',
60
+ :q_puppet_enterpriseconsole_auth_database_name => 'console_auth',
61
+ :q_puppet_enterpriseconsole_auth_database_user => 'mYu7hu3r',
62
+ :q_puppet_enterpriseconsole_auth_database_password => "'#{dashboard_password}'",
63
+ :q_puppet_enterpriseconsole_database_name => 'console',
64
+ :q_puppet_enterpriseconsole_database_user => 'mYc0nS03u3r',
65
+ :q_puppet_enterpriseconsole_database_root_password => "'#{dashboard_password}'",
66
+ :q_puppet_enterpriseconsole_database_password => "'#{dashboard_password}'",
67
+ :q_puppet_enterpriseconsole_inventory_hostname => host,
68
+ :q_puppet_enterpriseconsole_inventory_certname => host,
69
+ :q_puppet_enterpriseconsole_inventory_dnsaltnames => master,
70
+ :q_puppet_enterpriseconsole_inventory_port => 8140,
71
+ :q_puppet_enterpriseconsole_master_hostname => master,
72
+
73
+ :q_puppet_enterpriseconsole_auth_user_email => dashboard_user,
74
+ :q_puppet_enterpriseconsole_auth_password => "'#{dashboard_password}'",
75
+
76
+ :q_puppet_enterpriseconsole_httpd_port => 443,
77
+
78
+ :q_puppet_enterpriseconsole_smtp_host => smtp_host,
79
+ :q_puppet_enterpriseconsole_smtp_use_tls => smtp_use_tls,
80
+ :q_puppet_enterpriseconsole_smtp_port => smtp_port,
81
+ }
82
+
83
+ console_a[:q_puppet_enterpriseconsole_auth_user] = console_a[:q_puppet_enterpriseconsole_auth_user_email]
84
+
85
+ if smtp_password and smtp_username
86
+ console_a.merge!({
87
+ :q_puppet_enterpriseconsole_smtp_password => "'#{smtp_password}'",
88
+ :q_puppet_enterpriseconsole_smtp_username => "'#{smtp_username}'",
89
+ :q_puppet_enterpriseconsole_smtp_user_auth => 'y'
90
+ })
91
+ end
92
+
93
+ answers = agent_a.dup
94
+ if host == master
95
+ answers.merge! master_a
96
+ end
97
+
98
+ if host == dashboard
99
+ answers.merge! console_a
100
+ end
101
+
102
+ return answers
103
+ end
104
+
105
+ # Return answer data for all hosts.
106
+ #
107
+ # @param [Array<Beaker::Host>] hosts An array of host objects.
108
+ # @param [String] master_certname Hostname of the puppet master.
109
+ # @param [Hash] options options for answer files
110
+ # @option options [Symbol] :type Should be one of :upgrade or :install.
111
+ # @return [Hash] A hash (keyed from hosts) containing hashes of answer file
112
+ # data.
113
+ def self.answers(hosts, master_certname, options)
114
+ the_answers = {}
115
+ dashboard = only_host_with_role(hosts, 'dashboard')
116
+ master = only_host_with_role(hosts, 'master')
117
+ hosts.each do |h|
118
+ the_answers[h.name] = host_answers(h, master_certname, master, dashboard, options)
119
+ end
120
+ return the_answers
121
+ end
122
+ end
123
+ end
124
+ end
@@ -1,7 +1,20 @@
1
1
  module Beaker
2
2
  module Answers
3
+ # This class provides answer file information for PE version 2.8
4
+ #
5
+ # @api private
3
6
  module Version28
4
7
 
8
+ # Return answer data for a host
9
+ #
10
+ # @param [Beaker::Host] host Host to return data for
11
+ # @param [String] master_certname Hostname of the puppet master.
12
+ # @param [Beaker::Host] master Host object representing the master
13
+ # @param [Beaker::Host] dashboard Host object representing the dashboard
14
+ # @param [Hash] options options for answer files
15
+ # @option options [Symbol] :type Should be one of :upgrade or :install.
16
+ # @return [Hash] A hash (keyed from hosts) containing hashes of answer file
17
+ # data.
5
18
  def self.host_answers(host, master_certname, master, dashboard, options)
6
19
  return nil if host['platform'] =~ /windows/
7
20
 
@@ -89,6 +102,14 @@ module Beaker
89
102
  return answers
90
103
  end
91
104
 
105
+ # Return answer data for all hosts.
106
+ #
107
+ # @param [Array<Beaker::Host>] hosts An array of host objects.
108
+ # @param [String] master_certname Hostname of the puppet master.
109
+ # @param [Hash] options options for answer files
110
+ # @option options [Symbol] :type Should be one of :upgrade or :install.
111
+ # @return [Hash] A hash (keyed from hosts) containing hashes of answer file
112
+ # data.
92
113
  def self.answers(hosts, master_certname, options)
93
114
  the_answers = {}
94
115
  dashboard = only_host_with_role(hosts, 'dashboard')
@@ -1,7 +1,19 @@
1
1
  module Beaker
2
2
  module Answers
3
+ # This class provides answer file information for PE version 3.x
4
+ #
5
+ # @api private
3
6
  module Version30
4
-
7
+ # Return answer data for a host
8
+ #
9
+ # @param [Beaker::Host] host Host to return data for
10
+ # @param [String] master_certname Hostname of the puppet master.
11
+ # @param [Beaker::Host] master Host object representing the master
12
+ # @param [Beaker::Host] dashboard Host object representing the dashboard
13
+ # @param [Hash] options options for answer files
14
+ # @option options [Symbol] :type Should be one of :upgrade or :install.
15
+ # @return [Hash] A hash (keyed from hosts) containing hashes of answer file
16
+ # data.
5
17
  def self.host_answers(host, master_certname, master, database, dashboard, options)
6
18
  # Windows hosts don't have normal answers...
7
19
  return nil if host['platform'] =~ /windows/
@@ -13,7 +25,7 @@ module Beaker
13
25
  :q_verify_packages => ENV['q_verify_packages'] || 'y',
14
26
  :q_puppet_symlinks_install => 'y',
15
27
  :q_puppetagent_certname => host,
16
- :q_puppetagent_server => master,
28
+ :q_puppetagent_server => master_certname,
17
29
 
18
30
  # Disable database, console, and master by default
19
31
  # This will be overridden by other blocks being merged in.
@@ -50,7 +62,7 @@ module Beaker
50
62
  }
51
63
 
52
64
  if master['ip']
53
- master_a[:q_puppetmaster_dnsaltnames]+=","+master['ip']
65
+ master_a[:q_puppetmaster_dnsaltnames]+= "," + master['ip']
54
66
  end
55
67
 
56
68
  # Common answers for console and database
@@ -170,13 +182,21 @@ module Beaker
170
182
  return answers
171
183
  end
172
184
 
185
+ # Return answer data for all hosts.
186
+ #
187
+ # @param [Array<Beaker::Host>] hosts An array of host objects.
188
+ # @param [String] master_certname Hostname of the puppet master.
189
+ # @param [Hash] options options for answer files
190
+ # @option options [Symbol] :type Should be one of :upgrade or :install.
191
+ # @return [Hash] A hash (keyed from hosts) containing hashes of answer file
192
+ # data.
173
193
  def self.answers(hosts, master_certname, options)
174
194
  the_answers = {}
175
195
  database = only_host_with_role(hosts, 'database')
176
196
  dashboard = only_host_with_role(hosts, 'dashboard')
177
197
  master = only_host_with_role(hosts, 'master')
178
198
  hosts.each do |h|
179
- if options[:type] == :upgrade and options[:from] =~ /\A3.0/
199
+ if options[:type] == :upgrade and h[:pe_ver] =~ /\A3.0/
180
200
  # 3.0.x to 3.0.x should require no answers
181
201
  the_answers[h.name] = {
182
202
  :q_install => 'y',
@@ -188,7 +208,6 @@ module Beaker
188
208
  end
189
209
  return the_answers
190
210
  end
191
-
192
211
  end
193
212
  end
194
213
  end
data/lib/beaker/cli.rb CHANGED
@@ -1,29 +1,16 @@
1
1
  module Beaker
2
2
  class CLI
3
3
  def initialize
4
- @options = Beaker::Options.parse_args
4
+ @options_parser = Beaker::Options::Parser.new
5
+ @options = @options_parser.parse_args
5
6
  @logger = Beaker::Logger.new(@options)
6
7
  @options[:logger] = @logger
7
8
 
8
- if not @options[:config]
9
- report_and_raise(@logger, RuntimeError.new("Argh! There is no default for Config, specify one (-c or --config)!"), "CLI: initialize")
9
+ if @options[:help]
10
+ @logger.notify(@options_parser.usage)
11
+ exit
10
12
  end
11
-
12
- @logger.debug("Options")
13
- @options.each do |opt, val|
14
- if val and val != []
15
- @logger.debug("\t#{opt.to_s}:")
16
- if val.kind_of?(Array)
17
- val.each do |v|
18
- @logger.debug("\t\t#{v.to_s}")
19
- end
20
- else
21
- @logger.debug("\t\t#{val.to_s}")
22
- end
23
- end
24
- end
25
-
26
- @config = Beaker::TestConfig.new(@options[:config], @options)
13
+ @logger.notify(@options.dump)
27
14
 
28
15
  #add additional paths to the LOAD_PATH
29
16
  if not @options[:load_path].empty?
@@ -34,31 +21,37 @@ module Beaker
34
21
  @options[:helper].each do |helper|
35
22
  require File.expand_path(helper)
36
23
  end
24
+ end
37
25
 
38
- @hosts = []
39
- @network_manager = Beaker::NetworkManager.new(@config, @options, @logger)
40
- @hosts = @network_manager.provision
41
- #validate that the hosts are correctly configured
42
- Beaker::Utils::Validator.validate(@hosts, @logger)
26
+ def provision
27
+ begin
28
+ @hosts = []
29
+ @network_manager = Beaker::NetworkManager.new(@options, @logger)
30
+ @hosts = @network_manager.provision
31
+ rescue => e
32
+ report_and_raise(@logger, e, "CLI.provision")
33
+ end
34
+ end
43
35
 
36
+ def validate
37
+ begin
38
+ #validation phase
39
+ Beaker::Utils::Validator.validate(@hosts, @logger)
40
+ rescue => e
41
+ report_and_raise(@logger, e, "CLI.validate")
42
+ end
44
43
  end
45
44
 
46
- def execute!
45
+ def setup
47
46
  @ntp_controller = Beaker::Utils::NTPControl.new(@options, @hosts)
48
47
  @setup = Beaker::Utils::SetupHelper.new(@options, @hosts)
49
48
  @repo_controller = Beaker::Utils::RepoControl.new(@options, @hosts)
50
-
51
49
  setup_steps = [[:timesync, "Sync time on hosts", Proc.new {@ntp_controller.timesync}],
52
50
  [:root_keys, "Sync keys to hosts" , Proc.new {@setup.sync_root_keys}],
53
51
  [:repo_proxy, "Proxy packaging repositories on ubuntu, debian and solaris-11", Proc.new {@repo_controller.proxy_config}],
54
52
  [:add_el_extras, "Add Extra Packages for Enterprise Linux (EPEL) repository to el-* hosts", Proc.new {@repo_controller.add_el_extras}],
55
53
  [:add_master_entry, "Update /etc/hosts on master with master's ip", Proc.new {@setup.add_master_entry}]]
56
-
57
54
  begin
58
- trap(:INT) do
59
- @logger.warn "Interrupt received; exiting..."
60
- exit(1)
61
- end
62
55
  #setup phase
63
56
  setup_steps.each do |step|
64
57
  if (not @options.has_key?(step[0])) or @options[step[0]]
@@ -67,21 +60,38 @@ module Beaker
67
60
  step[2].call
68
61
  end
69
62
  end
63
+ rescue => e
64
+ report_and_raise(@logger, e, "CLI.setup")
65
+ end
66
+ end
67
+
68
+ def execute!
69
+
70
+ begin
71
+ trap(:INT) do
72
+ @logger.warn "Interrupt received; exiting..."
73
+ exit(1)
74
+ end
75
+
76
+ provision
77
+ validate
78
+ setup
70
79
 
71
80
  #pre acceptance phase
72
- run_suite('pre-suite', @options.merge({:tests => @options[:pre_suite]}), :fail_fast)
81
+ run_suite(:pre_suite, :fail_fast)
82
+
73
83
  #testing phase
74
84
  begin
75
- run_suite('acceptance', @options)
85
+ run_suite(:tests)
76
86
  #post acceptance phase
77
87
  rescue => e
78
88
  #post acceptance on failure
79
89
  #if we error then run the post suite as long as we aren't in fail-stop mode
80
- run_suite('post-suite', @options.merge({:tests => @options[:post_suite]})) unless @options[:fail_mode] == "stop"
90
+ run_suite(:post_suite) unless @options[:fail_mode] == "stop"
81
91
  raise e
82
92
  else
83
93
  #post acceptance on success
84
- run_suite('post-suite', @options.merge({:tests => @options[:post_suite]}))
94
+ run_suite(:post_suite)
85
95
  end
86
96
  #cleanup phase
87
97
  rescue => e
@@ -89,23 +99,27 @@ module Beaker
89
99
  #only do cleanup if we aren't in fail-stop mode
90
100
  @logger.notify "Cleanup: cleaning up after failed run"
91
101
  if @options[:fail_mode] != "stop"
92
- @network_manager.cleanup
102
+ if @network_manager
103
+ @network_manager.cleanup
104
+ end
93
105
  end
94
106
  raise "Failed to execute tests!"
95
107
  else
96
108
  #cleanup on success
97
109
  @logger.notify "Cleanup: cleaning up after successful run"
98
- @network_manager.cleanup
110
+ if @network_manager
111
+ @network_manager.cleanup
112
+ end
99
113
  end
100
114
  end
101
115
 
102
- def run_suite(name, options, failure_strategy = false)
103
- if (options[:tests].empty?)
104
- @logger.notify("No tests to run for suite '#{name}'")
116
+ def run_suite(suite_name, failure_strategy = false)
117
+ if (@options[suite_name].empty?)
118
+ @logger.notify("No tests to run for suite '#{suite_name.to_s}'")
105
119
  return
106
120
  end
107
121
  Beaker::TestSuite.new(
108
- name, @hosts, options, @config, failure_strategy
122
+ suite_name, @hosts, @options, failure_strategy
109
123
  ).run_and_raise_on_failure
110
124
  end
111
125