Установка Mercurial Server и использование авторизации по SSH
Установка Mercurial Server
Первым, что пришло в голову — была установка из репозиториев. Обновив пакеты и выполнив команду:
я обнаружил, что установилась версия 1.0.1-1, которая не является последней.
На официальном сайте был обнаружен deb-пакет с версией 1.2-1, который и был установлен командой
Настройка SSH для авторизации по ключам
Т.к. я хотел, чтобы все ключи пользователей, которые имеют доступ к серверу по ssh, хранились в одном месте, то в файл /etc/ssh/sshd_config была добавлена следующая строчка:
AuthorizedKeysFile /etc/ssh/keys/%u.pub
Она означает, что файлы ключей должны храниться в папке /etc/ssh/keys/ и иметь вид имя_пользователя.pub
Настройка Mercurial Server
Домашняя директория с конфигами Mercurial Server находится в /var/lib/mercurial-server. Нас интересует файл .mercurial-server, именно в нем хранится основной конфиг сервера. Там можно изменить пути к репозиториям, директории с публичными ключами и др. Т.к. репозитории у меня вынесены на другой диск, то и переменную repos я изменил соответствующим образом.
Пользователи делятся на две группы: root(имеют полные права на все репозитории, в том числе и на создание) и users(имеют право на pull и push).
Ключи пользователей, которые должны иметь доступ к серверу необходимо поместить в папку /etc/mercurial-server/keys/users, а ключи администраторов — /etc/mercurial-server/keys/root.
Специальный репозиторий hgadmin
После установки сервера автоматически создается служебный репозиторий hgadmin, в котором можно хранить ключи пользователей и администраторов. Это очень удобно, т.к. нет необходимости загружать в ручную ключи пользователей.
Структура точно такая же, как и в системе, т.е. ключи хранятся в /hgadmin/keys/users и /hgadmin/keys/root для пользователей и администраторов соответственно.
Там же можно хранить файл access.conf который отвечает за права доступа пользователей.
Окончательная настройка
/.ssh/authorized_keys нам нужно создать символическую ссылку в каталоге /etc/ssh/keys/. Для этого выполняем команду:
После того, как мы поместили ключ в /etc/mercurial-server/keys необходимо обновить права доступа, для этого необходимо выполнить следующую команду:
Если ключи были добавлены с помощью hgadmin, то изменения вступают в силу автоматически.
Mercurial на Windows Server 2003
Примечание. Все манипуляции касаются Mercurial 1.8.3, Python 2.6.6 и архитектуры x86. Для других версий mercurial нужно брать версию Python, для которой он скомпилирован (см. на офф. сайте mercurial).
Установка
- Скачать и установить Mercurial;
- Скачать и установить Python;
- Получить hgweb.cgi. Тут есть два способа:
- скачать исходники с сайта Mercurial
- или получить копию исходников
Нужный нам файл находится в корне директории:
Настройка
Теперь нужно разрешить python выполнять .cgi:
- Открыть диспетчер служб IIS;
- Нажать «Добавить новое расширение веб-служб…»;
- В открывшемся окне ввести имя расширения. Я назвал его Python;
- Нажать кнопку «Добавить» и в открывшемся окне ввести путь к исполняемому файлу C:\Python26\python.exe -u «%s» «%s» ;
- Установить галку «Установить состояние расширения как «Разрешено»»;
- В итоге имеем веб-расширение Python
Далее нужно создать виртуальную директорию для папки, где находится Mercurial, — с установкой галки «выполнение (например приложений ISAPI или CGI)» — и разрешить выполнять .cgi скрипты. Для этого нужно:
- В свойствах виртуальной директории на вкладке «Виртуальный каталог» в разделе «Параметры приложения» нажать кнопку «Настройка»;
- В открывшемся окне нажать верхнюю кнопку «Добавить…»;
- В открывшемся окне ввести путь к исполняемому файлу C:\Python26\python.exe -u «%s» «%s» , имя расширения .cgi , команды сократить до GET,HEAD,POST , убедиться, что установлена галка «Обработчик сценариев»;
Расширение .cgi добавлено: - Нажать все Океи.
Теперь можно проверить работоспособность Python. Создаем скрипт:
и сохраняем его в папку с Mercurial, например как test.cgi ( C:\Inetpub\hg\test.cgi ). Открываем браузер и смотрим:
Конфигурирование Mercurial
Примечание. hgweb.cgi у меня заработал только при ANSI-кодировке hgweb.config. При UTF-8 вылетала ошибка парсинга.
Этими строчками мы разрешили добавлять изменения всем пользователям без использования ssl.
Смотрим в браузере: 
Mercurial работает! Но нет ни одного репозитория…
Добавление репозиториев
F5 в браузере и видим наш репозиторий:
Чтобы каждый раз не добавлять вручную пути к репозиториям можно указать путь к коллекции:
Тогда все репозитории из каталога Repos будут отображаться автоматически.
Для красоты добавим оформление веб-страницы:
Monoblue — это один из шаблонов, которые находятся в папке C:\Inetpub\hg\Templates . Изначально в папке всего четыре шаблона — coal, gitweb, monoblue, paper. Но с легкостью можно создать свой. О шаблонах mercurial можно почитать здесь.
Чуть-чуть баловства и уже можно кое-что посмотреть:
Красивый URL
Признаюсь сделать это у меня получилось частично…
Хотя правило и заработало и URL стал красивый, но в html-коде страницы красовалось и, соответственно, стиль не применялся… Это я так и не поборол.
Поднимаем Mercurial на Windows-сервере (с Nginx)
Недавно случайно узнал, что BitBucket, где лежат мои Mercurial-репозитории, прекращает поддержку Mercurial: новые репозитории создавать уже нельзя, а существующие будут удалелы с 1.06.2020. Возможные варианты действий: перейти на Git, выбрать один из других сервисов, или настроить хостинг Mercurial на своём сервере. Сервер у меня есть, отказываться от Mercurial и менять привычки как-то не хочется, альтернативы BitBucket мне тоже не приглянулись — поэтому выбрал последний вариант. Задача вроде несложная, вот только сервер у меня под Windows, и, кажется, в процессе настройки я умудрился наступить на максимум возможных граблей. Надеюсь, эта статья поможет кому-нибудь избежать этого и сэкономить время.
Различные варианты организации Mercurial-хостинга описаны в документации. Их можно разделить на 3 группы:
- hg serve — т.е. сам Mercurial запускается в режиме сервера.
- HgWeb.cgi — официальный скрипт, входящий в дистрибутив Mercurial.
- Решения от внешних разработчиков — более функциональные, но со своими ограничениями и зачастую платные.
HG SERVE
Наиболее простым и логичным выглядит 1-й вариант. Как гласит документация, в Mercurial имеется встроенный веб-сервер, исполняющий HgWeb — именно он и работает, когда мы запускаем hg serve. Этот сервер не умеет делать аутентификацию, т.е. не умеет запрашивать логин/пароль пользователя, однако умеет делать авторизацию, т.е. давать/не давать тот или иной вид доспупа к репозиториям в соответствии с настройками доступа. Если нам нужны приватные репозитории, то для аутентификации можно использовать Nginx в качестве прокси-сервера, который будет запрашивать пароль. Настройка такой схемы описана здесь.
Для удобства hg serve запускается в виде сервиса с помощью winsw — утилиты, позволяющей запускать в виде сервиса любую команду (в данном случае это вообще bat-файл). Впрочем, для запуска можно обойтись и без сервиса, а, например, создать таск в Task Scheduler с триггером «At system startup» — такой таск будет запускаться при старте системы. Но это менее надёжный вариант: в случае сбоя таск не будет перезапущен, да и в логах информации об этом не будет.
Будьте внимательны с файлами конфигурации (hgweb.conf / hgrc):
- Их содержимое чувствительно к регистру: если, например, написать [Web] вместо [web] — работать не будет.
- Знак равенства обязательно должен быть окружен пробелами: если написать push_ssl=false — работать не будет, нужно писать push_ssl = false .
Ещё обратите внимание на то, что Mercurial делает push в репозиторий одним запросом, и если ваш проект не «Hello world», то этот запрос может быть объёмным и длительным. Пропишите в конфиге Nginx достаточно большие значения:
чтобы не оказаться в ситуации, когда вроде бы всё работает, а залить реальный проект на сервер не получается.
Проблема авторизации
В hgweb.conf задаётся общая для всех репозиториев конфигурация. Если нужны специфические настройки для каждого репозитория (а они нужны), то они указываются внутри репозитория: /.hg/hgrc Там можно, например, перечислить конкретных пользователей, имеющих доступ к данному репозиторию.
Чтобы это работало, Mercurial должен знать имя пользователя, который авторизовался в Nginx. И тут возникает проблема: на практике Mercurial видит всех пользователей, которых пропускает к нему Nginx одинаково безымянными. В различных источниках рекомендуют в конфигурации Nginx передавать имя пользователя в заголовках так:
но у меня это не сработало 🙁 Судя по коду HgWeb, имя пользователя берется из ENV(‘REMOTE_USER’), но вот как его туда поместить — загадка.
Если сложная авторизация не требуется, можно настроить её непосредственно в конфигурации Nginx либо создать 2 (или более) экземпляров hg serve, использующих различные файлы hgweb.conf . Недостаток в гибкости последнего метода в том, что настройки hgweb.conf глобальны и касаются всех (перечисленных в нем) репозиториев. Впрочем, комбинируя эти два метода можно добиться практически любых схем авторизации. В конце статьи я ещё коснусь этой темы.
HgWeb.cgi
Описанные выше манипуляции попахивают извращением, поэтому я решил попробовать официальный Python-скрипт HgWeb. В бинарном дистрибутиве Mercurial его нет, поэтому нужно скачать дистрибутив исходников и взять оттуда. Там, кроме основной (CGI) версии, имеются также более эффективные — WSGI и FCGI.
Поскольку Nginx не умеет запускать CGI, а для WSGI нужен WSGI-сервер (поставить который на Windows отдельная проблема), я решил использовать FCGI — то есть FastCGI. Для его запуска нужен Python, причём документация гласит, что Python должен быть такой же версии, какая используется в бинарном дистрибутиве Mercurial — то есть 2.7. Окей, установил 2.7. Для запуска HgWeb в Python также необходимо установить библиотеку Flup, причём не просто установить, а определённой версии (ибо последняя не поддерживает Python 2.7). Вот так работает:
Теперь нужно отредактировать сам hgweb.fcgi — прописать путь к файлу конфигурации (что очевидно) а также указать параметры запуска, как минимум обязательный параметр используемого локального адреса (что совершенно неочевидно):
Осталось добавить конфигурацию Nginx:
Я специально не редактировал файл fastcgi.conf , а вынес все дополнительные настройки fastcgi в секцию location для наглядности. Обратите внимание на параметр PATH_INFO — он важен для работы скрипта. В моём случае имя скрипта в url вообще отсутствует, а весь оставшийся путь идёт в PATH_INFO.
Теперь запускаем сам скрипт:
Еще немножко настроек
Как и в случае с hg serve, разумно сделать запуск HgWeb в виде сервиса. Для этого использую всё тот же winsw. Он выполняет такой bat-файл:
Обратите внимание, что я скопировал python.exe в python-hg.exe чтобы taskkill легко нашел единственный нужный процесс для остановки.
Не стоит забывать и о безопасности: выполнять сервисы для публичного доступа под юзером «Local System» — плохая идея! Нужно создать отдельного юзера, дать ему доступ только к нужным папкам и запускать сервис под ним.
Публичный доступ к репозиториям
Чтобы организовать публичный беспарольный доступ к некоторым репозиториям, документация рекомендует запускать два экземпляра HgWeb (или hg serve) с разными конфигурациями. Но можно сделать проще: для каждого репозитория, к которому нужен публичный доступ, добавить в конфигурацию Nginx отдельную секцию location без защиты паролем. Примерно так:
Все — репозиторий Base доступен без пароля.
Надеюсь, эта статья поможет вам сэкономить время. Лично у меня на всё это ушло примерно полтора дня (с учётом того, что Python я увидел, можно сказать, впервые в жизни 🙂









