m/n/c/network: log interfaces when none match

This helps users figure out what interfaces are available for matching
when no interfaces match a given description. Also helps distinguishing
bad selectors from hardware which does not show up (because of missing
drivers or hardware/firmware issues).

Change-Id: Ie4bbdc04b76af7feed123b5df587c9eb5ee7ea37
Reviewed-on: https://review.monogon.dev/c/monogon/+/4395
Tested-by: Jenkins CI
Reviewed-by: Jan Schär <jan@monogon.tech>
diff --git a/metropolis/node/core/network/static.go b/metropolis/node/core/network/static.go
index 43eef08..059cd5d 100644
--- a/metropolis/node/core/network/static.go
+++ b/metropolis/node/core/network/static.go
@@ -310,6 +310,20 @@
 		}
 		matchedDevices = append(matchedDevices, d.dev)
 	}
+	if len(matchedDevices) == 0 {
+		var available []string
+		for _, d := range hostDevices {
+			hwAddr := d.dev.HardwareAddr
+			if len(d.dev.PermHWAddr) > 0 {
+				hwAddr = d.dev.PermHWAddr
+			}
+			available = append(available, fmt.Sprintf("(%v,%v)", d.driver, hwAddr))
+		}
+		if len(available) == 0 {
+			available = append(available, "none")
+		}
+		return nil, fmt.Errorf("no host devices match (driver=%v,hwaddr=%v), have %s", it.Device.Driver, it.Device.HardwareAddress, strings.Join(available, ", "))
+	}
 	if len(matchedDevices) <= int(it.Device.Index) || it.Device.Index < 0 {
 		return nil, fmt.Errorf("there are %d matching host devices but requested device index is %d", len(matchedDevices), it.Device.Index)
 	}