-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgvproxy.go
More file actions
100 lines (82 loc) · 2.99 KB
/
gvproxy.go
File metadata and controls
100 lines (82 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// SPDX-FileCopyrightText: 2024-2025 OOMOL, Inc. <https://www.oomol.com>
// SPDX-License-Identifier: MPL-2.0
package gvproxy
import (
"context"
"fmt"
"os"
"os/exec"
"syscall"
"time"
"bauklotze/pkg/machine/define"
"bauklotze/pkg/machine/events"
"bauklotze/pkg/machine/fs"
"bauklotze/pkg/machine/vmconfig"
"bauklotze/pkg/registry"
"bauklotze/pkg/system"
gvproxyTypes "github.com/containers/gvisor-tap-vsock/pkg/types"
"github.com/containers/storage/pkg/fileutils"
"github.com/sirupsen/logrus"
)
func Start(ctx context.Context, mc *vmconfig.MachineConfig) error {
if err := system.KillExpectProcNameFromPPIDFile(mc.PIDFiles.GvproxyPidFile, define.GvProxyBinaryName); err != nil {
logrus.Warnf("kill old gvproxy from pid process failed: %v", err)
}
gvpBin, err := mc.GetGVProxyBin()
if err != nil {
return fmt.Errorf("unable to get gvproxy binary path: %w", err)
}
gvpCmd := gvproxyTypes.NewGvproxyCommand()
if err := mc.GetSSHPort(); err != nil {
return fmt.Errorf("unable to get available ssh port: %w", err)
}
// gvproxy listen a local socks file as Podman API socks (PodmanSocks.InHost)
// and forward to the guest's Podman API socks(PodmanSocks.InGuest).
gvpCmd.AddForwardSock(mc.PodmanSocks.InHost)
gvpCmd.AddForwardDest(mc.PodmanSocks.InGuest)
gvpCmd.AddForwardUser(mc.SSH.RemoteUsername)
gvpCmd.AddForwardIdentity(mc.SSH.PrivateKeyPath)
gvpCmd.PidFile = mc.PIDFiles.GvproxyPidFile
// gvproxy endpoint, which provide network backend for vfkit/krunkit
gvpEndPoint := fs.NewFile(mc.GetNetworkStackEndpoint())
if err := gvpEndPoint.DeleteInDir(vmconfig.Workspace); err != nil {
return fmt.Errorf("unable to remove gvproxy endpoint file: %w", err)
}
gvpCmd.AddVfkitSocket(fmt.Sprintf("unixgram://%s", gvpEndPoint.GetPath()))
if os.Getenv("OVM_GVPROXY_DEBUG") == "true" {
logrus.Infof("gvproxy running in debug mode")
gvpCmd.Debug = true
}
cmd := exec.CommandContext(ctx, gvpBin, gvpCmd.ToCmdline()...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
logrus.Infof("gvproxy full cmdline: %q", cmd.Args)
events.NotifyRun(events.StartGvProxy)
if err := cmd.Start(); err != nil {
return fmt.Errorf("unable to execute: %q: %w", cmd.Args, err)
}
defer registry.RegistryCmd(cmd)
return waitForSocket(ctx, gvpEndPoint.GetPath())
}
// we wait for the socket to be created, when gvproxy first run on macOS
// the Gatekeeper/Notarization will slow done the gvproxy code executed
func waitForSocket(ctx context.Context, socketPath string) error {
var backoff = 100 * time.Millisecond
for range 100 {
select {
case <-ctx.Done():
return fmt.Errorf("cancel waitForSocket,ctx cancelled: %w", context.Cause(ctx))
default:
if err := fileutils.Exists(socketPath); err != nil {
logrus.Warnf("Gvproxy network backend socket not ready, try test %q again....", socketPath)
time.Sleep(backoff)
continue
}
return nil
}
}
return fmt.Errorf("gvproxy network backend socket file not created in %q", socketPath)
}