lib/puppet/storage.rb in puppet-0.9.2 vs lib/puppet/storage.rb in puppet-0.13.0

- old
+ new

@@ -1,95 +1,106 @@ +require 'yaml' + module Puppet # a class for storing state - class Storage - include Singleton - - def initialize - self.class.load - end + class Storage + include Singleton + + def initialize + self.class.load + end + # Return a hash that will be stored to disk. It's worth noting + # here that we use the object's full path, not just the name/type + # combination. At the least, this is useful for those non-isomorphic + # types like exec, but it also means that if an object changes locations + # in the configuration it will lose its cache. + def self.cache(object) + unless object.is_a? Puppet::Type + raise Puppet::DevFail, "Must pass a Type instance to Storage.cache" + end + return @@state[object.path] ||= {} + end + def self.clear - @@state = nil + @@state.clear Storage.init end def self.init Puppet.debug "Initializing Storage" - @@state = Hash.new { |hash,key| - hash[key] = Hash.new(nil) - } + @@state = {} @@splitchar = "\t" end self.init - def self.load - if Puppet[:checksumfile].nil? + def self.load + if Puppet[:statefile].nil? raise Puppet::DevError, "Somehow the statefile is nil" end - unless File.exists?(Puppet[:checksumfile]) - Puppet.info "Statefile %s does not exist" % Puppet[:checksumfile] + unless File.exists?(Puppet[:statefile]) + Puppet.info "Statefile %s does not exist" % Puppet[:statefile] + unless defined? @@state and ! @@state.nil? + self.init + end return end - begin - #Puppet.debug "Loading statefile %s" % Puppet[:checksumfile] - File.open(Puppet[:checksumfile]) { |file| - file.each { |line| - myclass, key, value = line.split(@@splitchar) - + #Puppet.debug "Loading statefile %s" % Puppet[:statefile] + Puppet::Util.lock(Puppet[:statefile]) { |file| + #@@state = Marshal.load(file) + begin + @@state = YAML.load(file) + rescue => detail + Puppet.err "Checksumfile %s is corrupt (%s); replacing" % + [Puppet[:statefile], detail] begin - @@state[eval(myclass)][key] = Marshal::load(value) - rescue => detail + File.rename(Puppet[:statefile], + Puppet[:statefile] + ".bad") + rescue raise Puppet::Error, - "Failed to load value for %s::%s => %s" % [ - myclass,key,detail - ], caller + "Could not rename corrupt %s; remove manually" % + Puppet[:statefile] end - } - } - rescue => detail - Puppet.err "Could not read %s" % Puppet[:checksumfile] + end + } + + unless @@state.is_a?(Hash) + Puppet.err "State got corrupted" + self.init end #Puppet.debug "Loaded state is %s" % @@state.inspect - end + end - def self.state(myclass) - unless myclass.is_a? Class - myclass = myclass.class - end - result = @@state[myclass] - return result - end + def self.stateinspect + @@state.inspect + end - def self.store - unless FileTest.directory?(File.dirname(Puppet[:checksumfile])) + def self.store + Puppet.debug "Storing state" + unless FileTest.directory?(File.dirname(Puppet[:statefile])) begin - Puppet.recmkdir(File.dirname(Puppet[:checksumfile])) + Puppet.recmkdir(File.dirname(Puppet[:statefile])) Puppet.info "Creating state directory %s" % - File.dirname(Puppet[:checksumfile]) + File.dirname(Puppet[:statefile]) rescue => detail Puppet.err "Could not create state file: %s" % detail return end end - unless FileTest.exist?(Puppet[:checksumfile]) - Puppet.info "Creating state file %s" % Puppet[:checksumfile] + unless FileTest.exist?(Puppet[:statefile]) + Puppet.info "Creating state file %s" % Puppet[:statefile] end - File.open(Puppet[:checksumfile], File::CREAT|File::WRONLY, 0600) { |file| - @@state.each { |klass, thash| - thash.each { |key,value| - mvalue = Marshal::dump(value) - file.puts([klass,key,mvalue].join(@@splitchar)) - } - } - } - - #Puppet.debug "Stored state is %s" % @@state.inspect - end - end + Puppet::Util.lock( + Puppet[:statefile], "w", 0600 + ) { |file| + file.print YAML.dump(@@state) + } + end + end end -# $Id: storage.rb 742 2005-11-16 17:12:11Z luke $ +# $Id: storage.rb 848 2006-01-24 06:01:58Z luke $