summaryrefslogtreecommitdiffstats
path: root/func
diff options
context:
space:
mode:
authorMichael DeHaan <mdehaan@redhat.com>2007-10-26 17:33:44 -0400
committerMichael DeHaan <mdehaan@redhat.com>2007-10-26 17:33:44 -0400
commit9060cccfbfa77fbc8592f07e4641514d7a740a1f (patch)
tree10b0420e6a8ab82087b2898fd96cf5764162bd75 /func
parentd7f4a0ebebe416084ec726d38f485246aa88e886 (diff)
downloadthird_party-func-9060cccfbfa77fbc8592f07e4641514d7a740a1f.tar.gz
third_party-func-9060cccfbfa77fbc8592f07e4641514d7a740a1f.tar.xz
third_party-func-9060cccfbfa77fbc8592f07e4641514d7a740a1f.zip
Adds the filetracker module, originally developed by fordship, with some tweaks. "func spec call filetracker track filename" can be
used to track a file, and "func spec call filetracker untrack filename" removes it. Then it shows up with lots of data using "func spec call filetracker inventory". Addition can also specify for the contents of data in the said files to be noted in inventory. Additionally, the inventory function can be told to return data structures instead of an easily-diffable list, and the checksums can be enabled/disabled.
Diffstat (limited to 'func')
-rw-r--r--func/minion/modules/filetracker.py197
-rwxr-xr-xfunc/minion/modules/virt.py11
2 files changed, 207 insertions, 1 deletions
diff --git a/func/minion/modules/filetracker.py b/func/minion/modules/filetracker.py
new file mode 100644
index 0000000..efcc31c
--- /dev/null
+++ b/func/minion/modules/filetracker.py
@@ -0,0 +1,197 @@
+#!/usr/bin/python
+
+## func
+##
+## filetracker
+## maintains a manifest of files of which to keep track
+## provides file meta-data (and optionally full data) to func-inventory
+##
+## (C) Vito Laurenza <vitolaurenza@gmail.com>
+##
+## This software may be freely redistributed under the terms of the GNU
+## general public license.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+##
+
+# func modules
+from modules import func_module
+
+# other modules
+# import ConfigParser
+from stat import *
+import os
+import sys
+import md5
+
+# defaults
+CONFIG_FILE='/etc/func/modules/filetracker.conf'
+
+class FileTracker(func_module.FuncModule):
+
+ def __init__(self):
+ self.methods = {
+ "track" : self.track,
+ "untrack" : self.untrack,
+ "info" : self.inventory,
+ "inventory" : self.inventory,
+ }
+ func_module.FuncModule.__init__(self)
+
+ #==========================================================
+
+ def __load(self):
+ """
+ Parse file and return data structure.
+ """
+
+ filehash = {}
+ if os.path.exists(CONFIG_FILE):
+ config = open(CONFIG_FILE, "r")
+ data = config.read()
+ lines = data.split("\n")
+ for line in lines:
+ tokens = line.split(None)
+ if len(tokens) < 2:
+ continue
+ scan_mode = tokens[0]
+ path = " ".join(tokens[1:])
+ if str(scan_mode).lower() == "0":
+ scan_mode = 0
+ else:
+ scan_mode = 1
+ filehash[path] = scan_mode
+ return filehash
+
+ #==========================================================
+
+ def __save(self, filehash):
+ """
+ Write data structure to file.
+ """
+
+ config = open(CONFIG_FILE, "w+")
+ for (path, scan_mode) in filehash.iteritems():
+ config.write("%s %s\n" % (scan_mode, path))
+ config.close()
+
+ #==========================================================
+
+ def track(self, file_name, full_scan=0):
+ """
+ Adds files to keep track of.
+ full_scan implies tracking the full contents of the file, defaults to off
+ """
+
+ filehash = self.__load()
+ filehash[file_name] = full_scan
+ self.__save(filehash)
+ return 1
+
+ #==========================================================
+
+ def untrack(self, file_name):
+ """
+ Stop keeping track of a file.
+ This routine is tolerant of most errors since we're forgetting about the file anyway.
+ """
+
+ filehash = self.__load()
+ print "DEBUG: deleting: %s" % file_name
+ print "DEBUG: keys: %s" % filehash
+ if file_name in filehash.keys():
+ del filehash[file_name]
+ self.__save(filehash)
+ return 1
+
+ #==========================================================
+
+ def inventory(self, flatten=1, checksum_enabled=1):
+ """
+ Returns information on all tracked files
+ By default, 'flatten' is passed in as True, which makes printouts very clean in diffs
+ for use by func-inventory. If you are writting another software application, using flatten=False will
+ prevent the need to parse the returns.
+ """
+
+ # XMLRPC feeds us strings from the CLI when it shouldn't
+ flatten = int(flatten)
+ checksum_enabled = int(checksum_enabled)
+
+ filehash = self.__load()
+
+ # we'll either return a very flat string (for clean diffs)
+ # or a data structure
+ if flatten:
+ results = ""
+ else:
+ results = []
+
+ for (file_name, scan_type) in filehash.iteritems():
+
+ if not os.path.exists(file_name):
+ if flatten:
+ results = results + "%s: does not exist\n" % file_name
+ else:
+ results.append("%s: does not exist\n" % file_name)
+ continue
+
+ this_result = []
+
+ # ----- always process metadata
+ filestat = os.stat(file_name)
+ mode = filestat[ST_MODE]
+ mtime = filestat[ST_MTIME]
+ uid = filestat[ST_UID]
+ gid = filestat[ST_GID]
+ if not os.path.isdir(file_name) and checksum_enabled:
+ sum_handle = open(file_name)
+ hash = self.sumfile(sum_handle)
+ sum_handle.close()
+ else:
+ hash = "N/A"
+
+ # ------ what we return depends on flatten
+ if flatten:
+ this_result = "%s: mode=%s mtime=%s uid=%s gid=%s md5sum=%s\n" % (file_name,mode,mtime,uid,gid,hash)
+ else:
+ this_result = [file_name,mode,mtime,uid,gid,hash]
+
+ # ------ add on file data only if requested
+ if scan_type != 0 and os.path.isfile(file_name):
+ tracked_file = open(file_name)
+ data = tracked_file.read()
+ if flatten:
+ this_result = this_result + "*** DATA *******\n" + data + "\n*** END DATA ***\n\n"
+ else:
+ this_result.append(data)
+ tracked_file.close()
+
+ if flatten:
+ results = results + "\n" + this_result
+ else:
+ results.append(this_result)
+
+
+ return results
+
+ #==========================================================
+
+ def sumfile(self, fobj):
+ """
+ Returns an md5 hash for an object with read() method.
+ credit: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/266486
+ """
+
+ m = md5.new()
+ while True:
+ d = fobj.read(8096)
+ if not d:
+ break
+ m.update(d)
+ return m.hexdigest()
+
+methods = FileTracker()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/virt.py b/func/minion/modules/virt.py
index 7dc5697..3e7fc2d 100755
--- a/func/minion/modules/virt.py
+++ b/func/minion/modules/virt.py
@@ -22,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# other modules
import os
import sub_process
-import libvirt
+# import libvirt
# our modules
import codes
@@ -42,6 +42,13 @@ class FuncLibvirtConnection(object):
def __init__(self):
+ self.loaded = False
+
+ try:
+ import libvirt
+ self.loaded = True
+ except:
+ return
cmd = sub_process.Popen("uname -r", shell=True, stdout=sub_process.PIPE)
output = cmd.communicate()[0]
@@ -147,6 +154,8 @@ class Virt(func_module.FuncModule):
def get_conn(self):
self.conn = FuncLibvirtConnection()
+ if not self.conn.loaded:
+ return False
return self.conn
def info(self):