#!/bin/sh # # Copyright (C) 2013, 2016, 2017, 2019, 2020, 2021 Etersoft # Copyright (C) 2013, 2016, 2017, 2019, 2020, 2021 Vitaly Lipatov <lav@etersoft.ru> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # 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 Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # load_helper epm-query load_helper epm-repofix load_helper epm-reposave assure_safe_run() { if [ "$TERM" = "linux" ] ; then message "You have the best choise to run the '# epm release-upgrade' from text console." return fi if [ "$TERM" != "screen" ] ; then if [ -n "$force" ] ; then message 'You force me running not under screen (TERM=$TERM now)! You can lost your system!' return else warning 'It is very dangerous to upgrade to next release from a GUI (your TERM=$TERM).' if is_installed screen ; then warning "You have 'screen' already installed, just run upgrade via screen (check https://losst.ru/komanda-screen-linux if needed)." else warning "It is recommended install 'screen' and run upgrade via screen (check https://losst.ru/komanda-screen-linux if needed)." fi fatal "or run me with --force if you understand the risk." fi fi # run under screen, check if systemd will not kill our processes local res if ! is_active_systemd ; then return fi res="$(a= busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager KillUserProcesses)" if [ "$res" = "b false" ] ; then message "Good news: systemd-logind will not kill your screen processes (KillUserProcesses=false)" return else if [ -n "$force" ] ; then warning "You force runnning even if systemd-logind kills screen on disconnect" else if ! epm installed systemd-settings-disable-kill-user-processes ; then docmd epm install systemd-settings-disable-kill-user-processes || fatal "Can't install the package above. Fix it or run with --force." fi # commented, will kick off the user from the system (ALT issue 50580) #docmd serv systemd-logind restart || fatal "Can't restart systemd-logind service. Fix it or run with --force." fatal "Now you need relogin to the system. In this session your screen still will be killed." fi fi # check too: KillExcludeUsers # can continue return 0 } __wcount() { echo "$*" | wc -w } __p11_upgrade_fix() { if [[ ! $(docmd epm installed apt-conf-branch) ]]; then info "Need to install default apt-conf package to avoid missing $TO repo" docmd epm install apt-conf-branch || fatal fi # libcrypto1.1 fix docmd epm repo save docmd epm repo rm all docmd apt-repo add branch sisyphus 2024/05/22 docmd epm update docmd epm install libcrypto1.1 docmd epm repo rm all docmd epm repo restore } __sisyphus_downgrade_fix() { if [[ ! $(docmd epm installed apt-conf-branch) ]]; then info "Need to install default apt-conf package to avoid missing $TO repo" docmd epm install apt-conf-branch || fatal fi } # TODO: remove it or move to distro_info __detect_alt_release_by_repo() { local BRD=$(cat /etc/apt/sources.list /etc/apt/sources.list.d/*.list \ | grep -v "^#" \ | grep -E "[tpc][1-3]?[5-9][f.]?[0-9]?/branch/" \ | sed -e "s|.*\([tpc][1-3]\?[5-9][f.]\?[0-9]\?\)/branch.*|\1|g" \ | sort -u ) if [ "$(__wcount $BRD)" = "1" ] ; then echo "$BRD" return fi local BRD=$(cat /etc/apt/sources.list /etc/apt/sources.list.d/*.list \ | grep -v "^#" \ | grep "Sisyphus/" \ | sed -e "s|.*\(Sisyphus\).*|\1|g" \ | sort -u ) if [ "$(__wcount $BRD)" = "1" ] ; then echo "$BRD" return fi return 1 } __get_conflict_release_pkg() { epm qf --quiet --short /etc/fedora-release | head -n1 } get_fix_release_pkg() { local TOINSTALL='' local FORCE='' if [ "$1" = "--force" ] ; then FORCE="$1" shift fi local TO="$1" if [ "$TO" = "Sisyphus" ] ; then TO="sisyphus" echo "apt-conf-$TO" # apt-conf-sisyphus and apt-conf-branch conflicts epm installed apt-conf-branch && echo "apt-conf-branch-" #for i in apt apt-rsync libapt libpackagekit-glib librpm7 packagekit rpm synaptic realmd libldap2 ; do # epm installed $i && echo "$i" #done else epm installed apt-conf-branch && echo "apt-conf-branch" && epm installed apt-conf-sisyphus && echo "apt-conf-sisyphus-" fi if [ "$FORCE" = "--force" ] ; then # assure we have set needed release TOINSTALL="altlinux-release-$TO" else # just assure we have /etc/altlinux-release and switched from sisyphus if [ ! -s /etc/altlinux-release ] || epm qf /etc/altlinux-release | grep -q sisyphus ; then TOINSTALL="altlinux-release-$TO" fi fi #local AR="$(epm --short qf /etc/altlinux-release)" #if [ -n "$AR" ] && [ "$AR" != "$TOINSTALL" ] ; then # echo "$AR-" #fi # TODO: add bug? # workaround against obsoleted altlinux-release-sisyphus package from 2008 year [ "$TOINSTALL" = "altlinux-release-sisyphus" ] && TOINSTALL="branding-alt-sisyphus-release" if epm installed etersoft-gpgkeys ; then # TODO: we don't support LINUX@Etersoft for now # leave etersoft-gpgkeys only if we have LINUX@Etersoft repo #epm repo list | grep -q "LINUX@Etersoft" && echo "etersoft-gpgkeys" || echo "alt-gpgkeys" epm --quiet repo comment "LINUX@Etersoft" echo "alt-gpgkeys" else # update if installed (just print package name here to include in the install list) epm query --short alt-gpgkeys 2>/dev/null fi if [ -n "$TOINSTALL" ] ; then echo "$TOINSTALL" # workaround against # file /etc/fedora-release from install of altlinux-release-p8-20160414-alt1 conflicts with file from package branding-simply-linux-release-8.2.0-alt1 # problem local AR="$(__get_conflict_release_pkg)" if [ -n "$AR" ] && [ "$TOINSTALL" != "$AR" ] ; then #echo $AR- # remove conflicts package right here to workaround against asking 'Yes, do as I say!' later epm remove --nodeps $AR >/dev/null fi fi } __check_system() { local TO="$1" shift # sure we have systemd if systemd is running if is_active_systemd ; then docmd epm --skip-installed install systemd || fatal fi if [ "$TO" != "Sisyphus" ] ; then # note: we get --base-version directy to get new version if [ "$($DISTRVENDOR --base-version)" != "$TO" ] || epm installed altlinux-release-sisyphus >/dev/null ; then warning 'Current distro still is not $TO, or altlinux-release-sisyphus package is installed.' warning 'Trying to fix with altlinux-release-$TO' docmd epm install altlinux-release-$TO fi fi # switch from prefdm: https://bugzilla.altlinux.org/show_bug.cgi?id=26405#c47 if is_active_systemd ; then if serv display-manager exists || serv prefdm exists ; then # don't stop running X server! # docmd serv dm off docmd serv disable prefdm docmd serv disable display-manager docmd serv enable display-manager # $ epm sf dm.service # xinitrc: /lib/systemd/system/dm.service # gdm: /lib/systemd/system/gdm.service # lightdm: /lib/systemd/system/lightdm.service # lxde-lxdm: /lib/systemd/system/lxdm.service # xinitrc: /lib/systemd/system/prefdm.service # sddm: /lib/systemd/system/sddm.service # enable first available DM for i in lightdm sddm lxde-lxdm gdm ; do serv $i exists && docmd serv enable $i && break done fi fi } __epm_ru_update() { docmd epm update && return # TODO: there can be errors due obsoleted alt-gpgkeys epm update 2>&1 | grep "E: Unknown vendor ID" || return info "Drop vendor signs" __alt_replace_sign_name "" docmd epm update } __switch_repo_to() { epm_reposwitch "$@" __epm_ru_update || fatal } get_next_release() { local FROM="$1" case "$FROM" in "p6") echo "p7" ;; "p7") echo "p8" ;; "p8") echo "p9" ;; "p9") echo "p10" ;; "p10") echo "p11" ;; "c6") echo "c7" ;; "c7") echo "c8" ;; # "c8") # echo "c8.1" ;; "c8.1") echo "c8.2" ;; "c8") echo "c9f2" ;; "c9f1") echo "c9f2" ;; "c10f1") echo "c10f2" ;; *) echo "$FROM" ;; esac } __do_upgrade() { docmd epm $non_interactive $force_yes upgrade || fatal "Check the errors and run '# $0' again" } # TODO: install new conf without signs? __switch_alt_to_distro() { local TO="$2" local FROM="$1" info try_change_alt_repo case "$*" in "p6"|"p6 p7"|"t6 p7"|"c6 c7") confirm_info "Upgrade $DISTRNAME from $FROM to $TO ..." docmd epm install rpm apt $(get_fix_release_pkg "$FROM") || fatal __switch_repo_to $TO docmd epm install rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" end_change_alt_repo __do_upgrade docmd epm update-kernel info "Run epm release-upgrade again for update to p8" ;; "p7"|"p7 p8"|"t7 p8"|"c7 c8") confirm_info "Upgrade $DISTRNAME from $FROM to $TO ..." docmd epm install rpm apt $(get_fix_release_pkg "$FROM") || fatal __switch_repo_to $TO docmd epm install rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" end_change_alt_repo __do_upgrade __check_system "$TO" docmd epm update-kernel || fatal info "Run epm release-upgrade again for update to p9" ;; "c8"|"c8.1"|"c8.2"|"c8 c8.1"|"c8.1 c8.2"|"c8 c8.2") confirm_info "Upgrade $DISTRNAME from $FROM to $TO ..." docmd epm install rpm apt $(get_fix_release_pkg "$FROM") || fatal __switch_repo_to $TO docmd epm install rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" end_change_alt_repo __do_upgrade __check_system "$TO" docmd epm update-kernel || fatal ;; "p8 c8"|"p8 c8.1"|"p8 c8.2") confirm_info "Upgrade $DISTRNAME from $FROM to $TO ..." docmd epm install rpm apt $(get_fix_release_pkg "$FROM") || fatal __switch_repo_to $TO docmd epm install rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" if epm installed libcrypt ; then # glibc-core coflicts libcrypt docmd epm downgrade apt pam pam0_passwdqc glibc-core libcrypt- || fatal fi docmd epm $non_interactive $force_yes downgrade || fatal end_change_alt_repo __do_upgrade __check_system "$TO" docmd epm update-kernel || fatal ;; "p8"|"p8 p9"|"t8 p9"|"c8 c9"|"c8 p9"|"c8.1 p9"|"c8.2 p9"|"p9 p9"|"p9 c9f2") confirm_info "Upgrade $DISTRNAME from $FROM to $TO ..." docmd epm install rpm apt $(get_fix_release_pkg "$FROM") || fatal info "Workaround for https://bugzilla.altlinux.org/show_bug.cgi?id=35492 ..." if epm installed gdb >/dev/null ; then docmd epm remove gdb || fatal fi __switch_repo_to $TO end_change_alt_repo __do_upgrade docmd epm install rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" __check_system "$TO" docmd epm update-kernel || fatal info "Run epm release-upgrade again for update to p10" ;; "p9"|"p9 p10"|"p10 p10"|"p10 p11") info "Upgrade all packages to current $FROM repository" __do_upgrade confirm_info "Upgrade $DISTRNAME from $FROM to $TO ..." docmd epm install rpm apt $(get_fix_release_pkg "$FROM") || fatal if [ $TO = "p11" ]; then __p11_upgrade_fix; fi __switch_repo_to $TO end_change_alt_repo __do_upgrade docmd epm install rpm apt $(get_fix_release_pkg "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" __check_system "$TO" docmd epm update-kernel -t std-def || fatal ;; "p9 p8"|"c8.1 c8"|"c8.1 p8"|"p8 p8") confirm_info "Downgrade $DISTRNAME from $FROM to $TO ..." docmd epm install $(get_fix_release_pkg "$FROM") __switch_repo_to $TO docmd epm downgrade rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" if epm installed libcrypt >/dev/null ; then # glibc-core coflicts libcrypt docmd epm downgrade apt rpm pam pam0_passwdqc glibc-core libcrypt- || fatal fi docmd epm $force_yes $non_interactive downgrade || fatal "Check the error and run '# epm downgrade'" end_change_alt_repo __check_system "$TO" docmd epm upgrade || fatal ;; "p9 c8"|"p9 c8.1"|"p9 c8.2") confirm_info "Downgrade $DISTRNAME from $FROM to $TO ..." docmd epm install $(get_fix_release_pkg "$FROM") __switch_repo_to $TO docmd epm downgrade rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" #if epm installed libcrypt >/dev/null ; then # # glibc-core coflicts libcrypt # docmd epm downgrade apt rpm pam pam0_passwdqc glibc-core libcrypt- || fatal #fi docmd epm $force_yes $non_interactive downgrade || fatal "Check the error and run '# epm downgrade'" end_change_alt_repo __check_system "$TO" docmd epm upgrade || fatal ;; "p10 p9"|"p11 p9") confirm_info "Downgrade $DISTRNAME from $FROM to $TO ..." docmd epm install $(get_fix_release_pkg "$FROM") __switch_repo_to $TO docmd epm downgrade rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" docmd epm $force_yes $non_interactive downgrade || fatal "Check the error and run '# epm downgrade'" end_change_alt_repo __check_system "$TO" docmd epm upgrade || fatal ;; "Sisyphus p8"|"Sisyphus p9"|"Sisyphus p10"|"Sisyphus p11"|"Sisyphus c8"|"Sisyphus c8.1"|"Sisyphus c9f2"|"Sisyphus c10f1"|"Sisyphus c10f2") confirm_info "Downgrade $DISTRNAME from $FROM to $TO ..." docmd epm install $(get_fix_release_pkg "$FROM") if [ $TO = "p11" ]; then __sisyphus_downgrade_fix; fi __switch_repo_to $TO docmd epm downgrade rpm apt $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" docmd epm $force_yes $non_interactive downgrade || fatal "Check the error and run '# epm downgrade'" end_change_alt_repo __check_system "$TO" docmd epm upgrade || fatal ;; "p8 Sisyphus"|"p9 Sisyphus"|"p10 Sisyphus"|"p11 Sisyphus"|"10 Sisyphus"|"Sisyphus Sisyphus") confirm_info "Upgrade $DISTRNAME from $FROM to $TO ..." docmd epm install rpm apt $(get_fix_release_pkg "$FROM") || fatal docmd epm upgrade || fatal # TODO: epm_reposwitch?? __replace_alt_version_in_repo "$FROM/branch/" "$TO/" __switch_repo_to $TO [ -s /etc/rpm/macros.d/p10 ] && rm -fv /etc/rpm/macros.d/p10 [ -s /etc/rpm/macros.d/p11 ] && rm -fv /etc/rpm/macros.d/p11 __epm_ru_update || fatal docmd epm fix || fatal docmd epm install $(get_fix_release_pkg --force "$TO") || fatal "Check the errors and run '# epm release-upgrade' again" #local ADDPKG #ADDPKG=$(epm -q --short make-initrd sssd-ad 2>/dev/null) #docmd epm install librpm7 librpm rpm apt $ADDPKG $(get_fix_release_pkg --force "$TO") ConsoleKit2- || fatal "Check an error and run again" end_change_alt_repo docmd epm $force_yes $non_interactive upgrade || fatal "Check the error and run '# epm release-upgrade' again or just '# epm upgrade'" docmd epm $force_yes $non_interactive downgrade || fatal "Check the error and run '# epm downgrade'" __check_system "$TO" docmd epm update-kernel || fatal ;; *) if [ "$FROM" = "$TO" ] ; then info 'It seems your system is already $DISTRNAME $TO' else warning 'Unknown distro version. Have no idea how to switch from $DISTRNAME $FROM to $DISTRNAME $TO.' fi end_change_alt_repo info "Try run f.i. '# epm release-upgrade p10' or '# epm release-downgrade p9' or '# epm release-upgrade Sisyphus'" info "Also possible you need install altlinux-release-p? package for correct distro version detecting" return 1 esac docmd epm clean docmd epm update } epm_release_upgrade() { assure_root assure_safe_run info "Starting upgrade/switch whole system to other release" info "Check also http://wiki.etersoft.ru/Admin/UpdateLinux" cd / || fatal # TODO: it is possible eatmydata does not do his work export EPMNOEATMYDATA=1 case $BASEDISTRNAME in "alt") __epm_ru_update || fatal # TODO: remove this hack (or move it to distro_info) # try to detect current release by repo if [ "$DISTRVERSION" = "Sisyphus" ] || [ -z "$DISTRVERSION" ] ; then local dv dv="$(__detect_alt_release_by_repo)" if [ -n "$dv" ] && [ "$dv" != "$DISTRVERSION" ] ; then DISTRVERSION="$dv" info 'Detected running $DISTRNAME $DISTRVERSION (according to using repos)' fi fi TARGET="" [ -n "$3" ] && fatal 'Too many args: $*' if [ -n "$2" ] ; then DISTRVERSION="$1" info 'Force current distro version as $DISTRVERSION' TARGET="$2" elif [ -n "$1" ] ; then TARGET="$1" fi [ "$TARGET" = "Sisyphus" ] && info "Check also https://www.altlinux.org/Update/Sisyphus" [ -n "$TARGET" ] || TARGET="$(get_next_release $DISTRVERSION)" __alt_repofix __switch_alt_to_distro $DISTRVERSION $TARGET && info 'Done. The system has been successfully upgraded to the next release $TO.' return 0 ;; *) ;; esac case $DISTRNAME in "Mageia") epm repo remove all sudocmd urpmi.addmedia --distrib --mirrorlist 'http://mirrors.mageia.org/api/mageia.8.$DISTRARCH.list' sudocmd urpmi --auto-update $non_interactive $force return ;; "OpenMandrivaLx") sudocmd dnf clean all sudocmd dnf distro-sync --allowerasing return ;; "ROSA") # TODO: move to distro related upgrade #epm repo remove all # FIXME: don't work: #epm repo add "http://mirror.rosalinux.ru/rosa/rosa2021.1/repository/$DISTRARCH" #showcmd urpmi.addmedia --distrib http://mirror.yandex.ru/mandriva/devel/2010.2/i586/ #sudocmd urpmi --auto-update --replacefiles return ;; *) ;; esac case $PMTYPE in apt-rpm) #docmd epm update info 'Have no idea how to upgrade $DISTRNAME. It is possible you need use release-downgrade' ;; *-dpkg) assure_exists do-release-upgrade update-manager-core sudocmd do-release-upgrade ;; packagekit) docmd pkcon upgrade-system "$@" ;; yum-rpm) docmd epm install rpm yum sudocmd yum clean all info "Try do manually:" showcmd rpm -Uvh http://mirror.yandex.ru/fedora/linux/releases/16/Fedora/x86_64/os/Packages/fedora-release-16-1.noarch.rpm showcmd epm Upgrade ;; dnf-rpm) if [ "$DISTRNAME/$DISTRVERSION" = "CentOS/8" ] ; then if [ "$1" = "RockyLinux" ] ; then info "https://github.com/rocky-linux/rocky-tools/tree/main/migrate2rocky/" confirm_info "Switch to Rocky Linux 8.x" cd /tmp docmd epm install git sudocmd git clone https://github.com/rocky-linux/rocky-tools.git || fatal sudocmd bash rocky-tools/migrate2rocky/migrate2rocky.sh -r exit fi if [ "$1" = "OracleLinux" ] ; then info "Check https://t.me/srv_admin/1630" confirm_info "Switch to Oracle Linux 8.x" cd /tmp docmd epm install git sudocmd sed -i -r \ -e 's!^mirrorlist=!#mirrorlist=!' \ -e 's!^#?baseurl=http://(mirror|vault).centos.org/\$contentdir/\$releasever/!baseurl=https://dl.rockylinux.org/vault/centos/8.5.2111/!i' \ /etc/yum.repos.d/CentOS-*.repo sudocmd git clone https://github.com/oracle/centos2ol.git || fatal a= bash centos2ol/centos2ol.sh exit fi info "Check https://www.cyberciti.biz/howto/upgrade-migrate-from-centos-8-to-centos-stream-conversion/" confirm_info "Switch to CentOS Stream?" sudocmd sed -i -r \ -e 's!^mirrorlist=!#mirrorlist=!' \ -e 's!^#?baseurl=http://(mirror|vault).centos.org/\$contentdir/\$releasever/!baseurl=https://dl.rockylinux.org/vault/centos/8.5.2111/!i' \ /etc/yum.repos.d/CentOS-*.repo docmd epm install centos-release-stream sudocmd dnf swap centos-{linux,stream}-repos sudocmd dnf distro-sync info "You can run '# epm autoorphans' to remove orphaned packages" exit fi if [ "$DISTRNAME" = "RockyLinux" ] ; then sudocmd dnf --refresh upgrade || fatal sudocmd dnf clean all info "Check https://www.centlinux.com/2022/07/upgrade-your-servers-from-rocky-linux-8-to-9.html" info "For upgrading your yum repositories from Rocky Linux 8 to 9 ..." epm install "https://download.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os/Packages/r/rocky-gpg-keys*.rpm" || fatal epm install "https://download.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os/Packages/r/rocky-repos*.rpm" "https://download.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os/Packages/r/rocky-release*.rpm" || fatal # hack (TODO) DV=$(echo "$DISTRVERSION" | sed -e "s|\..*||") local RELEASEVER="$1" [ -n "$RELEASEVER" ] || RELEASEVER=$(($DV + 1)) confirm_info 'Upgrade to $DISTRNAME/$RELEASEVER' sudocmd dnf distro-sync -y --releasever=$RELEASEVER --allowerasing --setopt=deltarpm=false sudocmd rpm --rebuilddb epm upgrade info "You can run '# epm autoorphans' to remove orphaned packages" info "Use # dnf module reset <module> to resolve 'nothing provides module' error" exit fi info "Check https://fedoraproject.org/wiki/DNF_system_upgrade for an additional info" #docmd epm install epel-release yum-utils sudocmd dnf --refresh upgrade || fatal sudocmd dnf clean all assure_exists dnf-plugin-system-upgrade sudocmd dnf upgrade --refresh local RELEASEVER="$1" [ -n "$RELEASEVER" ] || RELEASEVER=$(($DISTRVERSION + 1)) #[ -n "$RELEASEVER" ] || fatal "Run me with new version" confirm_info 'Upgrade to $DISTRNAME/$RELEASEVER' sudocmd dnf system-upgrade download --refresh --releasever=$RELEASEVER # TODO: from docs: # dnf system-upgrade reboot # FIXME: download all packages again sudocmd dnf distro-sync --releasever=$RELEASEVER info "You can run '# epm autoorphans' to remove orphaned packages" ;; zypper-rpm) docmd epm repolist # TODO: move to distro related upgrade # sudocmd zypper rr <номер_репозитория> showcmd rr N showcmd epm ar http://mirror.yandex.ru/opensuse/distribution/11.1/repo/oss 11.1oss showcmd zypper ref docmd epm update docmd epm install rpm zypper docmd epm upgrade ;; pacman) docmd epm Upgrade ;; conary) docmd epm Upgrade ;; emerge) docmd epm Upgrade ;; guix) sudocmd guix pull --verbose ;; *) fatal 'Have no suitable command for $PMTYPE' ;; esac }