You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.6 KiB
140 lines
4.6 KiB
#!/usr/bin/python3
|
|
|
|
# Copyright (C) 2020 Canonical Ltd.
|
|
# Author: Steve Langasek <steve.langasek@canonical.com>
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; version 3 of the License.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
'''Synchronize the i386 source package whitelist in Launchpad with the output
|
|
of germinate.
|
|
|
|
USAGE:
|
|
update-i386-whitelist [--dry-run] https://people.canonical.com/~ubuntu-archive/germinate-output/i386.focal/i386+build-depends.sources
|
|
'''
|
|
|
|
from launchpadlib.launchpad import Launchpad
|
|
import optparse
|
|
from urllib.request import urlopen
|
|
import sys
|
|
|
|
def get_sources_from_url(url):
|
|
'''Download the germinate output and parse out the list of sources.
|
|
|
|
Returns list of source package names.
|
|
'''
|
|
sources = []
|
|
|
|
file = urlopen(url)
|
|
for i in file:
|
|
if i.startswith(b'Source') or i.startswith(b'---'):
|
|
continue
|
|
sources.append(i.decode('utf-8').split(' ',maxsplit=1)[0])
|
|
return sources
|
|
|
|
def parse_options():
|
|
'''Parse command line arguments.
|
|
|
|
Return (options, source_package) tuple.
|
|
'''
|
|
parser = optparse.OptionParser(
|
|
usage='Usage: %prog [--dry-run] https://people.canonical.com/~ubuntu-archive/germinate-output/i386.focal/i386+build-depends.sources')
|
|
parser.add_option(
|
|
"--dry-run", help="don't change launchpad, just report the delta",
|
|
action="store_true")
|
|
parser.add_option(
|
|
"-s", dest="release", default=default_release, metavar="RELEASE",
|
|
help="release (default: %s)" % default_release)
|
|
|
|
(opts, args) = parser.parse_args()
|
|
|
|
if len(args) != 1:
|
|
parser.error('Need to specify a URL to sync from')
|
|
|
|
return (opts, args[0])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
default_release = 'focal'
|
|
|
|
(opts, url) = parse_options()
|
|
|
|
launchpad = Launchpad.login_with('update-i386-whitelist',
|
|
'production',
|
|
version="devel")
|
|
ubuntu = launchpad.distributions['ubuntu']
|
|
series = ubuntu.getSeries(name_or_version=opts.release)
|
|
archive = ubuntu.main_archive
|
|
|
|
sources = get_sources_from_url(url)
|
|
|
|
packageset = launchpad.packagesets.getByName(name='i386-whitelist',
|
|
distroseries=series)
|
|
currentSet = set(packageset.getSourcesIncluded())
|
|
newSet = set(sources)
|
|
# hard-coded list of ppa-only additions; can maybe go away when
|
|
# https://bugs.launchpad.net/launchpad/+bug/1855069 is fixed, but this is
|
|
# also potentially useful for bootstrapping any additional packages into
|
|
# the archive if needed.
|
|
|
|
# bootstrap new spdlog dep
|
|
newSet.update(['fmtlib'])
|
|
# for new lintian
|
|
newSet.update(['libdevel-size-perl', 'libcpanel-json-xs-perl',
|
|
'libsereal-decoder-perl', 'libsereal-encoder-perl',
|
|
'libjson-xs-perl'])
|
|
|
|
# needed to bootstrap openjdk-N
|
|
newSet.update(['openjdk-12'])
|
|
newSet.update(['openjdk-13'])
|
|
newSet.update(['openjdk-14'])
|
|
newSet.update(['openjdk-15'])
|
|
newSet.update(['openjdk-8'])
|
|
|
|
# we get the wrong answer from germinate about a source package's
|
|
# whitelisting when the package provides both Arch: any and Arch: all
|
|
# binaries but we actually only want the Arch: all ones. Rather than
|
|
# fix this in germinate, for now just manually exclude the packages
|
|
# we've found that have this problem.
|
|
for pkg in ('frei0r', 'xorg', 'ubuntu-drivers-common'):
|
|
try:
|
|
newSet.remove(pkg)
|
|
except KeyError:
|
|
pass
|
|
print("Additions:" )
|
|
additions = list(newSet-currentSet)
|
|
additions.sort()
|
|
for i in additions:
|
|
print(" * %s" % i)
|
|
print("Removals:" )
|
|
removals = list(currentSet-newSet)
|
|
removals.sort()
|
|
for i in removals:
|
|
print(" * %s" % i)
|
|
if opts.dry_run:
|
|
print("--dry-run is set, doing nothing.")
|
|
sys.exit(0)
|
|
|
|
if additions or removals:
|
|
print("Commit changes to the packageset? [yN] ", end="")
|
|
sys.stdout.flush()
|
|
response = sys.stdin.readline()
|
|
if not response.strip().lower().startswith('y'):
|
|
sys.exit(1)
|
|
|
|
if additions:
|
|
packageset.addSources(names=additions)
|
|
if removals:
|
|
packageset.removeSources(names=removals)
|
|
|