aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/ventoo/augeas_utils.py')
-rw-r--r--src/ventoo/augeas_utils.py240
1 files changed, 240 insertions, 0 deletions
diff --git a/src/ventoo/augeas_utils.py b/src/ventoo/augeas_utils.py
new file mode 100644
index 0000000..6db6551
--- /dev/null
+++ b/src/ventoo/augeas_utils.py
@@ -0,0 +1,240 @@
+"""
+
+ This file is part of the Ventoo program.
+
+ This is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ It is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this software. If not, see <http://www.gnu.org/licenses/>.
+
+ Copyright 2010 Christopher Harvey
+
+"""
+
+import augeas
+import os.path as osp
+import getpass
+import shutil
+import os
+import pdb
+
+"""
+ Fills the fileSet parameter with the files that augeas loaded.
+ The returned files are system paths
+"""
+def accumulateFiles(a, node="/files", fileSet=[]):
+ aug_root = a.get("/augeas/root")
+ thisChildren = a.match(osp.join(node, '*'))
+ for child in thisChildren:
+ sysPath = osp.join(aug_root, osp.relpath(child, '/files'))
+ if osp.isfile(sysPath):
+ fileSet.append(sysPath)
+ elif osp.isdir(sysPath):
+ accumulateFiles(a, child, fileSet)
+ return fileSet
+
+
+"""
+ Use an augeas file path to get a ventoo module name.
+"""
+def getVentooModuleNameFromAugPath(a, augPath):
+ aug_root = a.get("/augeas/root")
+ sysPath = osp.join(aug_root, osp.relpath(augPath, '/files'))
+ return str.split(osp.split(sysPath)[1], ".")[0]
+
+"""
+ Use a full system path to get a ventoo module name.
+"""
+def getVentooModuleNameFromSysPath(a, sysPath):
+ #remove the first character '/' if sysPath is absolute or join wont work.
+ if sysPath[0] == '/':
+ augQuery = osp.join('augeas/files', sysPath[1:], 'lens/info')
+ else:
+ augQuery = osp.join('augeas/files', sysPath, 'lens/info')
+ lensFile = a.get(augQuery)
+ return str.split(osp.split(lensFile)[1], ".")[0]
+
+
+"""
+ Get an augeas path to a file from a system path
+"""
+def getAugeasPathFromSystemPath(a, sysPath):
+ aug_root = a.get("/augeas/root")
+ if aug_root != '/':
+ tmp = osp.relpath(sysPath, aug_root)
+ else:
+ tmp = sysPath
+ return osp.join('/files/', stripLeadingSlash(tmp))
+
+"""
+ Return an int that says how much to add to 'have' so that it matches mult.
+ Mult can be a number, or ?, +, *
+"""
+def matchDiff(mult, have):
+ if mult == '*':
+ return 0
+ elif mult == '+':
+ if have > 0:
+ return 0
+ else:
+ return 1
+ elif mult == '?':
+ return 0
+ else:
+ return max(0, int(mult) - have)
+
+"""
+ True if adding more to 'have' will make the match invalid.
+"""
+def matchExact(mult, have):
+ if mult == '*':
+ return False
+ elif mult == '+':
+ return False
+ elif mult == '?':
+ if have == 0:
+ return False
+ elif have == 1:
+ return True
+ else:
+ raise ValueError("passed ? and "+str(have)+" to matchExact")
+ elif int(mult) == have:
+ return True
+ elif int(mult) < have:
+ raise ValueError("passed "+mult+" and "+str(have)+" to matchExact")
+ return False
+
+"""
+ True if the children in augPath are
+ augPath/1
+ augPath/2
+ etc...
+"""
+def isDupLevel(a, augPath):
+ q = osp.join(augPath, '*')
+ matches = a.match(q)
+ for match in matches:
+ try:
+ int(osp.split(match)[1])
+ return True
+ except ValueError:
+ pass
+ return False
+
+"""
+ Turn /foo/bar/ into /foo/bar
+"""
+def stripTrailingSlash(a):
+ if a.endswith('/'):
+ ret = a[0:len(a)-1]
+ else:
+ ret = a
+ return ret
+
+"""
+ Turn /foo/bar/ into foo/bar/
+"""
+def stripLeadingSlash(a):
+ if a.startswith('/'):
+ ret = a[1:]
+ else:
+ ret = a
+ return ret
+
+def stripBothSlashes(a):
+ return stripTrailingSlash(stripLeadingSlash(a))
+
+"""
+ Get the path to the directory where the diff tree is to be stored.
+"""
+def getDiffRoot():
+ return osp.join('/tmp', getpass.getuser(), 'augeas')
+
+
+"""
+ Called by makeDiffTree, this actually checks files and performs the copies.
+ makeDiffTree only walks the directories and sets up the base paths.
+"""
+def __makeCopies(bases, currentDir, files):
+ #bases[0] = copyTargetBase
+ #bases[1] = aug_root
+ if osp.commonprefix([bases[0], currentDir]) == bases[0]:
+ return #ignore anything inside where we are copying to.
+ for f in files:
+ if f.endswith(".augnew"):
+ #print 'would copy ' + srcFile + ' to ' + targetDir
+ srcFile = osp.join(currentDir, f)
+ targetDir = osp.join(bases[0], osp.relpath(currentDir, bases[1]))
+ targetFile = osp.join(targetDir, f)
+ try:
+ os.makedirs(targetDir) #make sure target dir exists
+ except:
+ pass #don't care if it already exists.
+ shutil.copy(srcFile, targetFile)
+
+"""
+ Make a tree in treeRoot that contains a replica of the edited
+ filesystem except with .augnew files for future comparisions.
+"""
+def makeDiffTree(a, treeRoot):
+ saveMethod = a.get('augeas/save')
+ userName = getpass.getuser()
+ #if userName == 'root':
+ # raise ValueError("this function isn't safe to be run as root.")
+ if saveMethod != 'newfile':
+ raise ValueError('the save method for augeas is not "newfile"')
+ if not osp.isdir(treeRoot):
+ raise ValueError(treeRoot + ' is not a directory')
+ files = accumulateFiles(a)
+ for i in range(len(files)): #append .augnew to each file.
+ files[i] += '.augnew'
+ a.save()
+ for f in files:
+ #each file could exist, copy the ones that do.
+ if osp.isfile(f):
+ try:
+ os.makedirs(osp.join("/tmp", userName, "augeas", stripLeadingSlash(osp.split(f)[0])))
+ except:
+ pass #don't care if it exists.
+ shutil.move(f, osp.join("/tmp", userName, "augeas", stripLeadingSlash(f)))
+"""
+ Turns a system path like /etc/hosts into a the place where its
+ diff (edited) version would be saved. Use this function to compare
+ two files.
+"""
+def getDiffLocation(a, sysPath):
+ aug_root = a.get("/augeas/root")
+ return osp.join(getDiffRoot(), stripBothSlashes(sysPath)) + '.augnew'
+
+
+def getFileErrorList(a, node = "augeas/files", errorList = {}):
+ aug_root = a.get("/augeas/files/")
+ thisChildren = a.match(osp.join(node, '*'))
+ for child in thisChildren:
+ thisError = a.get(osp.join(child, "error"))
+ if not thisError == None:
+ errorList[osp.relpath(child, "/augeas/files")] = thisError
+ else:
+ getFileErrorList(a, child, errorList)
+ return errorList
+
+"""
+ Removes numbers form paths. a/1/foo/bar/5/6/blah -> a/foo/bar/blah
+"""
+def removeNumbers(path):
+ out = ""
+ for node in path.split("/"):
+ try:
+ tmp = int(node)
+ except ValueError:
+ out = osp.join(out, node)
+ return out
+