123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- #!/bin/sh
- # SlackCheck
- #
- # $Id: slcheck.sh,v 1.45 2010/03/02 12:28:54 gf Exp $
- #
- # Copyright (c) 2002-2006 Georgi Chorbadzhiyski, Sofia, Bulgaria
- # All rights reserved.
- #
- # Redistribution and use of this script, with or without modification, is
- # permitted provided that the following conditions are met:
- #
- # 1. Redistributions of this script must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- #
- # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #
-
- echo "SlackCheck v3.91"
- echo
-
- cd $(dirname $0)
-
- INC_CONFIG="0"
- . ./config.sh
-
- if [ "$INC_CONFIG" = "0" ]
- then
- echo "*** Error including ./config.sh"
- exit
- fi
-
- # Show usage information
- usage() {
- echo "Usage: $(basename $0) [options]"
- echo
- echo " OPTIONS:"
- echo
- echo " --local Operate on local machine"
- echo " --host h1 h2 h3 Upgrade this host(s)"
- echo " --file filename Read list of hosts from this file"
- echo
- echo " --sync Get latest list of packages from the WWW/FTP/Local file"
- echo
- echo " --collect Build package lists for hosts that'll be upgraded"
- echo
- echo " --gen Generate upgrade scripts"
- echo
- echo " --upgrade Upgrade hosts using generated scripts"
- echo " --dist Only copy upgrade scripts to hosts, do not updgrade"
- echo
- echo " --skip-ignore Skip checks for ignored packages"
- echo
- echo " --verbose Show more info when update scripts are generated"
- echo
- echo " HOW TO UPGRADE CURRENT HOST"
- echo " Run: $(basename $0) --local --sync --collect --gen --upgrade"
- echo
- echo " HOW TO UPGRADE MULTIPLE HOSTS:"
- echo " Edit: \"update_hosts\" file to add your slackware machines"
- echo " Run: $(basename $0) --sync --collect --gen"
- echo " Edit: ${DIR_UPD}/${FILE_UPDATES}*"
- echo " Run: $(basename $0) --upgrade (for automatic upgrade)"
- echo " or"
- echo " Run: $(basename $0) --dist (for manual upgrade after that)"
- echo
- echo " HOW TO UPGRADE SINGLE HOST:"
- echo " Run: $(basename $0) --host blah.example.org --sync --collect --gen --upgrade"
- echo
- exit 1
- }
-
- # Get newest package list
- sync_master_list() {
- echo "===> Getting newest package list..."
- WD=$(pwd)
- mkdir $DIR_PKG 2>/dev/null
- cd $DIR_PKG
- TMPDIR=".Tmp"
- rm -rf $TMPDIR 2>/dev/null
- mkdir $TMPDIR && cd $TMPDIR
-
- ${DL_PRG} ${DL_PRG_OPTS} ${DL_HOST}/CHECKSUMS.md5
-
- # Parse file
- grep -E "\.t[a-z]z$" CHECKSUMS.md5 | grep patches | cut -d" " -f3 | sed -e 's|\./||' > ../${FILE_NEWEST}
- grep -E "\.t[a-z]z$" CHECKSUMS.md5 | grep slackware | cut -d" " -f3 | sed -e 's|\./||' >> ../${FILE_NEWEST}
- if [ $(LANG=C ls -l ../${FILE_NEWEST} | tr -s ' ' | cut -d" " -f 5) = "0" ]
- then
- grep -E "\.t[a-z]z$" CHECKSUMS.md5 | cut -d" " -f3 | sed -e 's|\./||' >> ../${FILE_NEWEST}
- fi
- rev < ../${FILE_NEWEST} | cut -d- -f4- | rev | sed -e 's|.*/||;s|[^A-Za-z0-9_]|_|g' > ../.${FILE_NEWEST}.base
- paste ../.${FILE_NEWEST}.base ../${FILE_NEWEST} | sed -e 's|\.\(t[a-z]z\)| \1|' > ../.${FILE_NEWEST}.paste
- cd ..
- rm -rf $TMPDIR 2>/dev/null
- cd $WD
- }
-
- # Generate list of packages for every host
- collect_package_lists() {
- [ -d $DIR_PKG ] || mkdir -p $DIR_PKG
- echo "===> Collecting package lists..."
- for HOST in $SLACK_HOSTS
- do
- echo " ---> $HOST"
- # Localhost
- if [ "$HOST" == "$(hostname)" -o \
- "$HOST" == "$(hostname -f)" -o \
- "$HOST" == "localhost" ]
- then
- ls /var/log/packages > ${DIR_PKG}/$HOST
- # Remote host
- else
- ${RSH_LISTS} $HOST "ls /var/log/packages" > ${DIR_PKG}/${HOST}.tmp
- mv ${DIR_PKG}/${HOST}.tmp ${DIR_PKG}/${HOST} 2>/dev/null
- fi
- done
- }
-
- # Generate upgrade scripts
- generate_upgrade_scripts() {
- [ -d ${DIR_UPD} ] || mkdir ${DIR_UPD}
- echo "===> Generating upgrade scripts..."
- if [ ! -f ${DIR_PKG}/.${FILE_NEWEST}.paste ]
- then
- sync_master_list
- fi
- # Init \$basepkg variables
- while read basepkg hostpkg ext
- do
- eval $basepkg=$hostpkg
- eval E_$basepkg=$hostpkg.$ext
- done < ${DIR_PKG}/.${FILE_NEWEST}.paste
- for HOST in $SLACK_HOSTS
- do
- UPDATED=0
- SKIPPED=0
- CURRENT=0
- UNKNOWN=0
- TOTAL=0
- CHECKED=0
- FILL=$((28 - $(echo $HOST | wc -c)))
- if [ $FILL -le 0 ]
- then
- FILL=4
- fi
- FL="$(yes "_" | head -$FILL | xargs echo | sed -e 's| ||g;s|_| |g')"
- # Check if package list exist
- if [ -f ${DIR_PKG}/${HOST} ]
- then
- if [ "$VERBOSE" != "1" ]; then
- echo -n " => $HOST "
- else
- echo " => $HOST "
- fi
- # Cleanup old files
- rm ${DIR_UPD}/${FILE_UNKPACKS}${HOST} >/dev/null 2>&1
- rm ${DIR_UPD}/${FILE_UPDATES}${HOST} >/dev/null 2>&1
- rm ${DIR_UPD}/${FILE_UPDATES}${HOST}.* >/dev/null 2>&1
- # Generate file with package basenames
- rev < ${DIR_PKG}/$HOST | cut -d- -f4- | rev | sed -e 's|.*/||;s|[^A-Za-z0-9_]|_|g' > ${DIR_UPD}/${FILE_UPDATES}${HOST}.base
- paste ${DIR_PKG}/$HOST ${DIR_UPD}/${FILE_UPDATES}${HOST}.base > ${DIR_UPD}/${FILE_UPDATES}${HOST}.paste
- TOTAL=$(wc -l < ${DIR_UPD}/${FILE_UPDATES}${HOST}.paste)
- while read hostpkg basepkg
- do
- CHECKED=$(($CHECKED + 1))
- # Get package from the distro packages
- # This contains FULL directory + package name
- eval distro_package="\$$basepkg"
- eval distro_package_ext="\$E_$basepkg"
- if [ "$distro_package" != "" -a "$distro_package" != "\$" ]
- then # Host package exist in the distro packages
- distropkg="${distro_package##*/}" # Faster basename using build-in BASH tricks
- if [ "$distropkg" != "$hostpkg" ]
- then
- UPDATED=$(($UPDATED + 1))
- echo "\
- UPDATE=\"\$UPDATE ${distro_package_ext}\" # EXISTING: ${hostpkg}\
- " >> ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs
- if [ "$VERBOSE" == "1" ]; then
- echo " UPD: $hostpkg -> $distropkg ($distro_package_ext)"
- fi
- else
- CURRENT=$(($CURRENT + 1))
- if [ "$VERBOSE" == "1" ]; then
- echo " CURR: $hostpkg -> $distropkg ($distro_package_ext)"
- fi
- fi
- else # Add to unknown packages
- UNKNOWN=$(($UNKNOWN+1))
- if [ "$VERBOSE" == "1" ]; then
- echo " UNKN: $hostpkg"
- fi
- echo "$hostpkg" >> ${DIR_UPD}/${FILE_UNKPACKS}${HOST}
- fi
- if [ "$VERBOSE" != "1" ]; then
- echo -n
" => ${HOST}${FL} Check $CHECKED of $TOTAL"
- fi
- done < ${DIR_UPD}/${FILE_UPDATES}${HOST}.paste
- # Skip ignored packages
- if [ -s ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs -a \
- -f "do_not_update" -a \
- "$SKIP_IGNORE" != "1" ]
- then
- ignore_packs=$(grep ^${HOST}: do_not_update | sed -e 's|^.*:|/|g;s| |\||g' | xargs echo | sed -e 's| |\||g')
- if [ "$ignore_packs" != "" ]
- then
- grep -v -E "${ignore_packs}" ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs > ${DIR_UPD}/.${HOST}.newpkgs.tmp
- if [ -f ${DIR_UPD}/.${HOST}.newpkgs.tmp ]
- then
- skip1=$(wc -l < ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs)
- skip2=$(wc -l < ${DIR_UPD}/.${HOST}.newpkgs.tmp)
- SKIPPED=$(($skip1 - $skip2))
- UPDATED=$(($UPDATED - $SKIPPED))
- fi
- mv ${DIR_UPD}/.${HOST}.newpkgs.tmp ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs
- if [ ! -s ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs ]
- then
- rm ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs
- fi
- fi
- fi
- status="${UPDATED} for update "
- if [ "$UPDATED" = "0" ]; then
- status="Up to date "
- fi
- if [ "$CURRENT" = "0" ]; then
- status="No host info "
- fi
- echo -n
" => ${HOST}${FL} ${status}/cr ${CURRENT} un ${UNKNOWN} sk ${SKIPPED} new ${UPDATED}/"
- echo
- # Add intereter
- if [ -s ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs ]
- then
- sort ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs > ${DIR_UPD}/.${HOST}.newpkgs.tmp
- mv ${DIR_UPD}/.${HOST}.newpkgs.tmp ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs
- (echo '#!/bin/sh'
- echo
- echo "DL_HOST=\"${DL_HOST}\""
- echo "DL_PRG=\"${DL_PRG}\""
- echo "DL_PRG_OPTS=\"${DL_PRG_OPTS}\""
- echo
- echo "MD5_CHECK=\"${MD5_CHECK}\""
- echo "SIG_CHECK=\"${SIG_CHECK}\""
- echo
- echo "REMOTE_DIR=\"${REMOTE_DIR}\""
- echo "REMOTE_DIR_DEL=\"${REMOTE_DIR_DEL}\""
- echo
- echo "SMART_UPGRADE=\"${SMART_UPGRADE}\""
- echo
- echo "GENERATED=\"1\""
- echo
- echo "# If you don't want package to be updated just delete the line."
- echo
- # pkgtools and tar must be first
- # glibc and elflibs next
- cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep a/pkgtools
- cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep a/tar
- cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep a/glibc
- cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep a/elflibs
- cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep -v -E "a/(pkgtools|tar|glibc|elflibs)"
- echo "PKG_KMOD=\"`grep kmod- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo "PKG_GMP=\"`grep gmp- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo "PKG_LIBCAP=\"`grep libcap- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo "PKG_XZ=\"`grep xz- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo "PKG_SED=\"`grep sed- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo "PKG_COREUTILS=\"`grep coreutils- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo "PKG_UTEMPTER=\"`grep utempter- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo "PKG_MODULEINITTOOLS=\"`grep module-init-tools- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo "PKG_AAAELFLIBS=\"`grep aaa_elflibs- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
- echo
- grep -v ^# update_script.sh
- ) > ${DIR_UPD}/${FILE_UPDATES}${HOST}
- fi
- # Cleanup
- rm ${DIR_UPD}/${FILE_UPDATES}${HOST}.* 2>/dev/null
- fi
- done
- echo
- }
-
- # Upgrade remote hosts
- upgrade_machines() {
- NOW=$(date +%Y-%m-%d)
- echo "===> Upgrating hosts..."
- for HOST in $SLACK_HOSTS
- do
- hname=$(hostname 2>/dev/null)
- hname_full=$(hostname -f 2>/dev/null)
- if [ -f ${DIR_UPD}/${FILE_UPDATES}${HOST} ]
- then
- # Localhost
- if [ "$HOST" == "$hname" -o \
- "$HOST" == "$hname_full" -o \
- "$HOST" == "localhost" ]
- then
- echo " ---> $HOST (Local machine)"
- # Use su if we're running not as root
- if [ "$(id -u)" != "0" ]; then
- echo " Enter root password"
- (su -c "/bin/sh ${DIR_UPD}/${FILE_UPDATES}${HOST}") 2>&1 | tee ${DIR_UPD}/log_${FILE_UPDATES}${HOST}
- else
- (/bin/sh ${DIR_UPD}/${FILE_UPDATES}${HOST}) 2>&1 | tee ${DIR_UPD}/log_${FILE_UPDATES}${HOST}
- fi
- # Remote host
- else
- echo " ---> $HOST"
- (cat ${DIR_UPD}/${FILE_UPDATES}${HOST} | \
- ${RSH_UPGRADE} ${HOST} \
- "cat - > ${FILE_UPDATES}${HOST}_${NOW}; \
- /bin/sh ${FILE_UPDATES}${HOST}_${NOW};") 2>&1 | tee ${DIR_UPD}/log_${FILE_UPDATES}${HOST}
- fi
- fi
- done
- }
-
- # Send upgrade scripts to hosts
- distribute_up_scripts() {
- NOW=$(date +%Y-%m-%d)
- echo "===> Copying upgrade scripts..."
- for HOST in $SLACK_HOSTS
- do
- if [ -f ${DIR_UPD}/${FILE_UPDATES}${HOST} ]
- then
- # Localhost
- if [ "$HOST" == "$(hostname)" -o \
- "$HOST" == "$(hostname -f)" -o \
- "$HOST" == "localhost" ]
- then
- echo " ---> $HOST (Local machine - no need to copy upgrade script)"
- # Remote host
- else
- echo " ---> $HOST"
- cat ${DIR_UPD}/${FILE_UPDATES}${HOST} | \
- ${RSH_UPGRADE} ${HOST} \
- "cat - > ${FILE_UPDATES}${HOST}_${NOW}"
- fi
- fi
- done
- }
-
- if [ "$1" = "" ]; then
- usage
- fi
-
- # Process command line arguments
- while [ "$1" != "" ]; do
- param=$1
- shift
- case "$param" in
- --local)
- SLACK_HOSTS="localhost"
- ;;
- --host)
- if [ "$1" != "" ]; then
- SLACK_HOSTS=""
- fi
- while [ "$1" != "" ]; do
- param=$1
- case "$param" in
- --*)
- break
- ;;
- *)
- SLACK_HOSTS="$SLACK_HOSTS $param"
- ;;
- esac
- shift
- done
- ;;
- --file)
- HOSTS_FILE="$1"
- if [ "$HOSTS_FILE" = "" -o ! -f "$HOSTS_FILE" ]; then
- echo "*** --file parameter is missing or file not found."
- echo
- usage
- exit 1
- fi
- SLACK_HOSTS=`grep -v ^# $HOSTS_FILE`
- shift
- ;;
- --sync)
- DO_SYNC="1"
- ;;
- --collect)
- DO_COLLECT="1"
- ;;
- --gen)
- DO_GEN="1"
- ;;
- --dist)
- DO_DIST="1"
- ;;
- --skip-ignore)
- SKIP_IGNORE="1"
- ;;
- --upgrade)
- DO_UPGRADE="1"
- ;;
- --verbose)
- VERBOSE="1"
- ;;
- *)
- usage
- ;;
- esac
- done
-
- if [ "$SLACK_HOSTS" = "" ]; then
- echo "*** No hosts. Check --host parameter, --file parameter ot 'upgrade_hosts' file."
- echo
- exit 1
- fi
-
- echo -n "---> Hosts: "
- echo $SLACK_HOSTS
- echo
-
- [ "$DO_SYNC" = "1" ] && sync_master_list
- [ "$DO_COLLECT" = "1" ] && collect_package_lists
- [ "$DO_GEN" = "1" ] && generate_upgrade_scripts
- [ "$DO_DIST" = "1" ] && distribute_up_scripts
- [ "$DO_UPGRADE" = "1" ] && upgrade_machines
|