[PATCH 2/2] Fix handling for RPMs added by -a or -add

Martin Kolman mkolman at redhat.com
Wed Aug 21 14:08:37 UTC 2013


Print all added RPMs and process all paths with os.path.abspath()
so that both relative and absolute paths can be safely used.
Correctly normalize the list of all added paths, remove duplicates
and skip "manually" added packages during autofetch.

Please note that if a package is added using the -a/--add option,
it will override any other packages that might be available either
in Koji or in the local cache and any version mismatch will be _ignored_.
The version is ignored on purpose, so that individual packages can
be manually overridden if needed.

Signed-off-by: Martin Kolman <mkolman at redhat.com>
---
 scripts/makeupdates | 96 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 82 insertions(+), 14 deletions(-)

diff --git a/scripts/makeupdates b/scripts/makeupdates
index a0af985..1fbcb93 100755
--- a/scripts/makeupdates
+++ b/scripts/makeupdates
@@ -465,9 +465,21 @@ def copyUpdatedWidgets(updates, cwd):
     if os.path.isfile(typelib):
         shutil.copy2(typelib, updates + libdir + "girepository-1.0")
 
-def addRpms(updates, add_rpms):
+def addRpms(updates_path, add_rpms):
+    """
+    Add content one or more RPM packages to the updates image
+
+    :param updates_path: path to the updates image folder
+    :type updates_path: string
+    :param add_rpms: list of paths to RPM files
+    :type add_rpms: list of strings
+    """
+    # convert all the RPM paths to absolute paths, so that
+    # relative paths can be used with -a/--add
+    add_rpms = map(lambda x: os.path.abspath(x), add_rpms)
+
     for rpm in add_rpms:
-        cmd = "cd %s && rpm2cpio %s | cpio -dium" % (updates, rpm)
+        cmd = "cd %s && rpm2cpio %s | cpio -dium" % (updates_path, rpm)
         sys.stdout.write(cmd+"\n")
         os.system(cmd)
 
@@ -476,7 +488,7 @@ def createUpdatesImage(cwd, updates):
     os.system("find . | cpio -c -o | gzip -9cv > %s/updates.img" % (cwd,))
     sys.stdout.write("updates.img ready\n")
 
-def check_for_new_packages(tag, arch):
+def check_for_new_packages(tag, arch, added_rpms):
     """Download any new packages added to Requires and Defines
     since the given tag, return list of RPM paths
     """
@@ -537,8 +549,13 @@ def check_for_new_packages(tag, arch):
         new_packages[package_name] = Package(package_name, version, version_request)
 
     if new_packages:
-        print("found %d new packages in Requires" %
+        print("%d new packages found in Requires:" %
               len(new_packages))
+        for p in new_packages.values():
+            if p.version_request:
+                print("%s %s %s" % (p.name, p.version_request, p.version))
+            else:
+                print(p.name)
     else:
         print("no new Requires found")
         return []
@@ -546,15 +563,25 @@ def check_for_new_packages(tag, arch):
     # make sure the RPM cache folder exists
     create_RPM_cache_folder()
     fedora_number = get_fedora_version()
+
+    # get package names for RPMs added by the -a/--add flags
+    added_names = {}
+    for path in added_rpms:
+        try:
+            name = parse_nvra(path)['name']
+            basename = os.path.basename(path)
+            added_names[name] = basename
+        except ValueError:
+            print("malformed RPM name ? : %s" % path)
     # remove available packages from the list
-    new_packages, include_rpms = remove_local_packages(new_packages, arch)
+    new_packages, include_rpms = remove_local_packages(new_packages, arch, added_names)
     # if some packages are not locally available, download them from Koji
     if new_packages:
         include_rpms.extend(get_RPMs_from_koji(new_packages, fedora_number, arch))
     # return absolute paths for the packages
     return map(lambda x: os.path.abspath(x), include_rpms)
 
-def remove_local_packages(packages, arch):
+def remove_local_packages(packages, arch, added_rpms):
     """Remove locally available RPMs from the list of needed packages,
     return locally unavailable packages and paths to relevant locally
     available RPMs for inclusion"""
@@ -562,6 +589,7 @@ def remove_local_packages(packages, arch):
     folder_glob = os.path.join(RPM_FOLDER_NAME, "*.rpm")
     folder_glob = os.path.abspath(folder_glob)
     include_rpms = []
+    skipped_packages = []
     # only check RPMs that are either noarch or built for the
     # currently specified architecture
     allowed = ("noarch.rpm", "%s.rpm" % arch)
@@ -583,22 +611,43 @@ def remove_local_packages(packages, arch):
         if name in packages:
             package = packages[name]
             package_version = package.version
+            # check if the package was added by the
+            # -a/--add option
+            if name in added_rpms:
+                # the package was added by the -a/--add option,
+                # remove it from the list so it is not loaded from
+                # RPM cache and not fetched
+                # NOTE: the version of the added package is not checked,
+                # so "added" packages are always used, even if their
+                # version does not comply with the one given in the specfile
+                del packages[name]
+                # remember which packages were skipped due to the
+                # -a/--add option
+                skipped_packages.append(added_rpms[name])
+
             # handle versions with build number and without it
-            if not package_version or package_version == version_build or \
+            elif not package_version or package_version == version_build or \
                     package_version == version or \
                     check_package_version(version, package):
                 include_rpms.append(rpm_path)
                 del packages[name]
 
     # return only those packages that are not locally available
-    if include_rpms and not packages:
-        print("all %d RPMs found locally:" % len(include_rpms))
+    if include_rpms and not packages and not added_rpms:
+        print("all required %d RPMs found locally:" % len(include_rpms))
     elif include_rpms:
-        print("%d RPMs found locally:" % len(include_rpms))
+        print("%d required RPMs found locally:" % len(include_rpms))
+        for rpm in include_rpms:
+            print(os.path.basename(rpm))
     else:
-        print("no packages found locally")
-    for rpm in include_rpms:
-        print(os.path.basename(rpm))
+        print("no required packages found locally")
+
+    # print skipped packages
+    if skipped_packages:
+        print('%d required packages found in the manually added RPMs:' % len(skipped_packages))
+        for item in skipped_packages:
+            print(item)
+
     return packages, include_rpms
 
 def get_RPMs_from_koji(packages, fedora_number, arch):
@@ -790,9 +839,28 @@ def main():
         if widgetsChanged(args.tag):
             copyUpdatedWidgets(updates, cwd)
 
+    if args.add_rpms:
+        # as using -a or --add mutltiple times
+        # adds a new list to the list instead of extending the
+        # original list, we need to "normalize" to a
+        # one-level list of strings
+        normalized_rpm_paths = []
+        for item in args.add_rpms:
+            if isinstance(item, list):
+                normalized_rpm_paths.extend(item)
+            else:
+                normalized_rpm_paths.append(item)
+        # also remove any duplicated paths
+        # by converting the list into a set
+        args.add_rpms = list(set(normalized_rpm_paths))
+
+        print('%d RPMs added manually:' % len(args.add_rpms))
+        for item in args.add_rpms:
+            print(os.path.basename(item))
+
     if args.fetch:
         arch = args.fetch
-        rpm_paths = check_for_new_packages(args.tag, arch)
+        rpm_paths = check_for_new_packages(args.tag, arch, args.add_rpms)
         args.add_rpms.extend(rpm_paths)
 
     if args.add_rpms:
-- 
1.8.3.1



More information about the anaconda-patches mailing list