(no commit message)
authorSapan Bhatia <sapanb@cs.princeton.edu>
Sat, 15 Aug 2009 00:33:02 +0000 (00:33 +0000)
committerSapan Bhatia <sapanb@cs.princeton.edu>
Sat, 15 Aug 2009 00:33:02 +0000 (00:33 +0000)
sfatables/README
sfatables/matches/hrn.xml
sfatables/sfatables
sfatables/targets/filternodes.xsl [new file with mode: 0644]
sfatables/xmlextension.py [new file with mode: 0644]

index 2151922..050e54a 100644 (file)
@@ -30,3 +30,10 @@ E.g. if the policy is that your site is limited to < 1000 slivers (e.g. sfatable
 only requires the user's HRN. A site's slice count match may require the number of slices/site. The config file consists of a set of 
 
 - When sfa needs to invoke sfatables, it passes a 'rule context' (i.e. the parameter to the sfatables command line) along with the input from the current context to the appropriate match. If it returns True, then it goes on to invoke target specified by the rule, and uses the filtered version of the rspec that it produces.
+
+
+Specifics:
+
+- On startup sfa calls sfatables.load(), which loads available commands, matches and targets
+
+- When invoking sfatables 
index 1200160..ff6bbde 100644 (file)
@@ -7,8 +7,8 @@ as the one matched by this rule.
 
 -->
 
-<match xmlns="http://www.planet-lab.org/sfa/sfatables/match/2009/8">
-    <sfa-input select="//sfa//user/hrn"/>
-    <rule-input select="//request//user/hrn"/>
+<match>
+    <context select="//sfa//user/hrn"/>
+    <rule><argument param="user-hrn"/></rule-input>
     <processor name="hrn.xsl"/>
 </match>
index 8762a50..977153e 100755 (executable)
 import sys
 import os
 import pdb
+import libxml2
 from optparse import OptionParser
 
 from sfatables import commands, matches, targets
+from sfatables import Xmlextension
 
-def load_extensions(module, list):
-    command_dict={}
+def load_commands(module, list):
+    ext_dict={}
 
     for command_name in list:
         command_module = __import__(".".join([module,command_name]),fromlist=[module])
         command = getattr(command_module, command_name)
         command_dict[command_name]=command()
 
-    return command_dict
+    return ext_dict
+
+def load_xml_extensions(module, list):
+    ext_dict={}
+
+    for ext_name in list:
+        module = Xmlextension(ext_name)
+        ext_dict[ext_name]=module
+
+    return ext_dict
+
 
 def create_parser(command_dict):
     parser = OptionParser(usage="sfatables [command] [chain] [match] [target]",
@@ -35,6 +47,17 @@ def create_parser(command_dict):
 
     return parser
 
+def xml_ext_create_parser(ext_dict):
+    parser = OptionParser(usage="sfatables [command] [chain] [match] [target]",
+                             description='See "man sfatables" for more detail.')
+    
+    for k in command_dict.keys():
+        command = command_dict[k]
+        for arg in command.arguments:
+            parser.add_option(None,"--"+arg,dest=arg,help=command.help,metavar=command.operand)
+
+    return parser
+
 
 def partition(sep, lst):
     ret = []
@@ -55,7 +78,7 @@ def main():
     
     pargs = partition('--', sys.argv[1:])
 
-    command_dict = load_extensions("sfatables.commands",commands.all)
+    command_dict = load_commands("sfatables.commands",commands.all)
     command_parser = create_parser(command_dict)
     (options, args) = command_parser.parse_args()
 
@@ -64,7 +87,7 @@ def main():
     if (command.matches):
         if (len(pargs)<2):
             raise Exception("Must specify match for this command")
-        match_dict = load_extensions("sfatables.matches",matches.all)
+        match_dict = load_xml_extensions("sfatables.matches",matches.all)
         match_parser = create_parser(match_dict)
         (match_options, args) = match_parser.parse_args(pargs[1])
     else:
@@ -73,7 +96,7 @@ def main():
     if (command.targets):
         if (len(pargs)<3):
             raise Exception("Must specify a target for this command")
-        match_dict = load_extensions("sfatables.targets",targets.all)
+        match_dict = load_xml_extensions("sfatables.targets",targets.all)
         target_parser = create_parser(match_dict)
         (target_options, args) = target_parser.parse_args(pargs[2])
     else:
diff --git a/sfatables/targets/filternodes.xsl b/sfatables/targets/filternodes.xsl
new file mode 100644 (file)
index 0000000..d65a2ae
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- This is an aggregate-specific target for the PL aggregate.
+     Its function is to drop nodes that do not match the user-specified pattern.
+-->
+
+<xsl:stylesheet version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+    <xsl:template match="/">
+        <xsl:variable name="result">
+            <xsl:for-each select="//rspec-match/context-input//nodespec">
+                <xsl:variable name="context-hostname" select="hostname"/>
+                <xsl:for-each select="//rspec-match/rule-input//user">
+                    <xsl:choose>
+                    <xsl:when test="starts-with($context-hrn, hrn)">
+                        True
+                    </xsl:when>
+                    <xsl:otherwise>
+                        False
+                    </xsl:otherwise>
+                </xsl:choose>
+                </xsl:for-each>
+            </xsl:for-each>
+        </xsl:variable>
+        <xsl:value-of select="$result"/>
+    </xsl:template>
+</xsl:stylesheet>
diff --git a/sfatables/xmlextension.py b/sfatables/xmlextension.py
new file mode 100644 (file)
index 0000000..b4b52cd
--- /dev/null
@@ -0,0 +1,30 @@
+import libxml2
+
+class Xmlextension:
+    context = ""
+    processor = ""
+    operand = "VALUE"
+    arguments = []
+
+    def __init__(filename):
+        self.xmldoc = libxml2.parseFile(filename)
+        # TODO: Check xmldoc against a schema
+
+        p = self.xmldoc.XPathNewContext()
+
+        # <context select="..."/>
+        # <rule><argument param="..."/></rule>
+        # <processor name="..."/>
+
+        context = p.xpathEval('//context/@select')
+        self.context = context[0].value
+
+        processor = p.xpathEval('//processor@name')
+        self.context = processor[0].value
+
+        params = p.xpathEval('//rule/argument/@param')
+        self.arguments = [node.value for node in params]
+
+
+        return
+