Module: Beaker::DSL::Helpers
- Included in:
- Beaker::DSL
- Defined in:
- lib/beaker/dsl/helpers.rb
Overview
This is the heart of the Puppet Acceptance DSL. Here you find a helper to proxy commands to hosts, more commands to move files between hosts and execute remote scripts, confine test cases to certain hosts and prepare the state of a test case.
To mix this is into a class you need the following:
-
a method hosts that yields any hosts implementing Host‘s interface to act upon.
-
a method options that provides an options hash, see Options::OptionsHash
-
a method logger that yields a logger implementing Logger‘s interface.
-
the module Roles that provides access to the various hosts implementing Host‘s interface to act upon
-
the module Wrappers the provides convenience methods for Command creation
Instance Method Summary collapse
-
#apply_manifest(manifest, opts = {}, &block) ⇒ Object
Runs ‘puppet apply’ on default host, piping manifest through stdin.
-
#apply_manifest_on(host, manifest, opts = {}, &block) ⇒ Object
Runs ‘puppet apply’ on a remote host, piping manifest through stdin.
-
#confine(type, criteria, host_array = nil, &block) ⇒ Array<Host>
Limit the hosts a test case is run against.
-
#confine_block(type, criteria, host_array = nil, &block) ⇒ Object
Ensures that host restrictions as specifid by type, criteria and host_array are confined to activity within the passed block.
-
#copy_hiera_data(source) ⇒ Object
Copy hiera data files to the default host.
-
#copy_hiera_data_to(host, source) ⇒ Object
Copy hiera data files to one or more provided hosts.
-
#create_remote_file(hosts, file_path, file_content, opts = {}) ⇒ Result
Create a remote file out of a string.
-
#create_tmpdir_for_user(host, name = '/tmp/beaker', user = nil) ⇒ String
Create a temp directory on remote host owned by specified user.
-
#curl_on(host, cmd, opts = {}, &block) ⇒ Object
Run a curl command on the provided host(s).
- #curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1) ⇒ Object
-
#deploy_package_repo(host, path, name, version) ⇒ Object
Deploy packaging configurations generated by github.com/puppetlabs/packaging to a host.
- #exit_code ⇒ Object deprecated Deprecated.
-
#fact(name, opts = {}) ⇒ Object
Get a facter fact from the default host.
-
#fact_on(host, name, opts = {}) ⇒ Object
Get a facter fact from a provided host.
-
#hiera_datadir(host) ⇒ String
Get file path to the hieradatadir for a given host.
-
#modify_tk_config(host, config_file_path, options_hash, replace = false) ⇒ Object
Modify the given TrapperKeeper config file.
-
#on(host, command, opts = {}, &block) ⇒ Result
The primary method for executing commands on some set of hosts.
-
#port_open_within?(host, port = 8140, seconds = 120) ⇒ Boolean
Blocks until the port is open on the host specified, returns false on failure.
-
#puppet_group(host) ⇒ Object
Return the name of the puppet group.
-
#puppet_user(host) ⇒ Object
Return the name of the puppet user.
-
#retry_on(host, command, opts = {}, &block) ⇒ Object
This command will execute repeatedly until success or it runs out with an error.
-
#rsync_to(host, from_path, to_path, opts = {}) ⇒ Result
Move a local file or directory to a remote host using rsync.
- #run_agent_on(host, arg = '--no-daemonize --verbose --onetime --test', options = {}, &block) ⇒ Object deprecated Deprecated.
-
#run_script(script, opts = {}, &block) ⇒ Object
Move a local script to default host and execute it.
-
#run_script_on(host, script, opts = {}, &block) ⇒ Result
Move a local script to a remote host and execute it.
-
#scp_from(host, from_path, to_path, opts = {}) ⇒ Result
Move a file from a remote to a local path.
-
#scp_to(host, from_path, to_path, opts = {}) ⇒ Result
Move a local file to a remote host using scp.
-
#select_hosts(criteria, host_array = nil, &block) ⇒ Array<Host>
Return a set of hosts that meet the given criteria.
-
#shell(command, opts = {}, &block) ⇒ Result
The method for executing commands on the default host.
-
#sign_certificate ⇒ Object
prompt the master to sign certs then check to confirm the cert for the default host is signed.
-
#sign_certificate_for(host) ⇒ Object
Ensure the host has requested a cert, then sign it.
- #sleep_until_nc_started(host) ⇒ Object
- #sleep_until_puppetdb_started(host) ⇒ Object
- #sleep_until_puppetserver_started(host) ⇒ Object
- #stderr ⇒ Object deprecated Deprecated.
- #stdout ⇒ Object deprecated Deprecated.
-
#stop_agent ⇒ Object
stops the puppet agent running on the default host.
-
#stop_agent_on(agent) ⇒ Object
stops the puppet agent running on the host.
-
#stub_forge(forge_host = nil) ⇒ Object
This wraps the method ‘stub_hosts` and makes the stub specific to the forge alias.
-
#stub_forge_on(machine, forge_host = nil) ⇒ Object
This wraps the method ‘stub_hosts_on` and makes the stub specific to the forge alias.
-
#stub_hosts(ip_spec) ⇒ Object
This method accepts a block and using the puppet resource ‘host’ will setup host aliases before and after that block on the default host.
-
#stub_hosts_on(machine, ip_spec) ⇒ Object
This method using the puppet resource ‘host’ will setup host aliases and register the remove of host aliases via Beaker::TestCase#teardown.
-
#version_is_less(a, b) ⇒ Boolean
Is semver-ish version a less than semver-ish version b.
-
#wait_for_host_in_dashboard(host) ⇒ Object
wait for a given host to appear in the dashboard.
-
#with_forge_stubbed(forge_host = nil, &block) ⇒ Object
This wraps ‘with_forge_stubbed_on` and provides it the default host.
-
#with_forge_stubbed_on(host, forge_host = nil, &block) ⇒ Object
This wraps the method ‘with_host_stubbed_on` and makes the stub specific to the forge alias.
-
#with_host_stubbed_on(host, ip_spec, &block) ⇒ Object
This method accepts a block and using the puppet resource ‘host’ will setup host aliases before and after that block.
-
#with_puppet_running(conf_opts, testdir = host.tmpdir(File.basename(@path)), &block) ⇒ Object
Test Puppet running in a certain run mode with specific options, on the default host.
-
#with_puppet_running_on(host, conf_opts, testdir = host.tmpdir(File.basename(@path)), &block) ⇒ Object
Test Puppet running in a certain run mode with specific options.
-
#write_hiera_config(hierarchy) ⇒ Object
Write hiera config file for the default host.
-
#write_hiera_config_on(host, hierarchy) ⇒ Object
Write hiera config file on one or more provided hosts.
Instance Method Details
#apply_manifest(manifest, opts = {}, &block) ⇒ Object
Runs ‘puppet apply’ on default host, piping manifest through stdin
993 994 995 |
# File 'lib/beaker/dsl/helpers.rb', line 993 def apply_manifest(manifest, opts = {}, &block) apply_manifest_on(default, manifest, opts, &block) end |
#apply_manifest_on(host, manifest, opts = {}, &block) ⇒ Object
Runs ‘puppet apply’ on a remote host, piping manifest through stdin
915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 |
# File 'lib/beaker/dsl/helpers.rb', line 915 def apply_manifest_on(host, manifest, opts = {}, &block) block_on host do | host | = {} [:acceptable_exit_codes] = Array(opts[:acceptable_exit_codes]) puppet_apply_opts = {} if opts[:debug] puppet_apply_opts[:debug] = nil else puppet_apply_opts[:verbose] = nil end puppet_apply_opts[:parseonly] = nil if opts[:parseonly] puppet_apply_opts[:trace] = nil if opts[:trace] puppet_apply_opts[:parser] = 'future' if opts[:future_parser] puppet_apply_opts[:modulepath] = opts[:modulepath] if opts[:modulepath] puppet_apply_opts[:noop] = nil if opts[:noop] # From puppet help: # "... an exit code of '2' means there were changes, an exit code of # '4' means there were failures during the transaction, and an exit # code of '6' means there were both changes and failures." if [opts[:catch_changes],opts[:catch_failures],opts[:expect_failures],opts[:expect_changes]].compact.length > 1 raise(ArgumentError, 'Cannot specify more than one of `catch_failures`, ' + '`catch_changes`, `expect_failures`, or `expect_changes` ' + 'for a single manifest') end if opts[:catch_changes] puppet_apply_opts['detailed-exitcodes'] = nil # We're after idempotency so allow exit code 0 only. [:acceptable_exit_codes] |= [0] elsif opts[:catch_failures] puppet_apply_opts['detailed-exitcodes'] = nil # We're after only complete success so allow exit codes 0 and 2 only. [:acceptable_exit_codes] |= [0, 2] elsif opts[:expect_failures] puppet_apply_opts['detailed-exitcodes'] = nil # We're after failures specifically so allow exit codes 1, 4, and 6 only. [:acceptable_exit_codes] |= [1, 4, 6] elsif opts[:expect_changes] puppet_apply_opts['detailed-exitcodes'] = nil # We're after changes specifically so allow exit code 2 only. [:acceptable_exit_codes] |= [2] else # Either use the provided acceptable_exit_codes or default to [0] [:acceptable_exit_codes] |= [0] end # Not really thrilled with this implementation, might want to improve it # later. Basically, there is a magic trick in the constructor of # PuppetCommand which allows you to pass in a Hash for the last value in # the *args Array; if you do so, it will be treated specially. So, here # we check to see if our caller passed us a hash of environment variables # that they want to set for the puppet command. If so, we set the final # value of *args to a new hash with just one entry (the value of which # is our environment variables hash) if opts.has_key?(:environment) puppet_apply_opts['ENV'] = opts[:environment] end file_path = host.tmpfile('apply_manifest.pp') create_remote_file(host, file_path, manifest + "\n") if host[:default_apply_opts].respond_to? :merge puppet_apply_opts = host[:default_apply_opts].merge( puppet_apply_opts ) end on host, puppet('apply', file_path, puppet_apply_opts), , &block end end |
#confine(type, criteria, host_array = nil, &block) ⇒ Array<Host>
This will modify the TestCase#hosts member in place unless an array of hosts is passed into it and TestCase#logger yielding an object that responds like Logger#warn, as well as Outcomes#skip_test, and optionally TestCase#hosts.
Limit the hosts a test case is run against
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'lib/beaker/dsl/helpers.rb', line 391 def confine(type, criteria, host_array = nil, &block) hosts_to_modify = host_array || hosts case type when :except hosts_to_modify = hosts_to_modify - select_hosts(criteria, hosts_to_modify, &block) when :to hosts_to_modify = select_hosts(criteria, hosts_to_modify, &block) else raise "Unknown option #{type}" end if hosts_to_modify.empty? logger.warn "No suitable hosts with: #{criteria.inspect}" skip_test 'No suitable hosts found' end self.hosts = hosts_to_modify hosts_to_modify end |
#confine_block(type, criteria, host_array = nil, &block) ⇒ Object
Ensures that host restrictions as specifid by type, criteria and host_array are confined to activity within the passed block. TestCase#hosts is reset after block has executed.
414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/beaker/dsl/helpers.rb', line 414 def confine_block(type, criteria, host_array = nil, &block) begin original_hosts = self.hosts.dup confine(type, criteria, host_array) yield ensure self.hosts = original_hosts end end |
#copy_hiera_data(source) ⇒ Object
Copy hiera data files to the default host
1432 1433 1434 |
# File 'lib/beaker/dsl/helpers.rb', line 1432 def copy_hiera_data(source) copy_hiera_data_to(default, source) end |
#copy_hiera_data_to(host, source) ⇒ Object
Copy hiera data files to one or more provided hosts
@param[Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
or a role (String or Symbol) that identifies one or more hosts.
@param Directory containing the hiera data files.
1426 1427 1428 |
# File 'lib/beaker/dsl/helpers.rb', line 1426 def copy_hiera_data_to(host, source) scp_to host, File.(source), hiera_datadir(host) end |
#create_remote_file(hosts, file_path, file_content, opts = {}) ⇒ Result
This method uses Tempfile in Ruby’s STDLIB as well as #scp_to.
Create a remote file out of a string
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/beaker/dsl/helpers.rb', line 266 def create_remote_file(hosts, file_path, file_content, opts = {}) Tempfile.open 'beaker' do |tempfile| File.open(tempfile.path, 'w') {|file| file.puts file_content } opts[:protocol] ||= 'scp' case opts[:protocol] when 'scp' scp_to hosts, tempfile.path, file_path, opts when 'rsync' rsync_to hosts, tempfile.path, file_path, opts else logger.debug "Unsupported transfer protocol, returning nil" nil end end end |
#create_tmpdir_for_user(host, name = '/tmp/beaker', user = nil) ⇒ String
Create a temp directory on remote host owned by specified user.
the ownership of a temp directory. directory. Default value is ‘/tmp/beaker’ directory. If no username is specified, use ‘puppet master –configprint user` to obtain username from master. Raise RuntimeError if this puppet command returns a non-zero exit code.
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/beaker/dsl/helpers.rb', line 295 def create_tmpdir_for_user(host, name='/tmp/beaker', user=nil) if not user result = on host, puppet("master --configprint user") if not result.exit_code == 0 raise "`puppet master --configprint` failed, check that puppet is installed on #{host} or explicitly pass in a user name." end user = result.stdout.strip end if not on(host, "getent passwd #{user}").exit_code == 0 raise "User #{user} does not exist on #{host}." end if defined? host.tmpdir dir = host.tmpdir(name) on host, "chown #{user}:#{user} #{dir}" return dir else raise "Host platform not supported by `create_tmpdir_for_user`." end end |
#curl_on(host, cmd, opts = {}, &block) ⇒ Object
Run a curl command on the provided host(s)
1389 1390 1391 1392 1393 1394 1395 |
# File 'lib/beaker/dsl/helpers.rb', line 1389 def curl_on(host, cmd, opts = {}, &block) if .is_pe? #check global options hash on host, "curl --tlsv1 %s" % cmd, opts, &block else on host, "curl %s" % cmd, opts, &block end end |
#curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1) ⇒ Object
1178 1179 1180 1181 1182 1183 1184 1185 |
# File 'lib/beaker/dsl/helpers.rb', line 1178 def curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1) opts = { :desired_exit_codes => desired_exit_codes, :max_retries => max_retries, :retry_interval => retry_interval } retry_on(host, "curl -m 1 #{url}", opts) end |
#deploy_package_repo(host, path, name, version) ⇒ Object
To ensure the repo configs are available for deployment, you should run ‘rake pl:jenkins:deb_repo_configs` and `rake pl:jenkins:rpm_repo_configs` on your project checkout
Deploy packaging configurations generated by github.com/puppetlabs/packaging to a host.
249 250 251 |
# File 'lib/beaker/dsl/helpers.rb', line 249 def deploy_package_repo host, path, name, version host.deploy_package_repo path, name, version end |
#exit_code ⇒ Object
An proxy for the last Result#exit_code returned by a method that makes remote calls. Use the Result object returned by the method directly instead. For Usage see Result.
160 161 162 163 |
# File 'lib/beaker/dsl/helpers.rb', line 160 def exit_code return nil if @result.nil? @result.exit_code end |
#fact(name, opts = {}) ⇒ Object
Get a facter fact from the default host
1377 1378 1379 |
# File 'lib/beaker/dsl/helpers.rb', line 1377 def fact(name, opts = {}) fact_on(default, name, opts) end |
#fact_on(host, name, opts = {}) ⇒ Object
Get a facter fact from a provided host
1366 1367 1368 1369 1370 1371 1372 1373 |
# File 'lib/beaker/dsl/helpers.rb', line 1366 def fact_on(host, name, opts = {}) result = on host, facter(name, opts) if result.kind_of?(Array) result.map { |res| res.stdout.chomp } else result.stdout.chomp end end |
#hiera_datadir(host) ⇒ String
Get file path to the hieradatadir for a given host. Handles whether or not a host is AIO-based & backwards compatibility
@param host Host you want to use the hieradatadir from
1442 1443 1444 |
# File 'lib/beaker/dsl/helpers.rb', line 1442 def hiera_datadir(host) host[:type] =~ /aio/ ? File.join(host.puppet['codedir'], 'hieradata') : host[:hieradatadir] end |
#modify_tk_config(host, config_file_path, options_hash, replace = false) ⇒ Object
TrapperKeeper config files can be HOCON, JSON, or Ini. We don’t
Modify the given TrapperKeeper config file.
particularly care which of these the file named by ‘config_file_path` on the SUT actually is, just that the contents can be parsed into a map.
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 |
# File 'lib/beaker/dsl/helpers.rb', line 767 def modify_tk_config(host, config_file_path, , replace=false) if .empty? return nil end new_hash = Beaker::Options::OptionsHash.new if replace new_hash.merge!() else if not host.file_exist?( config_file_path ) raise "Error: #{config_file_path} does not exist on #{host}" end file_string = host.exec( Command.new( "cat #{config_file_path}" )).stdout begin tk_conf_hash = read_tk_config_string(file_string) rescue RuntimeError raise "Error reading trapperkeeper config: #{config_file_path} at host: #{host}" end new_hash.merge!(tk_conf_hash) new_hash.merge!() end file_string = JSON.dump(new_hash) create_remote_file host, config_file_path, file_string end |
#on(host, command, opts = {}, &block) ⇒ Result
The primary method for executing commands on some set of hosts.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/beaker/dsl/helpers.rb', line 77 def on(host, command, opts = {}, &block) block_on host do | host | cur_command = command if command.is_a? Command cur_command = command.cmd_line(host) end cmd_opts = {} #add any additional environment variables to the command if opts[:environment] cmd_opts['ENV'] = opts[:environment] end @result = host.exec(Command.new(cur_command.to_s, [], cmd_opts), opts) # Also, let additional checking be performed by the caller. if block_given? case block.arity #block with arity of 0, just hand back yourself when 0 yield self #block with arity of 1 or greater, hand back the result object else yield @result end end @result end end |
#port_open_within?(host, port = 8140, seconds = 120) ⇒ Boolean
Blocks until the port is open on the host specified, returns false on failure
839 840 841 842 843 |
# File 'lib/beaker/dsl/helpers.rb', line 839 def port_open_within?( host, port = 8140, seconds = 120 ) repeat_for( seconds ) do host.port_open?( port ) end end |
#puppet_group(host) ⇒ Object
This method assumes puppet is installed on the host.
Return the name of the puppet group.
475 476 477 |
# File 'lib/beaker/dsl/helpers.rb', line 475 def puppet_group(host) return host.puppet('master')['group'] end |
#puppet_user(host) ⇒ Object
This method assumes puppet is installed on the host.
Return the name of the puppet user.
465 466 467 |
# File 'lib/beaker/dsl/helpers.rb', line 465 def puppet_user(host) return host.puppet('master')['user'] end |
#retry_on(host, command, opts = {}, &block) ⇒ Object
This command will execute repeatedly until success or it runs out with an error
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 |
# File 'lib/beaker/dsl/helpers.rb', line 1204 def retry_on(host, command, opts = {}, &block) option_exit_codes = opts[:desired_exit_codes] option_max_retries = opts[:max_retries].to_i option_retry_interval = opts[:retry_interval].to_f desired_exit_codes = option_exit_codes ? [option_exit_codes].flatten : [0] desired_exit_codes = [0] if desired_exit_codes.empty? max_retries = option_max_retries == 0 ? 60 : option_max_retries # nil & "" both return 0 retry_interval = option_retry_interval == 0 ? 1 : option_retry_interval verbose = true.to_s == opts[:verbose] log_prefix = host.log_prefix logger.debug "\n#{log_prefix} #{Time.new.strftime('%H:%M:%S')}$ #{command}" logger.debug " Trying command #{max_retries} times." logger.debug ".", add_newline=false result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}, &block num_retries = 0 until desired_exit_codes.include?(result.exit_code) sleep retry_interval result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}, &block num_retries += 1 logger.debug ".", add_newline=false if (num_retries > max_retries) logger.debug " Command \`#{command}\` failed." fail("Command \`#{command}\` failed.") end end logger.debug "\n#{log_prefix} #{Time.new.strftime('%H:%M:%S')}$ #{command} ostensibly successful." result end |
#rsync_to(host, from_path, to_path, opts = {}) ⇒ Result
rsync is required on the local host.
Move a local file or directory to a remote host using rsync
223 224 225 226 227 228 229 230 231 232 |
# File 'lib/beaker/dsl/helpers.rb', line 223 def rsync_to host, from_path, to_path, opts = {} block_on host do | host | if host['platform'] =~ /windows/ && to_path.match('`cygpath') result = host.echo "#{to_path}" to_path = result.raw_output.chomp end @result = host.do_rsync_to(from_path, to_path, opts) @result end end |
#run_agent_on(host, arg = '--no-daemonize --verbose --onetime --test', options = {}, &block) ⇒ Object
998 999 1000 1001 1002 1003 |
# File 'lib/beaker/dsl/helpers.rb', line 998 def run_agent_on(host, arg='--no-daemonize --verbose --onetime --test', ={}, &block) block_on host do | host | on host, puppet_agent(arg), , &block end end |
#run_script(script, opts = {}, &block) ⇒ Object
Move a local script to default host and execute it
343 344 345 |
# File 'lib/beaker/dsl/helpers.rb', line 343 def run_script(script, opts = {}, &block) run_script_on(default, script, opts, &block) end |
#run_script_on(host, script, opts = {}, &block) ⇒ Result
328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/beaker/dsl/helpers.rb', line 328 def run_script_on(host, script, opts = {}, &block) # this is unsafe as it uses the File::SEPARATOR will be set to that # of the coordinator node. This works for us because we use cygwin # which will properly convert the paths. Otherwise this would not # work for running tests on a windows machine when the coordinator # that the harness is running on is *nix. We should use # {Beaker::Host#temp_path} instead. TODO remote_path = File.join("", "tmp", File.basename(script)) scp_to host, script, remote_path on host, remote_path, opts, &block end |
#scp_from(host, from_path, to_path, opts = {}) ⇒ Result
If using Host for the hosts scp is not required on the system as it uses Ruby’s net/scp library. The net-scp gem however is required (and specified in the gemspec).
Move a file from a remote to a local path
178 179 180 181 182 183 184 |
# File 'lib/beaker/dsl/helpers.rb', line 178 def scp_from host, from_path, to_path, opts = {} block_on host do | host | @result = host.do_scp_from(from_path, to_path, opts) @result.log logger @result end end |
#scp_to(host, from_path, to_path, opts = {}) ⇒ Result
If using Host for the hosts scp is not required on the system as it uses Ruby’s net/scp library. The net-scp gem however is required (and specified in the gemspec. When using SCP with Windows it will now auto expand path when using ‘cygpath instead of failing or requiring full path
Move a local file to a remote host using scp
201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/beaker/dsl/helpers.rb', line 201 def scp_to host, from_path, to_path, opts = {} block_on host do | host | if host['platform'] =~ /windows/ && to_path.match('`cygpath') result = on host, "echo #{to_path}" to_path = result.raw_output.chomp end @result = host.do_scp_to(from_path, to_path, opts) @result.log logger @result end end |
#select_hosts(criteria, host_array = nil, &block) ⇒ Array<Host>
Return a set of hosts that meet the given criteria
444 445 446 447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/beaker/dsl/helpers.rb', line 444 def select_hosts(criteria, host_array = nil, &block) hosts_to_select_from = host_array || hosts criteria.each_pair do |property, value| hosts_to_select_from = hosts_to_select_from.select do |host| inspect_host host, property, value end end if block_given? hosts_to_select_from = hosts_to_select_from.select do |host| yield host end end hosts_to_select_from end |
#shell(command, opts = {}, &block) ⇒ Result
The method for executing commands on the default host
131 132 133 |
# File 'lib/beaker/dsl/helpers.rb', line 131 def shell(command, opts = {}, &block) on(default, command, opts, &block) end |
#sign_certificate ⇒ Object
prompt the master to sign certs then check to confirm the cert for the default host is signed
1353 1354 1355 |
# File 'lib/beaker/dsl/helpers.rb', line 1353 def sign_certificate sign_certificate_for(default) end |
#sign_certificate_for(host) ⇒ Object
Ensure the host has requested a cert, then sign it
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 |
# File 'lib/beaker/dsl/helpers.rb', line 1325 def sign_certificate_for(host) block_on host do | host | if [master, dashboard, database].include? host on host, puppet( 'agent -t' ), :acceptable_exit_codes => [0,1,2] on master, puppet( "cert --allow-dns-alt-names sign #{host}" ), :acceptable_exit_codes => [0,24] else hostname = Regexp.escape host.node_name last_sleep = 0 next_sleep = 1 (0..10).each do |i| fail_test("Failed to sign cert for #{hostname}") if i == 10 on master, puppet("cert --sign --all --allow-dns-alt-names"), :acceptable_exit_codes => [0,24] break if on(master, puppet("cert --list --all")).stdout =~ /\+ "?#{hostname}"?/ sleep next_sleep (last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep end end end end |
#sleep_until_nc_started(host) ⇒ Object
1173 1174 1175 1176 |
# File 'lib/beaker/dsl/helpers.rb', line 1173 def sleep_until_nc_started(host) curl_with_retries("start nodeclassifier (ssl)", host, "https://#{host.node_name}:4433", [35, 60]) end |
#sleep_until_puppetdb_started(host) ⇒ Object
1162 1163 1164 1165 1166 |
# File 'lib/beaker/dsl/helpers.rb', line 1162 def sleep_until_puppetdb_started(host) curl_with_retries("start puppetdb", host, "http://localhost:8080", 0, 120) curl_with_retries("start puppetdb (ssl)", host, "https://#{host.node_name}:8081", [35, 60]) end |
#sleep_until_puppetserver_started(host) ⇒ Object
1168 1169 1170 1171 |
# File 'lib/beaker/dsl/helpers.rb', line 1168 def sleep_until_puppetserver_started(host) curl_with_retries("start puppetserver (ssl)", host, "https://#{host.node_name}:8140", [35, 60]) end |
#stderr ⇒ Object
An proxy for the last Result#stderr returned by a method that makes remote calls. Use the Result object returned by the method directly instead. For Usage see Result.
150 151 152 153 |
# File 'lib/beaker/dsl/helpers.rb', line 150 def stderr return nil if @result.nil? @result.stderr end |
#stdout ⇒ Object
An proxy for the last Result#stdout returned by a method that makes remote calls. Use the Result object returned by the method directly instead. For Usage see Result.
140 141 142 143 |
# File 'lib/beaker/dsl/helpers.rb', line 140 def stdout return nil if @result.nil? @result.stdout end |
#stop_agent ⇒ Object
stops the puppet agent running on the default host
1307 1308 1309 |
# File 'lib/beaker/dsl/helpers.rb', line 1307 def stop_agent stop_agent_on(default) end |
#stop_agent_on(agent) ⇒ Object
stops the puppet agent running on the host
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 |
# File 'lib/beaker/dsl/helpers.rb', line 1272 def stop_agent_on(agent) block_on agent do | host | vardir = agent.puppet['vardir'] agent_running = true while agent_running agent_running = agent.file_exist?("#{vardir}/state/agent_catalog_run.lock") if agent_running sleep 2 end end # The agent service is `pe-puppet` everywhere EXCEPT certain linux distros on PE 2.8 # In all the case that it is different, this init script will exist. So we can assume # that if the script doesn't exist, we should just use `pe-puppet` agent_service = 'pe-puppet-agent' agent_service = 'pe-puppet' unless agent.file_exist?('/etc/init.d/pe-puppet-agent') # Under a number of stupid circumstances, we can't stop the # agent using puppet. This is usually because of issues with # the init script or system on that particular configuration. avoid_puppet_at_all_costs = false avoid_puppet_at_all_costs ||= agent['platform'] =~ /el-4/ avoid_puppet_at_all_costs ||= agent['pe_ver'] && version_is_less(agent['pe_ver'], '3.2') && agent['platform'] =~ /sles/ if avoid_puppet_at_all_costs # When upgrading, puppet is already stopped. On EL4, this causes an exit code of '1' on agent, "/etc/init.d/#{agent_service} stop", :acceptable_exit_codes => [0, 1] else on agent, puppet_resource('service', agent_service, 'ensure=stopped') end end end |
#stub_forge(forge_host = nil) ⇒ Object
This wraps the method ‘stub_hosts` and makes the stub specific to the forge alias.
1156 1157 1158 1159 1160 |
# File 'lib/beaker/dsl/helpers.rb', line 1156 def stub_forge(forge_host = nil) #use global options hash forge_host ||= [:forge_host] stub_forge_on(default, forge_host) end |
#stub_forge_on(machine, forge_host = nil) ⇒ Object
This wraps the method ‘stub_hosts_on` and makes the stub specific to the forge alias.
forge api v1 canonical source is forge.puppetlabs.com forge api v3 canonical source is forgeapi.puppetlabs.com
1117 1118 1119 1120 1121 1122 1123 1124 1125 |
# File 'lib/beaker/dsl/helpers.rb', line 1117 def stub_forge_on(machine, forge_host = nil) #use global options hash forge_host ||= [:forge_host] @forge_ip ||= Resolv.getaddress(forge_host) block_on machine do | host | stub_hosts_on(host, 'forge.puppetlabs.com' => @forge_ip) stub_hosts_on(host, 'forgeapi.puppetlabs.com' => @forge_ip) end end |
#stub_hosts(ip_spec) ⇒ Object
This method accepts a block and using the puppet resource ‘host’ will setup host aliases before and after that block on the default host
1104 1105 1106 |
# File 'lib/beaker/dsl/helpers.rb', line 1104 def stub_hosts(ip_spec) stub_hosts_on(default, ip_spec) end |
#stub_hosts_on(machine, ip_spec) ⇒ Object
This method using the puppet resource ‘host’ will setup host aliases and register the remove of host aliases via Beaker::TestCase#teardown
A teardown step is also added to make sure unstubbing of the host is removed always.
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 |
# File 'lib/beaker/dsl/helpers.rb', line 1052 def stub_hosts_on(machine, ip_spec) block_on machine do | host | ip_spec.each do |address, ip| logger.notify("Stubbing address #{address} to IP #{ip} on machine #{host}") on( host, puppet('resource', 'host', address, 'ensure=present', "ip=#{ip}") ) end teardown do ip_spec.each do |address, ip| logger.notify("Unstubbing address #{address} to IP #{ip} on machine #{host}") on( host, puppet('resource', 'host', address, 'ensure=absent') ) end end end end |
#version_is_less(a, b) ⇒ Boolean
3.0.0-160-gac44cfb is greater than 3.0.0, and 2.8.2
-rc being less than final builds is not yet implemented.
Is semver-ish version a less than semver-ish version b
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 |
# File 'lib/beaker/dsl/helpers.rb', line 1242 def version_is_less a, b a_nums = a.split('-')[0].split('.') b_nums = b.split('-')[0].split('.') (0...a_nums.length).each do |i| if i < b_nums.length if a_nums[i] < b_nums[i] return true elsif a_nums[i] > b_nums[i] return false end else return false end end #checks all dots, they are equal so examine the rest a_rest = a.split('-', 2)[1] b_rest = b.split('-', 2)[1] if a_rest and b_rest and a_rest < b_rest return false elsif a_rest and not b_rest return false elsif not a_rest and b_rest return true end return false end |
#wait_for_host_in_dashboard(host) ⇒ Object
wait for a given host to appear in the dashboard
1313 1314 1315 1316 |
# File 'lib/beaker/dsl/helpers.rb', line 1313 def wait_for_host_in_dashboard(host) hostname = host.node_name retry_on(dashboard, "! curl --tlsv1 -k -I https://#{dashboard}/nodes/#{hostname} | grep '404 Not Found'") end |
#with_forge_stubbed(forge_host = nil, &block) ⇒ Object
This wraps ‘with_forge_stubbed_on` and provides it the default host
1148 1149 1150 |
# File 'lib/beaker/dsl/helpers.rb', line 1148 def with_forge_stubbed( forge_host = nil, &block ) with_forge_stubbed_on( default, forge_host, &block ) end |
#with_forge_stubbed_on(host, forge_host = nil, &block) ⇒ Object
This wraps the method ‘with_host_stubbed_on` and makes the stub specific to the forge alias.
forge api v1 canonical source is forge.puppetlabs.com forge api v3 canonical source is forgeapi.puppetlabs.com
1136 1137 1138 1139 1140 1141 1142 1143 1144 |
# File 'lib/beaker/dsl/helpers.rb', line 1136 def with_forge_stubbed_on( host, forge_host = nil, &block ) #use global options hash forge_host ||= [:forge_host] @forge_ip ||= Resolv.getaddress(forge_host) with_host_stubbed_on( host, {'forge.puppetlabs.com' => @forge_ip, 'forgeapi.puppetlabs.com' => @forge_ip}, &block ) end |
#with_host_stubbed_on(host, ip_spec, &block) ⇒ Object
This method accepts a block and using the puppet resource ‘host’ will setup host aliases before and after that block.
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 |
# File 'lib/beaker/dsl/helpers.rb', line 1079 def with_host_stubbed_on(host, ip_spec, &block) begin block_on host do |host| ip_spec.each_pair do |address, ip| logger.notify("Stubbing address #{address} to IP #{ip} on machine #{host}") on( host, puppet('resource', 'host', address, 'ensure=present', "ip=#{ip}") ) end end block.call ensure ip_spec.each do |address, ip| logger.notify("Unstubbing address #{address} to IP #{ip} on machine #{host}") on( host, puppet('resource', 'host', address, 'ensure=absent') ) end end end |
#with_puppet_running(conf_opts, testdir = host.tmpdir(File.basename(@path)), &block) ⇒ Object
Test Puppet running in a certain run mode with specific options, on the default host
643 644 645 |
# File 'lib/beaker/dsl/helpers.rb', line 643 def with_puppet_running conf_opts, testdir = host.tmpdir(File.basename(@path)), &block with_puppet_running_on(default, conf_opts, testdir, &block) end |
#with_puppet_running_on(host, conf_opts, testdir = host.tmpdir(File.basename(@path)), &block) ⇒ Object
Test Puppet running in a certain run mode with specific options. This ensures the following steps are performed:
-
The pre-test Puppet configuration is backed up
-
A new Puppet configuraton file is layed down
-
Puppet is started or restarted in the specified run mode
-
Ensure Puppet has started correctly
-
Further tests are yielded to
-
Revert Puppet to the pre-test state
-
Testing artifacts are saved in a folder named for the test
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
# File 'lib/beaker/dsl/helpers.rb', line 552 def with_puppet_running_on host, conf_opts, testdir = host.tmpdir(File.basename(@path)), &block raise(ArgumentError, "with_puppet_running_on's conf_opts must be a Hash. You provided a #{conf_opts.class}: '#{conf_opts}'") if !conf_opts.kind_of?(Hash) cmdline_args = conf_opts[:__commandline_args__] service_args = conf_opts[:__service_args__] || {} conf_opts = conf_opts.reject { |k,v| [:__commandline_args__, :__service_args__].include?(k) } curl_retries = host['master-start-curl-retries'] || ['master-start-curl-retries'] logger.debug "Setting curl retries to #{curl_retries}" if [:is_puppetserver] confdir = host.puppet('master')['confdir'] vardir = host.puppet('master')['vardir'] if cmdline_args split_args = cmdline_args.split() split_args.each do |arg| case arg when /--confdir=(.*)/ confdir = $1 when /--vardir=(.*)/ vardir = $1 end end end puppetserver_opts = { "jruby-puppet" => { "master-conf-dir" => confdir, "master-var-dir" => vardir, }} puppetserver_conf = File.join("#{host['puppetserver-confdir']}", "puppetserver.conf") modify_tk_config(host, puppetserver_conf, puppetserver_opts) end begin backup_file = backup_the_file(host, host.puppet('master')['confdir'], testdir, 'puppet.conf') lay_down_new_puppet_conf host, conf_opts, testdir if host.use_service_scripts? && !service_args[:bypass_service_script] bounce_service( host, host['puppetservice'], curl_retries ) else puppet_master_started = start_puppet_from_source_on!( host, cmdline_args ) end yield self if block_given? rescue Beaker::DSL::Assertions, Minitest::Assertion => early_assertion fail_test(early_assertion) rescue Exception => early_exception original_exception = RuntimeError.new("PuppetAcceptance::DSL::Helpers.with_puppet_running_on failed (check backtrace for location) because: #{early_exception}\n#{early_exception.backtrace.join("\n")}\n") raise(original_exception) ensure begin if host.use_service_scripts? && !service_args[:bypass_service_script] restore_puppet_conf_from_backup( host, backup_file ) bounce_service( host, host['puppetservice'], curl_retries ) else if puppet_master_started stop_puppet_from_source_on( host ) else dump_puppet_log(host) end restore_puppet_conf_from_backup( host, backup_file ) end rescue Exception => teardown_exception begin if !host.is_pe? dump_puppet_log(host) end rescue Exception => dumping_exception logger.error("Raised during attempt to dump puppet logs: #{dumping_exception}") end if original_exception logger.error("Raised during attempt to teardown with_puppet_running_on: #{teardown_exception}\n---\n") raise original_exception else raise teardown_exception end end end end |
#write_hiera_config(hierarchy) ⇒ Object
Write hiera config file for the default host
1417 1418 1419 |
# File 'lib/beaker/dsl/helpers.rb', line 1417 def write_hiera_config(hierarchy) write_hiera_config_on(default, hierarchy) end |
#write_hiera_config_on(host, hierarchy) ⇒ Object
Write hiera config file on one or more provided hosts
@param[Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
or a role (String or Symbol) that identifies one or more hosts.
@param One or more hierarchy paths
1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 |
# File 'lib/beaker/dsl/helpers.rb', line 1402 def write_hiera_config_on(host, hierarchy) block_on host do |host| hiera_config=Hash.new hiera_config[:backends] = 'yaml' hiera_config[:yaml] = {} hiera_config[:yaml][:datadir] = hiera_datadir(host) hiera_config[:hierarchy] = hierarchy hiera_config[:logger] = 'console' create_remote_file host, host.puppet['hiera_config'], hiera_config.to_yaml end end |