Files
LangBot/scripts/check_core_artifacts.py
T

58 lines
2.0 KiB
Python

from __future__ import annotations
import argparse
import json
from pathlib import Path, PurePosixPath
import tarfile
import zipfile
def forbidden_member(name: str) -> bool:
parts = PurePosixPath(name.replace('\\', '/')).parts
return 'plugins' in parts[:2] or name.endswith('.lbpkg')
def check_artifact(path: Path) -> None:
if path.is_dir():
names = [item.relative_to(path).as_posix() for item in path.rglob('*')]
elif zipfile.is_zipfile(path):
with zipfile.ZipFile(path) as archive:
names = archive.namelist()
elif tarfile.is_tarfile(path):
with tarfile.open(path) as archive:
names = archive.getnames()
else:
raise ValueError(f'Unsupported Core artifact: {path}')
forbidden = [name for name in names if forbidden_member(name)]
if forbidden:
raise ValueError(f'Plugin content in {path}: {forbidden[:10]}')
print(f'Core artifact excludes official plugins: {path.name} ({len(names)} entries)')
def check_docker_archive(path: Path) -> None:
with tarfile.open(path) as image:
manifests = json.load(image.extractfile('manifest.json'))
for manifest in manifests:
for layer in manifest['Layers']:
with tarfile.open(fileobj=image.extractfile(layer), mode='r|*') as contents:
for member in contents:
if forbidden_member(member.name):
raise ValueError(f'Plugin content in Docker layer {layer}: {member.name}')
print(f'Docker image layers exclude official plugins: {path.name}')
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('--docker-archive', action='store_true')
parser.add_argument('artifacts', type=Path, nargs='+')
args = parser.parse_args()
for artifact in args.artifacts:
if args.docker_archive:
check_docker_archive(artifact)
else:
check_artifact(artifact)
if __name__ == '__main__':
main()