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

Instance Method Details

#apply_manifest(manifest, opts = {}, &block) ⇒ Object

Runs ‘puppet apply’ on default host, piping manifest through stdin

See Also:



959
960
961
# File 'lib/beaker/dsl/helpers.rb', line 959

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

Parameters:

  • host (Host)

    The host that this command should be run on

  • manifest (String)

    The puppet manifest to apply

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

  • block (Block)

    This method will yield to a block of code passed by the caller; this can be used for additional validation, etc.

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.

  • :parseonly (Boolean) — default: false

    If this key is true, the “–parseonly” command line parameter will be passed to the ‘puppet apply’ command.

  • :trace (Boolean) — default: false

    If this key exists in the Hash, the “–trace” command line parameter will be passed to the ‘puppet apply’ command.

  • :acceptable_exit_codes (Array<Integer>) — default: [0]

    The list of exit codes that will NOT raise an error when found upon command completion. If provided, these values will be combined with those used in :catch_failures and :expect_failures to create the full list of passing exit codes.

  • :environment (Hash)

    Additional environment variables to be passed to the ‘puppet apply’ command

  • :catch_failures (Boolean) — default: false

    By default ‘puppet –apply` will exit with 0, which does not count as a test failure, even if there were errors or changes when applying the manifest. This option enables detailed exit codes and causes a test failure if `puppet –apply` indicates there was a failure during its execution.

  • :catch_changes (Boolean) — default: false

    This option enables detailed exit codes and causes a test failure if ‘puppet –apply` indicates that there were changes or failures during its execution.

  • :expect_changes (Boolean) — default: false

    This option enables detailed exit codes and causes a test failure if ‘puppet –apply` indicates that there were no resource changes during its execution.

  • :expect_failures (Boolean) — default: false

    This option enables detailed exit codes and causes a test failure if ‘puppet –apply` indicates there were no failure during its execution.

  • :future_parser (Boolean) — default: false

    This option enables the future parser option that is available from Puppet verion 3.2 By default it will use the ‘current’ parser.

  • :noop (Boolean) — default: false

    If this option exists, the the “–noop” command line parameter will be passed to the ‘puppet apply’ command.

  • :modulepath (String)

    The search path for modules, as a list of directories separated by the system path separator character. (The POSIX path separator is ‘:’, and the Windows path separator is ‘;’.)

  • :debug (String) — default: false

    If this option exists, the “–debug” command line parameter will be passed to the ‘puppet apply’ command.



881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
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
# File 'lib/beaker/dsl/helpers.rb', line 881

def apply_manifest_on(host, manifest, opts = {}, &block)
  block_on host do | host |
    on_options = {}
    on_options[: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.
      on_options[: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.
      on_options[: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.
      on_options[: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.
      on_options[:acceptable_exit_codes] |= [2]
    else
      # Either use the provided acceptable_exit_codes or default to [0]
      on_options[: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), on_options, &block
  end
end

#confine(type, criteria, host_array = nil, &block) ⇒ Array<Host>

Note:

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

Examples:

Basic usage to confine to debian OSes.

confine :to, :platform => 'debian'

Confining to anything but Windows and Solaris

confine :except, :platform => ['windows', 'solaris']

Using additional block to confine to Solaris global zone.

confine :to, :platform => 'solaris' do |solaris|
  on( solaris, 'zonename' ) =~ /global/
end

Parameters:

  • type (Symbol)

    The type of confinement to do. Valid parameters are :to to confine the hosts to only those that match criteria or :except to confine the test case to only those hosts that do not match criteria.

  • criteria (Hash{Symbol,String=>String,Regexp,Array<String,Regexp>})

    Specify the criteria with which a host should be considered for inclusion or exclusion. The key is any attribute of the host that will be yielded by Host#[]. The value can be any string/regex or array of strings/regexp. The values are compared using [Enumerable#any?] so that if one value of an array matches the host is considered a match for that criteria.

  • host_array (Array<Host>) (defaults to: nil)

    This creatively named parameter is an optional array of hosts to confine to. If not passed in, this method will modify TestCase#hosts in place.

  • block (Proc)

    Addition checks to determine suitability of hosts for confinement. Each host that is still valid after checking criteria is then passed in turn into this block. The block should return true if the host matches this additional criteria.

Returns:

  • (Array<Host>)

    Returns an array of hosts that are still valid targets for this tests case.

Raises:

  • (SkipTest)

    Raises skip test if there are no valid hosts for this test case after confinement.



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'lib/beaker/dsl/helpers.rb', line 359

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.

See Also:



382
383
384
385
386
387
388
389
390
391
392
# File 'lib/beaker/dsl/helpers.rb', line 382

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



1397
1398
1399
# File 'lib/beaker/dsl/helpers.rb', line 1397

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.



1391
1392
1393
# File 'lib/beaker/dsl/helpers.rb', line 1391

def copy_hiera_data_to(host, source)
  scp_to host, File.expand_path(source), host[:hieradatadir]
end

#create_remote_file(hosts, file_path, file_content, opts = {}) ⇒ Result

Note:

This method uses Tempfile in Ruby’s STDLIB as well as #scp_to.

Create a remote file out of a string

Parameters:

  • hosts (Host, #do_scp_to)

    One or more hosts (or some object that responds like Host#do_scp_from.

  • file_path (String)

    A remote path to place file_content at.

  • file_content (String)

    The contents of the file to be placed.

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.

Returns:

  • (Result)

    Returns the result of the underlying SCP operation.



243
244
245
246
247
248
249
# File 'lib/beaker/dsl/helpers.rb', line 243

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.

Parameters:

  • host (Host)

    A single remote host on which to create and adjust

  • name (String) (defaults to: '/tmp/beaker')

    A remote path prefix for the new temp

  • user (String) (defaults to: nil)

    The name of user that should own the temp

Returns:

  • (String)

    Returns the name of the newly-created file.



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/beaker/dsl/helpers.rb', line 263

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)

Parameters:

  • host (Host, Array<Host>, String, Symbol)

    One or more hosts to act upon, or a role (String or Symbol) that identifies one or more hosts.

  • cmd (String, Command)

    The curl command to execute on host.

  • block (Proc)

    Additional actions or assertions.

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.



1354
1355
1356
1357
1358
1359
1360
# File 'lib/beaker/dsl/helpers.rb', line 1354

def curl_on(host, cmd, opts = {}, &block)
  if options.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



1144
1145
1146
1147
1148
1149
1150
1151
# File 'lib/beaker/dsl/helpers.rb', line 1144

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

Note:

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.

Parameters:

  • host (Host)
  • path (String)

    The path to the generated repository config files. ex: /myproject/pkg/repo_configs

  • name (String)

    A human-readable name for the repository

  • version (String)

    The version of the project, as used by the packaging tools. This can be determined with ‘rake pl:print_build_params` from the packaging repo.



228
229
230
# File 'lib/beaker/dsl/helpers.rb', line 228

def deploy_package_repo host, path, name, version
  host.deploy_package_repo path, name, version
end

#exit_codeObject

Deprecated.

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

See Also:



1342
1343
1344
# File 'lib/beaker/dsl/helpers.rb', line 1342

def fact(name, opts = {})
  fact_on(default, name, opts)
end

#fact_on(host, name, opts = {}) ⇒ Object

Get a facter fact from a provided host

Parameters:

  • host (Host, Array<Host>, String, Symbol)

    One or more hosts to act upon, or a role (String or Symbol) that identifies one or more hosts.

  • name (String)

    The name of the fact to query for

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.

Returns:

  • String The value of the fact ‘name’ on the provided host

Raises:

  • (FailTest)

    Raises an exception if call to facter fails



1331
1332
1333
1334
1335
1336
1337
1338
# File 'lib/beaker/dsl/helpers.rb', line 1331

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

#modify_tk_config(host, config_file_path, options_hash, replace = false) ⇒ Object

Note:

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.

Parameters:

  • host (Host)

    A host object

  • options_hash (OptionsHash)

    New hash which will be merged into the given TrapperKeeper config.

  • config_file_path (String)

    Path to the TrapperKeeper config on the given host which is to be modified.

  • replace (Bool) (defaults to: false)

    If set true, instead of updating the existing TrapperKeeper configuration, replace it entirely with the contents of the given hash.



733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
# File 'lib/beaker/dsl/helpers.rb', line 733

def modify_tk_config(host, config_file_path, options_hash, replace=false)
  if options_hash.empty?
    return nil
  end

  new_hash = Beaker::Options::OptionsHash.new

  if replace
    new_hash.merge!(options_hash)
  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!(options_hash)
  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.

Examples:

Most basic usage

on hosts, 'ls /tmp'

Allowing additional exit codes to pass

on agents, 'puppet agent -t', :acceptable_exit_codes => [0,2]

Using the returned result for any kind of checking

if on(host, 'ls -la ~').stdout =~ /\.bin/
  ...do some action...
end

Using TestCase helpers from within a test.

agents.each do |agent|
  on agent, 'cat /etc/puppet/puppet.conf' do
    assert_match stdout, /server = #{master}/, 'WTF Mate'
  end
end

Using a role (defined in a String) to identify the host

on "master", "echo hello"

Using a role (defined in a Symbol) to identify the host

on :dashboard, "echo hello"

Parameters:

  • host (Host, Array<Host>, String, Symbol)

    One or more hosts to act upon, or a role (String or Symbol) that identifies one or more hosts.

  • command (String, Command)

    The command to execute on host.

  • block (Proc)

    Additional actions or assertions.

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.

Returns:

  • (Result)

    An object representing the outcome of command.

Raises:

  • (FailTest)

    Raises an exception if command obviously fails.



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

Returns:

  • (Boolean)


805
806
807
808
809
# File 'lib/beaker/dsl/helpers.rb', line 805

def port_open_within?( host, port = 8140, seconds = 120 )
  repeat_for( seconds ) do
    host.port_open?( port )
  end
end

#puppet_group(host) ⇒ Object

Note:

This method assumes puppet is installed on the host.

Return the name of the puppet group.

Parameters:

  • host (Host)

    One object that acts like a Beaker::Host



443
444
445
# File 'lib/beaker/dsl/helpers.rb', line 443

def puppet_group(host)
  return host.puppet('master')['group']
end

#puppet_user(host) ⇒ Object

Note:

This method assumes puppet is installed on the host.

Return the name of the puppet user.

Parameters:

  • host (Host)

    One object that acts like a Beaker::Host



433
434
435
# File 'lib/beaker/dsl/helpers.rb', line 433

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

Parameters:

  • host (Host, Array<Host>, String, Symbol)

    One or more hosts to act upon, or a role (String or Symbol) that identifies one or more hosts.

  • command (String, Command)

    The command to execute on host.

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

  • block (Proc)

    Additional actions or assertions.

Options Hash (opts):

  • :desired_exit_codes (Array<Fixnum>, Fixnum) — default: 0

    An array or integer exit code(s) that should be considered acceptable. An error will be thrown if the exit code never matches one of the values in this list.

  • :max_retries (Fixnum) — default: 60

    number of times the command will be tried before failing

  • :retry_interval (Float) — default: 1

    number of seconds that we’ll wait between tries

  • :verbose (Boolean) — default: false


1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
# File 'lib/beaker/dsl/helpers.rb', line 1170

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

#run_agent_on(host, arg = '--no-daemonize --verbose --onetime --test', options = {}, &block) ⇒ Object

Deprecated.


964
965
966
967
968
969
# File 'lib/beaker/dsl/helpers.rb', line 964

def run_agent_on(host, arg='--no-daemonize --verbose --onetime --test',
                 options={}, &block)
  block_on host do | host |
    on host, puppet_agent(arg), options, &block
  end
end

#run_script(script, opts = {}, &block) ⇒ Object

Move a local script to default host and execute it

See Also:



311
312
313
# File 'lib/beaker/dsl/helpers.rb', line 311

def run_script(script, opts = {}, &block)
  run_script_on(default, script, opts, &block)
end

#run_script_on(host, script, opts = {}, &block) ⇒ Result

Note:

this relies on #on and #scp_to

Move a local script to a remote host and execute it

Parameters:

  • host (Host, #do_scp_to)

    One or more hosts (or some object that responds like Host#do_scp_from.

  • script (String)

    A local path to find an executable script at.

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

  • block (Proc)

    Additional tests to run after script has executed

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.

Returns:

  • (Result)

    Returns the result of the underlying SCP operation.



296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/beaker/dsl/helpers.rb', line 296

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

Note:

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

Parameters:

  • host (Host, #do_scp_from)

    One or more hosts (or some object that responds like Host#do_scp_from.

  • from_path (String)

    A remote path to a file.

  • to_path (String)

    A local path to copy from_path to.

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.

Returns:

  • (Result)

    Returns the result of the SCP operation



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

Note:

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

Parameters:

  • host (Host, #do_scp_to)

    One or more hosts (or some object that responds like Host#do_scp_to.

  • from_path (String)

    A local path to a file.

  • to_path (String)

    A remote path to copy from_path to.

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.

Returns:

  • (Result)

    Returns the result of the SCP operation



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

Parameters:

  • criteria (Hash{Symbol,String=>String,Regexp,Array<String,Regexp>})

    Specify the criteria with which a host should be considered for inclusion. The key is any attribute of the host that will be yielded by Host#[]. The value can be any string/regex or array of strings/regexp. The values are compared using [Enumerable#any?] so that if one value of an array matches the host is considered a match for that criteria.

  • host_array (Array<Host>) (defaults to: nil)

    This creatively named parameter is an optional array of hosts to confine to. If not passed in, this method will modify TestCase#hosts in place.

  • block (Proc)

    Addition checks to determine suitability of hosts for selection. Each host that is still valid after checking criteria is then passed in turn into this block. The block should return true if the host matches this additional criteria.

Returns:

  • (Array<Host>)

    Returns an array of hosts that meet the provided criteria



412
413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'lib/beaker/dsl/helpers.rb', line 412

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

Examples:

Most basic usage

shell 'ls /tmp'

Allowing additional exit codes to pass

shell 'puppet agent -t', :acceptable_exit_codes => [0,2]

Using the returned result for any kind of checking

if shell('ls -la ~').stdout =~ /\.bin/
  ...do some action...
end

Using TestCase helpers from within a test.

agents.each do |agent|
  shell('cat /etc/puppet/puppet.conf') do |result|
    assert_match result.stdout, /server = #{master}/, 'WTF Mate'
  end
end

Parameters:

  • command (String, Command)

    The command to execute on host.

  • block (Proc)

    Additional actions or assertions.

  • opts (Hash{Symbol=>String}) (defaults to: {})

    Options to alter execution.

Options Hash (opts):

  • :silent (Boolean) — default: false

    Do not produce log output

  • :acceptable_exit_codes (Array<Fixnum>) — default: [0]

    An array (or range) of integer exit codes that should be considered acceptable. An error will be thrown if the exit code does not match one of the values in this list.

  • :environment (Hash{String=>String}) — default: {}

    These will be treated as extra environment variables that should be set before running the command.

Returns:

  • (Result)

    An object representing the outcome of command.

Raises:

  • (FailTest)

    Raises an exception if command obviously fails.



131
132
133
# File 'lib/beaker/dsl/helpers.rb', line 131

def shell(command, opts = {}, &block)
  on(default, command, opts, &block)
end

#sign_certificateObject

prompt the master to sign certs then check to confirm the cert for the default host is signed



1318
1319
1320
# File 'lib/beaker/dsl/helpers.rb', line 1318

def sign_certificate
  sign_certificate_for(default)
end

#sign_certificate_for(host) ⇒ Object

Ensure the host has requested a cert, then sign it

Parameters:

  • host (Host, Array<Host>, String, Symbol)

    One or more hosts to act upon, or a role (String or Symbol) that identifies one or more hosts.

Returns:

  • nil

Raises:



1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
# File 'lib/beaker/dsl/helpers.rb', line 1290

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



1139
1140
1141
1142
# File 'lib/beaker/dsl/helpers.rb', line 1139

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



1128
1129
1130
1131
1132
# File 'lib/beaker/dsl/helpers.rb', line 1128

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



1134
1135
1136
1137
# File 'lib/beaker/dsl/helpers.rb', line 1134

def sleep_until_puppetserver_started(host)
  curl_with_retries("start puppetserver (ssl)",
                    host, "https://#{host.node_name}:8140", [35, 60])
end

#stderrObject

Deprecated.

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

#stdoutObject

Deprecated.

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_agentObject

stops the puppet agent running on the default host

See Also:



1272
1273
1274
# File 'lib/beaker/dsl/helpers.rb', line 1272

def stop_agent
  stop_agent_on(default)
end

#stop_agent_on(agent) ⇒ Object

stops the puppet agent running on the host

Parameters:

  • agent (Host, Array<Host>, String, Symbol)

    One or more hosts to act upon, or a role (String or Symbol) that identifies one or more hosts.



1238
1239
1240
1241
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
1268
# File 'lib/beaker/dsl/helpers.rb', line 1238

def stop_agent_on(agent)
  block_on agent do | host |
    vardir = agent.puppet['vardir']
    agent_running = true
    while agent_running
      result = on host, "[ -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
      # 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.

See Also:



1122
1123
1124
1125
1126
# File 'lib/beaker/dsl/helpers.rb', line 1122

def stub_forge(forge_host = nil)
  #use global options hash
  forge_host ||= options[: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

Parameters:

  • machine (String)

    the host to perform the stub on

  • forge_host (String) (defaults to: nil)

    The URL to use as the forge alias, will default to using :forge_host in the global options hash



1083
1084
1085
1086
1087
1088
1089
1090
1091
# File 'lib/beaker/dsl/helpers.rb', line 1083

def stub_forge_on(machine, forge_host = nil)
  #use global options hash
  forge_host ||= options[: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

Examples:

Stub puppetlabs.com on the default host to 127.0.0.1

stub_hosts('puppetlabs.com' => '127.0.0.1')

See Also:



1070
1071
1072
# File 'lib/beaker/dsl/helpers.rb', line 1070

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.

Examples:

Stub puppetlabs.com on the master to 127.0.0.1

stub_hosts_on(master, 'puppetlabs.com' => '127.0.0.1')

Parameters:

  • machine (Host, Array<Host>, String, Symbol)

    One or more hosts to act upon, or a role (String or Symbol) that identifies one or more hosts.

  • ip_spec (Hash{String=>String})

    a hash containing the host to ip mappings



1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
# File 'lib/beaker/dsl/helpers.rb', line 1018

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

Note:

3.0.0-160-gac44cfb is greater than 3.0.0, and 2.8.2

Note:

-rc being less than final builds is not yet implemented.

Is semver-ish version a less than semver-ish version b

Parameters:

  • a (String)

    A version of the from ‘d.d.d.*’

  • b (String)

    A version of the form ‘d.d.d.*’

Returns:

  • (Boolean)

    true if a is less than b, otherwise return false



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 1208

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



1278
1279
1280
1281
# File 'lib/beaker/dsl/helpers.rb', line 1278

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



1114
1115
1116
# File 'lib/beaker/dsl/helpers.rb', line 1114

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

Parameters:

  • host (String)

    the host to perform the stub on

  • forge_host (String) (defaults to: nil)

    The URL to use as the forge alias, will default to using :forge_host in the global options hash



1102
1103
1104
1105
1106
1107
1108
1109
1110
# File 'lib/beaker/dsl/helpers.rb', line 1102

def with_forge_stubbed_on( host, forge_host = nil, &block )
  #use global options hash
  forge_host ||= options[: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.

Examples:

Stub puppetlabs.com on the master to 127.0.0.1

with_host_stubbed_on(master, 'forgeapi.puppetlabs.com' => '127.0.0.1') do
  puppet( "module install puppetlabs-stdlib" )
end

Parameters:

  • host (Host, Array<Host>, String, Symbol)

    One or more hosts to act upon, or a role (String or Symbol) that identifies one or more hosts.

  • ip_spec (Hash{String=>String})

    a hash containing the host to ip mappings



1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
# File 'lib/beaker/dsl/helpers.rb', line 1045

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



609
610
611
# File 'lib/beaker/dsl/helpers.rb', line 609

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:

  1. The pre-test Puppet configuration is backed up

  2. A new Puppet configuraton file is layed down

  3. Puppet is started or restarted in the specified run mode

  4. Ensure Puppet has started correctly

  5. Further tests are yielded to

  6. Revert Puppet to the pre-test state

  7. Testing artifacts are saved in a folder named for the test

Examples:

A simple use case to ensure a master is running

with_puppet_running_on( master ) do
    ...tests that require a master...
end

Fully utilizing the possiblities of config options

with_puppet_running_on( master,
                        :main => {:logdest => '/var/blah'},
                        :master => {:masterlog => '/elswhere'},
                        :agent => {:server => 'localhost'} ) do

  ...tests to be ran...
end

Parameters:

  • host (Host)

    One object that act like Host

  • conf_opts (Hash{Symbol=>String})

    Represents puppet settings. Sections of the puppet.conf may be specified, if no section is specified the a puppet.conf file will be written with the options put in a section named after [mode]

  • testdir (File) (defaults to: host.tmpdir(File.basename(@path)))

    The temporary directory which will hold backup configuration, and other test artifacts.

  • block (Block)

    The point of this method, yields so tests may be ran. After the block is finished puppet will revert to a previous state.

Options Hash (conf_opts):

  • :__commandline_args__ (String)

    A special setting for command_line arguments such as –debug or –logdest, which cannot be set in puppet.conf. For example:

    :commandline_args => ‘–logdest /tmp/a.log’

    These will only be applied when starting a FOSS master, as a pe master is just bounced.

  • :__service_args__ (Hash)

    A special setting of options for controlling how the puppet master service is handled. The only setting currently is :bypass_service_script, which if set true will force stopping and starting a webrick master using the start_puppet_from_source_* methods, even if it seems the host has passenger. This is needed in FOSS tests to initialize SSL.

Raises:

  • (ArgumentError)


520
521
522
523
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
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
# File 'lib/beaker/dsl/helpers.rb', line 520

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'] || options['master-start-curl-retries']
  logger.debug "Setting curl retries to #{curl_retries}"

  if options[: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['puppetconfdir'], 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 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



1382
1383
1384
# File 'lib/beaker/dsl/helpers.rb', line 1382

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



1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
# File 'lib/beaker/dsl/helpers.rb', line 1367

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] = host[:hieradatadir]
    hiera_config[:hierarchy] = hierarchy
    hiera_config[:logger] = 'console'
    create_remote_file host, host[:hieraconf], hiera_config.to_yaml
  end
end