mirror of
https://github.com/containers/podman.git
synced 2025-06-22 01:48:54 +08:00
Merge pull request #15404 from arixmkii/win_compat2
Improved Windows compatibility for machine command
This commit is contained in:
20
pkg/machine/machine_windows.go
Normal file
20
pkg/machine/machine_windows.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetProcessState(pid int) (active bool, exitCode int) {
|
||||||
|
const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE
|
||||||
|
handle, err := syscall.OpenProcess(da, false, uint32(pid))
|
||||||
|
if err != nil {
|
||||||
|
return false, int(syscall.ERROR_PROC_NOT_FOUND)
|
||||||
|
}
|
||||||
|
|
||||||
|
var code uint32
|
||||||
|
syscall.GetExitCodeProcess(handle, &code)
|
||||||
|
return code == 259, int(code)
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
//go:build (amd64 && !windows) || (arm64 && !windows)
|
//go:build amd64 || arm64
|
||||||
// +build amd64,!windows arm64,!windows
|
// +build amd64 arm64
|
||||||
|
|
||||||
package qemu
|
package qemu
|
||||||
|
|
||||||
@ -33,7 +33,6 @@ import (
|
|||||||
"github.com/digitalocean/go-qemu/qmp"
|
"github.com/digitalocean/go-qemu/qmp"
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -125,7 +124,7 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vm.QMPMonitor = monitor
|
vm.QMPMonitor = monitor
|
||||||
cmd = append(cmd, []string{"-qmp", monitor.Network + ":/" + monitor.Address.GetPath() + ",server=on,wait=off"}...)
|
cmd = append(cmd, []string{"-qmp", monitor.Network + ":" + monitor.Address.GetPath() + ",server=on,wait=off"}...)
|
||||||
|
|
||||||
// Add network
|
// Add network
|
||||||
// Right now the mac address is hardcoded so that the host networking gives it a specific IP address. This is
|
// Right now the mac address is hardcoded so that the host networking gives it a specific IP address. This is
|
||||||
@ -629,14 +628,9 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
// check if qemu is still alive
|
// check if qemu is still alive
|
||||||
var status syscall.WaitStatus
|
err := checkProcessStatus("qemu", cmd.Process.Pid, stderrBuf)
|
||||||
pid, err := syscall.Wait4(cmd.Process.Pid, &status, syscall.WNOHANG, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read qemu process status: %w", err)
|
return err
|
||||||
}
|
|
||||||
if pid > 0 {
|
|
||||||
// child exited
|
|
||||||
return fmt.Errorf("qemu exited unexpectedly with exit code %d, stderr: %s", status.ExitStatus(), stderrBuf.String())
|
|
||||||
}
|
}
|
||||||
time.Sleep(wait)
|
time.Sleep(wait)
|
||||||
wait++
|
wait++
|
||||||
@ -1724,14 +1718,6 @@ func (p *Provider) RemoveAndCleanMachines() error {
|
|||||||
return prevErr
|
return prevErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func isProcessAlive(pid int) bool {
|
|
||||||
err := unix.Kill(pid, syscall.Signal(0))
|
|
||||||
if err == nil || err == unix.EPERM {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) VMType() string {
|
func (p *Provider) VMType() string {
|
||||||
return vmtype
|
return vmtype
|
||||||
}
|
}
|
||||||
|
33
pkg/machine/qemu/machine_unix.go
Normal file
33
pkg/machine/qemu/machine_unix.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd
|
||||||
|
|
||||||
|
package qemu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isProcessAlive(pid int) bool {
|
||||||
|
err := unix.Kill(pid, syscall.Signal(0))
|
||||||
|
if err == nil || err == unix.EPERM {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkProcessStatus(processHint string, pid int, stderrBuf *bytes.Buffer) error {
|
||||||
|
var status syscall.WaitStatus
|
||||||
|
pid, err := syscall.Wait4(pid, &status, syscall.WNOHANG, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read qem%su process status: %w", processHint, err)
|
||||||
|
}
|
||||||
|
if pid > 0 {
|
||||||
|
// child exited
|
||||||
|
return fmt.Errorf("%s exited unexpectedly with exit code %d, stderr: %s", processHint, status.ExitStatus(), stderrBuf.String())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
//go:build (!amd64 && !arm64) || windows
|
//go:build (!amd64 && !arm64)
|
||||||
// +build !amd64,!arm64 windows
|
// +build !amd64,!arm64
|
||||||
|
|
||||||
package qemu
|
package qemu
|
||||||
|
27
pkg/machine/qemu/machine_windows.go
Normal file
27
pkg/machine/qemu/machine_windows.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package qemu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containers/podman/v4/pkg/machine"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isProcessAlive(pid int) bool {
|
||||||
|
if checkProcessStatus("process", pid, nil) == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkProcessStatus(processHint string, pid int, stderrBuf *bytes.Buffer) error {
|
||||||
|
active, exitCode := machine.GetProcessState(pid)
|
||||||
|
if !active {
|
||||||
|
if stderrBuf != nil {
|
||||||
|
return fmt.Errorf("%s exited unexpectedly, exit code: %d stderr: %s", processHint, exitCode, stderrBuf.String())
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("%s exited unexpectedly, exit code: %d", processHint, exitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
13
pkg/machine/qemu/options_windows.go
Normal file
13
pkg/machine/qemu/options_windows.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package qemu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getRuntimeDir() (string, error) {
|
||||||
|
tmpDir, ok := os.LookupEnv("TEMP")
|
||||||
|
if !ok {
|
||||||
|
tmpDir = os.Getenv("LOCALAPPDATA") + "\\Temp"
|
||||||
|
}
|
||||||
|
return tmpDir, nil
|
||||||
|
}
|
@ -1063,7 +1063,7 @@ func launchWinProxy(v *MachineVM) (bool, string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return globalName, pipePrefix + waitPipe, waitPipeExists(waitPipe, 30, func() error {
|
return globalName, pipePrefix + waitPipe, waitPipeExists(waitPipe, 30, func() error {
|
||||||
active, exitCode := getProcessState(cmd.Process.Pid)
|
active, exitCode := machine.GetProcessState(cmd.Process.Pid)
|
||||||
if !active {
|
if !active {
|
||||||
return fmt.Errorf("win-sshproxy.exe failed to start, exit code: %d (see windows event logs)", exitCode)
|
return fmt.Errorf("win-sshproxy.exe failed to start, exit code: %d (see windows event logs)", exitCode)
|
||||||
}
|
}
|
||||||
|
@ -280,18 +280,6 @@ func obtainShutdownPrivilege() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProcessState(pid int) (active bool, exitCode int) {
|
|
||||||
const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE
|
|
||||||
handle, err := syscall.OpenProcess(da, false, uint32(pid))
|
|
||||||
if err != nil {
|
|
||||||
return false, int(syscall.ERROR_PROC_NOT_FOUND)
|
|
||||||
}
|
|
||||||
|
|
||||||
var code uint32
|
|
||||||
syscall.GetExitCodeProcess(handle, &code)
|
|
||||||
return code == 259, int(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func addRunOnceRegistryEntry(command string) error {
|
func addRunOnceRegistryEntry(command string) error {
|
||||||
k, _, err := registry.CreateKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\RunOnce`, registry.WRITE)
|
k, _, err := registry.CreateKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\RunOnce`, registry.WRITE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user