Массовый апдейт дрюпала

Пока что 4 сайта на drupal multi-site конфигурации, а апдейт уже превращается в ужасно нудную процедуру. В соответствии с мануалом перед апдейтом надо поставить все сайты в offline режим, а после - запустить для каждого update.php и режим поправить обратно.

Всё ничего, да вот пароли администратора на некоторых сайтах я забыл, а в перспективе возможен вариант и "не знал". Неужели придётся ставить временный пароль через БД, шарахаться по интерфейсу, менять что-то ... И это для всех сайтов! Ужасная потеря времени, да и однообразная работа не прельщает.

Итак задача для написания скрипта:
- автоматизировать "включение/выключение" всех сайтов в установке
- разрешать/запрещать анонимным пользователям запуск update.php
Скрипт требует 2 параметра: включить/выключить ( on/off ) и путь к файлу settings.php. Кстати из этого файла и выдираются явки и пароли доступа к БД.

switchUpdatable
#!/bin/bash

FILENAME="settings.php"

SWITCH="$1"
FILE="$2"

if [ $# -ne 2 ]; then
        echo "ERROR: Wrong number of parameters"
        exit 1
fi
if [ ! \( "$SWITCH" = "on" -o "$SWITCH" = "off" \) ]; then
        echo "ERROR: first parameter should be either 'on' or 'off' given '$SWITCH'"
        exit 1
fi
if [ `echo "$FILE" | grep -c "$FILENAME"` -ne 1 ]; then
        echo "ERROR: script is only ment for files named '$FILENAME' given '$FILE'"
        exit 1
fi
if [ ! -f "$FILE" ]; then
        echo "ERROR: file '$FILE' does not exist or not a file"
        exit 1
fi

UPDATE_FREE_ACCESS='FALSE'
WEBSITE_OFFLINE=0

if [ "$SWITCH" = "on" ]; then
        UPDATE_FREE_ACCESS='TRUE'
        WEBSITE_OFFLINE=1
fi

echo -n -e  "$FILE:\n\tSetting \$update_free_access"

#in given file replace "$update_free_access = SOMETHING" by what we need
COMMAND="sed -i -e 's/update_free_access\s*=\s*[A-Za-z]*/update_free_access = $UPDATE_FREE_ACCESS/gi' $FILE"
eval "$COMMAND"

if [ "$?" -eq 0 ]; then echo -n -e " = $UPDATE_FREE_ACCESS; ok"; else echo -n " ... failed"; exit 1; fi

#$db_url = 'mysqli://username:password@localhost/databasename';
DBSTRING=`cat $FILE | grep '^\s*\$db_url'`              # Take line with database url
DBSTRING=`echo $DBSTRING | sed -e 's#^[^/]*//##'`       # Trim beginning of the line untill "//" is reached
DBSTRING=`echo $DBSTRING | sed -e s/\'.*$//`            #'`# Trim from "'" untill end of line

#username:password@localhost/databasename
#Extract variables
DB_USER=`echo $DBSTRING | sed -e 's/:.*$//'`
DB_PASS=`echo $DBSTRING | sed -e 's/^[^:]*://' | sed -e 's/@.*$//'`
DB_HOST=`echo $DBSTRING | sed -e 's/^[^@]*@//' | sed -e 's#/.*$##'`
DB_NAME=`echo $DBSTRING | sed -e 's#^[^/]*/##'`

#according to drupal code cache should be cleaned taking into consideration "expire" field and current time
TIME=`date +%s`

echo -n -e "\n\tTaking site ";
if [ "$WEBSITE_OFFLINE" -eq 0 ]; then echo -n "online"; else echo -n "offline"; fi
echo -n " ... "

#set site offline and clear cache
mysql --user "$DB_USER" --password=$DB_PASS "$DB_NAME" << EOF
UPDATE variable SET value='s:1:"$WEBSITE_OFFLINE";' WHERE name = 'site_offline';
DELETE FROM cache WHERE CID = 'variables';
DELETE FROM cache_page WHERE expire != '0' AND expire < '$TIME';
DELETE FROM cache_block WHERE expire != '0' AND expire < '$TIME';
EOF

if [ "$?" -eq 0 ]; then echo "ok"; else echo "failed"; fi

Скрипт не требует настройки. Использование:
$ ./switchUpdatable [on|off] path/to/settings.php

Ну, и для полного счастья неплохо было-бы обработать все сайты разом:
switchAllUpdatable

#!/bin/bash

DRUPAL_PATH="/path/to/drupal"

SED_SCRIPT="$DRUPAL_PATH/switchUpdatable"
FILENAME='settings.php'

REPLACE_INFO='off'
if [ $# -gt 0 -a "$1" = "on" ]; then REPLACE_INFO='on'; fi

echo "Turning updatability $REPLACE_INFO"

find $DRUPAL_PATH/htdocs/sites/ -type f -name $FILENAME -exec  $SED_SCRIPT $REPLACE_INFO {} \;

Скрипт сначала надо настроить, указав папку с дрюпалом и папку с первым скриптом. При использовании требуется один необязательный параметр. Ищет файлы settings.php и применяет к ним первый скрипт с параметром "on", если таковой указан у него самого, иначе "off".

$ ./switchAllUpdatable [on]

Данная конструкция призвана значительно сэкономить время, хоть, по некоторым мнениям и не лишена недостатков:
- полностью очищает кэш ( что не нравилось товарищу у которого был подсмотрен вариант исполнения )
- увидев на вашем сайте сообщение о техобслуживании, злоумышленник может угадать, что всем открыт доступ к update.php

Последняя проблема легко решается добавлением дополнительного параметра ))