summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2005-06-01 21:30:47 +0000
committerLuke Kanies <luke@madstop.com>2005-06-01 21:30:47 +0000
commitd1f2187c26358288c3a0986b752ffdf5e7b87388 (patch)
treea0a6f988ebc1eb926d25718592aa81d85b7e7d92 /lib
parent18d755ac266e15f5c9fb284846df1c7d4c4a1457 (diff)
downloadpuppet-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.rb174
-rw-r--r--lib/blink/type.rb51
-rw-r--r--lib/blink/type/file.rb142
-rw-r--r--lib/blink/type/state.rb12
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
#---------------------------------------------------------------