-
Notifications
You must be signed in to change notification settings - Fork 16
infra: netlaunch: Add new grpc modes #530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
8b6a78a
881463b
2172bc9
b86b2fa
96611e9
f074fab
97fa5b9
4dde430
e174372
139a831
f1a1fae
3c3870b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,11 +36,14 @@ var ( | |
| tridentBinaryPath string | ||
| osmodifierBinaryPath string | ||
| streamImage bool | ||
| localProxyPath string | ||
| ) | ||
|
|
||
| const ( | ||
| rcpModeLegacy = "cli" | ||
| rcpModeGrpc = "grpc" | ||
| rcpModeLegacy = "cli" | ||
| rcpModeGrpcLocalProxy = "grpc-local-proxy" | ||
| rcpModeGrpcInstall = "grpc-install" | ||
| rcpModeGrpcStream = "grpc-stream" | ||
| ) | ||
|
|
||
| var backgroundLogstreamFull string | ||
|
|
@@ -74,8 +77,8 @@ var rootCmd = &cobra.Command{ | |
|
|
||
| if rcpMode != "" { | ||
| log.Infof("Using RCP mode: %s", rcpMode) | ||
| if rcpMode != rcpModeGrpc && rcpMode != rcpModeLegacy { | ||
| log.Fatalf("Invalid RCP mode, must be: %s or %s, got: %s", rcpModeLegacy, rcpModeGrpc, rcpMode) | ||
| if rcpMode != rcpModeGrpcLocalProxy && rcpMode != rcpModeGrpcInstall && rcpMode != rcpModeGrpcStream && rcpMode != rcpModeLegacy { | ||
| log.Fatalf("Invalid RCP mode, must be: %s, %s, %s or %s, got: %s", rcpModeLegacy, rcpModeGrpcLocalProxy, rcpModeGrpcInstall, rcpModeGrpcStream, rcpMode) | ||
| } | ||
| } else { | ||
| if tridentBinaryPath != "" { | ||
|
|
@@ -118,8 +121,20 @@ var rootCmd = &cobra.Command{ | |
| config.MaxPhonehomeFailures = maxFailures | ||
|
|
||
| if rcpMode != "" { | ||
| config.Rcp = &netlaunch.RcpConfiguration{ | ||
| GrpcMode: rcpMode == rcpModeGrpc, | ||
| config.Rcp = &netlaunch.RcpConfiguration{} | ||
|
|
||
| // Map the CLI RCP mode to the config GRPC mode. | ||
| switch rcpMode { | ||
| case rcpModeGrpcLocalProxy: | ||
| config.Rcp.GrpcMode = netlaunch.GrpcModeLocalProxy | ||
| config.Rcp.LocalProxySocket = localProxyPath | ||
| log.Infof("Using local proxy socket path: %s", localProxyPath) | ||
| case rcpModeGrpcInstall: | ||
| config.Rcp.GrpcMode = netlaunch.GrpcModeInstall | ||
| case rcpModeGrpcStream: | ||
| config.Rcp.GrpcMode = netlaunch.GrpcModeStream | ||
| case rcpModeLegacy: | ||
| config.Rcp.GrpcMode = netlaunch.GrpcModeDisabled | ||
| } | ||
|
|
||
| if tridentBinaryPath != "" { | ||
|
|
@@ -170,6 +185,7 @@ func init() { | |
| rootCmd.PersistentFlags().StringVarP(&tridentBinaryPath, "trident-binary", "", "", "Optional path to Trident binary to be copied into the VM, requires RCP mode.") | ||
|
Comment on lines
184
to
185
|
||
| rootCmd.PersistentFlags().StringVarP(&osmodifierBinaryPath, "osmodifier-binary", "", "", "Optional path to Osmodifier binary to be copied into the VM, requires RCP mode.") | ||
| rootCmd.PersistentFlags().BoolVarP(&streamImage, "stream-image", "", false, "Use stream image for installation instead of the default method, requires RCP mode.") | ||
| rootCmd.PersistentFlags().StringVarP(&localProxyPath, "local-proxy-socket", "", "/tmp/rcp_local_proxy.sock", "Path to the local proxy socket to use when RCP mode is grpc-local-proxy") | ||
| rootCmd.Flags().StringVarP(&iso, "iso", "i", "", "ISO for Netlaunch testing") | ||
| rootCmd.MarkFlagRequired("iso-template") | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,127 @@ | ||||||||||||||||||
| package netlaunch | ||||||||||||||||||
|
|
||||||||||||||||||
| import ( | ||||||||||||||||||
| "context" | ||||||||||||||||||
| "errors" | ||||||||||||||||||
| "fmt" | ||||||||||||||||||
| "io" | ||||||||||||||||||
| "net" | ||||||||||||||||||
| "os" | ||||||||||||||||||
| "syscall" | ||||||||||||||||||
| "time" | ||||||||||||||||||
| rcpclient "tridenttools/pkg/rcp/client" | ||||||||||||||||||
|
|
||||||||||||||||||
| "github.com/sirupsen/logrus" | ||||||||||||||||||
|
frhuelsz marked this conversation as resolved.
Outdated
|
||||||||||||||||||
| log "github.com/sirupsen/logrus" | ||||||||||||||||||
| ) | ||||||||||||||||||
|
|
||||||||||||||||||
| // openLocalProxy sets up a local proxy that listens on the specified socket | ||||||||||||||||||
| // path and forwards connections to the netlaunch server. Only one connection | ||||||||||||||||||
| // will be accepted and forwarded at a time. When a connection closes, the proxy | ||||||||||||||||||
| // will accept a new connection. | ||||||||||||||||||
| func openLocalProxy(ctx context.Context, socketPath string, rcpListener *rcpclient.RcpListener) error { | ||||||||||||||||||
| for { | ||||||||||||||||||
| log.Info("Waiting for RCP connection...") | ||||||||||||||||||
| select { | ||||||||||||||||||
| case <-ctx.Done(): | ||||||||||||||||||
| return ctx.Err() | ||||||||||||||||||
| case conn := <-rcpListener.ConnChan: | ||||||||||||||||||
| log.Infof("Accepted RCP connection from %s", conn.RemoteAddr()) | ||||||||||||||||||
| err := runLocalProxy(ctx, socketPath, conn) | ||||||||||||||||||
| if err != nil { | ||||||||||||||||||
| log.Errorf("Error running local proxy: %v", err) | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| func runLocalProxy(ctx context.Context, socketPath string, remoteConn net.Conn) error { | ||||||||||||||||||
| defer remoteConn.Close() | ||||||||||||||||||
| // Remove any existing socket file to avoid "address already in use" errors. | ||||||||||||||||||
| if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) { | ||||||||||||||||||
| return fmt.Errorf("failed to remove existing socket %s: %w", socketPath, err) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| listener, err := net.Listen("unix", socketPath) | ||||||||||||||||||
| if err != nil { | ||||||||||||||||||
| return fmt.Errorf("failed to listen on unix socket %s: %w", socketPath, err) | ||||||||||||||||||
| } | ||||||||||||||||||
|
||||||||||||||||||
| } | |
| } | |
| // Restrict permissions on the Unix socket so that only the owner can access it. | |
| if err := os.Chmod(socketPath, 0o600); err != nil { | |
| listener.Close() | |
| _ = os.Remove(socketPath) | |
| return fmt.Errorf("failed to set permissions on unix socket %s: %w", socketPath, err) | |
| } |
Copilot
AI
Mar 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment on forwardConnections says it "blocks until both directions are finished", but the implementation returns after the first copy completes (it waits for a single message from doneChan). Please update the comment to match the actual behavior (or wait for both directions if that was the intent).
| // It blocks until both directions are finished (i.e. one side closes or errors). | |
| // It blocks until one direction is finished (i.e. one side closes or errors) or the context is cancelled. |
Copilot
AI
Mar 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forwardConnections' docstring says it blocks until both directions are finished, but the implementation waits for only one doneChan message (or context cancel) and then returns. Either update the comment to match the behavior, or wait for both copy goroutines to finish (e.g., read twice from doneChan) to match the stated contract.
Uh oh!
There was an error while loading. Please reload this page.