Отладка ошибок Rust Cargo в Gitlab
4 февраля 2023 г.Rust играет ключевую роль в серверных приложениях моей компании. Он широко известен своей способностью создавать безопасные, быстрые, параллельные, современные и эффективные программы.
Мы были одними из первых пользователей экосистемы Rust. Поскольку мы не работаем с открытым исходным кодом, нам нужно было место для хранения наших пакетов Rust (известных как Crates) для повторного использования и управления зависимостями. Мы не могли использовать публичный реестр Crates.io, предлагаемый Rust, да и других вариантов в то время не было. Итак, коллега, который также работал DevOps, написал собственный реестр на языке Go. Для него это не было сложной задачей, поскольку технически это было просто — всего лишь HTTP-сервер с несколькими вызовами API и индексом, хранящимся в репозитории GIT. Он даже добавил MongoDB для сохраняемости, но, на мой взгляд, это не обязательно.
Когда Jfrog представила поддержку реестра Cargo в Artifactory, мы переключились. Это был сложный и одновременно простой процесс по двум причинам:
* Не было возможности выполнить миграцию ни на уровне приложения (Artifactory), ни на уровне реестра (Cargo). * Я написал скрипт, чтобы просмотреть все наши репозитории Rust, изменить конфигурацию в коде, чтобы она указывала на новый реестр, и запустить «Cargo push». Однако каждый репозиторий имел различную структуру каталогов и конфигурации, что усложняло анализ.
Хорошо, давайте перейдем от прелюдий. В центре внимания этой статьи не миграция, поэтому давайте перейдем к главному.
Однажды разработчик показал мне следующую ошибку в GitLab CI:
$ cargo build
Updating `my-cargo-registry` index
error: failed to select a version for the requirement `my-lib-core = "^2.2.1"`
candidate versions found which didn't match: 2.2.0, 2.1.2, 2.1.1, ...
На первый взгляд ошибка казалась очевидной. Итак, я проверил проект Artifactory и увидел, что артефакт с версией 2.2.1 существует. Похоже, проблема была с индексом. Я нашел индекс Cargo по тому же пути Artifactory и обнаружил, что запись с правильной версией находится в файле config.json.
«Давай снова отправим его в Artifactory», — подумал я. Слава богу, репо все еще активно поддерживалось. Я внес изменения на уровне CI и убедился, что файл был обновлен на удаленном компьютере. Чтобы перепроверить, я также нажал кнопку «Пересчитать индекс» на Artifactory, которая помогала мне в прошлом. Кроме того, для большей уверенности я сравнил даты и контрольные суммы этого конкретного файла.
Несмотря на все эти шаги, сборки все еще не удались.
Хорошо, давайте попробуем шаги CI на локальной машине. Это стандартный этап диагностики для любого инженера. Чтобы получить более точный результат, я удалил все данные Cargo из ~/.cargo и запустил команду «cargo clean» на уровне проекта, и... это сработало локально. Отлично!
Я повторил шаги в системе CI, и... по-прежнему безрезультатно.
Хорошо, давайте копнем глубже. Сообщение об ошибке не помогло, поэтому я добавил «RUST_LOG=debug» перед командой и изменил команду на «обновление груза». К моему удивлению, лог оказался таким же (как упоминалось ранее) без какой-либо дополнительной информации. Похоже, что параметр отладки недоступен для команды «обновить».
И тут я вспомнил. Я уже исправлял аналогичную проблему с Cargo на этом Gitlab CI. Это было связано с кэшем Cargo (иногда Cargo может барахлить и не видеть новые ящики, если кэш поврежден). Одна из проблем GitHub предложила удалить каталог ~/.cargo (что я сделал локально). Однако на стороне Gitlab также был CI-кеш, поэтому мне пришлось его очистить и временно отключить.
Шаблон Gitlab с кешем:
.rust_build_cache:
cache:
key: "$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME"
paths:
- $CARGO_HOME/registry
Я также нажал кнопку Очистить кэш Runners на странице проекта Gitlab CI.
Я пытался запускать задание непрерывной интеграции снова и снова... безуспешно.
Я провел около часа, прыгая с одной вкладки браузера на другую, читая проблемы, экспериментируя локально и чувствуя себя разочарованным, пока не узнал, что вы можете установить переменные среды для переопределения реестра в файлах конфигурации. Эти переменные называются:
CARGO_REGISTRY_NAME
CARGO_REGISTRIES_MY_CARGO_REGISTRY_INDEX
И они были указаны в нашем старом пользовательском реестре.
Наконец-то я нашел корень проблемы. CI использовал старые переменные реестра, которые указывали на наш собственный реестр. Сначала я их пропустил, потому что они были не в файле gitlab-ci.yaml
, а в настройках CI/CD на веб-странице переменных проекта. Их установил разработчик, поэтому я не знал, что они могут перезаписать мои изменения. Это было и очевидно, и одновременно неприятно осознавать.
Простая мораль этой истории: всегда сначала проверяйте переменные среды в настройках CI. Они могут перезаписать ваши конфигурации и вызвать непредвиденные проблемы.
Главное изображение источник.
Оригинал