Ansible roles by Evolix
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.

240 lines
8.3 KiB

  1. #!/bin/bash
  2. # Exit codes :
  3. # - 30 : $skip_releases or $skip_packages is set to "all"
  4. # - 40 : current release is in $skip_releases list
  5. # - 50 : all upgradable packages are in the $skip_packages list
  6. # - 60 : current release is not in the $r_releases list
  7. # - 70 : at least an upgradable package is not in the $r_packages list
  8. set -e
  9. configFile="/etc/evolinux/listupgrade.cnf"
  10. packages=$(mktemp --tmpdir=/tmp evoupdate.XXX)
  11. packagesHold=$(mktemp --tmpdir=/tmp evoupdate.XXX)
  12. servicesToRestart=$(mktemp --tmpdir=/tmp evoupdate.XXX)
  13. template=$(mktemp --tmpdir=/tmp evoupdate.XXX)
  14. clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2)
  15. mailto=$clientmail
  16. date="Ce jeudi entre 18h00 et 23h00."
  17. hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2)
  18. hostname=${hostname%%.evolix.net}
  19. # If hostname is composed with -, remove the first part.
  20. if [[ $hostname =~ "-" ]]; then
  21. hostname=$(echo $hostname | cut -d'-' -f2-)
  22. fi
  23. # Edit $configFile to override some variables.
  24. [ -r $configFile ] && . $configFile
  25. # Remove temporary files on exit.
  26. trap "rm $packages $packagesHold $servicesToRestart $template" EXIT
  27. # Parse line in retrieved upgrade file and ensure there is no malicious values.
  28. get_value() {
  29. file="$1"
  30. variable="$2"
  31. value="$(grep "^$2:" $1 |head -n 1 |cut -d ':' -f 2 |sed 's/^ //')"
  32. if echo "$value" |grep -q -E '^[-.: [:alnum:]]*$'; then
  33. echo $value
  34. else
  35. printf >&2 "Error parsing value \"$value\" for variable $variables.\n"
  36. fi
  37. }
  38. # Fetch which packages/releases will be upgraded.
  39. fetch_upgrade_info() {
  40. upgradeInfo=$(mktemp --tmpdir=/tmp evoupdate.XXX)
  41. wget -q -O $upgradeInfo https://upgrades.evolix.org/upgrade
  42. r_releases="$(get_value $upgradeInfo "releases")"
  43. r_skip_releases="$(get_value $upgradeInfo "skip_releases")"
  44. r_packages="$(get_value $upgradeInfo "packages")"
  45. r_skip_packages="$(get_value $upgradeInfo "skip_packages")"
  46. rm $upgradeInfo
  47. }
  48. # Check if element $element is in (space separated) list $list.
  49. is_in() {
  50. list="$1"
  51. element="$2"
  52. for i in $list; do
  53. if [ "$element" = "$i" ]; then
  54. return 0
  55. fi
  56. done
  57. return 1
  58. }
  59. if [[ "$1" != "--cron" ]]; then
  60. echo "À quel date/heure allez vous planifier l'envoi ?"
  61. echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00"
  62. echo -n ">"
  63. read date
  64. echo "À qui envoyer le mail ?"
  65. echo -n ">"
  66. read mailto
  67. fi
  68. # Update APT cache and get packages to upgrade and packages on hold.
  69. aptUpdateOutput=$(apt update 2>&1 | (egrep -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true ))
  70. if (echo "$aptUpdateOutput" | egrep "^Err(:[0-9]+)? http"); then
  71. echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me"
  72. exit 100
  73. fi
  74. apt-mark showhold > $packagesHold
  75. apt list --upgradable 2>&1 | grep -v -f $packagesHold | egrep -v '^(Listing|WARNING|$)' > $packages
  76. packagesParsable=$(cut -f 1 -d / <$packages |tr '\n' ' ')
  77. # No updates? Exit!
  78. test ! -s $packages && exit 0
  79. test ! -s $packagesHold && echo 'Aucun' > $packagesHold
  80. fetch_upgrade_info
  81. local_release=$(cut -f 1 -d . </etc/debian_version)
  82. # Exit if skip_releases or skip_packages in upgrade info file are set to all.
  83. ([ "$r_skip_releases" = "all" ] || [ "$r_skip_packages" = "all" ]) && exit 30
  84. # Exit if the server's release is in skip_releases.
  85. [ -n "$r_skip_releases" ] && is_in "$r_skip_releases" "$local_release" && exit 40
  86. # Exit if all packages to upgrade are listed in skip_packages:
  87. # we remove each package to skip from the $packageToUpgrade list. At the end,
  88. # if there is no additional packages to upgrade, we can exit.
  89. if [ -n "$r_skip_packages" ]; then
  90. packageToUpgrade="$packagesParsable"
  91. for pkg in $r_skip_packages; do
  92. packageToUpgrade="${packageToUpgrade/$pkg}"
  93. done
  94. packageToUpgrade=$(echo $packageToUpgrade |sed 's/ \+//g')
  95. if [ -z "$packageToUpgrade" ]; then
  96. exit 50
  97. fi
  98. fi
  99. # Exit if the server's release is not in releases.
  100. if [ -n "$r_releases" ] && [ "$r_releases" != "all" ]; then
  101. is_in "$r_releases" "$local_release" || exit 60
  102. fi
  103. # Exit if there is packages to upgrades that are not in packages list:
  104. # we exit at the first package encountered that is not in packages list.
  105. if [ -n "$r_packages" ] && [ "$r_packages" != "all" ]; then
  106. for pkg in $packagesParsable; do
  107. is_in "$r_packages" "$pkg" || exit 70
  108. done
  109. fi
  110. # Guess which services will be restarted.
  111. for pkg in $packagesParsable; do
  112. if echo "$pkg" |grep -qE "^(lib)?apache2"; then
  113. echo "Apache2" >>$servicesToRestart
  114. elif echo "$pkg" |grep -q "^nginx"; then
  115. echo "Nginx" >>$servicesToRestart
  116. elif echo "$pkg" |grep -q "^php5-fpm"; then
  117. echo "PHP FPM" >>$servicesToRestart
  118. elif echo "$pkg" |grep -q "^mysql-server"; then
  119. echo "MySQL" >>$servicesToRestart
  120. elif echo "$pkg" |grep -q "^mariadb-server"; then
  121. echo "MariaDB" >>$servicesToRestart
  122. elif echo "$pkg" |grep -qE "^postgresql-[[:digit:]]+\.[[:digit:]]+$"; then
  123. echo "PostgreSQL" >>$servicesToRestart
  124. elif echo "$pkg" |grep -qE "^tomcat[[:digit:]]+$"; then
  125. echo "Tomcat" >>$servicesToRestart
  126. elif [ "$pkg" = "redis-server" ]; then
  127. echo "Redis" >>$servicesToRestart
  128. elif [ "$pkg" = "mongodb-server" ]; then
  129. echo "MondoDB" >>$servicesToRestart
  130. elif echo "$pkg" |grep -qE "^courier-(pop|imap)"; then
  131. echo "Courier POP/IMAP" >>$servicesToRestart
  132. elif echo "$pkg" |grep -qE "^dovecot-(pop|imap)d"; then
  133. echo "Dovecot POP/IMAP" >>$servicesToRestart
  134. elif [ "$pkg" = "samba" ]; then
  135. echo "Samba" >>$servicesToRestart
  136. elif [ "$pkg" = "slapd" ]; then
  137. echo "OpenLDAP" >>$servicesToRestart
  138. elif [ "$pkg" = "bind9" ]; then
  139. echo "Bind9" >>$servicesToRestart
  140. elif [ "$pkg" = "postfix" ]; then
  141. echo "Postfix" >>$servicesToRestart
  142. elif [ "$pkg" = "haproxy" ]; then
  143. echo "HAProxy" >>$servicesToRestart
  144. elif [ "$pkg" = "varnish" ]; then
  145. echo "Varnish" >>$servicesToRestart
  146. elif [ "$pkg" = "squid" ]; then
  147. echo "Squid" >>$servicesToRestart
  148. elif [ "$pkg" = "elasticsearch" ]; then
  149. echo "Elasticsearch" >>$servicesToRestart
  150. elif [ "$pkg" = "logstash" ]; then
  151. echo "Logstash" >>$servicesToRestart
  152. elif [ "$pkg" = "libc6" ]; then
  153. echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libc6)." >$servicesToRestart
  154. break
  155. elif [ "$pkg" = "libstdc++6" ]; then
  156. echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libstdc++6)." >$servicesToRestart
  157. break
  158. elif echo "$pkg" |grep -q "^libssl"; then
  159. echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libssl)." >$servicesToRestart
  160. break
  161. fi
  162. done
  163. test ! -s $servicesToRestart && echo "Aucun" >$servicesToRestart
  164. cat << EOT > $template
  165. Content-Type: text/plain; charset="utf-8"
  166. Reply-To: equipe@evolix.fr
  167. From: equipe@evolix.net
  168. To: ${clientmail}
  169. Subject: Prochain creneau pour mise a jour de votre serveur $hostname
  170. X-Debian-Release: $local_release
  171. X-Packages: $packagesParsable
  172. X-Date: $date
  173. Bonjour,
  174. Des mises-à-jour de sécurité ou mineures sont à réaliser sur votre serveur
  175. ${hostname}.
  176. Sauf indication contraire de votre part, le prochain créneau prévu pour
  177. intervenir manuellement pour réaliser ces mises-à-jour est :
  178. ${date}
  179. Si nous intervenons, un redémarrage des éventuels services concernés sera
  180. réalisé, entraînant a priori quelques secondes de coupure. Si nous ne sommes
  181. pas intervenus sur ce créneau, vous recevrez une nouvelle notification la
  182. semaine prochaine.
  183. Voici la listes de packages qui seront mis à jour :
  184. $(cat $packages)
  185. Liste des packages dont la mise-à-jour a été manuellement suspendue :
  186. $(cat $packagesHold)
  187. Liste des services qui seront redémarrés :
  188. $(cat $servicesToRestart)
  189. N'hésitez pas à nous faire toute remarque sur ce créneau d'intervention le plus
  190. tôt possible.
  191. Cordialement,
  192. --
  193. Équipe Evolix - Hébergement et Infogérance Open Source
  194. http://evolix.com | Twitter: @Evolix @EvolixNOC | http://blog.evolix.com
  195. EOT
  196. <$template /usr/sbin/sendmail $mailto
  197. # Now we try to fetch all the packages for the next update session
  198. downloadstatus=$(apt dist-upgrade --assume-yes --download-only -q2 2>&1)
  199. echo "$downloadstatus" | grep -q 'Download complete and in download only mode'
  200. if [ $? -ne 0 ]; then
  201. echo "$downloadstatus"
  202. fi;