fix: correctly predict interface name on darwin

Old implementation didn't work if the interface to be created wasn't the biggest index.

For example if interfaces `bridge100` and `bridge102` already existed, vmnet would create a `bridge 101`,
but the old logic expected a `bridge103`.

Signed-off-by: Orzelius <albert.kostusev@siderolabs.com>
This commit is contained in:
Orzelius 2025-06-09 18:56:41 +09:00
parent cfcfad3c45
commit 3035744a80
No known key found for this signature in database
GPG Key ID: C17C8E3962A0D9B1
2 changed files with 8 additions and 27 deletions

View File

@ -5,39 +5,20 @@
package vm
import (
"errors"
"fmt"
"regexp"
"strconv"
"sync"
"slices"
)
var vmnetInterfaceRegex = sync.OnceValue(func() *regexp.Regexp { return regexp.MustCompile(`\bbridge(1\d\d)\b`) })
// GetVmnetInterfaceName returns the name of the interface that will be assigned to the next vmnet interface.
// The name is assigned incrementing by one, starting from "bridge100".
func GetVmnetInterfaceName(allCurrentInterfaces []string) (string, error) {
vmnetInterfaceFound := false
largestVmnetIfIndex := 100
for _, iface := range allCurrentInterfaces {
matches := vmnetInterfaceRegex().FindSubmatch([]byte(iface))
if matches != nil {
vmnetInterfaceFound = true
index, err := strconv.Atoi(string(matches[1]))
if err != nil {
return "", fmt.Errorf("failed to parse interface name: %w", err)
}
if index > largestVmnetIfIndex {
largestVmnetIfIndex = index
}
for i := 100; i < 200; i++ {
interfaceName := fmt.Sprintf("bridge%d", i)
if slices.Index(allCurrentInterfaces, interfaceName) == -1 {
return interfaceName, nil
}
}
if !vmnetInterfaceFound {
return "bridge100", nil
}
return "bridge" + strconv.Itoa(largestVmnetIfIndex+1), nil
return "", errors.New("all interface names seem to be already in use")
}

View File

@ -24,7 +24,7 @@ func TestGetVmnetInterfaceNameNoVmnetInterface(t *testing.T) {
func TestGetVmnetInterfaceNameWithExistingVmnetInterfaces(t *testing.T) {
interfaces := []string{
"bridge", "bridge1", "eth0", "utun1", "bridge001", "bridge1001", "bridge100", "bridge101",
"bridge", "bridge1", "eth0", "utun1", "bridge001", "bridge1001", "bridge100", "bridge101", "bridge104",
}
result, err := vm.GetVmnetInterfaceName(interfaces)
assert.NoError(t, err)