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
Constant Summary collapse
- PUPPET_MODULE_INSTALL_IGNORE =
['.git', '.idea', '.vagrant', '.vendor', 'acceptance', 'spec', 'tests', 'log']
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.
-
#build_ignore_list(opts = {}) ⇒ Object
Build an array list of files/directories to ignore when pushing to remote host Automatically adds ‘..’ and ‘.’ to array.
-
#check_for_package(host, package_name) ⇒ Boolean
Check to see if a package is installed on a remote host.
-
#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_module_to(host, opts = {}) ⇒ Object
(also: #copy_root_module_to)
Install local module for acceptance testing should be used as a presuite to ensure local module is copied to the hosts you want, particularly masters.
-
#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.
-
#get_module_name(author_module_name) ⇒ String?
Parse modulename from the pattern ‘Auther-ModuleName’.
-
#install_package(host, package_name, package_version = nil) ⇒ Result
Install a package on a host.
-
#on(host, command, opts = {}, &block) ⇒ Result
The primary method for executing commands on some set of hosts.
-
#parse_for_modulename(root_module_dir) ⇒ String
Parse root directory of a module for module name Searches for metadata.json and then if none found, Modulefile and parses for the Name attribute.
-
#parse_for_moduleroot(possible_module_directory) ⇒ String?
Recursive method for finding the module root Assumes that a Modulefile exists.
-
#port_open_within?(host, port = 8140, seconds = 120) ⇒ Boolean
Blocks until the port is open on the host specified, returns false on failure.
-
#puppet_module_install(opts = {}) ⇒ Object
Copy a puppet module from a given source to all hosts under test.
-
#puppet_module_install_on(host, opts = {}) ⇒ Object
Copy a puppet module from a given source to all hosts under test.
- #retry_command(desc, host, command, desired_exit_codes = 0, max_retries = 60, retry_interval = 1, verbose = false) ⇒ Object
- #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.
-
#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_puppetdb_started(host) ⇒ Object
-
#split_author_modulename(author_module_attr) ⇒ Hash<Symbol,String>?
Split the Author-Name into a hash.
- #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 accepts a block and using the puppet resource ‘host’ will setup host aliases before and after that block.
-
#upgrade_package(host, package_name) ⇒ Result
Upgrade a package on a host.
-
#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_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.
Instance Method Details
#apply_manifest(manifest, opts = {}, &block) ⇒ Object
Runs ‘puppet apply’ on default host, piping manifest through stdin
849 850 851 |
# File 'lib/beaker/dsl/helpers.rb', line 849 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
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 |
# File 'lib/beaker/dsl/helpers.rb', line 771 def apply_manifest_on(host, manifest, opts = {}, &block) if host.is_a?(Array) return host.map do |h| apply_manifest_on(h, manifest, opts, &block) end end = {} [:acceptable_exit_codes] = Array(opts[:acceptable_exit_codes]) puppet_apply_opts = {} puppet_apply_opts[:verbose] = nil 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 |
#build_ignore_list(opts = {}) ⇒ Object
Build an array list of files/directories to ignore when pushing to remote host Automatically adds ‘..’ and ‘.’ to array. If not opts of :ignore list is provided it will use the static variable PUPPET_MODULE_INSTALL_IGNORE
1253 1254 1255 1256 1257 1258 1259 1260 1261 |
# File 'lib/beaker/dsl/helpers.rb', line 1253 def build_ignore_list(opts = {}) ignore_list = opts[:ignore_list] || PUPPET_MODULE_INSTALL_IGNORE if !ignore_list.kind_of?(Array) || ignore_list.nil? raise ArgumentError "Ignore list must be an Array" end ignore_list << '.' unless ignore_list.include? '.' ignore_list << '..' unless ignore_list.include? '..' ignore_list end |
#check_for_package(host, package_name) ⇒ Boolean
Check to see if a package is installed on a remote host
218 219 220 |
# File 'lib/beaker/dsl/helpers.rb', line 218 def check_for_package host, package_name host.check_for_package package_name 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
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'lib/beaker/dsl/helpers.rb', line 407 def confine(type, criteria, host_array = nil, &block) provided_hosts = host_array ? true : false hosts_to_modify = host_array || hosts criteria.each_pair do |property, value| case type when :except hosts_to_modify = hosts_to_modify.reject do |host| inspect_host host, property, value end if block_given? hosts_to_modify = hosts_to_modify.reject do |host| yield host end end when :to hosts_to_modify = hosts_to_modify.select do |host| inspect_host host, property, value end if block_given? hosts_to_modify = hosts_to_modify.select do |host| yield host end end else raise "Unknown option #{type}" end 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.
447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/beaker/dsl/helpers.rb', line 447 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_module_to(host, opts = {}) ⇒ Object Also known as: copy_root_module_to
Install local module for acceptance testing should be used as a presuite to ensure local module is copied to the hosts you want, particularly masters
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 |
# File 'lib/beaker/dsl/helpers.rb', line 1160 def copy_module_to(host, opts = {}) opts = {:source => './', :target_module_path => host['distmoduledir'], :ignore_list => PUPPET_MODULE_INSTALL_IGNORE}.merge(opts) ignore_list = build_ignore_list(opts) target_module_dir = opts[:target_module_path] if opts.has_key?(:module_name) module_name = opts[:module_name] else module_name = parse_for_modulename(opts[:source]) end scp_to host, File.join(opts[:source]), File.join(target_module_dir, module_name), {:ignore => ignore_list} 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
272 273 274 275 276 277 278 |
# File 'lib/beaker/dsl/helpers.rb', line 272 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 } scp_to hosts, tempfile.path, file_path, opts 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.
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/beaker/dsl/helpers.rb', line 292 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)
1132 1133 1134 1135 1136 1137 1138 |
# File 'lib/beaker/dsl/helpers.rb', line 1132 def curl_on(host, cmd, opts = {}, &block) if .is_pe? #check global options hash on host, "curl --sslv3 %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
966 967 968 |
# File 'lib/beaker/dsl/helpers.rb', line 966 def curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1) retry_command(desc, host, "curl -m 1 #{url}", desired_exit_codes, max_retries, retry_interval) 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.
257 258 259 |
# File 'lib/beaker/dsl/helpers.rb', line 257 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.
163 164 165 166 |
# File 'lib/beaker/dsl/helpers.rb', line 163 def exit_code return nil if @result.nil? @result.exit_code end |
#fact(name, opts = {}) ⇒ Object
Get a facter fact from the default host
1120 1121 1122 |
# File 'lib/beaker/dsl/helpers.rb', line 1120 def fact(name, opts = {}) fact_on(default, name, opts) end |
#fact_on(host, name, opts = {}) ⇒ Object
Get a facter fact from a provided host
1113 1114 1115 1116 |
# File 'lib/beaker/dsl/helpers.rb', line 1113 def fact_on(host, name, opts = {}) result = on host, facter(name, opts) result.stdout.chomp if result.stdout end |
#get_module_name(author_module_name) ⇒ String?
Parse modulename from the pattern ‘Auther-ModuleName’
1226 1227 1228 1229 1230 1231 |
# File 'lib/beaker/dsl/helpers.rb', line 1226 def get_module_name() split_name = () if split_name split_name[:module] end end |
#install_package(host, package_name, package_version = nil) ⇒ Result
Install a package on a host
228 229 230 |
# File 'lib/beaker/dsl/helpers.rb', line 228 def install_package host, package_name, package_version = nil host.install_package package_name, '', package_version end |
#on(host, command, opts = {}, &block) ⇒ Result
The primary method for executing commands on some set of hosts.
76 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 104 105 106 |
# File 'lib/beaker/dsl/helpers.rb', line 76 def on(host, command, opts = {}, &block) unless command.is_a? Command cmd_opts = {} if opts[:environment] cmd_opts['ENV'] = opts[:environment] end command = Command.new(command.to_s, [], cmd_opts) end if host.is_a? String or host.is_a? Symbol host = hosts_as(host) #check by role end if host.is_a? Array host.map { |h| on h, command, opts, &block } else @result = host.exec(command, 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 return @result end end |
#parse_for_modulename(root_module_dir) ⇒ String
Parse root directory of a module for module name Searches for metadata.json and then if none found, Modulefile and parses for the Name attribute
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 |
# File 'lib/beaker/dsl/helpers.rb', line 1199 def parse_for_modulename(root_module_dir) module_name = nil if File.exists?("#{root_module_dir}/metadata.json") logger.debug "Attempting to parse Modulename from metadata.json" module_json = JSON.parse (File.read "#{root_module_dir}/metadata.json") if(module_json.has_key?('name')) module_name = get_module_name(module_json['name']) end end if !module_name && File.exists?("#{root_module_dir}/Modulefile") logger.debug "Attempting to parse Modulename from Modulefile" if /^name\s+'?(\w+-\w+)'?\s*$/i.match(File.read("#{root_module_dir}/Modulefile")) module_name = get_module_name(Regexp.last_match[1]) end end if !module_name logger.debug "Unable to determine name, returning null" end module_name end |
#parse_for_moduleroot(possible_module_directory) ⇒ String?
Recursive method for finding the module root Assumes that a Modulefile exists
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 |
# File 'lib/beaker/dsl/helpers.rb', line 1182 def parse_for_moduleroot(possible_module_directory) if File.exists?("#{possible_module_directory}/Modulefile") possible_module_directory elsif possible_module_directory === '/' logger.error "At root, can't parse for another directory" nil else logger.debug "No Modulefile found at #{possible_module_directory}, moving up" parse_for_moduleroot File.(File.join(possible_module_directory,'..')) 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
699 700 701 702 703 |
# File 'lib/beaker/dsl/helpers.rb', line 699 def port_open_within?( host, port = 8140, seconds = 120 ) repeat_for( seconds ) do host.port_open?( port ) end end |
#puppet_module_install(opts = {}) ⇒ Object
Copy a puppet module from a given source to all hosts under test.
359 360 361 |
# File 'lib/beaker/dsl/helpers.rb', line 359 def puppet_module_install opts = {} puppet_module_install_on(hosts, opts) end |
#puppet_module_install_on(host, opts = {}) ⇒ Object
Copy a puppet module from a given source to all hosts under test. Assumes each host under test has an associated ‘distmoduledir’ (set in the host configuration YAML file).
351 352 353 354 355 |
# File 'lib/beaker/dsl/helpers.rb', line 351 def puppet_module_install_on(host, opts = {}) Array(host).each do |h| on h, puppet("module install #{opts[:module_name]}") end end |
#retry_command(desc, host, command, desired_exit_codes = 0, max_retries = 60, retry_interval = 1, verbose = false) ⇒ Object
970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 |
# File 'lib/beaker/dsl/helpers.rb', line 970 def retry_command(desc, host, command, desired_exit_codes = 0, max_retries = 60, retry_interval = 1, verbose = false) 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 desired_exit_codes = [desired_exit_codes].flatten result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose} 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} 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." end |
#run_agent_on(host, arg = '--no-daemonize --verbose --onetime --test', options = {}, &block) ⇒ Object
854 855 856 857 858 859 860 861 |
# File 'lib/beaker/dsl/helpers.rb', line 854 def run_agent_on(host, arg='--no-daemonize --verbose --onetime --test', ={}, &block) if host.is_a? Array host.each { |h| run_agent_on h, arg, , &block } else on host, puppet_agent(arg), , &block end end |
#run_script(script, opts = {}, &block) ⇒ Object
Move a local script to default host and execute it
340 341 342 |
# File 'lib/beaker/dsl/helpers.rb', line 340 def run_script(script, opts = {}, &block) run_script_on(default, script, opts, &block) end |
#run_script_on(host, script, opts = {}, &block) ⇒ Result
325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/beaker/dsl/helpers.rb', line 325 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
181 182 183 184 185 186 187 188 |
# File 'lib/beaker/dsl/helpers.rb', line 181 def scp_from host, from_path, to_path, opts = {} if host.is_a? Array host.each { |h| scp_from h, from_path, to_path, opts } else @result = host.do_scp_from(from_path, to_path, opts) @result.log logger 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.
Move a local file to a remote host
203 204 205 206 207 208 209 210 |
# File 'lib/beaker/dsl/helpers.rb', line 203 def scp_to host, from_path, to_path, opts = {} if host.is_a? Array host.each { |h| scp_to h, from_path, to_path, opts } else @result = host.do_scp_to(from_path, to_path, opts) @result.log logger end end |
#shell(command, opts = {}, &block) ⇒ Result
The method for executing commands on the default host
134 135 136 |
# File 'lib/beaker/dsl/helpers.rb', line 134 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
1101 1102 1103 |
# File 'lib/beaker/dsl/helpers.rb', line 1101 def sign_certificate sign_certificate_for(default) end |
#sign_certificate_for(host) ⇒ Object
Ensure the host has requested a cert, then sign it
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 |
# File 'lib/beaker/dsl/helpers.rb', line 1075 def sign_certificate_for(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"), :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 |
#sleep_until_puppetdb_started(host) ⇒ Object
960 961 962 963 964 |
# File 'lib/beaker/dsl/helpers.rb', line 960 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 |
#split_author_modulename(author_module_attr) ⇒ Hash<Symbol,String>?
Split the Author-Name into a hash
1238 1239 1240 1241 1242 1243 1244 1245 |
# File 'lib/beaker/dsl/helpers.rb', line 1238 def () result = /(\w+)-(\w+)/.match() if result {:author => result[1], :module => result[2]} else nil end 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.
153 154 155 156 |
# File 'lib/beaker/dsl/helpers.rb', line 153 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.
143 144 145 146 |
# File 'lib/beaker/dsl/helpers.rb', line 143 def stdout return nil if @result.nil? @result.stdout end |
#stop_agent ⇒ Object
stops the puppet agent running on the default host
1058 1059 1060 |
# File 'lib/beaker/dsl/helpers.rb', line 1058 def stop_agent stop_agent_on(default) end |
#stop_agent_on(agent) ⇒ Object
stops the puppet agent running on the host
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 |
# File 'lib/beaker/dsl/helpers.rb', line 1027 def stop_agent_on(agent) vardir = agent.puppet['vardir'] agent_running = true while agent_running result = on agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1] agent_running = (result.exit_code == 0) sleep 2 unless agent_running 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` result = on agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1] agent_service = (result.exit_code == 0) ? 'pe-puppet-agent' : 'pe-puppet' # 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 on agent, "/etc/init.d/#{agent_service} stop" else on agent, puppet_resource('service', agent_service, 'ensure=stopped') end end |
#stub_forge(forge_host = nil) ⇒ Object
This wraps the method ‘stub_hosts` and makes the stub specific to the forge alias.
954 955 956 957 958 |
# File 'lib/beaker/dsl/helpers.rb', line 954 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
942 943 944 945 946 947 948 |
# File 'lib/beaker/dsl/helpers.rb', line 942 def stub_forge_on(machine, forge_host = nil) #use global options hash forge_host ||= [:forge_host] @forge_ip ||= Resolv.getaddress(forge_host) stub_hosts_on(machine, 'forge.puppetlabs.com' => @forge_ip) stub_hosts_on(machine, 'forgeapi.puppetlabs.com' => @forge_ip) 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
929 930 931 |
# File 'lib/beaker/dsl/helpers.rb', line 929 def stub_hosts(ip_spec) stub_hosts_on(default, ip_spec) end |
#stub_hosts_on(machine, ip_spec) ⇒ Object
This method accepts a block and using the puppet resource ‘host’ will setup host aliases before and after that block.
A teardown step is also added to make sure unstubbing of the host is removed always.
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 |
# File 'lib/beaker/dsl/helpers.rb', line 907 def stub_hosts_on(machine, ip_spec) ip_spec.each do |host, ip| logger.notify("Stubbing host #{host} to IP #{ip} on machine #{machine}") on( machine, puppet('resource', 'host', host, 'ensure=present', "ip=#{ip}") ) end teardown do ip_spec.each do |host, ip| logger.notify("Unstubbing host #{host} to IP #{ip} on machine #{machine}") on( machine, puppet('resource', 'host', host, 'ensure=absent') ) end end end |
#upgrade_package(host, package_name) ⇒ Result
Upgrade a package on a host. The package must already be installed
238 239 240 |
# File 'lib/beaker/dsl/helpers.rb', line 238 def upgrade_package host, package_name host.upgrade_package package_name 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
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 |
# File 'lib/beaker/dsl/helpers.rb', line 999 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
1064 1065 1066 1067 |
# File 'lib/beaker/dsl/helpers.rb', line 1064 def wait_for_host_in_dashboard(host) hostname = host.node_name retry_command("Wait for #{hostname} to be in the console", dashboard, "! curl --sslv3 -k -I https://#{dashboard}/nodes/#{hostname} | grep '404 Not Found'") 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
585 586 587 |
# File 'lib/beaker/dsl/helpers.rb', line 585 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
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 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 |
# File 'lib/beaker/dsl/helpers.rb', line 524 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__] conf_opts = conf_opts.reject { |k,v| k == :__commandline_args__ } curl_retries = host['master-start-curl-retries'] || ['master-start-curl-retries'] logger.debug "Setting curl retries to #{curl_retries}" begin backup_file = backup_the_file(host, host['puppetpath'], testdir, 'puppet.conf') lay_down_new_puppet_conf host, conf_opts, testdir if host['puppetservice'] 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 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 restore_puppet_conf_from_backup( host, backup_file ) if host['puppetservice'] bounce_service( host, host['puppetservice'], curl_retries ) else if puppet_master_started stop_puppet_from_source_on( host ) else dump_puppet_log(host) end 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 |