Arturo Borrero Gonzalez has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/398079 )
Change subject: apt: unattended-upgrades: add targetted upgrades script ...................................................................... apt: unattended-upgrades: add targetted upgrades script This script is meant to be run by hand by the admins to easily upgrade packages just from the given source repo/channel. Is part of our new workflow for unattended/attended upgrades for servers. Related docs: https://wikitech.wikimedia.org/wiki/Portal:Cloud_VPS/Admin/Attended_package_upgrades Bug: T181647 Change-Id: I88ea78826c763e54f25cac22f2ea65ae301a7645 Signed-off-by: Arturo Borrero Gonzalez <aborr...@wikimedia.org> --- A modules/apt/files/apt-upgrade.py M modules/apt/manifests/unattendedupgrades.pp 2 files changed, 138 insertions(+), 0 deletions(-) Approvals: Faidon Liambotis: Looks good to me, but someone else must approve Arturo Borrero Gonzalez: Verified; Looks good to me, approved Rush: Looks good to me, but someone else must approve diff --git a/modules/apt/files/apt-upgrade.py b/modules/apt/files/apt-upgrade.py new file mode 100644 index 0000000..7d4e117 --- /dev/null +++ b/modules/apt/files/apt-upgrade.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 + +import argparse +import os +import sys +import apt +import apt_pkg +import apt.cache + +# Common usage: +# 'apt-upgrade stretch-security upgrade packages from stretch-security +# 'apt-upgrade stretch-security -s like above, but simulating operations +# 'apt-upgrade stretch-security -v like above, but being verbose +# +# make sure you hold+pin beforehand those packages that should not be upgraded + + +def print_verbose(verbose, msg): + """ print information if verbose + :param verbose: boolean + :param msg: str + """ + if verbose: + print(msg) + + +def print_verbose_pkg(verbose, pkg): + """ print information about a package + :param verbose: boolean + :param pkg: Package + """ + if not verbose: + return + name = pkg.name + orig = pkg._pkg.current_ver.ver_str + if pkg.marked_delete: + dest = "remove" + else: + dest = pkg.candidate.version + print_verbose(verbose, '{} {} --> {}'.format(name, orig, dest)) + + +def pkg_upgrade(verbose, pkg): + """ try to mark a package for upgrade + :param verbose: boolean + :param pkg: Package + """ + if not pkg.is_installed: + return False + try: + pkg.mark_upgrade() + marked_upgrade = True + except apt_pkg.Error as e: + print_verbose(verbose, '{} not for upgrade: {}'.format(pkg.name, str(e))) + pkg.mark_keep() + marked_upgrade = False + + return marked_upgrade + + +class AptFilter(apt.cache.Filter): + """ filter for python-apt cache to filter only packages upgradable from a + specific source. + """ + + def __init__(self, src): + super().__init__() + self.src = src + + def apply(self, pkg): + """ filtering function + :param pkg: Package + """ + if pkg.is_installed and pkg.is_upgradable and \ + pkg.candidate.origins[0].archive == self.src: + return True + + return False + + +def run(src, simulate, verbose): + """ run the cache update, calculate upgrades and commit them + :param src: str + :param simulate: boolean + :param verbose: boolean + """ + cache = apt.Cache() + print_verbose(verbose, "Updating cache ...") + cache.update() + cache.open(None) + fcache = apt.cache.FilteredCache(cache) + fcache.set_filter(AptFilter(src)) + + pkgs_to_upgrade = False + for pkg_name in fcache.keys(): + pkgs_to_upgrade += pkg_upgrade(verbose, cache[pkg_name]) + + if not pkgs_to_upgrade: + print_verbose(verbose, 'No packages found to upgrade from {}'.format(src)) + return + + # report what we will be doing + for pkg in cache.get_changes(): + print_verbose_pkg(verbose, pkg) + + if not simulate: + cache.commit() + else: + print_verbose(verbose, "Simulate, not performing changes") + + cache.close() + + +def main(): + parser = argparse.ArgumentParser(description="Run a targeted upgrade of packages") + parser.add_argument('-v', action='store_true', help="be verbose") + parser.add_argument('-s', action='store_true', + help="simulate operations") + parser.add_argument('source', + help="Main argument: source repository to upgrade from") + args = parser.parse_args() + + if os.geteuid() != 0: + sys.exit("root needed") + + run(args.source, args.s, args.v) + + +if __name__ == "__main__": + main() diff --git a/modules/apt/manifests/unattendedupgrades.pp b/modules/apt/manifests/unattendedupgrades.pp index 0878ac6..ef1b489 100644 --- a/modules/apt/manifests/unattendedupgrades.pp +++ b/modules/apt/manifests/unattendedupgrades.pp @@ -79,4 +79,12 @@ source => 'puppet:///modules/apt/report-pending-upgrades.sh', require => Package['apt-show-versions'], } + + file { '/usr/local/sbin/apt-upgrade': + ensure => present, + owner => 'root', + group => 'root', + mode => '0755', + source => 'puppet:///modules/apt/apt-upgrade.py', + } } -- To view, visit https://gerrit.wikimedia.org/r/398079 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I88ea78826c763e54f25cac22f2ea65ae301a7645 Gerrit-PatchSet: 17 Gerrit-Project: operations/puppet Gerrit-Branch: production Gerrit-Owner: Arturo Borrero Gonzalez <aborr...@wikimedia.org> Gerrit-Reviewer: Arturo Borrero Gonzalez <aborr...@wikimedia.org> Gerrit-Reviewer: Faidon Liambotis <fai...@wikimedia.org> Gerrit-Reviewer: Rush <r...@wikimedia.org> Gerrit-Reviewer: Volans <rcocci...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits