This commit is contained in:
MengMengCode
2026-07-22 16:57:44 +08:00
parent ec38ab9136
commit 53d56be8f9
3 changed files with 46 additions and 9 deletions
+15 -7
View File
@@ -1724,12 +1724,12 @@ func ensureDefaultNetwork() error {
// Ensure libvirtd is running
if err := exec.Command("systemctl", "start", "libvirtd").Run(); err != nil {
// Non-systemd systems may use a different init, try virsh connect
if exec.Command("virsh", "connect").Run() != nil {
if virshCLocaleCommand("connect").Run() != nil {
return fmt.Errorf("libvirtd is not running and could not be started")
}
}
// Ensure default network is defined
if exec.Command("virsh", "net-info", "default").Run() != nil {
if virshCLocaleCommand("net-info", "default").Run() != nil {
// Default network may not be defined; try to define it
netXML := `<network>
<name>default</name>
@@ -1746,7 +1746,7 @@ func ensureDefaultNetwork() error {
return fmt.Errorf("failed to write default network XML: %v", err)
}
defer os.Remove(tmpFile)
if out, err := exec.Command("virsh", "net-define", tmpFile).CombinedOutput(); err != nil {
if out, err := virshCLocaleCommand("net-define", tmpFile).CombinedOutput(); err != nil {
return fmt.Errorf("failed to define libvirt default network: %v, output: %s", err, string(out))
}
if err := os.MkdirAll(filepath.Dir(libvirtDefaultNetworkMarker), 0755); err == nil {
@@ -1754,19 +1754,27 @@ func ensureDefaultNetwork() error {
}
}
// Start and autostart the default network
if out, err := exec.Command("virsh", "net-info", "default").Output(); err == nil {
if out, err := virshCLocaleCommand("net-info", "default").Output(); err == nil {
if !libvirtNetworkActive(string(out)) {
if startOut, startErr := exec.Command("virsh", "net-start", "default").CombinedOutput(); startErr != nil {
return fmt.Errorf("failed to start libvirt default network: %v, output: %s", startErr, string(startOut))
if startOut, startErr := virshCLocaleCommand("net-start", "default").CombinedOutput(); startErr != nil {
if verifyOut, verifyErr := virshCLocaleCommand("net-info", "default").Output(); verifyErr != nil || !libvirtNetworkActive(string(verifyOut)) {
return fmt.Errorf("failed to start libvirt default network: %v, output: %s", startErr, string(startOut))
}
}
}
}
if out, err := exec.Command("virsh", "net-autostart", "default").CombinedOutput(); err != nil {
if out, err := virshCLocaleCommand("net-autostart", "default").CombinedOutput(); err != nil {
return fmt.Errorf("failed to set autostart for libvirt default network: %v, output: %s", err, string(out))
}
return nil
}
func virshCLocaleCommand(args ...string) *exec.Cmd {
cmd := exec.Command("virsh", args...)
cmd.Env = append(os.Environ(), "LC_ALL=C", "LC_MESSAGES=C", "LANG=C", "LANGUAGE=C")
return cmd
}
func libvirtNetworkActive(info string) bool {
for _, line := range strings.Split(info, "\n") {
key, value, ok := strings.Cut(line, ":")
+21
View File
@@ -24,6 +24,27 @@ func TestImagePathUsesAllowlistedImageID(t *testing.T) {
}
}
func TestLibvirtNetworkActiveParsesCLocaleOutput(t *testing.T) {
tests := []struct {
name string
info string
want bool
}{
{name: "active", info: "Name: default\nActive: yes\n", want: true},
{name: "spacing and case", info: " Active : YES \r\n", want: true},
{name: "inactive", info: "Name: default\nActive: no\n", want: false},
{name: "missing field", info: "Name: default\nAutostart: yes\n", want: false},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
if got := libvirtNetworkActive(tc.info); got != tc.want {
t.Fatalf("libvirtNetworkActive(%q) = %v, want %v", tc.info, got, tc.want)
}
})
}
}
func TestChpasswdStdinPreservesShellMetacharacters(t *testing.T) {
password := `pa'";$(touch /tmp/pwned); echo #\\word`
got, err := chpasswdStdin("root", password)