SlackCheck allows users to keep many Slackware machines up to date with the latest packages. All upgrades are performed from single machine though SSH (or RSH). It generates an upgrade script and list of non-standard packages for every machine. https://georgi.unixsol.org/programs/slackcheck/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

slcheck.sh 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. #!/bin/sh
  2. # SlackCheck
  3. #
  4. # $Id: slcheck.sh,v 1.45 2010/03/02 12:28:54 gf Exp $
  5. #
  6. # Copyright (c) 2002-2006 Georgi Chorbadzhiyski, Sofia, Bulgaria
  7. # All rights reserved.
  8. #
  9. # Redistribution and use of this script, with or without modification, is
  10. # permitted provided that the following conditions are met:
  11. #
  12. # 1. Redistributions of this script must retain the above copyright
  13. # notice, this list of conditions and the following disclaimer.
  14. #
  15. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  16. # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  17. # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  18. # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  20. # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  21. # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  22. # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  23. # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  24. # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. #
  26. echo "SlackCheck v3.91"
  27. echo
  28. cd $(dirname $0)
  29. INC_CONFIG="0"
  30. . ./config.sh
  31. if [ "$INC_CONFIG" = "0" ]
  32. then
  33. echo "*** Error including ./config.sh"
  34. exit
  35. fi
  36. # Show usage information
  37. usage() {
  38. echo "Usage: $(basename $0) [options]"
  39. echo
  40. echo " OPTIONS:"
  41. echo
  42. echo " --local Operate on local machine"
  43. echo " --host h1 h2 h3 Upgrade this host(s)"
  44. echo " --file filename Read list of hosts from this file"
  45. echo
  46. echo " --sync Get latest list of packages from the WWW/FTP/Local file"
  47. echo
  48. echo " --collect Build package lists for hosts that'll be upgraded"
  49. echo
  50. echo " --gen Generate upgrade scripts"
  51. echo
  52. echo " --upgrade Upgrade hosts using generated scripts"
  53. echo " --dist Only copy upgrade scripts to hosts, do not updgrade"
  54. echo
  55. echo " --skip-ignore Skip checks for ignored packages"
  56. echo
  57. echo " --verbose Show more info when update scripts are generated"
  58. echo
  59. echo " HOW TO UPGRADE CURRENT HOST"
  60. echo " Run: $(basename $0) --local --sync --collect --gen --upgrade"
  61. echo
  62. echo " HOW TO UPGRADE MULTIPLE HOSTS:"
  63. echo " Edit: \"update_hosts\" file to add your slackware machines"
  64. echo " Run: $(basename $0) --sync --collect --gen"
  65. echo " Edit: ${DIR_UPD}/${FILE_UPDATES}*"
  66. echo " Run: $(basename $0) --upgrade (for automatic upgrade)"
  67. echo " or"
  68. echo " Run: $(basename $0) --dist (for manual upgrade after that)"
  69. echo
  70. echo " HOW TO UPGRADE SINGLE HOST:"
  71. echo " Run: $(basename $0) --host blah.example.org --sync --collect --gen --upgrade"
  72. echo
  73. exit 1
  74. }
  75. # Get newest package list
  76. sync_master_list() {
  77. echo "===> Getting newest package list..."
  78. WD=$(pwd)
  79. mkdir $DIR_PKG 2>/dev/null
  80. cd $DIR_PKG
  81. TMPDIR=".Tmp"
  82. rm -rf $TMPDIR 2>/dev/null
  83. mkdir $TMPDIR && cd $TMPDIR
  84. ${DL_PRG} ${DL_PRG_OPTS} ${DL_HOST}/CHECKSUMS.md5
  85. # Parse file
  86. grep -E "\.t[a-z]z$" CHECKSUMS.md5 | grep patches | cut -d" " -f3 | sed -e 's|\./||' > ../${FILE_NEWEST}
  87. grep -E "\.t[a-z]z$" CHECKSUMS.md5 | grep slackware | cut -d" " -f3 | sed -e 's|\./||' >> ../${FILE_NEWEST}
  88. if [ $(LANG=C ls -l ../${FILE_NEWEST} | tr -s ' ' | cut -d" " -f 5) = "0" ]
  89. then
  90. grep -E "\.t[a-z]z$" CHECKSUMS.md5 | cut -d" " -f3 | sed -e 's|\./||' >> ../${FILE_NEWEST}
  91. fi
  92. rev < ../${FILE_NEWEST} | cut -d- -f4- | rev | sed -e 's|.*/||;s|[^A-Za-z0-9_]|_|g' > ../.${FILE_NEWEST}.base
  93. paste ../.${FILE_NEWEST}.base ../${FILE_NEWEST} | sed -e 's|\.\(t[a-z]z\)| \1|' > ../.${FILE_NEWEST}.paste
  94. cd ..
  95. rm -rf $TMPDIR 2>/dev/null
  96. cd $WD
  97. }
  98. # Generate list of packages for every host
  99. collect_package_lists() {
  100. [ -d $DIR_PKG ] || mkdir -p $DIR_PKG
  101. echo "===> Collecting package lists..."
  102. for HOST in $SLACK_HOSTS
  103. do
  104. echo " ---> $HOST"
  105. # Localhost
  106. if [ "$HOST" == "$(hostname)" -o \
  107. "$HOST" == "$(hostname -f)" -o \
  108. "$HOST" == "localhost" ]
  109. then
  110. ls /var/log/packages > ${DIR_PKG}/$HOST
  111. # Remote host
  112. else
  113. ${RSH_LISTS} $HOST "ls /var/log/packages" > ${DIR_PKG}/${HOST}.tmp
  114. mv ${DIR_PKG}/${HOST}.tmp ${DIR_PKG}/${HOST} 2>/dev/null
  115. fi
  116. done
  117. }
  118. # Generate upgrade scripts
  119. generate_upgrade_scripts() {
  120. [ -d ${DIR_UPD} ] || mkdir ${DIR_UPD}
  121. echo "===> Generating upgrade scripts..."
  122. if [ ! -f ${DIR_PKG}/.${FILE_NEWEST}.paste ]
  123. then
  124. sync_master_list
  125. fi
  126. # Init \$basepkg variables
  127. while read basepkg hostpkg ext
  128. do
  129. eval $basepkg=$hostpkg
  130. eval E_$basepkg=$hostpkg.$ext
  131. done < ${DIR_PKG}/.${FILE_NEWEST}.paste
  132. for HOST in $SLACK_HOSTS
  133. do
  134. UPDATED=0
  135. SKIPPED=0
  136. CURRENT=0
  137. UNKNOWN=0
  138. TOTAL=0
  139. CHECKED=0
  140. FILL=$((28 - $(echo $HOST | wc -c)))
  141. if [ $FILL -le 0 ]
  142. then
  143. FILL=4
  144. fi
  145. FL="$(yes "_" | head -$FILL | xargs echo | sed -e 's| ||g;s|_| |g')"
  146. # Check if package list exist
  147. if [ -f ${DIR_PKG}/${HOST} ]
  148. then
  149. if [ "$VERBOSE" != "1" ]; then
  150. echo -n " => $HOST "
  151. else
  152. echo " => $HOST "
  153. fi
  154. # Cleanup old files
  155. rm ${DIR_UPD}/${FILE_UNKPACKS}${HOST} >/dev/null 2>&1
  156. rm ${DIR_UPD}/${FILE_UPDATES}${HOST} >/dev/null 2>&1
  157. rm ${DIR_UPD}/${FILE_UPDATES}${HOST}.* >/dev/null 2>&1
  158. # Generate file with package basenames
  159. rev < ${DIR_PKG}/$HOST | cut -d- -f4- | rev | sed -e 's|.*/||;s|[^A-Za-z0-9_]|_|g' > ${DIR_UPD}/${FILE_UPDATES}${HOST}.base
  160. paste ${DIR_PKG}/$HOST ${DIR_UPD}/${FILE_UPDATES}${HOST}.base > ${DIR_UPD}/${FILE_UPDATES}${HOST}.paste
  161. TOTAL=$(wc -l < ${DIR_UPD}/${FILE_UPDATES}${HOST}.paste)
  162. while read hostpkg basepkg
  163. do
  164. CHECKED=$(($CHECKED + 1))
  165. # Get package from the distro packages
  166. # This contains FULL directory + package name
  167. eval distro_package="\$$basepkg"
  168. eval distro_package_ext="\$E_$basepkg"
  169. if [ "$distro_package" != "" -a "$distro_package" != "\$" ]
  170. then # Host package exist in the distro packages
  171. distropkg="${distro_package##*/}" # Faster basename using build-in BASH tricks
  172. if [ "$distropkg" != "$hostpkg" ]
  173. then
  174. UPDATED=$(($UPDATED + 1))
  175. echo "\
  176. UPDATE=\"\$UPDATE ${distro_package_ext}\" # EXISTING: ${hostpkg}\
  177. " >> ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs
  178. if [ "$VERBOSE" == "1" ]; then
  179. echo " UPD: $hostpkg -> $distropkg ($distro_package_ext)"
  180. fi
  181. else
  182. CURRENT=$(($CURRENT + 1))
  183. if [ "$VERBOSE" == "1" ]; then
  184. echo " CURR: $hostpkg -> $distropkg ($distro_package_ext)"
  185. fi
  186. fi
  187. else # Add to unknown packages
  188. UNKNOWN=$(($UNKNOWN+1))
  189. if [ "$VERBOSE" == "1" ]; then
  190. echo " UNKN: $hostpkg"
  191. fi
  192. echo "$hostpkg" >> ${DIR_UPD}/${FILE_UNKPACKS}${HOST}
  193. fi
  194. if [ "$VERBOSE" != "1" ]; then
  195. echo -n " => ${HOST}${FL} Check $CHECKED of $TOTAL"
  196. fi
  197. done < ${DIR_UPD}/${FILE_UPDATES}${HOST}.paste
  198. # Skip ignored packages
  199. if [ -s ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs -a \
  200. -f "do_not_update" -a \
  201. "$SKIP_IGNORE" != "1" ]
  202. then
  203. ignore_packs=$(grep ^${HOST}: do_not_update | sed -e 's|^.*:|/|g;s| |\||g' | xargs echo | sed -e 's| |\||g')
  204. if [ "$ignore_packs" != "" ]
  205. then
  206. grep -v -E "${ignore_packs}" ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs > ${DIR_UPD}/.${HOST}.newpkgs.tmp
  207. if [ -f ${DIR_UPD}/.${HOST}.newpkgs.tmp ]
  208. then
  209. skip1=$(wc -l < ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs)
  210. skip2=$(wc -l < ${DIR_UPD}/.${HOST}.newpkgs.tmp)
  211. SKIPPED=$(($skip1 - $skip2))
  212. UPDATED=$(($UPDATED - $SKIPPED))
  213. fi
  214. mv ${DIR_UPD}/.${HOST}.newpkgs.tmp ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs
  215. if [ ! -s ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs ]
  216. then
  217. rm ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs
  218. fi
  219. fi
  220. fi
  221. status="${UPDATED} for update "
  222. if [ "$UPDATED" = "0" ]; then
  223. status="Up to date "
  224. fi
  225. if [ "$CURRENT" = "0" ]; then
  226. status="No host info "
  227. fi
  228. echo -n " => ${HOST}${FL} ${status}/cr ${CURRENT} un ${UNKNOWN} sk ${SKIPPED} new ${UPDATED}/"
  229. echo
  230. # Add intereter
  231. if [ -s ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs ]
  232. then
  233. sort ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs > ${DIR_UPD}/.${HOST}.newpkgs.tmp
  234. mv ${DIR_UPD}/.${HOST}.newpkgs.tmp ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs
  235. (echo '#!/bin/sh'
  236. echo
  237. echo "DL_HOST=\"${DL_HOST}\""
  238. echo "DL_PRG=\"${DL_PRG}\""
  239. echo "DL_PRG_OPTS=\"${DL_PRG_OPTS}\""
  240. echo
  241. echo "MD5_CHECK=\"${MD5_CHECK}\""
  242. echo "SIG_CHECK=\"${SIG_CHECK}\""
  243. echo
  244. echo "REMOTE_DIR=\"${REMOTE_DIR}\""
  245. echo "REMOTE_DIR_DEL=\"${REMOTE_DIR_DEL}\""
  246. echo
  247. echo "SMART_UPGRADE=\"${SMART_UPGRADE}\""
  248. echo
  249. echo "GENERATED=\"1\""
  250. echo
  251. echo "# If you don't want package to be updated just delete the line."
  252. echo
  253. # pkgtools and tar must be first
  254. # glibc and elflibs next
  255. cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep a/pkgtools
  256. cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep a/tar
  257. cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep a/glibc
  258. cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep a/elflibs
  259. cat ${DIR_UPD}/${FILE_UPDATES}${HOST}.newpkgs | grep -v -E "a/(pkgtools|tar|glibc|elflibs)"
  260. echo "PKG_KMOD=\"`grep kmod- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  261. echo "PKG_GMP=\"`grep gmp- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  262. echo "PKG_LIBCAP=\"`grep libcap- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  263. echo "PKG_XZ=\"`grep xz- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  264. echo "PKG_SED=\"`grep sed- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  265. echo "PKG_COREUTILS=\"`grep coreutils- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  266. echo "PKG_UTEMPTER=\"`grep utempter- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  267. echo "PKG_MODULEINITTOOLS=\"`grep module-init-tools- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  268. echo "PKG_AAAELFLIBS=\"`grep aaa_elflibs- ${DIR_PKG}/${FILE_NEWEST} 2>/dev/null`\"";
  269. echo
  270. grep -v ^# update_script.sh
  271. ) > ${DIR_UPD}/${FILE_UPDATES}${HOST}
  272. fi
  273. # Cleanup
  274. rm ${DIR_UPD}/${FILE_UPDATES}${HOST}.* 2>/dev/null
  275. fi
  276. done
  277. echo
  278. }
  279. # Upgrade remote hosts
  280. upgrade_machines() {
  281. NOW=$(date +%Y-%m-%d)
  282. echo "===> Upgrating hosts..."
  283. for HOST in $SLACK_HOSTS
  284. do
  285. hname=$(hostname 2>/dev/null)
  286. hname_full=$(hostname -f 2>/dev/null)
  287. if [ -f ${DIR_UPD}/${FILE_UPDATES}${HOST} ]
  288. then
  289. # Localhost
  290. if [ "$HOST" == "$hname" -o \
  291. "$HOST" == "$hname_full" -o \
  292. "$HOST" == "localhost" ]
  293. then
  294. echo " ---> $HOST (Local machine)"
  295. # Use su if we're running not as root
  296. if [ "$(id -u)" != "0" ]; then
  297. echo " Enter root password"
  298. (su -c "/bin/sh ${DIR_UPD}/${FILE_UPDATES}${HOST}") 2>&1 | tee ${DIR_UPD}/log_${FILE_UPDATES}${HOST}
  299. else
  300. (/bin/sh ${DIR_UPD}/${FILE_UPDATES}${HOST}) 2>&1 | tee ${DIR_UPD}/log_${FILE_UPDATES}${HOST}
  301. fi
  302. # Remote host
  303. else
  304. echo " ---> $HOST"
  305. (cat ${DIR_UPD}/${FILE_UPDATES}${HOST} | \
  306. ${RSH_UPGRADE} ${HOST} \
  307. "cat - > ${FILE_UPDATES}${HOST}_${NOW}; \
  308. /bin/sh ${FILE_UPDATES}${HOST}_${NOW};") 2>&1 | tee ${DIR_UPD}/log_${FILE_UPDATES}${HOST}
  309. fi
  310. fi
  311. done
  312. }
  313. # Send upgrade scripts to hosts
  314. distribute_up_scripts() {
  315. NOW=$(date +%Y-%m-%d)
  316. echo "===> Copying upgrade scripts..."
  317. for HOST in $SLACK_HOSTS
  318. do
  319. if [ -f ${DIR_UPD}/${FILE_UPDATES}${HOST} ]
  320. then
  321. # Localhost
  322. if [ "$HOST" == "$(hostname)" -o \
  323. "$HOST" == "$(hostname -f)" -o \
  324. "$HOST" == "localhost" ]
  325. then
  326. echo " ---> $HOST (Local machine - no need to copy upgrade script)"
  327. # Remote host
  328. else
  329. echo " ---> $HOST"
  330. cat ${DIR_UPD}/${FILE_UPDATES}${HOST} | \
  331. ${RSH_UPGRADE} ${HOST} \
  332. "cat - > ${FILE_UPDATES}${HOST}_${NOW}"
  333. fi
  334. fi
  335. done
  336. }
  337. if [ "$1" = "" ]; then
  338. usage
  339. fi
  340. # Process command line arguments
  341. while [ "$1" != "" ]; do
  342. param=$1
  343. shift
  344. case "$param" in
  345. --local)
  346. SLACK_HOSTS="localhost"
  347. ;;
  348. --host)
  349. if [ "$1" != "" ]; then
  350. SLACK_HOSTS=""
  351. fi
  352. while [ "$1" != "" ]; do
  353. param=$1
  354. case "$param" in
  355. --*)
  356. break
  357. ;;
  358. *)
  359. SLACK_HOSTS="$SLACK_HOSTS $param"
  360. ;;
  361. esac
  362. shift
  363. done
  364. ;;
  365. --file)
  366. HOSTS_FILE="$1"
  367. if [ "$HOSTS_FILE" = "" -o ! -f "$HOSTS_FILE" ]; then
  368. echo "*** --file parameter is missing or file not found."
  369. echo
  370. usage
  371. exit 1
  372. fi
  373. SLACK_HOSTS=`grep -v ^# $HOSTS_FILE`
  374. shift
  375. ;;
  376. --sync)
  377. DO_SYNC="1"
  378. ;;
  379. --collect)
  380. DO_COLLECT="1"
  381. ;;
  382. --gen)
  383. DO_GEN="1"
  384. ;;
  385. --dist)
  386. DO_DIST="1"
  387. ;;
  388. --skip-ignore)
  389. SKIP_IGNORE="1"
  390. ;;
  391. --upgrade)
  392. DO_UPGRADE="1"
  393. ;;
  394. --verbose)
  395. VERBOSE="1"
  396. ;;
  397. *)
  398. usage
  399. ;;
  400. esac
  401. done
  402. if [ "$SLACK_HOSTS" = "" ]; then
  403. echo "*** No hosts. Check --host parameter, --file parameter ot 'upgrade_hosts' file."
  404. echo
  405. exit 1
  406. fi
  407. echo -n "---> Hosts: "
  408. echo $SLACK_HOSTS
  409. echo
  410. [ "$DO_SYNC" = "1" ] && sync_master_list
  411. [ "$DO_COLLECT" = "1" ] && collect_package_lists
  412. [ "$DO_GEN" = "1" ] && generate_upgrade_scripts
  413. [ "$DO_DIST" = "1" ] && distribute_up_scripts
  414. [ "$DO_UPGRADE" = "1" ] && upgrade_machines