initial commit
This commit is contained in:
commit
173c4bc898
1 changed files with 120 additions and 0 deletions
120
buildinfo2snapshot.py
Executable file
120
buildinfo2snapshot.py
Executable file
|
@ -0,0 +1,120 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
#
|
||||||
|
# Copyright 2014 Johannes Schauer
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
from debian import deb822
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from collections import defaultdict
|
||||||
|
import gzip
|
||||||
|
import io
|
||||||
|
|
||||||
|
snapshot_api = "http://snapshot.debian.org/mr/"
|
||||||
|
|
||||||
|
# archive can be debian, debian-archive, debian-backports, debian-ports,
|
||||||
|
# debian-security, debian-volatile
|
||||||
|
archive = "debian"
|
||||||
|
|
||||||
|
suite = "sid"
|
||||||
|
area = "main"
|
||||||
|
|
||||||
|
timestamps = defaultdict(list)
|
||||||
|
|
||||||
|
reqpkgs = set()
|
||||||
|
|
||||||
|
with open(sys.argv[1]) as f:
|
||||||
|
paragraph = list(deb822.Deb822.iter_paragraphs(f, use_apt_pkg=False))
|
||||||
|
if len(paragraph) != 1:
|
||||||
|
raise Exception("expected only one paragraph")
|
||||||
|
paragraph = paragraph[0]
|
||||||
|
arch = paragraph['Build-Architecture']
|
||||||
|
for pkg in deb822.PkgRelation.parse_relations(paragraph['Build-Environment']):
|
||||||
|
if len(pkg) != 1:
|
||||||
|
raise Exception("Build-Environment field must not have disjunctions")
|
||||||
|
pkg = pkg[0]
|
||||||
|
pkgarch = pkg['arch']
|
||||||
|
if pkgarch is None:
|
||||||
|
pkgarch = arch
|
||||||
|
pkgname = pkg['name']
|
||||||
|
if len(pkg['version']) != 2:
|
||||||
|
raise Exception("version must be a relation/number tuple")
|
||||||
|
if pkg['version'][0] != '=':
|
||||||
|
raise Exception("relationship must be '='")
|
||||||
|
pkgver = pkg['version'][1]
|
||||||
|
print(pkgname, pkgver, pkgarch)
|
||||||
|
reqpkgs.add((pkgname,pkgver,pkgarch))
|
||||||
|
json_data = urllib.request.urlopen("%s/binary/%s/"%(snapshot_api, pkgname))
|
||||||
|
if json_data.status != 200:
|
||||||
|
raise Exception("returned %d"%json_data.status)
|
||||||
|
json_data = json_data.read()
|
||||||
|
json_data = json.loads(json_data.decode('utf8'))
|
||||||
|
srcver = None
|
||||||
|
srcname = None
|
||||||
|
for res in json_data['result']:
|
||||||
|
if res['binary_version'] == pkgver:
|
||||||
|
srcver = res['version']
|
||||||
|
srcname = res['source']
|
||||||
|
break
|
||||||
|
if srcver is None or srcname is None:
|
||||||
|
raise Exception("cannot find source version for binary version")
|
||||||
|
json_data = urllib.request.urlopen("%s/package/%s/%s/binfiles/%s/%s?fileinfo=1"%(snapshot_api, srcname, srcver, pkgname, pkgver))
|
||||||
|
if json_data.status != 200:
|
||||||
|
raise Exception("returned %d"%json_data.status)
|
||||||
|
json_data = json_data.read()
|
||||||
|
json_data = json.loads(json_data.decode('utf8'))
|
||||||
|
pkghash = None
|
||||||
|
if len(json_data['result']) == 1:
|
||||||
|
if json_data['result'][0]['architecture'] != 'all':
|
||||||
|
Exception("excepted arch:all")
|
||||||
|
pkghash = json_data['result'][0]['hash']
|
||||||
|
else:
|
||||||
|
for res in json_data['result']:
|
||||||
|
if res['architecture'] == pkgarch:
|
||||||
|
pkghash = res['hash']
|
||||||
|
break
|
||||||
|
if pkghash is None:
|
||||||
|
raise Exception("cannot find architecture")
|
||||||
|
first_seen = [ph['first_seen'] for ph in json_data['fileinfo'][pkghash] if ph['archive_name'] == archive]
|
||||||
|
if len(first_seen) != 1:
|
||||||
|
raise Exception("more than one package with the same hash")
|
||||||
|
timestamps[datetime.strptime(first_seen[0], "%Y%m%dT%H%M%SZ")].append((pkgname,pkgver,pkgarch))
|
||||||
|
|
||||||
|
newest = sorted(timestamps.keys())[-1]
|
||||||
|
|
||||||
|
snapshot_timestamp = datetime.strftime(newest, "%Y%m%dT%H%M%SZ")
|
||||||
|
|
||||||
|
# using gz instead of xz in case old snapshots have to be retrieved
|
||||||
|
snapshot_url = "http://snapshot.debian.org/archive/%s/%s/dists/%s/%s/binary-%s/Packages.gz"%(archive, snapshot_timestamp, suite, area, arch)
|
||||||
|
|
||||||
|
pkgdata = urllib.request.urlopen(snapshot_url)
|
||||||
|
if pkgdata.status != 200:
|
||||||
|
raise Exception("returned %d"%pkgdata.status)
|
||||||
|
pkgdata = io.BytesIO(pkgdata.read())
|
||||||
|
pkgdata = gzip.GzipFile(fileobj=pkgdata)
|
||||||
|
for pkg in deb822.Deb822.iter_paragraphs(pkgdata, use_apt_pkg=False):
|
||||||
|
pkgname = pkg['Package']
|
||||||
|
pkgver = pkg['Version']
|
||||||
|
if pkg['Architecture'] == 'all':
|
||||||
|
pkgarch = arch
|
||||||
|
else:
|
||||||
|
pkgarch = pkg['Architecture']
|
||||||
|
if (pkgname,pkgver,pkgarch) in reqpkgs:
|
||||||
|
reqpkgs.remove((pkgname,pkgver,pkgarch))
|
||||||
|
|
||||||
|
if reqpkgs:
|
||||||
|
raise Exception("cannot find all package versions in found snapshot: %s"%reqpkgs)
|
||||||
|
|
||||||
|
print("architecture = %s"%arch)
|
||||||
|
print("mirror = http://snapshot.debian.org/archive/%s/%s/"%(archive, snapshot_timestamp))
|
Loading…
Reference in a new issue