create-update: support product updates 27/8227/2
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 13 Aug 2013 19:28:25 +0000 (22:28 +0300)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Wed, 14 Aug 2013 07:16:29 +0000 (10:16 +0300)
Support parsing product information metadata from listed packages and
adding that to the repository metadata inside the update.

Bug-Tizen: TZPC-3752

Change-Id: I5b94fe845dd04800da9ed749c7a9d6d0cf8fe0b2
Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
tools/updateinfo/TZPC-UP-0001-01.yaml
tools/updateinfo/create-update.py
tools/updateinfo/updateutils.py

index 056233d..2699de5 100644 (file)
@@ -11,3 +11,5 @@ Status: stable
 ID: TZPC-UP-0001-01
 BlacklistPkgs:
     - broken-pkg
+ProductPkgs:
+    - tizen-release
index b3e153f..2fe1bb1 100755 (executable)
@@ -103,7 +103,9 @@ with open(os.path.join(patch_dir, "repourl"), "w") as repourlfile:
 
 
 blacklist = patch['BlacklistPkgs'] if 'BlacklistPkgs' in patch else []
-repo_dir = create_delta_repo(tmp_dir, patch_dir, cached_pkgs_dir, tmp_dir, credentials, blacklist)
+product_pkgs = patch['ProductPkgs'] if 'ProductPkgs' in patch else []
+repo_dir = create_delta_repo(tmp_dir, patch_dir, cached_pkgs_dir, tmp_dir,
+                             credentials, blacklist, product_pkgs)
 
 # create updateinfo
 create_updateinfo(tmp_dir, patch)
index 9200238..63575f3 100755 (executable)
@@ -3,6 +3,7 @@ import urllib2
 import os
 import re, base64
 import shutil
+import tempfile
 import yaml
 from xml.dom import minidom
 import rpm
@@ -12,6 +13,7 @@ import gzip
 import zipfile
 import hashlib
 import fileinput
+import subprocess
 
 
 def http_get(url, credentials=(None, None)):
@@ -51,7 +53,8 @@ def parse_package_list(filename):
                 packages[pkg[0]] = {'scm': None, 'version': row[1], 'arch': pkg[1]}
     return packages
 
-def create_delta_repo(baseline_dir, target_dir, pkg_cache_dir, tmp_dir, credentials, blacklist):
+def create_delta_repo(baseline_dir, target_dir, pkg_cache_dir, tmp_dir,
+                      credentials, blacklist, product_pkgs):
     p1 = parse_package_list(os.path.join(baseline_dir, "packages"))
     p2 = parse_package_list(os.path.join(target_dir, "packages"))
 
@@ -66,8 +69,10 @@ def create_delta_repo(baseline_dir, target_dir, pkg_cache_dir, tmp_dir, credenti
     old_pkgs_dir = os.path.join(tmp_dir, 'old')
     repo_dir = os.path.join(tmp_dir, 'repo')
     changed_pkgs_dir = os.path.join(repo_dir, 'rpms')
+    product_pkgs_dir = os.path.join(tmp_dir, 'products')
     os.makedirs(old_pkgs_dir)
     os.makedirs(changed_pkgs_dir)
+    os.makedirs(product_pkgs_dir)
     new_pkgs_dir = changed_pkgs_dir
 
     with open(os.path.join(baseline_dir, "repourl"), "r") as repourlfile:
@@ -93,7 +98,20 @@ def create_delta_repo(baseline_dir, target_dir, pkg_cache_dir, tmp_dir, credenti
         rpm = "%s-%s.%s.rpm" % (p, p2[p]['version'], p2[p]['arch'])
         download("%s/%s/%s" % (new_repourl, arch, rpm), credentials, changed_pkgs_dir, pkg_cache_dir)
 
+    for p in product_pkgs:
+        if p in blacklist:
+            raise Exception("Cannot blacklist a product package: %s" % p)
+        rpm = "%s-%s.%s.rpm" % (p, p2[p]['version'], p2[p]['arch'])
+        arch = p2[p]['arch']
+        download("%s/%s/%s" % (new_repourl, arch, rpm), credentials, product_pkgs_dir, pkg_cache_dir)
+
+    products = create_product_info(product_pkgs_dir)
+    products_fn = os.path.join(tmp_dir, 'products.xml')
+    with open(products_fn, 'w') as products_fd:
+        products_fd.write(products)
+
     os.system("createrepo --deltas --oldpackagedirs=%s %s" % (old_pkgs_dir, repo_dir))
+    os.system("modifyrepo %s %s/repodata" % (products_fn, repo_dir))
 
     # Clean up the rpms dir: move all packages for which delta was generated
     nozip_pkgs_dir = os.path.join(repo_dir, 'nozip')
@@ -108,6 +126,29 @@ def create_delta_repo(baseline_dir, target_dir, pkg_cache_dir, tmp_dir, credenti
 
     return repo_dir
 
+def create_product_info(directory):
+    """Go through packages in a directory and extract zypper product info"""
+    tmpdir = tempfile.mkdtemp(dir=directory)
+    try:
+        # Extract the product files in all rpm packages in the given dir
+        for pkg in glob.glob('%s/*.rpm' % directory):
+            proc1 = subprocess.Popen(['rpm2cpio', pkg], stdout=subprocess.PIPE)
+            proc2 = subprocess.Popen(['cpio', '-id', './etc/products.d/*.prod'],
+                    stdin=proc1.stdout, cwd=tmpdir)
+            proc2.communicate()
+        # New document for listing all products
+        doc = minidom.Document()
+        root = doc.appendChild(doc.createElement('products'))
+
+        # Read all the product files and append data to our product database
+        for prod_file in glob.glob('%s/etc/products.d/*.prod' % tmpdir):
+            tmp_doc = minidom.parse(prod_file)
+            for product in tmp_doc.getElementsByTagName('product'):
+                root.appendChild(product)
+        return doc.toxml('UTF-8')
+    finally:
+        shutil.rmtree(tmpdir)
+
 def get_checksum(fileName, checksum_type="sha256", excludeLine="", includeLine=""):
     """Compute sha256 hash of the specified file"""
     m = hashlib.sha256()