feat: update BetterShift configuration to use dynamic versioning and enhance backup procedures

This commit is contained in:
martin.fencl
2026-11-10 10:19:51 +01:00
parent 12edc09589
commit f91ffffe83
3 changed files with 97 additions and 50 deletions
Vendored
BIN
View File
Binary file not shown.
@@ -1,9 +1,11 @@
# docker-compose/docker-compose-bettershift.yml
name: bettershift name: bettershift
services: services:
bettershift: bettershift:
container_name: bettershift container_name: bettershift
image: ghcr.io/pantelx/bettershift:v2.2.1 image: ghcr.io/pantelx/bettershift:${BETTERSHIFT_VERSION:-v2.2.1}
restart: unless-stopped restart: unless-stopped
ports: ports:
+94 -49
View File
@@ -1,85 +1,130 @@
# update_bettershift.yml # update_bettershift.yml
---
- name: Update BetterShift - name: Update BetterShift
hosts: pve2_vm hosts: pve2_vm
gather_facts: false gather_facts: false
become: true
vars: vars:
compose_local_dir: "{{ playbook_dir }}/docker-compose" compose_local_dir: "{{ playbook_dir }}/docker-compose"
compose_remote_base: "/home/{{ ansible_user }}/.ansible-compose/docker-compose" compose_remote_base: "/home/{{ ansible_user }}/.ansible-compose/docker-compose"
bettershift_project: bettershift bettershift_project: bettershift
bettershift_compose_filename: "docker-compose-bettershift.yml" bettershift_compose_filename: docker-compose-bettershift.yml
bettershift_service: bettershift bettershift_service: bettershift
bettershift_port: 3067 bettershift_port: 3067
bettershift_data_dir: "/data/compose/bettershift/data" bettershift_data_dir: /data/compose/bettershift/data
bettershift_version: v3.3.0
environment:
BETTERSHIFT_VERSION: "{{ bettershift_version }}"
tasks: tasks:
- name: Ensure remote compose directory exists - name: Check existing database and env file
ansible.builtin.file: ansible.builtin.stat:
path: "{{ compose_remote_base }}" path: "{{ item }}"
state: directory loop:
mode: "0755" - "{{ bettershift_data_dir }}/sqlite.db"
- "{{ compose_remote_base }}/.env.bettershift"
register: bettershift_files
- name: Ensure BetterShift data directory exists - name: Refuse missing or empty files
ansible.builtin.file: ansible.builtin.assert:
path: "{{ bettershift_data_dir }}" that:
state: directory - item.stat.isreg | default(false)
mode: "0755" - item.stat.size | default(0) > 0
fail_msg: "Missing or empty file: {{ item.item }}"
loop: "{{ bettershift_files.results }}"
loop_control:
label: "{{ item.item }}"
- name: Upload BetterShift compose file to remote host - name: Check database before changing deployment
ansible.builtin.command:
argv:
- python3
- -c
- |
import pathlib, sqlite3, sys
path = pathlib.Path(sys.argv[1])
with sqlite3.connect(path.as_uri() + '?mode=ro', uri=True) as src:
with sqlite3.connect(':memory:') as db:
src.backup(db)
integrity = db.execute('PRAGMA integrity_check').fetchall()
errors = db.execute('PRAGMA foreign_key_check').fetchall()
print('Integrity:', integrity, 'Foreign key violations:', errors)
sys.exit(0 if integrity == [('ok',)] and not errors else 1)
- "{{ bettershift_data_dir }}/sqlite.db"
changed_when: false
- name: Upload BetterShift compose file
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ compose_local_dir }}/{{ bettershift_compose_filename }}" src: "{{ compose_local_dir }}/{{ bettershift_compose_filename }}"
dest: "{{ compose_remote_base }}/{{ bettershift_compose_filename }}" dest: "{{ compose_remote_base }}/{{ bettershift_compose_filename }}"
mode: "0644" mode: '0644'
backup: true
- name: Check BetterShift env file exists on remote host - name: Pull image without starting it
ansible.builtin.stat: community.docker.docker_compose_v2_pull:
path: "{{ compose_remote_base }}/.env.bettershift" project_name: "{{ bettershift_project }}"
register: bettershift_env_file project_src: "{{ compose_remote_base }}"
files: ["{{ bettershift_compose_filename }}"]
- name: Fail if BetterShift env file is missing - name: Create private backup directory
ansible.builtin.fail: ansible.builtin.tempfile:
msg: >- state: directory
Missing {{ compose_remote_base }}/.env.bettershift on remote host. path: /data/compose/bettershift
Create it manually because it contains secrets. prefix: backup-before-upgrade-
when: not bettershift_env_file.stat.exists register: bettershift_backup
- name: Pull latest BetterShift image - name: Show backup location
ansible.builtin.debug:
msg: "Backup: {{ bettershift_backup.path }}"
- name: Stop service and create a verified backup
block:
- name: Stop BetterShift
ansible.builtin.command:
argv: [docker, stop, --timeout, '60', bettershift]
changed_when: true
- name: Copy data and compare files
ansible.builtin.shell: |
set -eu
test "$(docker inspect --format '{% raw %}{{.State.Running}}{% endraw %}' bettershift)" = false
cp -a -- "$DATA_DIR" "$BACKUP_DIR/data"
diff -qr -- "$DATA_DIR" "$BACKUP_DIR/data"
environment:
DATA_DIR: "{{ bettershift_data_dir }}"
BACKUP_DIR: "{{ bettershift_backup.path }}"
changed_when: true
rescue:
- name: Restart original container if backup fails
ansible.builtin.command:
argv: [docker, start, bettershift]
changed_when: true
- name: Abort update
ansible.builtin.fail:
msg: Backup failed. Original container restarted; update aborted.
- name: Recreate BetterShift once
community.docker.docker_compose_v2: community.docker.docker_compose_v2:
project_name: "{{ bettershift_project }}" project_name: "{{ bettershift_project }}"
project_src: "{{ compose_remote_base }}" project_src: "{{ compose_remote_base }}"
files: files: ["{{ bettershift_compose_filename }}"]
- "{{ bettershift_compose_filename }}" services: ["{{ bettershift_service }}"]
pull: always
- name: Recreate BetterShift service
community.docker.docker_compose_v2:
project_name: "{{ bettershift_project }}"
project_src: "{{ compose_remote_base }}"
files:
- "{{ bettershift_compose_filename }}"
services:
- "{{ bettershift_service }}"
state: present state: present
pull: never
recreate: always recreate: always
- name: Wait for BetterShift port
ansible.builtin.wait_for:
host: 127.0.0.1
port: "{{ bettershift_port }}"
timeout: 60
- name: Check BetterShift HTTP endpoint - name: Check BetterShift HTTP endpoint
ansible.builtin.uri: ansible.builtin.uri:
url: "http://127.0.0.1:{{ bettershift_port }}/" url: "http://127.0.0.1:{{ bettershift_port }}/"
status_code: status_code: [200, 307, 308]
- 200
- 307
- 308
follow_redirects: none follow_redirects: none
register: bettershift_http register: bettershift_http
retries: 30 retries: 30
delay: 3 delay: 3
until: bettershift_http.status in [200, 307, 308] until: bettershift_http.status | default(0) in [200, 307, 308]
changed_when: false changed_when: false