138 lines
3.8 KiB
Python
Executable File
138 lines
3.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""fetch a stage3 from Gentoo's mirror"""
|
|
|
|
import argparse
|
|
import urllib.request
|
|
import os
|
|
import re
|
|
import sys
|
|
import gnupg
|
|
from collections import namedtuple
|
|
|
|
MIRROR = 'http://gentoo.osuosl.org/'
|
|
Stage3 = namedtuple('Stage3', 'url cpu specialty minimal nomultilib systemd mergedusr size')
|
|
MINIMAL = re.compile(r'[\+-]minimal-')
|
|
NOMULTILIB = re.compile(r'[\+-]nomultilib-')
|
|
SYSTEMD = re.compile(r'[\+-]systemd-')
|
|
MERGEDUSR = re.compile(r'[\+-]mergedusr-')
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--cpu', type=str, default=None)
|
|
parser.add_argument('--specialty', type=str, default=None)
|
|
parser.add_argument('--no-multilib', action='store_true', default=False)
|
|
parser.add_argument('--systemd', action='store_true', default=False)
|
|
parser.add_argument('--minimal', action='store_true', default=False)
|
|
parser.add_argument('--mergedusr', action='store_true', default=False)
|
|
parser.add_argument('--outfile', type=str, default=None)
|
|
parser.add_argument('arch', type=str)
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def get_manifest(arch, mirror=MIRROR):
|
|
manifest = []
|
|
url = mirror + '/releases/{0}/autobuilds/latest-stage3.txt'.format(arch)
|
|
base_url = mirror + '/releases/{0}/autobuilds/'.format(arch)
|
|
gpg = gnupg.GPG(gnupghome="/home/user/.gnupg")
|
|
|
|
with urllib.request.urlopen(url) as fp:
|
|
text = gpg.verify_file(fp, extra_args=['-o', '-']).data
|
|
##text = fp.read()
|
|
text = text.decode('ascii')
|
|
|
|
for line in text.split('\n'):
|
|
line = line.strip()
|
|
|
|
if not line or line[0] == '#':
|
|
continue
|
|
|
|
filename, size = line.split()
|
|
size = int(size)
|
|
dirname, rest = filename.split('/', 1)
|
|
|
|
if '/' in rest:
|
|
specialty, rest = rest.split('/', 1)
|
|
else:
|
|
specialty = None
|
|
|
|
cpu = rest.split('-', 2)[1]
|
|
nomultilib = 'nomultilib-' in rest
|
|
nomultilib = bool(NOMULTILIB.search(rest))
|
|
systemd = 'systemd-' in rest
|
|
systemd = bool(SYSTEMD.search(rest))
|
|
mergedusr = 'mergedusr-' in rest
|
|
mergedusr = bool(MERGEDUSR.search(rest))
|
|
minimal = bool(MINIMAL.search(rest))
|
|
|
|
stage3 = Stage3(
|
|
cpu=cpu,
|
|
mergedusr=mergedusr,
|
|
minimal=minimal,
|
|
nomultilib=nomultilib,
|
|
systemd=systemd,
|
|
size=size,
|
|
specialty=specialty,
|
|
url=base_url + filename,
|
|
)
|
|
|
|
manifest.append(stage3)
|
|
|
|
return manifest
|
|
|
|
|
|
def fetch(url, outfile):
|
|
"""fetch url and write it to outfile"""
|
|
with urllib.request.urlopen(url) as infile, open(outfile, 'wb') as outfile:
|
|
while True:
|
|
data = infile.read(512)
|
|
|
|
if not data:
|
|
break
|
|
|
|
outfile.write(data)
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
manifest = get_manifest(args.arch)
|
|
manifest.reverse()
|
|
stage3 = None
|
|
|
|
for item in manifest:
|
|
if not args.cpu and item.cpu != args.arch:
|
|
continue
|
|
if args.cpu and item.cpu != args.cpu:
|
|
continue
|
|
|
|
if not all([
|
|
args.minimal == item.minimal,
|
|
args.mergedusr == item.mergedusr,
|
|
args.no_multilib == item.nomultilib,
|
|
args.systemd == item.systemd,
|
|
args.specialty == item.specialty,
|
|
]):
|
|
continue
|
|
|
|
stage3 = item
|
|
break
|
|
|
|
if not stage3:
|
|
msg = 'No stage3 found matching your criteria\n'
|
|
sys.stderr.write(msg)
|
|
sys.exit(404)
|
|
|
|
filename = os.path.basename(stage3.url)
|
|
if args.outfile:
|
|
outfile = args.outfile
|
|
else:
|
|
outfile = filename
|
|
|
|
print(filename)
|
|
fetch(stage3.url, outfile)
|
|
stat = os.stat(outfile)
|
|
|
|
assert stat.st_size == stage3.size, 'File size does not match manifest'
|
|
|
|
main()
|