diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-04-20 19:38:48 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-04-20 19:38:48 +0000 |
commit | d91b7df7befbd9e7877c97c2266b94864d55440f (patch) | |
tree | 94af7888852c643096d1c5fb2efd1b21da1152c9 /lib | |
parent | a9b67cce5ad2a22e916d20b39363b6c2c182e923 (diff) | |
download | puppet-d91b7df7befbd9e7877c97c2266b94864d55440f.tar.gz puppet-d91b7df7befbd9e7877c97c2266b94864d55440f.tar.xz puppet-d91b7df7befbd9e7877c97c2266b94864d55440f.zip |
Added a list class method to just about all types, and it seems to actually work for everyone. Now just to add a list method to the pelement server.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1125 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/puppet/filetype.rb | 10 | ||||
-rwxr-xr-x | lib/puppet/server/pelement.rb | 7 | ||||
-rw-r--r-- | lib/puppet/type.rb | 6 | ||||
-rwxr-xr-x | lib/puppet/type/cron.rb | 46 | ||||
-rwxr-xr-x | lib/puppet/type/exec.rb | 13 | ||||
-rwxr-xr-x | lib/puppet/type/group.rb | 2 | ||||
-rwxr-xr-x | lib/puppet/type/nameservice.rb | 21 | ||||
-rw-r--r-- | lib/puppet/type/package.rb | 10 | ||||
-rwxr-xr-x | lib/puppet/type/parsedtype.rb | 2 | ||||
-rw-r--r-- | lib/puppet/type/pfile.rb | 28 | ||||
-rwxr-xr-x | lib/puppet/type/pfile/checksum.rb | 15 | ||||
-rwxr-xr-x | lib/puppet/type/pfile/content.rb | 7 | ||||
-rw-r--r-- | lib/puppet/type/pfile/target.rb | 13 | ||||
-rwxr-xr-x | lib/puppet/type/schedule.rb | 2 | ||||
-rw-r--r-- | lib/puppet/type/service.rb | 142 | ||||
-rwxr-xr-x | lib/puppet/type/service/debian.rb | 2 | ||||
-rwxr-xr-x | lib/puppet/type/service/init.rb | 54 | ||||
-rwxr-xr-x | lib/puppet/type/tidy.rb | 4 | ||||
-rwxr-xr-x | lib/puppet/type/user.rb | 4 |
19 files changed, 297 insertions, 91 deletions
diff --git a/lib/puppet/filetype.rb b/lib/puppet/filetype.rb index 9054fddbe..8a1f13ec0 100755 --- a/lib/puppet/filetype.rb +++ b/lib/puppet/filetype.rb @@ -119,19 +119,19 @@ module Puppet # Read the file. def read - Puppet.info "Reading %s" % @path + Puppet.info "Reading %s from RAM" % @path @text end # Remove the file. def remove - Puppet.info "Removing %s" % @path + Puppet.info "Removing %s from RAM" % @path @text = "" end # Overwrite the file. def write(text) - Puppet.info "Writing %s" % @path + Puppet.info "Writing %s to RAM" % @path @text = text end end @@ -156,7 +156,9 @@ module Puppet raise Puppet::Error, "Could not retrieve user %s" % user end - @path = uid + # We have to have the user name, not the uid, because some + # systems *cough*linux*cough* require it that way + @path = user end # Read a specific @path's cron tab. diff --git a/lib/puppet/server/pelement.rb b/lib/puppet/server/pelement.rb index 791576666..660954942 100755 --- a/lib/puppet/server/pelement.rb +++ b/lib/puppet/server/pelement.rb @@ -44,6 +44,13 @@ class Server::PElementServer end end + # And get rid of any attributes that are nil + trans.each do |attr, value| + if value.nil? + trans.delete(attr) + end + end + if @local return trans else diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 93d0604bb..e28888833 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -1837,9 +1837,11 @@ class Type < Puppet::Element states.each { |state| unless state.insync? - self.debug("%s is not in sync: %s vs %s" % - [state, state.is.inspect, state.should.inspect]) + #state.debug("Not in sync: %s vs %s" % + # [state.is.inspect, state.should.inspect]) insync = false + #else + # state.debug("In sync") end } diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index 978901a98..3351e47b7 100755 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -90,7 +90,7 @@ module Puppet end def should_to_s - if @should.empty? + if ! defined? @should or @should.empty? return "*" else return @should.join(",") @@ -204,20 +204,20 @@ module Puppet The user defaults to whomever Puppet is running as." - defaultto Process.uid - - validate do |user| - require 'etc' - - begin - parent.uid = Puppet::Util.uid(user) - #obj = Etc.getpwnam(user) - rescue ArgumentError - self.fail "User %s not found" % user - end - - user - end + defaultto { ENV["USER"] } + +# validate do |user| +# require 'etc' +# +# begin +# parent.uid = Puppet::Util.uid(user) +# #obj = Etc.getpwnam(user) +# rescue ArgumentError +# self.fail "User %s not found" % user +# end +# +# user +# end end @doc = "Installs and manages cron jobs. All fields except the command @@ -314,6 +314,15 @@ module Puppet end end + def self.list + # Look for cron jobs for each user + Puppet::Type.type(:user).list.each { |user| + self.retrieve(user.name) + } + + self.collect { |c| c } + end + # Parse a user's cron job into individual cron objects. # # Autogenerates names for any jobs that don't already have one; these @@ -400,6 +409,13 @@ module Puppet # method. Returns nil if there was no cron job; else, returns the # number of cron instances found. def self.retrieve(user) + # First make sure the user exists + begin + Puppet::Util.uid(user) + rescue ArgumentError + raise Puppet::Error, "User %s not found" % user + end + @tabs[user] ||= @filetype.new(user) text = @tabs[user].read if $? != 0 diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb index cf16fd0db..51133297f 100755 --- a/lib/puppet/type/exec.rb +++ b/lib/puppet/type/exec.rb @@ -418,10 +418,11 @@ module Puppet tmp = [tmp] unless tmp.is_a? Array tmp.each do |line| - # And search the command line for files, adding any we find. This - # will also catch the command itself if it's fully qualified. It might - # not be a bad idea to add unqualified files, but, well, that's a - # bit more annoying to do. + # And search the command line for files, adding any we + # find. This will also catch the command itself if it's + # fully qualified. It might not be a bad idea to add + # unqualified files, but, well, that's a bit more annoying + # to do. reqs += line.scan(%r{(#{File::SEPARATOR}\S+)}) end } @@ -432,6 +433,10 @@ module Puppet reqs end + def self.list + self.collect { |i| i } + end + # Verify that we pass all of the checks. def check self.class.checks.each { |check| diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb index 5b54cc708..008645f5c 100755 --- a/lib/puppet/type/group.rb +++ b/lib/puppet/type/group.rb @@ -172,7 +172,7 @@ module Puppet end # List all groups - def self.list + def self.listbyname groups = [] while ent = Etc.getgrent groups << ent.name diff --git a/lib/puppet/type/nameservice.rb b/lib/puppet/type/nameservice.rb index c9106a532..df0c4b139 100755 --- a/lib/puppet/type/nameservice.rb +++ b/lib/puppet/type/nameservice.rb @@ -11,6 +11,27 @@ class Type # netinfo types if that were the case. attr_accessor :netinfodir + # Create an instance for every object that exists on the machine + def list + listbyname.collect do |name| + obj = nil + check = @states.collect { |st| st.name } + if obj = self[name] + obj[:check] = check + else + # unless it exists, create it as an unmanaged object + obj = self.create(:name => name, :check => check) + end + + next unless obj # In case there was an error somewhere + + obj.retrieve + + + obj + end + end + def newstate(*args, &block) s = super(*args, &block) diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb index 8da557aa7..8578d05f0 100644 --- a/lib/puppet/type/package.rb +++ b/lib/puppet/type/package.rb @@ -60,7 +60,12 @@ module Puppet mod.module_eval(&block) - mod.send(:module_function, :list) + # It's at least conceivable that a module would not define this method + # "module_function" makes the :list method private, so if the parent + # method also called module_function, then it's already private + if mod.public_method_defined? :list or mod.private_method_defined? :list + mod.send(:module_function, :list) + end # Add it to our list @pkgtypes[name] = mod @@ -465,11 +470,12 @@ module Puppet return object end + # List all package instances def self.list pkgtype(default).list() self.collect do |pkg| - pkg.name + pkg end end diff --git a/lib/puppet/type/parsedtype.rb b/lib/puppet/type/parsedtype.rb index 7812d1fb4..5c8a46bb6 100755 --- a/lib/puppet/type/parsedtype.rb +++ b/lib/puppet/type/parsedtype.rb @@ -211,7 +211,7 @@ module Puppet retrieve self.collect do |obj| - obj.name + obj end end diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb index 69246f8a8..a6b8c5a1f 100644 --- a/lib/puppet/type/pfile.rb +++ b/lib/puppet/type/pfile.rb @@ -70,7 +70,7 @@ module Puppet case value when false, "false": false - when true, "true": + when true, "true", ".puppet-bak": ".puppet-bak" when String: # We can't depend on looking this up right now, @@ -157,6 +157,29 @@ module Puppet end end + # List files, but only one level deep. + def self.list(base = "/") + unless FileTest.directory?(base) + return [] + end + + files = [] + Dir.entries(base).reject { |e| + e == "." or e == ".." + }.each do |name| + path = File.join(base, name) + if obj = self[path] + obj[:check] = :all + files << obj + else + files << self.create( + :name => path, :check => :all + ) + end + end + files + end + @depthfirst = false @@ -682,6 +705,7 @@ module Puppet # stat object accordingly (mostly by testing the 'ftype' value). def stat(refresh = false) method = :stat + # Files are the only types that support links if self.class.name == :file and self[:links] != :follow method = :lstat @@ -826,11 +850,11 @@ module Puppet require 'puppet/type/pfile/checksum' require 'puppet/type/pfile/content' # can create the file require 'puppet/type/pfile/source' # can create the file + require 'puppet/type/pfile/target' require 'puppet/type/pfile/ensure' # can create the file require 'puppet/type/pfile/uid' require 'puppet/type/pfile/group' require 'puppet/type/pfile/mode' - require 'puppet/type/pfile/target' require 'puppet/type/pfile/type' end # $Id$ diff --git a/lib/puppet/type/pfile/checksum.rb b/lib/puppet/type/pfile/checksum.rb index c1f00e5b8..54ab3d860 100755 --- a/lib/puppet/type/pfile/checksum.rb +++ b/lib/puppet/type/pfile/checksum.rb @@ -39,16 +39,15 @@ module Puppet @checktypes = [] end - if FileTest.directory?(@parent[:path]) - value = "time" - end - - if value =~ /^\{(\w+)\}(.+)$/ @checktypes << $1 - return $2 + #return $2 + return value else - value = super + if FileTest.directory?(@parent[:path]) + value = "time" + end + value = super(value) @checktypes << value return getcachedsum() end @@ -168,6 +167,7 @@ module Puppet end return "{#{checktype}}" + sum.to_s + #return sum.to_s end # At this point, we don't actually modify the system, we modify @@ -228,6 +228,7 @@ module Puppet if stat.ftype == "link" and @parent[:links] != :follow self.debug "Not checksumming symlink" + #@parent.delete(:checksum) self.is = self.should return end diff --git a/lib/puppet/type/pfile/content.rb b/lib/puppet/type/pfile/content.rb index 2fd28c536..a91e407cc 100755 --- a/lib/puppet/type/pfile/content.rb +++ b/lib/puppet/type/pfile/content.rb @@ -34,11 +34,16 @@ module Puppet end if stat.ftype == "link" and @parent[:links] == :ignore - self.info "Not changing the content of symlink" self.is = self.should return end + # Don't even try to manage the content on directories + if stat.ftype == "directory" and @parent[:links] == :ignore + @parent.delete(:content) + return + end + begin @is = File.read(@parent[:path]) rescue => detail diff --git a/lib/puppet/type/pfile/target.rb b/lib/puppet/type/pfile/target.rb index 426c52b6d..b354e6650 100644 --- a/lib/puppet/type/pfile/target.rb +++ b/lib/puppet/type/pfile/target.rb @@ -48,12 +48,17 @@ module Puppet else if stat = @parent.stat # If we're just checking the value - if should = self.should and - should != :notlink + if (should = self.should) and + (should != :notlink) and File.exists?(should) and - tstat = File.lstat(should) and - tstat.ftype == "directory" and + (tstat = File.lstat(should)) and + (tstat.ftype == "directory") and @parent.recurse? + unless @parent.recurse? + raise "wtf?" + end + warning "Changing ensure to directory; recurse is %s but %s" % + [@parent[:recurse].inspect, @parent.recurse?] @parent[:ensure] = :directory @is = should @linkmaker = true diff --git a/lib/puppet/type/schedule.rb b/lib/puppet/type/schedule.rb index e09200929..a62f7f4c8 100755 --- a/lib/puppet/type/schedule.rb +++ b/lib/puppet/type/schedule.rb @@ -296,7 +296,7 @@ module Puppet end def self.list - self.collect do |obj| obj.name end + self.collect do |obj| obj end end def self.mkdefaultschedules diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb index 09bd4f659..59ae833c7 100644 --- a/lib/puppet/type/service.rb +++ b/lib/puppet/type/service.rb @@ -109,7 +109,6 @@ module Puppet def retrieve self.is = @parent.status - self.debug "Current status is '%s'" % self.is end def sync @@ -168,11 +167,14 @@ module Puppet # representing the module. munge do |type| if type.is_a?(String) - type = @parent.class.svctype(type.intern) + type = type.intern end - Puppet.debug "Service type is %s" % type.name - @parent.extend(type) + if type.is_a?(Symbol) + typeklass = @parent.class.svctype(type) + end + @parent.extend(typeklass) + # Return the name, not the object return type end end @@ -254,7 +256,7 @@ module Puppet newparam(:status) do desc "Specify a *status* command manually. If left unspecified, the status method will be determined - automatically, usually by looking for the service int he + automatically, usually by looking for the service in the process table." end @@ -262,6 +264,79 @@ module Puppet desc "Specify a *stop* command manually." end + # Retrieve the default type for the current platform. + def self.defaulttype + unless defined? @defsvctype + @defsvctype = nil + os = Facter["operatingsystem"].value + case os + when "Debian": + @defsvctype = self.svctype(:debian) + when "Solaris": + release = Facter["operatingsystemrelease"].value + if release.sub(/5\./,'').to_i < 10 + @defsvctype = self.svctype(:init) + else + @defsvctype = self.svctype(:smf) + end + when "CentOS", "RedHat", "Fedora": + @defsvctype = self.svctype(:redhat) + else + if Facter["kernel"] == "Linux" + Puppet.notice "Using service type %s for %s" % + ["init", Facter["operatingsystem"].value] + @defsvctype = self.svctype(:init) + end + end + + unless @defsvctype + Puppet.info "Defaulting to base service type" + @defsvctype = self.svctype(:base) + end + end + + unless defined? @notifieddefault + Puppet.debug "Default service type is %s" % @defsvctype.name + @notifieddefault = true + end + + return @defsvctype.name + end + + # List all available services + def self.list + # First see if the default service type can list services for us + deftype = svctype(defaulttype()) + + names = [] + if deftype.respond_to? :list + deftype.list(deftype.name) + else + Puppet.debug "Type %s does not respond to list" % deftype.name + end + + self.collect { |s| s } + end + + # Add a new path to our list of paths that services could be in. + def self.newpath(type, path) + type = type.intern if type.is_a? String + @paths ||= {} + @paths[type] ||= [] + + unless @paths[type].include? path + @paths[type] << path + end + end + + def self.paths(type) + type = type.intern if type.is_a? String + @paths ||= {} + @paths[type] ||= [] + + @paths[type].dup + end + # Create new subtypes of service management. def self.newsvctype(name, parent = nil, &block) if parent @@ -299,6 +374,27 @@ module Puppet mod.module_eval(&block) + #unless mod.respond_to? :list + # Puppet.debug "Service type %s has no list method" % name + #end + + # "module_function" makes the :list method private, so if the parent + # method also called module_function, then it's already private + if mod.public_method_defined? :list or mod.private_method_defined? :list + mod.send(:module_function, :list) + end + + # mark it as a valid type + unless defined? @typeparam + @typeparam = @parameters.find { |p| p.name == :type } + + unless @typeparam + raise Puppet::DevError, "Could not package type parameter" + end + end + @typeparam.newvalues(name) + + # And add it to our list of types @modules ||= Hash.new do |hash, key| if key.is_a?(String) key = key.intern @@ -334,42 +430,6 @@ module Puppet @modules[name] end - # Retrieve the default type for the current platform. - def self.defaulttype - unless defined? @defsvctype - @defsvctype = nil - os = Facter["operatingsystem"].value - case os - when "Debian": - @defsvctype = self.svctype(:debian) - when "Solaris": - release = Facter["operatingsystemrelease"].value - if release.sub(/5\./,'').to_i < 10 - @defsvctype = self.svctype(:init) - else - @defsvctype = self.svctype(:smf) - end - when "CentOS", "RedHat", "Fedora": - @defsvctype = self.svctype(:redhat) - else - if Facter["kernel"] == "Linux" - Puppet.notice "Using service type %s for %s" % - ["init", Facter["operatingsystem"].value] - @defsvctype = self.svctype(:init) - end - end - - unless @defsvctype - Puppet.info "Defaulting to base service type" - @defsvctype = self.svctype(:base) - end - end - - Puppet.debug "Default service type is %s" % @defsvctype.name - - return @defsvctype - end - # Execute a command. Basically just makes sure it exits with a 0 # code. def execute(type, cmd) diff --git a/lib/puppet/type/service/debian.rb b/lib/puppet/type/service/debian.rb index c7996c423..b55dbf276 100755 --- a/lib/puppet/type/service/debian.rb +++ b/lib/puppet/type/service/debian.rb @@ -17,7 +17,7 @@ Puppet.type(:service).newsvctype(:debian, :init) do def enabled? cmd = %{update-rc.d -n -f #{self[:name]} remove 2>&1} - self.debug "Executing '%s'" % cmd + self.debug "Executing 'enabled' test: '%s'" % cmd output = %x{#{cmd}} unless $? == 0 raise Puppet::Error, "Could not check %s: %s" % diff --git a/lib/puppet/type/service/init.rb b/lib/puppet/type/service/init.rb index 61c2a2c48..4a9f52a31 100755 --- a/lib/puppet/type/service/init.rb +++ b/lib/puppet/type/service/init.rb @@ -1,18 +1,64 @@ # The standard init-based service type. Many other service types are # customizations of this module. Puppet.type(:service).newsvctype(:init) do - - # Set the default init directory. - Puppet.type(:service).attrclass(:path).defaultto do + def self.defpath case Facter["operatingsystem"].value when "FreeBSD": "/etc/rc.d" else - #@defaultrc = "/etc/rc%s.d" "/etc/init.d" end end + Puppet.type(:service).newpath(:init, defpath()) + + # Set the default init directory. + Puppet.type(:service).attrclass(:path).defaultto defpath() + + # List all services of this type. This has to be an instance method + # so that it's inherited by submodules. + def list(name) + # We need to find all paths specified for our type or any parent types + paths = Puppet.type(:service).paths(name) + + # Now see if there are any included modules + included_modules.each do |mod| + next unless mod.respond_to? :name + + mname = mod.name + + if mpaths = Puppet.type(:service).paths(mname) and ! mpaths.empty? + paths += mpaths + end + end + + paths.each do |path| + unless FileTest.directory?(path) + Puppet.notice "Service path %s does not exist" % path + next + end + + check = [:ensure] + + if public_method_defined? :enabled? + check << :enable + end + + Dir.entries(path).reject { |e| + fullpath = File.join(path, e) + e =~ /^\./ or ! FileTest.executable?(fullpath) + }.each do |name| + if obj = Puppet::Type.type(:service)[name] + obj[:check] = check + else + Puppet::Type.type(:service).create( + :name => name, :check => check, :path => path + ) + end + end + end + end + # Mark that our init script supports 'status' commands. def hasstatus=(value) case value diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb index 144141c56..0636e3fac 100755 --- a/lib/puppet/type/tidy.rb +++ b/lib/puppet/type/tidy.rb @@ -157,6 +157,10 @@ module Puppet validate do end + def self.list + self.collect { |t| t } + end + @depthfirst = true def initialize(hash) diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index d31a0fee6..d1d2a6896 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -388,8 +388,10 @@ module Puppet end end - def self.list + # List all found users + def self.listbyname users = [] + Etc.setpwent while ent = Etc.getpwent users << ent.name end |