[elbe-devel] [PATCH v3 4/4] Unpack the archives depending on volume attribute

Akash Satamkar akash at linutronix.de
Tue Sep 17 15:29:36 CEST 2019


The volume attribute can be used to specify the volume number
in which the archive is added.

When volume attribute is not specified, the archive is added
to each volume.

Signed-off-by: Akash Satamkar <akash at linutronix.de>
---
 elbepack/archivedir.py  | 65 +++++++++++++++++++++++++++++------------
 elbepack/cdroms.py      | 18 ++++++++++++
 elbepack/repomanager.py | 14 +++++++--
 3 files changed, 76 insertions(+), 21 deletions(-)

diff --git a/elbepack/archivedir.py b/elbepack/archivedir.py
index 10155228..1d357236 100644
--- a/elbepack/archivedir.py
+++ b/elbepack/archivedir.py
@@ -13,12 +13,14 @@ try:
 except ImportError:
     from urlparse import urljoin,urlparse
 
-from base64 import standard_b64encode
+from base64 import standard_b64encode, standard_b64decode
 from bz2 import compress as bz2compress
 from subprocess import CalledProcessError
-
+from tempfile import NamedTemporaryFile
 from elbepack.treeutils import etree
 from elbepack.shellhelper import system
+from elbepack.filesystem import TmpdirFilesystem
+
 
 class ArchivedirError(Exception):
     pass
@@ -67,9 +69,17 @@ def chg_archive(xml, path, keep):
 
     return xml
 
+
+def archive_tmpfile(arch_elem):
+    fp = NamedTemporaryFile()
+    fp.write(standard_b64decode(arch_elem))
+    fp.file.flush()
+    return fp
+
+
 def prepare_path(url):
     url = urlparse(url)
-    path = url.geturl().replace("%s://"%url.scheme, '', 1)
+    path = url.geturl().replace("%s://" % url.scheme, '', 1)
     return re.sub(r'/$', "", path)
 
 def get_and_append_local(url, tararchive, keep):
@@ -90,32 +100,51 @@ def get_and_append_method(url):
         'file': get_and_append_local,
     }.get(urlparse(url).scheme, get_and_append_unknown)
 
-def _combinearchivedir(xml):
+def _combinearchivedir(xml, xpath, use_volume):
     elbexml = etree(None)
     elbexml.et = xml
 
-    archive = '.combinedarchive.tar'
-    for archivedir in xml.iterfind("archivedir"):
+    tmp = TmpdirFilesystem()
+    for archivedir in elbexml.all(xpath):
+
         try:
-            archiveurl = urljoin(archivedir.base, archivedir.text)
-            keep = elbexml.check_boolean(archivedir, "keep-attributes")
+            archiveurl = urljoin(archivedir.et.base, archivedir.et.text)
+            keep = archivedir.bool_attr("keep-attributes")
+            parent = archivedir.get_parent()
+
+            if use_volume:
+                volume_attr = archivedir.et.get('volume', default='all')
+                fname_suffix = volume_attr
+
+                arch = parent.node("archive[@volume='%s']" % volume_attr)
+
+                if arch is None:
+                    arch = parent.append("archive")
+                    arch.et.set("volume", volume_attr)
+
+            else:
+                arch = parent.ensure_child("archive")
+                fname_suffix = ''
+
+
             get_and_append = get_and_append_method(archiveurl)
-            get_and_append(archiveurl, archive, keep)
-            archivedir.getparent().remove(archivedir)
+
+            archname = tmp.fname('archive%s.tar.bz2' % fname_suffix)
+            get_and_append(archiveurl, archname, keep)
+            arch.set_text(enbase(archname, True))
+
+            parent.remove_child(archivedir)
         except (CalledProcessError, OSError):
             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:
+    if xml.find("//archivedir") is None:
         return xml
 
-    return _combinearchivedir(xml)
+    _combinearchivedir(xml, "archivedir", False)
+    _combinearchivedir(xml, "src-cdrom/archivedir", True)
+
+    return xml
diff --git a/elbepack/cdroms.py b/elbepack/cdroms.py
index d2c1b2b0..d9e67195 100644
--- a/elbepack/cdroms.py
+++ b/elbepack/cdroms.py
@@ -12,6 +12,8 @@ import logging
 from shutil import copyfile
 
 from apt.package import FetchError
+
+from elbepack.archivedir import archive_tmpfile
 from elbepack.rpcaptcache import get_rpcaptcache
 from elbepack.repomanager import CdromSrcRepo
 from elbepack.repomanager import CdromBinRepo
@@ -91,6 +93,22 @@ def mk_source_cdrom(rfs, arch, codename, init_codename, target,
 
     if xml is not None:
         options = get_iso_options(xml)
+
+        for arch_vol in xml.node('src-cdrom').all('archive'):
+            volume_attr = arch_vol.et.get('volume')
+
+            if volume_attr == 'all':
+                volume_list = repo.volume_indexes
+            else:
+                volume_list = [int(v) for v in volume_attr.split(",")]
+            for volume_number in volume_list:
+                with archive_tmpfile(arch_vol.text(".")) as fp:
+                    if volume_number in repo.volume_indexes:
+                        do('tar xvfj "%s" -h -C "%s"' % (fp.name,
+                                repo.get_volume_fs(volume_number).path))
+                    else:
+                        logging.warning("The src-cdrom archive's volume value "
+                                "is not contained in the actual volumes")
     else:
         options = ""
 
diff --git a/elbepack/repomanager.py b/elbepack/repomanager.py
index f8ec8a23..1312ee45 100644
--- a/elbepack/repomanager.py
+++ b/elbepack/repomanager.py
@@ -9,7 +9,6 @@
 
 import os
 import shutil
-import logging
 
 from debian.deb822 import Deb822
 
@@ -98,7 +97,13 @@ class RepoBase(object):
 
     def get_volume_fs(self, volume):
         if self.maxsize:
-            volname = os.path.join(self.vol_path, "vol%02d" % volume)
+            if volume >= 0:
+                volume_no = volume
+            else:
+                # negative numbers represent the volumes counted from last
+                # (-1: last, -2: second last, ...)
+                volume_no = self.volume_count + 1 + volume
+            volname = os.path.join(self.vol_path, "vol%02d" % volume_no)
             return Filesystem(volname)
 
         return Filesystem(self.vol_path)
@@ -289,7 +294,7 @@ class RepoBase(object):
                (options, fname, new_path))
             files.append(fname)
         else:
-            for i in range(self.volume_count + 1):
+            for i in self.volume_indexes:
                 volfs = self.get_volume_fs(i)
                 newname = fname + ("%02d" % i)
                 do("genisoimage %s -o %s -J -joliet-long -R %s" %
@@ -298,6 +303,9 @@ class RepoBase(object):
 
         return files
 
+    @property
+    def volume_indexes(self):
+        return range(self.volume_count + 1)
 
 class UpdateRepo(RepoBase):
     def __init__(self, xml, path):
-- 
2.20.1




More information about the elbe-devel mailing list