mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2025-07-06 10:22:59 +00:00
When using apk as the package manager, imagebuilder make command make manifest STRIP_ABI=1 does not strip package names of their ABI-version suffix. The ASU server relies on this to validate builds, so many snapshot build requests are failing. Fix this by using the already existing package data parser in make-index-json.py and augment it to write the result in manifest format. Fixes: https://github.com/openwrt/openwrt/issues/19274 Signed-off-by: Eric Fahlgren <ericfahlgren@gmail.com> Link: https://github.com/openwrt/openwrt/pull/19278 Signed-off-by: Robert Marko <robimarko@gmail.com>
102 lines
3.1 KiB
Python
Executable File
102 lines
3.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Parse the native package index files into a json file for use by downstream
|
|
tools. See:
|
|
|
|
https://github.com/openwrt/openwrt/commit/218ce40cd738f3373438aab82467807a8707fb9c
|
|
|
|
The "version 1" index.json contained ABI-versioned package names, making the
|
|
unusable by the ASU server. The version 2 format contains package names that
|
|
have been stripped of their ABI version.
|
|
"""
|
|
|
|
import email.parser
|
|
import json
|
|
|
|
|
|
def removesuffix(src, suffix):
|
|
# For compatibility with Python < 3.9.
|
|
suffix_length = len(suffix)
|
|
return src[:-suffix_length] if suffix_length and src.endswith(suffix) else src
|
|
|
|
|
|
def parse_args():
|
|
from argparse import ArgumentParser
|
|
|
|
source_format = "apk", "opkg"
|
|
|
|
parser = ArgumentParser()
|
|
# fmt: off
|
|
parser.add_argument("-a", "--architecture", required=True,
|
|
help="Required device architecture: like 'x86_64' or 'aarch64_generic'")
|
|
parser.add_argument("-f", "--source-format", required=True, choices=source_format,
|
|
help="Required source format of input: 'apk' or 'opkg'")
|
|
parser.add_argument("-m", "--manifest", action="store_true", default=False,
|
|
help="Print output in manifest format, as package:version pairs")
|
|
parser.add_argument(dest="source",
|
|
help="File name for input, '-' for stdin")
|
|
# fmt: on
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
|
|
def parse_apk(text: str) -> dict:
|
|
packages: dict = {}
|
|
|
|
data = json.loads(text)
|
|
if isinstance(data, dict) and "packages" in data:
|
|
# Extract 'apk adbdump' dict field to 'apk query' package list
|
|
data = data["packages"]
|
|
|
|
for package in data:
|
|
package_name: str = package["name"]
|
|
|
|
for tag in package.get("tags", []):
|
|
if tag.startswith("openwrt:abiversion="):
|
|
package_abi: str = tag.split("=")[-1]
|
|
package_name = removesuffix(package_name, package_abi)
|
|
break
|
|
|
|
packages[package_name] = package["version"]
|
|
|
|
return packages
|
|
|
|
|
|
def parse_opkg(text: str) -> dict:
|
|
packages: dict = {}
|
|
|
|
parser: email.parser.Parser = email.parser.Parser()
|
|
chunks: list[str] = text.strip().split("\n\n")
|
|
for chunk in chunks:
|
|
package: dict = parser.parsestr(chunk, headersonly=True)
|
|
package_name: str = package["Package"]
|
|
package_abi = package.get("ABIVersion")
|
|
if package_abi:
|
|
package_name = removesuffix(package_name, package_abi)
|
|
|
|
packages[package_name] = package["Version"]
|
|
|
|
return packages
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
args = parse_args()
|
|
|
|
input = sys.stdin if args.source == "-" else open(args.source, "r")
|
|
with input:
|
|
text: str = input.read()
|
|
|
|
packages = parse_apk(text) if args.source_format == "apk" else parse_opkg(text)
|
|
if args.manifest:
|
|
for name, version in packages.items():
|
|
print(name, version)
|
|
else:
|
|
index = {
|
|
"version": 2,
|
|
"architecture": args.architecture,
|
|
"packages": packages,
|
|
}
|
|
print(json.dumps(index, indent=2))
|