commit f91d8226cb58ec78a80d6977e7db629971015ce1 Author: Chris Hammer Date: Thu Jul 31 10:52:35 2025 -0400 Initial project commit; forked from quick_tests repo diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..b6d3809 --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,5 @@ +skip_list: + - yaml[colons] + - yaml[empty-lines] + - yaml[line-length] + - no-changed-when diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8354596 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +roles/verified_reboot diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..d0d26f1 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,30 @@ +[defaults] +inventory = hosts +roles_path = roles +collections_path = collections +remote_tmp = /tmp/.ansible-${USER}/tmp +gathering = smart +gather_timeout = 600 +fact_caching = jsonfile +fact_caching_connection = /tmp/.ansible_facts +fact_caching_timeout = 300 +retry_files_enabled = false +forks = 40 +timeout = 30 +host_key_checking = false +display_skipped_hosts = false +deprecation_warnings = false +# task_timeout = 10 + +# callback_whitelist is deprecated +# we only include here for backwards compatibility +callback_whitelist = ansible.posix.profile_tasks, ansible.posix.timer +callbacks_enabled = ansible.posix.profile_tasks, ansible.posix.timer + +# *shrug* +show_custom_stats = true + +[ssh_connection] +pipelining = True +ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey + diff --git a/lazy_reboot.yml b/lazy_reboot.yml new file mode 100644 index 0000000..0546621 --- /dev/null +++ b/lazy_reboot.yml @@ -0,0 +1,49 @@ +--- +- name: Reboot host with hung NFS Share(s) + hosts: temp + become: true + gather_facts: false + + # With NFS share(s) being in a hung state, we cannot utilize `gather_facts` + # as that too hangs when it tries to figure out the current mounts on the + # system + tasks: + - name: Check for mounted NFS shares # noqa: command-instead-of-module + ansible.builtin.command: mount -t nfs,nfs4 + register: nfs_mounts_result + changed_when: false + failed_when: nfs_mounts_result['rc'] not in [0, 32] + + - name: Create a list of NFS mount points + ansible.builtin.set_fact: + nfs_mount_list: "{{ nfs_mounts_result['stdout_lines'] | map('split') | map(attribute=2) | list }}" + + - name: Verify mount status and reboot host + block: + - name: Verify mount status + ansible.builtin.command: "ls {{ item }}" + timeout: 5 + register: r_verify_mounts + loop: "{{ nfs_mount_list }}" + loop_control: + label: "{{ item }}" + + rescue: + - name: Group shares that failed check + ansible.builtin.set_fact: + failed_nfs_shares: + "{{ r_verify_mounts['results'] | selectattr('failed') | map(attribute='item') | list }}" + + - name: Lazily unmount the failed shares + ansible.builtin.command: "umount -f -l {{ item }}" + register: r_lazy_unmount + async: 30 + poll: 0 + loop: "{{ failed_nfs_shares }}" + loop_control: + label: "{{ item }}" + + always: + - name: Reboot host # noqa: no-handler + ansible.builtin.import_role: + name: verified_reboot diff --git a/roles/requirements.yml b/roles/requirements.yml new file mode 100644 index 0000000..6e01cf2 --- /dev/null +++ b/roles/requirements.yml @@ -0,0 +1,5 @@ +--- +- name: verified_reboot + src: https://gitea.thezengarden.net/ansible_plays/verified_reboot.git + scm: git + version: main diff --git a/scripts/write_file_msg.py b/scripts/write_file_msg.py new file mode 100755 index 0000000..9b3d46a --- /dev/null +++ b/scripts/write_file_msg.py @@ -0,0 +1,66 @@ +#!/usr/bin/python3 +import time +import os +import readline +from datetime import datetime + +# Changable optonis: +message = "Testing testing testing..." +max_iterations = 5 +msg_delay = 0.2 + +# Autocomplete path stuffs: +def complete_path(text, state): + expanded = os.path.expanduser(os.path.expandvars(text)) + + if os.path.isdir(expanded): + try: + entries = os.listdir(expanded) + completion_list = [ + os.path.abspath(os.path.join(expanded, entry)) + '/' + if os.path.isdir(os.path.join(expanded, entry)) + else os.path.abspath(os.path.join(expanded, entry)) + for entry in entries + ] + except FileNotFoundError: + completion_list = [] + else: + dirname = os.path.dirname(expanded) + basename = os.path.basename(expanded) + + if not dirname: + dirname = '.' + + try: + entries = [entry for entry in os.listdir(dirname) if entry.startswith(basename)] + completion_list = [ + os.path.abspath(os.path.join(dirname, entry)) + for entry in entries + ] + except FileNotFoundError: + completion_list = [] + + completion_list.sort() + try: + return completion_list[state] + except IndexError: + return None + +readline.set_completer_delims(' \t\n;') +readline.set_completer(complete_path) +readline.parse_and_bind("tab: complete") + +file_path = input("File to write to: ") + +try: + for i in range(max_iterations): + ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + tm = "{} -- {}: itr=>{}".format(ts, message, i) + print(f"{file_path} -> {tm}") + + with open(file_path, "a") as file: + file.write(tm + '\n') + + time.sleep(msg_delay) +except KeyboardInterrupt: + print("Ctrl-C hit; exiting...")