Skip to content

Commit 7d98cb2

Browse files
authored
Merge pull request #74 from linux-kdevops/cel/terraform-fixes
Assorted fixes for terraform-related issues
2 parents 6e3f136 + 3c7e8fd commit 7d98cb2

File tree

15 files changed

+464
-2
lines changed

15 files changed

+464
-2
lines changed

playbooks/dhclient_azure_cache.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
- name: Configure persistent DHCP caching for cloud VMs
3+
hosts: all:!localhost
4+
gather_facts: true
5+
roles:
6+
- role: dhclient_cache

playbooks/dhclient_cache.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
- name: Configure persistent DHCP caching for cloud VMs
3+
hosts: all:!localhost
4+
gather_facts: true
5+
roles:
6+
- role: dhclient_cache
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
# Default variables for dhclient_cache role
3+
dhclient_cache_enabled: true
4+
dhclient_cache_timeout: 3600
5+
dhclient_cache_retry_interval: 10
6+
dhclient_cache_max_retries: 30
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
# ISC dhclient persistent DHCP caching implementation
3+
# Used by: Debian, Ubuntu, older RHEL/CentOS/Fedora
4+
5+
- name: Detect primary network interface
6+
ansible.builtin.set_fact:
7+
primary_interface: "{{ ansible_default_ipv4.interface | default('eth0') }}"
8+
9+
- name: Create dhclient enter hook for persistent lease caching
10+
become: true
11+
become_flags: "su - -c"
12+
become_method: sudo
13+
ansible.builtin.template:
14+
src: isc-dhclient-enter-hook.j2
15+
dest: /etc/dhcp/dhclient-enter-hooks.d/kdevops-persistent-cache
16+
mode: "0755"
17+
owner: root
18+
group: root
19+
20+
- name: Create dhclient exit hook for persistent lease caching
21+
become: true
22+
become_flags: "su - -c"
23+
become_method: sudo
24+
ansible.builtin.template:
25+
src: isc-dhclient-exit-hook.j2
26+
dest: /etc/dhcp/dhclient-exit-hooks.d/kdevops-persistent-cache
27+
mode: "0755"
28+
owner: root
29+
group: root
30+
31+
- name: Update dhclient configuration for aggressive retry
32+
become: true
33+
become_flags: "su - -c"
34+
become_method: sudo
35+
ansible.builtin.lineinfile:
36+
path: /etc/dhcp/dhclient.conf
37+
regexp: "^{{ item.key }}\\s+"
38+
line: "{{ item.key }} {{ item.value }};"
39+
create: false
40+
loop:
41+
- { key: "timeout", value: "{{ dhclient_cache_timeout }}" }
42+
- { key: "retry", value: "{{ dhclient_cache_retry_interval }}" }
43+
44+
- name: Ensure lease cache directory exists
45+
become: true
46+
become_flags: "su - -c"
47+
become_method: sudo
48+
ansible.builtin.file:
49+
path: /var/lib/dhcp/cache
50+
state: directory
51+
mode: "0755"
52+
owner: root
53+
group: root
54+
55+
- name: Create initial cached lease from current lease
56+
become: true
57+
become_flags: "su - -c"
58+
become_method: sudo
59+
ansible.builtin.shell: |
60+
if [ -f /var/lib/dhcp/dhclient.{{ primary_interface }}.leases ]; then
61+
cp -a /var/lib/dhcp/dhclient.{{ primary_interface }}.leases \
62+
/var/lib/dhcp/cache/dhclient.{{ primary_interface }}.cached-lease
63+
chmod 644 /var/lib/dhcp/cache/dhclient.{{ primary_interface }}.cached-lease
64+
fi
65+
args:
66+
creates: /var/lib/dhcp/cache/dhclient.{{ primary_interface }}.cached-lease
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
- name: Configure persistent DHCP caching for cloud VMs
3+
block:
4+
- name: Detect DHCP client mechanism
5+
ansible.builtin.set_fact:
6+
dhcp_mechanism: >-
7+
{%- if ansible_facts['os_family']|lower == 'suse' -%}
8+
wicked
9+
{%- elif ansible_facts['os_family']|lower in ['redhat', 'rocky', 'almalinux'] -%}
10+
{%- if ansible_facts['distribution_major_version']|int >= 8 -%}
11+
networkmanager
12+
{%- else -%}
13+
isc-dhclient
14+
{%- endif -%}
15+
{%- elif ansible_facts['os_family']|lower == 'debian' -%}
16+
isc-dhclient
17+
{%- else -%}
18+
unknown
19+
{%- endif -%}
20+
21+
- name: Display detected DHCP mechanism
22+
ansible.builtin.debug:
23+
msg: "Detected DHCP mechanism: {{ dhcp_mechanism }} on {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
24+
25+
- name: Configure ISC dhclient persistent caching
26+
ansible.builtin.include_tasks: isc-dhclient.yml
27+
when: dhcp_mechanism == 'isc-dhclient'
28+
29+
- name: Configure NetworkManager persistent caching
30+
ansible.builtin.include_tasks: networkmanager.yml
31+
when: dhcp_mechanism == 'networkmanager'
32+
33+
- name: Configure wicked persistent caching
34+
ansible.builtin.include_tasks: wicked.yml
35+
when: dhcp_mechanism == 'wicked'
36+
37+
- name: Warn about unsupported DHCP mechanism
38+
ansible.builtin.debug:
39+
msg: "WARNING: DHCP mechanism '{{ dhcp_mechanism }}' is not supported for persistent caching"
40+
when: dhcp_mechanism == 'unknown'
41+
42+
when:
43+
- dhclient_cache_enabled|bool
44+
- kdevops_enable_terraform is defined
45+
- kdevops_enable_terraform|bool
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
# NetworkManager persistent DHCP caching implementation
3+
# Used by: RHEL 8+, Fedora 30+, CentOS 8+
4+
5+
- name: Detect primary network interface
6+
ansible.builtin.set_fact:
7+
primary_interface: "{{ ansible_default_ipv4.interface | default('eth0') }}"
8+
9+
- name: Create NetworkManager dispatcher script for DHCP cache save
10+
become: true
11+
become_flags: "su - -c"
12+
become_method: sudo
13+
ansible.builtin.template:
14+
src: networkmanager-dispatcher.j2
15+
dest: /etc/NetworkManager/dispatcher.d/10-kdevops-dhcp-cache
16+
mode: "0755"
17+
owner: root
18+
group: root
19+
20+
- name: Ensure lease cache directory exists
21+
become: true
22+
become_flags: "su - -c"
23+
become_method: sudo
24+
ansible.builtin.file:
25+
path: /var/lib/NetworkManager/cache
26+
state: directory
27+
mode: "0755"
28+
owner: root
29+
group: root
30+
31+
- name: Get current IP configuration via NetworkManager
32+
become: true
33+
become_flags: "su - -c"
34+
become_method: sudo
35+
ansible.builtin.shell: |
36+
nmcli -t -f IP4.ADDRESS,IP4.GATEWAY,IP4.DNS device show {{ primary_interface }} | \
37+
awk -F: '{print $2}' > /var/lib/NetworkManager/cache/{{ primary_interface }}.cached-config
38+
echo "cache_timestamp=$(date +%s)" >> /var/lib/NetworkManager/cache/{{ primary_interface }}.cached-config
39+
chmod 644 /var/lib/NetworkManager/cache/{{ primary_interface }}.cached-config
40+
args:
41+
creates: /var/lib/NetworkManager/cache/{{ primary_interface }}.cached-config
42+
changed_when: true
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
# Wicked persistent DHCP caching implementation
3+
# Used by: SUSE Linux Enterprise Server, openSUSE
4+
5+
- name: Detect primary network interface
6+
ansible.builtin.set_fact:
7+
primary_interface: "{{ ansible_default_ipv4.interface | default('eth0') }}"
8+
9+
- name: Create wicked extension for DHCP cache save
10+
become: true
11+
become_flags: "su - -c"
12+
become_method: sudo
13+
ansible.builtin.template:
14+
src: wicked-extension.j2
15+
dest: /etc/wicked/extensions/kdevops-dhcp-cache
16+
mode: "0755"
17+
owner: root
18+
group: root
19+
20+
- name: Ensure lease cache directory exists
21+
become: true
22+
become_flags: "su - -c"
23+
become_method: sudo
24+
ansible.builtin.file:
25+
path: /var/lib/wicked/cache
26+
state: directory
27+
mode: "0755"
28+
owner: root
29+
group: root
30+
31+
- name: Get current IP configuration via wicked
32+
become: true
33+
become_flags: "su - -c"
34+
become_method: sudo
35+
ansible.builtin.shell: |
36+
wicked show {{ primary_interface }} | \
37+
grep -E "addr.*inet|route.*default|DNS" | \
38+
awk '{print}' > /var/lib/wicked/cache/{{ primary_interface }}.cached-config
39+
echo "cache_timestamp=$(date +%s)" >> /var/lib/wicked/cache/{{ primary_interface }}.cached-config
40+
chmod 644 /var/lib/wicked/cache/{{ primary_interface }}.cached-config
41+
args:
42+
creates: /var/lib/wicked/cache/{{ primary_interface }}.cached-config
43+
changed_when: true
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
# Persistent DHCP lease caching - ISC dhclient enter hook
3+
# This hook saves successful DHCP leases to a persistent cache
4+
# Managed by kdevops - dhclient_cache role
5+
6+
CACHE_DIR="/var/lib/dhcp/cache"
7+
CACHE_FILE="${CACHE_DIR}/dhclient.${interface}.cached-lease"
8+
CACHE_TIMEOUT={{ dhclient_cache_timeout }}
9+
10+
# Only cache on BOUND, RENEW, or REBIND events
11+
case "${reason}" in
12+
BOUND|RENEW|REBIND)
13+
# Ensure cache directory exists
14+
mkdir -p "${CACHE_DIR}"
15+
16+
# Save current lease information to cache file
17+
if [ -n "${new_ip_address}" ]; then
18+
{
19+
echo "# Cached DHCP lease for ${interface}"
20+
echo "# Cached at: $(date)"
21+
echo "# Cache timeout: ${CACHE_TIMEOUT} seconds"
22+
echo "interface=\"${interface}\""
23+
echo "new_ip_address=\"${new_ip_address}\""
24+
echo "new_subnet_mask=\"${new_subnet_mask}\""
25+
echo "new_routers=\"${new_routers}\""
26+
echo "new_domain_name_servers=\"${new_domain_name_servers}\""
27+
echo "new_broadcast_address=\"${new_broadcast_address}\""
28+
echo "new_dhcp_lease_time=\"${new_dhcp_lease_time}\""
29+
echo "cache_timestamp=\"$(date +%s)\""
30+
} > "${CACHE_FILE}"
31+
32+
chmod 644 "${CACHE_FILE}"
33+
logger -t kdevops-dhcp-cache "Saved DHCP lease to cache for ${interface}: ${new_ip_address}"
34+
fi
35+
;;
36+
esac
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/bin/bash
2+
# Persistent DHCP lease caching - ISC dhclient exit hook
3+
# This hook restores cached DHCP configuration if DHCP fails after reboot
4+
# Managed by kdevops - dhclient_cache role
5+
6+
CACHE_DIR="/var/lib/dhcp/cache"
7+
CACHE_FILE="${CACHE_DIR}/dhclient.${interface}.cached-lease"
8+
CACHE_TIMEOUT={{ dhclient_cache_timeout }}
9+
10+
# Only attempt cache restore on TIMEOUT or FAIL events
11+
case "${reason}" in
12+
TIMEOUT|FAIL)
13+
if [ -f "${CACHE_FILE}" ]; then
14+
# Source the cached lease
15+
source "${CACHE_FILE}"
16+
17+
# Check if cache is still valid (within timeout period)
18+
current_timestamp=$(date +%s)
19+
cache_age=$((current_timestamp - cache_timestamp))
20+
21+
if [ ${cache_age} -lt ${CACHE_TIMEOUT} ]; then
22+
logger -t kdevops-dhcp-cache "DHCP ${reason} for ${interface}, restoring from cache (age: ${cache_age}s)"
23+
24+
# Apply cached IP configuration
25+
if [ -n "${new_ip_address}" ]; then
26+
ip addr flush dev "${interface}" 2>/dev/null || true
27+
ip addr add "${new_ip_address}/${new_subnet_mask}" dev "${interface}"
28+
29+
if [ -n "${new_routers}" ]; then
30+
ip route add default via "${new_routers}" dev "${interface}" 2>/dev/null || true
31+
fi
32+
33+
if [ -n "${new_domain_name_servers}" ]; then
34+
# Update resolv.conf with cached DNS servers
35+
{
36+
echo "# Generated by dhclient-azure-cache from cached lease"
37+
echo "# Cached DNS servers restored after DHCP ${reason}"
38+
for nameserver in ${new_domain_name_servers}; do
39+
echo "nameserver ${nameserver}"
40+
done
41+
} > /etc/resolv.conf
42+
fi
43+
44+
logger -t kdevops-dhcp-cache "Successfully restored cached IP configuration: ${new_ip_address}"
45+
46+
# Set exit code to indicate we handled the failure
47+
exit 0
48+
fi
49+
else
50+
logger -t kdevops-dhcp-cache "Cached lease for ${interface} expired (age: ${cache_age}s > ${CACHE_TIMEOUT}s)"
51+
fi
52+
else
53+
logger -t kdevops-dhcp-cache "No cached lease found for ${interface} after DHCP ${reason}"
54+
fi
55+
;;
56+
esac
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/bash
2+
# Persistent DHCP caching - NetworkManager dispatcher script
3+
# This script saves successful DHCP configuration and restores on failure
4+
# Managed by kdevops - dhclient_cache role
5+
6+
INTERFACE="$1"
7+
ACTION="$2"
8+
CACHE_DIR="/var/lib/NetworkManager/cache"
9+
CACHE_FILE="${CACHE_DIR}/${INTERFACE}.cached-config"
10+
CACHE_TIMEOUT={{ dhclient_cache_timeout }}
11+
12+
# Ensure cache directory exists
13+
mkdir -p "${CACHE_DIR}"
14+
15+
case "${ACTION}" in
16+
up|dhcp4-change)
17+
# Save current network configuration to cache
18+
IP4_ADDRESS=$(nmcli -t -f IP4.ADDRESS device show "${INTERFACE}" 2>/dev/null | cut -d: -f2)
19+
IP4_GATEWAY=$(nmcli -t -f IP4.GATEWAY device show "${INTERFACE}" 2>/dev/null | cut -d: -f2)
20+
IP4_DNS=$(nmcli -t -f IP4.DNS device show "${INTERFACE}" 2>/dev/null | cut -d: -f2 | tr '\n' ' ')
21+
22+
if [ -n "${IP4_ADDRESS}" ]; then
23+
{
24+
echo "# Cached NetworkManager DHCP configuration for ${INTERFACE}"
25+
echo "# Cached at: $(date)"
26+
echo "# Cache timeout: ${CACHE_TIMEOUT} seconds"
27+
echo "IP4_ADDRESS=\"${IP4_ADDRESS}\""
28+
echo "IP4_GATEWAY=\"${IP4_GATEWAY}\""
29+
echo "IP4_DNS=\"${IP4_DNS}\""
30+
echo "cache_timestamp=\"$(date +%s)\""
31+
} > "${CACHE_FILE}"
32+
chmod 644 "${CACHE_FILE}"
33+
logger -t kdevops-dhcp-cache "Saved NetworkManager DHCP config to cache for ${INTERFACE}: ${IP4_ADDRESS}"
34+
fi
35+
;;
36+
37+
connectivity-change)
38+
# Check if we have connectivity, if not try to restore from cache
39+
CONNECTIVITY=$(nmcli -t -f CONNECTIVITY general status)
40+
if [ "${CONNECTIVITY}" = "none" ] || [ "${CONNECTIVITY}" = "limited" ]; then
41+
if [ -f "${CACHE_FILE}" ]; then
42+
source "${CACHE_FILE}"
43+
44+
# Check if cache is still valid
45+
current_timestamp=$(date +%s)
46+
cache_age=$((current_timestamp - cache_timestamp))
47+
48+
if [ ${cache_age} -lt ${CACHE_TIMEOUT} ]; then
49+
logger -t kdevops-dhcp-cache "NetworkManager connectivity ${CONNECTIVITY} for ${INTERFACE}, restoring from cache (age: ${cache_age}s)"
50+
51+
# Apply cached configuration using nmcli
52+
if [ -n "${IP4_ADDRESS}" ]; then
53+
nmcli connection modify "${INTERFACE}" ipv4.method manual \
54+
ipv4.addresses "${IP4_ADDRESS}" \
55+
ipv4.gateway "${IP4_GATEWAY}" \
56+
ipv4.dns "${IP4_DNS}"
57+
nmcli connection up "${INTERFACE}"
58+
logger -t kdevops-dhcp-cache "Successfully restored cached NetworkManager configuration: ${IP4_ADDRESS}"
59+
fi
60+
else
61+
logger -t kdevops-dhcp-cache "Cached config for ${INTERFACE} expired (age: ${cache_age}s > ${CACHE_TIMEOUT}s)"
62+
fi
63+
else
64+
logger -t kdevops-dhcp-cache "No cached config found for ${INTERFACE} after connectivity change"
65+
fi
66+
fi
67+
;;
68+
esac

0 commit comments

Comments
 (0)