lib/beaker/dsl/helpers.rb in beaker-1.12.2 vs lib/beaker/dsl/helpers.rb in beaker-1.13.0
- old
+ new
@@ -271,10 +271,44 @@
scp_to hosts, tempfile.path, file_path, opts
end
end
+ # Create a temp directory on remote host owned by specified user.
+ #
+ # @param [Host] host A single remote host on which to create and adjust
+ # the ownership of a temp directory.
+ # @param [String] name A remote path prefix for the new temp
+ # directory. Default value is '/tmp/beaker'
+ # @param [String] user The name of user that should own the temp
+ # 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.
+ #
+ # @return [String] Returns the name of the newly-created file.
+ 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
+
# Move a local script to a remote host and execute it
# @note this relies on {#on} and {#scp_to}
#
# @param [Host, #do_scp_to] host One or more hosts (or some object
# that responds like
@@ -716,10 +750,14 @@
# @option opts [Boolean] :future_parser (false) This option enables
# the future parser option that is available
# from Puppet verion 3.2
# By default it will use the 'current' parser.
#
+ # @option opts [Boolean] :noop (false) If this option exists, the
+ # the "--noop" command line parameter will be
+ # passed to the 'puppet apply' command.
+ #
# @option opts [String] :modulepath 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 ‘;’.)
#
@@ -735,40 +773,46 @@
end
on_options = {}
on_options[:acceptable_exit_codes] = Array(opts[:acceptable_exit_codes])
- args = ["--verbose"]
- args << "--parseonly" if opts[:parseonly]
- args << "--trace" if opts[:trace]
- args << "--parser future" if opts[:future_parser]
- args << "--modulepath #{opts[:modulepath]}" if opts[:modulepath]
+ 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]].select{|x|x}.length > 1
- raise(ArgumentError, "Cannot specify more than one of `catch_failures`, `catch_changes`, `expect_failures`, or `expect_changes` for a single manifest")
+ 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]
- args << '--detailed-exitcodes'
+ 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]
- args << '--detailed-exitcodes'
+ 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]
- args << '--detailed-exitcodes'
+ 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]
- args << '--detailed-exitcodes'
+ 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]
@@ -782,17 +826,21 @@
# 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)
- args << { :environment => opts[:environment]}
+ puppet_apply_opts['ENV'] = opts[:environment]
end
file_path = host.tmpfile('apply_manifest.pp')
create_remote_file(host, file_path, manifest + "\n")
- args << file_path
- on host, puppet( 'apply', *args), on_options, &block
+
+ 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
# Runs 'puppet apply' on default host, piping manifest through stdin
# @see #apply_manifest_on
def apply_manifest(manifest, opts = {}, &block)
@@ -914,21 +962,29 @@
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
- def retry_command(desc, host, command, desired_exit_codes = 0, max_retries = 60, retry_interval = 1)
+ 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)
+ 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)
+ result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}
num_retries += 1
+ @logger.debug ".", add_newline=false
if (num_retries > max_retries)
- fail("Unable to #{desc}")
+ @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
#Is semver-ish version a less than semver-ish version b
#@param [String] a A version of the from '\d.\d.\d.*'
#@param [String] b A version of the form '\d.\d.\d.*'