GCP - Cloud Function не может найти пакет Python из реестра артефактов в том же проекте
Я пробовал GCP Artifact Registry, который в настоящее время находится в альфа-версии для пакетов Python.
Я выполняю аутентификацию через связку ключей вместе со своей учетной записью службы, как описано в документации .
Я могу успешно загрузить пакет с помощью Twine, и я могу успешно загрузить его в локальный проект Python, установив следующее:
--extra-index-url https://my-region-pypi.pkg.dev/my-project/my-python-repo/simple/
my-package
Однако, когда я развертываю минимальную облачную функцию в том же проекте, что и мой реестр артефактов, с тем же, что показано выше, развертывание завершается ошибкой со следующим выходом:
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: `pip_download_wheels` had stderr output:
ERROR: Could not find a version that satisfies the requirement my-package (from -r requirements.txt (line 2)) (from versions: none)
ERROR: No matching distribution found for my-package (from -r requirements.txt (line 2))
Я пробовал с обоими
--extra-index-url
и просто
--index-url
, без разницы. Я также попытался установить зависимости связки ключей со следующими
requirements.txt
:
--extra-index-url https://my-region-pypi.pkg.dev/my-project/my-python-repo/simple/
keyring
keyrings.google-artifactregistry-auth
my-module
Но я получаю ту же ошибку.
Я проверил разрешения для своей учетной записи службы App Engine по умолчанию для моего проекта, которая также используется для облачных функций, и могу подтвердить, что у нее есть роль читателя реестра артефактов, поэтому, похоже, это не проблема с разрешениями.
Я также попытался развернуть минимальную службу App Engine вместо облачной функции, но получаю ту же ошибку.
Большое спасибо за помощь.
3 ответа
Мне потребовалось некоторое время, но мне удалось получить CF из одного проекта, чтобы загрузить пакет из другого проекта.
Есть несколько шагов, один из которых на данный момент не задокументирован. Некоторое тестирование и просмотр журналов помогли мне сузить фактическое поведение.
1: Иметь пакет в одном проекте. Я назову этот проект.
Обратите внимание, пакет, который я загрузил, является простым, который просто возвращает
2: Есть еще один проект для облачной функции. Я назову этот проект.
3: Создайте учетную запись службы в любом проекте и предоставьте ей разрешение на чтение реестра артефактов в . Я позвоню этому.
4: Это недокументированный шаг: предоставить учетной записи службы облачной сборки из того же разрешения для чтения реестра артефактов в . Формат имени этой учетной записи:
<PROJECT-NUMBER>@cloudbuild.gserviceaccount.com
5: Не уверен, что это необходимо, но я сделал именно так. Я выполнил приведенную ниже команду, указывающую на загруженную версию JSON
Это распечатывает значение для
(обратите внимание, я сделал несколько дополнительных шагов, которые не нужны, см. ниже, чтобы гарантировать, что ключ не будет загружен в какой-либо репозиторий github, прикрепленный к коду для CF)
6: Разверните код, как вам нравится.
Резюме
Итак, подведем итог: первая аутентификация в репозитории выполняется с любым SA, который вы используете (например, в связке ключей или с использованием метода, описанного выше). Как ни глупо, сама загрузка делается со встроенным SA для Cloud Build из проекта, в который вы разворачиваете Cloud Function (). ИМХО это должен делать тот же СА что и первый.
Что касается того, как я узнал, что SA для Cloud Build был проблемой, когда я только добавил
У меня были и другие сценарии, когда внутреннее использование SA на стороне Google было немного шатким, и Cloud Build определенно является повторным нарушителем здесь.
Дополнительные шаги для безопасности
Я создал вторичный файл требований и добавил его в свой
требования.txt
-r privatereq.txt
mypythonpackage
частный.req.txt
--extra-index-url https://_json_key_base64:[BASE64_KEY_SNIPPED]@[LOCATION]-python.pkg.dev/[REPO-PROJECT]/python-repo/simple/
.gitignore
*/privatereq.txt
Это определенно была недостающая часть, я думал, что должен дать разрешение учетной записи службы по умолчанию в реестре артефактов. Замена его на Cloud Build вместо этого привела меня туда. Ничего кроме этого делать не пришлось.
указать требования к:
--extra-index-url https://<location>-python.pkg.dev/<project>/<repository>/simple
<package>
и импортирует в main:
from <package> import <module>
работает на меня. Не забудьте повторить необходимые модули для вашего пакета в файле requirements.txt (setup.cfg из пакета работает только в процессе сборки)