beaker 3.18.0 → 3.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +8 -8
  2. data/Rakefile +0 -23
  3. data/beaker.gemspec +1 -0
  4. data/lib/beaker/dsl/helpers.rb +3 -4
  5. data/lib/beaker/dsl/install_utils.rb +2 -7
  6. data/lib/beaker/dsl/wrappers.rb +0 -87
  7. data/lib/beaker/host/unix/pkg.rb +56 -17
  8. data/lib/beaker/hypervisor/docker.rb +26 -1
  9. data/lib/beaker/options/parser.rb +12 -5
  10. data/lib/beaker/options/subcommand_options_file_parser.rb +11 -4
  11. data/lib/beaker/ssh_connection.rb +6 -6
  12. data/lib/beaker/subcommand.rb +6 -0
  13. data/lib/beaker/version.rb +1 -1
  14. data/spec/beaker/host/unix/pkg_spec.rb +130 -0
  15. data/spec/beaker/hypervisor/docker_spec.rb +28 -1
  16. data/spec/beaker/options/parser_spec.rb +38 -18
  17. data/spec/beaker/options/subcommand_options_parser_spec.rb +28 -5
  18. data/spec/beaker/ssh_connection_spec.rb +17 -17
  19. metadata +16 -28
  20. data/acceptance/config/puppetgem/acceptance-options.rb +0 -9
  21. data/acceptance/config/puppetgit/acceptance-options.rb +0 -9
  22. data/acceptance/config/puppetpkg/acceptance-options.rb +0 -8
  23. data/acceptance/pre_suite/puppet_gem/install.rb +0 -8
  24. data/acceptance/pre_suite/puppet_git/install.rb +0 -98
  25. data/acceptance/pre_suite/puppet_pkg/install.rb +0 -9
  26. data/acceptance/tests/puppet/README.md +0 -3
  27. data/acceptance/tests/puppet/install_smoke_test.rb +0 -21
  28. data/acceptance/tests/puppet/stub_host.rb +0 -47
  29. data/acceptance/tests/puppet/web_helpers_test.rb +0 -55
  30. data/acceptance/tests/puppet/with_puppet_running_on.rb +0 -26
  31. data/lib/beaker/dsl/helpers/puppet_helpers.rb +0 -865
  32. data/lib/beaker/dsl/helpers/tk_helpers.rb +0 -89
  33. data/lib/beaker/dsl/install_utils/aio_defaults.rb +0 -93
  34. data/lib/beaker/dsl/install_utils/ezbake_utils.rb +0 -256
  35. data/lib/beaker/dsl/install_utils/foss_defaults.rb +0 -211
  36. data/lib/beaker/dsl/install_utils/foss_utils.rb +0 -1307
  37. data/lib/beaker/dsl/install_utils/module_utils.rb +0 -244
  38. data/lib/beaker/dsl/install_utils/puppet_utils.rb +0 -157
  39. data/lib/beaker/options/homedir_options_file_parser.rb +0 -0
  40. data/spec/beaker/dsl/helpers/facter_helpers_spec.rb +0 -59
  41. data/spec/beaker/dsl/helpers/puppet_helpers_spec.rb +0 -1179
  42. data/spec/beaker/dsl/helpers/tk_helpers_spec.rb +0 -83
  43. data/spec/beaker/dsl/install_utils/foss_utils_spec.rb +0 -1307
  44. data/spec/beaker/dsl/install_utils/module_utils_spec.rb +0 -261
  45. data/spec/beaker/dsl/install_utils/puppet_utils_spec.rb +0 -136
@@ -1,244 +0,0 @@
1
- module Beaker
2
- module DSL
3
- module InstallUtils
4
- #
5
- # This module contains methods to help install puppet modules
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
- module ModuleUtils
15
-
16
- # The directories in the module directory that will not be scp-ed to the test system when using
17
- # `copy_module_to`
18
- PUPPET_MODULE_INSTALL_IGNORE = ['.bundle', '.git', '.idea', '.vagrant', '.vendor', 'vendor', 'acceptance',
19
- 'bundle', 'spec', 'tests', 'log', '.svn', 'junit', 'pkg', 'example']
20
-
21
- # Install the desired module on all hosts using either the PMT or a
22
- # staging forge
23
- #
24
- # @see install_dev_puppet_module
25
- def install_dev_puppet_module_on( host, opts )
26
- if options[:forge_host]
27
- with_forge_stubbed_on( host ) do
28
- install_puppet_module_via_pmt_on( host, opts )
29
- end
30
- else
31
- copy_module_to( host, opts )
32
- end
33
- end
34
- alias :puppet_module_install_on :install_dev_puppet_module_on
35
-
36
- # Install the desired module on all hosts using either the PMT or a
37
- # staging forge
38
- #
39
- # Passes options through to either `install_puppet_module_via_pmt_on`
40
- # or `copy_module_to`
41
- #
42
- # @param opts [Hash]
43
- #
44
- # @example Installing a module from the local directory
45
- # install_dev_puppet_module( :source => './', :module_name => 'concat' )
46
- #
47
- # @example Installing a module from a staging forge
48
- # options[:forge_host] = 'my-forge-api.example.com'
49
- # install_dev_puppet_module( :source => './', :module_name => 'concat' )
50
- #
51
- # @see install_puppet_module_via_pmt
52
- # @see copy_module_to
53
- def install_dev_puppet_module( opts )
54
- block_on( hosts ) {|h| install_dev_puppet_module_on( h, opts ) }
55
- end
56
- alias :puppet_module_install :install_dev_puppet_module
57
-
58
- # Install the desired module with the PMT on a given host
59
- #
60
- # @param opts [Hash]
61
- # @option opts [String] :module_name The short name of the module to be installed
62
- # @option opts [String] :version The version of the module to be installed
63
- def install_puppet_module_via_pmt_on( host, opts = {} )
64
- block_on host do |h|
65
- version_info = opts[:version] ? "-v #{opts[:version]}" : ""
66
- if opts[:source]
67
- author_name, module_name = parse_for_modulename( opts[:source] )
68
- modname = "#{author_name}-#{module_name}"
69
- else
70
- modname = opts[:module_name]
71
- end
72
-
73
- puppet_opts = {}
74
- if host[:default_module_install_opts].respond_to? :merge
75
- puppet_opts = host[:default_module_install_opts].merge( puppet_opts )
76
- end
77
-
78
- on h, puppet("module install #{modname} #{version_info}", puppet_opts)
79
- end
80
- end
81
-
82
- # Install the desired module with the PMT on all known hosts
83
- # @see #install_puppet_module_via_pmt_on
84
- def install_puppet_module_via_pmt( opts = {} )
85
- install_puppet_module_via_pmt_on(hosts, opts)
86
- end
87
-
88
- # Install local module for acceptance testing
89
- # should be used as a presuite to ensure local module is copied to the hosts you want, particularly masters
90
- # @param [Host, Array<Host>, String, Symbol] one_or_more_hosts
91
- # One or more hosts to act upon,
92
- # or a role (String or Symbol) that identifies one or more hosts.
93
- # @option opts [String] :source ('./')
94
- # The current directory where the module sits, otherwise will try
95
- # and walk the tree to figure out
96
- # @option opts [String] :module_name (nil)
97
- # Name which the module should be installed under, please do not include author,
98
- # if none is provided it will attempt to parse the metadata.json and then the Module file to determine
99
- # the name of the module
100
- # @option opts [String] :target_module_path (host['distmoduledir']/modules)
101
- # Location where the module should be installed, will default
102
- # to host['distmoduledir']/modules
103
- # @option opts [Array] :ignore_list
104
- # @option opts [String] :protocol
105
- # Name of the underlying transfer method. Valid options are 'scp' or 'rsync'.
106
- # @raise [ArgumentError] if not host is provided or module_name is not provided and can not be found in Modulefile
107
- #
108
- def copy_module_to(one_or_more_hosts, opts = {})
109
- block_on one_or_more_hosts do |host|
110
- opts = {:source => './',
111
- :target_module_path => host['distmoduledir'],
112
- :ignore_list => PUPPET_MODULE_INSTALL_IGNORE}.merge(opts)
113
-
114
- ignore_list = build_ignore_list(opts)
115
- target_module_dir = on( host, "echo #{opts[:target_module_path]}" ).stdout.chomp
116
- source_path = File.expand_path( opts[:source] )
117
- source_dir = File.dirname(source_path)
118
- source_name = File.basename(source_path)
119
- if opts.has_key?(:module_name)
120
- module_name = opts[:module_name]
121
- else
122
- _, module_name = parse_for_modulename( source_path )
123
- end
124
-
125
- target_path = File.join(target_module_dir, module_name)
126
- if host.is_powershell? #make sure our slashes are correct
127
- target_path = target_path.gsub(/\//,'\\')
128
- end
129
-
130
- opts[:protocol] ||= 'scp'
131
- case opts[:protocol]
132
- when 'scp'
133
- #move to the host
134
- logger.debug "Using scp to transfer #{source_path} to #{target_path}"
135
- scp_to host, source_path, target_module_dir, {:ignore => ignore_list}
136
-
137
- #rename to the selected module name, if not correct
138
- cur_path = File.join(target_module_dir, source_name)
139
- if host.is_powershell? #make sure our slashes are correct
140
- cur_path = cur_path.gsub(/\//,'\\')
141
- end
142
- host.mv cur_path, target_path unless cur_path == target_path
143
- when 'rsync'
144
- logger.debug "Using rsync to transfer #{source_path} to #{target_path}"
145
- rsync_to host, source_path, target_path, {:ignore => ignore_list}
146
- else
147
- logger.debug "Unsupported transfer protocol, returning nil"
148
- nil
149
- end
150
- end
151
- end
152
- alias :copy_root_module_to :copy_module_to
153
-
154
- #Recursive method for finding the module root
155
- # Assumes that a Modulefile exists
156
- # @param [String] possible_module_directory
157
- # will look for Modulefile and if none found go up one level and try again until root is reached
158
- #
159
- # @return [String,nil]
160
- def parse_for_moduleroot(possible_module_directory)
161
- if File.exists?("#{possible_module_directory}/Modulefile") || File.exists?("#{possible_module_directory}/metadata.json")
162
- possible_module_directory
163
- elsif possible_module_directory === '/'
164
- logger.error "At root, can't parse for another directory"
165
- nil
166
- else
167
- logger.debug "No Modulefile or metadata.json found at #{possible_module_directory}, moving up"
168
- parse_for_moduleroot File.expand_path(File.join(possible_module_directory,'..'))
169
- end
170
- end
171
-
172
- #Parse root directory of a module for module name
173
- # Searches for metadata.json and then if none found, Modulefile and parses for the Name attribute
174
- # @param [String] root_module_dir
175
- # @return [String] module name
176
- def parse_for_modulename(root_module_dir)
177
- author_name, module_name = nil, nil
178
- if File.exists?("#{root_module_dir}/metadata.json")
179
- logger.debug "Attempting to parse Modulename from metadata.json"
180
- module_json = JSON.parse(File.read "#{root_module_dir}/metadata.json")
181
- if(module_json.has_key?('name'))
182
- author_name, module_name = get_module_name(module_json['name'])
183
- end
184
- end
185
- if !module_name && File.exists?("#{root_module_dir}/Modulefile")
186
- logger.debug "Attempting to parse Modulename from Modulefile"
187
- if /^name\s+'?(\w+-\w+)'?\s*$/i.match(File.read("#{root_module_dir}/Modulefile"))
188
- author_name, module_name = get_module_name(Regexp.last_match[1])
189
- end
190
- end
191
- if !module_name && !author_name
192
- logger.debug "Unable to determine name, returning null"
193
- end
194
- return author_name, module_name
195
- end
196
-
197
- #Parse modulename from the pattern 'Auther-ModuleName'
198
- #
199
- # @param [String] author_module_name <Author>-<ModuleName> pattern
200
- #
201
- # @return [String,nil]
202
- #
203
- def get_module_name(author_module_name)
204
- split_name = split_author_modulename(author_module_name)
205
- if split_name
206
- return split_name[:author], split_name[:module]
207
- end
208
- end
209
-
210
- #Split the Author-Name into a hash
211
- # @param [String] author_module_attr
212
- #
213
- # @return [Hash<Symbol,String>,nil] :author and :module symbols will be returned
214
- #
215
- def split_author_modulename(author_module_attr)
216
- result = /(\w+)-(\w+)/.match(author_module_attr)
217
- if result
218
- {:author => result[1], :module => result[2]}
219
- else
220
- nil
221
- end
222
- end
223
-
224
- # Build an array list of files/directories to ignore when pushing to remote host
225
- # Automatically adds '..' and '.' to array. If not opts of :ignore list is provided
226
- # it will use the static variable PUPPET_MODULE_INSTALL_IGNORE
227
- #
228
- # @param opts [Hash]
229
- # @option opts [Array] :ignore_list A list of files/directories to ignore
230
- def build_ignore_list(opts = {})
231
- ignore_list = opts[:ignore_list] || PUPPET_MODULE_INSTALL_IGNORE
232
- if !ignore_list.kind_of?(Array) || ignore_list.nil?
233
- raise ArgumentError "Ignore list must be an Array"
234
- end
235
- ignore_list << '.' unless ignore_list.include? '.'
236
- ignore_list << '..' unless ignore_list.include? '..'
237
- ignore_list
238
- end
239
-
240
- end
241
- end
242
-
243
- end
244
- end
@@ -1,157 +0,0 @@
1
- module Beaker
2
- module DSL
3
- module InstallUtils
4
- #
5
- # This module contains methods useful for both foss and pe installs
6
- #
7
- module PuppetUtils
8
-
9
- #Given a type return an understood host type
10
- #@param [String] type The host type to be normalized
11
- #@return [String] The normalized type
12
- #
13
- #@example
14
- # normalize_type('pe-aio')
15
- # 'pe'
16
- #@example
17
- # normalize_type('git')
18
- # 'foss'
19
- #@example
20
- # normalize_type('foss-internal')
21
- # 'foss'
22
- def normalize_type type
23
- case type
24
- when /(\A|-)(git)|(foss)(\Z|-)/
25
- 'foss'
26
- when /(\A|-)pe(\Z|-)/
27
- 'pe'
28
- when /(\A|-)aio(\Z|-)/
29
- 'aio'
30
- else
31
- nil
32
- end
33
- end
34
-
35
- #Given a host construct a PATH that includes puppetbindir, facterbindir and hierabindir
36
- # @param [Host] host A single host to construct pathing for
37
- def construct_puppet_path(host)
38
- path = (%w(puppetbindir facterbindir hierabindir)).compact.reject(&:empty?)
39
- #get the PATH defaults
40
- path.map! { |val| host[val] }
41
- path = path.compact.reject(&:empty?)
42
- #run the paths through echo to see if they have any subcommands that need processing
43
- path.map! { |val| echo_on(host, val) }
44
-
45
- separator = host['pathseparator']
46
- if not host.is_powershell?
47
- separator = ':'
48
- end
49
- path.join(separator)
50
- end
51
-
52
- #Append puppetbindir, facterbindir and hierabindir to the PATH for each host
53
- # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
54
- # or a role (String or Symbol) that identifies one or more hosts.
55
- def add_puppet_paths_on(hosts)
56
- block_on hosts do | host |
57
- puppet_path = construct_puppet_path(host)
58
- host.add_env_var('PATH', puppet_path)
59
- host.add_env_var('PATH', 'PATH') # don't destroy the path!
60
- end
61
- end
62
-
63
- #Remove puppetbindir, facterbindir and hierabindir to the PATH for each host
64
- #
65
- # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
66
- # or a role (String or Symbol) that identifies one or more hosts.
67
- def remove_puppet_paths_on(hosts)
68
- block_on hosts do | host |
69
- puppet_path = construct_puppet_path(host)
70
- host.delete_env_var('PATH', puppet_path)
71
- host.add_env_var('PATH', 'PATH') # don't destroy the path!
72
- end
73
- end
74
-
75
- #Configure the provided hosts to be of the provided type (one of foss, aio, pe), if the host
76
- #is already associated with a type then remove the previous settings for that type
77
- # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
78
- # or a role (String or Symbol) that identifies one or more hosts.
79
- # @param [String] type One of 'aio', 'pe' or 'foss'
80
- def configure_defaults_on( hosts, type )
81
- block_on hosts do |host|
82
-
83
- # check to see if the host already has a type associated with it
84
- remove_defaults_on(host)
85
-
86
- add_method = "add_#{type}_defaults_on"
87
- if self.respond_to?(add_method, host)
88
- self.send(add_method, host)
89
- else
90
- raise "cannot add defaults of type #{type} for host #{host.name} (#{add_method} not present)"
91
- end
92
- # add pathing env
93
- add_puppet_paths_on(host)
94
- end
95
- end
96
-
97
- # Configure the provided hosts to be of their host[:type], it host[type] == nil do nothing
98
- def configure_type_defaults_on( hosts )
99
- block_on hosts do |host|
100
- has_defaults = false
101
- if host[:type]
102
- host_type = host[:type]
103
- # clean up the naming conventions here (some teams use foss-package, git-whatever, we need
104
- # to correctly handle that
105
- # don't worry about aio, that happens in the aio_version? check
106
- host_type = normalize_type(host_type)
107
- if host_type and host_type !~ /aio/
108
- add_method = "add_#{host_type}_defaults_on"
109
- if self.respond_to?(add_method, host)
110
- self.send(add_method, host)
111
- else
112
- raise "cannot add defaults of type #{host_type} for host #{host.name} (#{add_method} not present)"
113
- end
114
- has_defaults = true
115
- end
116
- end
117
- if aio_version?(host)
118
- add_aio_defaults_on(host)
119
- has_defaults = true
120
- end
121
- # add pathing env
122
- if has_defaults
123
- add_puppet_paths_on(host)
124
- end
125
- end
126
- end
127
- alias_method :configure_foss_defaults_on, :configure_type_defaults_on
128
- alias_method :configure_pe_defaults_on, :configure_type_defaults_on
129
-
130
- #If the host is associated with a type remove all defaults and environment associated with that type.
131
- # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
132
- # or a role (String or Symbol) that identifies one or more hosts.
133
- def remove_defaults_on( hosts )
134
- block_on hosts do |host|
135
- if host['type']
136
- # clean up the naming conventions here (some teams use foss-package, git-whatever, we need
137
- # to correctly handle that
138
- # don't worry about aio, that happens in the aio_version? check
139
- host_type = normalize_type(host['type'])
140
- remove_puppet_paths_on(hosts)
141
- remove_method = "remove_#{host_type}_defaults_on"
142
- if self.respond_to?(remove_method, host)
143
- self.send(remove_method, host)
144
- else
145
- raise "cannot remove defaults of type #{host_type} associated with host #{host.name} (#{remove_method} not present)"
146
- end
147
- if aio_version?(host)
148
- remove_aio_defaults_on(host)
149
- end
150
- end
151
- end
152
- end
153
-
154
- end
155
- end
156
- end
157
- end
@@ -1,59 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class ClassMixedWithDSLHelpers
4
- include Beaker::DSL::Helpers
5
- include Beaker::DSL::Wrappers
6
- include Beaker::DSL::Roles
7
- include Beaker::DSL::Patterns
8
-
9
- def logger
10
- RSpec::Mocks::Double.new('logger').as_null_object
11
- end
12
-
13
- end
14
-
15
- describe ClassMixedWithDSLHelpers do
16
- let( :command ){ 'ls' }
17
- let( :host ) { double.as_null_object }
18
- let( :result ) { Beaker::Result.new( host, command ) }
19
-
20
- let( :master ) { make_host( 'master', :roles => %w( master agent default) ) }
21
- let( :agent ) { make_host( 'agent', :roles => %w( agent ) ) }
22
- let( :custom ) { make_host( 'custom', :roles => %w( custom agent ) ) }
23
- let( :dash ) { make_host( 'console', :roles => %w( dashboard agent ) ) }
24
- let( :db ) { make_host( 'db', :roles => %w( database agent ) ) }
25
- let( :hosts ) { [ master, agent, dash, db, custom ] }
26
-
27
-
28
- describe '#fact_on' do
29
- it 'retrieves a fact on a single host' do
30
- result.stdout = "family\n"
31
- expect( subject ).to receive(:facter).with('osfamily',{}).once
32
- expect( subject ).to receive(:on).and_return(result)
33
-
34
- expect( subject.fact_on('host','osfamily') ).to be === result.stdout.chomp
35
- end
36
-
37
- it 'retrieves an array of facts from multiple hosts' do
38
- allow( subject ).to receive( :hosts ).and_return( hosts )
39
- times = hosts.length
40
- result.stdout = "family\n"
41
- hosts.each do |host|
42
- expect( host ).to receive(:exec).and_return(result)
43
- end
44
-
45
- expect( subject.fact_on(hosts,'osfamily') ).to be === [result.stdout.chomp] * hosts.length
46
-
47
- end
48
- end
49
-
50
- describe '#fact' do
51
- it 'delegates to #fact_on with the default host' do
52
- allow( subject ).to receive(:hosts).and_return(hosts)
53
- expect( subject ).to receive(:fact_on).with(master,"osfamily",{}).once
54
-
55
- subject.fact('osfamily')
56
- end
57
- end
58
-
59
- end