Browse Source

KVM: Remove need for ifupdown* to configure VM interfaces

Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
Maximilian Wilhelm 1 year ago
parent
commit
9c7c0bd8b1
3 changed files with 61 additions and 7 deletions
  1. 37 0
      kvm/get-bridge-vids
  2. 14 0
      kvm/init.sls
  3. 10 7
      kvm/qemu-hook

+ 37 - 0
kvm/get-bridge-vids

@@ -0,0 +1,37 @@
+#!/usr/bin/python3
+#
+# Maximilian Wilhelm <max@sdn.clinic>
+#  --  Fri 28 Apr 2023 08:41:13 PM CEST
+#
+
+import re
+import sys
+
+if len (sys.argv) != 2:
+    print("Usage: get-bridge-vids IFACE", file=sys.stderr)
+    sys.exit(1)
+
+ifname = sys.argv[1]
+
+ifstanza_re = re.compile(rf"^iface {ifname}")
+bridge_vid_re = re.compile(r"bridge-vids (.*)$")
+
+interfaces_fh = open("/etc/network/interfaces", "r")
+iface_found = False
+
+for line in interfaces_fh.readlines():
+    line = line.strip()
+
+    if line.startswith('#'):
+        continue
+
+    if iface_found:
+        match = bridge_vid_re.search(line)
+        if match:
+            print (match.group(1))
+
+        continue
+
+    match = ifstanza_re.search(line)
+    if match:
+        iface_found = True

+ 14 - 0
kvm/init.sls

@@ -15,9 +15,23 @@ virt-pkgs:
       - xmlstarlet
       - netcat-openbsd
 
+libvirtd:
+  service.running:
+    - enable: True
+    - reload: True
+
 /etc/libvirt/hooks/qemu:
   file.managed:
     - source: salt://kvm/qemu-hook
     - mode: 755
     - require:
       - pkg: virt-pkgs
+    - watch_in:
+      - service: libvirtd
+
+/etc/libvirt/hooks/get-bridge-vids:
+  file.managed:
+    - source: salt://kvm/get-bridge-vids
+    - mode: 755
+    - require:
+      - pkg: virt-pkgs

+ 10 - 7
kvm/qemu-hook

@@ -61,17 +61,17 @@ echo "${domain_xml}" | xmlstarlet sel -t -m '//interface[@type="bridge"]' -v 'co
 	vlan_id=$(echo ${iface} | grep -o '_v[0-9]\{1,4\}$' | cut -c3-)
 
 	# If vlan filtering is activated and we found a vlan id, kindly do the needful.
-	if [ "${vlan_filtering}" -a "${vlan_id}" ]; then
+	if [ "${vlan_filtering}" = 1 -a "${vlan_id}" ]; then
 		# Remove association with vlan 1 and add association with
 		# vlan $vlan_id with packages being sent out untagged and
 		# untagged ingress packets get tagged accordingly.
 		bridge vlan del vid 1 dev "${iface}"
 		bridge vlan add vid "${vlan_id}" dev "${iface}" pvid untagged
-		logger -t "${my_name}" "Configured untagged pvid ${vlan_id} for ${iface} in bridge ${bridge}."
+		logger -t "${my_name}" "Configured untagged VLAN ${vlan_id} for ${iface} in bridge ${bridge}."
 
 	# If vlan filtering isn't activated or supported but we found a vlan id,
 	# this probably is an error!
-	elif [ ! "${vlan_filtering}" -a "${vlan_id}" ]; then
+	elif [ "${vlan_filtering}" = 0 -a "${vlan_id}" ]; then
 		logger -t "${my_name}" -p user.error "ERROR: Should configure untagged pvid ${vlan_id} for ${iface} in bridge ${bridge}, but bridge does not support vlan filtering!"
 	fi
 
@@ -87,10 +87,13 @@ echo "${domain_xml}" | xmlstarlet sel -t -m '//interface[@type="bridge"]' -v 'co
 	# for this interfaces, we try to get it up and running. Proceed
 	# with fingers crossed.
 	if grep -q "^iface\s\+${iface}" /etc/network/interfaces; then
-		if ifup $iface; then
-			logger -t "${my_name}" "ifup'ed ${iface}."
-		else
-			logger -t "${my_name}" -p user.error "ifup ${iface} FAILED."
+		vids=$(/etc/libvirt/hooks/get-bridge-vids "${iface}")
+		if [ "${vids}" ]; then
+			bridge vlan del vid 1 dev "${iface}"
+			for vid in ${vids}; do
+				bridge vlan add vid ${vid} dev "${iface}"
+			done
+	                logger -t "${my_name}" "Configured tagged VLANs ${vids} for ${iface} in bridge ${bridge}."
 		fi
 	fi
 done