Дженкинс не использует локали системы.

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

У меня есть интересное поведение в Jenkins.
Оболочка Jenkins не использует мои системные локали.

Jenkins работает как пользователь jenkins в моей системе.

Вошел как jenkins через SSH:

locale выводит:

LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE=”en_US.UTF-8″
и т.д…

env показывает переменные LANG и LANGUAGE:

LANG=en_US.UTF-8
LANGUAGE=en_US:en

id показывает ID пользователя:

uid=1008(jenkins) gid=…

Введенные выше команды в оболочке задания Jenkins:

locale выводит:

LANG=
LANGUAGE=
LC_CTYPE=”POSIX”
и т.д…

env не показывает переменные LANG и LANGUAGE

id показывает ID пользователя (как и ожидалось):

uid=1008(jenkins) gid=…

файлы:

/etc/profile содержит:

export LANG=en_US.UTF-8
export LANGUAGE=en_US:en

/etc/default/locale содержит:

export LANG=en_US.UTF-8
export LANGUAGE=en_US:en

скрипт запуска /etc/init.d/jenkins должен экспортировать системные локали:

# загрузка окружений
if [ -r /etc/default/locale ]; then
. /etc/default/locale
export LANG LANGUAGE
elif [ -r /etc/environment ]; then
. /etc/environment
export LANG LANGUAGE
fi

Конечно, я перезагрузил систему после изменения локалей 😉

Apache также использует системные локали
Моя система – это установка Ubuntu 14.04.
Я что-то пропустил?

Спасибо за внимание!
Надеюсь, кто-то сможет помочь 🙂

Решение:

Это происходит потому, что Jenkins master подключается к slave машине через non-interactive оболочку, поэтому /etc/profile не выполняется, и также /etc/default/locale не имеет никакого эффекта.
non-interactive оболочки обычно используют ~/.bashrc.

Практически все детали по этой теме можно найти на askubuntu:
https://askubuntu.com/questions/247738/why-is-etc-profile-not-invoked-for-non-login-shells

добавление в ~/.bashrc:

export LANG=en_US.UTF-8
export LANGUAGE=en_US:en

это решило мою проблему.

Эта ‘проблема с slave’ также обсуждается здесь:
https://groups.google.com/forum/#!topic/jenkinsci-users/hscDs4pKIoU
https://groups.google.com/forum/#!topic/jenkinsci-users/g0fNnDltqeM
С уважением, whosit

Кроме того, что объяснено в ответе @whosit, оболочка, запущенная с помощью команды Jenkins sh, наследует переменные окружения процесса Jenkins и выполняется как не интерактивная и не логин оболочка. Это означает, что файл .bashrc не считывается при каждом вызове sh, но его значения могут быть видны, так как они наследуются от основного процесса (либо контроллера Jenkins, либо агента).

Это может вызвать путаницу, когда файл .bashrc или любая другая глобальная переменная обновляется, и новое значение не сразу видно в оболочках, запущенных после изменения.

Существует несколько способов отразить изменения:

  • перезагрузить контроллер Jenkins и/или агентов (в зависимости от того, где работает оболочка)
  • подключить файл .bashrc при каждом вызове sh
sh """
  source .bashrc
  printenv
"""
  • запустить команду sh с директивой shebang, чтобы сказать Jenkins запускать логин оболочку (с --login, то есть это заставляет новую оболочку считывать файл .bashrc)
sh """#!/bin/bash --login
  printenv
"""

Тот факт, что переменные окружения видны, потому что они наследуются, а не считываются из файлов профиля, не является очень интуитивным и не документируется четко.

В нашем случае невозможно изменить все пайплайны, чтобы добавить директиву shebang или подключать файл .bashrc каждый раз, когда мы используем команду sh Jenkins, поэтому мы находим более удобным перезагружать агента каждый раз, когда происходит изменение глобальных настроек окружения (что происходит не очень часто).

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

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

Проблема с локалями в Jenkins

В вашем сценарии Jenkins работает под пользователем jenkins, и вы заметили, что при запуске команд через Jenkins не устанавливаются соответствующие переменные локали, как это происходит при ведении SSH-сессии. При вводе команд locale и env в Jenkins вы видите, что переменные LANG и LANGUAGE отсутствуют или имеют значения, отличные от ожидаемых.

Причины

Это поведение связано с тем, что Jenkins запускает shell-команды в неинтерактивной среде. В неинтерактивных оболочках, таких как та, которую использует Jenkins, не выполняются некоторые конфигурационные файлы, такие как /etc/profile и ~/.bashrc, которые обычно загружают переменные окружения.

Когда вы входите в систему под пользователем jenkins через SSH, система запускает интерактивную оболочку и загружает необходимые параметры конфигурации, включая локали. В случае Jenkins, запускаемого как сервис, данный механизм не работает.

Решения

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

  1. Добавление переменных в ~/.bashrc:
    Откройте файл ~/.bashrc для пользователя jenkins и добавьте туда строки:

    export LANG=en_US.UTF-8
    export LANGUAGE=en_US:en

    Это обеспечит загрузку переменных в среде, когда Jenkins запустит новую оболочку.

  2. Перезапуск Jenkins и/или агентов:
    Если вы изменяли файл ~/.bashrc, необходимо перезапустить Jenkins или его агентов для применения изменений. Перезапуск сервиса позволит загрузить новую конфигурацию.

  3. Явная загрузка ~/.bashrc в скрипте:
    В каждом скрипте, выполняемом в Jenkins, можно явно указать загрузку .bashrc. Например:

    sh """
    source /home/jenkins/.bashrc
    env
    """
  4. Использование shebang с директивой --login:
    Вы можете запускать команды в Jenkins с указанием оболочки в верхней части скрипта:

    sh """#!/bin/bash --login
    env
    """

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

Заключение

Таким образом, для обеспечения работы локалей в Jenkins следует внести изменения в конфигурации окружения, так как Jenkins по умолчанию запускает shell-команды в неинтерактивной оболочке. Решение может заключаться в редактировании файлов конфигурации, явном источнике инструкций оболочки или перезапуске сервисов Jenkins или его агентов. Это необходимо учитывать для корректного выполнения скриптов и предотвращения неожиданных ошибок, связанных с локалями.

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

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