176 lines
5.4 KiB
Python
Executable File
176 lines
5.4 KiB
Python
Executable File
#!/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 <poros@redhat.com>
|
|
# 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 <poros@redhat.com>"
|
|
__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)
|