summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-09-05 01:41:09 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-09-05 01:41:09 +0000
commit8f39318ce46148c3bd483d790c965f277a4eb1c9 (patch)
tree2a5ed0c59c9cc1d42c40808ca313d41dc6e7988c /lib
parentb43b489073beb01da9b4de501d3c019326d97961 (diff)
downloadpuppet-8f39318ce46148c3bd483d790c965f277a4eb1c9.tar.gz
puppet-8f39318ce46148c3bd483d790c965f277a4eb1c9.tar.xz
puppet-8f39318ce46148c3bd483d790c965f277a4eb1c9.zip
Committing a small amount of work in cron. I have decided that this is too last-minute, and not important enough to hold up the release. I want to get this refactoring done, but it is clearly not the 4 hour job I hoped it was. It will have to be in another release, I think.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1553 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
-rwxr-xr-xlib/puppet/provider/cron/parsed.rb161
-rwxr-xr-xlib/puppet/provider/parsedfile.rb8
-rwxr-xr-xlib/puppet/type/cron.rb9
3 files changed, 169 insertions, 9 deletions
diff --git a/lib/puppet/provider/cron/parsed.rb b/lib/puppet/provider/cron/parsed.rb
new file mode 100755
index 000000000..1626162bd
--- /dev/null
+++ b/lib/puppet/provider/cron/parsed.rb
@@ -0,0 +1,161 @@
+require 'puppet/provider/parsedfile'
+
+Puppet::Type.type(:cron).provide :parsed, :parent => Puppet::Provider::ParsedFile do
+ @fields = [:minute, :hour, :monthday, :month, :weekday, :command]
+
+ # XXX This should be switched to use providers or something similar on
+ # the backend.
+ def self.defaulttype
+ case Facter["operatingsystem"].value
+ when "Solaris":
+ return Puppet::FileType.filetype(:suntab)
+ else
+ return Puppet::FileType.filetype(:crontab)
+ end
+ end
+
+ self.filetype = self.defaulttype()
+
+ # We have to maintain separate file objects for every user, unfortunately.
+ def self.filetype(user)
+ @tabs ||= {}
+ @tabs[user] ||= @filetype.new(user)
+
+ @tabs[user]
+ end
+
+ # Parse a user's cron job into individual cron objects.
+ #
+ # Autogenerates names for any jobs that don't already have one; these
+ # names will get written back to the file.
+ #
+ # This method also stores existing comments, and it stores all cron
+ # jobs in order, mostly so that comments are retained in the order
+ # they were written and in proximity to the same jobs.
+ def self.parse(user, text)
+ count = 0
+
+ envs = []
+ instances = []
+ text.chomp.split("\n").each { |line|
+ hash = {}
+ case line
+ when /^# Puppet Name: (.+)$/
+ hash[:name] = $1
+ next
+ when /^#/:
+ # add other comments to the list as they are
+ instances << line
+ next
+ when /^\s*(\w+)\s*=\s*(.+)\s*$/:
+ # Match env settings.
+ if hash[:name]
+ envs << line
+ else
+ instances << line
+ end
+ next
+ when /^@(\w+)\s+(.+)/ # FreeBSD special cron crap
+ fields().each do |field|
+ next if field == :command
+ hash[field] = :absent
+ end
+ hash[:special] = $1
+ hash[:command] = $2
+ else
+ if match = /^(\S+) (\S+) (\S+) (\S+) (\S+) (.+)$/.match(line)
+ fields().zip(match.captures).each { |param, value|
+ if value == "*"
+ hash[param] = [:absent]
+ else
+ if param == :command
+ hash[param] = [value]
+ else
+ # We always want the 'is' value to be an
+ # array
+ hash[param] = value.split(",")
+ end
+ end
+ }
+ else
+ # Don't fail on unmatched lines, just warn on them
+ # and skip them.
+ Puppet.warning "Could not match '%s'" % line
+ next
+ end
+ end
+
+ unless envs.empty?
+ hash[:environment] = envs
+ end
+
+ hash[:user] = user
+
+ instances << hash
+
+ envs.clear
+ count += 1
+ }
+
+ return instances
+ end
+
+ def self.retrieve(user)
+ text = fileobj(user).read
+ if text.nil? or text == ""
+ return []
+ else
+ self.parse(user, text)
+ end
+ end
+
+ # Another override. This will pretty much only ever have one user's instances,
+ def self.store(instances)
+ instances.find_all { |i| i.is_a? Hash }.collect { |i| i[:user] }.each do |user|
+ fileobj(user).write(self.to_file(instances))
+ end
+ end
+
+ # Convert the current object a cron-style string. Adds the cron name
+ # as a comment above the cron job, in the form '# Puppet Name: <name>'.
+ def self.to_record(hash)
+ hash = {}
+
+ str = ""
+
+ str = "# Puppet Name: %s\n" % hash[:name]
+
+ if @states.include?(:environment) and
+ @states[:environment].should != :absent
+ envs = @states[:environment].should
+ unless envs.is_a? Array
+ envs = [envs]
+ end
+
+ envs.each do |line| str += (line + "\n") end
+ end
+
+ line = nil
+ if special = hash[:special]
+ line = str + "@%s %s" %
+ [special, hash[:command]]
+ else
+ line = str + self.class.fields.collect { |f|
+ if hash[f] and hash[f] != :absent
+ hash[f]
+ else
+ "*"
+ end
+ }.join(" ")
+ end
+
+ return line
+ end
+
+ # Override the mechanism for retrieving instances, because we're user-specific.
+ def allinstances
+ self.class.retrieve(@model[:user])
+ end
+end
+
+# $Id$
diff --git a/lib/puppet/provider/parsedfile.rb b/lib/puppet/provider/parsedfile.rb
index 53c49ef5e..f690c03a4 100755
--- a/lib/puppet/provider/parsedfile.rb
+++ b/lib/puppet/provider/parsedfile.rb
@@ -107,6 +107,12 @@ class Puppet::Provider::ParsedFile < Puppet::Provider
end
end
+ # A Simple wrapper method that subclasses can override, so there's more control
+ # over how instances are retrieved.
+ def allinstances
+ self.class.retrieve
+ end
+
def clear
super
@instances = nil
@@ -114,7 +120,7 @@ class Puppet::Provider::ParsedFile < Puppet::Provider
# Return a hash that maps to our info, if possible.
def hash
- @instances = self.class.retrieve
+ @instances = allinstances()
if @instances and h = @instances.find do |o|
o.is_a? Hash and o[:name] == @model[:name]
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb
index 03ac24d29..a911dac04 100755
--- a/lib/puppet/type/cron.rb
+++ b/lib/puppet/type/cron.rb
@@ -1,7 +1,3 @@
-require 'etc'
-require 'facter'
-require 'puppet/type/state'
-require 'puppet/filetype'
require 'puppet/type/parsedtype'
module Puppet
@@ -9,7 +5,7 @@ module Puppet
# as parameters, with the 'command' as the single state. Also requires a
# completely symbolic 'name' paremeter, which gets written to the file
# and is used to manage the job.
- newtype(:cron) do
+ newtype(:cron, Puppet::Type::ParsedType) do
# A base class for all of the Cron parameters, since they all have
# similar argument checking going on. We're stealing the base class
@@ -337,9 +333,6 @@ module Puppet
}
"
- @instances = {}
- @tabs = {}
-
class << self
attr_accessor :filetype