Три типичных отказа пула (формулировки для согласования)
- Размываются границы подписи. Несколько пайплайнов делят один сеанс входа, «уплывает» разблокировка keychain, расходятся профили, ошибки
codesignневозможно приписать владельцу job. - Параллелизм игнорирует мьютексы каталогов. Одновременные
xcodebuildбьют в общий DerivedData, префикс Pods или каталог артефактов и оставляют индексы в полузаписанном состоянии. - Таймауты живут в «устной традиции». Потолки ожидания замка, job и меток runner расходятся, зомби держат
flock, пул замирает без явного сигнала перегрузки.
Сначала выровняйте сеансы с FAQ по изоляции SSH/VNC и правам, затем настраивайте подпись.
Изоляция SSH-сессий и разделы keychain для codesign
Раздельные пользователи SSH необходимы, но недостаточны для предсказуемой подписи на общем удалённом Mac: транспорт и POSIX не заменяют политику удостоверений.
| Измерение | SSH / изоляция сеанса | Keychain и раздел codesign |
|---|---|---|
| Основной предохранитель | Идентичность входа, владение файлами, учётные записи автоматизации без GUI. | Видимость сертификатов, доступ к закрытым ключам, привязка профиля к bundle, учётные данные нотаризации. |
| Типовой контроль | SSH-сертификаты по ролям, jump host, запрет общих приватных ключей. | Выделенные файлы keychain, хуки разблокировки только для CI, профили по средам. |
| Частая ошибка | Считать SSH достаточным, пока две сессии делят один GUI-логин. | Использовать login keychain как общее хранилище секретов команды без журнала ротации. |
Лимиты конкурентности, flock и очереди оркестратора
Скрипты shell и группы конкурентности в CI должны совпадать с доменами flock, иначе ожидания раздуваются незаметно. Правила раскладки worktree — в матрице Git worktree и lock-файлов.
| Политика | Когда подходит | Интуиция параметров |
|---|---|---|
| Строгая сериализация + flock | Один клон, общий DerivedData, глобальные установки toolchain. | Одна тяжёлая job; flock -w 30–60 для коротких мутаций; алерт при медиане ожидания очереди выше ~15 минут. |
| Ограниченный параллелизм | Изолированные worktree, раздельные песочницы сборки, мониторинг CPU и RAM. | До двух тяжёлых интеграций или двух–четырёх лёгких job при запасе; автоматически снижать при свободном диске близко к 15%. |
| Платформенная очередь | Self-hosted runner, внутренние планировщики. | Метки runner = доменам flock; потолок ожидания ~20 задач на полосу; масштабировать узлы раньше, чем поднимать целые числа в YAML. |
Матрица стратегий путей DerivedData
Политика DerivedData — это выбор конкурентности: закрепите один столбец на класс узлов пула и свяжите его с таймаутами очереди и политикой очистки диска.
| Стратегия | Сильная сторона | Заметка по конкурентности | Эксплуатационная цена |
|---|---|---|---|
| Путь Xcode по умолчанию | Нулевая настройка для ad-hoc пользователей. | Максимальный риск коллизий; считайте одним писателем, если пути не разнесены по job. | Нужна агрессивная плановая очистка. |
| Путь на репозиторий или worktree | Понятное владение для тикетов поддержки. | Две параллельные сборки возможны вместе с раздельными деревьями исходников. | Больше скриптов в CI или обёртках xcodebuild. |
| Общий read-кэш + записываемая песочница | Быстрее пересборки модулей при многих приложениях. | Нужны read-only монтирования или жёсткие права и flock вокруг писателей. | Сложнее рассуждать; нужны метрики попаданий в кэш. |
Лист параметров таймаутов очереди сборок
Держите таблицу рядом с FAQ по flock и очереди в runbook дежурства.
| Параметр | Стартовое значение | Заметки |
|---|---|---|
| Глубина очереди (pending) | около 20 задач на полосу | Быстрый отказ с явным retry вместо молчаливого хвоста. |
| Таймаут лёгкой job | 15–25 минут | Линт, небольшие юниты, проверки codegen. |
| Стандартная компиляция и тесты | 35–60 минут | От p95 репозитория плюс запас. |
| Архив и выгрузка | 45–90 минут | Включите нотаризацию и загрузку символов. |
flock -w (сек.) |
120–300 для deps, 30–60 для коротких секций | Всегда короче таймаута job; калибровка по p95 ожидания замка. |
| Алерт по медиане ожидания | > 15 минут устойчиво | Сигнал недостаточной ёмкости пула или зависших замков. |
Пять шагов внедрения политики пула
- Инвентаризация мьютексов: перечислите каждый общий корень DerivedData, кэш зависимостей, полосу Simulator и удостоверение подписи на класс узла.
- Назначение идентичностей: сопоставьте учётки автоматизации с файлами keychain, наборами профилей и ролями SSH; запретите общие GUI-сессии для CI.
- Согласование оркестрации: метки runner, группы конкурентности и пути
flockдолжны называть один и тот же ресурс. - Кодирование таймаутов: вставьте лист параметров в YAML CI, внутреннюю wiki и правила алертов с владельцами.
- Еженаблюдение: раз в неделю — перцентили ожидания, свободный диск, своп и ошибки подписи; корректируйте потолки раньше сырого роста параллелизма.
Цифры для ссылок в политиках и RFC
- Тяжёлая конкурентность Xcode на общий изменяемый корень: стартуйте с одной активной job.
- Лёгкие job: до двух, если CPU устойчиво ниже ~75%, а свободной RAM остаётся более ~8 ГБ.
- Давление по диску: приостанавливайте новые архивы при свободном месте ниже ~15% или ~40 ГБ (что больше).
- Хранение логов CI: метаданные порядка 14–30 дней, подробные логи порядка 7 дней — как отправная точка для аудита без переполнения тома.
Краткий FAQ корпоративного пула
Заменяет ли изоляция SSH разделение keychain? Нет: SSH задаёт транспорт и границы POSIX; codesign всё равно требует разнесённых удостоверений и неинтерактивных путей разблокировки.
Можно ли два archive одновременно? Только при изолированных worktree, раздельных DerivedData, проверенном запасе RAM и диска и согласованной конкурентности runner — иначе оставайтесь в серийном режиме.
Слишком длинные таймауты? Зомби фиксируют замки — ужесточайте потолки и устраняйте утечки процессов. Квоты и конфликты — в чеклисте пула.
Следующие шаги
Зафиксируйте матрицу в runbook рядом с контактами владельца пула и ссылками на мониторинг. Для выделенного железа под политики подписи и очередей откройте главную Meshmac, страницу покупки и тарифов без обязательного входа и центр помощи по SSH, VNC и базовой гигиене доступа. Полный список материалов — в разделе блога.