#!/usr/bin/python3 # # show-kabi - Red Hat kABI reference module extraction tool # # We use this script to dump info from kabi infrastructure. # # Author: Petr Oros # Copyright (C) 2014 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # General Public License (GPL). # Changelog: # # 2018/06/01 - Update for python3 by Petr Oros. __author__ = "Petr Oros " __version__ = "1.0" __date__ = "2014/09/05" __copyright__ = "Copyright (C) 2014 Red Hat, Inc" __license__ = "GPL" import getopt import os import sys import re def load_kabi(dirname, kabi, order, arch): """Load a reference stablelist content.""" try: archlist = [] if arch == "": for arch in os.listdir(dirname): if "kabi_" in arch: archlist.append(arch[5:]) kabi[arch[5:]] = {} order[arch[5:]] = [] else: # no kabi arch dir continue else: archlist.append(arch) kabi[arch] = {} order[arch] = [] for arch in archlist: for symbol in os.listdir(dirname + "/kabi_" + arch): if '.' in symbol: # skip files continue kabi_file = open(dirname + "/kabi_" + arch + "/" + symbol, "r") line = [] offset = 0 lines = 0 for l in kabi_file: l = l.rstrip('\n') m = re.match(r"^#([^0-9]+):(.*)", l) if m: # store index metadata if m.group(1) == "I": offset = int(m.group(2)) # skip any other metadata continue if l.startswith("#"): # store version metadata line.append(l) continue if lines == offset: line.append(l) break lines += 1 kabi[arch][symbol] = line order[arch].append(symbol) kabi_file.close() order[arch].sort() except OSError as err: print("Invalid arch: {}".format(arch)) print(str(err)) sys.exit(1) def check_struct(dirname): match_files = 0 try: if os.path.isdir(dirname): for arch_dir in os.listdir(dirname): if os.path.isdir(dirname + "/" + arch_dir): match_files += len(os.listdir(dirname + "/" + arch_dir)) else: return -1 return match_files except OSError: print("Invalid kabi-module/ root directory") print("Use -k param to specify right path") sys.exit(1) def show_kabi(kabi, order, release, fmt, show_head): rhel_minor = release.split('.', 1)[-1] if rhel_minor == "": rhel_minor = sys.maxsize else: rhel_minor = int(rhel_minor) for current_arch in kabi: if show_head and (fmt == "stablelist"): print("[rhel9_{}_stablelist]".format(current_arch)) for sym in order[current_arch]: if kabi[current_arch][sym][0][0] != "#": print("Invalid metadata format: {}".format(kabi[current_arch][sym][0])) sys.exit(1) minor_range = kabi[current_arch][sym][0][1:].split("-", 2) minor_range[0] = int(minor_range[0]) if minor_range[1] == "": minor_range[1] = sys.maxsize else: minor_range[1] = int(minor_range[1]) if minor_range[0] > rhel_minor: continue if (minor_range[1] <= rhel_minor) and (minor_range[1] != sys.maxsize): continue # format Module.kabi_$arch styled file if fmt == "module": print(kabi[current_arch][sym][1]) # format kabi_stablelist_$arch styled file else: print("\t{}".format(sym)) def usage(): print("""show-kabi: -a arch architecture, ( default all archs ) -k dir kabi-module root directory ( default ./kabi-module ) -m output Module.kabi_$(arch) styled file default output kabi_stablelist_$(arch) styled file -r release release, for example 8.1 ( default latest ) -s show header ( no headers like [rhel9_x86_64_stablelist] ) -h this help""") if __name__ == "__main__": kabi = {} kabi_order = {} arch = "" kabi_dir = "kabi-module" release = "" kabi_head = False kabi_out = "stablelist" opts, args = getopt.getopt(sys.argv[1:], 'a:k:mr:sh') for o, v in opts: if o == "-a": arch = v if o == "-k": kabi_dir = v if o == "-m": kabi_out = "module" if o == "-r": release = v if o == "-s": kabi_head = True if o == "-h": usage() sys.exit(0) if check_struct(kabi_dir) < 0: print("Invalid directory structure!!!") print("kabi-module/ specified as root must contain") print("arch specific directories like kabi_ppc64...") sys.exit(1) load_kabi(kabi_dir, kabi, kabi_order, arch) show_kabi(kabi, kabi_order, release, kabi_out, kabi_head)