summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-09-15 04:48:52 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-09-15 04:48:52 +0000
commit669ae388f2209b3be7af2671579773b2cc24cbfc (patch)
tree7535b20789bd63d12e674fd9513b4f3416a6e4d8 /lib
parentae00500eff131b4088850283b0e848a014f67d8e (diff)
downloadpuppet-669ae388f2209b3be7af2671579773b2cc24cbfc.tar.gz
puppet-669ae388f2209b3be7af2671579773b2cc24cbfc.tar.xz
puppet-669ae388f2209b3be7af2671579773b2cc24cbfc.zip
modifications to eliminate code duplication in state creation, mostly to support cron
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@663 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/statechange.rb54
-rw-r--r--lib/puppet/type.rb76
-rwxr-xr-xlib/puppet/type/cron.rb178
-rw-r--r--lib/puppet/type/state.rb6
4 files changed, 149 insertions, 165 deletions
diff --git a/lib/puppet/statechange.rb b/lib/puppet/statechange.rb
index af066a773..081ef395c 100644
--- a/lib/puppet/statechange.rb
+++ b/lib/puppet/statechange.rb
@@ -41,33 +41,39 @@ module Puppet
end
begin
- event = @state.sync
- @run = true
-
- # default to a simple event type
- if event.nil?
- #event = @state.parent.class.name.id2name + "_changed"
- # they didn't actually change anything
+ events = @state.sync
+ if events.nil?
return nil
- elsif ! event.is_a?(Symbol)
- Puppet.warning "State '%s' returned invalid event '%s'; resetting to default" %
- [@state.class,event]
-
- event = @state.parent.class.name.id2name + "_changed"
end
- # i should maybe include object type, but the event type
- # should basically point to that, right?
- #:state => @state,
- #:object => @state.parent,
- Puppet.notice self.to_s
- return Puppet::Event.new(
- :event => event,
- :change => self,
- :transaction => @transaction,
- :source => @state.parent,
- :message => self.to_s
- )
+ unless events.is_a?(Array)
+ events = [events]
+ end
+ @run = true
+
+ return events.collect { |event|
+ # default to a simple event type
+ if ! event.is_a?(Symbol)
+ Puppet.warning("State '%s' returned invalid event '%s'; resetting to default" %
+ [@state.class,event])
+
+ event = @state.parent.class.name.id2name + "_changed"
+ end
+
+ # i should maybe include object type, but the event type
+ # should basically point to that, right?
+ #:state => @state,
+ #:object => @state.parent,
+ # FIXME this is where loglevel stuff should go
+ Puppet.notice self.to_s
+ Puppet::Event.new(
+ :event => event,
+ :change => self,
+ :transaction => @transaction,
+ :source => @state.parent,
+ :message => self.to_s
+ )
+ }
rescue => detail
#Puppet.err "%s failed: %s" % [self.to_s,detail]
raise
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index b9ddec44f..27f5c95b4 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -460,28 +460,7 @@ class Type < Puppet::Element
if @states.include?(name)
@states[name].should = value
else
- #Puppet.warning "Creating state %s for %s" %
- # [stateklass.name,self.name]
- begin
- # make sure the state doesn't have any errors
- newstate = stateklass.new(
- :parent => self,
- :should => value
- )
- @states[name] = newstate
- rescue Puppet::Error => detail
- # the state failed, so just ignore it
- Puppet.warning "State %s failed: %s" %
- [name, detail]
- rescue Puppet::DevError => detail
- # the state failed, so just ignore it
- Puppet.err "State %s failed: %s" %
- [name, detail]
- rescue => detail
- # the state failed, so just ignore it
- Puppet.err "State %s failed: %s (%s)" %
- [name, detail, detail.class]
- end
+ newstate(name, :should => value)
end
end
elsif self.class.validparameter?(name)
@@ -494,7 +473,7 @@ class Type < Puppet::Element
@parameters[name] = value
end
else
- raise "Invalid parameter %s" % [name]
+ raise Puppet::Error, "Invalid parameter %s" % [name]
end
end
#---------------------------------------------------------------
@@ -602,6 +581,45 @@ class Type < Puppet::Element
#---------------------------------------------------------------
#---------------------------------------------------------------
+ # create a new state
+ def newstate(name, hash = {})
+ if stateklass = self.class.validstate?(name)
+ if @states.include?(name)
+ hash.each { |var,value|
+ if value.is_a?(Puppet::State)
+ raise "huh?"
+ end
+ @states[name].send(var.to_s + "=", value)
+ }
+ else
+ #Puppet.warning "Creating state %s for %s" %
+ # [stateklass.name,self.name]
+ hash[:parent] = self
+ begin
+ # make sure the state doesn't have any errors
+ newstate = stateklass.new(hash)
+ @states[name] = newstate
+ rescue Puppet::Error => detail
+ # the state failed, so just ignore it
+ Puppet.warning "State %s failed: %s" %
+ [name, detail]
+ rescue Puppet::DevError => detail
+ # the state failed, so just ignore it
+ Puppet.err "State %s failed: %s" %
+ [name, detail]
+ rescue => detail
+ # the state failed, so just ignore it
+ Puppet.err "State %s failed: %s (%s)" %
+ [name, detail, detail.class]
+ end
+ end
+ else
+ raise Puppet::Error, "Invalid parameter %s" % name
+ end
+ end
+ #---------------------------------------------------------------
+
+ #---------------------------------------------------------------
# return the value of a parameter
def parameter(name)
unless name.is_a? Symbol
@@ -1017,17 +1035,7 @@ class Type < Puppet::Element
next if @states.include?(state)
stateklass = nil
- unless stateklass = self.class.validstate?(state)
- raise "%s is not a valid state for %s" % [state,self.class]
- end
-
- # XXX it's probably a bad idea to have code this important in
- # two places
- @states[state] = stateklass.new(
- :parent => self
- )
- #@states[state] = stateklass.new()
- #@states[state].parent = self
+ self.newstate(state)
}
end
#---------------------------------------------------------------
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb
index 6f057890e..8694fcd07 100755
--- a/lib/puppet/type/cron.rb
+++ b/lib/puppet/type/cron.rb
@@ -2,13 +2,44 @@
# $Id$
+require 'facter'
require 'puppet/type/state'
module Puppet
- # okay, how do we deal with parameters that don't have operations
- # associated with them?
+ module CronType
+ module Default
+ def self.fields
+ return [:minute, :hour, :weekday, :monthday, :command]
+ end
+
+ def self.retrieve(user)
+ %x{crontab -u #{user} -l 2>/dev/null}.split("\n").each { |line|
+ hash = {}
+ ary = line.split(" ")
+ fields().each { |param|
+ hash[param] = ary.shift
+ }
+
+ if ary.length > 0
+ hash[:command] += " " + ary.join(" ")
+ end
+ cron = nil
+ unless cron = Puppet::Type::Cron[hash[:command]]
+ cron = Puppet::Type::Cron.new
+ end
+
+ hash.each { |param, value|
+ cron.is = [param, value]
+ }
+ }
+ end
+
+ def self.sync(user)
+ end
+ end
+ end
+
class State
- # this always runs
class CronCommand < Puppet::State
@doc = "The command to execute in the cron job. The environment
provided to the command varies by local system rules, and it is
@@ -17,109 +48,19 @@ module Puppet
user's environment is desired it should be sourced manually."
@name = :command
- # because this command always runs,
- # we're just using retrieve to verify that the command
- # exists and such
def retrieve
- cmd = self.parent[:command]
- if cmd =~ /^\//
- exe = cmd.split(/ /)[0]
- unless FileTest.exists?(exe)
- raise TypeError.new(
- "Could not find executable %s" % exe
- )
- end
- unless FileTest.executable?(exe)
- raise TypeError.new(
- "%s is not executable" % exe
- )
- end
- elsif path = self.parent[:path]
- exe = cmd.split(/ /)[0]
- tmppath = ENV["PATH"]
- ENV["PATH"] = self.parent[:path]
-
- path = %{which #{exe}}.chomp
- if path == ""
- raise TypeError.new(
- "Could not find command '%s'" % exe
- )
- end
- ENV["PATH"] = tmppath
- else
- raise TypeError.new(
- "%s is somehow not qualified with no search path" %
- self.parent[:command]
- )
- end
-
- if self.parent[:refreshonly]
- # if refreshonly is enabled, then set things so we
- # won't sync
- self.is = self.should
- else
- # else, just set it to something we know it won't be
- self.is = nil
- end
+ # nothing...
end
def sync
- olddir = nil
- unless self.parent[:cwd].nil?
- debug "Resetting cwd to %s" % self.parent[:cwd]
- olddir = Dir.getwd
- begin
- Dir.chdir(self.parent[:cwd])
- rescue => detail
- raise "Failed to set cwd: %s" % detail
- end
- end
-
- tmppath = ENV["PATH"]
- ENV["PATH"] = self.parent[:path]
-
- # capture both stdout and stderr
- @output = %x{#{self.parent[:command]} 2>&1}
- status = $?
-
- loglevel = :info
- if status.exitstatus.to_s != self.should.to_s
- err("%s returned %s" %
- [self.parent[:command],status.exitstatus])
-
- # if we've had a failure, up the log level
- loglevel = :err
- end
-
- # and log
- @output.split(/\n/).each { |line|
- Puppet.send(loglevel, "%s: %s" % [self.parent[:command],line])
- }
-
- # reset things to how we found them
- ENV["PATH"] = tmppath
-
- unless olddir.nil?
- begin
- Dir.chdir(olddir)
- rescue => detail
- err("Could not reset cwd to %s: %s" %
- [olddir,detail])
- end
- end
-
- return :executed_command
end
end
end
class Type
class Cron < Type
- # this is kind of hackish, using the return value as the
- # state, but apparently namevars can't also be states
- # who knew?
@states = [
- Puppet::State::Returns
+ Puppet::State::CronCommand
]
@parameters = [
@@ -154,24 +95,51 @@ module Puppet
@name = :cron
@namevar = :name
- def initialize(hash)
+ @loaded = {}
+
+ @synced = {}
+
+ case Facter["operatingsystem"].value
+ when "Stub":
+ # nothing
+ else
+ Puppet.err "including default"
+ include Puppet::CronType::Default
end
- def output
- if self.state(:returns).nil?
- return nil
+ def self.loaded?(user)
+ if @loaded.include?(user)
+ return @loaded[user]
else
- return self.state(:returns).output
+ return nil
end
end
- # this might be a very, very bad idea...
- def refresh
- self.state(:returns).sync
+ def self.sync(user)
+ end
+
+ def initialize(hash)
end
- def to_s
- "exec(%s)" % self.name
+ def is=(ary)
+ param, value = ary
+ if param.is_a?(String)
+ param = param.intern
+ end
+ unless @states.include?(param)
+ if stateklass = self.class.validstate?(name)
+ begin
+ @states[param] = stateklass.new(
+ :parent => self
+ )
+ rescue => detail
+ end
+ else
+ raise Puppet::Error, "Invalid parameter %s" % [name]
+ end
+
+ end
+ @states[param].is = value
end
end
end
diff --git a/lib/puppet/type/state.rb b/lib/puppet/type/state.rb
index e77992b29..502de0ef9 100644
--- a/lib/puppet/type/state.rb
+++ b/lib/puppet/type/state.rb
@@ -69,8 +69,10 @@ class State < Puppet::Element
if hash.include?(:should)
self.should = hash[:should]
- else # we got passed no argument
- # leave @should undefined
+ end
+
+ if hash.include?(:is)
+ self.is = hash[:is]
end
end
#---------------------------------------------------------------