суббота, 8 марта 2008 г.

Откат изменений при загрузке

Пришла мне в голову идея - помню вот народ Hg использовал для сохранения всех изменений в дереве /etc, я и сам пользуюсь этим на серверах. Кто не в курсе - Hg это система контроля версий, Mercurial. Системы контроля версий сохраняют все ваши изменения и используются в основном программистами для совместной работы и, собственно, контроля версий : )
Итак, в качестве полигона используем папку у себя в домашней директории :

aptitude install mercurial # у кого еще нет : )
mkdir temp
cd temp
hg init
# создадим тестовый набор файлов
for i in `echo "0 1 2 3 4" | xargs`; do touch test$i; done

Добавим их под контроль:


hg add test*

смотрим hg status:



A test0
A test1
A test2
A test3
A test4

Далее фиксируем текущий шаг изменений:


»mkrivushin@dot:~/temp$ hg commit -m "`date` автоматический фикс"
No username found, using 'mkrivushin@dot.souzt.tld' instead

еще разок:



»mkrivushin@dot:~/temp$ hg commit -m "`date` автоматический фикс"
nothing changed

Как видите, по второму разу неизмененное не фиксируется.

поправим test0:



echo "wqerqwrqwer" > test0
»mkrivushin@dot:~/temp$ hg commit -m “`date` автоматический фикс”
No username found, using ‘mkrivushin@dot.souzt.tld’ instead

Изменения зафиксировались, посмотрим:



»mkrivushin@dot:~/temp$ hg log
changeset: 1:e2aab7338581
tag: tip
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:44:18 2008 +0600
summary: Птн Мар 7 11:44:18 NOVT 2008 автоматический фикс

changeset: 0:88a5a7a6c86a
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:41:39 2008 +0600
summary: Птн Мар 7 11:41:39 NOVT 2008 автоматический фикс

Пробуем теперь с откатами к предыдущей редакции:



»mkrivushin@dot:~/temp$ echo "осмысленный текст" > test0
»mkrivushin@dot:~/temp$ hg commit -m "`date` автоматический фикс"
No username found, using 'mkrivushin@dot.souzt.tld' instead
»mkrivushin@dot:~/temp$ hg log
changeset: 2:0b341c5a3f32
tag: tip
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:47:00 2008 +0600
summary: Птн Мар 7 11:47:00 NOVT 2008 автоматический фикс

changeset: 1:e2aab7338581
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:44:18 2008 +0600
summary: Птн Мар 7 11:44:18 NOVT 2008 автоматический фикс

changeset: 0:88a5a7a6c86a
user: mkrivushin@dot.souzt.tld
date: Fri Mar 07 11:41:39 2008 +0600
summary: Птн Мар 7 11:41:39 NOVT 2008 автоматический фикс
»mkrivushin@dot:~/temp$ hg revert -a -r 1
reverting test0
»mkrivushin@dot:~/temp$ cat test0
wqerqwrqwer

Вот, то что надо - откат изменений. Теперь бы перевести на автоматические рельсы это хозяйство. Во первых нужно автоматическое добавление новых файлов, второе - автоматическая фиксация изменений. Можно конечно и без автомата, самим точки когда надо ставить.




»mkrivushin@dot:~/temp$ for i in `echo "0 1 2 3 4" | xargs`; do touch new$i; done
»mkrivushin@dot:~/temp$ ls
new0 new1 new2 new3 new4 test0 test1 test2 test3 test4
»mkrivushin@dot:~/temp$ hg st
? new0
? new1
? new2
? new3
? new4

Смотрим - новые файлы выводятся вопросами. Ну значит применим : )



»mkrivushin@dot:~/temp$ hg st | grep ^? | sed s/^?\ /\"/g | sed s/$/\"/g | xargs -n 1 hg add
»mkrivushin@dot:~/temp$ hg st
A kuku kuku
A new0
A new1
A new2
A new3
A new4

Добавились! : )


В общем вы догадались уже, что это можно применить к одному очень интересному каталогу - /etc
Но это еще не все! А как же нам при загрузке вернуться к рабочей системе, которую мы грохнули изучая pam, hesiod и kerberos? : ) Вот тут приходит такой очень хороший каталог - /proc



»mkrivushin@dot:~/temp$ cat /proc/cmdline
root=UUID=hehe-hehe-hehe-hehe ro quiet splash

А вот и параметры переданные ядру : ) Продолжать? Я думаю, вы конечно догадались, но так и быть допишем опус. Итак, напишем скрипт, который будет смотреть в параметры переданые ядру при загрузке, вылавливать оттуда номер ревизии и откатывать /etc к ней.



#! /usr/bin/python
import re
import os
cmd = open(’/proc/cmdline’,'r’).read().strip()
try:
revert = re.search(r’revert=(?P\d+)’,cmd).groupdict()[’revert’]
except:
revert=None
if revert:
os.system(”cd /etc && hg revert -a -r %s”%revert)
print “System config catalog /etc was reverted!!!”


Ставим этот скрипт в загрузку первым (/etc/event.d или используем дебиановский update-rc.d) и ломаем систему спокойно : ) Можно еще сделать возврат к какой либо версии по дате/времени.


А теперь самоe страшное - не тестировал, только собираюсь, но времени пока нет. Если кому-то интересно, я могу помочь советами, а также могу помочь сделать пакет из этого хозяйства. Кстати, если это велосипед, скажите автору в комментариях, чтоб больше не занимался фигней на рабочем месте : )

Комментариев нет: