Make /opt/stack a Forgejo git checkout instead of rsync-only
Prefer stack_deploy_method=git: init/fetch on the server, register an SSH deploy key with Forgejo, and leave local secrets untracked. Document git pull for day-to-day updates; keep rsync as an opt-in fallback.
This commit is contained in:
parent
6c9e085cbd
commit
90f3cf62c5
4 changed files with 159 additions and 10 deletions
|
|
@ -47,14 +47,142 @@
|
|||
loop: "{{ media_subdirs }}"
|
||||
tags: [stack, storage]
|
||||
|
||||
- name: Deploy stack files from control machine
|
||||
# ---------------------------------------------------------------------------
|
||||
# Code deploy: git (preferred) or rsync
|
||||
# Local-only paths stay untracked: config/, .env, models/*.gguf, wireguard/wg0.conf
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
- name: Ensure git is installed on stack host
|
||||
ansible.builtin.apt:
|
||||
name: git
|
||||
state: present
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Ensure stack owner has an SSH key for Forgejo git
|
||||
become: true
|
||||
become_user: "{{ stack_owner }}"
|
||||
ansible.builtin.user:
|
||||
name: "{{ stack_owner }}"
|
||||
generate_ssh_key: true
|
||||
ssh_key_type: ed25519
|
||||
ssh_key_file: "/home/{{ stack_owner }}/.ssh/id_ed25519"
|
||||
ssh_key_comment: "{{ stack_owner }}@{{ inventory_hostname }}-forgejo"
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Read stack owner public key
|
||||
ansible.builtin.slurp:
|
||||
src: "/home/{{ stack_owner }}/.ssh/id_ed25519.pub"
|
||||
register: stack_owner_pubkey
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Ensure Forgejo knows the stack host deploy key (idempotent via API best-effort)
|
||||
ansible.builtin.shell: |
|
||||
set -e
|
||||
PUB='{{ stack_owner_pubkey.content | b64decode | trim }}'
|
||||
# Create a short-lived admin token, add key if fingerprint not present, drop token
|
||||
TOKEN=$(docker exec -u 1000 forgejo gitea admin user generate-access-token \
|
||||
--username "{{ stack_owner }}" \
|
||||
--token-name "ansible-deploy-$(date +%s)" \
|
||||
--scopes all 2>/dev/null | awk '/Access token was successfully created:/{print $NF}')
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "Could not create Forgejo token (is forgejo up?). Continuing — key may already exist."
|
||||
exit 0
|
||||
fi
|
||||
# List keys; add if title missing
|
||||
if curl -fsS -H "Authorization: token $TOKEN" http://127.0.0.1:3002/api/v1/user/keys \
|
||||
| grep -q "ansible-ser5\|{{ inventory_hostname }}-forgejo"; then
|
||||
echo "SSH key already registered"
|
||||
else
|
||||
curl -fsS -X POST http://127.0.0.1:3002/api/v1/user/keys \
|
||||
-H "Authorization: token $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"title\":\"ansible-{{ inventory_hostname }}\",\"key\":\"$PUB\"}" || true
|
||||
fi
|
||||
args:
|
||||
executable: /bin/bash
|
||||
when:
|
||||
- deploy_stack_files | bool
|
||||
- stack_deploy_method == "git"
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Initialize git repo in stack root if missing
|
||||
become: true
|
||||
become_user: "{{ stack_owner }}"
|
||||
ansible.builtin.command: git init -b {{ stack_git_branch }}
|
||||
args:
|
||||
chdir: "{{ stack_root }}"
|
||||
creates: "{{ stack_root }}/.git"
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Configure origin remote
|
||||
become: true
|
||||
become_user: "{{ stack_owner }}"
|
||||
ansible.builtin.shell: |
|
||||
set -e
|
||||
cd "{{ stack_root }}"
|
||||
if git remote get-url origin >/dev/null 2>&1; then
|
||||
git remote set-url origin "{{ stack_git_repo }}"
|
||||
else
|
||||
git remote add origin "{{ stack_git_repo }}"
|
||||
fi
|
||||
args:
|
||||
executable: /bin/bash
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
changed_when: true
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Mark stack root as safe.directory for git
|
||||
become: true
|
||||
become_user: "{{ stack_owner }}"
|
||||
ansible.builtin.command: git config --global --add safe.directory {{ stack_root }}
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Fetch and hard-reset tracked files to origin (keeps untracked secrets)
|
||||
become: true
|
||||
become_user: "{{ stack_owner }}"
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
cd "{{ stack_root }}"
|
||||
export GIT_SSH_COMMAND="ssh -i /home/{{ stack_owner }}/.ssh/id_ed25519 -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new"
|
||||
git fetch origin "{{ stack_git_branch }}"
|
||||
# Preserve local-only paths; only reset tracked files
|
||||
git checkout -B "{{ stack_git_branch }}" "origin/{{ stack_git_branch }}"
|
||||
args:
|
||||
executable: /bin/bash
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
register: stack_git_pull
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Show git HEAD after pull
|
||||
become: true
|
||||
become_user: "{{ stack_owner }}"
|
||||
ansible.builtin.command: git -C {{ stack_root }} log -1 --oneline
|
||||
register: stack_git_head
|
||||
changed_when: false
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Report stack git revision
|
||||
ansible.builtin.debug:
|
||||
msg: "stack @ {{ stack_git_head.stdout | default('n/a') }}"
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "git"
|
||||
tags: [stack, deploy, git]
|
||||
|
||||
- name: Deploy stack files from control machine (rsync fallback)
|
||||
ansible.posix.synchronize:
|
||||
src: "{{ stack_src }}/"
|
||||
dest: "{{ stack_root }}/"
|
||||
delete: false
|
||||
recursive: true
|
||||
# Non-root rsync cannot chown/chgrp files Docker created as root
|
||||
# (e.g. searxng). Content sync only; ownership fixed in next task.
|
||||
archive: true
|
||||
owner: false
|
||||
group: false
|
||||
|
|
@ -72,11 +200,11 @@
|
|||
- "--no-owner"
|
||||
- "--no-group"
|
||||
- "--chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r"
|
||||
when: deploy_stack_files | bool
|
||||
when: deploy_stack_files | bool and stack_deploy_method == "rsync"
|
||||
become: false
|
||||
tags: [stack, deploy]
|
||||
tags: [stack, deploy, rsync]
|
||||
|
||||
- name: Fix ownership after rsync
|
||||
- name: Fix ownership of stack tree
|
||||
ansible.builtin.file:
|
||||
path: "{{ stack_root }}"
|
||||
state: directory
|
||||
|
|
@ -84,7 +212,6 @@
|
|||
group: "{{ stack_group }}"
|
||||
recurse: true
|
||||
when: deploy_stack_files | bool
|
||||
# become: true from play — can reset root-owned files from containers
|
||||
tags: [stack, deploy]
|
||||
|
||||
- name: Deploy production .env for this host
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue