-
Notifications
You must be signed in to change notification settings - Fork 14
Description
Hi! I really appreciate the debops project! :-) I've done my best to exclude errors on my part, but as best as I can tell, the ifupdown-reconfigure-interfaces can never successfully reconfigure interfaces on my Debian Buster system.
The scenario: A baremetal server with some LXC containers running on it, interfaces are configured statically. The ifupdown role will generate the interface configs in /etc/network/interface.config.d/ but the task to apply the new configs always fails.
From looking at the script, it seems the issue revolves around the assumption that systemd-based systems always have ifup@${if}.service units to control their network interfaces... my system is systemd-based, but has no such units, either on host or in containers.
For the sake of sparing the baremetal host a lot of mucking around with the network, I've done most of my testing with a test container, but the behavior is the same when applied against the host:
(.ansible_venv) ansible@mgmt1:~/midgard/prod$ debops -l test1 --tags "role::ifupdown" Running Ansible playbooks:
/opt/ansible/midgard/prod/ansible/playbooks/site.yml
...
PLAY [Manage network configuration using ifupdown] ********************************************************************
TASK [Gathering Facts] ************************************************************************************************
ok: [test1]
TASK [ifupdown : Prepare configuration of dependent Ansible roles] ****************************************************
ok: [test1]
TASK [sysctl : Pre hooks] *********************************************************************************************
TASK [sysctl : Post hooks] ********************************************************************************************
TASK [ifupdown : Make sure that Ansible local facts directory exists] *************************************************
ok: [test1]
TASK [ifupdown : Save ifupdown local facts] ***************************************************************************
ok: [test1]
TASK [ifupdown : Install required packages] ***************************************************************************
ok: [test1]
TASK [ifupdown : Purge conflicting packages] **************************************************************************
ok: [test1]
TASK [ifupdown : Check systemd version] *******************************************************************************
ok: [test1]
TASK [ifupdown : Install custom ifupdown services] ********************************************************************
ok: [test1] => (item=iface@.service)
ok: [test1] => (item=ifup-wait-all-auto.service)
ok: [test1] => (item=ifup-allow-boot.service)
TASK [ifupdown : Test if Ansible is running in check mode] ************************************************************
ok: [test1]
TASK [ifupdown : Enable custom ifupdown services] *********************************************************************
ok: [test1] => (item=ifup-wait-all-auto)
ok: [test1] => (item=ifup-allow-boot)
TASK [ifupdown : Create configuration directories] ********************************************************************
ok: [test1] => (item=/etc/network/interfaces.d)
ok: [test1] => (item=/etc/network/interfaces.config.d)
TASK [ifupdown : Divert original /etc/network/interfaces] *************************************************************
ok: [test1]
TASK [ifupdown : Create /etc/network/interfaces] **********************************************************************
changed: [test1]
TASK [ifupdown : Ensure that runtime directory exists] ****************************************************************
ok: [test1]
TASK [ifupdown : Request entire network reconfiguration] **************************************************************
changed: [test1]
TASK [ifupdown : Generate network interface configuration] ************************************************************
changed: [test1] => (item={'key': 'eth0', 'value': {'address': '10.100.201.201/16', 'allow': 'hotplug', 'auto': True, 'dns_nameservers': ['10.100.0.2', '10.100.0.1'], 'dns_search': ['midgard.metalwanderer.net'], 'gateway': '10.100.254.254', 'iface': 'eth0', 'inet': 'static', 'inet6': 'auto', 'type': 'ether'}})
TASK [ifupdown : Remove unknown interface configuration] **************************************************************
changed: [test1] => (item={'diff': [], 'dest': '/etc/network/interfaces.config.d/020_iface_eth0', 'src': '/opt/ansible/.ansible/tmp/ansible-tmp-1630618748.460853-1555-254863054817577/source', 'md5sum': '8b79c694c47bae5507c79247f6867de8', 'checksum': '4274a513ad2e2092b86e06428ec96f5a4d2f7d49', 'changed': True, 'uid': 0, 'gid': 0, 'owner': 'root', 'group': 'root', 'mode': '0644', 'state': 'file', 'size': 330, 'invocation': {'module_args': {'src': '/opt/ansible/.ansible/tmp/ansible-tmp-1630618748.460853-1555-254863054817577/source', 'dest': '/etc/network/interfaces.config.d/020_iface_eth0', 'owner': 'root', 'group': 'root', 'mode': '0644', 'follow': False, '_original_basename': 'iface.j2', 'checksum': '4274a513ad2e2092b86e06428ec96f5a4d2f7d49', 'backup': False, 'force': True, 'unsafe_writes': False, 'content': None, 'validate': None, 'directory_mode': None, 'remote_src': None, 'local_follow': None, 'seuser': None, 'serole': None, 'selevel': None, 'setype': None, 'attributes': None}}, 'failed': False, 'item': {'key': 'eth0', 'value': {'address': '10.100.201.201/16', 'allow': 'hotplug', 'auto': True, 'dns_nameservers': ['10.100.0.2', '10.100.0.1'], 'dns_search': ['midgard.metalwanderer.net'], 'gateway': '10.100.254.254', 'iface': 'eth0', 'inet': 'static', 'inet6': 'auto', 'type': 'ether'}}, 'ansible_loop_var': 'item'})
TASK [ifupdown : Mark modified interfaces for processing] *************************************************************
changed: [test1] => (item={'diff': [], 'dest': '/etc/network/interfaces.config.d/020_iface_eth0', 'src': '/opt/ansible/.ansible/tmp/ansible-tmp-1630618748.460853-1555-254863054817577/source', 'md5sum': '8b79c694c47bae5507c79247f6867de8', 'checksum': '4274a513ad2e2092b86e06428ec96f5a4d2f7d49', 'changed': True, 'uid': 0, 'gid': 0, 'owner': 'root', 'group': 'root', 'mode': '0644', 'state': 'file', 'size': 330, 'invocation': {'module_args': {'src': '/opt/ansible/.ansible/tmp/ansible-tmp-1630618748.460853-1555-254863054817577/source', 'dest': '/etc/network/interfaces.config.d/020_iface_eth0', 'owner': 'root', 'group': 'root', 'mode': '0644', 'follow': False, '_original_basename': 'iface.j2', 'checksum': '4274a513ad2e2092b86e06428ec96f5a4d2f7d49', 'backup': False, 'force': True, 'unsafe_writes': False, 'content': None, 'validate': None, 'directory_mode': None, 'remote_src': None, 'local_follow': None, 'seuser': None, 'serole': None, 'selevel': None, 'setype': None, 'attributes': None}}, 'failed': False, 'item': {'key': 'eth0', 'value': {'address': '10.100.201.201/16', 'allow': 'hotplug', 'auto': True, 'dns_nameservers': ['10.100.0.2', '10.100.0.1'], 'dns_search': ['midgard.metalwanderer.net'], 'gateway': '10.100.254.254', 'iface': 'eth0', 'inet': 'static', 'inet6': 'auto', 'type': 'ether'}}, 'ansible_loop_var': 'item'})
TASK [ifupdown : Install custom ifupdown hooks] ***********************************************************************
ok: [test1] => (item={'name': 'filter-dhcp-options', 'hook': 'etc/dhcp/dhclient-enter-hooks.d/filter-dhcp-options', 'mode': '0644', 'state': 'present'})
TASK [ifupdown : Save role version information] ***********************************************************************
ok: [test1]
RUNNING HANDLER [ifupdown : Apply ifupdown configuration] *************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: NoneType: None
fatal: [test1]: FAILED! => changed=true
msg: non-zero return code
rc: 1
stderr: |-
Shared connection to test1.midgard.metalwanderer.net closed.
stderr_lines: <omitted>
stdout: |-
Detected interfaces to reconfigure: eth0
Bringing down 'eth0' interface
Error: Script was working on 'eth0' network interface when it lost knowledge about the network interface state. The '/etc/network/interfaces.d/' might be desynchronized. Exiting to avoid loss of connectivity, investigate the issue.
stdout_lines: <omitted>
NO MORE HOSTS LEFT ****************************************************************************************************
PLAY RECAP ************************************************************************************************************
test1 : ok=25 changed=5 unreachable=0 failed=1 skipped=9 rescued=0 ignored=0
Purge conflicting packages ---------------------------------------------- 4.21s
Prepare configuration of dependent Ansible roles ------------------------ 4.04s
Install custom ifupdown services ---------------------------------------- 2.56s
Gathering Facts --------------------------------------------------------- 2.52s
Generate network interface configuration -------------------------------- 2.16s
Install required packages ----------------------------------------------- 2.11s
Install custom ifupdown hooks ------------------------------------------- 1.95s
Enable custom ifupdown services ----------------------------------------- 1.68s
Remove network interface configuration ---------------------------------- 1.17s
Save ifupdown local facts ----------------------------------------------- 1.15s
Relevant hostvars:
---
ifupdown__interface_layout: static
ifupdown__host_interfaces:
"eth0":
inet: static
allow: hotplug
address: >
{{ [ ansible_facts.eth0.ipv4.address, ansible_facts.eth0.ipv4.netmask ] |
join('/') | ansible.netcommon.ipv4 }}
gateway: "{{ gateways_prod[0] }}"
dns_nameservers: "{{ nameservers_prod }}"
dns_search: "{{ ( [netbase__domain] + [site_domain] ) | unique }}"
auto: True
Filesystem state after run:
root@test1:~# find /etc/network
/etc/network
/etc/network/interfaces
/etc/network/interfaces.dpkg-divert
/etc/network/if-up.d
/etc/network/if-up.d/000resolvconf
/etc/network/if-up.d/chrony
/etc/network/interfaces.d
/etc/network/if-post-down.d
/etc/network/if-post-down.d/chrony
/etc/network/interfaces.config.d
/etc/network/interfaces.config.d/020_iface_eth0
/etc/network/if-pre-up.d
/etc/network/if-down.d
/etc/network/if-down.d/resolvconf
To attempt to manually apply, I restore the /etc/network/interfaces file, and run with: debops -l test1 --tags "role::ifupdown" --extra-vars "ifupdown__reconfigure_auto=False"
After the run, on the container:
root@test1:~# find /run/network
/run/network
/run/network/debops-ifupdown-reconfigure,020,eth0
/run/network/debops-ifupdown-reconfigure.networking
/run/network/ifstate
/run/network/ifstate.eth0
/run/network/.ifstate.lock
/run/network/ifstate.lo
# I've added 'set -x' at the beginning of the script to get debug output
root@test1:~# /usr/local/lib/ifupdown-reconfigure-interfaces
+ set -o nounset -o pipefail -o errexit
+ pid=10696
++ basename /usr/local/lib/ifupdown-reconfigure-interfaces
+ script=ifupdown-reconfigure-interfaces
+ interface_request_path=/run/network
+ interface_request_prefix=debops-ifupdown-reconfigure
+ interface_reconfigure_all=networking
+ trap on_exit EXIT
+ '[' -d /run/network ']'
+ declare -a changed_interfaces
+ declare -a changed_interface_names
+ declare -a created_interfaces
+ declare -a removed_interfaces
+ mapfile -t changed_interfaces
++ find /run/network -type f -name 'debops-ifupdown-reconfigure,*'
++ sed -e 's#^/run/network/debops-ifupdown-reconfigure,##'
++ sort -n
+ mapfile -t changed_interface_names
++ find /run/network -type f -name 'debops-ifupdown-reconfigure,*'
++ sed -e 's#^/run/network/debops-ifupdown-reconfigure,##'
++ sort -n
++ sed -e 's/^.*\,//'
+ '[' 1 -gt 0 ']'
++ join_by , eth0
++ local IFS=,
++ shift
++ echo eth0
+ log_message -m 'Detected interfaces to reconfigure: eth0'
+ local -A args
+ local OPTIND optchar
+ local optspec=:mflth-:
+ getopts :mflth-: optchar
+ case "${optchar}" in
+ args["message"]='Detected interfaces to reconfigure: eth0'
+ OPTIND=3
+ getopts :mflth-: optchar
+ key_exists args message
+ eval '[ ${args[$2]+test_of_existence} ]'
++ '[' test_of_existence ']'
+ tty -s
+ echo 'Detected interfaces to reconfigure: eth0'
Detected interfaces to reconfigure: eth0
+ type logger
+ logger -t 'ifupdown-reconfigure-interfaces[10696]' 'Detected interfaces to reconfigure: eth0'
+ declare -a systemd_ifup_instances
+ declare -a systemd_iface_instances
+ declare -a systemd_interface_instances
+ is_systemd
+ '[' -d /run/systemd/system ']'
+ return 0
+ mapfile -t systemd_ifup_instances
++ systemctl list-units --no-legend --state=active 'ifup@*.service'
++ awk '{print $1}'
++ sed -e 's/^ifup\@//' -e 's/\.service$//'
+ mapfile -t systemd_iface_instances
++ systemctl list-units --no-legend --state=active 'iface@*.service'
++ awk '{print $1}'
++ sed -e 's/^iface\@//' -e 's/\.service$//'
+ '[' 0 -gt 0 ']'
+ '[' 0 -gt 0 ']'
+ systemd_interface_instances=("${systemd_ifup_instances[@]:-}" "${systemd_iface_instances[@]:-}")
+ containsElement networking eth0
+ local e
+ for e in "${@:2}"
+ [[ eth0 == \n\e\t\w\o\r\k\i\n\g ]]
+ return 1
+ (( i=1-1 ))
+ (( i>=0 ))
+ iface=020,eth0
++ echo 020,eth0
++ sed -e 's/^.*\,//'
+ iface_name=eth0
+ '[' 020,eth0 '!=' networking ']'
+ '[' changed '!=' created ']'
+ ifquery --state eth0
+ log_message -m 'Bringing down '\''eth0'\'' interface'
+ local -A args
+ local OPTIND optchar
+ local optspec=:mflth-:
+ getopts :mflth-: optchar
+ case "${optchar}" in
+ args["message"]='Bringing down '\''eth0'\'' interface'
+ OPTIND=3
+ getopts :mflth-: optchar
+ key_exists args message
+ eval '[ ${args[$2]+test_of_existence} ]'
++ '[' test_of_existence ']'
+ tty -s
+ echo 'Bringing down '\''eth0'\'' interface'
Bringing down 'eth0' interface
+ type logger
+ logger -t 'ifupdown-reconfigure-interfaces[10696]' 'Bringing down '\''eth0'\'' interface'
+ interface_down eth0
+ is_systemd
+ '[' -d /run/systemd/system ']'
+ return 0
+ local -a if_hotplug_interfaces
+ local -a if_boot_interfaces
+ local -a systemd_ifup_instances
+ mapfile -t if_hotplug_interfaces
++ ifquery --list --allow=hotplug
+ mapfile -t if_boot_interfaces
++ ifquery --list --allow=boot
+ mapfile -t systemd_ifup_instances
++ systemctl list-units --no-legend --state=active 'ifup@*.service'
++ awk '{print $1}'
++ sed -e 's/^ifup\@//' -e 's/\.service$//'
+ '[' 0 -gt 0 ']'
+ '[' 0 -gt 0 ']'
+ ifquery --state eth0
+ containsElement eth0 '' ''
+ local e
+ for e in "${@:2}"
+ [[ '' == \e\t\h\0 ]]
+ for e in "${@:2}"
+ [[ '' == \e\t\h\0 ]]
+ return 1
+ log_message -m 'Error: Script was working on '\''eth0'\'' network interface when it lost knowledge about the network interface state. The '\''/etc/network/interfaces.d/'\'' might be desynchronized. Exiting to avoid loss of connectivity, investigate the issue.'
+ local -A args
+ local OPTIND optchar
+ local optspec=:mflth-:
+ getopts :mflth-: optchar
+ case "${optchar}" in
+ args["message"]='Error: Script was working on '\''eth0'\'' network interface when it lost knowledge about the network interface state. The '\''/etc/network/interfaces.d/'\'' might be desynchronized. Exiting to avoid loss of connectivity, investigate the issue.'
+ OPTIND=3
+ getopts :mflth-: optchar
+ key_exists args message
+ eval '[ ${args[$2]+test_of_existence} ]'
++ '[' test_of_existence ']'
+ tty -s
+ echo 'Error: Script was working on '\''eth0'\'' network interface when it lost knowledge about the network interface state. The '\''/etc/network/interfaces.d/'\'' might be desynchronized. Exiting to avoid loss of connectivity, investigate the issue.'
Error: Script was working on 'eth0' network interface when it lost knowledge about the network interface state. The '/etc/network/interfaces.d/' might be desynchronized. Exiting to avoid loss of connectivity, investigate the issue.
+ type logger
+ logger -t 'ifupdown-reconfigure-interfaces[10696]' 'Error: Script was working on '\''eth0'\'' network interface when it lost knowledge about the network interface state. The '\''/etc/network/interfaces.d/'\'' might be desynchronized. Exiting to avoid loss of connectivity, investigate the issue.'
+ exit 1
+ on_exit
+ rm -f /run/network/debops-ifupdown-reconfigure,020,eth0
This is a systemd-based system:
root@test1:~# ls -d /run/systemd/system
/run/systemd/system
root@test1:~# dpkg -s systemd | grep Version:
Version: 241-7~deb10u8
But there are no ifup@${if}.service units:
root@test1:~# systemctl list-units --no-legend --state=active 'ifup@*.service'
root@test1:~# echo $?
0
So it seems to me that interface_down() will always fail to stop any interfaces.
There is nothing particularly unusual about my install that I can think of which make networking behave radically different. Am I missing something obvious?
Here's some output from the baremetal host:
root@thor:~# ifdown br_mgmt
root@thor:~# systemctl start ifup@br_mgmt.service
A dependency job for ifup@br_mgmt.service failed. See 'journalctl -xe' for details.
root@thor:~# journalctl -xe
Sep 02 22:34:05 thor audit[10842]: AVC apparmor="ALLOWED" operation="open" profile="/usr/sbin/sssd" name="/sys/devices/
Sep 02 22:34:05 thor kernel: audit: type=1400 audit(1630614845.624:24283): apparmor="ALLOWED" operation="open" profile=
Sep 02 22:35:58 thor systemd[1]: sys-subsystem-net-devices-br_mgmt.device: Job sys-subsystem-net-devices-br_mgmt.device
Sep 02 22:35:58 thor systemd[1]: Timed out waiting for device /sys/subsystem/net/devices/br_mgmt.
-- Subject: A start job for unit sys-subsystem-net-devices-br_mgmt.device has failed
-- Defined-By: systemd
-- Support: https://www.debian.org/support
--
-- A start job for unit sys-subsystem-net-devices-br_mgmt.device has finished with a failure.
--
-- The job identifier is 13458 and the job result is timeout.
Sep 02 22:35:58 thor systemd[1]: Dependency failed for ifup for br_mgmt.
-- Subject: A start job for unit ifup@br_mgmt.service has failed
-- Defined-By: systemd
-- Support: https://www.debian.org/support
--
-- A start job for unit ifup@br_mgmt.service has finished with a failure.
--
-- The job identifier is 13455 and the job result is dependency.
Sep 02 22:35:58 thor systemd[1]: ifup@br_mgmt.service: Job ifup@br_mgmt.service/start failed with result 'dependency'.
Sep 02 22:35:58 thor systemd[1]: sys-subsystem-net-devices-br_mgmt.device: Job sys-subsystem-net-devices-br_mgmt.device
Sep 02 22:36:01 thor CRON[23138]: pam_unix(cron:session): session opened for user root by (uid=0)
Sep 02 22:36:01 thor CRON[23139]: (root) CMD (cd / && run-parts --report /etc/cron.hourly)
Sep 02 22:36:01 thor CRON[23138]: pam_unix(cron:session): session closed for user root
root@thor:~# systemctl list-units --no-legend --state=active 'ifup@*.service'
root@thor:~# ifup br_mgmt
Waiting for br_mgmt to get ready (MAXWAIT is 32 seconds).
root@thor:~# ip a show dev br_mgmt
138: br_mgmt: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 2c:ea:7f:f9:c1:64 brd ff:ff:ff:ff:ff:ff
inet 10.254.10.10/16 brd 10.254.255.255 scope global br_mgmt
valid_lft forever preferred_lft forever
inet6 fe80::2eea:7fff:fef9:c164/64 scope link
valid_lft forever preferred_lft forever
root@thor:~# find /etc/network
/etc/network
/etc/network/if-up.d
/etc/network/if-up.d/chrony
/etc/network/if-up.d/ip
/etc/network/if-up.d/ifenslave
/etc/network/if-up.d/000resolvconf
/etc/network/interfaces
/etc/network/interfaces.config.d
/etc/network/interfaces.d
/etc/network/interfaces.d/020_iface_eno2
/etc/network/interfaces.d/010_iface_bond0
/etc/network/interfaces.d/060_iface_br_local
/etc/network/interfaces.d/060_iface_br_guest
/etc/network/interfaces.d/020_iface_eno1
/etc/network/interfaces.d/020_iface_ens1f1
/etc/network/interfaces.d/020_iface_ens1f0
/etc/network/interfaces.d/060_iface_br_mgmt
/etc/network/interfaces.d/015_iface_bond0.1
/etc/network/interfaces.d/015_iface_bond0.1200
/etc/network/if-down.d
/etc/network/if-down.d/resolvconf
/etc/network/interfaces.dpkg-divert
/etc/network/interfaces.old
/etc/network/if-post-down.d
/etc/network/if-post-down.d/chrony
/etc/network/if-post-down.d/bridge
/etc/network/if-post-down.d/ifenslave
/etc/network/if-post-down.d/vlan
/etc/network/if-pre-up.d
/etc/network/if-pre-up.d/bridge
/etc/network/if-pre-up.d/ifenslave
/etc/network/if-pre-up.d/vlan
Note: I have manually moved the interface configs from interfaces.config.d/ to interfaces.d/ to activate them.
What's so strange about my setup that it breaks the script assumptions?