[elbe-devel] [PATCH 1/2] preprocess: allow building variants of a xml file

Manuel Traut manut at linutronix.de
Thu Dec 21 16:06:02 CET 2017


Other build-systems allow building different flavours or variants of a
image based on some config values. This eases the maintainance of very
similar images.

The elbe preprocess subcommand allows modifying XML files before they are
used with other elbe subcommands. The XML file used by the preprocess
subcommand doesn't need to validate with 'dbsfed.xsd', but the output needs
to.

This adds a new parameter '--variant' to the 'preprocess' subcommand. A
XML tag inside the XML file given to 'preprocess' can contain a 'variant'
attribute. If the value of the variant attribute inside XML matches with
a variant given as parameter to the preprocess command, the XML tag
stays inside the XML file. If the XML tag has a variant attribute but
doesn't match with the variant given as parameter to 'preprocess' the
XML tag will be dropped. If no 'variant' parameter is given to the
'preprocess' subcommand all tags with a 'variant' parameter are dropped.

This allows XML snippets like this:

  <url variant='security'>
          <binary>http://security.debian.org/ stretch/updates main</binary>
          <source>http://security.debian.org/ stretch/updates main</source>
  </url>

  <pkg-list>
          <pkg variant='security'>openssh-server</pkg>
          <pkg variant='audio,video'>totem</pkg>
  </pkg-list>

Signed-off-by: Manuel Traut <manut at linutronix.de>
---
 debian/control                  |  2 ++
 elbepack/commands/preprocess.py |  9 ++++++++-
 elbepack/xmlpreprocess.py       | 31 ++++++++++++++++++++++++++++++-
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/debian/control b/debian/control
index c9454ae5..5889a751 100644
--- a/debian/control
+++ b/debian/control
@@ -59,6 +59,7 @@ Depends: ${misc:Depends},
   python-gpgme,
   python-pyme|python-gpg,
   python-libvirt,
+  python-numpy,
   wget,
   cpio
 Description: common files
@@ -75,6 +76,7 @@ Depends: ${misc:Depends},
   python3-gpgme,
   python3-gpg,
   python3-libvirt,
+  python3-numpy,
   wget,
   cpio
 Description: common files
diff --git a/elbepack/commands/preprocess.py b/elbepack/commands/preprocess.py
index b39f6317..ad3e8726 100644
--- a/elbepack/commands/preprocess.py
+++ b/elbepack/commands/preprocess.py
@@ -16,6 +16,9 @@ def run_command(argv):
     oparser.add_option("-o", "--output", dest="output",
                        default="preprocess.xml",
                        help="preprocessed output file", metavar="<xmlfile>")
+    oparser.add_option("-v", "--variants", dest="variant",
+                       default=None,
+                       help="enable only tags with empty or given variant")
     (opt, args) = oparser.parse_args(argv)
 
     if len(args) != 1:
@@ -27,8 +30,12 @@ def run_command(argv):
         print("%s doesn't exist" % args[0], file=sys.stderr)
         sys.exit(20)
 
+    variants = []
+    if opt.variant:
+        variants = opt.variant.split(',')
+
     try:
-        xmlpreprocess(args[0], opt.output)
+        xmlpreprocess(args[0], opt.output, variants)
     except XMLPreprocessError as e:
         print(e, file=sys.stderr)
         sys.exit(20)
diff --git a/elbepack/xmlpreprocess.py b/elbepack/xmlpreprocess.py
index 3b479fef..3c9b9af0 100644
--- a/elbepack/xmlpreprocess.py
+++ b/elbepack/xmlpreprocess.py
@@ -6,6 +6,7 @@
 import sys
 from lxml import etree
 from lxml.etree import XMLParser, parse
+from numpy import intersect1d
 
 
 class XMLPreprocessError(Exception):
@@ -13,7 +14,7 @@ class XMLPreprocessError(Exception):
         Exception.__init__(self, message)
 
 
-def xmlpreprocess(fname, output):
+def xmlpreprocess(fname, output, variants=[]):
     schema_file = "https://www.linutronix.de/projects/Elbe/dbsfed.xsd"
     parser = XMLParser(huge_tree=True)
     schema_tree = etree.parse(schema_file)
@@ -23,6 +24,34 @@ def xmlpreprocess(fname, output):
         xml = parse(fname, parser=parser)
         xml.xinclude()
 
+        rmlist = []
+        for tag in xml.iter('*'):
+            if 'variant' in tag.attrib:
+                if not len(variants):
+                    # remove tags with variant attribute if no variant is
+                    # specified to be used
+                    rmlist.append(tag)
+                else:
+                    tag_variants = tag.attrib['variant'].split(',')
+                    intersect = intersect1d(tag_variants, variants)
+                    # if variant is wanted, keep it and remove the variant
+                    # attribute
+                    if len(intersect):
+                        tag.attrib.pop('variant')
+                    # if tag has a variant attribute but the variant was not
+                    # specified remove the tag
+                    else:
+                        rmlist.append(tag)
+
+        # postponed tag deletion
+        for tag in rmlist:
+            tag.getparent().remove(tag)
+
+        xml.write(
+            output,
+            encoding="UTF-8",
+            pretty_print=True)
+
         if schema.validate(xml):
             xml.write(
                 output,
-- 
2.15.1




More information about the elbe-devel mailing list