User:Flexibeast/guides/An update function for Gentoo

From Gentoo Wiki
Jump to:navigation Jump to:search

i update my Gentoo system via an update function i've defined in my root .bashrc. This function:

  1. Syncs enabled repositories.
  2. Checks for News items, presenting any new items to the user.
  3. Defers updates of 'big' packages - listed in an /etc/portage/package.big file - so that they can update at a later time. i've set up a cron job to do package updates in the early hours of the morning, which performs such deferred updates while i'm probably not using my machine.
  4. Uses genlop to provide an estimate of the time it will take to merge all updates, based on previous merges, allowing the user to cancel the update if desired.

The only two dependencies are the app-portage/genlop package and the app-text/ansifilter package (in order to remove ANSI escape sequences in the data passed to genlop, which we otherwise want to keep).

FILE /root/.bashrc
function update1 {

        QUIET=no
        if [ "${1}" = "-q" ]
        then
                QUIET=yes
                shift
        fi
        CMD="emerge --color y -uUN ${@} @world"
        if [ "${QUIET}" = "no" ]
        then
                echo "Running '${CMD}' ..."
        fi
        $CMD

}

function update {

        local IFS=' '
        CMD='update1 -q -D'
        DEFERRED=''
        
        emaint -a sync && touch /emaint-sync-done

        if (( "$(eselect news count)" > 0 ))
        then
                eselect news read
        else
                echo -e "No news."
        fi

        echo -e "Checking for updates via '${CMD} -p' ..."
        DATA=$(${CMD} -p)
        UPDATES=$(echo "${DATA}" | awk '/^\[/ { print }')
        if [ -z "${UPDATES}" ]
        then
                echo "No updates."
                return 0
        fi
        echo "Checking for updates to defer ..." 
        ATOMS=$(echo "${DATA}" | awk -F' ' '/^\[ebuild/ { print $4 }' | \
                sed 's/^\(.*\)-[[:digit:]].*$/\1/' | tr '\n' ' ')
        TO_DEFER=$(cat /etc/portage/package.big | tr '\n' ' ')
        for PKG in ${ATOMS}
        do
                if [[ "${TO_DEFER}" == *"${PKG}"* ]] 
                then
                        UPDATES=$(echo "${UPDATES}" | grep -v "${PKG}")
                        echo "Deferring update of ${PKG}."
                        DEFERRED="${DEFERRED} --exclude ${PKG}"
                        touch /deferred-updates
                fi
        done
        if [ -z "${DEFERRED}" ]
        then
                echo "No updates to defer."
        fi

        ESTIMATE=$(echo "${UPDATES}" | ansifilter | genlop -p | awk '/Estimated/ { print }')
        echo "Updating:"
        echo -e "${UPDATES}"
        read -N1 -p "${ESTIMATE} Proceed (Y/n)? " ANSWER
        echo -e "\n"
        if [ "${ANSWER}" = "Y" ]
        then
                ${CMD}${DEFERRED}
        else
                echo "Update aborted."
                return 1   
        fi
        
        emerge -c

}