[elbe-devel] [PATCH 2/3] Add archivedir support

Benedikt Spranger b.spranger at linutronix.de
Thu Jul 5 10:44:36 CEST 2018


The <archive> handling is unwieldy to track changes in the archive,
since it is not obvious, what changed in a base64 encoded bziped tar
archive.

Furthermore it has major drawbacks in variant handling:
If a variant needs changes in the archive the whole archive needs
to be exchanged. The changes between these archives are neither
obvious too.

The new element <archivedir> points to an local directory and add
the content into a newly created archive. <archivedir> can be
specified more then once. The content of the direcories is copied
in order of appearance. Existing files are overwritten by the later
ones. <archive> and <archivedir> are mutual exclusive.

<archivedir> is only allowed in XML files going into 'elbe
preprocess' and are converted into an <archive> tag by this elbe
subcommand.

Example snippet to use <archivedir>:
...
<archivedir>foo</archivedir>
<archivedir variant="production">bar</archivedir>
<archivedir keep-attributes="true">baz</archivedir>
<archivedir>file:///overlay</archivedir>
...

Keep in mind that URIs matching 'file://[^/].*' are rejected.
Handling these URIs is misleading at least and vary between
implementations.

Signed-off-by: Benedikt Spranger <b.spranger at linutronix.de>
Reviewed-by: Manuel Traut <manut at linutronix.de>
---
 elbepack/archivedir.py | 66 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/elbepack/archivedir.py b/elbepack/archivedir.py
index 5a363b81..14df26f2 100644
--- a/elbepack/archivedir.py
+++ b/elbepack/archivedir.py
@@ -4,13 +4,24 @@
 # SPDX-License-Identifier: GPL-3.0-or-later
 
 import os
+import re
+import sys
+
+# The urlparse module is renamed to urllib.parse in Python 3.
+try:
+    from urllib.parse import urljoin,urlparse
+except ImportError:
+    from urlparse import urljoin,urlparse
 
 from base64 import standard_b64encode
 from bz2 import compress as bz2compress
-from subprocess import check_call
+from subprocess import CalledProcessError, check_call
 
 from elbepack.treeutils import etree
 
+class ArchivedirError(Exception):
+    pass
+
 def enbase(fname, compress=True):
     infile = file(fname, "r")
     s = infile.read()
@@ -54,3 +65,56 @@ def chg_archive(xml, path, keep):
         os.remove(archive)
 
     return xml
+
+def prepare_path(url):
+    url = urlparse(url)
+    path = url.geturl().replace("%s://"%url.scheme, '', 1)
+    return re.sub(r'/$', "", path)
+
+def get_and_append_local(url, tararchive, keep):
+    if urlparse(url).netloc:
+        msg = "Reject suspicious file:// URI \"{}\". ".format(url)
+        msg += "Please use an absolute URI (file:///a/b/c) or a "
+        msg += "relative URI (a/b/c) instead."
+        raise ArchivedirError(msg)
+    collect(tararchive, prepare_path(url), keep)
+
+def get_and_append_unknown(url, archive):
+    msg = "unhandled scheme \"{}://\"".format(urlparse(url).scheme)
+    raise NotImplementedError(msg)
+
+def get_and_append_method(url):
+    return {
+        '': get_and_append_local,
+        'file': get_and_append_local,
+    }.get(urlparse(url).scheme, get_and_append_unknown)
+
+def _combinearchivedir(xml):
+    elbexml = etree(None)
+    elbexml.et = xml
+
+    archive = '.combinedarchive.tar'
+    for archivedir in xml.iterfind("archivedir"):
+        try:
+            archiveurl = urljoin(archivedir.base, archivedir.text)
+            keep = elbexml.check_boolean(archivedir, "keep-attributes")
+            get_and_append = get_and_append_method(archiveurl)
+            get_and_append(archiveurl, archive, keep)
+            archivedir.getparent().remove(archivedir)
+        except (CalledProcessError, OSError) as ex:
+            msg = "Failure while processing \"" + archivedir.text + "\":\n"
+            msg += str(sys.exc_info()[1])
+            raise ArchivedirError(msg)
+
+    arch = elbexml.ensure_child("archive")
+    arch.set_text(enbase(archive, True))
+
+    os.remove(archive)
+
+    return xml
+
+def combinearchivedir(xml):
+    if xml.find("archivedir") is None:
+        return xml
+
+    return _combinearchivedir(xml)
-- 
2.18.0




More information about the elbe-devel mailing list