Отказано в доступе: вызов сценария оболочки из Python в задании Jenkins

Пытаясь предоставить минимальное количество информации, необходимой здесь, поэтому я многое упустил. Много похожих вопросов, но самый распространенный ответ (используйте chmod +x) мне не подходит.

У меня есть скрипт Python и скрипт оболочки, которые находятся рядом с каждым в репозитории GitHub Enterprise:

Затем в Jenkins я проверяю код в этом репозитории. Два ключевых шага в моем файле Jenkins выглядят так:

dir ("$WORK/python")
{           
    sh "chmod +x test.sh"
    sh "python3 foo.py -t '${AUTH}'"
}

Здесь $WORK — это расположение на узле Jenkins, в которое проверяется код, а python (да, плохое название) — это папка в репозитории, в которой живут Python и сценарий оболочки. Теперь foo.py вызывает сценарий оболочки таким образом. :

try:
    cmd = f'test.sh {repo_name}'
    subprocess.Popen(cmd.split())

except Exception as e:
    print(f'Error during repository scan: {e}')  

Здесь repo_name — это просто аргумент, который я определяю над этим фрагментом, с которым я прошу сценарий оболочки что-то сделать. Когда я запускаю задание в Jenkins, оно технически выполняется без ошибок, но ветвь исключений выше выполняется:

11:37:24  Error during repository scan - [Errno 13] Permission denied: 'test.sh'

Я хотел убедиться, что chmod в файле Jenkins работает, поэтому я открыл терминал на машине, на которой был проверен код, и обнаружил, что разрешения на выполнение действительно установлены правильно:

-rw-r--r-- 1 adm domain users   4106 Feb  6 14:24 foo.py
-rwxr-xr-x 1 adm domain users    619 Feb  6 14:37 test.sh

Я занимался этим большую часть дня. Что же такое происходит?

добавьте #!/usr/bin/python в первую строку вашего исходного кода, или, если вы используете python 2.7, вы можете добавить #!/usr/bin/python2.7

Mohammad Nazari 06.02.2023 21:51

Я уже использую #!/usr/bin/python3 в верхней части моего файла Python, а также #!/bin/bash в верхней части моего сценария оболочки, поэтому я не думаю, что это связано с этим.

Pat Jones 06.02.2023 22:02

Попробуйте использовать /bin/bash test.sh (или любой другой подходящий интерпретатор) в своем подпроцессе. Единственное, что я действительно могу придумать, что позволит запускать скрипт python, но не скрипт bash, это если в вашей системе есть какая-то утилита белого списка.

tjm3772 06.02.2023 22:44

Также, возможно, проверьте, что родительские каталоги являются исполняемыми для пользователя, выполняющего это задание, и что каталог не находится в точке монтирования с noexec (проверьте с помощью findmnt -T .). Основное различие между вашими двумя программами заключается в том, что вы полагаетесь на то, что скрипт python будет доступен для чтения python3, но вы полагаетесь на то, что скрипт bash является исполняемым файлом, поэтому любые внешние блокираторы выполнения разрешат скрипт python, но не баш скрипт.

tjm3772 06.02.2023 22:53

Достаточно интересно, если я выполняю test.sh вручную в терминале узла, после того, как задание Jenkins попыталось запустить его, я получаю успешное выполнение. Мы используем сценарии оболочки в других местах нашей кодовой базы, поэтому я склонен думать, что это не проблема на уровне машины, как noexec.

Pat Jones 06.02.2023 23:17

Давайте продолжим обсуждение в чате.

tjm3772 06.02.2023 23:39

@ tjm3772 - Все разрешения для родительского каталога выглядят хорошо. findmnt показывает некоторые подкаталоги в /sys, в которых есть noexec, но каталоги, важные для работы, в порядке. Если я сделаю /bin/bash test.sh в вызове подпроцесса, результат на выходе консоли будет 14:12:52 /bin/bash: test.sh: No such file or directory.

Pat Jones 06.02.2023 23:47
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
7
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Выполнение этого исправило это:

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

cmd = f'{BASE_DIR}/test.sh {repo_name}'
Popen(cmd.split())

Почему? По своему невежеству, связанному с подбором чужого кода, я забыл увидеть, закопанное выше, перед вызовом сценария оболочки, что мы переходим в папку на уровень ниже:

os.chdir('repo_content')

Сценарий оболочки, конечно, там не живет. Поэтому вызов без указания пути не сработает. Я не уверен, почему это приводит к [Errno 13] Permission denied: 'test.sh', так как это будет означать, что сценарий оболочки был найден, но полное указание пути, как указано выше, делает именно то, на что я надеялся.

Другие вопросы по теме