#!/bin/bash # # Drupal management script. # BASE=${BASE:="/var/www/data"} SITES=${SITES:="$BASE/drupal"} #SERIES="6 7 8 9" #LATEST_SERIES="9" SERIES="6 7 8" LATEST_SERIES="8" # Ensure we have a proper path, useful when called through cron export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' # Read a parameter from user function drupal_user_input { local input param="$1" default="$2" shift 2 if echo $param | grep -q 'passwd'; then read -s -rep "$* (defaults to $default): " input else read -rep "$* (defaults to $default): " input fi if [ -z "$input" ]; then export $param="$default" else export $param="$input" fi } # Get drupal major version function drupal_get_major { echo $1 | sed -e 's/\(^.\).*/\1/' } # Check for existing installations function drupal_check_existing { if [ -e "$BASE/drupal-$1" ]; then if [ "$SILENT" != "yes" ]; then echo "Folder $BASE/drupal-$1 already exists, skipping" fi exit fi } # Check for non existing installations function drupal_check_not_existing { if [ ! -e "$BASE/drupal-$1" ]; then if [ "$SILENT" != "yes" ]; then echo "Folder $BASE/drupal-$1 does not exist, skipping" fi exit 1 fi } # Iterate through all drupal instances function drupal_iterate { local command="$1" if [ -z "$command" ]; then return fi if [ "$command" != "cron" ] && [ "$SILENT" != "yes" ]; then echo "Issuing $command in all installed instances..." fi for version in $SERIES; do # Setup base folder base="$BASE/drupal-$version" if [ ! -d "$base/sites" ]; then continue fi # Only cron action is available for drupal 6 if [ "$version" == "6" ] && [ "$command" != "cron" ]; then continue fi # Setup site folders with .onion sites in the end of the list # and ignoring site names without dots cd $base/sites drupals="`ls -1 -I default -I all -I example.sites.php -I '*.onion' | grep "\." | xargs`" drupals="$drupals `ls -1 | grep '.onion$' | xargs`" # Issue updates for drupal in $drupals; do if [ -e "$drupal/settings.php" ]; then hash="`sha1sum $drupal/settings.php | cut -d ' ' -f 1`" # Process sites just once, avoiding symlinks if echo $settings_hash | grep -q -v "$command:$hash"; then settings_hash="$settings_hash-$command:$hash" if [ "$command" != "cron" ] && [ "$SILENT" != "yes" ]; then echo "Processing $drupal..." fi if [ "$command" == "update" ] || [ "$command" == "cron-update" ]; then shift drupal_update $command $drupal $* else drush -l $drupal $* fi fi fi done # Fix permissions #if [ "`whoami`" == "root" ]; then # chown -R drupal.drupal $base/modules # chown -R drupal.drupal $base/themes # if [ -e "$base/sites/all/modules" ]; then # chown -R drupal.drupal $base/sites/all/modules # fi # if [ -e "$base/sites/all/themes" ]; then # chown -R drupal.drupal $base/sites/all/themes # fi #fi done } # Update a drupal instance function drupal_update { local method="$1" local instance="$2" local confirm local line shift 2 if [ "$method" == "cron-update" ]; then confirm="-y" fi # See https://drupal.org/node/823146#comment-3319070 drush -l $instance up -u 1 --pipe | \ grep -v -E 'Unknown|Up-to-date|Atualizado|Desconhecido|^Array$|^\($|^\)$|OK' | while read line ; do # Avoid automated core updates code="`echo $line | cut -d " " -f1`" if [ "$code" == "drupal" ]; then echo "Core update available: $line" else echo "Updating $code on instance $instance..." drush -l $instance up -u 1 $confirm $* $code fi done } # Get the current installed version of a given series function drupal_current { local series="$1" if [ -z "$series" ]; then series="$LATEST_SERIES" fi if [ -e "$BASE/drupal-${series}" ]; then readlink $BASE/drupal-${series} | sed -e 's/^drupal-//' else echo 0 fi } # Get the latest version of a given series # Operate only on stable releases, filtering out dev, alpha, beta and rc releases # https://drupal.stackexchange.com/questions/23700/how-to-find-download-latest-drupal-version-via-bash#23704 function drupal_latest { local series="$1" if [ -z "$series" ]; then series="$LATEST_SERIES" fi if [ "$series" == "9" ]; then latest="`wget -O- -q https://www.drupal.org/node/3060/release/feed | grep "" | grep "releases/9." | cut -d "/" -f 7 | cut -d '<' -f 1 | sort -r | head -1`" echo $latest else latest="`wget -O- -q https://updates.drupal.org/release-history/drupal/${series}.x | grep -oPm1 "(?<=)[^<]+" | grep -v -- '-dev' | grep -v -- '-alpha' | grep -v -- '-beta' | grep -v -- '-rc' | head -1`" latest="`basename $latest`" echo $latest | sed -e 's/^drupal-//' -e 's/.tar.gz$//' fi } # Deploy a fresh drupal tree function drupal_download { if [ -z "$1" ]; then echo "Usage: `basename $0` download [--upgrade]" exit 1 else new="$1" fi # Check for latest releases if no specific version was given if [ "$new" == "9" ]; then drupal_series="9" new="`drupal_latest 9`" elif [ "$new" == "8" ]; then drupal_series="8" new="`drupal_latest 8`" elif [ "$new" == "7" ]; then drupal_series="7" new="`drupal_latest 7`" elif [ "$new" == "6" ]; then drupal_series="6" new="`drupal_latest 6`" else drupal_series="`drupal_get_major $new`" fi cd $BASE drupal_check_existing $new # Deploy a fresh drupal tree wget http://ftp.drupal.org/files/projects/drupal-$new.tar.gz tar zxvf drupal-$new.tar.gz && rm drupal-$new.tar.gz if [ "`whoami`" == "root" ]; then chown -R drupal.drupal drupal-$new/ fi # Upgrade mode, erase sites folder as the previous should be copied. if [ "$2" == "--upgrade" ]; then cd drupal-$new && rm -rf sites fi # Make symlink if needed. if [ ! -e "$BASE/drupal-$drupal_series/CHANGELOG.txt" ]; then # Deal with a possibly empty drupal folder rmdir $BASE/drupal-$drupal_series &> /dev/null ( cd $BASE && ln -s drupal-$new drupal-$drupal_series ) fi } # Upgrade a drupal instance using upstream source function drupal_upgrade { if [ "$#" != "1" ] && [ "$#" != "2" ]; then echo "Usage: `basename $0` upgrade [new_version]" exit 1 fi # Get versions old="$1" new="$2" # Fix versions if just a series is given if [ "$old" == "9" ] && [ -z "$new" ]; then old="`drupal_current 9`" new="`drupal_latest 9`" drupal_series="9" elif [ "$old" == "8" ] && [ -z "$new" ]; then old="`drupal_current 8`" new="`drupal_latest 8`" drupal_series="8" elif [ "$old" == "7" ] && [ -z "$new" ]; then old="`drupal_current 7`" new="`drupal_latest 7`" drupal_series="7" elif [ "$old" == "6" ] && [ -z "$new" ]; then old="`drupal_current 6`" new="`drupal_latest 6`" drupal_series="6" else old_major="`drupal_get_major $old`" new_major="`drupal_get_major $new`" drupal_series="$new_major" fi if [ "$old_major" != "$new_major" ]; then echo "Major versions doesn't match" exit 1 fi drupal_check_existing $new drupal_check_not_existing $old cd $BASE # Deploy a fresh drupal tree drupal_download $new --upgrade # Ensure we're in the new drupal folder cd $BASE/drupal-$new # Copy files for file in sites; do if [ ! -h "../drupal-$old/$file" ]; then cp -alf ../drupal-$old/$file . &> /dev/null else # Symlink handling ln -sf $file `readlink ../drupal-$old/$file` fi done extra_folders="" # Extra folder for extra_folder in $extra_folders; do if [ -d ../drupal-$old/$extra_folder ]; then cp -Rp ../drupal-$old/$extra_folder . fi done # Copy installation profiles rsync -av --exclude=default ../drupal-$old/profiles/ profiles/ # Copy installation themes and modules for Drupal 8 or newer if [ "$new_major" != "5" ] && [ "$new_major" != "6" ] && [ "$new_major" != "7" ]; then rsync -av ../drupal-$old/modules/ modules/ rsync -av ../drupal-$old/themes/ themes/ rsync -av ../drupal-$old/libraries/ libraries/ fi # Change symlink to point to the new location cd $BASE ; rm -rf drupal-$drupal_series && ln -sf drupal-$new drupal-$drupal_series # Done echo "Audit: `du -hs drupal-$old`" echo "Audit: `du -hs drupal-$new`" echo "Check procedure and remove drupal-$old once you make sure that everything is fine." } # Run a drupal makefile function drupal_make { if [ -z "$1" ]; then echo "Usage: `basename $0` make " exit 1 fi series="$1" base="$BASE/drupal-$series" makefile="/usr/local/share/drupal/drupal$series.make" makefile_themes="/usr/local/share/drupal/themes$series.make" if [ -e "$makefile" ]; then if [ ! -e "$base" ]; then echo "Please download drupal code at $base first" exit 1 fi drush dl drush_make ( cd $base && drush make -y --no-core $makefile ) ( cd $base && drush make -y --no-core $makefile_themes ) else echo "Makefile not found: $makefile" exit 1 fi } # Ensure base is absolute if [ ! -d "$BASE" ]; then echo "Folder $BASE does not exist" exit 1 else BASE="`cd $BASE &> /dev/null && pwd`" fi # Main procedure if [ -z "$1" ]; then echo "Usage: `basename $0` [arguments]" exit 1 elif [ "$1" == "cron" ]; then drupal_iterate cron elif [ "$1" == "cron-update" ]; then SILENT="yes" drupal_iterate pm-refresh &> /dev/null drupal_iterate cron-update elif [ "$1" == "download" ] || [ "$1" == "dl" ]; then shift drupal_download $* elif [ "$1" == "update" ]; then shift drupal_iterate pm-refresh drupal_iterate update $* # Update alone might not trigger updatedb in a farm for all instances. drupal_iterate updatedb $* drupal_iterate cc all $* elif [ "$1" == "updatedb" ]; then shift drupal_iterate updatedb $* elif [ "$1" == "upgrade" ]; then shift drupal_upgrade $* elif [ "$1" == "current" ]; then shift drupal_current $* elif [ "$1" == "latest" ]; then shift drupal_latest $* elif [ "$1" == "run" ]; then shift drupal_iterate $* elif [ "$1" == "make" ]; then shift drupal_make $* else echo "No action $1" exit 1 fi