Browse Source

enough: unify network configuration libvirt/openstack

keep-around/51b54738f539c6a681edc7c1648a3a7b0e42e14c
Loïc Dachary 6 months ago
committed by some
parent
commit
51b54738f5
Signed by: dachary GPG Key ID: 992D23B392F9E4F2
  1. 23
      enough/common/libvirt.py
  2. 2
      enough/common/ssh.py
  3. 4
      inventory/group_vars/all/network.yml
  4. 94
      playbooks/infrastructure/network.sh
  5. 103
      playbooks/infrastructure/template-host.yaml
  6. 3
      tests/conftest.py

23
enough/common/libvirt.py

@ -42,10 +42,19 @@ class Libvirt(object):
return f'{self.config_dir}/infrastructure_key.pub'
def sysprep(self, name, definition):
sh.virt_sysprep('-a', self.host_image_name(name),
'--enable', 'customize',
'--no-network',
'--ssh-inject', f'debian:file:{self.public_key()}')
sh.virt_sysprep(
'-a', self.host_image_name(name),
'--enable', 'customize',
'--no-network',
'--ssh-inject', f'debian:file:{self.public_key()}',
'--copy-in', f'{self.share_dir}/playbooks/infrastructure/network.sh:/root',
'--firstboot-command', ('env '
f'PORT={definition["port"]} '
f'ROUTED={definition["network_interface_routed"]} '
f'NOT_ROUTED={definition["network_interface_not_routed"]} '
f'UNCONFIGURED={definition["network_interface_unconfigured"]} '
'bash -x /root/network.sh'),
)
def get(self, name):
try:
@ -126,6 +135,9 @@ class Libvirt(object):
'port': definition.get('ansible_port', '22'),
'ram': definition.get('libvirt_ram', '2048'),
# 'disk': definition.get('libvirt_disk', '20G'),
'network_interface_unconfigured': definition.get('network_interface_unconfigured'),
'network_interface_routed': definition.get('network_interface_routed'),
'network_interface_not_routed': definition.get('network_interface_not_routed'),
})
return r
@ -147,10 +159,11 @@ class Libvirt(object):
'--format', 'qcow2',
'--size', '20G',
'--install', 'sudo',
'--root-password', 'disabled',
'--run-command', 'dpkg-reconfigure --frontend=noninteractive openssh-server',
'--run-command', ('useradd -s /bin/bash -m debian || true ; '
'echo "debian ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-debian'),
'--edit', '/etc/network/interfaces: s/ens2/enp1s0/')
)
sh.chmod('0660', image)
sh.chgrp('libvirt', image)
return True

2
enough/common/ssh.py

@ -36,7 +36,7 @@ class SSH(object):
return subprocess.run(ssh + args, **kwargs)
@staticmethod
@retry((socket.timeout, ConnectionRefusedError, OSError), 9)
@retry((socket.timeout, ConnectionRefusedError, OSError), 8)
def wait_for_ssh(ip, port):
log.info('Check if SSH is available on %s:%s', ip, port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

4
inventory/group_vars/all/network.yml

@ -15,8 +15,8 @@
# the default route is network_secondary_interface
#
network_internal_only: false
network_primary_interface: eth0
network_secondary_interface: eth1
network_primary_interface: "{{ infrastructure_driver == 'openstack' | ternary('eth0', 'enp1s0') }}"
network_secondary_interface: "{{ infrastructure_driver == 'openstack' | ternary('eth1', 'enp2s0') }}"
#
# Only one of the two interfaces is routed
#

94
playbooks/infrastructure/network.sh

@ -0,0 +1,94 @@
#!/bin/bash
#
# Prefer IPv4 because IPv6 is not supported
#
sed -i -e 's|^#precedence ::ffff:0:0/96 100|precedence ::ffff:0:0/96 100|' /etc/gai.conf
echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99force-ipv4
if [ "$PORT" -ne "22" ]; then
# Reload SSH
sed -i -e '/^#Port/s/^.*$/Port '$PORT'/' /etc/ssh/sshd_config
systemctl reload ssh
fi
if test -f /etc/network/interfaces.d/50-cloud-init ; then
if ! test -f /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg ; then
echo 'network: {config: disabled}' > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
rm -f /etc/network/interfaces.d/50-cloud-init
fi
fi
for i in $ROUTED $NOT_ROUTED $UNCONFIGURED ; do
if test "$i" != "noname" ; then
ip link set "$i" up
for _ in $(seq 500) ; do
if test "$(cat /sys/class/net/$i/operstate)" = "up" ; then
break
fi
sleep 1
done
if test "$(cat /sys/class/net/$i/operstate)" != "up" ; then
echo "the $i interface is not up, giving up"
fi
fi
done
ifdown --force $ROUTED
if test $NOT_ROUTED != noname ; then
ifdown --force $NOT_ROUTED
fi
if test $UNCONFIGURED != noname ; then
ifdown --force $UNCONFIGURED
fi
#
# This may be necessary when a given interface is specified multiple
# times in /etc/network/interfaces* at boot time, resulting in multiple
# dhclient running. When bringing down the interface (see above) only
# one dhclient will be killed and the other will remain until the next
# reboot, interfering with other dhclient in unpredictible ways.
#
pkill -f dhclient
#
# Whatever resolvconf has cached for a given interface so far is
# discarded. In some weird cases /var/run/resolvconf/interface/lo.inet
# is set to a nameserver that will stick around until the next reboot
# and cannot be discarded.
#
rm -f /var/run/resolvconf/interface/*
cat > /etc/dhcp/dhclient-enter-hooks.d/ignore_unrequested_options <<'EOF'
# some DHCP servers send unrequested options: ignore these options
RUN="yes"
if [ "$RUN" = "yes" ]; then
if [ "$interface" = "$NOT_ROUTED" ]; then
# loop over some DHCP variables passed to dhclient-script
for var in new_domain_name new_domain_search new_domain_name_servers \
new_routers new_rfc3442_classless_static_routes; do
unset $var
done
fi
fi
EOF
echo 'source /etc/network/interfaces.d/*' > /etc/network/interfaces
( echo 'auto lo' ; echo 'iface lo inet loopback' ) > /etc/network/interfaces.d/interface-lo.cfg
cp /etc/dhcp/dhclient.conf /etc/dhcp/dhclient_routers.conf
( echo "auto $ROUTED" ; echo "iface $ROUTED inet manual" ; echo ' mtu 1500' ; echo " up /sbin/dhclient -4 -v -pf /run/dhclient.$ROUTED.pid -lf /var/lib/dhcp/dhclient.$ROUTED.leases -I -cf /etc/dhcp/dhclient_routers.conf $ROUTED" ; echo " down /sbin/dhclient -4 -v -r -pf /run/dhclient.$ROUTED.pid -lf /var/lib/dhcp/dhclient.$ROUTED.leases -I -cf /etc/dhcp/dhclient_routers.conf $ROUTED" ) > /etc/network/interfaces.d/interface-$ROUTED.cfg
cp /etc/dhcp/dhclient.conf /etc/dhcp/dhclient_no_routers.conf
sed -i -e 's/routers,//' -e 's/rfc3442-classless-static-routes,//' -e 's/domain-name, domain-name-servers, domain-search,//' /etc/dhcp/dhclient_no_routers.conf
if test $NOT_ROUTED != noname ; then
( echo "allow-hotplug $NOT_ROUTED" ; echo "auto $NOT_ROUTED" ; echo "iface $NOT_ROUTED inet manual" ; echo ' mtu 1500' ; echo " up /sbin/dhclient -4 -v -pf /run/dhclient.$NOT_ROUTED.pid -lf /var/lib/dhcp/dhclient.$NOT_ROUTED.leases -I -cf /etc/dhcp/dhclient_no_routers.conf $NOT_ROUTED" ; echo " down /sbin/dhclient -4 -v -r -pf /run/dhclient.$NOT_ROUTED.pid -lf /var/lib/dhcp/dhclient.$NOT_ROUTED.leases -I -cf /etc/dhcp/dhclient_no_routers.conf $NOT_ROUTED" ) > /etc/network/interfaces.d/interface-$NOT_ROUTED.cfg
fi
if test $UNCONFIGURED != noname ; then
( echo "auto $UNCONFIGURED" ; echo "iface $UNCONFIGURED inet manual" ) > /etc/network/interfaces.d/interface-$UNCONFIGURED.cfg
fi
ifup $ROUTED
if test $NOT_ROUTED != noname ; then
ifup $NOT_ROUTED
fi

103
playbooks/infrastructure/template-host.yaml

@ -61,105 +61,12 @@ resources:
- network: { get_param: network }
user_data:
str_replace:
template: |
#!/bin/bash
#
# Prefer IPv4 because IPv6 is not supported
#
sed -i -e 's|^#precedence ::ffff:0:0/96 100|precedence ::ffff:0:0/96 100|' /etc/gai.conf
echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99force-ipv4
if [ "PORT" -ne "22" ]; then
# Reload SSH
sed -i -e '/^#Port/s/^.*$/Port PORT/' /etc/ssh/sshd_config
systemctl reload ssh
fi
if test -f /etc/network/interfaces.d/50-cloud-init ; then
if ! test -f /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg ; then
echo 'network: {config: disabled}' > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
rm -f /etc/network/interfaces.d/50-cloud-init
fi
fi
for i in ROUTED NOT_ROUTED UNCONFIGURED ; do
if test "$i" != "noname" ; then
for _ in $(seq 500) ; do
if test "$(cat /sys/class/net/$i/operstate)" = "up" ; then
break
fi
sleep 1
done
if test "$(cat /sys/class/net/$i/operstate)" != "up" ; then
echo "the $i interface is not up, giving up"
fi
fi
done
ifdown --force ROUTED
if test NOT_ROUTED != noname ; then
ifdown --force NOT_ROUTED
fi
if test UNCONFIGURED != noname ; then
ifdown --force UNCONFIGURED
fi
#
# This may be necessary when a given interface is specified multiple
# times in /etc/network/interfaces* at boot time, resulting in multiple
# dhclient running. When bringing down the interface (see above) only
# one dhclient will be killed and the other will remain until the next
# reboot, interfering with other dhclient in unpredictible ways.
#
pkill -f dhclient
#
# Whatever resolvconf has cached for a given interface so far is
# discarded. In some weird cases /var/run/resolvconf/interface/lo.inet
# is set to a nameserver that will stick around until the next reboot
# and cannot be discarded.
#
rm -f /var/run/resolvconf/interface/*
cat > /etc/dhcp/dhclient-enter-hooks.d/ignore_unrequested_options <<'EOF'
# some DHCP servers send unrequested options: ignore these options
RUN="yes"
if [ "$RUN" = "yes" ]; then
if [ "$interface" = "NOT_ROUTED" ]; then
# loop over some DHCP variables passed to dhclient-script
for var in new_domain_name new_domain_search new_domain_name_servers \
new_routers new_rfc3442_classless_static_routes; do
unset $var
done
fi
fi
EOF
echo 'source /etc/network/interfaces.d/*' > /etc/network/interfaces
( echo 'auto lo' ; echo 'iface lo inet loopback' ) > /etc/network/interfaces.d/interface-lo.cfg
cp /etc/dhcp/dhclient.conf /etc/dhcp/dhclient_routers.conf
( echo 'auto ROUTED' ; echo 'iface ROUTED inet manual' ; echo ' mtu 1500' ; echo ' up /sbin/dhclient -4 -v -pf /run/dhclient.ROUTED.pid -lf /var/lib/dhcp/dhclient.ROUTED.leases -I -cf /etc/dhcp/dhclient_routers.conf ROUTED' ; echo ' down /sbin/dhclient -4 -v -r -pf /run/dhclient.ROUTED.pid -lf /var/lib/dhcp/dhclient.ROUTED.leases -I -cf /etc/dhcp/dhclient_routers.conf ROUTED' ) > /etc/network/interfaces.d/interface-ROUTED.cfg
cp /etc/dhcp/dhclient.conf /etc/dhcp/dhclient_no_routers.conf
sed -i -e 's/routers,//' -e 's/rfc3442-classless-static-routes,//' -e 's/domain-name, domain-name-servers, domain-search,//' /etc/dhcp/dhclient_no_routers.conf
if test NOT_ROUTED != noname ; then
( echo 'allow-hotplug NOT_ROUTED' ; echo 'auto NOT_ROUTED' ; echo 'iface NOT_ROUTED inet manual' ; echo ' mtu 1500' ; echo ' up /sbin/dhclient -4 -v -pf /run/dhclient.NOT_ROUTED.pid -lf /var/lib/dhcp/dhclient.NOT_ROUTED.leases -I -cf /etc/dhcp/dhclient_no_routers.conf NOT_ROUTED' ; echo ' down /sbin/dhclient -4 -v -r -pf /run/dhclient.NOT_ROUTED.pid -lf /var/lib/dhcp/dhclient.NOT_ROUTED.leases -I -cf /etc/dhcp/dhclient_no_routers.conf NOT_ROUTED' ) > /etc/network/interfaces.d/interface-NOT_ROUTED.cfg
fi
if test UNCONFIGURED != noname ; then
( echo 'auto UNCONFIGURED' ; echo 'iface UNCONFIGURED inet manual' ) > /etc/network/interfaces.d/interface-UNCONFIGURED.cfg
fi
ifup ROUTED
if test NOT_ROUTED != noname ; then
ifup NOT_ROUTED
fi
template: { get_file: network.sh }
params:
PORT: { get_param: port }
UNCONFIGURED: { get_param: network_interface_unconfigured }
ROUTED: { get_param: network_interface_routed }
NOT_ROUTED: { get_param: network_interface_not_routed }
$PORT: { get_param: port }
$UNCONFIGURED: { get_param: network_interface_unconfigured }
$ROUTED: { get_param: network_interface_routed }
$NOT_ROUTED: { get_param: network_interface_not_routed }
volume:
type: OS::Cinder::Volume

3
tests/conftest.py

@ -154,6 +154,9 @@ class InfrastructureLibvirt(Infrastructure):
'name': self.prefix,
'ansible_port': port,
'libvirt_ram': '1024',
'network_interface_unconfigured': 'noname',
'network_interface_routed': 'enp1s0',
'network_interface_not_routed': 'enp2s0',
},
}
definitions[self.prefix].update(global_variables)

Loading…
Cancel
Save