mirror of
https://github.com/fscotto/infra.git
synced 2026-10-03 21:39:50 +00:00
Enable boot startup for Atlas iCloudPD
This commit is contained in:
@@ -61,7 +61,7 @@ Ansible-driven personal infrastructure repo for Fedora and Void desktops, Fedora
|
|||||||
`ansible-playbook ansible/site.yml --limit atlas --tags storage,sharing,containers --check --diff`
|
`ansible-playbook ansible/site.yml --limit atlas --tags storage,sharing,containers --check --diff`
|
||||||
- Atlas rootless Gitea staging (does not start Gitea):
|
- Atlas rootless Gitea staging (does not start Gitea):
|
||||||
`ansible-playbook ansible/site.yml --limit atlas --tags gitea --check --diff`
|
`ansible-playbook ansible/site.yml --limit atlas --tags gitea --check --diff`
|
||||||
- Atlas iCloudPD storage and inactive Quadlet (does not start it):
|
- Atlas iCloudPD storage and boot-started Quadlet:
|
||||||
`ansible-playbook ansible/site.yml --limit atlas --tags icloudpd --check --diff`
|
`ansible-playbook ansible/site.yml --limit atlas --tags icloudpd --check --diff`
|
||||||
- Atlas explicit Gitea host-owner migration (live outage; never a normal run):
|
- Atlas explicit Gitea host-owner migration (live outage; never a normal run):
|
||||||
`ansible-playbook ansible/site.yml --limit atlas --tags gitea_owner_migration -e atlas_gitea_owner_migration=true`
|
`ansible-playbook ansible/site.yml --limit atlas --tags gitea_owner_migration -e atlas_gitea_owner_migration=true`
|
||||||
@@ -375,8 +375,10 @@ successfully. The first monthly scrub remains a runtime check.
|
|||||||
- [x] Deploy the declared Atlas iCloudPD state dataset and inactive rootless `admin` Quadlet.
|
- [x] Deploy the declared Atlas iCloudPD state dataset and inactive rootless `admin` Quadlet.
|
||||||
Photos belong under `/zpool/archive/Pictures/iCloudPD`; private config/MFA state belongs in
|
Photos belong under `/zpool/archive/Pictures/iCloudPD`; private config/MFA state belongs in
|
||||||
`zpool/services/data/icloudpd`. Photobook remains reserved for Immich. Ansible now renders
|
`zpool/services/data/icloudpd`. Photobook remains reserved for Immich. Ansible now renders
|
||||||
`icloudpd.conf` with the Apple ID from the existing Vault key, but does not store the password,
|
`icloudpd.conf` with the Apple ID from the existing Vault key, but does not store the password
|
||||||
manage MFA, or enable automatic startup. The isolated no-network layout test is documented in
|
or manage MFA. Automatic startup was approved on 2026-10-03; the Quadlet now
|
||||||
|
uses `WantedBy=default.target` and Ansible keeps the service running.
|
||||||
|
The isolated no-network layout test is documented in
|
||||||
`docs/atlas-icloudpd-migration.md`. On 2026-10-02 Atlas deployment and a second idempotent run
|
`docs/atlas-icloudpd-migration.md`. On 2026-10-02 Atlas deployment and a second idempotent run
|
||||||
passed; no app config existed at deployment. A manual first start on 2026-10-02 generated
|
passed; no app config existed at deployment. A manual first start on 2026-10-02 generated
|
||||||
`icloudpd.conf`; an Ansible run then replaced it with a private mode-0600 Vault-backed template
|
`icloudpd.conf`; an Ansible run then replaced it with a private mode-0600 Vault-backed template
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
- atlas_icloudpd_image is search('@sha256:[0-9a-f]{64}$')
|
- atlas_icloudpd_image is search('@sha256:[0-9a-f]{64}$')
|
||||||
fail_msg: Verify the fixed, separate Atlas iCloudPD photo and state paths.
|
fail_msg: Verify the fixed, separate Atlas iCloudPD photo and state paths.
|
||||||
|
|
||||||
- name: Declare inactive rootless Atlas iCloudPD storage and Quadlet
|
- name: Declare rootless Atlas iCloudPD storage and boot-started Quadlet
|
||||||
tags: [atlas, icloudpd]
|
tags: [atlas, icloudpd]
|
||||||
block:
|
block:
|
||||||
- name: Inspect the existing Archive and application-data datasets
|
- name: Inspect the existing Archive and application-data datasets
|
||||||
@@ -162,4 +162,27 @@
|
|||||||
owner: "{{ atlas_admin_username }}"
|
owner: "{{ atlas_admin_username }}"
|
||||||
group: "{{ atlas_admin_group }}"
|
group: "{{ atlas_admin_group }}"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
notify: Reload Atlas admin user manager
|
register: atlas_icloudpd_quadlet
|
||||||
|
|
||||||
|
- name: Reload the Atlas admin user manager after iCloudPD Quadlet changes
|
||||||
|
become_user: "{{ atlas_admin_username }}"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
scope: user
|
||||||
|
daemon_reload: true
|
||||||
|
environment:
|
||||||
|
XDG_RUNTIME_DIR: "/run/user/{{ atlas_admin_uid }}"
|
||||||
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ atlas_admin_uid }}/bus"
|
||||||
|
when:
|
||||||
|
- atlas_icloudpd_quadlet.changed
|
||||||
|
- not ansible_check_mode
|
||||||
|
|
||||||
|
- name: Keep the rootless Atlas iCloudPD service running
|
||||||
|
become_user: "{{ atlas_admin_username }}"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: atlas-icloudpd.service
|
||||||
|
scope: user
|
||||||
|
state: started
|
||||||
|
environment:
|
||||||
|
XDG_RUNTIME_DIR: "/run/user/{{ atlas_admin_uid }}"
|
||||||
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ atlas_admin_uid }}/bus"
|
||||||
|
when: not ansible_check_mode
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
- name: Import staged Atlas rootless Gitea tasks
|
- name: Import staged Atlas rootless Gitea tasks
|
||||||
ansible.builtin.import_tasks: gitea.yml
|
ansible.builtin.import_tasks: gitea.yml
|
||||||
|
|
||||||
- name: Import Atlas iCloudPD storage and inactive Quadlet tasks
|
- name: Import Atlas iCloudPD storage and boot-started Quadlet tasks
|
||||||
ansible.builtin.import_tasks: icloudpd.yml
|
ansible.builtin.import_tasks: icloudpd.yml
|
||||||
|
|
||||||
- name: Import explicit Atlas Gitea restore rehearsal tasks
|
- name: Import explicit Atlas Gitea restore rehearsal tasks
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Managed by Ansible. No install target or automatic start.
|
# Managed by Ansible. Start automatically with the lingering admin user manager.
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Atlas rootless iCloud Photos Downloader
|
Description=Atlas rootless iCloud Photos Downloader
|
||||||
RequiresMountsFor={{ atlas_icloudpd_state_dir }} {{ atlas_icloudpd_photos_dir }}
|
RequiresMountsFor={{ atlas_icloudpd_state_dir }} {{ atlas_icloudpd_photos_dir }}
|
||||||
@@ -20,3 +20,6 @@ NoNewPrivileges=true
|
|||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=300
|
RestartSec=300
|
||||||
TimeoutStartSec=900
|
TimeoutStartSec=900
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
|||||||
@@ -55,11 +55,12 @@ path, user/UID, and folder format as the bind mounts. References:
|
|||||||
|
|
||||||
The photo subtree receives a managed marker and the image's `.mounted` file.
|
The photo subtree receives a managed marker and the image's `.mounted` file.
|
||||||
An existing unmarked path is refused rather than taken over. The existing
|
An existing unmarked path is refused rather than taken over. The existing
|
||||||
Pictures tree is not chowned or emptied. The Quadlet has no `[Install]`
|
Pictures tree is not chowned or emptied. The Quadlet now has `[Install]` with
|
||||||
section, so Ansible does not start or enable it. Ansible renders a mode-0600
|
`WantedBy=default.target`, so the lingering admin user manager starts it at boot.
|
||||||
|
Ansible keeps the service running. Ansible renders a mode-0600
|
||||||
`icloudpd.conf` with `no_log` and no diff, but does not pull the image,
|
`icloudpd.conf` with `no_log` and no diff, but does not pull the image,
|
||||||
initialize MFA, or run a cutover task. The service was started manually and
|
initialize MFA, or run a cutover task. Boot startup was approved on 2026-10-03
|
||||||
will not start automatically after reboot under this design.
|
after a reboot left the previously manual-started service inactive.
|
||||||
|
|
||||||
The previous gated check-mode tests and isolated Quadlet-generator test proved
|
The previous gated check-mode tests and isolated Quadlet-generator test proved
|
||||||
only the proposed layout; they predate the simplified declarative role. They
|
only the proposed layout; they predate the simplified declarative role. They
|
||||||
@@ -110,8 +111,8 @@ completed backup or restore of iCloudPD data**, which did not exist at the time.
|
|||||||
on first start. Ansible replaced that default file with a private template
|
on first start. Ansible replaced that default file with a private template
|
||||||
using the Apple ID already in Vault. The operator initialized password
|
using the Apple ID already in Vault. The operator initialized password
|
||||||
and MFA interactively; never put credentials or codes in the repository,
|
and MFA interactively; never put credentials or codes in the repository,
|
||||||
chat, or Ansible extra-vars. The Quadlet has no automatic boot start;
|
chat, or Ansible extra-vars. Automatic boot startup was separately approved
|
||||||
enablement requires a separate deliberate design change.
|
on 2026-10-03; this does not change the interactive MFA procedure.
|
||||||
- Initial ingestion completed on 2026-10-03. Still check folder structure,
|
- Initial ingestion completed on 2026-10-03. Still check folder structure,
|
||||||
ownership, SELinux and SMB access, no unintended deletions, the next daily
|
ownership, SELinux and SMB access, no unintended deletions, the next daily
|
||||||
cycle, completed Borg and USB versions, and isolated restore of photos and
|
cycle, completed Borg and USB versions, and isolated restore of photos and
|
||||||
@@ -161,3 +162,12 @@ is a filesystem file count, not a count of distinct iCloud assets. A later
|
|||||||
read-only check found the service still active. This closes initial
|
read-only check found the service still active. This closes initial
|
||||||
authentication and ingestion only: a subsequent daily cycle and end-to-end
|
authentication and ingestion only: a subsequent daily cycle and end-to-end
|
||||||
recovery of the new photos and private state remain untested.
|
recovery of the new photos and private state remain untested.
|
||||||
|
|
||||||
|
On 2026-10-03 Atlas rebooted at 10:17 CEST; iCloudPD stayed inactive because
|
||||||
|
its Quadlet had no install target. A manual start restored the running service
|
||||||
|
and the application began listing iCloud files. The operator then approved
|
||||||
|
persistent boot startup. The managed Quadlet now declares
|
||||||
|
`WantedBy=default.target`; the live generator created
|
||||||
|
`default.target.wants/atlas-icloudpd.service`, admin has `Linger=yes`, and the
|
||||||
|
service remained active with zero restarts. No NAS reboot was performed to
|
||||||
|
test this change; actual post-reboot startup remains untested.
|
||||||
|
|||||||
Reference in New Issue
Block a user