From fbe7a7d5b1470c722419c6d3e2ca29e233420375 Mon Sep 17 00:00:00 2001 From: Dustin Kirkland Date: Thu, 10 Sep 2009 12:10:47 -0500 Subject: [PATCH] * bin/updates-available, profiles/common: - reworked to be far more efficient, and accurate, LP: #427373 - look at the timestamp on /var/lib/apt, and only update cache if /var/lib/apt has been touched since the cache - in particular, these changes fix a bug when the user does an apt-get install or upgrade, and changes to the update status are not update for up to an hour later; with these fixes, it's nearly immediate - and now that updates_available is trivial (in most cases), we can run it more frequently --- bin/updates_available | 101 ++++++++++++++++++------------------------ debian/changelog | 11 ++++- profiles/common | 2 +- 3 files changed, 54 insertions(+), 60 deletions(-) diff --git a/bin/updates_available b/bin/updates_available index 56a848b9..d864b891 100755 --- a/bin/updates_available +++ b/bin/updates_available @@ -30,11 +30,6 @@ if [ "$1" = "--detail" -o "$1" = "--short" ]; then exit 0 fi -PKG="byobu" - -# expire the cache in X seconds; 1 hour by default -EXPIRATION=3600 - print_updates() { u=$1 s=$2 @@ -49,65 +44,55 @@ print_updates() { printf "\005{-} " fi fi - exit 0 } -cache="/var/run/updates-available" -mycache="/var/run/screen/S-$USER/$PKG.updates-available" -now=`date +%s` -cache_timestamp=`stat -c "%Y" $cache 2>/dev/null || echo 0` -mycache_timestamp=`stat -c "%Y" $mycache 2>/dev/null || echo 0` -diff=`expr $now - $cache_timestamp` -u= -# If global updates-available cache is present, and newer than mycache, and -# within expiration, use it, and cache it (to preserve across reboots). -# Only available in Jaunty+. -if [ -r $cache -a $cache_timestamp -gt $mycache_timestamp -a $diff -lt $EXPIRATION ]; then - u=`grep -m 1 "^[0-9]" $cache | sed "s/\s.*$//"` - s=`grep -m 2 "^[0-9]" $cache | tail -n 1 | sed "s/\s.*$//"` - cp -a "$cache" "$mycache" - print_updates $u $s -fi - -# If the user's updates-available cache is present, and less than an hour old, -# use it. (The "hour" part should be configurable) -if [ -r $mycache -a -O $mycache ]; then - diff=`expr $now - $mycache_timestamp` - if [ $diff -lt $EXPIRATION ]; then - print_updates `grep "^[0-9]" $mycache | sed "s/ .*$//"` - fi -else - # Otherwise, let's quickly clear the cache, and then recreate it with - # a really old timestamp (so that it get's updated on next run) - # and exit immediately +update_cache() { + mycache=$1 + # Clear the cache, and background an immediate update. rm -f $mycache touch -t 197001010000 $mycache - exit 0 -fi + # Now we actually have to do hard computational work to calculate updates. + # Let's try to be "nice" about it: + renice 10 $$ >/dev/null 2>&1 || true + ionice -c3 -p $$ >/dev/null 2>&1 || true + # These are very computationally intensive processes. + # Background this work, have it write to the cache files, + # and let the next cache check pick up the results. + if [ -x /usr/lib/update-notifier/apt-check ]; then + # If apt-check binary exists, use it + exec /usr/lib/update-notifier/apt-check 2>&1 | tail -n 1 | sed "s/;/ /" > $mycache & + elif which apt-get >/dev/null; then + # If apt-get exists, use it + exec apt-get -s -o Debug::NoLocking=true upgrade | grep -c ^Inst > $mycache & + elif which zypper >/dev/null; then + # If zypper exists, use it + exec zypper --no-refresh lu --best-effort | grep 'v |' | wc -l > $mycache & + elif which yum >/dev/null; then + # If yum exists, use it + # TODO: We need a better way of counting updates available from a RH expert + exec yum list updates | egrep -v "Updated Packages|Loaded plugins" | wc -l > $mycache & + fi +} -# If we make it to this point, we actually have to do hard computational -# work to calculate updates. Let's try to be "nice" about it: -renice 10 $$ >/dev/null 2>&1 || true -ionice -c3 -p $$ >/dev/null 2>&1 || true +PKG="byobu" -# These are very computationally intensive processes. -# Background this work, have it write to the cache files, -# and let the next cache check pick up the results. +# The following is somewhat Ubuntu and Debian specific. +# I would welcome contributions from other distros to make this +# more distro-agnostic. -if [ -x /usr/lib/update-notifier/apt-check ]; then - # If apt-check binary exists, use it - /usr/lib/update-notifier/apt-check 2>&1 | tail -n 1 | sed "s/;/ /" > $mycache & -elif which apt-get >/dev/null; then - # If apt-get exists, use it - apt-get -s -o Debug::NoLocking=true upgrade | grep -c ^Inst > $mycache & -elif which zypper >/dev/null; then - # If zypper exists, use it - zypper --no-refresh lu --best-effort | grep 'v |' | wc -l > $mycache & -elif which yum >/dev/null; then - # If yum exists, use it - # TODO: We need a better way of counting updates available from a RH expert - yum list updates | egrep -v "Updated Packages|Loaded plugins" | wc -l > $mycache & +cache="/var/lib/update-notifier/updates-available" +mycache="/var/run/screen/S-$USER/$PKG.updates-available" + +# If global cache is newer than mycache, overwrite mycache +[ $cache -nt $mycache ] && cp -a "$cache" "$mycache" + +# If apt is newer than mycache, background an update now +[ "/var/lib/apt" -nt "$mycache" ] && update_cache "$mycache" + +# If mycache is present, use it +if [ -r $mycache ]; then + print_updates `grep "^[0-9]" $mycache | sed "s/ .*$//"` else - # If we're here, we have no idea - print_updates "?" + # Otherwise, background an update now + update_cache "$mycache" fi diff --git a/debian/changelog b/debian/changelog index 0ad955ea..7f045235 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,16 @@ byobu (2.31) unreleased; urgency=low [ Dustin Kirkland ] - * UNRELEASED + * bin/updates-available, profiles/common: + - reworked to be far more efficient, and accurate, LP: #427373 + - look at the timestamp on /var/lib/apt, and only update cache + if /var/lib/apt has been touched since the cache + - in particular, these changes fix a bug when the user does an + apt-get install or upgrade, and changes to the update status + are not update for up to an hour later; with these fixes, it's + nearly immediate + - and now that updates_available is trivial (in most cases), we + can run it more frequently [ Mathias Gug ] * Check that byobu-launcher exists before calling it (chroots use the same diff --git a/profiles/common b/profiles/common index a6f61cab..935ec231 100644 --- a/profiles/common +++ b/profiles/common @@ -37,7 +37,7 @@ backtick 10 86389 86389 byobu-janitor backtick 11 86399 86399 printf "\005-1=" backtick 99 86011 86011 byobu-status logo backtick 100 599 599 byobu-status release -backtick 101 181 181 byobu-status updates_available +backtick 101 7 7 byobu-status updates_available backtick 102 5 5 byobu-status reboot_required backtick 103 2 2 byobu-status cpu_freq backtick 104 86017 86017 byobu-status cpu_count