Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ IS_UBUNTU_24_OR_NEWER := $(shell \

RUN_NETLAUNCH_TRIDENT_BIN ?= $(if $(filter yes,$(IS_UBUNTU_24_OR_NEWER)),bin/trident-azl3,bin/trident)

.PHONY: run-netlaunch run-netlaunch-stream
.PHONY: run-netlaunch run-netlaunch-stream run-netlaunch-proxy
run-netlaunch: $(NETLAUNCH_CONFIG) $(TRIDENT_CONFIG) $(NETLAUNCH_ISO) bin/netlaunch validate artifacts/osmodifier $(RUN_NETLAUNCH_TRIDENT_BIN)
@echo "Using trident binary: $(RUN_NETLAUNCH_TRIDENT_BIN)"
@mkdir -p artifacts/test-image
Expand All @@ -579,20 +579,34 @@ run-netlaunch-stream: $(NETLAUNCH_CONFIG) $(TRIDENT_CONFIG) $(NETLAUNCH_ISO) bin
@cp $(RUN_NETLAUNCH_TRIDENT_BIN) artifacts/test-image/trident
@cp artifacts/osmodifier artifacts/test-image/
@bin/netlaunch \
--stream-image \
--trident-binary $(RUN_NETLAUNCH_TRIDENT_BIN) \
--osmodifier-binary artifacts/osmodifier \
--rcp-agent-mode cli \
--rcp-agent-mode grpc-stream \
--iso $(NETLAUNCH_ISO) \
$(if $(NETLAUNCH_PORT),--port $(NETLAUNCH_PORT)) \
--config $(NETLAUNCH_CONFIG) \
--trident $(TRIDENT_CONFIG) \
--logstream \
--remoteaddress remote-addr \
--servefolder artifacts/test-image \
--trace-file trident-metrics.jsonl \
$(if $(LOG_TRACE),--log-trace)

run-netlaunch-proxy: $(NETLAUNCH_CONFIG) $(NETLAUNCH_ISO) bin/netlaunch artifacts/osmodifier $(RUN_NETLAUNCH_TRIDENT_BIN)
@echo "Using trident binary: $(RUN_NETLAUNCH_TRIDENT_BIN)"
@mkdir -p artifacts/test-image
@cp $(RUN_NETLAUNCH_TRIDENT_BIN) artifacts/test-image/trident
@cp artifacts/osmodifier artifacts/test-image/
@bin/netlaunch \
--trident-binary $(RUN_NETLAUNCH_TRIDENT_BIN) \
--osmodifier-binary artifacts/osmodifier \
--rcp-agent-mode grpc-local-proxy \
--iso $(NETLAUNCH_ISO) \
$(if $(NETLAUNCH_PORT),--port $(NETLAUNCH_PORT)) \
--config $(NETLAUNCH_CONFIG) \
--servefolder artifacts/test-image \
--trace-file trident-metrics.jsonl \
$(if $(LOG_TRACE),--log-trace)

# To run this, VM requires at least 11 GiB of memory (virt-deploy create --mem 11).
.PHONY: run-netlaunch-container-images
run-netlaunch-container-images: \
Expand Down
28 changes: 22 additions & 6 deletions tools/cmd/netlaunch/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 != "" {
Expand Down Expand Up @@ -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 != "" {
Expand Down Expand Up @@ -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
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --rcp-agent-mode flag help text still says "(grpc|cli)", but the CLI now accepts multiple gRPC modes (grpc-local-proxy / grpc-install / grpc-stream). Update the help string to list the supported values so users discover the new modes via --help.

Copilot uses AI. Check for mistakes.
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")
}
Expand Down
31 changes: 30 additions & 1 deletion tools/cmd/rcp-agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ func main() {
}
}

// Apply service configuration
if err := applyServicesConfiguration(config.Services); err != nil {
logrus.Fatalf("Failed to apply services configuration: %v", err)
}

if config.ClientAddress == "" {
logrus.Warn("No client address specified, running legacy Trident install service.")

Expand All @@ -77,7 +82,14 @@ func main() {
}

logrus.Infof("Starting reverse-connect proxy with client address: '%s' and server address: '%s'", config.ClientAddress, config.ServerAddress)
if err := proxy.StartReverseConnectProxy(ctx, &config.RcpClientTls, config.ClientAddress, config.ServerAddress, time.Second); err != nil {
if err := proxy.StartReverseConnectProxy(
ctx,
&config.RcpClientTls,
config.ClientAddress,
config.ServerAddress,
config.ServerConnectionType,
time.Second,
); err != nil {
Comment thread
frhuelsz marked this conversation as resolved.
logrus.Fatalf("reverse-connect proxy error: %v", err)
}
logrus.Info("Shutdown complete")
Expand Down Expand Up @@ -128,3 +140,20 @@ func enableAndStartTridentInstallService() error {

return nil
}

func applyServicesConfiguration(config agent.ServicesConfiguration) error {
for _, service := range config.Start {
logrus.Infof("Enabling and starting service '%s'", service)
err := cmd.Run("systemctl", "enable", service)
if err != nil {
return fmt.Errorf("failed to enable service '%s': %w", service, err)
}

err = cmd.Run("systemctl", "start", "--no-block", service)
if err != nil {
return fmt.Errorf("failed to start service '%s': %w", service, err)
}
}

return nil
}
83 changes: 71 additions & 12 deletions tools/pkg/netlaunch/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package netlaunch

import "tridenttools/pkg/bmc"
import (
"os"
"tridenttools/pkg/bmc"
)

type NetCommonConfig struct {
// Port to serve the HTTP server on.
Expand Down Expand Up @@ -66,13 +69,9 @@ type NetLaunchConfig struct {

// Configuration for netlaunch reverse-connect proxy.
type RcpConfiguration struct {
// Run netlaunch in gRPC mode. When true, netlaunch will use the
// reverse-connect proxy to communicate with Trident using gRPC. When false,
// netlaunch will use the reverse-connect proxy to download the Host
// Configuration file and start the legacy installation service.
//
// If omitted, defaults to false.
GrpcMode bool `yaml:"grpcMode,omitempty"`
// gRPC mode to use in netlaunch. If not specified, gRPC mode will be
// disabled and netlaunch will use the legacy CLI installation method.
GrpcMode GrpcMode `yaml:"grpcMode,omitempty"`

// Port number to listen on for incoming connections from the
// reverse-connect proxy.
Expand All @@ -84,15 +83,75 @@ type RcpConfiguration struct {
// If not specified, no Trident binary will be copied.
LocalTridentPath *string `yaml:"localTridentPath,omitempty"`

// An optional path to a local osmodifier binary to copy into the remote host.
// If not specified, no Osmodifier binary will be copied.
// An optional path to a local osmodifier binary to copy into the remote
// host. If not specified, no Osmodifier binary will be copied.
LocalOsmodifierPath *string `yaml:"localOsmodifierPath,omitempty"`

// Replace the execution for trident-install to use stream image instead of
// the default installation method.
UseStreamImage bool `yaml:"useStreamImage,omitempty"`

// The local Unix socket netlaunch will listen on when gRPC mode is
// `local-proxy`.
LocalProxySocket string `yaml:"localProxySocket,omitempty"`

AdditionalFiles []RcpAdditionalFile `yaml:"-"`

// The address of the server the RCP agent should connect to. This is only
// used in gRPC modes.
//
// If not specified, the RCP agent will connect to Trident's default unix
// socket address.
RcpAgentServerAddress string `yaml:"rcpAgentServerAddress,omitempty"`

// The connection type to use when the RCP agent connects to the server.
// This is only used in gRPC modes.
//
// If not specified, the RCP agent will use "unix" as the default connection
// type, connecting to Trident's default unix socket address.
RcpAgentServerConnectionType string `yaml:"rcpAgentServerConnectionType,omitempty"`

// Systemd services to start via the RCP agent after file downloads.
StartServices []string `yaml:"-"`
}

type RcpAdditionalFile struct {
Name string
Destination string
Mode os.FileMode
Data []byte
}

func (c *RcpConfiguration) GetGrpcMode() GrpcMode {
if c.GrpcMode == "" {
return GrpcModeDisabled
}

return c.GrpcMode
}

func (c *RcpConfiguration) IsGrpcModeEnabled() bool {
return c.GetGrpcMode() != GrpcModeDisabled
}

type GrpcMode string

const (
// GrpcModeDisabled: gRPC mode is disabled and netlaunch will use the legacy
// CLI installation method.
GrpcModeDisabled GrpcMode = "disabled"
// GrpcModeLocalProxy: gRPC mode is enabled and netlaunch will open a local
// listener and forward connections to Trident via the reverse-connect
// proxy.
GrpcModeLocalProxy GrpcMode = "local-proxy"
// GrpcModeDirect: gRPC mode is enabled and netlaunch will directly connect
Comment thread
frhuelsz marked this conversation as resolved.
Outdated
// to Trident via the reverse-connect proxy to perform an install.
GrpcModeInstall GrpcMode = "install"
// GrpcModeStream: gRPC mode is enabled and netlaunch will directly connect
// to Trident via the reverse-connect proxy to stream a disk image.
GrpcModeStream GrpcMode = "stream"
)

type HostConnectionConfiguration struct {
// Configuration for physical/emulated BMCs.

Expand Down Expand Up @@ -142,6 +201,6 @@ type NetListenConfig struct {
}
}

func (c *NetLaunchConfig) IsGrpcMode() bool {
return c.Rcp != nil && c.Rcp.GrpcMode
func (c *NetLaunchConfig) IsGrpcModeEnabled() bool {
return c.Rcp != nil && c.Rcp.IsGrpcModeEnabled()
}
Loading