aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2023-08-10 17:50:50 +0200
committerEgor Tensin <Egor.Tensin@gmail.com>2023-08-10 19:30:13 +0200
commita86d828553d4d724d4ad3ca5335711b6bb1c0eb5 (patch)
treedb7b9ae3803aec2f871c8ead356b9091a581c014
parentcloud_init_wait: tolerate reboots (diff)
downloadinfra-ansible-a86d828553d4d724d4ad3ca5335711b6bb1c0eb5.tar.gz
infra-ansible-a86d828553d4d724d4ad3ca5335711b6bb1c0eb5.zip
cloud_init_wait: factor out to file_wait
-rw-r--r--roles/cloud_init_wait/defaults/main.yml1
-rw-r--r--roles/cloud_init_wait/tasks/check.yml23
-rw-r--r--roles/cloud_init_wait/tasks/main.yml10
-rw-r--r--roles/file_wait/README.md4
-rw-r--r--roles/file_wait/defaults/main.yml3
-rw-r--r--roles/file_wait/tasks/check.yml25
-rw-r--r--roles/file_wait/tasks/main.yml7
7 files changed, 44 insertions, 29 deletions
diff --git a/roles/cloud_init_wait/defaults/main.yml b/roles/cloud_init_wait/defaults/main.yml
index e5971c9..b857f1d 100644
--- a/roles/cloud_init_wait/defaults/main.yml
+++ b/roles/cloud_init_wait/defaults/main.yml
@@ -1,3 +1,2 @@
cloud_init_wait_path: /var/lib/cloud/instance/boot-finished
cloud_init_wait_seconds: 300
-cloud_init_wait_delay: 10
diff --git a/roles/cloud_init_wait/tasks/check.yml b/roles/cloud_init_wait/tasks/check.yml
deleted file mode 100644
index 2dc20aa..0000000
--- a/roles/cloud_init_wait/tasks/check.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-# Make a playbook usable immediately after creating a VM - even before
-# the SSH server is started.
-- name: Wait for SSH connection
- ansible.builtin.wait_for_connection:
- timeout: '{{ cloud_init_wait_seconds }}'
-
-# Again, make a playbook usable immediately after creating a VM - that includes
-# waiting until cloud-init is done.
-- name: Wait until cloud-init is finished
- ansible.builtin.file:
- path: '{{ cloud_init_wait_path }}'
- state: file
- register: boot_finished
- until: boot_finished is succeeded
- # About 5 minutes worth of attempts.
- retries: '{{ cloud_init_wait_seconds // cloud_init_wait_delay }}'
- delay: '{{ cloud_init_wait_delay }}'
- ignore_unreachable: true
- ignore_errors: true
-
-- ansible.builtin.include_tasks: check.yml
- when:
- - boot_finished is unreachable
diff --git a/roles/cloud_init_wait/tasks/main.yml b/roles/cloud_init_wait/tasks/main.yml
index dec4162..22c258d 100644
--- a/roles/cloud_init_wait/tasks/main.yml
+++ b/roles/cloud_init_wait/tasks/main.yml
@@ -1,5 +1,5 @@
-- ansible.builtin.include_tasks: check.yml
-
-- ansible.builtin.fail:
- msg: Failed to wait until cloud-init is done
- when: boot_finished is not defined or boot_finished is not succeeded
+- ansible.builtin.include_role:
+ name: file_wait
+ vars:
+ file_wait_path: '{{ cloud_init_wait_path }}'
+ file_wait_seconds: '{{ cloud_init_wait_seconds }}'
diff --git a/roles/file_wait/README.md b/roles/file_wait/README.md
new file mode 100644
index 0000000..0f4c22b
--- /dev/null
+++ b/roles/file_wait/README.md
@@ -0,0 +1,4 @@
+This weird and extremely convoluted way to wait until a file exists
+(disregarding reboots) was borrowed from RedHat themselves:
+
+ https://www.ansible.com/blog/tolerable-ansible
diff --git a/roles/file_wait/defaults/main.yml b/roles/file_wait/defaults/main.yml
new file mode 100644
index 0000000..1e8625c
--- /dev/null
+++ b/roles/file_wait/defaults/main.yml
@@ -0,0 +1,3 @@
+file_wait_seconds: 300
+file_wait_delay: 10
+file_wait_reboots: 3
diff --git a/roles/file_wait/tasks/check.yml b/roles/file_wait/tasks/check.yml
new file mode 100644
index 0000000..1a7c138
--- /dev/null
+++ b/roles/file_wait/tasks/check.yml
@@ -0,0 +1,25 @@
+- name: Wait for connection
+ ansible.builtin.wait_for_connection:
+ timeout: '{{ file_wait_seconds }}'
+
+- name: Check if the file exists
+ ansible.builtin.file:
+ path: '{{ file_wait_path }}'
+ state: file
+ register: file_wait_check
+ until: file_wait_check is succeeded
+ retries: '{{ file_wait_seconds // file_wait_delay }}'
+ delay: '{{ file_wait_delay }}'
+ ignore_unreachable: true
+ ignore_errors: true
+
+- name: If the host restarted, try again
+ block:
+ - name: Note a reboot happened
+ ansible.builtin.set_fact:
+ file_wait_reboots: '{{ (file_wait_reboots | int) - 1 }}'
+
+ - name: Retry if there're more attempts
+ ansible.builtin.include_tasks: check.yml
+ when: (file_wait_reboots | int > 0)
+ when: file_wait_check is unreachable
diff --git a/roles/file_wait/tasks/main.yml b/roles/file_wait/tasks/main.yml
new file mode 100644
index 0000000..76dce68
--- /dev/null
+++ b/roles/file_wait/tasks/main.yml
@@ -0,0 +1,7 @@
+- name: Checking if the file exists
+ ansible.builtin.include_tasks: check.yml
+
+- name: Fail unless the file exists
+ ansible.builtin.fail:
+ msg: 'File is missing: {{ file_wait_path }}'
+ when: file_wait_check is not defined or file_wait_check is not succeeded or file_wait_check is unreachable