[libvirt] [PATCH 3/4] xkcd: enabling pre-processing of XML with perl

Daniel P. Berrange berrange at redhat.com
Fri Apr 1 11:30:29 UTC 2016


As told in comic 224, God mostly hacked together the universe
using perl. If it is good enough for God, it is good enough
for libvirt. So this extends the XML parser so that it feeds
all XML through a perl script allowing arbitrary modifications.

For example, if you think your guest domain names are not
christmasy enough you can use this script to add snowmen
to their names

   $ cat > hack.pl <<EOF
   #!/usr/bin/perl

   while (<>) {
      s,<name>(.*)</name>,<name>☃$1☃</name>,;
      print;
   }
   EOF

   LIBVIRT_XKCD=221,224:/home/berrange/hack.pl /usr/sbin/libvirtd

   $ virsh list --all
   Id    Name                           State
   ----------------------------------------------------
    -     ☃demo-spec☃                shut off
    -     ☃demo☃                     shut off
    -     ☃nodisplay☃                shut off
    -     ☃ppcdemo☃                  shut off
    -     ☃QEMUGuest1☃               shut off
    -     ☃secret☃                   shut off
    -     ☃serial☃                   shut off

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/util/virxml.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/util/virxml.c b/src/util/virxml.c
index 489bad8..7e94ead 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -37,6 +37,8 @@
 #include "viralloc.h"
 #include "virfile.h"
 #include "virstring.h"
+#include "virxkcd.h"
+#include "vircommand.h"
 
 #define VIR_FROM_THIS VIR_FROM_XML
 
@@ -738,14 +740,35 @@ virXMLParseHelper(int domcode,
     pctxt->_private = &private;
     pctxt->sax->error = catchXMLError;
 
-    if (filename) {
-        xml = xmlCtxtReadFile(pctxt, filename, NULL,
-                              XML_PARSE_NONET |
-                              XML_PARSE_NOWARNING);
-    } else {
-        xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, url, NULL,
+    if (virXKCDIsEnabled(224)) {
+        const char *script = virXKCDGetData(224);
+        virCommandPtr cmd = virCommandNewArgList("perl", script, filename, NULL);
+        char *newXML = NULL;
+
+        if (!filename) {
+            virCommandSetInputBuffer(cmd, xmlStr);
+        }
+        virCommandSetOutputBuffer(cmd, &newXML);
+
+        if (virCommandRun(cmd, NULL) < 0) {
+            virCommandFree(cmd);
+            goto error;
+        }
+        virCommandFree(cmd);
+        xml = xmlCtxtReadDoc(pctxt, BAD_CAST newXML, url, NULL,
                              XML_PARSE_NONET |
                              XML_PARSE_NOWARNING);
+        VIR_FREE(newXML);
+    } else {
+        if (filename) {
+            xml = xmlCtxtReadFile(pctxt, filename, NULL,
+                                  XML_PARSE_NONET |
+                                  XML_PARSE_NOWARNING);
+        } else {
+            xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, url, NULL,
+                                 XML_PARSE_NONET |
+                                 XML_PARSE_NOWARNING);
+        }
     }
     if (!xml)
         goto error;
-- 
2.5.5




More information about the libvir-list mailing list