/
/
/
Ansible role that deployss my nas configuration. It mostly handles nfs configurations and exports that are tailored to the hardware and service configuration.
1---
2# ============================================================================
3# Docker / Storage Mount Boot Ordering
4# ============================================================================
5# Problem this solves:
6# Docker has no ordering dependency on the storage mount by default, and the
7# array is mounted with 'nofail'. After an unclean shutdown mdadm assembly is
8# slow, so Docker can start containers BEFORE {{ nas_storage_base }} is
9# mounted. Any container bind-mounting that path then latches onto the empty
10# pre-mount directory on the root filesystem instead of the array. Containers
11# keep running against the wrong filesystem and report the root LV's capacity
12# rather than the array's - silently, with no error anywhere.
13#
14# RequiresMountsFor= makes systemd order docker.service after the generated
15# mount unit for that path (and pull it in), so containers only ever start
16# once the array is really mounted.
17# ============================================================================
18
19- name: Check whether docker is installed on this host
20 stat:
21 path: /lib/systemd/system/docker.service
22 register: nas_docker_unit
23
24- name: Resolve systemd mount unit name for the storage base
25 command: "systemd-escape --path --suffix=mount {{ nas_storage_base }}"
26 register: nas_storage_mount_unit
27 changed_when: false
28 check_mode: false
29 when: nas_docker_unit.stat.exists
30
31- name: Create docker.service drop-in directory
32 file:
33 path: /etc/systemd/system/docker.service.d
34 state: directory
35 mode: '0755'
36 owner: root
37 group: root
38 become: true
39 when: nas_docker_unit.stat.exists
40
41- name: Order docker.service after the storage array mount
42 copy:
43 dest: "/etc/systemd/system/docker.service.d/{{ nas_docker_mount_ordering_dropin }}"
44 mode: '0644'
45 owner: root
46 group: root
47 content: |
48 # Managed by Ansible (roles/nas) - do not edit by hand.
49 #
50 # Prevents Docker from starting containers before {{ nas_storage_base }}
51 # is mounted. Without this, containers that bind-mount the array can bind
52 # the empty pre-mount directory on the root filesystem after an unclean
53 # shutdown delays mdadm assembly.
54 [Unit]
55 RequiresMountsFor={{ nas_storage_base }}
56 After={{ nas_storage_mount_unit.stdout }}
57 become: true
58 when: nas_docker_unit.stat.exists
59 notify: reload systemd daemon
60
61- name: Verify the storage mount is backed by the expected array device
62 command: "findmnt -no SOURCE --target {{ nas_storage_base }}"
63 register: nas_storage_source
64 changed_when: false
65 failed_when: false
66 check_mode: false
67
68- name: Warn if the storage base is not backed by an md array
69 debug:
70 msg: |
71 â ï¸ WARNING: {{ nas_storage_base }} is backed by
72 '{{ nas_storage_source.stdout | trim }}', not an /dev/md* array device.
73
74 This is the signature of the boot race described above: the path is
75 resolving to the root filesystem rather than the RAID array. Any
76 container bind-mounting it is reading the wrong filesystem and will
77 report the wrong capacity.
78
79 To recover on this host:
80 mount {{ nas_storage_base }}
81 docker restart $(docker ps -q) # re-resolves stale bind mounts
82 when:
83 - nas_storage_source.rc == 0
84 - nas_storage_source.stdout | trim | length > 0
85 - not (nas_storage_source.stdout | trim is match('^/dev/md'))
86