fix(orchestration): eliminate layer race conditions and secure tier0 git push

This commit is contained in:
v 2026-10-25 08:51:03 +03:00
parent a1df91dd75
commit 2a927ce416
4 changed files with 84 additions and 29 deletions

View file

@ -28,14 +28,20 @@
- /astra/data
- /astra/data/git0
# ================= LXC 103 (git0 - Forgejo GitOps) =================
- name: Check if LXC 103 configuration exists
ansible.builtin.stat:
path: /etc/pve/lxc/103.conf
register: lxc_103_conf
- name: Check if Forgejo database is already seeded on astra
ansible.builtin.stat:
path: /astra/data/git0/data/forgejo.db
register: git0_db_stat
- name: Seed Forgejo data from LXC 103 rootfs to astra (One-time migration)
ansible.builtin.shell: |
set -e
STATUS=$(pct status 103 | awk '{print $2}')
STATUS=$(pct status 103 2>/dev/null | awk '{print $2}' || true)
[ "$STATUS" = "running" ] && pct stop 103
pct mount 103
if [ -d /var/lib/lxc/103/rootfs/var/lib/forgejo ]; then
@ -44,21 +50,35 @@
fi
pct unmount 103
[ "$STATUS" = "running" ] && pct start 103
when: not git0_db_stat.stat.exists
when:
- lxc_103_conf.stat.exists
- not git0_db_stat.stat.exists
- name: Check existing mount points for LXC 103
ansible.builtin.command: >
grep -q "^mp0: /astra/data/git0,mp=/var/lib/forgejo" /etc/pve/lxc/103.conf
register: check_103
changed_when: false
failed_when: false
when: lxc_103_conf.stat.exists
- name: Apply mount points for LXC 103
ansible.builtin.command: pct set 103 -mp0 /astra/data/git0,mp=/var/lib/forgejo
when: check_103.rc != 0
when:
- lxc_103_conf.stat.exists
- check_103.rc is defined and check_103.rc != 0
register: apply_103
- name: Reboot LXC 103 to apply pending mount points
ansible.builtin.command: pct reboot 103
when: apply_103.changed
when: apply_103.changed | default(false)
# ================= LXC 104 (storage0 - NAS) =================
- name: Check if LXC 104 configuration exists
ansible.builtin.stat:
path: /etc/pve/lxc/104.conf
register: lxc_104_conf
- name: Check existing mount points for LXC 104
ansible.builtin.command: >
grep -q "^{{ item.id }}: {{ item.src }},mp={{ item.dest }}" /etc/pve/lxc/104.conf
@ -71,22 +91,32 @@
- { id: 'mp2', src: '/terra/vault', dest: '/backups' }
- { id: 'mp3', src: '/terra/models', dest: '/models' }
- { id: 'mp4', src: '/terra/packages', dest: '/packages' }
when: lxc_104_conf.stat.exists
- name: Apply mount points for LXC 104
ansible.builtin.command: pct set 104 -{{ item.item.id }} {{ item.item.src }},mp={{ item.item.dest }}
when: item.rc != 0
when:
- lxc_104_conf.stat.exists
- item.rc is defined and item.rc != 0
register: apply_104
loop: "{{ check_104.results }}"
loop: "{{ check_104.results | default([]) }}"
loop_control:
label: "{{ item.item.id }}"
- name: Configure AppArmor unconfined for LXC 104 kernel NFS
ansible.builtin.lineinfile:
path: /etc/pve/lxc/104.conf
line: "lxc.apparmor.profile: unconfined"
state: present
register: apparmor_104
when: lxc_104_conf.stat.exists
- name: Reboot LXC 104 to apply mounts and AppArmor
ansible.builtin.command: pct reboot 104
when: apply_104.changed or apparmor_104.changed
when:
- lxc_104_conf.stat.exists
- (apply_104.changed | default(false)) or (apparmor_104.changed | default(false))
- name: Ensure SSH server is initialized and running in LXC 104 (Alpine)
ansible.builtin.shell: |
pct exec 104 -- sh -c '
@ -96,7 +126,14 @@
rc-service sshd status | grep -q started || rc-service sshd start
'
changed_when: false
when: lxc_104_conf.stat.exists
# ================= LXC 105 (registry0 - Zot OCI) =================
- name: Check if LXC 105 configuration exists
ansible.builtin.stat:
path: /etc/pve/lxc/105.conf
register: lxc_105_conf
- name: Check existing mount points for LXC 105
ansible.builtin.command: >
grep -q "^{{ item.id }}: {{ item.src }},mp={{ item.dest }}" /etc/pve/lxc/105.conf
@ -105,16 +142,24 @@
failed_when: false
loop:
- { id: 'mp0', src: '/terra/registry', dest: '/mnt/registry' }
when: lxc_105_conf.stat.exists
- name: Apply mount points for LXC 105
ansible.builtin.command: pct set 105 -{{ item.item.id }} {{ item.item.src }},mp={{ item.item.dest }}
when: item.rc != 0
when:
- lxc_105_conf.stat.exists
- item.rc is defined and item.rc != 0
register: apply_105
loop: "{{ check_105.results }}"
loop: "{{ check_105.results | default([]) }}"
loop_control:
label: "{{ item.item.id }}"
- name: Reboot LXC 105 to apply pending mount points
ansible.builtin.command: pct reboot 105
when: apply_105.changed
when:
- lxc_105_conf.stat.exists
- apply_105.changed | default(false)
# ================= DAY-0 OS IMAGES & TEMPLATES (SSOT) =================
- name: Update pveam repository catalog
ansible.builtin.command: pveam update

View file

@ -4,6 +4,23 @@ source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh"
ensure_prerequisites
load_secrets_to_ram
log_info "[Layer 0: PVE Host] Накатка директорий и прав ZFS..."
log_info "[Layer 0: PVE Host] Подготовка хоста, шаблонов и базовых директорий ZFS..."
ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/01_pve_host_day0.yml"
log_ok "Layer 0 готов."
log_info "[Layer 0: PVE Host] Инициализация compute-скелетов ВМ и LXC через OpenTofu..."
cd "${REPO_ROOT}/tofu" && tofu apply \
-target=proxmox_virtual_environment_vm.vyos_router \
-target=proxmox_virtual_environment_container.dns0 \
-target=proxmox_virtual_environment_container.vault0 \
-target=proxmox_virtual_environment_container.git0 \
-target=proxmox_virtual_environment_container.storage0 \
-target=proxmox_virtual_environment_container.registry0 \
-target=proxmox_virtual_environment_vm.talos_master_1 \
-target=proxmox_virtual_environment_vm.talos_worker_1 \
-target=proxmox_virtual_environment_vm.talos_worker_2 \
-auto-approve
log_info "[Layer 0: PVE Host] Применение постоянных ZFS-маунтов (mp) на созданные LXC..."
ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/01_pve_host_day0.yml"
log_ok "Layer 0 готов: хост настроен, ВМ и LXC созданы, ZFS смонтирован."

View file

@ -4,16 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh"
ensure_prerequisites
load_secrets_to_ram
log_info "[Layer 2: Tier-0 Air-Gap] Подъем базовых контейнеров через Tofu..."
cd "${REPO_ROOT}/tofu" && tofu apply -target=proxmox_virtual_environment_container.dns0 \
-target=proxmox_virtual_environment_container.vault0 \
-target=proxmox_virtual_environment_container.git0 \
-target=proxmox_virtual_environment_container.storage0 \
-target=proxmox_virtual_environment_container.registry0 -auto-approve
log_info "[Layer 2: Tier-0 Air-Gap] Применение ZFS-маунтов и прав на хосте Proxmox..."
ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/01_pve_host_day0.yml"
log_info "[Layer 2: Tier-0 Air-Gap] Развертывание базовой инфраструктуры (Registry, DNS, Vault)..."
for pb in 03_zot_registry.yml 04_technitium_dns.yml 05_openbao_vault.yml; do
ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/${pb}"
@ -30,7 +20,9 @@ for pb in 06_forgejo_git.yml 07_nas_storage.yml; do
ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/${pb}"
done
log_info "[Layer 2: Tier-0 Air-Gap] Автоматическая первичная синхронизация Git в Forgejo..."
git -C "${REPO_ROOT}" push -u origin master 2>/dev/null || git -C "${REPO_ROOT}" push 2>/dev/null || true
log_info "[Layer 2: Tier-0 Air-Gap] Автоматическая первичная синхронизация Git в Forgejo (SEC-03 RAM auth)..."
CURRENT_BRANCH=$(git -C "${REPO_ROOT}" branch --show-current 2>/dev/null || echo "master")
git -C "${REPO_ROOT}" push -u http://10.0.10.13:3000/atlas/atlas.git "${CURRENT_BRANCH}" 2>/dev/null || \
git -C "${REPO_ROOT}" push http://10.0.10.13:3000/atlas/atlas.git "${CURRENT_BRANCH}" 2>/dev/null || true
log_ok "Layer 2 готов. Базовые сервисы, секреты и GitOps-репозиторий развернуты."

View file

@ -1,23 +1,24 @@
#!/bin/bash
# Network routing and terminal prerequisites
ensure_prerequisites() {
local target_ip="${VAULT_ADDR#*//}"
target_ip="${target_ip%%:*}"
if ! ip route get "${target_ip}" 2>/dev/null | grep -q "${VYOS_ROUTER_IP}"; then
log_info "Восстанавливаем маршрут к ${NET_PREFIX} через VyOS (${VYOS_ROUTER_IP})..."
sudo ip route replace "${NET_PREFIX}" via "${VYOS_ROUTER_IP}" 2>/dev/null || true
fi
# Регистрация Git Credential Helper
# Регистрация Git Credential Helper (доменный и прямой IP Tier-0)
local target_helper="!${REPO_ROOT}/deploy.sh git-credential"
local current_helper
current_helper=$(git config --global --get credential."https://${GIT_HOST}".helper 2>/dev/null || true)
if [[ "${current_helper}" != "${target_helper}" ]]; then
git config --global credential."https://${GIT_HOST}".helper "${target_helper}"
fi
local direct_helper
direct_helper=$(git config --global --get credential."http://10.0.10.13:3000".helper 2>/dev/null || true)
if [[ "${direct_helper}" != "${target_helper}" ]]; then
git config --global credential."http://10.0.10.13:3000".helper "${target_helper}"
fi
# Нативная привязка IdentityFile для всех C2-хостов и LXC-контейнеров
local ssh_hosts="proxmox pve0 vyos vyos_router 10.0.* dns0 vault0 git0 storage0 registry0"
if [[ -f "${HOME}/.ssh/config" ]] && ! grep -q "IdentityFile ${RAM_KEY}" "${HOME}/.ssh/config"; then