☰ Оглавление

Задача совместного использования mercurial по SSH

В вашей команде доступ к mercurial организован по ssh. Вы хотите открыть доступ к определённым вашим репозиториям для определённых пользователей.

Простое решение

Простых решений два.

Первое. Если у вас на сервере достаточно современный современный mercurial, то вы можете воспользоваться стандартными средствами.

Второе. Если у вас в сети всё достаточно демократично, и требуется простое и быстрое решение, то вы можете поднять локальный сервер

hg serve

А чтобы ваши пользователи могли выполнять push, вам надо добавить в ~/.hgrc что-то подобное:

[web]
allow_push = *
push_ssl = false

Всё это не относится к моей ситуации.

Универсальное решение

На сервере

Кладём скрипт-обёртку hg-ssh, скажем в /opt/home/michurin/bin/hg-ssh.

#!/bin/sh

base_rep_dir='/opt/mercurial'
logfile="$HOME/bin/hg-ssh.log"

export LANG=C

l() {
  echo `date` "$@" >>"$logfile"
}

x() {
  f="$1~$2~$4~$5"
  if [ "$f" != 'hg~-R~serve~--stdio' ]
  then
    l "ERR: Invalid command f=[$f]"
    return 1
  fi
  r="$3"
  shift 5
  for x in "$@"
  do
    if [ "$r" = "$x" ]
    then
      return 0
    fi
  done
  l "ERR: Invalid repo r=[$r]"
  return 2
}

cd "$base_rep_dir"
l "INFO: [$SSH_CONNECTION] CMD=[$SSH_ORIGINAL_COMMAND] ARGS=[$@]"
if x $SSH_ORIGINAL_COMMAND "$@"
then
  $SSH_ORIGINAL_COMMAND
fi

Скорее всего, вы захотите поправить пути к логам и репозиториям.

Добавляем в ~/.ssh/authorized_keys ключ пользователя, которому хотим выдать право push-ить в наши репозитории. Опции (в одну строку):

command="/opt/home/michurin/bin/hg-ssh XX YY ZZ",
no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa ...

Тем самым мы дали пользователю право работать с репозиториями XX, YY, ZZ от нашего имени с нашими правами. (Автор коммита при этом будет записываться правильно.)

На стороне пользователя

Пишем в ~/.ssh/config:

Host hg
    # ваш пользователь и хост (куда открываем доступ)
    User michurin
    HostName 192.168.1.33

Теперь к репозиториям можно обращаться так:

hg clone ssh://hg/XX

Если вам приходится работать на многих машинах, то полезно иметь возможность собрать все изменения со всех машин и разослать их на много машин. Для этого в ~/.hgrc можно добавить полезные команды:

[alias]
echo = !echo $@
pushall = !for p in $(hg paths -q); do hg push $p; done
pullall = !for p in $(hg paths -q); do hg pull $p; done
pushallf = !for p in $(hg paths -q); do hg push -f $p; done

Теперь вы можете одной командой разостлать/получить код на все машинки, которые у вас прописаны в [paths]. Если при этом надо создавать новые головы, то используйте f-варианты.

Команда

hg pushallf

разошлёт во все репозитории, если надо, то будет создавать новые головы.

Команда

hg pullall

подтянет все изменения со всех репозиториев (и, кстати, создаст головы, если это необходимо; для этого не нужно никаких дополнительных ключей).

Это удобно, когда код одного проекта работает на разных машинах. Это могут быть JavaScript-файлы, конфигурации RRD, MySQL,… скрипты серверной части… В таких случая очень удобно иметь центральный репозиторий и легко синхронизироваться через него всю свою работу.