[node-patches] Change in ovirt-node[ovirt-3.5]: Update augeas.py
fabiand at redhat.com
fabiand at redhat.com
Wed Nov 26 10:20:06 UTC 2014
Fabian Deutsch has uploaded a new change for review.
Change subject: Update augeas.py
......................................................................
Update augeas.py
Our "own" augeas.py was outdateed. We update it to match
upstream.
Change-Id: If78a333b44ac2441bba685e65938871f652631c6
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
(cherry picked from commit eaeacd9b34ad2aefd40ff31d5e44cd911feaa686)
---
M scripts/augeas.py
1 file changed, 220 insertions(+), 57 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/86/35586/1
diff --git a/scripts/augeas.py b/scripts/augeas.py
index 3b1d782..ca5e191 100644
--- a/scripts/augeas.py
+++ b/scripts/augeas.py
@@ -38,9 +38,32 @@
Nils Philippsen <nils at redhat.com>
"""
+import types
import ctypes
import ctypes.util
from sys import version_info as _pyver
+from functools import reduce
+
+
+PY3 = _pyver >= (3,)
+AUGENC = 'utf8'
+
+
+if PY3:
+ string_types = str
+else:
+ string_types = basestring
+
+
+def enc(st):
+ if st:
+ return st.encode(AUGENC)
+
+
+def dec(st):
+ if st:
+ return st.decode(AUGENC)
+
def _dlopen(*args):
"""Search for one of the libraries given as arguments and load it.
@@ -55,12 +78,6 @@
class Augeas(object):
"Class wrapper for the augeas library"
- # Load libpython (for 'PyFile_AsFile()' and 'PyMem_Free()')
- # pylint: disable-msg=W0142
- _libpython = _dlopen(*["python" + _v % _pyver[:2]
- for _v in ("%d.%d", "%d%d")])
- _libpython.PyFile_AsFile.restype = ctypes.c_void_p
-
# Load libaugeas
_libaugeas = _dlopen("augeas")
_libaugeas.aug_init.restype = ctypes.c_void_p
@@ -74,6 +91,7 @@
SAVE_NOOP = 1 << 4
NO_LOAD = 1 << 5
NO_MODL_AUTOLOAD = 1 << 6
+ ENABLE_SPAN = 1 << 7
def __init__(self, root=None, loadpath=None, flags=NONE):
"""Initialize the library.
@@ -89,17 +107,19 @@
'flags' is a bitmask made up of values from AUG_FLAGS."""
# Sanity checks
- if not isinstance(root, basestring) and root != None:
+ if not isinstance(root, string_types) and root != None:
raise TypeError("root MUST be a string or None!")
- if not isinstance(loadpath, basestring) and loadpath != None:
+ if not isinstance(loadpath, string_types) and loadpath != None:
raise TypeError("loadpath MUST be a string or None!")
if not isinstance(flags, int):
raise TypeError("flag MUST be a flag!")
# Create the Augeas object
- self.__handle = Augeas._libaugeas.aug_init(root, loadpath, flags)
+ self.__handle = Augeas._libaugeas.aug_init(enc(root), enc(loadpath), flags)
if not self.__handle:
raise RuntimeError("Unable to create Augeas object!")
+ # Make sure self.__handle is a void*, not an integer
+ self.__handle = ctypes.c_void_p(self.__handle)
def __del__(self):
self.close()
@@ -110,7 +130,7 @@
It is an error if more than one node matches 'path'."""
# Sanity checks
- if not isinstance(path, basestring):
+ if not isinstance(path, string_types):
raise TypeError("path MUST be a string!")
if not self.__handle:
raise RuntimeError("The Augeas object has already been closed!")
@@ -119,12 +139,34 @@
value = ctypes.c_char_p()
# Call the function and pass value by reference (char **)
- ret = Augeas._libaugeas.aug_get(self.__handle, path,
+ ret = Augeas._libaugeas.aug_get(self.__handle, enc(path),
ctypes.byref(value))
if ret > 1:
raise ValueError("path specified had too many matches!")
- return value.value
+ return dec(value.value)
+
+ def label(self, path):
+ """Lookup the label associated with 'path'.
+ Returns the label of the path specified.
+ It is an error if more than one node matches 'path'."""
+
+ # Sanity checks
+ if not isinstance(path, string_types):
+ raise TypeError("path MUST be a string!")
+ if not self.__handle:
+ raise RuntimeError("The Augeas object has already been closed!")
+
+ # Create the char * value
+ label = ctypes.c_char_p()
+
+ # Call the function and pass value by reference (char **)
+ ret = Augeas._libaugeas.aug_label(self.__handle, enc(path),
+ ctypes.byref(label))
+ if ret > 1:
+ raise ValueError("path specified had too many matches!")
+
+ return dec(label.value)
def set(self, path, value):
"""Set the value associated with 'path' to 'value'.
@@ -132,15 +174,15 @@
It is an error if more than one node matches 'path'."""
# Sanity checks
- if not isinstance(path, basestring):
+ if not isinstance(path, string_types):
raise TypeError("path MUST be a string!")
- if not isinstance(value, basestring):
- raise TypeError("value MUST be a string!")
+ if not isinstance(value, string_types) and type(value) != type(None):
+ raise TypeError("value MUST be a string or None!")
if not self.__handle:
raise RuntimeError("The Augeas object has already been closed!")
# Call the function
- ret = Augeas._libaugeas.aug_set(self.__handle, path, value)
+ ret = Augeas._libaugeas.aug_set(self.__handle, enc(path), enc(value))
if ret != 0:
raise ValueError("Unable to set value to path!")
@@ -153,18 +195,65 @@
# Sanity checks
if type(base) != str:
- raise TypeError, "base MUST be a string!"
+ raise TypeError("base MUST be a string!")
if type(sub) != str and sub != None:
- raise TypeError, "sub MUST be a string or None!"
+ raise TypeError("sub MUST be a string or None!")
if type(value) != str:
- raise TypeError, "value MUST be a string!"
+ raise TypeError("value MUST be a string!")
if not self.__handle:
- raise RuntimeError, "The Augeas object has already been closed!"
+ raise RuntimeError("The Augeas object has already been closed!")
# Call the function
- ret = Augeas._libaugeas.aug_setm(self.__handle, base, sub, value)
+ ret = Augeas._libaugeas.aug_setm(
+ self.__handle, enc(base), enc(sub), enc(value))
if ret < 0:
- raise ValueError, "Unable to set value to path!"
+ raise ValueError("Unable to set value to path!")
+ return ret
+
+ def text_store(self, lens, node, path):
+ """Use the value of node 'node' as a string and transform it into a tree
+ using the lens 'lens' and store it in the tree at 'path', which will be
+ overwritten. 'path' and 'node' are path expressions."""
+
+ # Sanity checks
+ if not isinstance(lens, string_types):
+ raise TypeError("lens MUST be a string!")
+ if not isinstance(node, string_types):
+ raise TypeError("node MUST be a string!")
+ if not isinstance(path, string_types):
+ raise TypeError("path MUST be a string!")
+ if not self.__handle:
+ raise RuntimeError("The Augeas object has already been closed!")
+
+ # Call the function
+ ret = Augeas._libaugeas.aug_text_store(
+ self.__handle, enc(lens), enc(node), enc(path))
+ if ret != 0:
+ raise ValueError("Unable to store text at node!")
+ return ret
+
+ def text_retrieve(self, lens, node_in, path, node_out):
+ """Transform the tree at 'path' into a string using lens 'lens' and store it in
+ the node 'node_out', assuming the tree was initially generated using the
+ value of node 'node_in'. 'path', 'node_in', and 'node_out' are path expressions."""
+
+ # Sanity checks
+ if not isinstance(lens, string_types):
+ raise TypeError("lens MUST be a string!")
+ if not isinstance(node_in, string_types):
+ raise TypeError("node_in MUST be a string!")
+ if not isinstance(path, string_types):
+ raise TypeError("path MUST be a string!")
+ if not isinstance(node_out, string_types):
+ raise TypeError("node_out MUST be a string!")
+ if not self.__handle:
+ raise RuntimeError("The Augeas object has already been closed!")
+
+ # Call the function
+ ret = Augeas._libaugeas.aug_text_retrieve(
+ self.__handle, enc(lens), enc(node_in), enc(path), enc(node_out))
+ if ret != 0:
+ raise ValueError("Unable to store text at node!")
return ret
def defvar(self, name, expr):
@@ -180,16 +269,16 @@
# Sanity checks
if type(name) != str:
- raise TypeError, "name MUST be a string!"
+ raise TypeError("name MUST be a string!")
if type(expr) != str and expr != None:
- raise TypeError, "expr MUST be a string or None!"
+ raise TypeError("expr MUST be a string or None!")
if not self.__handle:
- raise RuntimeError, "The Augeas object has already been closed!"
+ raise RuntimeError("The Augeas object has already been closed!")
# Call the function
- ret = Augeas._libaugeas.aug_defvar(self.__handle, name, expr)
+ ret = Augeas._libaugeas.aug_defvar(self.__handle, enc(name), enc(expr))
if ret < 0:
- raise ValueError, "Unable to register variable!"
+ raise ValueError("Unable to register variable!")
return ret
def defnode(self, name, expr, value):
@@ -204,18 +293,19 @@
# Sanity checks
if type(name) != str:
- raise TypeError, "name MUST be a string!"
+ raise TypeError("name MUST be a string!")
if type(expr) != str:
- raise TypeError, "expr MUST be a string!"
+ raise TypeError("expr MUST be a string!")
if type(value) != str:
- raise TypeError, "value MUST be a string!"
+ raise TypeError("value MUST be a string!")
if not self.__handle:
- raise RuntimeError, "The Augeas object has already been closed!"
+ raise RuntimeError("The Augeas object has already been closed!")
# Call the function
- ret = Augeas._libaugeas.aug_defnode(self.__handle, name, expr, value, None)
+ ret = Augeas._libaugeas.aug_defnode(
+ self.__handle, enc(name), enc(expr), enc(value), None)
if ret < 0:
- raise ValueError, "Unable to register node!"
+ raise ValueError("Unable to register node!")
return ret
def move(self, src, dst):
@@ -226,17 +316,34 @@
does not exist yet, it and all its missing ancestors are created."""
# Sanity checks
- if not isinstance(src, basestring):
+ if not isinstance(src, string_types):
raise TypeError("src MUST be a string!")
- if not isinstance(dst, basestring):
+ if not isinstance(dst, string_types):
raise TypeError("dst MUST be a string!")
if not self.__handle:
raise RuntimeError("The Augeas object has already been closed!")
# Call the function
- ret = Augeas._libaugeas.aug_mv(self.__handle, src, dst)
+ ret = Augeas._libaugeas.aug_mv(self.__handle, enc(src), enc(dst))
if ret != 0:
raise ValueError("Unable to move src to dst!")
+
+ def rename(self, src, dst):
+ """Rename the label of all nodes matching 'src' to 'lbl'."""
+
+ # Sanity checks
+ if not isinstance(src, string_types):
+ raise TypeError("src MUST be a string!")
+ if not isinstance(dst, string_types):
+ raise TypeError("dst MUST be a string!")
+ if not self.__handle:
+ raise RuntimeError("The Augeas object has already been closed!")
+
+ # Call the function
+ ret = Augeas._libaugeas.aug_rename(self.__handle, enc(src), enc(dst))
+ if ret < 0:
+ raise ValueError("Unable to rename src as dst!")
+ return ret
def insert(self, path, label, before=True):
"""Create a new sibling 'label' for 'path' by inserting into the tree
@@ -248,16 +355,16 @@
index '[N]'."""
# Sanity checks
- if not isinstance(path, basestring):
+ if not isinstance(path, string_types):
raise TypeError("path MUST be a string!")
- if not isinstance(label, basestring):
+ if not isinstance(label, string_types):
raise TypeError("label MUST be a string!")
if not self.__handle:
raise RuntimeError("The Augeas object has already been closed!")
# Call the function
- ret = Augeas._libaugeas.aug_insert(self.__handle, path,
- label, before and 1 or 0)
+ ret = Augeas._libaugeas.aug_insert(self.__handle, enc(path),
+ enc(label), before and 1 or 0)
if ret != 0:
raise ValueError("Unable to insert label!")
@@ -267,13 +374,13 @@
removed."""
# Sanity checks
- if not isinstance(path, basestring):
+ if not isinstance(path, string_types):
raise TypeError("path MUST be a string!")
if not self.__handle:
raise RuntimeError("The Augeas object has already been closed!")
# Call the function
- return Augeas._libaugeas.aug_rm(self.__handle, path)
+ return Augeas._libaugeas.aug_rm(self.__handle, enc(path))
def match(self, path):
"""Return the matches of the path expression 'path'. The returned paths
@@ -292,7 +399,7 @@
matches more than one path segment."""
# Sanity checks
- if not isinstance(path, basestring):
+ if not isinstance(path, string_types):
raise TypeError("path MUST be a string!")
if not self.__handle:
raise RuntimeError("The Augeas object has already been closed!")
@@ -302,26 +409,61 @@
array = ctypes.POINTER(ctypes.c_void_p)()
# Call the function and pass the void ** by reference (void ***)
- ret = Augeas._libaugeas.aug_match(self.__handle, path,
+ ret = Augeas._libaugeas.aug_match(self.__handle, enc(path),
ctypes.byref(array))
if ret < 0:
- raise RuntimeError("Error during match procedure!")
+ raise RuntimeError("Error during match procedure!", path)
# Loop through the string array
matches = []
for i in range(ret):
if array[i]:
# Create a python string and append it to our matches list
- matches.append(str(ctypes.cast(array[i],
+ matches.append(dec(ctypes.cast(array[i],
ctypes.c_char_p).value))
# Free the string at this point in the array
- Augeas._libpython.PyMem_Free(array[i])
+ # Wrap the string as a void* as it was not allocated by Python
+ ctypes.pythonapi.PyMem_Free(ctypes.c_void_p(array[i]))
# Free the array itself
- Augeas._libpython.PyMem_Free(array)
+ ctypes.pythonapi.PyMem_Free(array)
return matches
+
+ def span(self, path):
+ """Get the span according to input file of the node associated with
+ PATH. If the node is associated with a file, un tuple of 5 elements is
+ returned: (filename, label_start, label_end, value_start, value_end,
+ span_start, span_end). If the node associated with PATH doesn't
+ belong to a file or is doesn't exists, ValueError is raised."""
+
+ # Sanity checks
+ if not isinstance(path, string_types):
+ raise TypeError("path MUST be a string!")
+ if not self.__handle:
+ raise RuntimeError("The Augeas object has already been closed!")
+
+ filename = ctypes.c_char_p()
+ label_start = ctypes.c_uint()
+ label_end = ctypes.c_uint()
+ value_start = ctypes.c_uint()
+ value_end = ctypes.c_uint()
+ span_start = ctypes.c_uint()
+ span_end = ctypes.c_uint()
+
+ r = ctypes.byref
+
+ ret = Augeas._libaugeas.aug_span(self.__handle, enc(path), r(filename),
+ r(label_start), r(label_end),
+ r(value_start), r(value_end),
+ r(span_start), r(span_end))
+ if (ret < 0):
+ raise ValueError("Error during span procedure")
+
+ return (dec(filename.value), label_start.value, label_end.value,
+ value_start.value, value_end.value,
+ span_start.value, span_end.value)
def save(self):
"""Write all pending changes to disk. Only files that had any changes
@@ -387,23 +529,44 @@
lens: the (file)name of the lens to use
incl: one or more glob patterns for the files to transform
- name: a unique name; use the module name of the lens if omitted
+ name: deprecated parameter
excl: zero or more glob patterns of files to exclude from transforming
"""
- if not name:
- name = lens.split(".")[0].replace("@", "", 1)
- if isinstance (incl, basestring):
+ if name:
+ import warnings
+ warnings.warn("name is now deprecated in this function", DeprecationWarning,
+ stacklevel=2)
+ if isinstance (incl, string_types):
incl = [incl]
- if isinstance (excl, basestring):
+ if isinstance (excl, string_types):
excl = [excl]
- xfm = "/augeas/load/%s/" % name
- self.set (xfm + "lens", lens)
for i in range(len(incl)):
- self.set(xfm + "incl[%d]" % (i+1), incl[i])
+ self.transform(lens, incl[i], False)
for i in range(len(excl)):
- self.set(xfm + "excl[%d]" % (i+1), excl[i])
+ self.transform(lens, excl[i], True)
+
+ def transform(self, lens, file, excl=False):
+ """Add a transform for 'file' using 'lens'.
+ 'excl' specifies if this the file is to be included (False)
+ or excluded (True) from the 'lens'.
+ The 'lens' may be a module name or a full lens name.
+ If a module name is given, then lns will be the lens assumed.
+ """
+
+ if not isinstance(lens, string_types):
+ raise TypeError("lens MUST be a string!")
+ if not isinstance(file, string_types):
+ raise TypeError("file MUST be a string!")
+ if not isinstance(excl, bool):
+ raise TypeError("excl MUST be a boolean!")
+ if not self.__handle:
+ raise RuntimeError("The Augeas object has already been closed!")
+
+ ret = Augeas._libaugeas.aug_transform(self.__handle, enc(lens), enc(file), excl)
+ if ret != 0:
+ raise RuntimeError("Unable to add transform!")
def close(self):
"""Close this Augeas instance and free any storage associated with it.
--
To view, visit http://gerrit.ovirt.org/35586
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If78a333b44ac2441bba685e65938871f652631c6
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Fabian Deutsch <fabiand at redhat.com>
More information about the node-patches
mailing list