diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/provider.rb | 19 | ||||
-rw-r--r-- | lib/puppet/provider/nameservice.rb | 3 | ||||
-rw-r--r-- | lib/puppet/provider/nameservice/netinfo.rb | 17 | ||||
-rwxr-xr-x | lib/puppet/provider/package/apple.rb | 2 | ||||
-rwxr-xr-x | lib/puppet/provider/package/darwinport.rb | 1 | ||||
-rwxr-xr-x | lib/puppet/provider/package/gem.rb | 20 | ||||
-rw-r--r-- | lib/puppet/provider/user/netinfo.rb | 21 | ||||
-rw-r--r-- | lib/puppet/suidmanager.rb | 43 | ||||
-rw-r--r-- | lib/puppet/transaction.rb | 1 | ||||
-rwxr-xr-x | lib/puppet/type/exec.rb | 4 | ||||
-rwxr-xr-x | lib/puppet/type/host.rb | 15 | ||||
-rwxr-xr-x | lib/puppet/type/user.rb | 6 | ||||
-rw-r--r-- | lib/puppet/util.rb | 54 |
13 files changed, 131 insertions, 75 deletions
diff --git a/lib/puppet/provider.rb b/lib/puppet/provider.rb index a5890f131..3a31a89a3 100644 --- a/lib/puppet/provider.rb +++ b/lib/puppet/provider.rb @@ -1,6 +1,7 @@ # The container class for implementations. class Puppet::Provider include Puppet::Util + include Puppet::Util::Errors Puppet::Util.logmethods(self, true) @@ -47,22 +48,24 @@ class Puppet::Provider @commands[name] = path confine :exists => path - # Now define a method for that package - #unless method_defined? name + # Now define a method for that command unless metaclass.method_defined? name - meta_def(name) do |args| - if args - cmd = command(name) + " " + args + meta_def(name) do |*args| + if args.empty? + cmd = [command(name)] else - cmd = command(name) + cmd = [command(name)] + args end # This might throw an ExecutionFailure, but the system above # will catch it, if so. return execute(cmd) end + + # And then define an instance method that just calls the class method. + # We need both, so both instances and classes can easily run the commands. unless method_defined? name - define_method(name) do |args| - self.class.send(name, args) + define_method(name) do |*args| + self.class.send(name, *args) end end end diff --git a/lib/puppet/provider/nameservice.rb b/lib/puppet/provider/nameservice.rb index d33ab1936..b10ac34ad 100644 --- a/lib/puppet/provider/nameservice.rb +++ b/lib/puppet/provider/nameservice.rb @@ -307,6 +307,9 @@ class Puppet::Provider::NameService < Puppet::Provider def set(param, value) #self.class.validate(param, value) cmd = modifycmd(param, value) + unless cmd.is_a?(Array) + raise Puppet::DevError, "Nameservice command must be an array" + end begin execute(cmd) rescue Puppet::ExecutionFailure => detail diff --git a/lib/puppet/provider/nameservice/netinfo.rb b/lib/puppet/provider/nameservice/netinfo.rb index 313b41753..54f2e8c00 100644 --- a/lib/puppet/provider/nameservice/netinfo.rb +++ b/lib/puppet/provider/nameservice/netinfo.rb @@ -12,7 +12,7 @@ class NetInfo < Puppet::Provider::NameService # Attempt to flush the database, but this doesn't seem to work at all. def self.flush begin - output = execute("/usr/sbin/lookupd -flushcache 2>&1") + output = execute(["/usr/sbin/lookupd", "-flushcache"]) rescue Puppet::ExecutionFailure # Don't throw an error; it's just a failed cache flush Puppet.err "Could not flush lookupd cache: %s" % output @@ -89,7 +89,7 @@ class NetInfo < Puppet::Provider::NameService end begin - output = execute(cmd.join(" ")) + output = execute(cmd) rescue Puppet::ExecutionFailure => detail Puppet.err "Failed to call nireport: %s" % detail return nil @@ -111,7 +111,7 @@ class NetInfo < Puppet::Provider::NameService cmd << "/" << "/%s/%s" % [self.class.netinfodir(), @model[:name]] - return cmd.join(" ") + return cmd end def deletecmd @@ -175,14 +175,16 @@ class NetInfo < Puppet::Provider::NameService cmd << "-createprop" << "/" << "/%s/%s" % [self.class.netinfodir, @model[:name]] + value = [value] unless value.is_a?(Array) if key = netinfokey(param) - cmd << key << "'%s'" % value + cmd << key + cmd += value else raise Puppet::DevError, "Could not find netinfokey for state %s" % self.class.name end - cmd.join(" ") + cmd end # Determine the flag to pass to our command. @@ -196,11 +198,10 @@ class NetInfo < Puppet::Provider::NameService end def setuserlist(group, list) - cmd = "#{command(:niutil)} -createprop / /groups/%s users %s" % - [group, list.join(",")] + cmd = [command(:niutil), "-createprop", "/", "/groups/%s" % group, "users", list.join(",")] begin output = execute(cmd) - rescue Puppet::Execution::Failure => detail + rescue Puppet::ExecutionFailure => detail raise Puppet::Error, "Failed to set user list on %s: %s" % [group, detail] end diff --git a/lib/puppet/provider/package/apple.rb b/lib/puppet/provider/package/apple.rb index 4238447a3..7f1c93e5b 100755 --- a/lib/puppet/provider/package/apple.rb +++ b/lib/puppet/provider/package/apple.rb @@ -44,7 +44,7 @@ Puppet::Type.type(:package).provide :apple do self.fail "Mac OS X packages must specify a package source" end - installer "-pkg #{source} -target /" + installer "-pkg", source, "-target", "/" end end diff --git a/lib/puppet/provider/package/darwinport.rb b/lib/puppet/provider/package/darwinport.rb index 43e9bce5b..729371db5 100755 --- a/lib/puppet/provider/package/darwinport.rb +++ b/lib/puppet/provider/package/darwinport.rb @@ -21,6 +21,7 @@ Puppet::Type.type(:package).provide :darwinport do } hash.delete :location + hash[:provider] = self.name yield hash.dup else raise Puppet::DevError, diff --git a/lib/puppet/provider/package/gem.rb b/lib/puppet/provider/package/gem.rb index 0fb55c67c..24f997613 100755 --- a/lib/puppet/provider/package/gem.rb +++ b/lib/puppet/provider/package/gem.rb @@ -6,16 +6,16 @@ Puppet::Type.type(:package).provide :gem do commands :gem => "gem" def self.gemlist(hash) - command = "#{command(:gem)} list " + command = [command(:gem), "list"] if hash[:local] - command += "--local " + command << "--local" else - command += "--remote " + command << "--remote" end if name = hash[:justme] - command += name + command << name end begin @@ -61,17 +61,17 @@ Puppet::Type.type(:package).provide :gem do end def install(useversion = true) - command = "install " + command = ["install"] if (! @model.should(:ensure).is_a? Symbol) and useversion - command += "-v %s " % @model.should(:ensure) + command << "-v" << @model.should(:ensure) end if source = @model[:source] - command += source + command << source else - command += @model[:name] + command << @model[:name] end - gem command + gem(*command) end def latest @@ -86,7 +86,7 @@ Puppet::Type.type(:package).provide :gem do end def uninstall - gem "uninstall -x -a #{@model[:name]}" + gem "uninstall", "-x", "-a", @model[:name] end def update diff --git a/lib/puppet/provider/user/netinfo.rb b/lib/puppet/provider/user/netinfo.rb index 79469fa24..6f82d1d34 100644 --- a/lib/puppet/provider/user/netinfo.rb +++ b/lib/puppet/provider/user/netinfo.rb @@ -9,6 +9,13 @@ Puppet::Type.type(:user).provide :netinfo, :parent => Puppet::Provider::NameServ options :comment, :key => "realname" defaultfor :operatingsystem => :darwin + + def gid=(value) + unless value.is_a?(Integer) + raise ArgumentError, "gid= only accepts integers, not %s(%s)" % [value.class, value.inspect] + end + super + end # The list of all groups the user is a member of. Different # user mgmt systems will need to override this method. @@ -71,16 +78,12 @@ Puppet::Type.type(:user).provide :netinfo, :parent => Puppet::Provider::NameServ end end end - - def setuserlist(group, list) - cmd = "#{command(:niutil)} -createprop / /groups/%s users %s" % - [group, list.join(",")] - begin - output = execute(cmd) - rescue Puppet::ExecutionFailure - raise Puppet::Error, - "Failed to set groups: %s" % output + + def uid=(value) + unless value.is_a?(Integer) + raise ArgumentError, "uid= only accepts integers" end + super end end diff --git a/lib/puppet/suidmanager.rb b/lib/puppet/suidmanager.rb index b65b5eb60..659ffaab8 100644 --- a/lib/puppet/suidmanager.rb +++ b/lib/puppet/suidmanager.rb @@ -35,22 +35,12 @@ module Puppet end old_egid = old_euid = nil if new_egid - saved_state_egid = new_egid - new_egid = Puppet::Util.gid(new_egid) - if new_egid == nil - raise Puppet::Error, "Invalid group: %s" % saved_state_egid - end old_egid = self.egid - self.egid = new_egid + self.egid = convert_xid(:gid, new_egid) end if new_euid - saved_state_euid = new_euid - new_euid = Puppet::Util.uid(new_euid) - if new_euid == nil - raise Puppet::Error, "Invalid user: %s" % saved_state_euid - end old_euid = self.euid - self.euid = new_euid + self.euid = convert_xid(:uid, new_euid) end return yield @@ -58,23 +48,24 @@ module Puppet self.euid = old_euid if old_euid self.egid = old_egid if old_egid end + + # Make sure the passed argument is a number. + def convert_xid(type, id) + map = {:gid => :group, :uid => :user} + raise ArgumentError, "Invalid id type %s" % type unless map.include?(type) + ret = Puppet::Util.send(type, id) + if ret == nil + raise Puppet::Error, "Invalid %s: %s" % [map[type], id] + end + return ret + end - module_function :asuser + module_function :asuser, :convert_xid def run_and_capture(command, new_uid=nil, new_gid=nil) output = nil - - asuser(new_uid, new_gid) do - # capture both stdout and stderr unless we are on ruby < 1.8.4 - # NOTE: this would be much better facilitated with a specialized popen() - # (see the test suite for more details.) - if new_uid and (Facter['rubyversion'].value <=> "1.8.4") < 0 - Puppet::Util::Warnings.warnonce "Cannot capture STDERR when running as another user on Ruby < 1.8.4" - output = %x{#{command}} - else - output = %x{#{command} 2>&1} - end - end + + output = Puppet::Util.execute(command, false, new_uid, new_gid) [output, $?.dup] end @@ -89,7 +80,7 @@ module Puppet end status end - + module_function :system end end diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index 59b42f82c..7c7aaa38b 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -506,6 +506,7 @@ class Transaction def skip?(resource) skip = false if ! tagged?(resource) + p resource.tags resource.debug "Not tagged with %s" % tags.join(", ") elsif ! scheduled?(resource) resource.debug "Not scheduled" diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb index c9fa0aa36..44903f40c 100755 --- a/lib/puppet/type/exec.rb +++ b/lib/puppet/type/exec.rb @@ -536,13 +536,13 @@ module Puppet end env[name] = value else - warning "Cannot understand env setting '%s'" % setting + warning "Cannot understand env setting %s" % setting.inspect end end end withenv env do - output, status = Puppet::SUIDManager.run_and_capture(command, self[:user], self[:group]) + output, status = Puppet::SUIDManager.run_and_capture([command], self[:user], self[:group]) # The shell returns 127 if the command is missing. if status.exitstatus == 127 raise ArgumentError, output diff --git a/lib/puppet/type/host.rb b/lib/puppet/type/host.rb index abc0ad30c..d11d1894c 100755 --- a/lib/puppet/type/host.rb +++ b/lib/puppet/type/host.rb @@ -22,9 +22,7 @@ module Puppet # Make sure our "is" value is always an array. def is current = super - unless current.is_a? Array - current = [current] - end + current = [current] unless current.is_a? Array current end @@ -48,7 +46,16 @@ module Puppet def retrieve super - @is = [@is] unless @is.is_a?(Array) + case @is + when String + @is = @is.split(/\s*,\s*/) + when Symbol: + @is = [@is] + when Array + # nothing + else + raise Puppet::DevError, "Invalid @is type %s" % @is.class + end end # We actually want to return the whole array here, not just the first diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index 661d10e4a..e9cd2372e 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -124,6 +124,10 @@ module Puppet newstate(:gid) do desc "The user's primary group. Can be specified numerically or by name." + + def found? + defined? @found and @found + end munge do |gid| method = :getgrgid @@ -157,7 +161,7 @@ module Puppet unless defined? @should return super end - unless defined? @found and @found + unless found? @should = @should.each { |val| next unless val Puppet::Util.gid(val) diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb index 246be2bd0..906184c18 100644 --- a/lib/puppet/util.rb +++ b/lib/puppet/util.rb @@ -267,18 +267,60 @@ module Util end # Execute the desired command, and return the status and output. - def execute(command, failonfail = true) + def execute(command, failonfail = true, uid = nil, gid = nil) + if command.is_a?(Array) + command = command.collect { |i| i.to_s } + str = command.join(" ") + else + raise "Must pass an array" + str = command + end if respond_to? :debug - debug "Executing '%s'" % command + debug "Executing '%s'" % str else - Puppet.debug "Executing '%s'" % command + Puppet.debug "Executing '%s'" % str + end + + if uid + uid = Puppet::SUIDManager.convert_xid(:uid, uid) + end + if gid + gid = Puppet::SUIDManager.convert_xid(:gid, gid) + end + + @@os ||= Facter.value(:operatingsystem) + output = nil + IO.popen("-") do |f| + if f + output = f.read + else + begin + $stderr.close + $stderr = $stdout.dup + if gid + Process.egid = gid + Process.gid = gid unless @@os == "Darwin" + end + if uid + Process.euid = uid + Process.uid = uid unless @@os == "Darwin" + end + if command.is_a?(Array) + system(*command) + else + system(command) + end + exit!($?.exitstatus) + rescue => detail + puts detail.to_s + exit!(1) + end + end end - command += " 2>&1" unless command =~ />/ - output = %x{#{command}} if failonfail unless $? == 0 - raise ExecutionFailure, "Could not execute '%s': %s" % [command, output] + raise ExecutionFailure, "Execution of '%s' returned %s: %s" % [str, $?, output] end end |