Move all image conf operations into imagedata class,
authorHasan Wan <hasan.wan@intel.com>
Wed, 29 May 2013 06:43:02 +0000 (14:43 +0800)
committerHasan Wan <hasan.wan@intel.com>
Wed, 29 May 2013 09:45:11 +0000 (17:45 +0800)
repomaker use imagedata class to handle image conf

Change-Id: I8d2d57c3e8d5029cb645057cffd7ff0134feff47
Signed-off-by: Hasan Wan <hasan.wan@intel.com>
common/imagedata.py
common/repomaker.py

index f13d754..6055445 100644 (file)
@@ -20,7 +20,9 @@ This module takes care of handling/generating/parsing of build.xml
 """
 
 import re
+import os
 
+from subprocess import check_output, CalledProcessError
 from collections import OrderedDict
 from xml.dom import minidom
 
@@ -36,10 +38,7 @@ class ImageData(object):
 
     def __init__(self):
         self.images = OrderedDict()
-
-    def add_image(self, image):
-        """Add (or update) target to the list of targets."""
-        self.images[image["name"]] = image
+        self.ks = OrderedDict()
 
     def load(self, xml):
         """Load image data from xml."""
@@ -51,13 +50,16 @@ class ImageData(object):
             except IndexError:
                 raise ImageDataError("Error: <%s><%s> not found" % \
                                      (node.nodeName, name))
+
         dom = minidom.parseString(xml)
-        images = get_elem(dom, "images")
 
-        for image in images.getElementsByTagName("image"):
+        # Keep compatible with old repo structure,
+        # TODO: update this part when new repo structure ready
+        images = get_elem(dom, "image-configs")
+
+        for image in images.getElementsByTagName("config"):
             img = {}
-            for field in ('name', 'description', 'path', 'arch',
-                          'ks', 'buildtarget'):
+            for field in ('name', 'description', 'path', 'arch'):
                 img[field] = str(get_elem(image, field).firstChild.data)
 
             self.images[img['name']] = img
@@ -81,8 +83,51 @@ class ImageData(object):
 
         return content
 
-    def save(self, fname, hreadable=True):
-        """Save image data to xml file."""
+    def save(self, path_to_repo, hreadable=True):
+        """
+        Save image data to xml file and save ks files to
+        image-configuration dir
+        """
+        if not os.path.isdir(os.path.join(path_to_repo,
+                                          'builddata',
+                                          'image-configurations')):
+            os.makedirs(os.path.join(path_to_repo,
+                                          'builddata',
+                                          'image-configurations'))
         # Write content down
-        with open(fname, 'w') as out:
+        with open(os.path.join(path_to_repo,
+                               'builddata/images.xml'), 'w') as out:
             out.write(self.to_xml(hreadable))
+
+        for ksname, kscontent in self.ks.items():
+            with open(os.path.join(path_to_repo,
+                                   'builddata/image-configurations',
+                                   ksname), 'w') as out:
+                out.write(kscontent)
+
+    def extract_image_conf(self, rpm):
+        """Extract ks files and image data from rpm."""
+        try:
+            output = check_output("rpm2cpio %s |cpio -t" % rpm, shell=True)
+        except CalledProcessError, err:
+            raise ImageDataError("Can't get content of %s: %s" % (rpm, err))
+
+        for path in output.split():
+            if path.endswith('.ks'):
+                try:
+                    content = check_output('rpm2cpio %s |cpio -i --quiet '\
+                                           '--to-stdout %s' % (rpm, path),
+                                           shell=True)
+                except CalledProcessError, err:
+                    raise ImageDataError("Can't extract %s from %s: %s" % \
+                                         (path, rpm, err))
+                self.ks[os.path.basename(path)] = content
+            if path.endswith('.xml'):
+                try:
+                    content = check_output('rpm2cpio %s |cpio -i --quiet '\
+                                           '--to-stdout %s' % (rpm, path),
+                                           shell=True)
+                except CalledProcessError, err:
+                    raise ImageDataError("Can't extract %s from %s: %s" % \
+                                         (path, rpm, err))
+                self.load(content)
index fab5bd2..d349838 100644 (file)
@@ -25,6 +25,7 @@ from hashlib import sha256
 from subprocess import check_output, CalledProcessError
 
 from common.builddata import BuildData, BuildDataError
+from common.imagedata import ImageData, ImageDataError
 
 class RepoMakerError(Exception):
     """Custom RepoMaker exception."""
@@ -92,26 +93,6 @@ def move_or_hardlink(fpath, target_dirs, move=False):
         else:
             os.link(fpath, tpath)
 
-def extract_ks(rpm):
-    """Extract .ks file from rpm."""
-
-    try:
-        output = check_output("rpm2cpio %s |cpio -t" % rpm, shell=True)
-    except CalledProcessError, err:
-        raise RepoMakerError("Can't get content of %s: %s" % (rpm, err))
-
-    for path in output.split():
-        if path.endswith('.ks'):
-            try:
-                content = check_output('rpm2cpio %s |cpio -i --quiet '\
-                                       '--to-stdout %s' % (rpm, path),
-                                       shell=True)
-            except CalledProcessError, err:
-                raise RepoMakerError("Can't extract %s from %s: %s" % \
-                                     (path, rpm, err))
-
-            yield os.path.basename(path), content
-
 class RepoMaker(object):
     """Makes rpm repositories."""
 
@@ -127,7 +108,7 @@ class RepoMaker(object):
         self.build_id = build_id
         self.outdir = os.path.join(outdir, build_id)
         self.repos = {}
-        self.images = []
+        self.imagedata = None
 
     def add_repo(self, in_dir, name, buildconf=None, move=False, gpg_key=None,
                  signer='/usr/bin/sign'):
@@ -179,8 +160,7 @@ class RepoMaker(object):
                                                              filename)))
             # get names and content of .ks files from rpm
             if is_imageconf:
-                for ksname, kscontent in extract_ks(fpath):
-                    self.images.append(ksname, kscontent)
+                self.load_imagedata(fpath)
 
         # Save build configuration file if provided
         if buildconf:
@@ -191,10 +171,6 @@ class RepoMaker(object):
         # Generate or update build.xml
         self.update_builddata(name, dirs, buildconf)
 
-        # Generate/Update images.xml
-        if self.images:
-            self.update_imgdata()
-
         # Run createrepo
         for _rtype, _rarch, rpath in dirs:
             # run createrepo
@@ -212,6 +188,22 @@ class RepoMaker(object):
                                            "repomd.xml")
                 os.system('%s -d % s' % (signer, repomd_path))
 
+    def load_imagedata(self, rpm):
+        """
+
+        Args:
+
+        Raises: ImageDataError
+
+        """
+        self.imagedata = ImageData()
+        self.imagedata.extract_image_conf(rpm)
+
+    def gen_image_info(self):
+        """
+        Generate images.xml and save a copy of ks file under builddata dir
+        """
+        self.imagedata.save(self.outdir)
 
     def update_builddata(self, name, dirs, buildconf=None):
         """
@@ -249,8 +241,3 @@ class RepoMaker(object):
             bdata.save(outf)
         except BuildDataError, err:
             raise RepoMakerError("Unable to generate build.xml: %s" % err)
-
-    def add_images(self, images):
-        """Add image configurations."""
-        for name, content in images:
-            self.images.append((name, content))