# ============================================================================= # AnsibleTemplate - Универсальная система тестирования Ansible ролей # Автор: Сергей Антропов # Сайт: https://devops.org.ru # ============================================================================= SHELL := /bin/bash # ============================================================================= # ПЕРЕМЕННЫЕ # ============================================================================= # Цвета для вывода RED := \033[0;31m GREEN := \033[0;32m YELLOW := \033[0;33m BLUE := \033[0;34m PURPLE := \033[0;35m CYAN := \033[0;36m WHITE := \033[0;37m RESET := \033[0m # Глобальные переменные PROJECT_NAME ?= ansible-template VERSION ?= 0.1.0 AUTHOR ?= "Сергей Антропов" SITE ?= "https://devops.org.ru" DOCKER_IMAGE ?= inecs/ansible-controller:latest DOCKER_DIND_IMAGE ?= docker:27-dind CONTAINER_NAME ?= ansible-controller # Переменные для Docker Hub DOCKER_REGISTRY ?= inecs/ansible-lab DOCKER_VERSION ?= latest DOCKER_IMAGES := ansible-controller alt-linux astra-linux redos rhel centos alma rocky # Multi-arch поддержка DOCKER_PLATFORMS ?= linux/amd64,linux/arm64 DOCKER_BUILDX_BUILDER ?= multiarch-builder # Базовые образы и их теги BASE_IMAGES := altlinux/p9 astralinux/astra-1.7 redos/redos:9 registry.access.redhat.com/ubi8/ubi quay.io/centos/centos:stream9 almalinux:8 rockylinux:8 .PHONY: role vault git docker presets controller help # ============================================================================= # КОМАНДЫ ДЛЯ РАБОТЫ С РОЛЯМИ # ============================================================================= role: @case "$(word 2, $(MAKECMDGOALS))" in \ lint) \ echo "🔍 Проверка синтаксиса ролей ..."; \ docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace -e ANSIBLE_FORCE_COLOR=1 $(DOCKER_IMAGE) bash -c "ansible-lint roles/ --config-file .ansible-lint || true"; \ echo "✅ Lint завершен";; \ test) \ echo "🚀 Тестирование ролей ..."; \ PRESET="default"; \ ARGS="$(wordlist 3,10,$(MAKECMDGOALS))"; \ if [ -n "$$ARGS" ]; then \ PRESET="$$(echo $$ARGS | cut -d' ' -f1)"; \ fi; \ echo "📋 Используется пресет: $$PRESET"; \ if [ ! -f "molecule/presets/$$PRESET.yml" ]; then \ echo "❌ Ошибка: Пресет '$$PRESET' не найден!"; \ echo "💡 Доступные пресеты:"; \ ls -1 molecule/presets/*.yml 2>/dev/null | sed 's|molecule/presets/||g' | sed 's|\.yml||g' | sed 's/^/ - /' || echo " ⚠️ Пресеты не найдены"; \ exit 1; \ fi; \ echo ""; \ if [ "$$PRESET" = "standart" ]; then \ ./scripts/test-standart.sh; \ else \ docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \ -v /var/run/docker.sock:/var/run/docker.sock \ -e ANSIBLE_FORCE_COLOR=1 \ -e MOLECULE_PRESET=$$PRESET \ $(DOCKER_IMAGE) \ bash -c "cd molecule/default && ansible-playbook -i localhost, create.yml --connection=local && ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini site.yml && ansible-playbook -i localhost, destroy.yml --connection=local" || echo "✅ Тестирование завершено"; \ fi;; \ deploy) \ echo "🚀 Развертывание ролей на реальные серверы..."; \ echo ""; \ if [ ! -f "inventory/hosts.ini" ]; then \ echo "❌ Ошибка: Файл inventory/hosts.ini не найден!"; \ echo "💡 Создайте файл inventory/hosts.ini с вашими серверами"; \ exit 1; \ fi; \ echo "📋 Используется inventory: inventory/hosts.ini"; \ echo "📄 Содержимое inventory:"; \ cat inventory/hosts.ini; \ echo ""; \ echo "🚀 Запуск развертывания..."; \ ansible-playbook -i inventory/hosts.ini deploy.yml --check; \ echo ""; \ read -p "Продолжить развертывание? (y/N): " confirm; \ if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \ ansible-playbook -i inventory/hosts.ini deploy.yml; \ else \ echo "❌ Развертывание отменено"; \ fi;; \ *) \ echo "🎯 Доступные команды:"; \ echo ""; \ echo " 🚀 make role test [preset] - протестировать роли с preset'ом"; \ echo " 💡 Примеры:"; \ echo " make role test # с default preset"; \ echo " make role test minimal # с minimal preset"; \ echo " make role test etcd-patroni # с etcd-patroni preset"; \ echo ""; \ echo " 🚀 make role deploy - развернуть роли на реальные серверы"; \ echo " 💡 Требует: inventory/hosts.ini"; \ echo ""; \ echo " 🔍 make role lint - проверить синтаксис ролей"; \ echo " 💡 Использует: ansible-lint";; \ esac # ============================================================================= # КОМАНДЫ ДЛЯ РАБОТЫ С PRESET'АМИ # ============================================================================= presets: @case "$(word 2, $(MAKECMDGOALS))" in \ list) \ echo "📋 Доступные пресеты:"; \ echo ""; \ preset_count=0; \ for preset in molecule/presets/*.yml; do \ if [ -f "$$preset" ]; then \ preset_name=$$(basename "$$preset" .yml); \ preset_desc=$$(grep -E "^#description:" "$$preset" | head -1 | sed 's/^#description: *//' || echo "Описание отсутствует"); \ host_count=$$(grep -c "^- name:" "$$preset" 2>/dev/null || echo "?"); \ printf " 📄 %s - %s (%s хостов)\n" "$$preset_name" "$$preset_desc" "$$host_count"; \ preset_count=$$((preset_count + 1)); \ fi; \ done; \ if [ $$preset_count -eq 0 ]; then \ echo " ⚠️ Пресеты не найдены"; \ fi;; \ info) \ if [ -z "$(PRESET)" ]; then \ echo "❌ Ошибка: Укажите PRESET=имя_пресета"; \ echo "💡 Пример: make presets info PRESET=etcd-patroni"; \ exit 1; \ fi; \ if [ ! -f "molecule/presets/$(PRESET).yml" ]; then \ echo "❌ Ошибка: Пресет '$(PRESET)' не найден!"; \ echo "💡 Доступные пресеты:"; \ make presets list; \ exit 1; \ fi; \ echo "📋 Информация о пресете: $(PRESET)"; \ echo ""; \ echo "📄 Описание:"; \ grep -E "^#description:" "molecule/presets/$(PRESET).yml" | head -1 | sed 's/^#description: *//' || echo "Описание отсутствует"; \ echo ""; \ echo "🏠 Хосты:"; \ grep -E "^- name:" "molecule/presets/$(PRESET).yml" | sed 's/^- name: / - /' || echo "Хосты не найдены"; \ echo ""; \ echo "🌐 Сеть:"; \ grep -E "^docker_network:" "molecule/presets/$(PRESET).yml" | sed 's/^docker_network: / - /' || echo "Сеть не указана"; \ echo ""; \ echo "🐳 Образы:"; \ grep -E "^- " "molecule/presets/$(PRESET).yml" | grep -E "family:" | sed 's/.*family: / - /' || echo "Образы не найдены";; \ test) \ if [ -z "$(PRESET)" ]; then \ echo "❌ Ошибка: Укажите PRESET=имя_пресета"; \ echo "💡 Пример: make presets test PRESET=etcd-patroni"; \ exit 1; \ fi; \ if [ ! -f "molecule/presets/$(PRESET).yml" ]; then \ echo "❌ Ошибка: Пресет '$(PRESET)' не найден!"; \ echo "💡 Доступные пресеты:"; \ make presets list; \ exit 1; \ fi; \ echo "🚀 Тестирование с пресетом: $(PRESET)"; \ echo ""; \ docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \ -v /var/run/docker.sock:/var/run/docker.sock \ -e ANSIBLE_FORCE_COLOR=1 \ -e MOLECULE_PRESET=$(PRESET) \ $(DOCKER_IMAGE) \ bash -c "cd molecule/default && molecule test" || echo "✅ Тестирование завершено";; \ *) \ echo "🎯 Доступные команды:"; \ echo ""; \ echo " 📋 make presets list - показать список всех preset'ов"; \ echo " 💡 Показывает: название, описание, количество хостов"; \ echo ""; \ echo " 📄 make presets info - подробная информация о preset'е"; \ echo " 💡 Показывает: описание, хосты, сеть, образы"; \ echo " 💡 Требует: PRESET=имя_пресета"; \ echo ""; \ echo " 🚀 make presets test - запустить тест с preset'ом"; \ echo " 💡 Запускает: molecule test с выбранным preset'ом"; \ echo " 💡 Требует: PRESET=имя_пресета"; \ echo ""; \ echo "💡 Примеры:"; \ echo " make presets list # показать все preset'ы"; \ echo " make presets info PRESET=etcd-patroni # информация о etcd-patroni"; \ echo " make presets test PRESET=minimal # тест с minimal preset"; \ echo " make presets test PRESET=performance # тест с performance preset";; \ esac # ============================================================================= # КОМАНДЫ ДЛЯ РАБОТЫ С VAULT # ============================================================================= vault: @case "$(word 2, $(MAKECMDGOALS))" in \ create) \ echo "🔐 Создание файла секретов..."; \ read -p "Введите имя файла (без .yml): " FILE; \ docker run --rm -it -v "$(PWD):/workspace" -w /workspace \ quay.io/ansible/creator-ee:latest \ ansible-vault create --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \ edit) \ echo "🔐 Редактирование секретов..."; \ ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \ echo ""; \ read -p "Введите имя файла (без .yml): " FILE; \ docker run --rm -it -v "$(PWD):/workspace" -w /workspace \ quay.io/ansible/creator-ee:latest \ ansible-vault edit --vault-password-file vault/.vault vault/$$FILE.yml;; \ show) \ echo "🔐 Просмотр секретов..."; \ ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \ echo ""; \ read -p "Введите имя файла (без .yml): " FILE; \ docker run --rm -v "$(PWD):/workspace" -w /workspace \ quay.io/ansible/creator-ee:latest \ ansible-vault view --vault-password-file vault/.vault vault/$$FILE.yml;; \ delete) \ echo "🔐 Удаление секретов..."; \ ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \ echo ""; \ read -p "Введите имя файла (без .yml): " FILE; \ rm -f vault/$$FILE.yml;; \ encrypt) \ echo "🔐 Шифрование файла..."; \ ls -la vault/*.yml 2>/dev/null || echo "Нет файлов для шифрования"; \ echo ""; \ read -p "Введите имя файла (без .yml): " FILE; \ docker run --rm -v "$(PWD):/workspace" -w /workspace \ quay.io/ansible/creator-ee:latest \ ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \ decrypt) \ echo "🔐 Расшифровка файла..."; \ ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \ echo ""; \ read -p "Введите имя файла (без .yml): " FILE; \ docker run --rm -v "$(PWD):/workspace" -w /workspace \ quay.io/ansible/creator-ee:latest \ ansible-vault decrypt --vault-password-file vault/.vault vault/$$FILE.yml;; \ rekey) \ echo "🔐 Смена пароля..."; \ ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \ echo ""; \ read -p "Введите имя файла (без .yml): " FILE; \ docker run --rm -it -v "$(PWD):/workspace" -w /workspace \ quay.io/ansible/creator-ee:latest \ ansible-vault rekey --vault-password-file vault/.vault vault/$$FILE.yml;; \ check) \ echo "🔍 Проверка vault файлов..."; \ if [ ! -d "vault" ]; then \ echo "❌ Директория vault не найдена"; \ exit 1; \ fi; \ vault_files=$$(find vault -name "*.yml" -type f 2>/dev/null); \ if [ -z "$$vault_files" ]; then \ echo "⚠️ Vault файлы не найдены"; \ exit 0; \ fi; \ echo "📋 Найденные vault файлы:"; \ for file in $$vault_files; do \ echo " 📄 $$file"; \ done; \ echo ""; \ echo "🔍 Проверка структуры..."; \ for file in $$vault_files; do \ if grep -q "ANSIBLE_VAULT" "$$file"; then \ echo " ✅ $$file - зашифрован"; \ else \ echo " ⚠️ $$file - не зашифрован"; \ fi; \ done;; \ scan) \ echo "🔍 Поиск секретов в проекте..."; \ echo "📋 Поиск потенциальных секретов:"; \ find . -name "*.yml" -o -name "*.yaml" | grep -v ".git" | while read file; do \ if grep -qE "(password|secret|key|token|api_key)" "$$file" 2>/dev/null; then \ echo " ⚠️ $$file - содержит потенциальные секреты"; \ fi; \ done; \ echo ""; \ echo "💡 Рекомендации:"; \ echo " - Используйте ansible-vault для шифрования секретов"; \ echo " - Не храните секреты в открытом виде"; \ echo " - Регулярно проверяйте файлы на наличие секретов";; \ *) \ echo "🎯 Доступные команды:"; \ echo ""; \ echo " 🔐 make vault create - создать новый файл секретов"; \ echo " 💡 Интерактивное создание зашифрованного файла"; \ echo ""; \ echo " ✏️ make vault edit - редактировать существующие секреты"; \ echo " 💡 Открывает редактор для изменения секретов"; \ echo ""; \ echo " 👁️ make vault show - показать содержимое секретов"; \ echo " 💡 Расшифровывает и показывает содержимое"; \ echo ""; \ echo " 🗑️ make vault delete - удалить файл секретов"; \ echo " 💡 Безвозвратное удаление файла"; \ echo ""; \ echo " 🔒 make vault encrypt - зашифровать существующий файл"; \ echo " 💡 Шифрует незашифрованный файл"; \ echo ""; \ echo " 🔓 make vault decrypt - расшифровать файл"; \ echo " 💡 Создает незашифрованную копию"; \ echo ""; \ echo " 🔑 make vault rekey - сменить пароль шифрования"; \ echo " 💡 Изменяет пароль для существующего файла"; \ echo ""; \ echo " ✅ make vault check - проверить vault файлы"; \ echo " 💡 Проверяет структуру и статус файлов"; \ echo ""; \ echo " 🔍 make vault scan - поиск потенциальных секретов"; \ echo " 💡 Сканирует проект на наличие незашифрованных секретов";; \ esac # ============================================================================= # КОМАНДЫ ДЛЯ РАБОТЫ С GIT # ============================================================================= git: @case "$(word 2, $(MAKECMDGOALS))" in \ push) \ echo "📤 Отправка изменений в репозиторий..."; \ git add .; \ git commit -m "Обновление проекта"; \ git push origin main;; \ pull) \ echo "📥 Получение изменений из репозитория..."; \ git pull origin main;; \ new) \ echo "🌿 Создание новой ветки..."; \ read -p "Введите имя ветки: " BRANCH; \ git checkout -b "$$BRANCH"; \ echo "✅ Ветка '$$BRANCH' создана";; \ *) \ echo "🎯 Доступные команды:"; \ echo ""; \ echo " 📤 make git push - отправить изменения в репозиторий"; \ echo " 💡 Выполняет: git add . && git commit && git push"; \ echo ""; \ echo " 📥 make git pull - получить изменения из репозитория"; \ echo " 💡 Выполняет: git pull origin main"; \ echo ""; \ echo " 🌿 make git new - создать новую ветку"; \ echo " 💡 Интерактивно запрашивает имя ветки"; \ echo " 💡 Выполняет: git checkout -b имя_ветки";; \ esac # ============================================================================= # КОМАНДЫ ДЛЯ РАБОТЫ С DOCKER # ============================================================================= docker: @case "$(word 2, $(MAKECMDGOALS))" in \ prepare) \ echo "🔧 Подготовка Docker образов для Docker Hub..."; \ echo "📋 Registry: $(DOCKER_REGISTRY)"; \ echo "📋 Version: $(DOCKER_VERSION)"; \ echo "📋 Images: $(DOCKER_IMAGES)"; \ echo ""; \ echo "💡 Для работы с Docker Hub выполните:"; \ echo " docker login - авторизация в Docker Hub"; \ echo " make docker build - сборка образов"; \ echo " make docker push - отправка в Docker Hub";; \ build) \ echo "🐳 Сборка Docker образов (multi-arch)..."; \ echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \ echo "📋 Builder: $(DOCKER_BUILDX_BUILDER)"; \ echo "📋 Registry: $(DOCKER_REGISTRY)"; \ echo "📋 Version: $(DOCKER_VERSION)"; \ echo "📋 Images: $(DOCKER_IMAGES)"; \ echo ""; \ $(MAKE) docker setup-builder; \ for image in $(DOCKER_IMAGES); do \ echo "🔨 Сборка $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \ $(MAKE) docker-build-image IMAGE=$$image; \ done; \ echo "✅ Образы собраны";; \ rebuild) \ echo "🔄 Полная пересборка Docker образов (multi-arch)..."; \ echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \ echo "📋 Builder: $(DOCKER_BUILDX_BUILDER)"; \ echo "📋 Registry: $(DOCKER_REGISTRY)"; \ echo "📋 Version: $(DOCKER_VERSION)"; \ echo "📋 Images: $(DOCKER_IMAGES)"; \ echo "🧹 Очистка кеша и старых образов..."; \ echo ""; \ $(MAKE) docker clean; \ $(MAKE) docker clean-builder; \ $(MAKE) docker setup-builder; \ for image in $(DOCKER_IMAGES); do \ echo "🔨 Пересборка $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \ $(MAKE) docker-build-image IMAGE=$$image; \ done; \ echo "✅ Образы пересобраны с нуля";; \ push) \ echo "📤 Отправка Docker образов в Docker Hub..."; \ for image in $(DOCKER_IMAGES); do \ echo "📤 Отправка $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \ docker push $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION); \ done; \ echo "✅ Образы отправлены в Docker Hub";; \ pull) \ echo "📥 Загрузка Docker образов из Docker Hub..."; \ for image in $(DOCKER_IMAGES); do \ echo "📥 Загрузка $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \ docker pull $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION) || echo "⚠️ Образ $$image не найден в Docker Hub"; \ done; \ echo "✅ Загрузка завершена";; \ clean) \ echo "🧹 Очистка Docker образов и builds..."; \ for image in $(DOCKER_IMAGES); do \ echo "🗑️ Удаление $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \ docker rmi $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION) 2>/dev/null || true; \ done; \ echo "🗑️ Удаление кеша builds для наших образов..."; \ docker buildx prune --filter type=exec.cachemount --filter type=source.local --filter type=source.git.checkout --force 2>/dev/null || true; \ echo "✅ Образы и кеш builds очищены";; \ info) \ echo "📊 Информация об образах..."; \ for image in $(DOCKER_IMAGES); do \ if docker images | grep -q "$(DOCKER_REGISTRY):$$image"; then \ echo "📦 $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \ docker images | grep "$(DOCKER_REGISTRY):$$image" | head -1; \ fi; \ done;; \ update) \ echo "🔄 Обновление всех образов..."; \ $(MAKE) docker pull; \ $(MAKE) docker build; \ $(MAKE) docker push; \ echo "✅ Все образы обновлены";; \ purge) \ echo "🧹 Полная очистка Docker..."; \ echo "⚠️ ВНИМАНИЕ: Это удалит ВСЕ Docker данные!"; \ echo ""; \ read -p "Продолжить? (y/N): " confirm; \ if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \ echo "🛑 Остановка всех контейнеров..."; \ docker stop $$(docker ps -aq) 2>/dev/null || true; \ echo "🗑️ Удаление всех контейнеров..."; \ docker rm $$(docker ps -aq) 2>/dev/null || true; \ echo "🗑️ Удаление всех образов..."; \ docker rmi $$(docker images -aq) 2>/dev/null || true; \ echo "🗑️ Удаление всех томов..."; \ docker volume rm $$(docker volume ls -q) 2>/dev/null || true; \ echo "🗑️ Удаление всех сетей..."; \ docker network rm $$(docker network ls -q) 2>/dev/null || true; \ echo "🧹 Очистка системы..."; \ docker system prune -af --volumes; \ echo "✅ Docker полностью очищен"; \ else \ echo "❌ Очистка отменена"; \ fi;; \ clean-builder) \ echo "🧹 Очистка multi-arch builder..."; \ $(MAKE) docker-reset-builder;; \ setup-builder) \ echo "🔧 Настройка multi-arch builder в контейнере..."; \ if $(MAKE) docker-check-builder >/dev/null 2>&1; then \ echo "✅ Builder $(DOCKER_BUILDX_BUILDER) уже существует и готов"; \ docker buildx use $(DOCKER_BUILDX_BUILDER); \ else \ echo "📦 Создание builder $(DOCKER_BUILDX_BUILDER)..."; \ $(MAKE) docker-create-builder; \ fi; \ echo "🔍 Финальная проверка builder..."; \ $(MAKE) docker-check-builder;; \ diagnose) \ echo "🔍 Диагностика buildx проблем..."; \ $(MAKE) docker-diagnose-buildx;; \ reset-builder) \ echo "🔄 Сброс buildx builder..."; \ $(MAKE) docker-reset-builder;; \ *) \ echo "🎯 Доступные команды:"; \ echo ""; \ echo " 🔧 make docker prepare - подготовка к работе с Docker Hub"; \ echo " 💡 Показывает: registry, version, список образов"; \ echo " 💡 Рекомендует: docker login перед работой"; \ echo ""; \ echo " 🐳 make docker build - собрать все Docker образы (multi-arch)"; \ echo " 💡 Собирает: ansible-controller, alt-linux, astra-linux, redos"; \ echo " 💡 Собирает: rhel, centos, alma, rocky"; \ echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \ echo " 💡 Тегирует: inecs/образ: (автоматически извлекает теги)"; \ echo " 💡 Отправляет: автоматически в Docker Hub"; \ echo ""; \ echo " 🔄 make docker rebuild - полная пересборка с очисткой кеша"; \ echo " 💡 Очищает: все локальные образы и кеш"; \ echo " 💡 Пересобирает: все образы с нуля"; \ echo " 💡 Полезно: при проблемах с кешем или зависимостями"; \ echo " 💡 Выполняет: clean + clean-builder + setup-builder + build"; \ echo ""; \ echo " 📤 make docker push - отправить образы в Docker Hub"; \ echo " 💡 Требует: docker login"; \ echo " 💡 Отправляет: все образы в registry inecs"; \ echo ""; \ echo " 📥 make docker pull - загрузить образы из Docker Hub"; \ echo " 💡 Загружает: все образы из registry inecs"; \ echo " 💡 Пропускает: отсутствующие образы"; \ echo ""; \ echo " 🧹 make docker clean - удалить локальные образы и кеш builds"; \ echo " 💡 Удаляет: все образы inecs/ansible-lab:*"; \ echo " 💡 Очищает: кеш builds (exec.cachemount, source.local, git.checkout)"; \ echo " 💡 Сохраняет: другие builds в системе"; \ echo " 💡 Безопасно: игнорирует ошибки"; \ echo ""; \ echo " 🧹 make docker clean-builder - очистка multi-arch builder"; \ <<<<<<< HEAD echo " 💡 Удаляет: builder контейнер и buildkit контейнеры"; \ echo " 💡 Полезно: при проблемах со сборкой"; \ ======= echo " 💡 Удаляет: builder контейнер принудительно"; \ echo " 💡 Очищает: весь кеш builds"; \ echo " 💡 Быстро: принудительное удаление без ожидания"; \ >>>>>>> 3caa0078e13b03c603a1af10bd1bdbdf1509e645 echo ""; \ echo " 🔧 make docker setup-builder - настройка multi-arch builder"; \ echo " 💡 Создает: builder в контейнере (не в системе)"; \ echo " 💡 Поддерживает: amd64 и arm64 архитектуры"; \ echo " 💡 Безопасно: использует inspect вместо buildx ls"; \ echo ""; \ echo " 🔍 make docker diagnose - диагностика buildx проблем"; \ echo " 💡 Проверяет: версии, контексты, builder, registry"; \ echo " 💡 Показывает: рекомендации по устранению проблем"; \ echo ""; \ echo " 🔄 make docker reset-builder - сброс buildx builder"; \ echo " 💡 Удаляет: старый builder и buildkit контейнеры"; \ echo " 💡 Создает: новый builder с предварительной загрузкой образа"; \ echo ""; \ echo " 📊 make docker info - информация о собранных образах"; \ echo " 💡 Показывает: размер, дата создания, теги"; \ echo ""; \ echo " 🔄 make docker update - обновить все образы"; \ echo " 💡 Выполняет: pull + build + push"; \ echo " 💡 Полный цикл обновления"; \ echo ""; \ echo " 💥 make docker purge - ПОЛНАЯ очистка Docker"; \ echo " ⚠️ УДАЛЯЕТ: все контейнеры, образы, тома, сети"; \ echo " ⚠️ ОСТАНОВИТ: все запущенные контейнеры"; \ echo " ⚠️ ТРЕБУЕТ: подтверждение пользователя"; \ echo "";; \ esac # ============================================================================= # ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ДЛЯ DOCKER # ============================================================================= # Надежная проверка существования buildx builder без использования buildx ls # Использует docker buildx inspect вместо buildx ls для избежания зависаний .PHONY: docker-check-builder docker-check-builder: @echo "🔍 Проверка buildx builder $(DOCKER_BUILDX_BUILDER)..." @if docker buildx inspect $(DOCKER_BUILDX_BUILDER) >/dev/null 2>&1; then \ echo "✅ Builder $(DOCKER_BUILDX_BUILDER) существует и готов"; \ exit 0; \ else \ echo "❌ Builder $(DOCKER_BUILDX_BUILDER) не найден"; \ exit 1; \ fi # Безопасное создание buildx builder с предварительной очисткой .PHONY: docker-create-builder docker-create-builder: @echo "🔧 Создание buildx builder $(DOCKER_BUILDX_BUILDER)..." @echo "📦 Предварительная загрузка образа buildkit..." @docker pull moby/buildkit:buildx-stable-1 || echo "⚠️ Не удалось загрузить moby/buildkit:buildx-stable-1, будет использован авто-пулл" @echo "🗑️ Удаление существующего builder (если есть)..." @docker buildx rm -f $(DOCKER_BUILDX_BUILDER) 2>/dev/null || true @echo "📦 Создание нового builder..." @docker buildx create \ --name $(DOCKER_BUILDX_BUILDER) \ --driver docker-container \ --driver-opt image=moby/buildkit:buildx-stable-1 \ --use || exit 1 @echo "⏳ Ожидание запуска buildkit контейнера..." @sleep 3 @echo "🔍 Проверка готовности builder..." @docker buildx inspect --builder $(DOCKER_BUILDX_BUILDER) --bootstrap >/dev/null || exit 1 @echo "✅ Builder $(DOCKER_BUILDX_BUILDER) создан и готов к работе" # Диагностика проблем с buildx .PHONY: docker-diagnose-buildx docker-diagnose-buildx: @echo "🔍 ДИАГНОСТИКА BUILDX ПРОБЛЕМ" @echo "==========================================" @echo "" @echo "📊 1. Версии Docker и Buildx:" @docker version --format "Docker: {{.Server.Version}}" 2>/dev/null || echo "❌ Docker недоступен" @docker buildx version 2>/dev/null || echo "❌ Buildx недоступен" @echo "" @echo "📋 2. Docker контексты (поиск мертвых tcp://):" @docker context ls 2>/dev/null || echo "❌ Не удалось получить список контекстов" @echo "" @echo "🔍 3. Проверка builder $(DOCKER_BUILDX_BUILDER):" @if docker buildx inspect $(DOCKER_BUILDX_BUILDER) >/dev/null 2>&1; then \ echo "✅ Builder $(DOCKER_BUILDX_BUILDER) существует"; \ docker buildx inspect $(DOCKER_BUILDX_BUILDER) --bootstrap >/dev/null 2>&1 && echo "✅ Builder готов" || echo "❌ Builder не готов"; \ else \ echo "❌ Builder $(DOCKER_BUILDX_BUILDER) не найден"; \ fi @echo "" @echo "🐳 4. Buildkit контейнеры:" @docker ps -a --filter "name=buildx_buildkit" --format "table {{.Names}}\t{{.Status}}\t{{.CreatedAt}}" 2>/dev/null || echo "❌ Не удалось получить список контейнеров" @echo "" @echo "🌐 5. Проверка доступа к registry:" @echo "📥 Тест загрузки moby/buildkit:buildx-stable-1..." @timeout 30 docker pull moby/buildkit:buildx-stable-1 >/dev/null 2>&1 && echo "✅ Доступ к registry OK" || echo "❌ Проблемы с доступом к registry" @echo "" @echo "🔧 6. Docker socket доступ:" @if [ -S /var/run/docker.sock ]; then \ echo "✅ Docker socket доступен: /var/run/docker.sock"; \ ls -la /var/run/docker.sock; \ else \ echo "❌ Docker socket недоступен: /var/run/docker.sock"; \ fi @echo "" @echo "💡 РЕКОМЕНДАЦИИ:" @echo " - Если buildx ls зависает: удалите мертвые контексты (docker context rm )" @echo " - Если pull зависает: настройте прокси или используйте mirror registry" @echo " - Если builder не создается: проверьте права доступа к Docker socket" @echo " - Для полной очистки: make docker clean-builder && make docker-create-builder" # Быстрая очистка и пересоздание builder .PHONY: docker-reset-builder docker-reset-builder: @echo "🔄 Сброс buildx builder..." @echo "🗑️ Удаление builder $(DOCKER_BUILDX_BUILDER)..." @docker buildx rm -f $(DOCKER_BUILDX_BUILDER) 2>/dev/null || true @echo "🧹 Очистка buildkit контейнеров..." @docker ps -a --filter "name=buildx_buildkit" --format "{{.Names}}" | xargs -r docker rm -f 2>/dev/null || true @echo "📦 Создание нового builder..." @$(MAKE) docker-create-builder @echo "✅ Builder сброшен и готов к работе" # Извлечение тега из базового образа docker-get-base-tag: @if [ -z "$(IMAGE)" ]; then \ echo "❌ Ошибка: IMAGE не указан"; \ exit 1; \ fi; \ case "$(IMAGE)" in \ alt-linux) \ BASE_IMAGE="altlinux/p9"; \ TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \ astra-linux) \ BASE_IMAGE="astralinux/astra-1.7"; \ TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \ redos) \ BASE_IMAGE="redos/redos:9"; \ TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \ rhel) \ BASE_IMAGE="registry.access.redhat.com/ubi8/ubi"; \ TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \ centos) \ BASE_IMAGE="quay.io/centos/centos:stream9"; \ TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \ alma) \ BASE_IMAGE="almalinux:8"; \ TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \ rocky) \ BASE_IMAGE="rockylinux:8"; \ TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \ ansible-controller) \ TAG="latest";; \ *) \ echo "❌ Неизвестный образ: $(IMAGE)"; \ exit 1;; \ esac; \ echo "$$TAG" # Сборка одного образа с multi-arch docker-build-image: @if [ -z "$(IMAGE)" ]; then \ echo "❌ Ошибка: IMAGE не указан"; \ exit 1; \ fi; \ TAG=$$($(MAKE) docker-get-base-tag IMAGE=$(IMAGE)); \ echo ""; \ echo "=========================================="; \ echo "🔨 СБОРКА ОБРАЗА: $(DOCKER_REGISTRY):$(IMAGE)-$$TAG"; \ echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \ echo "📋 Тег: $$TAG"; \ echo "📋 Registry: $(DOCKER_REGISTRY)"; \ echo "=========================================="; \ echo ""; \ cd dockerfiles/$(IMAGE) && \ docker buildx build \ --platform $(DOCKER_PLATFORMS) \ --tag $(DOCKER_REGISTRY):$(IMAGE)-$$TAG \ --tag $(DOCKER_REGISTRY):$(IMAGE)-latest \ --push \ .; \ echo ""; \ echo "✅ УСПЕШНО: $(DOCKER_REGISTRY):$(IMAGE)-$$TAG собран и отправлен"; \ echo "==========================================" # ============================================================================= # КОМАНДЫ ДЛЯ РАБОТЫ С ANSIBLE-CONTROLLER # ============================================================================= controller: @case "$(word 2, $(MAKECMDGOALS))" in \ build) \ echo "🔨 Сборка ansible-controller (multi-arch)..."; \ echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \ $(MAKE) docker setup-builder; \ cd dockerfiles/ansible-controller && \ docker buildx build \ --platform $(DOCKER_PLATFORMS) \ --tag $(DOCKER_REGISTRY)/ansible-controller:$(DOCKER_VERSION) \ --push \ .; \ echo "✅ ansible-controller собран и отправлен";; \ run) \ echo "🚀 Запуск ansible-controller..."; \ cd dockerfiles/ansible-controller && docker-compose up -d; \ echo "✅ ansible-controller запущен";; \ stop) \ echo "🛑 Остановка ansible-controller..."; \ cd dockerfiles/ansible-controller && docker-compose down; \ echo "✅ ansible-controller остановлен";; \ *) \ echo "🎯 Доступные команды:"; \ echo ""; \ echo " 🔨 make controller build - собрать ansible-controller (multi-arch)"; \ echo " 💡 Собирает: inecs/ansible-controller:latest"; \ echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \ echo " 💡 Использует: dockerfiles/ansible-controller/Dockerfile"; \ echo " 💡 Requirements: dockerfiles/ansible-controller/requirements.yml"; \ echo ""; \ echo " 🚀 make controller run - запустить ansible-controller"; \ echo " 💡 Запускает: docker-compose up -d"; \ echo " 💡 Использует: dockerfiles/ansible-controller/docker-compose.yml"; \ echo ""; \ echo " 🛑 make controller stop - остановить ansible-controller"; \ echo " 💡 Останавливает: docker-compose down"; \ echo " 💡 Удаляет: контейнеры и сети";; \ esac # ============================================================================= # СПРАВКА # ============================================================================= help: @echo "==========================================" @echo "AnsibleTemplate - Универсальная система" @echo "тестирования Ansible ролей" @echo "==========================================" @echo "" @echo "📁 Структура проекта:" @echo " scripts/ - Скрипты автоматизации" @echo " inventory/ - Инвентори файлы" @echo " molecule/default/ - Molecule конфигурация" @echo " roles/ - Ansible роли" @echo " vault/ - Зашифрованные секреты" @echo " dockerfiles/ - Docker образы для тестирования" @echo "" @echo "🚀 ОСНОВНЫЕ КОМАНДЫ:" @echo " make role lint - проверить синтаксис ролей" @echo " make role test [preset] - протестировать роли с preset'ом" @echo " make role deploy - развернуть роли на реальные серверы" @echo "" @echo "📋 PRESET'Ы (тестовые окружения):" @echo " make presets list - показать все доступные preset'ы" @echo " make presets info - подробная информация о preset'е" @echo " make presets test - запустить тест с preset'ом" @echo "" @echo "🐳 DOCKER ОБРАЗЫ (Multi-Arch):" @echo " make docker prepare - подготовка к работе с Docker Hub" @echo " make docker build - собрать все Docker образы (amd64 + arm64)" @echo " make docker rebuild - полная пересборка с очисткой кеша" @echo " make docker push - отправить образы в Docker Hub" @echo " make docker pull - загрузить образы из Docker Hub" @echo " make docker clean - удалить локальные образы" @echo " make docker info - информация о собранных образах" @echo " make docker update - обновить все образы (pull + build + push)" @echo " make docker purge - ПОЛНАЯ очистка Docker (ОСТОРОЖНО!)" @echo "" @echo "🔧 DOCKER BUILDER (Multi-Arch):" @echo " make docker setup-builder - настройка multi-arch builder в контейнере" @echo " make docker clean-builder - очистка multi-arch builder" @echo " make docker diagnose - диагностика buildx проблем" @echo " make docker reset-builder - сброс buildx builder" @echo " 💡 Поддерживает: amd64, arm64, riscv64, ppc64le, s390x, 386, arm/v7, arm/v6" @echo " 💡 Безопасно: использует inspect вместо buildx ls (избегает зависаний)" @echo "" @echo "🔐 VAULT (управление секретами):" @echo " make vault create - создать новый файл секретов" @echo " make vault edit - редактировать существующие секреты" @echo " make vault show - показать содержимое секретов" @echo " make vault delete - удалить файл секретов" @echo " make vault encrypt - зашифровать файл" @echo " make vault decrypt - расшифровать файл" @echo " make vault rekey - сменить пароль шифрования" @echo " make vault check - проверить vault файлы" @echo " make vault scan - поиск потенциальных секретов" @echo "" @echo "🌿 GIT (управление версиями):" @echo " make git push - отправить изменения в репозиторий" @echo " make git pull - получить изменения из репозитория" @echo " make git new - создать новую ветку" @echo "" @echo "🎮 CONTROLLER (ansible-controller Multi-Arch):" @echo " make controller build - собрать ansible-controller (amd64 + arm64)" @echo " make controller run - запустить ansible-controller" @echo " make controller stop - остановить ansible-controller" @echo "" @echo "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:" @echo " make presets list # показать все preset'ы" @echo " make presets test PRESET=etcd-patroni # тест с etcd-patroni" @echo " make role test minimal # быстрый тест" @echo " make docker setup-builder # настройка multi-arch builder" @echo " make docker diagnose # диагностика buildx проблем" @echo " make docker reset-builder # сброс buildx builder" @echo " make docker build # собрать все образы (amd64 + arm64)" @echo " make docker rebuild # полная пересборка с очисткой кеша" @echo " make controller build # собрать ansible-controller (multi-arch)" @echo " make docker clean-builder # очистка builder'а" @echo " make docker purge # полная очистка Docker" @echo " make vault create # создать секреты" @echo "" @echo "📖 Подробная справка: make [команда]" @echo "==========================================" # Пустые цели для совместимости view create edit show delete lint deploy new advanced list info test build push pull clean prepare update run stop purge clean-builder setup-builder diagnose reset-builder: @true