Git hook на SSH удаленном сервере не работает из-за того, что не считывается конфигурация оболочки.

Вопрос или проблема

Я использую хук post-receive в git, чтобы выполнять некоторые действия после git push на удаленный сервер. Этот удаленный сервер работает через SSH:

$ git remote -v
server  user@server:repo.git

Проблема в том, что этот хук написан на Perl и использует версию Perl, отличную от системной Perl (управляется с помощью Perlbrew). Когда скрипт выполняется после push (который проходит без проблем), он завершается с ошибкой из-за использования другой версии — то есть скрипт, который должен выполняться с современной версией Perl из Perlbrew, выполняется с системной Perl. Также важно отметить, что скрипт начинается с:

#!/usr/bin/env perl

Я полагаю, это происходит потому, что SSH через git не читает мой файл .zprofile, в котором настраивается Perlbrew. Почему это так? Если это происходит через SSH, разве не должна открываться оболочка от моего пользователя и, следовательно, считываться профиль?

Есть ли способ заставить это работать с моей кастомной версией Perl?

Ответ или решение

Теория

Проблема, с которой вы столкнулись, связана с разницей в окружении выполнения, когда скрипт запускается на удаленном сервере через Git hook. Действительно, SSH-соединения, которые используются Git для взаимодействия с удаленным сервером, по умолчанию не инициализируют пользовательскую оболочку, как если бы это происходило при обычном входе пользователя в систему. В результате ваш файл .zprofile не читается в рамках этого процесса, и переменные окружения, необходимые для корректного функционирования Perlbrew, остаются неинициализированными.

Когда вы используете shebang #!/usr/bin/env perl, это позволяет вам запускать скрипт с версией Perl, которая определена в переменной окружения PATH. Если Perlbrew не инициализируется должным образом, то вместо ожидаемой версии может быть использована системная версия Perl, что и вызывает сбой.

Пример

Сценарий, который вы описываете, может быть проиллюстрирован следующим образом:

  1. Вы создаете hook post-receive на удаленном сервере, например /path/to/repo.git/hooks/post-receive.
  2. В этом скрипте вызывается Perl, установленный через Perlbrew.
  3. Поскольку Perlbrew инициализирован в .zprofile, но этот файл не читается во время выполнения hook, то системный Perl, а не версия из Perlbrew, используется для выполнения скрипта.

Применение

Решение 1: Инициализация окружения Perlbrew вручную в hook

Одним из решений может быть явная инициализация окружения Perlbrew в самом скрипте hook. В начало вашего скрипта можно добавить такие строки, чтобы установить правильное окружение:

source ~/perl5/perlbrew/etc/bashrc
perlbrew use <your_perl_version>

Это позволит убедиться, что каждая сессия выполнит шрифты из нужной версии Perl.

Решение 2: Использование полного пути к интерпретатору Perl

Вместо #!/usr/bin/env perl, вы можете использовать полный путь к perl, установленному через Perlbrew. Например, если вы используете Perl 5.32.0, путь может выглядеть так:

#!/home/youruser/perl5/perlbrew/perls/perl-5.32.0/bin/perl

Эта строка shebang будет заставлять систему использовать конкретно установленную вами версию Perl, не полагаясь на env или переменные окружения.

Решение 3: Изменение вашего SSH-соединения

Так как SSH по умолчанию использует non-login shell, вы можете сделать несколько модификаций; однако, имейте в виду, что это менее безопасный подход. Один из вариантов — изменить настройки SSH-сервера, чтобы он запускал вашу оболочку как оболочку логина, однако это может повлиять на другие процессы и является потенциально небезопасным методом.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...