Я пытаюсь запустить некоторые из моих простых заданий CI (например, линтеры) в лямбда-функции для моих репозиториев Python.
Я использую для этого gitlab-ci и базовую архитектуру (ненепосредственно связана с проблемой, но это может помочь при выборе):
задания CI определяются как набор команд оболочки, в моем случае просто выполняющихся black --check .
(подстилка Python): 1. Команды оболочки отправляются в мою лямбду 2. лямбда-мерзавец клонирует репозиторий 3. лямбда выполняет в подпроцессе команды 4. результат возвращается
, поэтому моя лямбда выглядит так:
import os
import stat
import sys
import json
import subprocess
import stat
import shutil
from git import Repo
def main(event, lambda_context):
# I've commented out, so that if you like trying to reproduce it
# at home, you don't need the additional dependencies :)
#Repo.clone_from("https://example.com/the/repo.git")
# the command sent by the CI having a shebang in it
# the quick and dirty solution we found is to write it into
# a shell script and then executing said script
script = open("/tmp/script.sh", "w")
script.write(event["command"])
script.close()
st = os.stat("/tmp/script.sh")
os.chmod("/tmp/script.sh", st.st_mode | stat.S_IEXEC)
# the copy is just to be extra-safe
copy_env_variables = os.environ.copy()
# for all the binary added by the requirements.txt
# we edit PYTHONPATH for black in the subshell to find the modules
lambda_root_dir = os.environ["LAMBDA_TASK_ROOT"]
copy_env_variables["PATH"] = copy_env_variables["PATH"] + f":{lambda_root_dir}/bin"
copy_env_variables["PYTHONPATH"] = (
copy_env_variables.get("PYTHONPATH", "") + ":" + lambda_root_dir
)
proc = subprocess.Popen(
"/tmp/script.sh",
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=copy_env_variables,
)
(stdout, _) = proc.communicate()
return {"return_code": proc.returncode, "output": stdout.decode("utf-8")}
и лямбда-пакет упакован с этим сценарием: (python3 - это python3.7, а я нахожусь на linux x86_64)
python3 -m pip install -r requirements.txt -t ./
zip -r archive.zip . -x \*.pyc *.git*
файл needs.txt следующий:
gitpython
black
и когда я выполняю задание CI, я получаю выходные данные подпроцесса:
$ black --check .
Traceback (most recent call last):
File "/var/task/bin/black", line 6, in <module>
from black import patched_main
File "/var/task/black.py", line 15, in <module>
import regex as re
File "/var/task/regex/__init__.py", line 1, in <module>
from .regex import *
File "/var/task/regex/regex.py", line 402, in <module>
import regex._regex_core as _regex_core
File "/var/task/regex/_regex_core.py", line 21, in <module>
import regex._regex as _regex
ModuleNotFoundError: No module named 'regex._regex'
Особенностью regex._regexp
является то, что это скомпилированный модуль с именем regex/_regex.cpython-37m-x86_64-linux-gnu.so
, однако, если яимпортировать его прямо в мой лямбда-код, он работает без проблемlem.
Что-то мне не хватает в том, как python работает с модулями из библиотек .so?