summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/server/info.txt26
-rw-r--r--schemas/info.xsd3
-rw-r--r--src/lib/Server/Plugin.py25
3 files changed, 36 insertions, 18 deletions
diff --git a/doc/server/info.txt b/doc/server/info.txt
index 0d273c2b6..192805ed4 100644
--- a/doc/server/info.txt
+++ b/doc/server/info.txt
@@ -85,16 +85,16 @@ specification.
info.xml files
==============
-``info.xml`` files add the ability to specify different
-sets of file metadata on a group by group or host by host
-basis. These files are XML, and work similarly to those used by
-:ref:`Rules <server-plugins-generators-rules>` or :ref:`Pkgmgr
+``info.xml`` files add the ability to specify different sets of file
+metadata on a group by group or host by host basis, or by path (for
+files using :ref:`altsrc <server-plugins-structures-altsrc>`). These
+files are XML, and work similarly to those used by :ref:`Rules
+<server-plugins-generators-rules>` or :ref:`Pkgmgr
<server-plugins-generators-pkgmgr>`.
The following specifies a different global set of permissions
-(root/sys/0651) than on clients in group webserver (root/root/0652)
-
-.. code-block:: xml
+(root/sys/0651) than on clients in group webserver or named
+"foo.example.com" (root/root/0652)::
<FileInfo>
<Client name='foo.example.com'>
@@ -105,3 +105,15 @@ The following specifies a different global set of permissions
</Group>
<Info owner='root' group='sys' perms='0651'/>
</FileInfo>
+
+The following specifies a different set of permissions depending on
+the path of the file::
+
+ <FileInfo>
+ <Path name="/etc/bcfg2-web.conf">
+ <Info owner="root" group="apache" perms="0640"/>
+ </Path>
+ <Path name="/etc/bcfg2-web.conf" negate="true">
+ <Info owner="root" group="root" perms="0600"/>
+ </Path>
+ </FileInfo>
diff --git a/schemas/info.xsd b/schemas/info.xsd
index 169310ab6..37232ab23 100644
--- a/schemas/info.xsd
+++ b/schemas/info.xsd
@@ -25,6 +25,8 @@
maxOccurs='unbounded'/>
<xsd:element name='Client' type='GroupType' minOccurs='0'
maxOccurs='unbounded'/>
+ <xsd:element name='Path' type='GroupType' minOccurs='0'
+ maxOccurs='unbounded'/>
</xsd:choice>
<xsd:attribute type='xsd:string' name='name' use='required'/>
<xsd:attribute type='xsd:boolean' name='negate' />
@@ -35,6 +37,7 @@
<xsd:choice minOccurs='0' maxOccurs='unbounded'>
<xsd:element name='Group' type='GroupType'/>
<xsd:element name='Client' type='GroupType'/>
+ <xsd:element name='Path' type='GroupType'/>
<xsd:element name='Info' type='InfoType'/>
</xsd:choice>
</xsd:complexType>
diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py
index a05c537e5..17547be13 100644
--- a/src/lib/Server/Plugin.py
+++ b/src/lib/Server/Plugin.py
@@ -510,18 +510,20 @@ class INode:
LNodes provide lists of things available at a particular
group intersection.
"""
- raw = {'Client': "lambda x:'%s' == x.hostname and predicate(x)",
- 'Group': "lambda x:'%s' in x.groups and predicate(x)"}
- nraw = {'Client': "lambda x:'%s' != x.hostname and predicate(x)",
- 'Group': "lambda x:'%s' not in x.groups and predicate(x)"}
- containers = ['Group', 'Client']
+ raw = {'Client': "lambda m, e:'%(name)s' == m.hostname and predicate(m, e)",
+ 'Group': "lambda m, e:'%(name)s' in m.groups and predicate(m, e)",
+ 'Path': "lambda m, e:('%(name)s' == e.get('name') or '%(name)s' == e.get('realname')) and predicate(m, e)"}
+ nraw = {'Client': "lambda m, e:'%(name)s' != m.hostname and predicate(m, e)",
+ 'Group': "lambda m, e:'%(name)s' not in m.groups and predicate(m, e)",
+ 'Path': "lambda m, e:('%(name)s' != e.get('name') and '%(name)s' != e.get('realname')) and predicate(m, e)"}
+ containers = ['Group', 'Client', 'Path']
ignore = []
def __init__(self, data, idict, parent=None):
self.data = data
self.contents = {}
if parent == None:
- self.predicate = lambda x: True
+ self.predicate = lambda m, d: True
else:
predicate = parent.predicate
if data.get('negate', 'false') in ['true', 'True']:
@@ -529,7 +531,8 @@ class INode:
else:
psrc = self.raw
if data.tag in list(psrc.keys()):
- self.predicate = eval(psrc[data.tag] % (data.get('name')),
+ self.predicate = eval(psrc[data.tag] %
+ {'name': data.get('name')},
{'predicate': predicate})
else:
raise Exception
@@ -552,9 +555,9 @@ class INode:
except KeyError:
idict[item.tag] = [item.get('name')]
- def Match(self, metadata, data):
+ def Match(self, metadata, data, entry=lxml.etree.Element("None")):
"""Return a dictionary of package mappings."""
- if self.predicate(metadata):
+ if self.predicate(metadata, entry):
for key in self.contents:
try:
data[key].update(self.contents[key])
@@ -562,7 +565,7 @@ class INode:
data[key] = {}
data[key].update(self.contents[key])
for child in self.children:
- child.Match(metadata, data)
+ child.Match(metadata, data, entry=entry)
class XMLSrc(XMLFileBacked):
@@ -853,7 +856,7 @@ class EntrySet:
entry.set(key, self.metadata[key])
if self.infoxml:
mdata = {}
- self.infoxml.pnode.Match(metadata, mdata)
+ self.infoxml.pnode.Match(metadata, mdata, entry=entry)
if 'Info' not in mdata:
logger.error("Failed to set metadata for file %s" % \
(entry.get('name')))