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

Reply via email to