Пока что 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
Последняя проблема легко решается добавлением дополнительного параметра ))