Pull to refresh

Comments 58

И без cURL можно сделать возобновления закачки(HTTP_RANGE). А как вы поступите если обновление затрагивает только некоторые файлы(разбросанные по разным папкам)? 3-й вариант не подойдет(если я все правильно понял).
Первый вариант точно сработает.
Каковы направления применения предложенного решения?
Хочешь — вправо, хочешь — влево )
Образование на своем сайте security hole вселенского масштаба, по-моему. То, что предлагается, позволяет на по сути запустить совершенно произвольный код на сервере — немногим лучше eval(входящая-строчка).
Ботнет удобно обновлять…
Я для подобных целей храню актуальную версию всех скриптов (у меня не php, а микс из баша и дотнета, но сути дела не меняет) в deb-пакете и обновляю по крону централизованно из репозитария. При желании можно напихать в пакет скриптов для запуска при установке или удалении. Очень удобно и надёжно, а главное — без велосипедов.
Ещё, как простейший вариант, можно использовать git или svn. Удобно, быстро, и файлы не надо качать целиком, а только diff'ы.
Я давно о таком мечтаю, чтобы как только новая версия в репозитории, он ее оп и установил, думаю займусь завтра этим вопросом.
svn post commit вам в руки.

Обычный хук, который будет делать обновление на веб-морде по любому обновлению стейбл-бранча.
Откуда мой сервер узнает об обновлении бранча сервера разработчиков, которые обо мне в общем случае не знают?
Просто периодически делать update?
А причём здесь хуки тогда? Или имеется в виду сложная система деплоя, когда после апдейта на сервере (или вообще на третьей машине) из рабочей копии заливается в рабочий каталог и, возможно, запускаются миграции БД и т. п.?
Этот вариант, конечно, был бы самым удобным, но он будет работать далеко на всех хостингах: на своем сервере так и нужно делать, а вот на шаред-хостинге не получится.
на шаред-хостинге

И много вы видели шаред-хостингов с Curl, с ini_set, и.т.д?

Даже SSH может похвастаться не каждый, а на тех где есть, обновление делается намного проще. Точнее две строчки одна wget вторая (если ПО не состоит из одного файла) tar

(Можно делать это и из РНР, через всякие system/exec/passthru но это тоже извращение да и чаще всего на «шариках» они отключены)
Curl и ini_set есть на очень многих хостингах (говорю по опыту установки продукта Shop-Script, который за много лет поработал на очень многих хостингах и в рунете, и вне него).
А вам, по хорошему, надо было расписать всю вашу систему обновлений от начала и до конца в одной статье, без размазывания на 33 статьи на хабре :)
Если бы вы имели удовольствие поддерживать друпальные (или подобные) сайты, вы бы так не говорили :) Обновление core и в добавок кучи сторонних модулей вручную то еще удовольствие, сплошной wget→tar→diff→patch→db_update→«ищем почему все перестало работать»→«omfg, как это откатить обратно?».
У авторов вебасиста стоит именно такая задача → упростить обновление всей этой среды.
Я имею удовольствие заниматься подобными вещами уже дай бог памяти 6-7 лет, и согласен что «упростить обновление» очень и очень хорошее, и главное очень нужное занятие. (На многие CMS в этом плане без слёз в прямом смысле смотреть невозможно. И это только смотреть, обновлять вообще можно только со слезами.)

Однако делать это надо по уму, а не «как попало» вот дело то в чём.
Согласен, но я не уверен, что будет лучше если, разработчики ядра и модулей будут предоставлять bash скрипты сделанные «по уму» для обновлений и отката?
Вообще интересно, почему никто этим не занимается?
Этим обычно (в опенсорсе) принято выкладывать дистриб, а юзер дальше крутится сам. В разработках по контракту обычно в ТЗ пишут «хочу как там». Вот и вся математика.

Но те студии/фрилансеры/итд которые встречались с пунктом «обновление без проблем» в ТЗ чаще всего разрабатывают изначально так, чтоб это было возможно. (чтоб новые модули подключались без правки файлов из дистриба, чтоб конфиги и шаблоны при извлечении из дистриба не заменялись, и.т.д.) в итоге автообновление в 99% заключается в wget+tar и всё…
То что так принято, это понятно. Мой вопрос в том − почему так принято? Почему до сих пор эту проблему не решили даже в крупных проектах типа друпала?
Я в теме не разбирался, но должны же быть какие то причины видимо, вот какие вам известно?
Да просто никто не думал об этом в таком разрезе. (И не важно, крупные типа друпала, мелкие типа «Вася Пупкин Корпорейшин»)
Те кто думали давно уже что нибудь придумали. (кто-то лучше, кто-то хуже)
да ладно «не думал»!? все комьюнити на половину забиты вопросами связанными с проблемами с обновлениями.
Значит плевать они хотели на комьюнити, им самим удобно, и хоть ты тресни. Мне что ли вам объяснять как программисты нынче работают? (вы Хабр почитайте, и этот топик включительно)
[sarcasm]Как обычно — разработчикам это не нужно.Они не хостят сайты на шаред-хостингах, обновляются через шелл и т. п.[/sarcasm]
даже не на шареде обновить полугодовалый друпал может вылиться в приличный геморрой.
Для шаред-хостинга у меня была мысль брать список изменений из git'а и обновлять файлы через консольный интерфейс winscp.
для таких автообновлений есть замечательная чтука как различные оптимизаторы типа APC или eAccelerator.
Им можно либо запретить самостоятельно проверять mtime файлов, тогда можно делать со скритами все что угодно, хоть занулять — до некой команды оп код просто не будет обновлен. Либо просто поставить интервал проверки в некое разумное значение( минута ), вы же не меняете на самом деле файлы постоянно.
Ну или написать на node.js маленькое приложение для копирования файлов.
Массовые асинхронные операции над файлами очень любимы линуксами( если речь идет о полном копировании файлов это может быть раз в 20 быстрее rsync )
В случае обновления одного файла небольших размеров (в зависимости от настроек хостинга) максимум что необходимо это
<?php
$url = 'http://localhost/self.txt';
if ($updated = file_get_contents($url)) {
    file_put_contents(basename($_SERVER["PHP_SELF"]), $updated);
}
?>

Если файл не скачается (ошибка итд) put_contents не сработает, если сработал то всё прекрасно обновится без сбоев и прочего. Остальное это лирика. никакие доп-проверки и Curl-ыне нужны. Выдумывание проблем из ничего.

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

Касаемо кода, даже не дайте мне начать… По вашему allow_fopen_url может оказаться выключенным а ini_set нет?
Убило просто даже начало, вот ваш код
@ini_set('magic_quotes_gpc', 'off');
@ini_set('magic_quotes_runtime', 'off');

(дальше читаю через силу, и местами не могу сдержать смех)
100%. Никогда не понимал любителей писать километровый код для пустяковой задачи, да ещё и заворачивать в классы всё подряд.
>всё делается совершенно другими путями
очень интересно какими?
Есть много разумных и не очень путей.

Начнём с того что почти никто (в здравом уме) не делает авто-обновление прямо в РНР (есть исключительные случаи, но о них не сегодня)

Вообще авто-обновление мало кто делает, чаще всего где нибудь в админке (или просто в шапке когда человек залогинен как админ) вставляется так или иначе информер о том что новая версия есть (понравилось элегантное решение через просто картинку с надписью «последняя версия х.yy.zzz» в png/gif много трафика это не займёт, а за одно нет инклуда удалённого кода)

А для процесса обновления (мне нравится этот вариант) пишется уже .sh скрипт где:
(В случае автоматики можно запускать его по крону)
  1. Запрашивается удалённый сервер на предмет обновлённой версии
  2. Во временную папку (её размещение указывается в конфиге) качается tar (gz или bz2) архив
  3. С помощью tar разжимается в ту же временную папку (боян, но подчеркну что недоступную извне)
  4. Если скачивание/разжатие прошло удачно, то новые файлы передвигаются вместо старых.

(Такое делать надо замечу в продуктах где в дистрибе нет какого нибудь config.php как в том же рнрВВ2 а где есть config.sample который в последствии нужно скопировать/переименовать как например в рнрMyAdmin чтоб при обновлении не затереть конфиг на рабочем сервере)

Замечу, можно такое делать и на РНР, причём не используя sh/csh/bash/итд (хотя я не встречал, ибо будут нужны танцы с бубном по поводу chmod который надо будет менять, по поводу set_time_limit который также меняется далеко не везде, опять же будет множество танцев с выяснением способа скачки, сокеты/курл/фопен/итд) короче на РНР это делать очень неудобно.
Забыл упомянуть что старые в свою очередь файлы, перемещаются в тоже время во временную папку, для возможности «Rollback»
Увы, гораздо чаще возникает необходимость обновлять установленные скрипты в условиях хостинга с жесткими ограничениями на средства (без ssh, кронов и прочих удобств) и ресурсы (время выполнения, память, доступ к сети — все это приходится пробовать обойти автоматом, без привлечения пользователя), странными настройками окружения (права на файлы, распакованные через контрольную, самим скриптом и загруженные через FTP не совпадают, что приводит к различным проблемам с записью/модификацией файлов) и выполняется само обновление пользователями, для которых chmod созвучно ругательству.
Поэтому и пишется велосипед на PHP (гарантировать других методов в общем случае нельзя), который и обновляет скрипты (новые/модифицированные файлы продолжают принадлежать пользователю, из под которого запущен сервер), полная версия которого выполняет описанную вами процедуру, сдобренную костылями.
Так что скрипт обновления рассчитан на «исключительный случай», его полная версия может быть интересна как раз набором костылей, а не собственно идеей обновления.
Да, гораздо чаще всё идёт через (_|_) и на шаред-хостингах практически гарантировано что будет именно так (их настраивают чаще всего для безопасности и не всегда грамотно)

Однако велосипеды на РНР чаще всего не спасают, а только усугубляют проблему.

Но если вы и правы по поводу интересности костылей, то пусть он бы их и описал. (Увы я вижу лишь идею, причём далеко не самую удачную.)
Костыли в этом скрипте не значительны (некоторые из комментариев к коду вида //KNOWHOW описывают тот или иной костыль) и оно и вправду сейчас выглядит лишь идеей, их будет больше когда скрипт будет учиться докачивать обновления, распаковывать архив кусками, то есть уметь возобновлять свою работу, если его таки прихлопнут.
Если я правильно понимаю, то это создатели Shop-Script. Вот в этом скрипте инет магазина тоже есть авто обновление одной кнопкой. Каждый раз себе говорю «Не нажимай!», а потом сижу и плачу над километровыми высерами PHP и правлю ручками код.
Ещё с задачей обновления очень хорошо справляется rsync.
По шапке вам, господа, за такой хромой велосипед. Давать коду права на перезапись самого себя очень опасно.
Вот вам идея — хит.
Сделайте обновление сразу из svn! )
На своих серверах так и делаем. Но в общем случае на каком-нибудь виртуальном шаред-хостинге это не будет работать.
зато будет работать шелл-скриптинг + кронтаб. Этого в большинстве случаев достаточно.
Обновить вызываемый скрипт — не проблема. Попробуйте подобным образом обновить демон, да так, чтобы он после этой операции продолжил работать (обновлённым). И, да, вам бы хотя бы подписи туда прикрутить что ли.
Читал статью в надежде увидеть способ обновления скриптов которые работают непрерывно (демоны, например).
Недавно сделал такое на Perl. Могу описать.
Было бы интересно почитать.
UFO just landed and posted this here
Делать обновление сайта на PHP, это как из пушки по воробьям.

Для этого подойдет шелл-скриптинг банальный, зачем нагружать веб-сервер (как я понял из статьи это будет запускаться из браузера)?

Код вообще не выдерживает никакой критики:

1) форматирование
2) вывод ексепшена на экран
3) каша в файле из класса и логики

В первую очередь убивал бы программиста за такое форматирование. Ну и вообще по коду много странных решений.
На очень многих шаред-хостингах о шелл-скриптинге приходится только мечтать…
на этой неделе писал подобную фичу, только наоборот:
центральный сервер указывает куче скриптов самообновиться на разных хостах… при этом посылает бейз64 зашифрованный контент, подписанный контрольной суммой…
на серваках, ясно понятно, никакие фопены/курлы/сокеты не нужны… да и выглядит проще в разы :)
Года полтора назад тоже разрабатывал систему обновлений. Сначала скрипт засылал на центральный сервер список версий модулей ПО, потом получал список доступных обновлений. Обновление представляло собой архив с обязательным install.pl. Архив скачивался скриптом, разжимался, а выполнение install.pl форкалось.
Давно пора, у нас уже как года 3 такая штука стоит + утилита из вод Windows для обновления, когда сервер не разрешает ftp соединение с сервером обновлений, у Битрикса Сайтапдет есть тоже давно (я правда не вдавался в его детали). Прогресс на лицо, молодцы. Ну под эту дудочку еще удаленный web-install осталось сделать и будет полный зачет.
Я видел кучу шаред хостингов, в которых к php-файлам скриптов нет доступа не только на запись, но и на чтение из других скриптов (у меня была хитрая система инклюдинга «только то что нужно», но для нее надо было считывать пару строк в скриптах). Так вот на таких хостингах система не работала принципиально. Причем права на каталоги и файлы выставлял максимальные — бесполезно, блокирована сама возможность работы с содержимым скрипта из другого скрипта.

Думаю, такое автообновление в таих же условиях тоже не будет работать, т.к. не сможет переписать файл скрипта командой из скрипта.
Или я плохо искал, или обещанного продолжения так и нету(
Sign up to leave a comment.