s3fs: allow turning the mounts off, off on asxpio-ops
On the 38 GB ops disk the s3fs cache reserve (ensure_diskfree) never fit, so all three mounts failed at every boot since 2026-09-22. Backups now go to Hetzner S3 with rclone instead. Add s3fs_enabled (default true); when false the role unmounts the buckets and drops their fstab entries, keeping the credentials file that the rclone wrapper reads. Assisted-by: Claude:opus-5
This commit is contained in:
parent
ad056c97dc
commit
66ab6d8db3
3 changed files with 83 additions and 52 deletions
|
|
@ -6,4 +6,7 @@
|
||||||
ssh_allow_public_git: true
|
ssh_allow_public_git: true
|
||||||
ssh_git_user: git
|
ssh_git_user: git
|
||||||
|
|
||||||
|
# Off: the cache reserve never fit the 38 GB disk, so the mounts failed at
|
||||||
|
# every boot. Backups go to Hetzner S3 with rclone instead.
|
||||||
|
s3fs_enabled: false
|
||||||
s3fs_ensure_diskfree: 20000 # Total:40GB Keep:20GB free = ~15GB for Cache
|
s3fs_ensure_diskfree: 20000 # Total:40GB Keep:20GB free = ~15GB for Cache
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,10 @@ s3_region: "hel1"
|
||||||
s3_access_key: ""
|
s3_access_key: ""
|
||||||
s3_secret_key: ""
|
s3_secret_key: ""
|
||||||
|
|
||||||
|
# false: no mounts. Unmounts and drops the fstab entries; the credentials
|
||||||
|
# file stays (backups use it with rclone, /root/backups/rclone-hetzner.sh).
|
||||||
|
s3fs_enabled: true
|
||||||
|
|
||||||
# S3 Buckets to mount (non-replication buckets only)
|
# S3 Buckets to mount (non-replication buckets only)
|
||||||
s3_buckets:
|
s3_buckets:
|
||||||
- name: asxpio-terraform-main
|
- name: asxpio-terraform-main
|
||||||
|
|
|
||||||
|
|
@ -32,65 +32,89 @@
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
|
||||||
- name: Create mount points for S3 buckets
|
- name: Mount S3 buckets
|
||||||
ansible.builtin.file:
|
when: s3fs_enabled | bool
|
||||||
path: "{{ item.mount_point }}"
|
block:
|
||||||
state: directory
|
- name: Create mount points for S3 buckets
|
||||||
mode: "{{ item.mode }}"
|
ansible.builtin.file:
|
||||||
owner: "{{ item.owner }}"
|
path: "{{ item.mount_point }}"
|
||||||
group: "{{ item.group }}"
|
state: directory
|
||||||
|
mode: "{{ item.mode }}"
|
||||||
|
owner: "{{ item.owner }}"
|
||||||
|
group: "{{ item.group }}"
|
||||||
|
loop: "{{ s3_buckets }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }} -> {{ item.mount_point }}"
|
||||||
|
|
||||||
|
- name: Add S3 buckets to /etc/fstab
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/fstab
|
||||||
|
line: "{{ item.name }} {{ item.mount_point }} fuse.s3fs _netdev,{{ s3fs_options | join(',') }} 0 0"
|
||||||
|
regexp: "^{{ item.name }}\\s+{{ item.mount_point }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ s3_buckets }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }} -> {{ item.mount_point }}"
|
||||||
|
|
||||||
|
- name: Mount all S3 buckets
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "mount {{ item.mount_point }}"
|
||||||
|
loop: "{{ s3_buckets }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }} -> {{ item.mount_point }}"
|
||||||
|
register: mount_result
|
||||||
|
changed_when: mount_result.rc == 0
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Verify S3 buckets are mounted
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "mountpoint -q {{ item.mount_point }}"
|
||||||
|
loop: "{{ s3_buckets }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }} -> {{ item.mount_point }}"
|
||||||
|
register: verify_mount
|
||||||
|
changed_when: false
|
||||||
|
failed_when: verify_mount.rc != 0
|
||||||
|
|
||||||
|
- name: Display mounted S3 buckets
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: |
|
||||||
|
✅ S3 Buckets mounted successfully:
|
||||||
|
{% for bucket in s3_buckets %}
|
||||||
|
- {{ bucket.name }} -> {{ bucket.mount_point }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- name: Test write access to Immich bucket
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "S3FS test file created on {{ ansible_date_time.iso8601 }}"
|
||||||
|
dest: "{{ s3_buckets | selectattr('name', 'equalto', 'asxpio-immich-main') | map(attribute='mount_point') | first }}/.s3fs-test"
|
||||||
|
mode: '0644'
|
||||||
|
when: "'asxpio-immich-main' in s3_buckets | map(attribute='name')"
|
||||||
|
register: write_test
|
||||||
|
|
||||||
|
- name: Remove test file
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ s3_buckets | selectattr('name', 'equalto', 'asxpio-immich-main') | map(attribute='mount_point') | first }}/.s3fs-test"
|
||||||
|
state: absent
|
||||||
|
when: write_test is changed
|
||||||
|
|
||||||
|
- name: Unmount S3 buckets
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "umount {{ item.mount_point }}"
|
||||||
loop: "{{ s3_buckets }}"
|
loop: "{{ s3_buckets }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
label: "{{ item.name }} -> {{ item.mount_point }}"
|
label: "{{ item.mount_point }}"
|
||||||
|
register: umount_result
|
||||||
|
changed_when: umount_result.rc == 0
|
||||||
|
failed_when: false
|
||||||
|
when: not (s3fs_enabled | bool)
|
||||||
|
|
||||||
- name: Add S3 buckets to /etc/fstab
|
- name: Remove S3 buckets from /etc/fstab
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /etc/fstab
|
path: /etc/fstab
|
||||||
line: "{{ item.name }} {{ item.mount_point }} fuse.s3fs _netdev,{{ s3fs_options | join(',') }} 0 0"
|
regexp: "^{{ item.name }}\\s+{{ item.mount_point }}\\s"
|
||||||
regexp: "^{{ item.name }}\\s+{{ item.mount_point }}"
|
|
||||||
state: present
|
|
||||||
loop: "{{ s3_buckets }}"
|
|
||||||
loop_control:
|
|
||||||
label: "{{ item.name }} -> {{ item.mount_point }}"
|
|
||||||
|
|
||||||
- name: Mount all S3 buckets
|
|
||||||
ansible.builtin.command:
|
|
||||||
cmd: "mount {{ item.mount_point }}"
|
|
||||||
loop: "{{ s3_buckets }}"
|
|
||||||
loop_control:
|
|
||||||
label: "{{ item.name }} -> {{ item.mount_point }}"
|
|
||||||
register: mount_result
|
|
||||||
changed_when: mount_result.rc == 0
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Verify S3 buckets are mounted
|
|
||||||
ansible.builtin.command:
|
|
||||||
cmd: "mountpoint -q {{ item.mount_point }}"
|
|
||||||
loop: "{{ s3_buckets }}"
|
|
||||||
loop_control:
|
|
||||||
label: "{{ item.name }} -> {{ item.mount_point }}"
|
|
||||||
register: verify_mount
|
|
||||||
changed_when: false
|
|
||||||
failed_when: verify_mount.rc != 0
|
|
||||||
|
|
||||||
- name: Display mounted S3 buckets
|
|
||||||
ansible.builtin.debug:
|
|
||||||
msg: |
|
|
||||||
✅ S3 Buckets mounted successfully:
|
|
||||||
{% for bucket in s3_buckets %}
|
|
||||||
- {{ bucket.name }} -> {{ bucket.mount_point }}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
- name: Test write access to Immich bucket
|
|
||||||
ansible.builtin.copy:
|
|
||||||
content: "S3FS test file created on {{ ansible_date_time.iso8601 }}"
|
|
||||||
dest: "{{ s3_buckets | selectattr('name', 'equalto', 'asxpio-immich-main') | map(attribute='mount_point') | first }}/.s3fs-test"
|
|
||||||
mode: '0644'
|
|
||||||
when: "'asxpio-immich-main' in s3_buckets | map(attribute='name')"
|
|
||||||
register: write_test
|
|
||||||
|
|
||||||
- name: Remove test file
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ s3_buckets | selectattr('name', 'equalto', 'asxpio-immich-main') | map(attribute='mount_point') | first }}/.s3fs-test"
|
|
||||||
state: absent
|
state: absent
|
||||||
when: write_test is changed
|
loop: "{{ s3_buckets }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }} -> {{ item.mount_point }}"
|
||||||
|
when: not (s3fs_enabled | bool)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue