Files
DevOpsLab/Makefile
Sergey Antropoff 05881e8d74 podman: переход на Podman, Minikube, локальные образы и док для новичков
- Molecule: драйвер delegated, коллекция containers.podman, create/destroy/verify на Podman
- Makefile: все вызовы docker заменены на podman, сокет /run/podman/podman.sock
- Сборка образов: podman build (без buildx), buildall/buildall-image — только локально без push
- Ansible-controller: Podman в образе, docker-compose на podman compose, сокет Podman
- K8s: Kind заменён на Minikube (драйвер podman), скрипты и Makefile обновлены
- Пресеты: проверка локальных образов, без podman pull (registry запрещён)
- Документация: docs/podman.md, docs/quickstart-for-dummies.md (роли, плейбук, линт, тесты, пресеты, инвентори)
- README: ссылка на quickstart-for-dummies

Made-with: Cursor
2026-03-11 19:59:47 +03:00

1547 lines
82 KiB
Makefile
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# =============================================================================
# DevOpsLab - Универсальная система тестирования 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
# Глобальные переменные (Podman)
PROJECT_NAME ?= devops-lab
VERSION ?= 0.1.0
AUTHOR ?= "Сергей Антропов"
SITE ?= "https://devops.org.ru"
DOCKER_IMAGE ?= inecs/ansible-lab:ansible-controller-latest
DOCKER_K8S_IMAGE ?= inecs/ansible-lab:k8s-latest
CONTAINER_NAME ?= ansible-controller
EDITOR ?= nano
# Сокет Podman (rootful: /run/podman/podman.sock)
PODMAN_SOCKET ?= /run/podman/podman.sock
# Переменные для registry образов
DOCKER_REGISTRY ?= inecs/ansible-lab
DOCKER_VERSION ?= latest
DOCKER_IMAGES := ansible-controller alt9 alt10 astra-linux redos rhel centos7 centos8 centos9 alma rocky ubuntu20 ubuntu22 ubuntu24 debian9 debian10 debian11 debian12
# Multi-arch поддержка (podman build --platform)
DOCKER_PLATFORMS ?= linux/amd64,linux/arm64
# Базовые образы и их теги
BASE_IMAGES := altlinux/p9 astralinux/astra-1.7 redos/redos:9 registry.access.redhat.com/ubi8/ubi centos:7 quay.io/centos/centos:8 quay.io/centos/centos:stream9 almalinux:8 rockylinux:8 ubuntu:20.04 ubuntu:22.04 ubuntu:24.04 debian:9 debian:10 debian:11 debian:bookworm
.PHONY: role vault git docker presets controller k8s help update-playbooks generate-docs setup-cicd list create delete buildall buildall-image
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С РОЛЯМИ
# =============================================================================
role:
@case "$(word 2, $(MAKECMDGOALS))" in \
lint) \
$(MAKE) decrypt-all; \
ROLE_NAME="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$ROLE_NAME" ]; then \
echo "🔍 Проверка синтаксиса всех ролей ..."; \
podman 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"; \
else \
echo "🔍 Проверка синтаксиса роли: $$ROLE_NAME"; \
if [ -d "roles/$$ROLE_NAME" ]; then \
podman run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace -e ANSIBLE_FORCE_COLOR=1 $(DOCKER_IMAGE) bash -c "ansible-lint roles/$$ROLE_NAME/ --config-file .ansible-lint || true"; \
else \
echo "❌ Роль '$$ROLE_NAME' не найдена в roles/"; \
echo "📋 Доступные роли:"; \
ls -1 roles/ | grep -v "\.yml$$" | sed 's/^/ - /'; \
exit 1; \
fi; \
fi; \
$(MAKE) encrypt-all; \
echo ""; \
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 ""; \
$(MAKE) decrypt-all; \
echo "🔧 Запуск ansible-controller контейнера (Podman)..."; \
podman run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
-v $(PODMAN_SOCKET):/run/podman/podman.sock \
-u root \
-e ANSIBLE_FORCE_COLOR=1 \
-e CONTAINER_HOST=unix:///run/podman/podman.sock \
-e MOLECULE_PRESET=$$PRESET \
-e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule_workspace \
-e MOLECULE_VAULT_ENABLED=$${MOLECULE_VAULT_ENABLED:-false} \
$(DOCKER_IMAGE) \
bash -c " \
echo -e '\033[33m=== СОЗДАНИЕ ТЕСТОВЫХ КОНТЕЙНЕРОВ ==='; \
echo ''; \
mkdir -p /tmp/molecule_workspace/inventory && \
cd molecule/default && \
ansible-playbook -i localhost, create.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace && \
echo ''; \
echo -e '\033[33m=== НАСТРОЙКА VAULT И ПЕРЕМЕННЫХ ==='; \
echo ''; \
ansible-playbook -i localhost, converge.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace && \
echo ''; \
echo -e '\033[33m=== ПРОВЕРКА ПОДКЛЮЧЕНИЯ К КОНТЕЙНЕРАМ ==='; \
echo ''; \
ansible all -i /tmp/molecule_workspace/inventory/hosts.ini -m ping && \
echo ''; \
echo -e '\033[33m=== ЗАПУСК CONVERGE.YML НА ТЕСТОВЫХ КОНТЕЙНЕРАХ ===\033[0m'; \
echo ''; \
ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini converge.yml && \
echo ''; \
echo -e '\033[33m=== ЗАПУСК ROLES/DEPLOY.YML НА ТЕСТОВЫХ КОНТЕЙНЕРАХ ===\033[0m'; \
echo ''; \
ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini ../../roles/deploy.yml && \
echo ''; \
echo -e '\033[33m=== ОЧИСТКА РЕСУРСОВ ==='; \
echo ''; \
ansible-playbook -i localhost, destroy.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace && \
echo ''; \
echo '✅ Тестирование завершено'"; \
echo ''; \
$(MAKE) encrypt-all;; \
dryrun) \
echo "🔍 Проверка роли на реальных серверах (dry-run)..."; \
echo ""; \
if [ ! -f "inventory/hosts.ini" ]; then \
echo "❌ Ошибка: Файл inventory/hosts.ini не найден!"; \
echo "💡 Создайте файл inventory/hosts.ini с вашими серверами"; \
exit 1; \
fi; \
ROLE_NAME="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$ROLE_NAME" ]; then \
echo "❌ Укажите имя роли для проверки"; \
echo "📋 Доступные роли:"; \
ls -1 roles/ | grep -v "\.yml$$" | sed 's/^/ - /'; \
exit 1; \
fi; \
if [ ! -d "roles/$$ROLE_NAME" ]; then \
echo "❌ Роль '$$ROLE_NAME' не найдена в roles/"; \
echo "📋 Доступные роли:"; \
ls -1 roles/ | grep -v "\.yml$$" | sed 's/^/ - /'; \
exit 1; \
fi; \
$(MAKE) decrypt-all; \
echo "📋 Проверяемая роль: $$ROLE_NAME"; \
echo "📋 Используется inventory: inventory/hosts.ini"; \
echo "📄 Содержимое inventory:"; \
podman run --rm -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) cat inventory/hosts.ini || cat inventory/hosts.ini; \
echo ""; \
echo "🔍 Запуск dry-run проверки роли $$ROLE_NAME..."; \
podman run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
-v ~/.ssh:/root/.ssh:ro \
-e ANSIBLE_FORCE_COLOR=1 \
$(DOCKER_IMAGE) \
bash -c "ansible-playbook -i inventory/hosts.ini roles/$$ROLE_NAME/tasks/main.yml --check --diff"; \
echo ""; \
echo "✅ Dry-run проверка роли $$ROLE_NAME завершена"; \
$(MAKE) encrypt-all;; \
deploy) \
echo "🚀 Развертывание ролей на реальные серверы..."; \
echo ""; \
if [ ! -f "inventory/hosts.ini" ]; then \
echo "❌ Ошибка: Файл inventory/hosts.ini не найден!"; \
echo "💡 Создайте файл inventory/hosts.ini с вашими серверами"; \
exit 1; \
fi; \
$(MAKE) decrypt-all; \
echo "📋 Используется inventory: inventory/hosts.ini"; \
echo "📄 Содержимое inventory:"; \
podman run --rm -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) cat inventory/hosts.ini || cat inventory/hosts.ini; \
echo ""; \
echo "🚀 Запуск развертывания (в контейнере)..."; \
podman run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
-v ~/.ssh:/root/.ssh:ro \
-e ANSIBLE_FORCE_COLOR=1 \
$(DOCKER_IMAGE) \
bash -c "ansible-playbook -i inventory/hosts.ini roles/deploy.yml --check"; \
echo ""; \
read -p "Продолжить развертывание? (y/N): " confirm; \
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
podman run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
-v ~/.ssh:/root/.ssh:ro \
-e ANSIBLE_FORCE_COLOR=1 \
$(DOCKER_IMAGE) \
bash -c "ansible-playbook -i inventory/hosts.ini roles/deploy.yml"; \
else \
echo "❌ Развертывание отменено"; \
fi; \
$(MAKE) encrypt-all;; \
list) \
./scripts/role-manager.sh list;; \
create) \
./scripts/role-manager.sh create < /dev/tty;; \
delete) \
./scripts/role-manager.sh delete < /dev/tty;; \
*) \
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 all-images # со всеми образами"; \
echo " make role test etcd-patroni # с etcd-patroni preset"; \
echo ""; \
echo " 🚀 make role deploy - развернуть роли на реальные серверы"; \
echo " 💡 Требует: inventory/hosts.ini"; \
echo " 💡 Примеры:"; \
echo " make role deploy # развертывание всех ролей"; \
echo " ansible-playbook -i inventory/hosts.ini roles/deploy.yml --tags web"; \
echo " ansible-playbook -i inventory/hosts.ini roles/deploy.yml --limit webservers"; \
echo " ansible-playbook -i inventory/hosts.ini roles/deploy.yml --check"; \
echo " 💡 Документация: docs/deploy-yml-customization.md"; \
echo ""; \
echo " 🔍 make role dryrun [role] - проверить роль на реальных серверах (dry-run)"; \
echo " 💡 Требует: inventory/hosts.ini"; \
echo " 💡 Безопасно: не изменяет серверы, только проверяет"; \
echo " 💡 Примеры:"; \
echo " make role dryrun devops # проверить роль devops"; \
echo " make role dryrun docker # проверить роль docker"; \
echo ""; \
echo " 🔍 make role lint [role] - проверить синтаксис ролей"; \
echo " 💡 Использует: ansible-lint"; \
echo " 💡 Без параметра: проверяет все роли"; \
echo " 💡 С параметром: проверяет конкретную роль"; \
echo " 💡 Валидация: показывает доступные роли при ошибке"; \
echo " 💡 Примеры:"; \
echo " make role lint # проверить все роли"; \
echo " make role lint devops # проверить только devops"; \
echo " make role lint ping # проверить только ping"; \
echo ""; \
echo " 📋 make role list - показать все роли"; \
echo " 💡 Показывает: список всех ролей в roles/"; \
echo ""; \
echo " make role create - создать новую роль"; \
echo " 💡 Интерактивно: запрашивает имя роли"; \
echo " 💡 Создает: структуру папок и файлов"; \
echo " 💡 Обновляет: roles/deploy.yml"; \
echo ""; \
echo " 🗑️ make role delete - удалить роль"; \
echo " 💡 Интерактивно: запрашивает имя роли"; \
echo " 💡 Удаляет: папку роли и файлы"; \
echo " 💡 Обновляет: roles/deploy.yml"; \
echo ""; \
echo " 🔧 ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ О ЛИНТИНГЕ:"; \
echo " 💡 Линтинг проверяет: синтаксис, стиль, лучшие практики"; \
echo " 💡 Профили: production, basic, min"; \
echo " 💡 Конфигурация: .ansible-lint"; \
echo " 💡 Ошибки: показываются с номерами строк"; \
echo " 💡 Валидация: автоматическая проверка существования роли";; \
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 "Образы не найдены";; \
*) \
echo "🎯 Доступные команды:"; \
echo ""; \
echo " 📋 make presets list - показать список всех preset'ов"; \
echo " 💡 Показывает: название, описание, количество хостов"; \
echo ""; \
echo " 📄 make presets info - подробная информация о preset'е"; \
echo " 💡 Показывает: описание, хосты, сеть, образы"; \
echo " 💡 Требует: PRESET=имя_пресета"; \
echo ""; \
echo "💡 Примеры:"; \
echo " make presets list # показать все preset'ы"; \
echo " make presets info PRESET=etcd-patroni # информация о etcd-patroni";; \
esac
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С VAULT
# =============================================================================
vault:
@case "$(word 2, $(MAKECMDGOALS))" in \
init) \
echo "🔐 Инициализация vault..."; \
if [ ! -f "vault/.vault" ]; then \
echo "📝 Создание файла vault/.vault..."; \
read -sp "Введите пароль для vault: " PASSWORD; \
echo ""; \
echo "$$PASSWORD" > vault/.vault; \
chmod 600 vault/.vault; \
echo "✅ Файл vault/.vault создан"; \
else \
echo "✅ Файл vault/.vault уже существует"; \
fi;; \
edit) \
echo "🔐 Редактирование vars/main.yml выбранной роли..."; \
echo "📋 Доступные роли:"; \
ls -1 roles | grep -v "\\.yml$$" | sed 's/^/ - /'; \
read -p "Введите имя роли: " ROLE; \
FILE="roles/$$ROLE/vars/main.yml"; \
if [ ! -f "$$FILE" ]; then echo "❌ Файл $$FILE не найден"; exit 1; fi; \
$(MAKE) decrypt-role ROLE=$$ROLE; \
podman run --rm -it -v "$(PWD):/workspace" -w /workspace \
-e EDITOR=$(EDITOR) \
$(DOCKER_IMAGE) \
bash -c 'exec $${EDITOR:-nano} "$1"' _ "$$FILE"; \
$(MAKE) encrypt-role ROLE=$$ROLE;; \
show) \
echo "🔐 Просмотр vars/main.yml выбранной роли..."; \
echo "📋 Доступные роли:"; \
ls -1 roles | grep -v "\\.yml$$" | sed 's/^/ - /'; \
read -p "Введите имя роли: " ROLE; \
FILE="roles/$$ROLE/vars/main.yml"; \
if [ ! -f "$$FILE" ]; then echo "❌ Файл $$FILE не найден"; exit 1; fi; \
podman run --rm -v "$(PWD):/workspace" -w /workspace \
$(DOCKER_IMAGE) bash -c 'f="$1"; \
if grep -q "ANSIBLE_VAULT" "$${f}" 2>/dev/null; then \
ansible-vault view --vault-password-file vault/.vault "$${f}"; \
else \
cat "$${f}"; \
fi' _ "$$FILE";; \
encrypt) \
echo "🔐 Шифрование vars/main.yml выбранной роли..."; \
echo "📋 Доступные роли:"; \
ls -1 roles | grep -v "\\.yml$$" | sed 's/^/ - /'; \
read -p "Введите имя роли: " ROLE; \
$(MAKE) encrypt-role ROLE="$$ROLE";; \
decrypt) \
echo "🔓 Расшифровка vars/main.yml выбранной роли..."; \
echo "📋 Доступные роли:"; \
ls -1 roles | grep -v "\\.yml$$" | sed 's/^/ - /'; \
read -p "Введите имя роли: " ROLE; \
$(MAKE) decrypt-role ROLE="$$ROLE";; \
rekey) \
echo "🔑 Смена пароля для всех vars/main.yml..."; \
$(MAKE) rekey-all;; \
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 init - инициализировать vault (создать vault/.vault)"; \
echo " 💡 Первая команда для настройки vault"; \
echo ""; \
echo " ✏️ make vault edit - редактировать существующие секреты"; \
echo " 💡 Открывает nano для изменения секретов"; \
echo ""; \
echo " 👁️ make vault show - показать содержимое секретов"; \
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 "📤 Отправка изменений в репозиторий..."; \
$(MAKE) encrypt-all; \
if [ -d "vault" ]; then \
VAULT_FILES=$$(find vault -maxdepth 1 -type f -name "*.yml" 2>/dev/null); \
if [ -n "$$VAULT_FILES" ]; then \
echo "🔐 Шифрование vault/*.yml..."; \
for f in $$VAULT_FILES; do \
if ! grep -q "ANSIBLE_VAULT" "$$f" 2>/dev/null; then \
podman run --rm -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) \
ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault/.vault "$$f" || true; \
fi; \
done; \
fi; \
fi; \
git add .; \
read -p "Введите сообщение коммита: " COMMIT_MSG; \
git commit -m "$$COMMIT_MSG"; \
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 " podman login - авторизация в registry"; \
echo " make docker build - сборка образов"; \
echo " make docker push - отправка в registry";; \
build) \
echo "🐳 Сборка образов (Podman, multi-arch)..."; \
echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo "📋 Version: $(DOCKER_VERSION)"; \
echo "📋 Images: $(DOCKER_IMAGES)"; \
echo "⚠️ ВНИМАНИЕ: RED OS и Astra Linux собираются только для AMD64"; \
echo ""; \
for image in $(DOCKER_IMAGES); do \
echo "🔨 Сборка $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
$(MAKE) docker-build-image IMAGE=$$image; \
done; \
echo "✅ Образы собраны";; \
rebuild) \
echo "🔄 Полная пересборка образов (Podman, multi-arch)..."; \
echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo "📋 Images: $(DOCKER_IMAGES)"; \
echo "🧹 Очистка старых образов..."; \
echo ""; \
$(MAKE) docker clean; \
for image in $(DOCKER_IMAGES); do \
echo "🔨 Пересборка $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \
$(MAKE) docker-build-image IMAGE=$$image; \
done; \
echo "✅ Образы пересобраны с нуля";; \
push) \
echo "📤 Отправка образов в registry (Podman)..."; \
for image in $(DOCKER_IMAGES); do \
echo "📤 Отправка $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \
podman push $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION); \
done; \
echo "✅ Образы отправлены в registry";; \
pull) \
echo "📥 Загрузка образов из registry (Podman)..."; \
echo "⚠️ ВНИМАНИЕ: astra-linux и redos собираются только для AMD64"; \
for image in $(DOCKER_IMAGES); do \
echo "📥 Загрузка $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \
if [ "$$image" = "astra-linux" ] || [ "$$image" = "redos" ]; then \
podman pull --platform linux/amd64 $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION) || echo "⚠️ Образ $$image не найден"; \
else \
podman pull $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION) || echo "⚠️ Образ $$image не найден"; \
fi; \
done; \
echo "✅ Загрузка завершена";; \
clean) \
echo "🧹 Очистка образов (Podman)..."; \
for image in $(DOCKER_IMAGES); do \
echo "🗑️ Удаление $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \
podman rmi $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION) 2>/dev/null || true; \
done; \
echo "✅ Образы очищены";; \
info) \
echo "📊 Информация об образах (Podman)..."; \
for image in $(DOCKER_IMAGES); do \
if podman images | grep -q "$(DOCKER_REGISTRY):$$image"; then \
echo "📦 $(DOCKER_REGISTRY):$$image-$(DOCKER_VERSION)"; \
podman images | grep "$(DOCKER_REGISTRY):$$image" | head -1; \
fi; \
done;; \
update) \
echo "🔄 Обновление всех образов..."; \
$(MAKE) docker pull; \
$(MAKE) docker build; \
$(MAKE) docker push; \
echo "✅ Все образы обновлены";; \
purge) \
echo "🧹 Полная очистка Podman..."; \
echo "⚠️ ВНИМАНИЕ: Это удалит ВСЕ данные Podman!"; \
echo ""; \
read -p "Продолжить? (y/N): " confirm; \
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
echo "🛑 Остановка всех контейнеров..."; \
podman stop $$(podman ps -aq) 2>/dev/null || true; \
echo "🗑️ Удаление всех контейнеров..."; \
podman rm -f $$(podman ps -aq) 2>/dev/null || true; \
echo "🗑️ Удаление всех образов..."; \
podman rmi -f $$(podman images -aq) 2>/dev/null || true; \
echo "🧹 Очистка системы..."; \
podman system prune -af --volumes; \
echo "✅ Podman полностью очищен"; \
else \
echo "❌ Очистка отменена"; \
fi;; \
clean-builder) \
echo "🧹 Очистка multi-arch builder..."; \
$(MAKE) docker-reset-builder;; \
build-image) \
if [ -z "$(IMAGE)" ]; then \
echo "❌ Ошибка: Укажите IMAGE=имя_образа"; \
echo "💡 Пример: make docker build-image IMAGE=centos"; \
echo "💡 Доступные образы: $(DOCKER_IMAGES)"; \
exit 1; \
fi; \
if [ ! -d "dockerfiles/$(IMAGE)" ]; then \
echo "❌ Ошибка: Директория dockerfiles/$(IMAGE) не найдена!"; \
echo "💡 Доступные образы:"; \
for img in $(DOCKER_IMAGES); do \
if [ -d "dockerfiles/$$img" ]; then \
echo " - $$img"; \
fi; \
done; \
exit 1; \
fi; \
echo "🔨 Сборка отдельного образа: $(IMAGE)"; \
echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo ""; \
$(MAKE) docker-build-image IMAGE=$(IMAGE); \
echo "✅ Образ $(IMAGE) собран";; \
build-astra-arm64) \
echo "🔨 Сборка Astra Linux для ARM64 (совместимый образ)..."; \
echo "📋 Платформы: linux/amd64,linux/arm64"; \
echo "📋 Builder: $(DOCKER_BUILDX_BUILDER)"; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo "⚠️ ВНИМАНИЕ: Используется совместимый образ на базе Debian"; \
echo ""; \
cd dockerfiles/astra-linux && \
podman build --platform linux/amd64,linux/arm64 \
--tag $(DOCKER_REGISTRY):astra-linux-arm64-latest \
--tag $(DOCKER_REGISTRY):astra-linux-latest \
--file Dockerfile.arm64 \
.; \
podman push $(DOCKER_REGISTRY):astra-linux-arm64-latest; \
podman push $(DOCKER_REGISTRY):astra-linux-latest; \
echo "✅ Astra Linux для ARM64 собран и отправлен";; \
build-redos-arm64) \
echo "🔨 Сборка RedOS для ARM64 (совместимый образ)..."; \
echo "📋 Платформы: linux/amd64,linux/arm64"; \
echo "📋 Builder: $(DOCKER_BUILDX_BUILDER)"; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo "⚠️ ВНИМАНИЕ: Используется совместимый образ на базе CentOS Stream 9"; \
echo ""; \
cd dockerfiles/redos && \
podman build --platform linux/amd64,linux/arm64 \
--tag $(DOCKER_REGISTRY):redos-arm64-latest \
--tag $(DOCKER_REGISTRY):redos-latest \
--file Dockerfile.arm64 \
.; \
podman push $(DOCKER_REGISTRY):redos-arm64-latest; \
podman push $(DOCKER_REGISTRY):redos-latest; \
echo "✅ RedOS для ARM64 собран и отправлен";; \
setup-builder) \
echo " Podman: multi-arch через podman build --platform (builder не требуется)";; \
diagnose) \
echo "🔍 Диагностика Podman..."; \
podman version;; \
reset-builder) \
echo " Podman: builder не используется";; \
*) \
echo "🎯 Доступные команды (Podman):"; \
echo ""; \
echo " 🔧 make docker prepare - подготовка к работе с registry"; \
echo " 💡 Показывает: registry, version, список образов"; \
echo " 💡 Рекомендует: podman login перед работой"; \
echo ""; \
echo " 🐳 make docker build - собрать все Docker образы (multi-arch)"; \
echo " 💡 Собирает: ansible-controller, alt9, alt10, astra-linux, redos"; \
echo " 💡 Собирает: rhel, centos, alma, rocky, ubuntu, debian"; \
echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \
echo " 💡 Ограничения: RED OS и Astra Linux только AMD64"; \
echo " 💡 Тегирует: inecs/образ:<tag> (автоматически извлекает теги)"; \
echo " 💡 Отправляет: автоматически в Docker Hub"; \
echo ""; \
echo " 🔨 make docker build-image IMAGE=<имя> - собрать отдельный образ"; \
echo " 💡 Пример: make docker build-image IMAGE=centos"; \
echo " 💡 Собирает: только указанный образ (multi-arch)"; \
echo " 💡 Доступные образы: $(DOCKER_IMAGES)"; \
echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \
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 - заглушка (Podman не использует builder)"; \
setup-builder) \
echo " Podman: builder не требуется";; \
diagnose) \
podman version;; \
reset-builder) \
echo " Podman: builder не используется";; \
*) \
echo "🎯 Доступные команды (Podman):"; \
echo ""; \
echo " 🔧 make docker prepare - подготовка к работе с registry"; \
echo " 💡 Рекомендует: podman login перед работой"; \
echo ""; \
echo " 🐳 make docker build - собрать все образы (Podman, multi-arch)"; \
echo " 💡 Собирает: ansible-controller, alt9, alt10, astra-linux, redos"; \
echo " 💡 Собирает: rhel, centos, alma, rocky, ubuntu, debian"; \
echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \
echo " 💡 Ограничения: RED OS и Astra Linux только AMD64"; \
echo " 💡 Тегирует: inecs/образ:<tag> (автоматически извлекает теги)"; \
echo " 💡 Отправляет: автоматически в Docker Hub"; \
echo ""; \
echo " 🔨 make docker build-image IMAGE=<имя> - собрать отдельный образ"; \
echo " 💡 Пример: make docker build-image IMAGE=centos"; \
echo " 💡 Собирает: только указанный образ (multi-arch)"; \
echo " 💡 Доступные образы: $(DOCKER_IMAGES)"; \
echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \
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"; \
echo " 💡 Удаляет: builder контейнер и buildkit контейнеры"; \
echo " 💡 Полезно: при проблемах со сборкой"; \
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 для избежания зависаний
# Podman: buildx не используется, заглушки для совместимости
.PHONY: docker-check-builder
docker-check-builder:
@echo " Podman: builder не используется"; exit 0
.PHONY: docker-create-builder
docker-create-builder:
@echo " Podman: builder не требуется"
.PHONY: docker-diagnose-buildx
docker-diagnose-buildx:
@echo "🔍 Podman:"; podman version
.PHONY: docker-reset-builder
docker-reset-builder:
@echo " Podman: builder не используется"
# Извлечение тега из базового образа
docker-get-base-tag:
@if [ -z "$(IMAGE)" ]; then \
echo "❌ Ошибка: IMAGE не указан"; \
exit 1; \
fi; \
case "$(IMAGE)" in \
alt9) \
BASE_IMAGE="alt:p9"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
alt10) \
BASE_IMAGE="alt:p10"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
astra-linux) \
BASE_IMAGE="registry.astralinux.ru/library/astra/ubi17:1.7.6.uu2"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
redos) \
BASE_IMAGE="registry.red-soft.ru/ubi7/ubi:latest"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG="latest";; \
astra-linux-arm64) \
BASE_IMAGE="debian:bookworm-slim"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG="latest";; \
redos-arm64) \
BASE_IMAGE="quay.io/centos/centos:stream9"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG="latest";; \
rhel) \
BASE_IMAGE="registry.access.redhat.com/ubi8/ubi"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
centos7) \
BASE_IMAGE="centos:7"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
centos8) \
BASE_IMAGE="quay.io/centos/centos:8"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
centos9) \
BASE_IMAGE="quay.io/centos/centos:stream9"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
alma) \
BASE_IMAGE="almalinux:8"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
rocky) \
BASE_IMAGE="rockylinux:8"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
ubuntu20) \
BASE_IMAGE="ubuntu:20.04"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
ubuntu22) \
BASE_IMAGE="ubuntu:22.04"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
ubuntu24) \
BASE_IMAGE="ubuntu:24.04"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
debian9) \
BASE_IMAGE="debian:9"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
debian10) \
BASE_IMAGE="debian:10"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
debian11) \
BASE_IMAGE="debian:11"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
debian12) \
BASE_IMAGE="debian:bookworm"; \
echo "📦 Загрузка базового образа $$BASE_IMAGE..." >&2; \
podman pull $$BASE_IMAGE >/dev/null 2>&1 || echo "⚠️ Не удалось загрузить $$BASE_IMAGE" >&2; \
TAG=$$(podman inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
ansible-controller) \
TAG="latest";; \
k8s) \
TAG="latest";; \
k8s-portforward) \
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)); \
if [ "$(IMAGE)" = "redos" ] || [ "$(IMAGE)" = "astra-linux" ]; then \
PLATFORMS="linux/amd64"; \
echo ""; \
echo "=========================================="; \
echo "🔨 СБОРКА ОБРАЗА: $(DOCKER_REGISTRY):$(IMAGE)-$$TAG"; \
echo "📋 Платформы: $$PLATFORMS (только AMD64)"; \
echo "📋 Тег: $$TAG"; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo "⚠️ ВНИМАНИЕ: Базовый образ поддерживает только AMD64"; \
echo "=========================================="; \
elif [ "$(IMAGE)" = "astra-linux-arm64" ] || [ "$(IMAGE)" = "redos-arm64" ]; then \
PLATFORMS="linux/amd64,linux/arm64"; \
echo ""; \
echo "=========================================="; \
echo "🔨 СБОРКА ОБРАЗА: $(DOCKER_REGISTRY):$(IMAGE)-$$TAG"; \
echo "📋 Платформы: $$PLATFORMS (AMD64 + ARM64)"; \
echo "📋 Тег: $$TAG"; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo "⚠️ ВНИМАНИЕ: Совместимый образ с поддержкой ARM64"; \
echo "=========================================="; \
else \
PLATFORMS="$(DOCKER_PLATFORMS)"; \
echo ""; \
echo "=========================================="; \
echo "🔨 СБОРКА ОБРАЗА: $(DOCKER_REGISTRY):$(IMAGE)-$$TAG"; \
echo "📋 Платформы: $$PLATFORMS"; \
echo "📋 Тег: $$TAG"; \
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
echo "=========================================="; \
fi; \
echo ""; \
if [ "$(IMAGE)" = "astra-linux-arm64" ]; then \
cd dockerfiles/astra-linux && \
podman build --platform $$PLATFORMS --tag $(DOCKER_REGISTRY):$(IMAGE)-$$TAG --tag $(DOCKER_REGISTRY):$(IMAGE)-latest --file Dockerfile.arm64 .; \
podman push $(DOCKER_REGISTRY):$(IMAGE)-$$TAG; \
podman push $(DOCKER_REGISTRY):$(IMAGE)-latest; \
elif [ "$(IMAGE)" = "redos-arm64" ]; then \
cd dockerfiles/redos && \
podman build --platform $$PLATFORMS --tag $(DOCKER_REGISTRY):$(IMAGE)-$$TAG --tag $(DOCKER_REGISTRY):$(IMAGE)-latest --file Dockerfile.arm64 .; \
podman push $(DOCKER_REGISTRY):$(IMAGE)-$$TAG; \
podman push $(DOCKER_REGISTRY):$(IMAGE)-latest; \
else \
cd dockerfiles/$(IMAGE) && \
podman build --platform $$PLATFORMS \
--tag $(DOCKER_REGISTRY):$(IMAGE)-$$TAG \
--tag $(DOCKER_REGISTRY):$(IMAGE)-latest \
.; \
podman push $(DOCKER_REGISTRY):$(IMAGE)-$$TAG; \
podman push $(DOCKER_REGISTRY):$(IMAGE)-latest; \
fi; \
echo ""; \
echo "✅ УСПЕШНО: $(DOCKER_REGISTRY):$(IMAGE)-$$TAG собран и отправлен"; \
echo "=========================================="
# =============================================================================
# BUILDALL — сборка всех образов только локально (без push в registry)
# Для использования в presets Podman без доступа к registry
# =============================================================================
.PHONY: buildall buildall-image
buildall:
@echo "🔨 Сборка всех образов локально (Podman, без push в registry)..."; \
echo "📋 Образы: $(DOCKER_IMAGES)"; \
echo ""; \
for image in $(DOCKER_IMAGES); do \
$(MAKE) buildall-image IMAGE=$$image; \
done; \
echo ""; \
echo "✅ Все образы собраны локально. Для тестов: make role test [preset]"
# Сборка одного образа локально (без push)
buildall-image:
@if [ -z "$(IMAGE)" ]; then \
echo "❌ Укажите IMAGE=имя (например: make buildall-image IMAGE=ubuntu22)"; \
echo "💡 Образы: $(DOCKER_IMAGES)"; \
exit 1; \
fi; \
if [ ! -d "dockerfiles/$(IMAGE)" ]; then \
echo "⚠️ Пропуск $(IMAGE): нет dockerfiles/$(IMAGE)"; \
exit 0; \
fi; \
TAG=$$($(MAKE) docker-get-base-tag IMAGE=$(IMAGE)); \
PLATFORMS="$(DOCKER_PLATFORMS)"; \
if [ "$(IMAGE)" = "redos" ] || [ "$(IMAGE)" = "astra-linux" ]; then PLATFORMS="linux/amd64"; fi; \
echo "🔨 Локальная сборка $(DOCKER_REGISTRY):$(IMAGE)-latest (без push)..."; \
if [ "$(IMAGE)" = "astra-linux-arm64" ]; then \
cd dockerfiles/astra-linux && podman build --platform $$PLATFORMS --tag $(DOCKER_REGISTRY):$(IMAGE)-latest --file Dockerfile.arm64 .; \
elif [ "$(IMAGE)" = "redos-arm64" ]; then \
cd dockerfiles/redos && podman build --platform $$PLATFORMS --tag $(DOCKER_REGISTRY):$(IMAGE)-latest --file Dockerfile.arm64 .; \
elif [ "$(IMAGE)" = "astra-linux" ]; then \
cd dockerfiles/astra-linux && podman build --platform $$PLATFORMS --tag $(DOCKER_REGISTRY):$(IMAGE)-latest .; \
elif [ "$(IMAGE)" = "redos" ]; then \
cd dockerfiles/redos && podman build --platform $$PLATFORMS --tag $(DOCKER_REGISTRY):$(IMAGE)-latest .; \
else \
cd dockerfiles/$(IMAGE) && podman build --platform $$PLATFORMS --tag $(DOCKER_REGISTRY):$(IMAGE)-$$TAG --tag $(DOCKER_REGISTRY):$(IMAGE)-latest .; \
fi; \
echo "$(DOCKER_REGISTRY):$(IMAGE)-latest готов локально"
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С ANSIBLE-CONTROLLER
# =============================================================================
controller:
@case "$(word 2, $(MAKECMDGOALS))" in \
build) \
echo "🔨 Сборка ansible-controller (Podman, multi-arch)..."; \
echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \
cd dockerfiles/ansible-controller && \
podman build --platform $(DOCKER_PLATFORMS) \
--tag $(DOCKER_REGISTRY):ansible-controller-$(DOCKER_VERSION) \
--tag $(DOCKER_REGISTRY):ansible-controller-latest \
.; \
podman push $(DOCKER_REGISTRY):ansible-controller-$(DOCKER_VERSION); \
podman push $(DOCKER_REGISTRY):ansible-controller-latest; \
echo "✅ ansible-controller собран и отправлен";; \
rebuild) \
echo "🔄 Пересборка ansible-controller с исправлениями..."; \
echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \
cd dockerfiles/ansible-controller && \
podman build --no-cache --platform $(DOCKER_PLATFORMS) \
--tag $(DOCKER_REGISTRY):ansible-controller-$(DOCKER_VERSION) \
--tag $(DOCKER_REGISTRY):ansible-controller-latest \
.; \
podman push $(DOCKER_REGISTRY):ansible-controller-$(DOCKER_VERSION); \
podman push $(DOCKER_REGISTRY):ansible-controller-latest; \
echo "✅ ansible-controller пересобран";; \
run) \
echo "🚀 Запуск ansible-controller (Podman)..."; \
cd dockerfiles/ansible-controller && podman compose up -d; \
echo "✅ ansible-controller запущен";; \
stop) \
echo "🛑 Остановка ansible-controller..."; \
cd dockerfiles/ansible-controller && podman compose down; \
echo "✅ ansible-controller остановлен";; \
*) \
echo "🎯 Доступные команды:"; \
echo ""; \
echo " 🔨 make controller build - собрать ansible-controller (multi-arch)"; \
echo " 💡 Собирает: inecs/ansible-lab:ansible-controller-latest"; \
echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \
echo " 💡 Использует: dockerfiles/ansible-controller/Dockerfile"; \
echo " 💡 Requirements: dockerfiles/ansible-controller/requirements.yml"; \
echo ""; \
echo " 🔄 make controller rebuild - пересобрать ansible-controller с исправлениями"; \
echo " 💡 Пересобирает: с --no-cache для применения исправлений"; \
echo " 💡 Исправления: добавлен passlib для хеширования паролей"; \
echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \
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
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С KUBERNETES (Minikube + Podman)
# =============================================================================
k8s:
@case "$(word 2, $(MAKECMDGOALS))" in \
create) \
echo "☸️ Создание Minikube кластера (драйвер: podman)..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
PRESET=k8s-minimal; \
echo "📋 Используется preset по умолчанию: $$PRESET"; \
else \
PRESET=$$PRESET_ARG; \
echo "📋 Используется preset: $$PRESET"; \
fi; \
if [ ! -f "molecule/presets/k8s/$$PRESET.yml" ]; then \
echo "❌ Ошибка: Пресет '$$PRESET' не найден!"; \
ls -1 molecule/presets/k8s/*.yml 2>/dev/null | sed 's|molecule/presets/k8s/||g' | sed 's|\.yml||g' | sed 's/^/ - /' || echo " - k8s-minimal"; \
exit 1; \
fi; \
python3 scripts/create_minikube_cluster.py molecule/presets/k8s/$$PRESET.yml; \
echo "✅ Minikube кластер создан"; \
echo "💡 kubectl config use-context minikube"; \
echo "💡 make k8s status";; \
destroy) \
echo "🗑️ Удаление Minikube кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
PROFILE=$${PRESET_ARG:-minikube}; \
minikube delete -p $$PROFILE 2>/dev/null || true; \
echo "✅ Удаление завершено";; \
stop) \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
PROFILE=$${PRESET_ARG:-minikube}; \
echo "🛑 Остановка Minikube (профиль: $$PROFILE)..."; \
minikube stop -p $$PROFILE 2>/dev/null || true; \
echo "💡 Для запуска: make k8s start $$PROFILE";; \
start) \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
PROFILE=$${PRESET_ARG:-minikube}; \
echo "🚀 Запуск Minikube (профиль: $$PROFILE)..."; \
minikube start --driver=podman -p $$PROFILE; \
echo "✅ Minikube запущен";; \
status) \
echo "📊 Отчет о состоянии кластера (Minikube)..."; \
python3 scripts/k8s_status.py;; \
config) \
echo "📋 Minikube обновляет ~/.kube/config автоматически."; \
echo "💡 Использование: kubectl get nodes"; \
echo " или: eval \$$(minikube docker-env -p minikube 2>/dev/null) для Podman"; \
kubectl config view --minify 2>/dev/null || true;; \
nodes) \
echo "🖥️ Узлы кластера:"; \
kubectl get nodes -o wide;; \
shell) \
echo "💡 Minikube работает на хосте. Используйте kubectl и minikube напрямую."; \
echo " minikube ssh -p minikube # вход в ноду"; \
exec $$SHELL;; \
manifest) \
MANIFEST_CMD="$(word 3, $(MAKECMDGOALS))"; \
MANIFEST_ARG="$(word 4, $(MAKECMDGOALS))"; \
if [ -z "$$MANIFEST_CMD" ] || [ -z "$$MANIFEST_ARG" ]; then \
echo "❌ Укажите команду и путь: make k8s manifest apply https://example.com/manifest.yaml"; \
exit 1; \
fi; \
case "$$MANIFEST_CMD" in \
apply) kubectl apply -f $$MANIFEST_ARG;; \
delete) kubectl delete -f $$MANIFEST_ARG;; \
*) echo "💡 Команды: apply, delete"; exit 1;; \
esac;; \
helm) \
HELM_CMD="$(word 3, $(MAKECMDGOALS))"; \
RELEASE_ARG="$(word 4, $(MAKECMDGOALS))"; \
CHART_ARG="$(word 5, $(MAKECMDGOALS))"; \
if [ -z "$$HELM_CMD" ]; then \
helm list -A; \
exit 0; \
fi; \
case "$$HELM_CMD" in \
apply) [ -z "$$RELEASE_ARG" ] || [ -z "$$CHART_ARG" ] && { echo "💡 make k8s helm apply RELEASE CHART"; exit 1; }; helm upgrade --install $$RELEASE_ARG $$CHART_ARG;; \
delete) [ -z "$$RELEASE_ARG" ] && { echo "💡 make k8s helm delete RELEASE"; exit 1; }; helm uninstall $$RELEASE_ARG;; \
list) helm list -A;; \
*) echo "💡 Команды: apply, delete, list"; exit 1;; \
esac;; \
helmrepo) \
REPO_CMD="$(word 3, $(MAKECMDGOALS))"; \
NAME_ARG="$(word 4, $(MAKECMDGOALS))"; \
URL_ARG="$(word 5, $(MAKECMDGOALS))"; \
case "$$REPO_CMD" in \
add) [ -z "$$NAME_ARG" ] || [ -z "$$URL_ARG" ] && { echo "💡 make k8s helmrepo add NAME URL"; exit 1; }; helm repo add $$NAME_ARG $$URL_ARG; helm repo update;; \
list) helm repo list;; \
update) helm repo update;; \
*) echo "💡 Команды: add, list, update"; exit 1;; \
esac;; \
portforward) \
PORTFWD_CMD="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PORTFWD_CMD" ]; then echo "💡 make k8s portforward create|list|clear"; exit 1; fi; \
python3 scripts/portforward.py $$PORTFWD_CMD;; \
*) \
echo "☸️ Доступные команды:"; \
echo ""; \
echo " make k8s create [preset] - создать Kind кластер"; \
echo " 💡 Без параметра: используется k8s-minimal (без аддонов)"; \
echo " 💡 С параметром: используется указанный пресет"; \
echo " 💡 Кластер НЕ удаляется автоматически"; \
echo ""; \
echo " make k8s destroy [preset] - удалить Kind кластер полностью"; \
echo " 💡 Удалит: кластер и контейнер ansible-controller"; \
echo ""; \
echo " make k8s stop [cluster] - остановить Kind кластер (без удаления)"; \
echo " 💡 Можно указать имя кластера или остановить все"; \
echo " 💡 Для перезапуска: make k8s start"; \
echo ""; \
echo " make k8s start [cluster] - запустить остановленный кластер"; \
echo " 💡 Можно указать имя кластера или запустить все"; \
echo ""; \
echo " make k8s status [preset] - детальный отчет о состоянии кластера"; \
echo " 💡 Показывает: узлы, pods, сервисы, Ingress, события, Helm релизы и т.д."; \
echo " 💡 Требует: пресет"; \
echo " 💡 Пример: make k8s status kubernetes"; \
echo ""; \
echo " make k8s config [cluster] - получить kubeconfig для подключения"; \
echo " 💡 Сохраняет: kubeconfig в корне проекта"; \
echo " 💡 Можно указать имя конкретного кластера"; \
echo ""; \
echo " make k8s nodes [preset] - показать узлы кластера"; \
echo " 💡 Требует: пресет"; \
echo " 💡 Пример: make k8s nodes kubernetes"; \
echo ""; \
echo " make k8s shell [preset] - открыть shell в контейнере"; \
echo " 💡 Для: ручного управления kubectl/kind"; \
echo " 💡 Пример: make k8s shell kubernetes"; \
echo ""; \
echo " make k8s manifest [cmd] [preset] [url] - работа с манифестами"; \
echo " 💡 Команды: apply, delete"; \
echo " 💡 Пример: make k8s manifest apply kubernetes https://example.com/deploy.yaml"; \
echo ""; \
echo " make k8s helm [cmd] [preset] [release] [chart] - работа с Helm"; \
echo " 💡 Команды: apply, delete, update, rollback, list, status"; \
echo " 💡 Пример: make k8s helm apply kubernetes nginx stable/nginx-ingress"; \
echo ""; \
echo " make k8s helmrepo [cmd] [preset] [name] [url] - работа с Helm репозиториями"; \
echo " 💡 Команды: add, list, delete, update, packages"; \
echo " 💡 Пример: make k8s helmrepo add kubernetes stable https://charts.helm.sh/stable"; \
echo ""; \
echo " make k8s portforward [cmd] - управление port-forward"; \
echo " 💡 Команды: create, list, clear, recreate, delete [port]"; \
echo " 💡 Пример: make k8s portforward create"; \
echo ""; \
echo "💡 Примеры:"; \
echo " make k8s create # создать минимальный кластер"; \
echo " make k8s create kubernetes # создать кластер с аддонами"; \
echo " make k8s nodes kubernetes # показать узлы кластера"; \
echo " make k8s config kubernetes # получить kubeconfig для кластера"; \
echo " export KUBECONFIG=kubeconfig # использовать конфиг"; \
echo " kubectl get nodes # проверить узлы"; \
echo " make k8s manifest apply kubernetes https://example.com/manifest.yaml # установить манифест"; \
echo " make k8s stop kubernetes # остановить кластер"; \
echo " make k8s start kubernetes # запустить кластер"; \
echo " make k8s destroy kubernetes # удалить кластер с пресетом kubernetes";; \
esac
# =============================================================================
# СПРАВКА
# =============================================================================
help:
@echo "=========================================="
@echo "DevOpsLab - Универсальная система"
@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 [role] - проверить синтаксис ролей (все или конкретную)"
@echo " 💡 Примеры: make role lint, make role lint devops"
@echo " make role test [preset] - протестировать роли с preset'ом"
@echo " make role deploy - развернуть роли на реальные серверы"
@echo " make role dryrun [role] - проверить роль на реальных серверах (dry-run)"
@echo " make role list - показать все роли"
@echo " make role create - создать новую роль (интерактивно)"
@echo " make role delete - удалить роль (интерактивно)"
@echo ""
@echo "📖 ДОКУМЕНТАЦИЯ:"
@echo " docs/deploy-yml-customization.md - полное руководство по кастомизации"
@echo " docs/linting-guide.md - руководство по линтингу ролей"
@echo ""
@echo "🔍 ЛИНТИНГ РОЛЕЙ:"
@echo " make role lint [role] - проверить синтаксис (все или конкретную роль)"
@echo " 💡 Профили: production, basic, min"
@echo " 💡 Конфигурация: .ansible-lint"
@echo " 💡 Валидация: автоматическая проверка существования роли"
@echo ""
@echo "📋 PRESET'Ы (тестовые окружения):"
@echo " make presets list - показать все доступные preset'ы"
@echo " make presets info - подробная информация о preset'е"
@echo ""
@echo "🐳 ОБРАЗЫ (Podman, локально без registry):"
@echo " make buildall - собрать ВСЕ образы локально (без push), для presets"
@echo " make buildall-image IMAGE=<имя> - собрать один образ локально (напр. IMAGE=ubuntu22)"
@echo " make docker prepare - подготовка к работе с registry"
@echo " make docker build - собрать все образы и отправить в registry"
@echo " make docker build-image IMAGE=<имя> - собрать отдельный образ и push"
@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 ""
@echo "🔧 АВТОМАТИЗАЦИЯ:"
@echo " make update-playbooks - обновление playbook'ов при добавлении ролей"
@echo " make generate-docs - генерация документации для ролей"
@echo " make setup-cicd - настройка CI/CD для всех платформ"
@echo " 💡 Безопасно: использует inspect вместо buildx ls (избегает зависаний)"
@echo ""
@echo "🔐 VAULT (управление секретами):"
@echo " make vault init - инициализировать vault (создать vault/.vault)"
@echo " make vault edit - редактировать существующие секреты"
@echo " make vault show - показать содержимое секретов"
@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 "☸️ KUBERNETES (Kind кластеры):"
@echo " make k8s create [preset] - создать Kind кластер (по умолчанию: k8s-minimal)"
@echo " make k8s destroy [preset] - удалить Kind кластер"
@echo " make k8s start [preset] - запустить Kind кластер"
@echo " make k8s stop [preset] - остановить Kind кластер"
@echo " make k8s status [preset] - детальный отчет о состоянии кластера"
@echo " make k8s nodes [preset] - показать узлы кластера"
@echo " make k8s config [preset] - получить kubeconfig для подключения"
@echo " make k8s manifest [cmd] [preset] [url] - работа с манифестами (apply, delete)"
@echo " make k8s helm [cmd] [preset] [release] [chart] - работа с Helm"
@echo " make k8s helmrepo [cmd] [preset] [name] [url] - управление Helm репозиториями"
@echo " make k8s portforward [cmd] - управление port-forward (create, list, clear)"
@echo " make k8s shell [preset] - открыть shell в контейнере k8s"
@echo ""
@echo "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:"
@echo " make presets list # показать все preset'ы"
@echo " make role test minimal # быстрый тест"
@echo " make role test all-images # тест всех образов"
@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 init # инициализировать vault"
@echo " make vault create # создать секреты"
@echo ""
@echo "📖 Подробная справка: make [команда]"
@echo "=========================================="
# =============================================================================
# АВТОМАТИЗАЦИЯ
# =============================================================================
update-playbooks:
@echo "🔄 Обновление playbook'ов..."
@chmod +x scripts/update-playbooks.sh
@./scripts/update-playbooks.sh
generate-docs:
@echo "📚 Генерация документации..."
@chmod +x scripts/generate-role-docs.sh
@./scripts/generate-role-docs.sh
setup-cicd:
@echo "🔧 Настройка CI/CD..."
@chmod +x scripts/setup-cicd.sh
@./scripts/setup-cicd.sh
# Вспомогательные функции: шифрование/расшифровка roles/*/vars/main.yml
.PHONY: encrypt decrypt rekey-all
encrypt-all:
@echo "🔐 Шифрование всех roles/*/vars/main.yml (только незашифрованных) ..."
@podman run --rm -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) bash -c '\
VAULT=vault/.vault; \
for f in roles/*/vars/main.yml; do [ -f "$$f" ] || continue; \
if ! grep -q "ANSIBLE_VAULT" "$$f" 2>/dev/null; then \
ansible-vault encrypt --encrypt-vault-id default --vault-password-file "$$VAULT" "$$f" || true; \
printf "✅ Зашифровано: %s\n" "$$f"; \
else \
printf " Уже зашифровано: %s\n" "$$f"; \
fi; \
done'
decrypt-all:
@echo "🔓 Расшифровка всех roles/*/vars/main.yml (только зашифрованных) ..."
@podman run --rm -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) bash -c '\
VAULT=vault/.vault; \
for f in roles/*/vars/main.yml; do [ -f "$$f" ] || continue; \
if grep -q "ANSIBLE_VAULT" "$$f" 2>/dev/null; then \
ansible-vault decrypt --vault-password-file "$$VAULT" "$$f" || true; \
printf "✅ Расшифровано: %s\n" "$$f"; \
else \
printf " Уже расшифровано: %s\n" "$$f"; \
fi; \
done'
rekey-all:
@echo "🔑 Смена пароля для всех roles/*/vars/main.yml ..."
@echo "🔍 Проверка статуса шифрования файлов..."
@UNENCRYPTED_FILES=$$(podman run --rm -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) bash -c '\
for f in roles/*/vars/main.yml; do [ -f "$$f" ] || continue; \
if ! grep -q "ANSIBLE_VAULT" "$$f" 2>/dev/null; then \
echo "$$f"; \
fi; \
done'); \
if [ -n "$$UNENCRYPTED_FILES" ]; then \
echo "❌ Ошибка: Для смены пароля все файлы должны быть зашифрованы!"; \
echo "📋 Незашифрованные файлы:"; \
echo "$$UNENCRYPTED_FILES" | sed 's/^/ - /'; \
echo ""; \
echo "💡 Сначала зашифруйте все файлы командой: make encrypt-all"; \
exit 0; \
fi; \
echo "✅ Все файлы зашифрованы, можно менять пароль"; \
echo "📝 Введите новый пароль для vault:"; \
read -sp "Новый пароль: " NEW_PASSWORD; \
echo ""; \
echo "$$NEW_PASSWORD" > vault/.vault.new; \
chmod 600 vault/.vault.new; \
podman run --rm -it -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) bash -c '\
VAULT=vault/.vault; \
NEW_VAULT=vault/.vault.new; \
for f in roles/*/vars/main.yml; do [ -f "$$f" ] || continue; \
printf "🔑 Смена пароля для: %s\n" "$$f"; \
ansible-vault rekey --vault-password-file "$$VAULT" --new-vault-password-file "$$NEW_VAULT" "$$f" || true; \
printf "✅ Пароль изменен: %s\n" "$$f"; \
done'; \
mv vault/.vault.new vault/.vault; \
echo "✅ Пароль vault обновлен для всех ролей"
# Вспомогательные функции: шифрование/расшифровка ТОЛЬКО одной роли
.PHONY: encrypt-role decrypt-role rekey-role
encrypt-role:
@ROLE_NAME="$(ROLE)"; \
if [ -z "$$ROLE_NAME" ]; then \
echo "📋 Доступные роли:"; \
ls -1 roles | grep -v "\.yml$$" | sed 's/^/ - /'; \
read -p "Введите имя роли: " ROLE_NAME; \
fi; \
if [ ! -d "roles/$$ROLE_NAME" ]; then \
echo "❌ Роль '$$ROLE_NAME' не найдена"; \
exit 0; \
fi; \
FILE="roles/$$ROLE_NAME/vars/main.yml"; \
if [ ! -f "$$FILE" ]; then \
echo "❌ Файл $$FILE не найден"; \
exit 0; \
fi; \
if grep -q "ANSIBLE_VAULT" "$$FILE" 2>/dev/null; then \
echo " Уже зашифровано: $$FILE"; \
exit 0; \
fi; \
podman run --rm -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) bash -c '\
VAULT=vault/.vault; \
ansible-vault encrypt --encrypt-vault-id default --vault-password-file "$$VAULT" "$$1" || true' _ "$$FILE"; \
echo "✅ Зашифровано: $$FILE"
decrypt-role:
@ROLE_NAME="$(ROLE)"; \
if [ -z "$$ROLE_NAME" ]; then \
echo "📋 Доступные роли:"; \
ls -1 roles | grep -v "\.yml$$" | sed 's/^/ - /'; \
read -p "Введите имя роли: " ROLE_NAME; \
fi; \
if [ ! -d "roles/$$ROLE_NAME" ]; then \
echo "❌ Роль '$$ROLE_NAME' не найдена"; \
exit 0; \
fi; \
FILE="roles/$$ROLE_NAME/vars/main.yml"; \
if [ ! -f "$$FILE" ]; then \
echo "❌ Файл $$FILE не найден"; \
exit 0; \
fi; \
if ! grep -q "ANSIBLE_VAULT" "$$FILE" 2>/dev/null; then \
echo " Уже расшифровано: $$FILE"; \
exit 0; \
fi; \
podman run --rm -v "$(PWD):/workspace" -w /workspace $(DOCKER_IMAGE) bash -c '\
VAULT=vault/.vault; \
ansible-vault decrypt --vault-password-file "$$VAULT" "$$1" || true' _ "$$FILE"; \
echo "✅ Расшифровано: $$FILE"
rekey-role:
@ROLE_NAME="$(ROLE)"; \
echo "🔑 Смена пароля для vars/main.yml выбранной роли..."; \
echo "📋 Доступные роли:"; \
ls -1 roles | grep -v "\.yml$$" | sed 's/^/ - /'; \
if [ -z "$$ROLE_NAME" ]; then \
read -p "Введите имя роли: " ROLE_NAME; \
fi; \
if [ ! -d "roles/$$ROLE_NAME" ]; then \
echo "❌ Роль '$$ROLE_NAME' не найдена"; \
echo "📋 Доступные роли:"; \
ls -1 roles | grep -v "\\.yml$$" | sed 's/^/ - /'; \
echo "↩️ Возврат в интерактивный выбор роли для смены пароля..."; \
$(MAKE) vault rekey; \
exit 0; \
fi; \
FILE="roles/$$ROLE_NAME/vars/main.yml"; \
if [ ! -f "$$FILE" ]; then \
echo "❌ Файл $$FILE не найден"; \
exit 1; \
fi; \
if ! grep -q "ANSIBLE_VAULT" "$$FILE" 2>/dev/null; then \
echo " Файл $$FILE не зашифрован, сначала зашифруйте его"; \
exit 1; \
fi; \
podman run --rm -it -v "$(PWD):/workspace" -w /workspace \
-e EDITOR=$(EDITOR) \
$(DOCKER_IMAGE) \
ansible-vault rekey --vault-password-file vault/.vault "$$FILE"; \
echo "✅ Пароль изменен для: $$FILE"
# Очистка контейнеров Molecule
.PHONY: clean-containers
clean-containers:
@echo "🧹 Очистка контейнеров Molecule (Podman)..."
@echo "📋 Поиск контейнеров проекта..."
@podman ps -a --filter "ancestor=inecs/ansible-lab" --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" || true
@echo ""
@echo "🗑️ Удаление контейнеров..."
@podman ps -a --filter "ancestor=inecs/ansible-lab" --format "{{.ID}}" | xargs -r podman rm -f 2>/dev/null || true
@podman ps -a --filter "network=labnet" --format "{{.ID}}" | xargs -r podman rm -f 2>/dev/null || true
@echo "🧹 Очистка сетей..."
@podman network rm labnet 2>/dev/null || true
@echo "✅ Очистка завершена"
# Пустые цели для совместимости
.PHONY: encrypt decrypt
encrypt:
@echo " Команда переименована. Используйте: make encrypt-all или make vault encrypt"
@true
decrypt:
@echo " Команда переименована. Используйте: make decrypt-all или make vault decrypt"
@true
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 build-image:
@true
# Универсальный таргет для всех пресетов и других динамических целей
%:
@: