diff options
author | Luke Kanies <luke@madstop.com> | 2005-06-01 21:30:47 +0000 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2005-06-01 21:30:47 +0000 |
commit | d1f2187c26358288c3a0986b752ffdf5e7b87388 (patch) | |
tree | a0a6f988ebc1eb926d25718592aa81d85b7e7d92 /lib | |
parent | 18d755ac266e15f5c9fb284846df1c7d4c4a1457 (diff) | |
download | puppet-d1f2187c26358288c3a0986b752ffdf5e7b87388.tar.gz puppet-d1f2187c26358288c3a0986b752ffdf5e7b87388.tar.xz puppet-d1f2187c26358288c3a0986b752ffdf5e7b87388.zip |
checksums now work, but not all the way through yet
git-svn-id: https://reductivelabs.com/svn/puppet/library/trunk@292 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
-rw-r--r-- | lib/blink.rb | 174 | ||||
-rw-r--r-- | lib/blink/type.rb | 51 | ||||
-rw-r--r-- | lib/blink/type/file.rb | 142 | ||||
-rw-r--r-- | lib/blink/type/state.rb | 12 |
4 files changed, 153 insertions, 226 deletions
diff --git a/lib/blink.rb b/lib/blink.rb index 274e37550..17d3a8d6c 100644 --- a/lib/blink.rb +++ b/lib/blink.rb @@ -3,12 +3,6 @@ # $Id$ require 'singleton' -#require 'blink/component' -#require 'blink/interface' -#require 'blink/selector' -#require 'blink/type/service' -#require 'blink/type/file' -#require 'blink/type/symlink' # XXX see the bottom of the file for further inclusions @@ -31,11 +25,18 @@ module Blink # the hash that determines how our system behaves @@config = Hash.new(false) + @@config[:blinkroot] = "/var/blink" + @@config[:logdir] = "/var/blink/log" + @@config[:logfile] = "/var/blink/log/blink.log" + @@config[:statefile] = "/var/blink/log/state" - msglevels = [:debug,:verbose,:notice,:warning,:error] + + loglevels = [:debug,:verbose,:notice,:warning,:error] # handle the different message levels - msglevels.each { |level| + # XXX this should be redone to treat log-levels like radio buttons + # pick one, and it and all above it will be logged + loglevels.each { |level| define_method(level,proc { |args| Blink.message(level,args) }) @@ -69,47 +70,6 @@ module Blink puts msg end - # DISABLED - - # we've collected all data; now operate on it -# def Blink.run -# ops = Blink::Objects.genops() -# ops.find_all { |op| -# op.auto?() -# }.each { |op| -# Blink::Message.new( -# :level => :debug, -# :source => "Blink", -# :message => "Running op %s" % op -# ) -# op.check -# }.find_all { |op| -# puts "dirty? #{op}" -# op.dirty? -# }.collect { |op| -# puts "%s is dirty; %s instead of %s" % [op, op.state, op.should] -# op.fix -# }.each { |event| # this might need to support lists someday... -# #list.each { |event| -# puts event -# event.trigger -# #} -# } -# end -# -# def Blink.walk -# root = Blink::Objects.root -# root.check -# if root.dirty? -# Blink::Message.new( -# :message => "someone's dirty", -# :level => :notice, -# :source => root -# ) -# root.fix -# end -# end - # configuration parameter access and stuff def Blink.[](param) return @@config[param] @@ -120,120 +80,8 @@ module Blink @@config[param] = value end - # a class for storing state - # not currently used - class Storage - include Singleton - @@config = "/var/tmp/blinkstate" - @@state = Hash.new - @@splitchar = " " - - def initialize - self.load - end - - def Storage.load - puts "loading state" - return unless File.exists?(@@config) - File.open(@@config) { |file| - file.gets { |line| - myclass, key, value = line.split(@@splitchar) - - unless defined? @@state[myclass] - @@state[myclass] = Hash.new - end - - @@state[myclass][key] = value - } - } - end - - def Storage.state(myclass) - unless defined? @@state[myclass] - @@state[myclass] = Hash.new - end - return @@state[myclass] - end - - def Storage.store - File.open(@@config, File::CREAT|File::WRONLY, 0644) { |file| - @@state.each { |key, value| - file.puts([self.class,key,value].join(@@splitchar)) - } - } - end - end - - #------------------------------------------------------------ - # provide feedback of various types to the user - # modeled after syslog messages - # each level of message prints in a different color - class Message - @@messages = Array.new - @@levels = [ :debug, :verbose, :notice, :warning, :error ] - @@colors = { - :debug => SLATE, - :verbose => ORANGE, - :notice => PINK, - :warning => GREEN, - :error => YELLOW - } - - attr_reader :level, :message - attr_writer :level, :message - - def initialize(args) - unless args.include?(:level) && args.include?(:message) && - args.include?(:source) - raise "Blink::Message called incorrectly" - end - - if args[:level].class == String - @level = args[:level].intern - elsif args[:level].class == Symbol - @level = args[:level] - else - raise "Level is not a string or symbol: #{args[:level].class}" - end - @message = args[:message] - @source = args[:source] - @time = Time.now - # this should include the host name, and probly lots of other - # stuff, at some point - unless @@levels.include?(level) - raise "Invalid message level #{level}" - end - - @@messages.push(self) - Blink.newmessage(self) - end - - def to_s - # this probably won't stay, but until this leaves the console, - # i'm going to use coloring... - #return "#{@time} #{@source} (#{@level}): #{@message}" - #return @@colors[@level] + "%s %s (%s): %s" % [ - # @time, @source, @level, @message - #] + RESET - return @@colors[@level] + "%s (%s): %s" % [ - @source, @level, @message - ] + RESET - end - end - #------------------------------------------------------------ - - #------------------------------------------------------------ - class Modification - attr_accessor :object, :type, :from, :to - - def initialize(object) - @object = object - @type = object.class - @from = object.is? - @to = object.should? - end - end - #------------------------------------------------------------ end +require 'blink/storage' +require 'blink/message' require 'blink/type' diff --git a/lib/blink/type.rb b/lib/blink/type.rb index b08acdc49..5fd6d6aae 100644 --- a/lib/blink/type.rb +++ b/lib/blink/type.rb @@ -32,7 +32,7 @@ require 'blink/type/state' # to use this interface, just define an 'each' method and 'include Blink::Type' module Blink -class Blink::Type < Blink::Element +class Type < Blink::Element attr_accessor :children, :parameters, :parent, :states include Enumerable @@ -45,7 +45,7 @@ class Blink::Type < Blink::Element @states = [] @parameters = [:notused] - @allowedmethods = [:noop,:debug] + @allowedmethods = [:noop,:debug,:statefile] @@metaparams = [ :onerror, @@ -103,6 +103,12 @@ class Blink::Type < Blink::Element #--------------------------------------------------------------- #--------------------------------------------------------------- + def Type.statefile(file) + Blink[:statefile] = file + end + #--------------------------------------------------------------- + + #--------------------------------------------------------------- # ill thought-out # this needs to return @noop #def noop(ary) @@ -414,8 +420,12 @@ class Blink::Type < Blink::Element if @states.include?(mname) @states[mname].should = value else - @states[mname] = stateklass.new(value) - @states[mname].parent = self + @states[mname] = stateklass.new( + :parent => self, + :should => value + ) + #Blink.notice "Adding parent to %s" % mname + #@states[mname].parent = self end end elsif self.class.validparameter(mname) @@ -505,11 +515,11 @@ class Blink::Type < Blink::Element # if they're not using :name for the namevar but we got :name (probably # from the parser) - if namevar != :name and hash.include?(:name) + if namevar != :name and hash.include?(:name) and ! hash[:name].nil? self[namevar] = hash[:name] hash.delete(:name) # else if we got the namevar - elsif hash.has_key?(namevar) + elsif hash.has_key?(namevar) and ! hash[namevar].nil? self[namevar] = hash[namevar] hash.delete(namevar) # else something's screwy @@ -559,6 +569,14 @@ class Blink::Type < Blink::Element #--------------------------------------------------------------- #--------------------------------------------------------------- + def sync + self.collect { |child| + child.sync + }.flatten + end + #--------------------------------------------------------------- + + #--------------------------------------------------------------- def to_s self.name end @@ -572,7 +590,7 @@ class Blink::Type < Blink::Element #--------------------------------------------------------------- def eachstate - Blink.debug "have %s states" % @states.length + Blink.debug "%s has %s states" % [self,@states.length] tmpstates = [] self.class.states.each { |state| if @states.include?(state.name) @@ -706,8 +724,11 @@ class Blink::Type < Blink::Element # XXX it's probably a bad idea to have code this important in # two places - @states[state] = stateklass.new() - @states[state].parent = self + @states[state] = stateklass.new( + :parent => self + ) + #@states[state] = stateklass.new() + #@states[state].parent = self } end #--------------------------------------------------------------- @@ -783,18 +804,6 @@ class Blink::Type < Blink::Element @schedule = schedule end #--------------------------------------------------------------- - - #--------------------------------------------------------------- - # set up the "interface" methods - [:sync,:retrieve].each { |method| - self.send(:define_method,method) { - self.each { |subobj| - #Blink.debug("sending '%s' to '%s'" % [method,subobj]) - subobj.send(method) - } - } - } - #--------------------------------------------------------------- end # Blink::Type end diff --git a/lib/blink/type/file.rb b/lib/blink/type/file.rb index d7d7a1283..57f58fbe4 100644 --- a/lib/blink/type/file.rb +++ b/lib/blink/type/file.rb @@ -17,11 +17,20 @@ module Blink @name = :create @event = :file_created + def should=(value) + # default to just about anything meaning 'true' + if value == false or value.nil? + @should = false + else + @should = true + end + end + def retrieve stat = nil self.is = FileTest.exist?(self.parent[:path]) - Blink.debug "exists state is %s" % self.is + Blink.debug "'exists' state is %s" % self.is end @@ -36,6 +45,83 @@ module Blink end end + class FileChecksum < Blink::State + @name = :checksum + @event = :file_modified + + def should=(value) + @checktype = value + state = Blink::Storage.state(self) + if hash = state[self.parent[:path]] + if hash.include?(@checktype) + @should = hash[@checktype] + else + Blink.verbose "Found checksum for %s but not of type %s" % + [self.parent[:path],@checktype] + @should = nil + end + else + Blink.debug "No checksum for %s" % self.parent[:path] + end + end + + def retrieve + unless defined? @checktype + @checktype = "md5" + end + + sum = "" + case @checktype + when "md5": + File.open(self.parent[:path]) { |file| + sum = Digest::MD5.hexdigest(file.read) + } + when "md5lite": + File.open(self.parent[:path]) { |file| + sum = Digest::MD5.hexdigest(file.read(512)) + } + when "timestamp","mtime": + sum = File.stat(self.parent[:path]).mtime + when "time": + sum = File.stat(self.parent[:path]).ctime + end + + self.is = sum + + Blink.debug "checksum state is %s" % self.is + end + + + # at this point, we don't actually modify the system, we just kick + # off an event if we detect a change + def sync + if self.updatesum + return :file_modified + else + return nil + end + end + + def updatesum + state = Blink::Storage.state(self) + unless state.include?(self.parent[:path]) + state[self.parent[:path]] = Hash.new + end + # if we're replacing, vs. updating + if state[self.parent[:path]].include?(@checktype) + Blink.debug "Replacing checksum %s with %s" % + [state[self.parent[:path]][@checktype],@is] + result = true + else + Blink.verbose "Creating checksum %s for %s of type %s" % + [@is,self.parent[:path],@checktype] + result = false + end + state[self.parent[:path]][@checktype] = @is + return result + end + end + class FileUID < Blink::State require 'etc' attr_accessor :file @@ -43,13 +129,7 @@ module Blink @event = :inode_changed def retrieve - stat = nil - - unless stat = self.parent.stat(true) - self.is = -1 - Blink.debug "chown state is %d" % self.is - return - end + stat = self.parent.stat(true) self.is = stat.uid if defined? @should @@ -116,13 +196,7 @@ module Blink end def retrieve - stat = nil - - unless stat = self.parent.stat(true) - # a value we know we'll never get in reality - self.is = -1 - return - end + stat = self.parent.stat(true) self.is = stat.mode & 007777 Blink.debug "chmod state is %o" % self.is @@ -176,6 +250,7 @@ module Blink tmp = 1 end @parent.value[11] = tmp + return :inode_changed end end @@ -186,13 +261,7 @@ module Blink @event = :inode_changed def retrieve - stat = nil - - unless stat = self.parent.stat(true) - self.is = -1 - Blink.debug "chgrp state is %d" % self.is - return - end + stat = self.parent.stat(true) self.is = stat.gid @@ -254,6 +323,7 @@ module Blink Blink::State::FileUID, Blink::State::FileGroup, Blink::State::FileMode, + Blink::State::FileChecksum, Blink::State::FileSetUID ] @@ -265,6 +335,18 @@ module Blink @name = :file @namevar = :path + # a wrapper method to make sure the file exists before doing anything + def retrieve + unless stat = self.stat(true) + Blink.verbose "File %s does not exist" % self[:path] + @states.each { |name,state| + state.is = -1 + } + return + end + super + end + def stat(refresh = false) if @stat.nil? or refresh == true begin @@ -315,10 +397,6 @@ module Blink arghash[:path] = ::File.join(self[:path],file) - # if one of these files already exists, we're going to - # fail here, because this will try to clobber, which is bad - # mmmkay - #@children.push self.class.new(arghash) child = nil # if the file already exists... if child = self.class[arghash[:path]] @@ -334,18 +412,6 @@ module Blink end end end - - def sync - if @states[:create] and ! FileTest.exist?(self.path) - begin - File.open(self.path,"w") { # just create an empty file - } - rescue => detail - raise detail - end - end - super - end end # Blink::Type::File end # Blink::Type diff --git a/lib/blink/type/state.rb b/lib/blink/type/state.rb index 7bc0dfdd7..80c0a933b 100644 --- a/lib/blink/type/state.rb +++ b/lib/blink/type/state.rb @@ -70,15 +70,19 @@ class Blink::State < Blink::Element #--------------------------------------------------------------- #--------------------------------------------------------------- - def initialize(*should) + def initialize(hash) @is = nil - if should.length > 0 # we got passed an argument - self.should = should.shift + unless hash.include?(:parent) + raise "State %s was not passed a parent" % self + end + @parent = hash[:parent] + + if hash.include?(:should) + self.should = hash[:should] else # we got passed no argument # leave @should undefined end - @parent = nil end #--------------------------------------------------------------- |