119 lines
3.7 KiB
Python
Executable File
119 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Validate a directory of locally-built VPP .deb packages before a Docker build.
|
|
|
|
Checks:
|
|
- The directory exists
|
|
- Exactly one *.changes file
|
|
- Exactly one *.buildinfo file
|
|
- Exactly one of each required .deb package
|
|
- All packages carry the same version string
|
|
- Optionally: version matches an expected value (for cross-machine consistency)
|
|
|
|
Usage:
|
|
check-vppdebs.py [--print-version] [--assert-version VERSION] [directory]
|
|
|
|
--print-version Print only the detected version string and exit (no other output).
|
|
--assert-version VER After all checks pass, assert the detected version equals VER.
|
|
Use this to verify summer and jessica-orb have the same build.
|
|
directory Path to check (default: ~/src/vpp/build-root).
|
|
"""
|
|
|
|
import sys
|
|
import glob
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
REQUIRED_DEBS = [
|
|
"libvppinfra_*.deb",
|
|
"python3-vpp-api_*.deb",
|
|
"vpp_*.deb",
|
|
"vpp-crypto-engines_*.deb",
|
|
"vpp-plugin-core_*.deb",
|
|
]
|
|
|
|
def find(directory, pattern):
|
|
return sorted(glob.glob(str(directory / pattern)))
|
|
|
|
def version_from_deb(path):
|
|
"""Extract the version field from a deb filename: name_VERSION_arch.deb"""
|
|
return Path(path).stem.split("_")[1]
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(add_help=False)
|
|
parser.add_argument("--print-version", action="store_true")
|
|
parser.add_argument("--assert-version", metavar="VERSION", default=None)
|
|
parser.add_argument("directory", nargs="?", default="~/src/vpp/build-root")
|
|
args = parser.parse_args()
|
|
|
|
directory = Path(args.directory).expanduser()
|
|
errors = []
|
|
versions = []
|
|
|
|
if not args.print_version:
|
|
print(f"Checking VPP debs in: {directory}")
|
|
|
|
if not directory.is_dir():
|
|
print(f" ERROR: directory does not exist: {directory}")
|
|
sys.exit(1)
|
|
|
|
# *.changes
|
|
changes = find(directory, "*.changes")
|
|
if len(changes) == 1:
|
|
if not args.print_version:
|
|
print(f" OK changes : {Path(changes[0]).name}")
|
|
else:
|
|
errors.append(f"expected exactly 1 *.changes, found {len(changes)}: {[Path(f).name for f in changes]}")
|
|
|
|
# *.buildinfo
|
|
buildinfo = find(directory, "*.buildinfo")
|
|
if len(buildinfo) == 1:
|
|
if not args.print_version:
|
|
print(f" OK buildinfo : {Path(buildinfo[0]).name}")
|
|
else:
|
|
errors.append(f"expected exactly 1 *.buildinfo, found {len(buildinfo)}: {[Path(f).name for f in buildinfo]}")
|
|
|
|
# required debs
|
|
for pattern in REQUIRED_DEBS:
|
|
matches = find(directory, pattern)
|
|
if len(matches) == 1:
|
|
ver = version_from_deb(matches[0])
|
|
versions.append(ver)
|
|
if not args.print_version:
|
|
print(f" OK {pattern:<30s}: {Path(matches[0]).name}")
|
|
else:
|
|
errors.append(f"expected exactly 1 {pattern}, found {len(matches)}: {[Path(f).name for f in matches]}")
|
|
|
|
# version consistency within this directory
|
|
if versions and len(set(versions)) > 1:
|
|
errors.append(f"debs carry mixed versions: {sorted(set(versions))}")
|
|
|
|
if errors:
|
|
if not args.print_version:
|
|
print()
|
|
for e in errors:
|
|
print(f" ERROR: {e}")
|
|
sys.exit(1)
|
|
|
|
detected = versions[0] if versions else None
|
|
|
|
if args.print_version:
|
|
print(detected or "")
|
|
sys.exit(0)
|
|
|
|
print(f" OK version : {detected}")
|
|
|
|
# cross-machine version assertion
|
|
if args.assert_version:
|
|
if detected == args.assert_version:
|
|
print(f" OK matches summer : {detected}")
|
|
else:
|
|
print(f" ERROR: version mismatch: this machine={detected}, summer={args.assert_version}")
|
|
sys.exit(1)
|
|
|
|
print()
|
|
print("Preflight OK.")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|