From b437aa28ceb5869ec757e7bdc9aa410263415bcb Mon Sep 17 00:00:00 2001 From: Sam Al-Sapti Date: Wed, 19 Apr 2023 22:58:17 +0200 Subject: [PATCH] Attempt graceful shutdown of Docker services before reboot --- group_vars/all/vars.yml | 2 +- provision.sh | 2 +- roles/docker_services/tasks/config.yml | 33 +++++++++++++++++++ roles/docker_services/tasks/main.yml | 6 ++++ roles/docker_services/tasks/services.yml | 32 ------------------ .../docker_services/tasks/services/caddy.yml | 1 + roles/docker_services/tasks/services/emby.yml | 1 + .../tasks/services/monerod.yml | 1 + .../tasks/services/nextcloud.yml | 1 + .../tasks/services/postfix.yml | 1 + .../docker_services/tasks/services/restic.yml | 1 + .../tasks/services/snowflake.yml | 1 + .../tasks/services/watchtower.yml | 1 + .../tasks/services/wireguard.yml | 1 + roles/os_config/tasks/reboot.yml | 25 +++++++++++--- 15 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 roles/docker_services/tasks/config.yml diff --git a/group_vars/all/vars.yml b/group_vars/all/vars.yml index adc8340..673595d 100644 --- a/group_vars/all/vars.yml +++ b/group_vars/all/vars.yml @@ -11,4 +11,4 @@ ssd_mount_point: /opt/{{ ssd_name }} ssh_keys: - sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIFWZGLov8wPBNxuvnaPK+8vv6wK5hHUVEFzXKsN9QeuBAAAADHNzaDpzYW1zYXB0aQ== ssh:samsapti - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPd/4fQV7CL8/KVwbo/phiV5UdXFBIDlkZ+ps8C7FeRf + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPd/4fQV7CL8/KVwbo/phiV5UdXFBIDlkZ+ps8C7FeRf cardno:14 336 332 diff --git a/provision.sh b/provision.sh index f8ae12e..9801e78 100755 --- a/provision.sh +++ b/provision.sh @@ -30,7 +30,7 @@ case $1 in if [ "$2" = "-f" ] || [ "$2" = "--force" ]; then $BASE_CMD --tags "$1" --extra-vars "force_reboot=true" else - $BASE_CMD --tags "$1" + $BASE_CMD --tags "$1" --extra-vars "reboot=true" fi ;; services) diff --git a/roles/docker_services/tasks/config.yml b/roles/docker_services/tasks/config.yml new file mode 100644 index 0000000..c23bbdc --- /dev/null +++ b/roles/docker_services/tasks/config.yml @@ -0,0 +1,33 @@ +# vim: ft=yaml.ansible +--- +- name: Create base directory for Docker volumes + ansible.builtin.file: + name: "{{ base_volume }}" + owner: root + mode: u=rwx,g=rx,o=rx + state: directory + +- name: Copy Docker daemon config file + ansible.builtin.template: + src: daemon.json.j2 + dest: /etc/docker/daemon.json + owner: root + mode: u=rw,g=r,o=r + register: daemon_config + +- name: Disable and (re)start Docker daemon + ansible.builtin.service: + name: "{{ item }}" + enabled: false + state: "{{ 'restarted' if daemon_config.changed else 'started' }}" + loop: + - docker.socket + - docker.service + +- name: Create Docker network for services + community.docker.docker_network: + name: services + ipam_config: + - subnet: 172.16.0.0/16 + gateway: 172.16.0.1 + state: present diff --git a/roles/docker_services/tasks/main.yml b/roles/docker_services/tasks/main.yml index 6d6e51f..03d24e2 100644 --- a/roles/docker_services/tasks/main.yml +++ b/roles/docker_services/tasks/main.yml @@ -37,6 +37,12 @@ - docker - docker-compose +- name: Configure Docker + ansible.builtin.import_tasks: config.yml + tags: + - services + - reboot + - name: Set up Docker services ansible.builtin.import_tasks: services.yml tags: diff --git a/roles/docker_services/tasks/services.yml b/roles/docker_services/tasks/services.yml index e55dc45..e4fecee 100644 --- a/roles/docker_services/tasks/services.yml +++ b/roles/docker_services/tasks/services.yml @@ -1,37 +1,5 @@ # vim: ft=yaml.ansible --- -- name: Copy Docker daemon config file - ansible.builtin.template: - src: daemon.json.j2 - dest: /etc/docker/daemon.json - owner: root - mode: u=rw,g=r,o=r - register: daemon_config - -- name: Disable and (re)start Docker daemon - ansible.builtin.service: - name: "{{ item }}" - enabled: false - state: "{{ 'restarted' if daemon_config.changed else 'started' }}" - loop: - - docker.socket - - docker.service - -- name: Create base directory for Docker volumes - ansible.builtin.file: - name: "{{ base_volume }}" - owner: root - mode: u=rwx,g=rx,o=rx - state: directory - -- name: Create Docker network for services - community.docker.docker_network: - name: services - ipam_config: - - subnet: 172.16.0.0/16 - gateway: 172.16.0.1 - state: present - - name: Deploy services ansible.builtin.include_tasks: services/{{ item.key }}.yml loop: "{{ services | dict2items }}" diff --git a/roles/docker_services/tasks/services/caddy.yml b/roles/docker_services/tasks/services/caddy.yml index 47803cf..d81fc38 100644 --- a/roles/docker_services/tasks/services/caddy.yml +++ b/roles/docker_services/tasks/services/caddy.yml @@ -22,6 +22,7 @@ - name: Deploy Caddy Docker container community.docker.docker_container: name: caddy + state: "{{ 'absent' if stop is defined and stop else 'started' }}" image: caddy:{{ services.caddy.version }} restart_policy: always networks: diff --git a/roles/docker_services/tasks/services/emby.yml b/roles/docker_services/tasks/services/emby.yml index addf007..2c66564 100644 --- a/roles/docker_services/tasks/services/emby.yml +++ b/roles/docker_services/tasks/services/emby.yml @@ -16,6 +16,7 @@ - name: Deploy Emby Docker container community.docker.docker_container: name: emby_app + state: "{{ 'absent' if stop is defined and stop else 'started' }}" image: emby/embyserver_arm64v8:{{ services.emby.version }} restart_policy: always env: diff --git a/roles/docker_services/tasks/services/monerod.yml b/roles/docker_services/tasks/services/monerod.yml index 85b865b..06011a1 100644 --- a/roles/docker_services/tasks/services/monerod.yml +++ b/roles/docker_services/tasks/services/monerod.yml @@ -8,6 +8,7 @@ - name: Deploy Monero node Docker container community.docker.docker_container: name: monerod_node + state: "{{ 'absent' if stop is defined and stop else 'started' }}" image: sethsimmons/simple-monerod:{{ services.monerod.version }} restart_policy: always networks: diff --git a/roles/docker_services/tasks/services/nextcloud.yml b/roles/docker_services/tasks/services/nextcloud.yml index 4032d75..0900c42 100644 --- a/roles/docker_services/tasks/services/nextcloud.yml +++ b/roles/docker_services/tasks/services/nextcloud.yml @@ -37,6 +37,7 @@ - name: Deploy Nextcloud with Docker Compose community.docker.docker_compose: project_name: nextcloud + state: "{{ 'absent' if stop is defined and stop else 'present' }}" pull: true definition: version: '3.8' diff --git a/roles/docker_services/tasks/services/postfix.yml b/roles/docker_services/tasks/services/postfix.yml index b38365e..0ac20ac 100644 --- a/roles/docker_services/tasks/services/postfix.yml +++ b/roles/docker_services/tasks/services/postfix.yml @@ -15,6 +15,7 @@ - name: Deploy Postfix Docker container community.docker.docker_container: name: postfix + state: "{{ 'absent' if stop is defined and stop else 'started' }}" image: boky/postfix:{{ services.postfix.version }} restart_policy: always env: diff --git a/roles/docker_services/tasks/services/restic.yml b/roles/docker_services/tasks/services/restic.yml index 964fa59..90e9231 100644 --- a/roles/docker_services/tasks/services/restic.yml +++ b/roles/docker_services/tasks/services/restic.yml @@ -3,6 +3,7 @@ - name: Deploy Restic with Docker Compose community.docker.docker_compose: project_name: restic + state: "{{ 'absent' if stop is defined and stop else 'present' }}" pull: true definition: version: '3.8' diff --git a/roles/docker_services/tasks/services/snowflake.yml b/roles/docker_services/tasks/services/snowflake.yml index 146caa9..3bc55a2 100644 --- a/roles/docker_services/tasks/services/snowflake.yml +++ b/roles/docker_services/tasks/services/snowflake.yml @@ -3,6 +3,7 @@ - name: Deploy snowflake-proxy Docker container community.docker.docker_container: name: snowflake-proxy + state: "{{ 'absent' if stop is defined and stop else 'started' }}" image: thetorproject/snowflake-proxy:{{ services.snowflake.version }} restart_policy: always network_mode: host diff --git a/roles/docker_services/tasks/services/watchtower.yml b/roles/docker_services/tasks/services/watchtower.yml index ace5573..484423c 100644 --- a/roles/docker_services/tasks/services/watchtower.yml +++ b/roles/docker_services/tasks/services/watchtower.yml @@ -8,6 +8,7 @@ - name: Deploy Watchtower Docker container community.docker.docker_container: name: watchtower + state: "{{ 'absent' if stop is defined and stop else 'started' }}" image: containrrr/watchtower:{{ services.watchtower.version }} restart_policy: always networks: diff --git a/roles/docker_services/tasks/services/wireguard.yml b/roles/docker_services/tasks/services/wireguard.yml index c23e54e..c7298e4 100644 --- a/roles/docker_services/tasks/services/wireguard.yml +++ b/roles/docker_services/tasks/services/wireguard.yml @@ -15,6 +15,7 @@ - name: Deploy Wireguard Docker container community.docker.docker_container: name: wireguard + state: "{{ 'absent' if stop is defined and stop else 'started' }}" image: linuxserver/wireguard:{{ services.wireguard.version }} restart_policy: always networks: diff --git a/roles/os_config/tasks/reboot.yml b/roles/os_config/tasks/reboot.yml index a8a2ab1..a40fc99 100644 --- a/roles/os_config/tasks/reboot.yml +++ b/roles/os_config/tasks/reboot.yml @@ -5,16 +5,31 @@ path: /var/run/reboot-required register: needs_reboot -- name: Reboot host - ansible.builtin.reboot: - connect_timeout: 120 +- name: Include docker_services role for service shutdown + ansible.builtin.include_role: + name: docker_services + tasks_from: services.yml + apply: + ignore_errors: true + vars: + stop: true when: needs_reboot.stat.exists or (force_reboot is defined and force_reboot) - register: reboot + +- name: Reboot host + ansible.builtin.reboot: + when: needs_reboot.stat.exists or + (force_reboot is defined and force_reboot) + register: rebooted + +- name: End play if reboot is not needed + ansible.builtin.meta: end_play + when: reboot is defined and reboot and + (rebooted.rebooted is undefined or not rebooted.rebooted) - name: Re-gather facts ansible.builtin.setup: filter: - ansible_mounts - ansible_swaptotal_mb - when: reboot.rebooted is defined and reboot.rebooted + when: rebooted.rebooted is defined and rebooted.rebooted