get_newer_rpm_if_exists.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #!/bin/env python
  2. from __future__ import print_function
  3. import argparse
  4. import csv
  5. import rpm
  6. import subprocess
  7. import os
  8. import glob
  9. import shutil
  10. import io
  11. def get_srpm_info(srpmpath):
  12. return subprocess.check_output(['rpm', '-qp', srpmpath, '--qf', '%{name};;%{evr}']).split(';;')
  13. def compare_evrs(evr1, evr2):
  14. # returns -1 if evr1<evr2, 0 if equal, 1 if >...
  15. p = subprocess.Popen(['rpmdev-vercmp', evr1, evr2], stdout=subprocess.PIPE)
  16. output, _ = p.communicate()
  17. if " < " in output:
  18. return -1
  19. if " > " in output:
  20. return 1
  21. if " == " in output:
  22. return 0
  23. raise Exception("Unexpected output from rpmdev-vercmp: %s" % output)
  24. def path_for_srpm(rpmdir, srpmfilename):
  25. return os.path.join(rpmdir, 'SRPMS', srpmfilename)
  26. def check_dir(dirpath):
  27. if not os.path.isdir(dirpath):
  28. raise Exception("Directory %s doesn't exist" % dirpath)
  29. return dirpath
  30. def main():
  31. parser = argparse.ArgumentParser(description='Starting from a source RPM, looks for the latest version '
  32. 'and copies it to the destination directory')
  33. parser.add_argument('source_rpm', help='path to a source RPM')
  34. parser.add_argument('rpmdir', help='directory that contains the SRPMs and RPMs we\'ll '
  35. 'be searching for newer versions')
  36. parser.add_argument('rpms_and_srpms',
  37. help='file that contains a list of x86_64 and noarch packages with their source RPM')
  38. parser.add_argument('downloaddir', help='where to download the newer RPMs to')
  39. args = parser.parse_args()
  40. DEVNULL = open(os.devnull, 'w')
  41. rpmdir = os.path.abspath(check_dir(args.rpmdir))
  42. downloaddir = os.path.abspath(check_dir(args.downloaddir))
  43. # get package name from source RPM, e.g. findutils for findutils-4.5.11-5.el7.src.rpm
  44. filename = os.path.basename(args.source_rpm)
  45. name, evr = get_srpm_info(args.source_rpm)
  46. print("Searching for newer version of %s (%s)" % (filename, name))
  47. srpms_to_rpms = {}
  48. srpm_evrs = {}
  49. with open(args.rpms_and_srpms, 'rb') as csvfile:
  50. for row in csv.reader(csvfile, delimiter=','):
  51. srpm_filename = row[1]
  52. if srpm_filename not in srpms_to_rpms:
  53. if srpm_filename.startswith(name + "-"):
  54. package_name, srpm_evr = get_srpm_info(path_for_srpm(rpmdir, srpm_filename))
  55. # the "if" test above allowed filtering out most packages but is not 100% precise
  56. if package_name != name:
  57. continue
  58. srpms_to_rpms[srpm_filename] = [row[0]]
  59. srpm_evrs[srpm_filename] = srpm_evr
  60. else:
  61. srpms_to_rpms[srpm_filename].append(row[0])
  62. if filename not in srpms_to_rpms:
  63. print("Warning: source RPM %s is missing from the reference." % filename)
  64. srpm_evrs.append(filename, evr)
  65. latest_srpm = filename
  66. for srpm_filename, srpm_evr in srpm_evrs.iteritems():
  67. if compare_evrs(srpm_evr, srpm_evrs[latest_srpm]) > 0:
  68. latest_srpm = srpm_filename
  69. print(latest_srpm)
  70. if latest_srpm != filename:
  71. print("Newer version found: %s" % latest_srpm)
  72. # copy SRPM
  73. srpm_destination = os.path.join(downloaddir, 'Source', 'SPackages')
  74. if not os.path.isdir(srpm_destination):
  75. os.makedirs(srpm_destination)
  76. shutil.copy(path_for_srpm(rpmdir, latest_srpm), os.path.join(srpm_destination, latest_srpm))
  77. # copy all RPMs too
  78. rpm_destination = os.path.join(downloaddir, 'x86_64', 'Packages')
  79. if not os.path.isdir(rpm_destination):
  80. os.makedirs(rpm_destination)
  81. for rpm_filename in srpms_to_rpms[latest_srpm]:
  82. print("-> %s" % rpm_filename)
  83. shutil.copy(os.path.join(rpmdir, rpm_filename), os.path.join(rpm_destination, rpm_filename))
  84. if __name__ == "__main__":
  85. main()