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 $