Class: Puppet::Provider::Exec

Inherits:
Puppet::Provider show all
Includes:
Util::Execution
Defined in:
lib/puppet/provider/exec.rb

Constant Summary

Constants included from Util::Execution

Util::Execution::NoOptionsSpecified

Constants inherited from Puppet::Provider

Confine

Constants included from Util

Util::AbsolutePathPosix, Util::AbsolutePathWindows, Util::DEFAULT_POSIX_MODE, Util::DEFAULT_WINDOWS_MODE, Util::RFC_3986_URI_REGEX

Constants included from Util::SymbolicFileMode

Util::SymbolicFileMode::SetGIDBit, Util::SymbolicFileMode::SetUIDBit, Util::SymbolicFileMode::StickyBit, Util::SymbolicFileMode::SymbolicMode, Util::SymbolicFileMode::SymbolicSpecialToBit

Constants included from Util::POSIX

Util::POSIX::LOCALE_ENV_VARS, Util::POSIX::USER_ENV_VARS

Constants included from Util::Docs

Util::Docs::HEADER_LEVELS

Instance Attribute Summary

Attributes inherited from Puppet::Provider

#resource

Attributes included from Util::Docs

#doc, #nodoc

Instance Method Summary collapse

Methods included from Util::Execution

execfail, execpipe, execute, ruby_path

Methods inherited from Puppet::Provider

#<=>, #clear, command, #command, commands, declared_feature?, default?, default_match, defaultfor, execfail, #execfail, execpipe, #execpipe, execute, #execute, fact_match, feature_match, #flush, #get, has_command, #initialize, initvars, #inspect, instances, mk_resource_methods, #name, notdefaultfor, optional_commands, post_resource_eval, prefetch, #set, some_default_match, specificity, supports_parameter?, #to_s

Methods included from Util::Logging

#clear_deprecation_warnings, #debug, #deprecation_warning, #format_exception, #get_deprecation_offender, #log_and_raise, #log_deprecations_to_file, #log_exception, #puppet_deprecation_warning, #send_log, setup_facter_logging!, #warn_once

Methods included from Util

absolute_path?, benchmark, chuser, clear_environment, default_env, deterministic_rand, deterministic_rand_int, exit_on_fail, get_env, get_environment, logmethods, merge_environment, path_to_uri, pretty_backtrace, replace_file, safe_posix_fork, set_env, symbolizehash, thinmark, uri_encode, uri_query_encode, uri_to_path, which, withenv, withumask

Methods included from Util::SymbolicFileMode

#normalize_symbolic_mode, #symbolic_mode_to_int, #valid_symbolic_mode?

Methods included from Util::POSIX

#get_posix_field, #gid, groups_of, #idfield, #methodbyid, #methodbyname, #search_posix_field, #uid

Methods included from Util::Docs

#desc, #dochook, #doctable, #markdown_definitionlist, #markdown_header, #nodoc?, #pad, scrub

Methods included from Confiner

#confine, #confine_collection, #suitable?

Methods included from Util::Warnings

clear_warnings, debug_once, maybe_log, notice_once, warnonce

Methods included from Util::Errors

#adderrorcontext, #devfail, #error_context, error_location, error_location_with_space, error_location_with_unknowns, #exceptwrap, #fail

Constructor Details

This class inherits a constructor from Puppet::Provider

Instance Method Details

#environmentObject


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/puppet/provider/exec.rb', line 7

def environment
  env = {}

  if (path = resource[:path])
    env[:PATH] = path.join(File::PATH_SEPARATOR)
  end

  return env unless (envlist = resource[:environment])

  envlist = [envlist] unless envlist.is_a? Array
  envlist.each do |setting|
    unless (match = /^(\w+)=((.|\n)*)$/.match(setting))
      warning _("Cannot understand environment setting %{setting}") % { setting: setting.inspect }
      next
    end
    var = match[1]
    value = match[2]

    if env.include?(var) || env.include?(var.to_sym)
      warning _("Overriding environment setting '%{var}' with '%{value}'") % { var: var, value: value }
    end

    if value.nil? || value.empty?
      msg = _("Empty environment setting '%{var}'") % {var: var}
      Puppet.warn_once('undefined_variables', "empty_env_var_#{var}", msg, resource.file, resource.line)
    end

    env[var] = value
  end

  env
end

#extractexe(command) ⇒ Object


86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/puppet/provider/exec.rb', line 86

def extractexe(command)
  if command.is_a? Array
    command.first
  else
    match = /^"([^"]+)"|^'([^']+)'/.match(command)
    if match
      # extract whichever of the two sides matched the content.
      match[1] or match[2]
    else
      command.split(/ /)[0]
    end
  end
end

#run(command, check = false) ⇒ Object


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/puppet/provider/exec.rb', line 40

def run(command, check = false)
  output = nil
  sensitive = resource.parameters[:command].sensitive

  checkexe(command)

  debug "Executing#{check ? " check": ""} '#{sensitive ? '[redacted]' : command}'"

  # Ruby 2.1 and later interrupt execution in a way that bypasses error
  # handling by default. Passing Timeout::Error causes an exception to be
  # raised that can be rescued inside of the block by cleanup routines.
  #
  # This is backwards compatible all the way to Ruby 1.8.7.
  Timeout::timeout(resource[:timeout], Timeout::Error) do
    cwd = resource[:cwd]
    # It's ok if cwd is nil. In that case Puppet::Util::Execution.execute() simply will not attempt to
    # change the working directory, which is exactly the right behavior when no cwd parameter is
    # expressed on the resource.  Moreover, attempting to change to the directory that is already
    # the working directory can fail under some circumstances, so avoiding the directory change attempt
    # is preferable to defaulting cwd to that directory.

    # note that we are passing "false" for the "override_locale" parameter, which ensures that the user's
    # default/system locale will be respected.  Callers may override this behavior by setting locale-related
    # environment variables (LANG, LC_ALL, etc.) in their 'environment' configuration.
    output = Puppet::Util::Execution.execute(
      command,
      :failonfail => false,
      :combine => true,
      :cwd => cwd,
      :uid => resource[:user], :gid => resource[:group],
      :override_locale => false,
      :custom_environment => environment(),
      :sensitive => sensitive
    )
  end
  # The shell returns 127 if the command is missing.
  if output.exitstatus == 127
    raise ArgumentError, output
  end

  # Return output twice as processstatus was returned before, but only exitstatus was ever called.
  # Output has the exitstatus on it so it is returned instead. This is here twice as changing this
  #  would result in a change to the underlying API.
  return output, output
end

#validatecmd(command) ⇒ Object


100
101
102
103
104
# File 'lib/puppet/provider/exec.rb', line 100

def validatecmd(command)
  exe = extractexe(command)
  # if we're not fully qualified, require a path
  self.fail _("'%{exe}' is not qualified and no path was specified. Please qualify the command or specify a path.") % { exe: exe } if !absolute_path?(exe) and resource[:path].nil?
end