=== added file 'linaro-hwpack-replace'
@@ -0,0 +1,219 @@
+#!/usr/bin/env python
+# Copyright (C) 2010, 2011 Linaro
+#
+# Author: Deepti B. Kalakeri <deepti.kalakeri@linaro.org>
+#
+# This file is part of Linaro Image Tools. It adds the feature
+# to include/replace a debian package into the given hwpack
+#
+# Linaro Image Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Linaro Image Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Linaro Image Tools. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import sys
+import shutil
+import logging
+import tarfile
+import tempfile
+import argparse
+import datetime
+import fileinput
+from debian.deb822 import Packages
+from linaro_image_tools.hwpack.packages import get_packages_file
+from linaro_image_tools.hwpack.packages import FetchedPackage
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument("-t", "--hwpack_name", dest="hwpack_name",
+ help="Specific hwpack_name to use (default: None)")
+parser.add_argument("-p", "--deb_pack", dest="deb_pack",
+ help="Specific debian package to replace (default: None).")
+parser.add_argument("-d", "--debug-output", action="store_true", dest="debug",
+ help="Verbose messages are displayed when specified")
+
+logger = logging.getLogger("linaro-hwpack-replace")
+
+
+class DummyStanza(object):
+
+ def __init__(self, info):
+ self.info = info
+
+ def dump(self, fd):
+ fd.write(get_packages_file([self.info]))
+
+
+def set_logging_param(args):
+ ch = logging.StreamHandler()
+ ch.setLevel(logging.INFO)
+ formatter = logging.Formatter("%(message)s")
+ ch.setFormatter(formatter)
+ logger.setLevel(logging.INFO)
+ logger.addHandler(ch)
+ if args.debug:
+ ch.setLevel(logging.DEBUG)
+ formatter = logging.Formatter(
+ "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
+ ch.setFormatter(formatter)
+ logger.setLevel(logging.DEBUG)
+
+
+def get_hwpack_name(old_hwpack):
+ timestamp = [datetime.datetime.now().strftime("%Y%m%d-%H%S")]
+ hwpack_name_parts = (old_hwpack.split('_', 3))
+ return('_'.join(hwpack_name_parts[:2] + timestamp + hwpack_name_parts[3:]))
+
+
+def verify_existing_debians(debpack_dirname, new_debpack_info):
+ """
+ Find if the debian file with the same name exists,
+ if it exists then remove it and replace with the new deb file
+ If similar debian file exists then remove it
+ """
+
+ old_debpack_info = None
+ deb_file_to_remove = None
+
+ try:
+ for deb_filename in os.listdir(debpack_dirname):
+ root, ext = os.path.splitext(deb_filename)
+ root = root + '_'
+ if root.startswith("%s_" %new_debpack_info.name) and ext == '.deb':
+ deb_file_to_remove = os.path.join(debpack_dirname, deb_filename)
+ old_debpack_info = FetchedPackage.from_deb(deb_file_to_remove)
+ os.remove(deb_file_to_remove)
+ except Exception, details:
+ logger.error("Error Details: %s", details)
+
+ return old_debpack_info
+
+
+def modify_manifest_info(tempdir, new_debpack_info, deb_pack_found):
+ """ Modify the manifest file to include the new debian information """
+
+ debpack_manifest_fname = os.path.join(tempdir, "manifest")
+ new_debpack_line = '%s=%s\n' % (new_debpack_info.name, new_debpack_info.version)
+
+ for line in fileinput.FileInput(debpack_manifest_fname, inplace=1):
+ if '=' in line:
+ package_name, version = line.split('=')
+ old_debpack = '%s=%s' % (package_name, version)
+ else:
+ package_name = line.rstrip("\n")
+ old_debpack = '%s' % package_name
+
+ if new_debpack_info.name == package_name:
+ deb_pack_found = 1
+ line = new_debpack_line
+ sys.stdout.write(line)
+
+ if deb_pack_found == 0:
+ logger.debug("Adding the new debian package info to manifest")
+ fout = open(debpack_manifest_fname, "a")
+ fout.write(new_debpack_line)
+ fout.close()
+ else:
+ logger.debug("Replaced the old debian package information "\
+ "with the new information")
+
+
+def modify_Packages_info(debpack_dirname, new_debpack_info):
+ """ Modify the Packages file to include the new debian information """
+
+ debpack_Packages_fname = os.path.join(debpack_dirname, "Packages")
+ f = open(debpack_Packages_fname, "r+")
+ try:
+ output = []
+ for stanza in Packages.iter_paragraphs(f):
+ if stanza["Package"] == new_debpack_info.name:
+ output.append(DummyStanza(new_debpack_info))
+ else:
+ output.append(stanza)
+ f.seek(0,0)
+
+ for stanza in output:
+ stanza.dump(f)
+ f.write("\n")
+ finally:
+ f.close()
+
+
+def main():
+ # Validate that all the required information is passed on the command line
+ args = parser.parse_args()
+ if args.hwpack_name == None or args.deb_pack == None:
+ parser.print_help()
+ parser.error("You must specify both hwpack name "\
+ "and the debian package information\n")
+ return 1
+
+ set_logging_param(args)
+
+ deb_pack_found = 0
+ old_debpack_info = None
+ old_hwpack = args.hwpack_name
+ new_deb_file_to_copy = args.deb_pack
+ status = 0
+
+ try:
+ # Get the new hardware pack name
+ hwpack_name = get_hwpack_name(old_hwpack)
+ if hwpack_name == None:
+ logger.error("Did not get a valid hwpack name, exiting")
+ return status
+
+ # untar the hardware pack and extract all the files in it
+ tar = tarfile.open(old_hwpack, "r:gz")
+ tempdir = tempfile.mkdtemp()
+ tar.extractall(tempdir)
+
+ # Search if a similar package with the same name exists, if yes then
+ # replace it. IF the old and new debian have the same name then we
+ # are still replacing the old one with the new one.
+ debpack_dirname = os.path.join(tempdir, 'pkgs/')
+ if not os.path.exists(debpack_dirname):
+ logger.error("Failed to extract the hwpack: %s ", old_hwpack)
+ return status
+
+ new_debpack_info = FetchedPackage.from_deb(new_deb_file_to_copy)
+
+ old_debpack_info = verify_existing_debians(debpack_dirname, new_debpack_info)
+
+ # Copy the new debian file to the pkgs dir,
+ shutil.copy2(new_deb_file_to_copy, debpack_dirname)
+
+ modify_manifest_info(tempdir, new_debpack_info, deb_pack_found)
+
+ modify_Packages_info(debpack_dirname, new_debpack_info)
+
+ #tar the hardware pack with the new debian file included in it
+ tar = tarfile.open( hwpack_name , "w:gz")
+ os.chdir(tempdir)
+ tar.add('.', recursive=True)
+ tar.close()
+ except Exception, details:
+ logger.error("Error Details: %s", details)
+ status = 1
+
+ if status == 0:
+ logger.info("The debian package '%s' has been been included in '%s'",
+ new_deb_file_to_copy, hwpack_name)
+ else:
+ logger.error("Injecting the debian package '%s' failed", new_deb_file_to_copy)
+
+ return status
+
+
+if __name__ == '__main__':
+ sys.exit(main())