--- # ============================================================================= # CREATE - Создание тестовых инстансов # ============================================================================= - hosts: localhost gather_facts: false vars: # Получаем preset из переменной окружения или используем default preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}" # Проверяем сначала в папке k8s, затем в основной папке presets preset_file: "{{ '/workspace/molecule/presets/k8s/' + preset_name + '.yml' if (preset_name in ['k8s-minimal', 'kubernetes', 'k8s-full'] or preset_name.startswith('k8s-')) else '/workspace/molecule/presets/' + preset_name + '.yml' }}" # Fallback значения если preset файл не найден (Podman использует ту же сеть) docker_network: labnet podman_network: "{{ docker_network }}" generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini" images: alt9: "inecs/ansible-lab:alt9-latest" alt10: "inecs/ansible-lab:alt10-latest" astra: "inecs/ansible-lab:astra-linux-latest" astra-arm64: "inecs/ansible-lab:astra-linux-arm64-latest" rhel: "inecs/ansible-lab:rhel-latest" centos7: "inecs/ansible-lab:centos7-latest" centos8: "inecs/ansible-lab:centos8-latest" centos9: "inecs/ansible-lab:centos9-latest" alma: "inecs/ansible-lab:alma-latest" rocky: "inecs/ansible-lab:rocky-latest" redos: "inecs/ansible-lab:redos-latest" ubuntu20: "inecs/ansible-lab:ubuntu20-latest" ubuntu22: "inecs/ansible-lab:ubuntu22-latest" ubuntu24: "inecs/ansible-lab:ubuntu24-latest" debian9: "inecs/ansible-lab:debian9-latest" debian10: "inecs/ansible-lab:debian10-latest" debian11: "inecs/ansible-lab:debian11-latest" debian12: "inecs/ansible-lab:debian12-latest" systemd_defaults: privileged: true command: "/sbin/init" volumes: - "/sys/fs/cgroup:/sys/fs/cgroup:rw" tmpfs: ["/run", "/run/lock"] capabilities: ["SYS_ADMIN"] hosts: - name: u1 family: debian groups: [test] kind_clusters: [] tasks: - name: Display running create.yml debug: msg: | ================================================================================ Запуск create.yml ================================================================================ # Определяем архитектуру системы для корректной загрузки образов - name: Detect system architecture shell: | arch=$(uname -m) case $arch in x86_64) echo "linux/amd64" ;; aarch64|arm64) echo "linux/arm64" ;; armv7l) echo "linux/arm/v7" ;; *) echo "linux/amd64" ;; esac register: detected_platform changed_when: false - name: Set ansible_architecture variable set_fact: ansible_architecture: "{{ detected_platform.stdout }}" - name: Load preset configuration include_vars: "{{ preset_file }}" when: preset_file is file ignore_errors: true # Фильтрация хостов по поддерживаемым платформам - name: Filter hosts by supported platforms set_fact: filtered_hosts: "{{ filtered_hosts | default([]) + [item] }}" loop: "{{ hosts }}" when: | item.supported_platforms is not defined or ansible_architecture in item.supported_platforms - name: Update hosts list with filtered results set_fact: hosts: "{{ filtered_hosts | default(hosts) }}" # ============================================================================= # СЕТЕВОЕ ПОДКЛЮЧЕНИЕ (Podman) # ============================================================================= - name: Network setup debug: msg: | ================================================================================ НАСТРОЙКА СЕТИ (Podman) ================================================================================ Network: {{ podman_network | default(docker_network) }} ================================================================================ - name: Ensure network exists containers.podman.podman_network: name: "{{ podman_network | default(docker_network) }}" state: present # ============================================================================= # SYSTEMD NODES - Создание контейнеров с systemd # ============================================================================= - name: Systemd nodes setup debug: msg: | ================================================================================ SYSTEMD NODES - Создание контейнеров с systemd ================================================================================ Count: {{ hosts | selectattr('type','undefined') | list | length }} ================================================================================ # Только локальные образы (registry запрещён). Сборка: make buildall - name: Проверка наличия локальных образов (Podman) command: "podman image exists {{ images[item.family] }}" loop: "{{ hosts | selectattr('type','undefined') | list }}" loop_control: { label: "{{ item.name }}" } when: item.family is defined and images[item.family] is defined register: image_check failed_when: false changed_when: false - name: Остановка при отсутствии локальных образов fail: msg: | Локальные образы не найдены (доступ к registry запрещён). Выполните: make buildall Отсутствуют образы: {{ image_check.results | default([]) | selectattr('rc', 'ne', 0) | map(attribute='item') | map(attribute='family') | list | join(', ') }} when: image_check.results is defined and (image_check.results | selectattr('rc', 'ne', 0) | list | length > 0) - name: Start systemd nodes containers.podman.podman_container: name: "{{ item.name }}" image: "{{ images[item.family] }}" network: "{{ podman_network | default(docker_network) }}" privileged: "{{ systemd_defaults.privileged }}" command: "{{ '/bin/bash -c \"while true; do sleep 30; done\"' if item.family in ['alt10', 'alt9'] else systemd_defaults.command }}" volume: "{{ systemd_defaults.volumes | default([]) + (item.volumes | default([])) + ['/workspace/vault:/workspace/vault:ro', '/workspace/files:/workspace/files:ro', '/workspace/roles:/workspace/roles:ro'] }}" tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}" cap_add: "{{ systemd_defaults.capabilities | default([]) }}" ports: "{{ item.publish | default([]) }}" env: "{{ item.env | default({}) }}" security_opt: "{{ ['seccomp=unconfined', 'apparmor=unconfined'] if item.family in ['astra', 'redos'] else [] }}" state: started restart_policy: "unless-stopped" loop: "{{ hosts | selectattr('type','undefined') | list }}" loop_control: { label: "{{ item.name }}" } when: item.family is defined and images[item.family] is defined # Ожидание стабилизации контейнеров - name: Wait for containers to be ready pause: seconds: 10 when: hosts | length > 0 # Проверка готовности контейнеров (Podman) - name: Wait for containers to be running command: "podman inspect --format '{{ '{{' }}.State.Running{{ '}}' }}' {{ item.name }}" register: container_info loop: "{{ hosts | selectattr('type','undefined') | list }}" loop_control: { label: "{{ item.name }}" } when: item.family is defined and images[item.family] is defined retries: 10 delay: 5 until: container_info.stdout == 'true' # ============================================================================= # POoD NODES - Создание контейнеров Podman-out-of-Podman (сокет Podman) # ============================================================================= - name: POoD nodes setup debug: msg: | ================================================================================ POoD NODES - Контейнеры с монтированием сокета Podman ================================================================================ Count: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }} ================================================================================ - name: Start POoD nodes (systemd + podman.sock mount) containers.podman.podman_container: name: "{{ item.name }}" image: "{{ images[item.family] }}" network: "{{ podman_network | default(docker_network) }}" privileged: "{{ systemd_defaults.privileged }}" command: "{{ systemd_defaults.command }}" volume: "{{ (systemd_defaults.volumes | default([])) + ['/run/podman/podman.sock:/run/podman/podman.sock'] + (item.volumes | default([])) + ['/workspace/vault:/workspace/vault:ro', '/workspace/files:/workspace/files:ro', '/workspace/roles:/workspace/roles:ro'] }}" tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}" cap_add: "{{ systemd_defaults.capabilities | default([]) }}" ports: "{{ item.publish | default([]) }}" env: "{{ (item.env | default({})) | combine({'CONTAINER_HOST': 'unix:///run/podman/podman.sock'}) }}" state: started restart_policy: "unless-stopped" loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}" loop_control: { label: "{{ item.name }}" } when: item.family is defined and images[item.family] is defined # Build groups map - name: Initialize groups map set_fact: groups_map: {} - name: Append hosts to groups set_fact: groups_map: "{{ groups_map | combine({ item_group: (groups_map[item_group] | default([])) + [item_name] }) }}" loop: "{{ hosts | subelements('groups', skip_missing=True) }}" loop_control: label: "{{ item.0.name }}" vars: item_name: "{{ item.0.name }}" item_group: "{{ item.1 }}" # ============================================================================= # ИНВЕНТАРЬ - Генерация inventory файла # ============================================================================= - name: Inventory generation debug: msg: | ================================================================================ ИНВЕНТАРЬ - Генерация inventory файла ================================================================================ File: {{ generated_inventory }} ================================================================================ - name: Render inventory ini set_fact: inv_content: | [all:vars] ansible_connection=containers.podman.podman ansible_remote_tmp=/tmp/.ansible-tmp {% for group, members in (groups_map | dictsort) %} [{{ group }}] {% for h in members %}{{ h }} {% endfor %} {% endfor %} [all] {% for h in hosts %}{{ h.name }} {% endfor %} {# Группа с Debian-based системами (Debian, Ubuntu, Alt) - используем /usr/bin/python3 #} {% set debian_hosts = [] %} {% for h in hosts %} {% if h.family in ['ubuntu', 'debian', 'alt'] %} {% set _ = debian_hosts.append(h.name) %} {% endif %} {% endfor %} {% if debian_hosts %} [debian_family:vars] ansible_python_interpreter=/usr/bin/python3 [debian_family] {% for h in debian_hosts %}{{ h }} {% endfor %} {% endif %} {# Группа с RHEL-based системами (RHEL, CentOS, Alma, Rocky, RedOS) #} {% set rhel_hosts = [] %} {% for h in hosts %} {% if h.family in ['rhel', 'centos', 'alma', 'rocky', 'redos'] %} {% set _ = rhel_hosts.append(h.name) %} {% endif %} {% endfor %} {% if rhel_hosts %} [rhel_family:vars] ansible_python_interpreter=/usr/bin/python3 [rhel_family] {% for h in rhel_hosts %}{{ h }} {% endfor %} {% endif %} {# Astra Linux - используем /usr/bin/python3 #} {% set astra_hosts = [] %} {% for h in hosts %} {% if h.family == 'astra' %} {% set _ = astra_hosts.append(h.name) %} {% endif %} {% endfor %} {% if astra_hosts %} [astra_family:vars] ansible_python_interpreter=/usr/bin/python3 [astra_family] {% for h in astra_hosts %}{{ h }} {% endfor %} {% endif %} {# Глобальный fallback для остальных хостов #} [all:vars] ansible_python_interpreter=auto_silent - name: Write inventory file copy: dest: "{{ generated_inventory }}" content: "{{ inv_content }}" mode: "0644" - name: Display inventory summary shell: | echo "Inventory Summary:" echo "- Total hosts: {{ hosts | length }}" echo "- Groups: {{ groups_map.keys() | list | join(', ') }}" echo "- Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }}" echo "- DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}" echo "- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}" register: inventory_summary_output changed_when: false - name: Show inventory summary debug: msg: "{{ inventory_summary_output.stdout_lines }}" - name: End of create.yml debug: msg: | ================================================================================ Окончание работы create.yml ================================================================================