Сергей Супрунов
Система контроля версий RCS на службе сисадмина
Отслеживание настроек операционной системы, особенно если речь идёт о «типовых» конфигурациях, обычно не является сложной задачей. Но иногда бывает трудно вспомнить, какие изменения вносились несколько месяцев назад на том или ином сервере, и зачем это было сделано.
При разработке документации или работе с исходными кодами различных программ проблема отслеживания версий ощущается довольно отчётливо, и потому для её решения существует масса инструментов – CVS, Subversion и тому подобные. Они позволяют управлять доступом к хранилищу кода (репозитарию), в том числе и удалённым пользователям, отслеживать любые изменения, автоматически вести учёт ветвей и версий... Но для «частных» задач эти средства порой оказываются слишком громоздки, и там удобнее использовать одну из простейших систем контроля версий – RCS.
Системный администратор может приспособить её и для повышения удобства своей работы. Например, если регистрировать изменения в конфигурацию системы с её помощью, то RCS позволяет:
- отслеживать все внесённые изменения;
- обеспечивать «контролируемый» доступ нескольким пользователям к настройкам;
- сопровождать каждую модификацию пояснениями;
- при необходимости «откатываться» на любую из предыдущих версий.
Рассмотрим пример использования RCS во FreeBSD, где эта система контроля версий включена в базовую систему.
Типовая задача
В качестве примера приведём использование RCS для сопровождения файла конфигурации ядра (для конкретики пусть это будет /usr/src/sys/i386/conf/MICRO). Прежде всего в каталоге с конфигурационными файлами создаём подкаталог RCS. Этот шаг не является обязательным, но без такого каталога файлы-хранилища версий (с именем вида <имя_файла>,v) будут создаваться в рабочем каталоге, что, на мой взгляд, не слишком удобно. А так они будут автоматически перемещаться в подкаталог RCS. (Кстати, так проще выполнять и резервное копирование – достаточно сохранить целиком каталог RCS.)
Теперь выполняем следующую команду:
# ci -u MICRO
RCS/MICRO,v <-- MICRO
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
>> My kernel configuration.
>> .
initial revision: 1.1
done
|
В ответ на приглашение «>>» вводим назначение файла и завершаем его строкой с единственным символом «.», чтобы отметить окончание ввода. Текущее состояние файла MICRO будет занесено в RCS/MICRO,v под номером версии 1.1. Ключ -u необходим, чтобы оригинальный файл не удалялся после занесения в RCS. (Вообще-то для инициализации хранилища существует специальный ключ -i, но, на мой взгляд, в большинстве случаев вполне можно обойтись и без него).
Теперь, если взглянуть на права доступа к файлу MICRO, можно увидеть, что он доступен только для чтения – с точки зрения безопасности приобретение не слишком существенное, но, по крайней мере, vi предупредит вас, если вы попытаетесь внести в него изменения напрямую, в обход RCS. Старайтесь избегать соблазна проигнорировать это предупреждение и сохранить файл по команде «:w!».
Как же теперь модифицировать этот файл? Для начала полезно убедиться, что никто не изменил наш MICRO вручную и что он соответствует версии, находящейся в хранилище версий:
# rcsdiff -u MICRO
===================
RCS file: RCS/MICRO,v
retrieving revision 1.1
diff -u -r1.1 MICRO
|
Отсутствие информации о различиях – хороший знак. В противном случае все внесённые напрямую изменения будут потеряны при извлечении ранее сохранённой версии. Строго говоря, для файлов конфигурации ядра, во избежание путаницы, лучше не оставлять в каталоге рабочую копию (то есть выполнять команду ci без ключа -u). В этом случае единственно возможным способом работы с конфигурацией ядра будет её извлечение из хранилища версий. Но поскольку RCS также может быть полезна и для системных настроек, например, для отслеживания изменений в /etc/rc.conf или /etc/crontab, а эти файлы, очевидно, для нормальной работы системы должны присутствовать всегда, то я описываю здесь наиболее общий случай.
Далее выполняем команду «извлечения последней версии»:
# co -l MICRO
RCS/MICRO,v --> MICRO
revision 1.1 (locked)
done
|
Файл MICRO теперь получит право на запись, и его можно редактировать, как обычно. Нужно только не забывать про ключ -l, именно он даёт право записи, одновременно блокируя версию в хранилище, чтобы в это же время никто другой не мог тоже открыть его на запись. Без ключа файл будет извлекаться с правами «только для чтения», что для работы с конфигурацией не слишком полезно.
А вот после внесения изменений и начинают проявляться преимущества использования системы контроля версий. После того как необходимые изменения внесены, мы должны загрузить новую версию обратно в хранилище:
# ci -u MICRO
RCS/MICRO,v <-- MICRO
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single '.' or end of file:
>> change ident, disable IPFILTER.
>> .
done
|
Ключ -u по-прежнему необходим, чтобы сохранить оригинальную версию, которую будет использовать в своей работе операционная система (с поправкой на тот случай, когда рабочая копия файла не является жизненно необходимой). Вместо описания файла теперь нас просят ввести комментарий к сделанным изменениям (в данном случае я подправил строку ident и убрал поддержку IPFILTER). Номер версии, как видите, поменялся на 1.2.
Теперь можно просмотреть лог изменений:
root# rlog MICRO
RCS file: RCS/MICRO,v
Working file: MICRO
head: 1.2
. . . <здесь кое-что сокращено> . . .
total revisions: 2; selected revisions: 2
description:
My kernel configuration.
- ---------------------------
revision 1.2
date: 2007/02/22 05:19:24; author: serg; state: Exp; lines: +3 -3
change ident, disable IPFILTER.
- ---------------------------
revision 1.1
date: 2007/02/22 05:03:59; author: serg; state: Exp;
Initial revision
- ---------------------------
|
Обратите внимание, что в авторах изменений указывается имя пользователя, вошедшего в систему, даже если само редактирование выполняется с правами root после выполнения команды su. Это позволяет отслеживать, кто именно вносил изменения, если администрированием сервера занимаются несколько человек.
Если нужно посмотреть, что именно менялось между версиями 1.1 и 1.2, можно выполнить следующую команду:
# rcsdiff -r1.1 -r1.2 MICRO
= =======================
RCS file: RCS/MICRO,v
retrieving revision 1.1
retrieving revision 1.2
diff -r1.1 -r1.2
5c5
< ident MIKRO
---
> ident MICRO
61,62c61,62
< options IPFILTER
< options IPFILTER_LOG
---
> #options IPFILTER
> #options IPFILTER_LOG
|
Ну и, наконец, если текущая версия оказалась не подходящей, можно загрузить одну из предыдущих (последняя версия из хранилища всегда может быть восстановлена):
# co -r1.1 MICRO
RCS/MICRO,v --> MICRO
revision 1.1
done
|
Как видите, всё очень просто и удобно, если, конечно, не забывать заносить все изменения в хранилище.
Замечание про права доступа
RCS по умолчанию открывает рабочий файл на запись только пользователю-владельцу хранилища и суперпользователю. Однако есть возможность разрешить модификацию отслеживаемых файлов и другим пользователям без необходимости предоставлять им пароль root.
Для этого нужных пользователей требуется занести в так называемый access list хранилища, что выполняется такой командой:
# rcs -aserg MICRO
RCS file: RCS/MICRO,v
done
|
В файле-хранилище появится запись в разделе access log:
$ rlog MICRO
RCS file: RCS/MICRO,v
Working file: MICRO
head: 1.2
branch:
locks: strict
access list:
serg
. . . <дальше пропущено> . . .
|
Теперь пользователю serg тоже можно открывать рабочий файл на запись, но при этом нужно учитывать ряд ограничений и особенностей:
- пользователь должен иметь права на уровне файловой системы для изменения каталога RCS (если он есть) и рабочего каталога;
- при извлечении рабочей копии из хранилища владельцем копии станет текущий пользователь (именно для этого и нужно право записи в рабочий каталог);
- при фиксации модифицированной версии владельцем хранилища станет текущий пользователь (и поэтому нужны права на модификацию и каталога RCS).
Таким образом, если политика безопасности не допускает такое «плавание» прав владения конфигурационными файлами, то лучше избегать использования списков доступа на уровне RCS. Кроме того, следует учитывать эту особенность и в том случае, когда программа требует конкретного владельца для своих конфигурационных файлов. Тут придётся либо выполнять редактирование от имени этого пользователя (предварительно выполнив команду su), либо вручную менять владельца после внесения изменений. (Возможно, вы решите, что для таких файлов проще вообще отказаться от использования RCS.)
Также имейте в виду такую особенность: поскольку владельцем хранилища становится последний пользователь, внёсший туда изменения, а владельцу разрешена запись, даже если он не входит в access list, то простое исключение пользователя из списка доступа (командой rcs -e<имя_пользователя>) может не оказать должного действия. Так что не забывайте проверять также и то, кто в данный момент является владельцем файла-хранилища.
Это ещё не всё...
Возможности RCS этим не исчерпываются, так что если вам понадобится что-то ещё, обратитесь к документации (прежде всего man-страницам) – не исключено, что необходимая вам функция системой RCS поддерживается. Начать лучше всего с man rcsintro, ну и дальше согласно секции «See Also».