рабочий вариант, но скороть 10 МБит
build / backend (push) Has been cancelled
build / node-agent (push) Has been cancelled
build / worker (push) Has been cancelled

This commit is contained in:
2026-05-22 21:46:49 +03:00
parent 469fa0e860
commit 20d361a886
280 changed files with 954890 additions and 18524 deletions
@@ -1621,7 +1621,7 @@ func verdict(report loadtestReport) (string, []string) {
reasons = append(reasons, targetAckVerdictReasons(report)...)
reasons = append(reasons, routePressureDistributionVerdictReasons(report)...)
reasons = append(reasons, targetEndpointPolicyVerdictReasons(report)...)
reasons = append(reasons, legacyRouteModeVerdictReasons(report)...)
reasons = append(reasons, disallowedRouteModeVerdictReasons(report)...)
reasons = append(reasons, routeModeCoverageVerdictReasons(report)...)
if len(reasons) > 0 {
return "fail", reasons
@@ -1846,25 +1846,22 @@ func targetEndpointPolicyVerdictReasons(report loadtestReport) []string {
return []string{fmt.Sprintf("non_quic_targets=%s", strings.Join(invalid, ","))}
}
func legacyRouteModeVerdictReasons(report loadtestReport) []string {
func disallowedRouteModeVerdictReasons(report loadtestReport) []string {
if len(report.TargetStats) == 0 {
return nil
}
legacyModes := map[string]struct{}{
"relay": {},
"outbound_reverse": {},
"websocket": {},
"ws": {},
"wss": {},
"direct_http": {},
"direct_https": {},
"direct_tcp_tls": {},
supportedModes := map[string]struct{}{
string(mesh.FabricRouteDirect): {},
string(mesh.FabricRouteLAN): {},
string(mesh.FabricRouteICE): {},
string(mesh.FabricRouteReverse): {},
string(mesh.FabricRouteRelay): {},
}
found := map[string]int{}
for _, stats := range report.TargetStats {
for mode, count := range stats.RouteModes {
mode = strings.ToLower(strings.TrimSpace(mode))
if _, legacy := legacyModes[mode]; legacy && count > 0 {
if _, supported := supportedModes[mode]; !supported && count > 0 {
found[mode] += count
}
}
@@ -1877,7 +1874,7 @@ func legacyRouteModeVerdictReasons(report loadtestReport) []string {
modes = append(modes, fmt.Sprintf("%s:%d", mode, count))
}
sort.Strings(modes)
return []string{fmt.Sprintf("legacy_route_modes_observed=%s", strings.Join(modes, ","))}
return []string{fmt.Sprintf("compat_route_modes_observed=%s", strings.Join(modes, ","))}
}
func routeModeCoverageVerdictReasons(report loadtestReport) []string {
@@ -38,7 +38,7 @@ func TestRouteModeCoverageVerdictRequiresMixedModes(t *testing.T) {
}
}
func TestLegacyRouteModeVerdictRejectsNonQUICModes(t *testing.T) {
func TestDisallowedRouteModeVerdictRejectsNonQUICModes(t *testing.T) {
report := loadtestReport{
TargetStats: map[string]targetStats{
"a": {RouteModes: map[string]int{
@@ -49,12 +49,12 @@ func TestLegacyRouteModeVerdictRejectsNonQUICModes(t *testing.T) {
}},
},
}
reasons := legacyRouteModeVerdictReasons(report)
reasons := disallowedRouteModeVerdictReasons(report)
if len(reasons) != 1 ||
!strings.Contains(reasons[0], "relay:1") ||
!strings.Contains(reasons[0], "outbound_reverse:2") ||
!strings.Contains(reasons[0], "wss:3") {
t.Fatalf("reasons = %v, want legacy route mode failure", reasons)
t.Fatalf("reasons = %v, want compat route mode failure", reasons)
}
report.TargetStats["a"] = targetStats{RouteModes: map[string]int{
@@ -64,7 +64,7 @@ func TestLegacyRouteModeVerdictRejectsNonQUICModes(t *testing.T) {
string(mesh.FabricRouteReverse): 1,
string(mesh.FabricRouteRelay): 1,
}}
if reasons := legacyRouteModeVerdictReasons(report); len(reasons) != 0 {
if reasons := disallowedRouteModeVerdictReasons(report); len(reasons) != 0 {
t.Fatalf("reasons = %v, want QUIC modes accepted", reasons)
}
}
@@ -10,8 +10,6 @@ import (
"encoding/json"
"fmt"
"math/big"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"time"
@@ -22,22 +20,21 @@ import (
)
type smokeNode struct {
Local mesh.PeerIdentity
Runtime *mesh.SyntheticRuntime
URL string
server *httptest.Server
Local mesh.PeerIdentity
Runtime *mesh.SyntheticRuntime
Endpoint string
}
type smokeSyntheticTransport struct {
peers map[string]string
peers map[string]*mesh.SyntheticRuntime
}
func (t smokeSyntheticTransport) SendSynthetic(ctx context.Context, nextNodeID string, envelope mesh.SyntheticEnvelope) (mesh.SyntheticEnvelope, error) {
baseURL := t.peers[nextNodeID]
if baseURL == "" {
runtime := t.peers[nextNodeID]
if runtime == nil {
return mesh.SyntheticEnvelope{}, mesh.ErrSyntheticPeerUnavailable
}
return mesh.NewClient(baseURL).SendSynthetic(ctx, envelope)
return runtime.Receive(ctx, envelope)
}
type smokeReport struct {
@@ -104,8 +101,8 @@ func run(ctx context.Context) (smokeReport, error) {
relayRoute := smokeRoute("route-relay", []string{"node-a", "node-r", "node-b"})
routes := []mesh.SyntheticRoute{directRoute, relayRoute}
nodeAConfigPath, err := writeSmokeScopedConfig(nodeA.Local, map[string]string{
"node-r": nodeR.URL,
"node-b": nodeB.URL,
"node-r": nodeR.Endpoint,
"node-b": nodeB.Endpoint,
}, routes)
if err != nil {
return smokeReport{}, err
@@ -117,10 +114,19 @@ func run(ctx context.Context) (smokeReport, error) {
nodeA.Runtime = smokeRuntime(nodeA.Local, nodeAConfig.Routes, nodeAConfig.PeerEndpoints)
nodeR.Runtime = smokeRuntime(nodeR.Local, routes, map[string]string{
"node-b": nodeB.URL,
"node-b": nodeB.Endpoint,
})
nodeB.Runtime = smokeRuntime(nodeB.Local, routes, map[string]string{})
nodeA.Runtime = smokeRuntimeWithPeers(nodeA.Local, nodeAConfig.Routes, map[string]*mesh.SyntheticRuntime{
"node-r": nodeR.Runtime,
"node-b": nodeB.Runtime,
})
nodeR.Runtime = smokeRuntimeWithPeers(nodeR.Local, routes, map[string]*mesh.SyntheticRuntime{
"node-b": nodeB.Runtime,
})
nodeB.Runtime = smokeRuntimeWithPeers(nodeB.Local, routes, map[string]*mesh.SyntheticRuntime{})
directAck, err := nodeA.Runtime.SendProbe(ctx, directRoute.RouteID, mesh.SyntheticChannelFabricControl, "smoke-direct")
if err != nil {
return smokeReport{}, fmt.Errorf("direct probe: %w", err)
@@ -209,9 +215,9 @@ func run(ctx context.Context) (smokeReport, error) {
FabricSessionLatencyMS: fabricSessionLatency.Milliseconds(),
FabricSessionEndpoint: "quic://" + fabricQUICEndpoint,
PeerEndpoints: map[string]any{
"node-a": nodeA.URL,
"node-r": nodeR.URL,
"node-b": nodeB.URL,
"node-a": nodeA.Endpoint,
"node-r": nodeR.Endpoint,
"node-b": nodeB.Endpoint,
},
}, nil
}
@@ -472,21 +478,21 @@ func writeSmokeScopedConfig(local mesh.PeerIdentity, peers map[string]string, ro
}
func newSmokeNode(local mesh.PeerIdentity) *smokeNode {
node := &smokeNode{Local: local}
node.server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mesh.Server{Local: node.Local, SyntheticRuntime: node.Runtime}.Handler().ServeHTTP(w, r)
}))
node.URL = node.server.URL
return node
}
func (n *smokeNode) Close() {
if n.server != nil {
n.server.Close()
return &smokeNode{
Local: local,
Endpoint: "quic://smoke-" + local.NodeID,
}
}
func (n *smokeNode) Close() {
}
func smokeRuntime(local mesh.PeerIdentity, routes []mesh.SyntheticRoute, peers map[string]string) *mesh.SyntheticRuntime {
_ = peers
return smokeRuntimeWithPeers(local, routes, map[string]*mesh.SyntheticRuntime{})
}
func smokeRuntimeWithPeers(local mesh.PeerIdentity, routes []mesh.SyntheticRoute, peers map[string]*mesh.SyntheticRuntime) *mesh.SyntheticRuntime {
return mesh.NewSyntheticRuntime(mesh.SyntheticRuntimeConfig{
Enabled: true,
Local: local,
@@ -113,14 +113,13 @@ func applyStagedSelfUpdate() {
func runInstallLinux(ctx context.Context, args []string) error {
fs := flag.NewFlagSet("install-linux", flag.ContinueOnError)
cfg := hostagent.LinuxInstallConfig{}
var profileURL string
var installToken string
fs.StringVar(&cfg.RuntimeConfig.BackendURL, "backend-url", getenv("RAP_BACKEND_URL", ""), "Control Plane API base URL.")
var joinBundle string
fs.StringVar(&cfg.RuntimeConfig.ClusterID, "cluster-id", getenv("RAP_CLUSTER_ID", ""), "Cluster ID.")
fs.StringVar(&cfg.RuntimeConfig.ClusterAuthorityPublicKey, "cluster-authority-public-key", getenv("RAP_CLUSTER_AUTHORITY_PUBLIC_KEY", ""), "Pinned Ed25519 cluster authority public key for signed fabric registry records.")
fs.StringVar(&cfg.RuntimeConfig.FabricRegistryRecordsJSON, "fabric-registry-records-json", getenv("RAP_FABRIC_REGISTRY_RECORDS_JSON", ""), "JSON array of signed QUIC-only fabric registry records used as bootstrap seeds.")
fs.StringVar(&cfg.NodeID, "node-id", getenv("RAP_NODE_ID", ""), "Already enrolled node ID used by updater repair mode.")
fs.StringVar(&cfg.RuntimeConfig.JoinToken, "join-token", getenv("RAP_JOIN_TOKEN", ""), "One-time join token for first enrollment.")
fs.StringVar(&profileURL, "profile-url", getenv("RAP_INSTALL_PROFILE_URL", ""), "Control Plane API base URL or /node-agents/linux-install-profile URL for profile-based install.")
fs.StringVar(&installToken, "install-token", getenv("RAP_INSTALL_TOKEN", ""), "One-time install token used to fetch Linux install profile.")
fs.StringVar(&joinBundle, "join-bundle", getenv("RAP_JOIN_BUNDLE", ""), "Preferred local join bundle JSON with Linux install profile and QUIC fabric bootstrap seeds.")
fs.StringVar(&cfg.RuntimeConfig.NodeName, "node-name", getenv("RAP_NODE_NAME", ""), "Node display name.")
fs.StringVar(&cfg.StateDir, "state-dir", getenv("RAP_NODE_STATE_DIR", ""), "Node state directory.")
fs.StringVar(&cfg.InstallDir, "install-dir", getenv("RAP_LINUX_INSTALL_DIR", ""), "Directory for rap-node-agent and rap-host-agent.")
@@ -131,28 +130,31 @@ func runInstallLinux(ctx context.Context, args []string) error {
fs.BoolVar(&cfg.AutoUpdateEnabled, "auto-update-enabled", getenvBool("RAP_AUTO_UPDATE_ENABLED", true), "Install and start the Linux host-agent update service.")
fs.StringVar(&cfg.AutoUpdateCurrentVersion, "auto-update-current-version", getenv("RAP_NODE_AGENT_VERSION", agent.Version), "Initial node-agent version used by update-loop before the first successful update.")
fs.StringVar(&cfg.AutoUpdateChannel, "auto-update-channel", getenv("RAP_UPDATE_CHANNEL", ""), "Optional update channel override for update-loop.")
fs.IntVar(&cfg.AutoUpdateIntervalSeconds, "auto-update-interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", 21600), "Emergency fallback plan poll interval in seconds. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&cfg.AutoUpdateIntervalSeconds, "auto-update-interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", hostagent.DefaultUpdateIntervalSec), "Emergency rescue plan poll interval in seconds. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&cfg.AutoUpdateInitialDelaySeconds, "auto-update-initial-delay-seconds", getenvInt("RAP_UPDATE_INITIAL_DELAY_SECONDS", 15), "Update-loop initial delay in seconds.")
fs.IntVar(&cfg.AutoUpdateHealthTimeoutSeconds, "auto-update-health-timeout-seconds", getenvInt("RAP_UPDATE_HEALTH_TIMEOUT_SECONDS", 30), "Updated service health timeout in seconds.")
fs.StringVar(&cfg.HostAgentSourcePath, "host-agent-source-path", getenv("RAP_HOST_AGENT_SOURCE_PATH", ""), "Source rap-host-agent path copied to the persistent updater location.")
fs.BoolVar(&cfg.RuntimeConfig.WorkloadSupervisionEnabled, "workload-supervision-enabled", getenvBool("RAP_WORKLOAD_SUPERVISION_ENABLED", false), "Enable node-agent workload status reporting.")
fs.BoolVar(&cfg.RuntimeConfig.MeshSyntheticRuntimeEnabled, "mesh-synthetic-runtime-enabled", getenvBool("RAP_MESH_SYNTHETIC_RUNTIME_ENABLED", false), "Enable historical synthetic mesh runtime.")
fs.BoolVar(&cfg.RuntimeConfig.FabricRuntimeEnabled, "fabric-runtime-enabled", getenvBool("RAP_FABRIC_RUNTIME_ENABLED", false), "Enable node-local synthetic fabric control runtime.")
fs.BoolVar(&cfg.RuntimeConfig.MeshProductionForwardingEnabled, "mesh-production-forwarding-enabled", getenvBool("RAP_MESH_PRODUCTION_FORWARDING_ENABLED", false), "Enable production forwarding gate; runtime still fail-closed if unavailable.")
fs.BoolVar(&cfg.RuntimeConfig.VPNFabricSessionTransportEnabled, "vpn-fabric-session-transport-enabled", getenvBool("RAP_VPN_FABRIC_SESSION_TRANSPORT_ENABLED", false), "Route VPN packet transport over persistent fabric sessions.")
fs.BoolVar(&cfg.RuntimeConfig.MeshQUICFabricEnabled, "mesh-quic-fabric-enabled", getenvBool("RAP_MESH_QUIC_FABRIC_ENABLED", false), "Enable QUIC/UDP fabric listener.")
fs.StringVar(&cfg.RuntimeConfig.MeshQUICFabricListenAddr, "mesh-quic-fabric-listen-addr", getenv("RAP_MESH_QUIC_FABRIC_LISTEN_ADDR", ""), "QUIC/UDP fabric listen address.")
fs.IntVar(&cfg.RuntimeConfig.VPNFabricSessionStreamShards, "vpn-fabric-session-stream-shards", getenvInt("RAP_VPN_FABRIC_SESSION_STREAM_SHARDS", 4), "VPN fabric-session stream shards per traffic class.")
fs.IntVar(&cfg.RuntimeConfig.VPNFabricSessionStreamShards, "vpn-fabric-session-stream-shards", getenvInt("RAP_VPN_FABRIC_SESSION_STREAM_SHARDS", 8), "VPN fabric-session stream shards per traffic class.")
fs.IntVar(&cfg.RuntimeConfig.VPNFabricQUICMaxStreamsPerConn, "vpn-fabric-quic-max-streams-per-conn", getenvInt("RAP_VPN_FABRIC_QUIC_MAX_STREAMS_PER_CONN", 64), "Maximum logical fabric-session streams per cached VPN QUIC carrier connection.")
fs.IntVar(&cfg.RuntimeConfig.VPNFabricQUICIdleTTLSeconds, "vpn-fabric-quic-idle-ttl-seconds", getenvInt("RAP_VPN_FABRIC_QUIC_IDLE_TTL_SECONDS", 300), "Idle TTL seconds for cached VPN QUIC carrier connections.")
fs.StringVar(&cfg.RuntimeConfig.MeshListenAddr, "mesh-listen-addr", getenv("RAP_MESH_LISTEN_ADDR", ""), "Historical synthetic mesh HTTP listen address.")
fs.StringVar(&cfg.RuntimeConfig.MeshListenPortMode, "mesh-listen-port-mode", getenv("RAP_MESH_LISTEN_PORT_MODE", "auto"), "Mesh listen port behavior: manual, auto, or disabled.")
fs.IntVar(&cfg.RuntimeConfig.MeshListenAutoPortStart, "mesh-listen-auto-port-start", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_START", 19131), "First port used when mesh listen port mode is auto.")
fs.IntVar(&cfg.RuntimeConfig.MeshListenAutoPortEnd, "mesh-listen-auto-port-end", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_END", 19231), "Last port used when mesh listen port mode is auto.")
fs.StringVar(&cfg.RuntimeConfig.FabricListenAddr, "fabric-listen-addr", getenv("RAP_FABRIC_LISTEN_ADDR", ""), "Optional node listener address for QUIC fabric runtime.")
fs.StringVar(&cfg.RuntimeConfig.FabricListenPortMode, "fabric-listen-port-mode", getenv("RAP_FABRIC_LISTEN_PORT_MODE", "auto"), "Mesh listen port behavior: manual, auto, or disabled.")
fs.IntVar(&cfg.RuntimeConfig.FabricListenAutoPortStart, "fabric-listen-auto-port-start", getenvInt("RAP_FABRIC_LISTEN_AUTO_PORT_START", 19131), "First port used when mesh listen port mode is auto.")
fs.IntVar(&cfg.RuntimeConfig.FabricListenAutoPortEnd, "fabric-listen-auto-port-end", getenvInt("RAP_FABRIC_LISTEN_AUTO_PORT_END", 19231), "Last port used when mesh listen port mode is auto.")
fs.StringVar(&cfg.RuntimeConfig.MeshAdvertiseEndpoint, "mesh-advertise-endpoint", getenv("RAP_MESH_ADVERTISE_ENDPOINT", ""), "Advertised mesh endpoint.")
fs.StringVar(&cfg.RuntimeConfig.MeshAdvertiseEndpointsJSON, "mesh-advertise-endpoints-json", getenv("RAP_MESH_ADVERTISE_ENDPOINTS_JSON", ""), "Advertised endpoint candidates JSON.")
fs.StringVar(&cfg.RuntimeConfig.MeshAdvertiseTransport, "mesh-advertise-transport", getenv("RAP_MESH_ADVERTISE_TRANSPORT", "quic"), "Advertised transport.")
fs.StringVar(&cfg.RuntimeConfig.MeshConnectivityMode, "mesh-connectivity-mode", getenv("RAP_MESH_CONNECTIVITY_MODE", "outbound_only"), "Connectivity mode hint.")
fs.StringVar(&cfg.RuntimeConfig.MeshNATType, "mesh-nat-type", getenv("RAP_MESH_NAT_TYPE", "unknown"), "NAT type hint.")
fs.StringVar(&cfg.RuntimeConfig.MeshSiteID, "mesh-site-id", getenv("RAP_MESH_SITE_ID", ""), "Physical/logical site identifier advertised with QUIC endpoints.")
fs.StringVar(&cfg.RuntimeConfig.MeshLocalityGroupID, "mesh-locality-group-id", getenv("RAP_MESH_LOCALITY_GROUP_ID", ""), "Private locality group identifier used for LAN/private endpoint selection.")
fs.StringVar(&cfg.RuntimeConfig.MeshNATGroupID, "mesh-nat-group-id", getenv("RAP_MESH_NAT_GROUP_ID", ""), "Shared NAT/ingress group identifier advertised with QUIC endpoints.")
fs.StringVar(&cfg.RuntimeConfig.MeshRegion, "mesh-region", getenv("RAP_MESH_REGION", "linux"), "Region/site hint.")
fs.IntVar(&cfg.RuntimeConfig.HeartbeatIntervalSeconds, "heartbeat-interval-seconds", getenvInt("RAP_HEARTBEAT_INTERVAL_SECONDS", 15), "Heartbeat interval seconds.")
fs.IntVar(&cfg.RuntimeConfig.EnrollmentPollIntervalSeconds, "enrollment-poll-interval-seconds", getenvInt("RAP_ENROLLMENT_POLL_INTERVAL_SECONDS", 5), "Enrollment poll interval seconds.")
@@ -160,7 +162,7 @@ func runInstallLinux(ctx context.Context, args []string) error {
if err := fs.Parse(args); err != nil {
return err
}
if strings.TrimSpace(profileURL) != "" || strings.TrimSpace(installToken) != "" {
if strings.TrimSpace(joinBundle) != "" {
dryRun := cfg.DryRun
startupMode := strings.TrimSpace(cfg.StartupMode)
autoUpdateEnabled := cfg.AutoUpdateEnabled
@@ -170,7 +172,7 @@ func runInstallLinux(ctx context.Context, args []string) error {
autoUpdateInitialDelaySeconds := cfg.AutoUpdateInitialDelaySeconds
autoUpdateHealthTimeoutSeconds := cfg.AutoUpdateHealthTimeoutSeconds
hostAgentSourcePath := cfg.HostAgentSourcePath
profile, err := hostagent.FetchLinuxInstallProfile(ctx, hostagent.ProfileRequest{URL: profileURL, ClusterID: cfg.RuntimeConfig.ClusterID, InstallToken: installToken, NodeName: cfg.RuntimeConfig.NodeName})
profile, err := hostagent.LoadLinuxJoinBundle(joinBundle)
if err != nil {
return err
}
@@ -201,14 +203,13 @@ func runInstallLinux(ctx context.Context, args []string) error {
func runInstallWindows(ctx context.Context, args []string) error {
fs := flag.NewFlagSet("install-windows", flag.ContinueOnError)
cfg := hostagent.WindowsInstallConfig{}
var profileURL string
var installToken string
fs.StringVar(&cfg.RuntimeConfig.BackendURL, "backend-url", getenv("RAP_BACKEND_URL", ""), "Control Plane API base URL.")
var joinBundle string
fs.StringVar(&cfg.RuntimeConfig.ClusterID, "cluster-id", getenv("RAP_CLUSTER_ID", ""), "Cluster ID.")
fs.StringVar(&cfg.RuntimeConfig.ClusterAuthorityPublicKey, "cluster-authority-public-key", getenv("RAP_CLUSTER_AUTHORITY_PUBLIC_KEY", ""), "Pinned Ed25519 cluster authority public key for signed fabric registry records.")
fs.StringVar(&cfg.RuntimeConfig.FabricRegistryRecordsJSON, "fabric-registry-records-json", getenv("RAP_FABRIC_REGISTRY_RECORDS_JSON", ""), "JSON array of signed QUIC-only fabric registry records used as bootstrap seeds.")
fs.StringVar(&cfg.NodeID, "node-id", getenv("RAP_NODE_ID", ""), "Already enrolled node ID used by updater repair mode.")
fs.StringVar(&cfg.RuntimeConfig.JoinToken, "join-token", getenv("RAP_JOIN_TOKEN", ""), "One-time join token for first enrollment.")
fs.StringVar(&profileURL, "profile-url", getenv("RAP_INSTALL_PROFILE_URL", ""), "Control Plane API base URL or /node-agents/windows-install-profile URL for profile-based install.")
fs.StringVar(&installToken, "install-token", getenv("RAP_INSTALL_TOKEN", ""), "One-time install token used to fetch Windows install profile.")
fs.StringVar(&joinBundle, "join-bundle", getenv("RAP_JOIN_BUNDLE", ""), "Preferred local join bundle JSON with Windows install profile and QUIC fabric bootstrap seeds.")
fs.StringVar(&cfg.RuntimeConfig.NodeName, "node-name", getenv("RAP_NODE_NAME", ""), "Node display name.")
fs.StringVar(&cfg.RuntimeConfig.StateDir, "state-dir", getenv("RAP_NODE_STATE_DIR", ""), "Node state directory.")
fs.StringVar(&cfg.InstallDir, "install-dir", getenv("RAP_WINDOWS_INSTALL_DIR", ""), "Directory for rap-node-agent.exe and wrapper scripts.")
@@ -218,28 +219,31 @@ func runInstallWindows(ctx context.Context, args []string) error {
fs.BoolVar(&cfg.AutoUpdateEnabled, "auto-update-enabled", getenvBool("RAP_AUTO_UPDATE_ENABLED", true), "Install and start the Windows host-agent update task.")
fs.StringVar(&cfg.AutoUpdateCurrentVersion, "auto-update-current-version", getenv("RAP_NODE_AGENT_VERSION", agent.Version), "Initial node-agent version used by update-loop before the first successful update.")
fs.StringVar(&cfg.AutoUpdateChannel, "auto-update-channel", getenv("RAP_UPDATE_CHANNEL", ""), "Optional update channel override for update-loop.")
fs.IntVar(&cfg.AutoUpdateIntervalSeconds, "auto-update-interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", 21600), "Emergency fallback plan poll interval in seconds. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&cfg.AutoUpdateIntervalSeconds, "auto-update-interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", hostagent.DefaultUpdateIntervalSec), "Emergency rescue plan poll interval in seconds. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&cfg.AutoUpdateInitialDelaySeconds, "auto-update-initial-delay-seconds", getenvInt("RAP_UPDATE_INITIAL_DELAY_SECONDS", 15), "Update-loop initial delay in seconds.")
fs.IntVar(&cfg.AutoUpdateHealthTimeoutSeconds, "auto-update-health-timeout-seconds", getenvInt("RAP_UPDATE_HEALTH_TIMEOUT_SECONDS", 30), "Updated service health timeout in seconds.")
fs.StringVar(&cfg.HostAgentSourcePath, "host-agent-source-path", getenv("RAP_HOST_AGENT_SOURCE_PATH", ""), "Source rap-host-agent.exe path copied to the persistent updater location.")
fs.BoolVar(&cfg.RuntimeConfig.WorkloadSupervisionEnabled, "workload-supervision-enabled", getenvBool("RAP_WORKLOAD_SUPERVISION_ENABLED", false), "Enable node-agent workload status reporting.")
fs.BoolVar(&cfg.RuntimeConfig.MeshSyntheticRuntimeEnabled, "mesh-synthetic-runtime-enabled", getenvBool("RAP_MESH_SYNTHETIC_RUNTIME_ENABLED", false), "Enable historical synthetic mesh runtime.")
fs.BoolVar(&cfg.RuntimeConfig.FabricRuntimeEnabled, "fabric-runtime-enabled", getenvBool("RAP_FABRIC_RUNTIME_ENABLED", false), "Enable node-local synthetic fabric control runtime.")
fs.BoolVar(&cfg.RuntimeConfig.MeshProductionForwardingEnabled, "mesh-production-forwarding-enabled", getenvBool("RAP_MESH_PRODUCTION_FORWARDING_ENABLED", false), "Enable production forwarding gate; runtime still fail-closed if unavailable.")
fs.BoolVar(&cfg.RuntimeConfig.VPNFabricSessionTransportEnabled, "vpn-fabric-session-transport-enabled", getenvBool("RAP_VPN_FABRIC_SESSION_TRANSPORT_ENABLED", false), "Route VPN packet transport over persistent fabric sessions.")
fs.BoolVar(&cfg.RuntimeConfig.MeshQUICFabricEnabled, "mesh-quic-fabric-enabled", getenvBool("RAP_MESH_QUIC_FABRIC_ENABLED", false), "Enable QUIC/UDP fabric listener.")
fs.StringVar(&cfg.RuntimeConfig.MeshQUICFabricListenAddr, "mesh-quic-fabric-listen-addr", getenv("RAP_MESH_QUIC_FABRIC_LISTEN_ADDR", ""), "QUIC/UDP fabric listen address.")
fs.IntVar(&cfg.RuntimeConfig.VPNFabricSessionStreamShards, "vpn-fabric-session-stream-shards", getenvInt("RAP_VPN_FABRIC_SESSION_STREAM_SHARDS", 4), "VPN fabric-session stream shards per traffic class.")
fs.IntVar(&cfg.RuntimeConfig.VPNFabricSessionStreamShards, "vpn-fabric-session-stream-shards", getenvInt("RAP_VPN_FABRIC_SESSION_STREAM_SHARDS", 8), "VPN fabric-session stream shards per traffic class.")
fs.IntVar(&cfg.RuntimeConfig.VPNFabricQUICMaxStreamsPerConn, "vpn-fabric-quic-max-streams-per-conn", getenvInt("RAP_VPN_FABRIC_QUIC_MAX_STREAMS_PER_CONN", 64), "Maximum logical fabric-session streams per cached VPN QUIC carrier connection.")
fs.IntVar(&cfg.RuntimeConfig.VPNFabricQUICIdleTTLSeconds, "vpn-fabric-quic-idle-ttl-seconds", getenvInt("RAP_VPN_FABRIC_QUIC_IDLE_TTL_SECONDS", 300), "Idle TTL seconds for cached VPN QUIC carrier connections.")
fs.StringVar(&cfg.RuntimeConfig.MeshListenAddr, "mesh-listen-addr", getenv("RAP_MESH_LISTEN_ADDR", ""), "Historical synthetic mesh HTTP listen address.")
fs.StringVar(&cfg.RuntimeConfig.MeshListenPortMode, "mesh-listen-port-mode", getenv("RAP_MESH_LISTEN_PORT_MODE", "auto"), "Mesh listen port behavior: manual, auto, or disabled.")
fs.IntVar(&cfg.RuntimeConfig.MeshListenAutoPortStart, "mesh-listen-auto-port-start", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_START", 19131), "First port used when mesh listen port mode is auto.")
fs.IntVar(&cfg.RuntimeConfig.MeshListenAutoPortEnd, "mesh-listen-auto-port-end", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_END", 19231), "Last port used when mesh listen port mode is auto.")
fs.StringVar(&cfg.RuntimeConfig.FabricListenAddr, "fabric-listen-addr", getenv("RAP_FABRIC_LISTEN_ADDR", ""), "Optional node listener address for QUIC fabric runtime.")
fs.StringVar(&cfg.RuntimeConfig.FabricListenPortMode, "fabric-listen-port-mode", getenv("RAP_FABRIC_LISTEN_PORT_MODE", "auto"), "Mesh listen port behavior: manual, auto, or disabled.")
fs.IntVar(&cfg.RuntimeConfig.FabricListenAutoPortStart, "fabric-listen-auto-port-start", getenvInt("RAP_FABRIC_LISTEN_AUTO_PORT_START", 19131), "First port used when mesh listen port mode is auto.")
fs.IntVar(&cfg.RuntimeConfig.FabricListenAutoPortEnd, "fabric-listen-auto-port-end", getenvInt("RAP_FABRIC_LISTEN_AUTO_PORT_END", 19231), "Last port used when mesh listen port mode is auto.")
fs.StringVar(&cfg.RuntimeConfig.MeshAdvertiseEndpoint, "mesh-advertise-endpoint", getenv("RAP_MESH_ADVERTISE_ENDPOINT", ""), "Advertised mesh endpoint.")
fs.StringVar(&cfg.RuntimeConfig.MeshAdvertiseEndpointsJSON, "mesh-advertise-endpoints-json", getenv("RAP_MESH_ADVERTISE_ENDPOINTS_JSON", ""), "Advertised endpoint candidates JSON.")
fs.StringVar(&cfg.RuntimeConfig.MeshAdvertiseTransport, "mesh-advertise-transport", getenv("RAP_MESH_ADVERTISE_TRANSPORT", "quic"), "Advertised transport.")
fs.StringVar(&cfg.RuntimeConfig.MeshConnectivityMode, "mesh-connectivity-mode", getenv("RAP_MESH_CONNECTIVITY_MODE", "outbound_only"), "Connectivity mode hint.")
fs.StringVar(&cfg.RuntimeConfig.MeshNATType, "mesh-nat-type", getenv("RAP_MESH_NAT_TYPE", "unknown"), "NAT type hint.")
fs.StringVar(&cfg.RuntimeConfig.MeshSiteID, "mesh-site-id", getenv("RAP_MESH_SITE_ID", ""), "Physical/logical site identifier advertised with QUIC endpoints.")
fs.StringVar(&cfg.RuntimeConfig.MeshLocalityGroupID, "mesh-locality-group-id", getenv("RAP_MESH_LOCALITY_GROUP_ID", ""), "Private locality group identifier used for LAN/private endpoint selection.")
fs.StringVar(&cfg.RuntimeConfig.MeshNATGroupID, "mesh-nat-group-id", getenv("RAP_MESH_NAT_GROUP_ID", ""), "Shared NAT/ingress group identifier advertised with QUIC endpoints.")
fs.StringVar(&cfg.RuntimeConfig.MeshRegion, "mesh-region", getenv("RAP_MESH_REGION", "windows"), "Region/site hint.")
fs.IntVar(&cfg.RuntimeConfig.HeartbeatIntervalSeconds, "heartbeat-interval-seconds", getenvInt("RAP_HEARTBEAT_INTERVAL_SECONDS", 15), "Heartbeat interval seconds.")
fs.IntVar(&cfg.RuntimeConfig.EnrollmentPollIntervalSeconds, "enrollment-poll-interval-seconds", getenvInt("RAP_ENROLLMENT_POLL_INTERVAL_SECONDS", 5), "Enrollment poll interval seconds.")
@@ -247,7 +251,7 @@ func runInstallWindows(ctx context.Context, args []string) error {
if err := fs.Parse(args); err != nil {
return err
}
if strings.TrimSpace(profileURL) != "" || strings.TrimSpace(installToken) != "" {
if strings.TrimSpace(joinBundle) != "" {
dryRun := cfg.DryRun
startupMode := strings.TrimSpace(cfg.StartupMode)
autoUpdateEnabled := cfg.AutoUpdateEnabled
@@ -257,12 +261,7 @@ func runInstallWindows(ctx context.Context, args []string) error {
autoUpdateInitialDelaySeconds := cfg.AutoUpdateInitialDelaySeconds
autoUpdateHealthTimeoutSeconds := cfg.AutoUpdateHealthTimeoutSeconds
hostAgentSourcePath := cfg.HostAgentSourcePath
profile, err := hostagent.FetchWindowsInstallProfile(ctx, hostagent.ProfileRequest{
URL: profileURL,
ClusterID: cfg.RuntimeConfig.ClusterID,
InstallToken: installToken,
NodeName: cfg.RuntimeConfig.NodeName,
})
profile, err := hostagent.LoadWindowsJoinBundle(joinBundle)
if err != nil {
return err
}
@@ -364,7 +363,7 @@ func runUpdate(ctx context.Context, args []string) error {
}
fmt.Printf("action=%s reason=%s target=%s production_forwarding=%t\n", plan.Action, plan.Reason, plan.TargetVersion, plan.ProductionForwarding)
if plan.Artifact != nil {
fmt.Printf("artifact=%s sha256=%s size=%d\n", plan.Artifact.URL, plan.Artifact.SHA256, plan.Artifact.SizeBytes)
fmt.Printf("artifact_id=%s sha256=%s size=%d transport=quic_fabric\n", plan.Artifact.ID, plan.Artifact.SHA256, plan.Artifact.SizeBytes)
}
return nil
}
@@ -407,7 +406,7 @@ func runUpdateLoop(ctx context.Context, args []string) error {
var hostAgentVersion string
var hostAgentBinaryPath string
registerUpdateFlags(fs, &req, &healthTimeoutSeconds)
fs.IntVar(&intervalSeconds, "interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", 21600), "Seconds between emergency fallback update plan polls. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&intervalSeconds, "interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", hostagent.DefaultUpdateIntervalSec), "Seconds between emergency rescue update plan polls. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&initialDelaySeconds, "initial-delay-seconds", getenvInt("RAP_UPDATE_INITIAL_DELAY_SECONDS", 0), "Seconds to wait before the first poll.")
fs.Float64Var(&jitter, "jitter", getenvFloat("RAP_UPDATE_JITTER", 0.15), "Fractional random jitter for interval and initial delay, 0..1.")
fs.IntVar(&maxRuns, "max-runs", getenvInt("RAP_UPDATE_MAX_RUNS", 0), "Maximum loop iterations. Use 0 to run until stopped.")
@@ -432,7 +431,6 @@ func runUpdateLoop(ctx context.Context, args []string) error {
}
cfg.HostAgentUpdateEnabled = hostAgentStatusEnabled
cfg.HostAgentUpdateRequest = hostagent.HostAgentUpdateRequest{
BackendURL: req.BackendURL,
ClusterID: req.ClusterID,
NodeID: req.NodeID,
StateDir: req.StateDir,
@@ -487,7 +485,6 @@ func parseMonitor(args []string) (hostagent.MonitorConfig, error) {
var staleRestartingSeconds int
var tmpMinAgeMinutes int
watchContainers := repeatedFlag{}
fs.StringVar(&cfg.BackendURL, "backend-url", getenv("RAP_BACKEND_URL", ""), "Control Plane API base URL used for monitor status reports.")
fs.StringVar(&cfg.ClusterID, "cluster-id", getenv("RAP_CLUSTER_ID", ""), "Cluster ID.")
fs.StringVar(&cfg.NodeID, "node-id", getenv("RAP_NODE_ID", ""), "Already enrolled node ID.")
fs.StringVar(&cfg.StateDir, "state-dir", getenv("RAP_NODE_STATE_DIR", hostagent.DefaultStateDir), "Host path containing node-agent identity.json.")
@@ -545,13 +542,12 @@ func runInstallUpdater(ctx context.Context, args []string) error {
var selfUpdater bool
var monitorEnabled bool
monitorContainers := repeatedFlag{}
fs.StringVar(&runtimeCfg.BackendURL, "backend-url", getenv("RAP_BACKEND_URL", ""), "Control Plane API base URL.")
fs.StringVar(&runtimeCfg.ClusterID, "cluster-id", getenv("RAP_CLUSTER_ID", ""), "Cluster ID.")
fs.StringVar(&runtimeCfg.ContainerName, "container-name", getenv("RAP_NODE_AGENT_CONTAINER", hostagent.DefaultContainerName), "Docker container name to update.")
fs.StringVar(&runtimeCfg.StateDir, "state-dir", getenv("RAP_NODE_STATE_DIR", hostagent.DefaultStateDir), "Host path containing node-agent identity.json.")
fs.StringVar(&service.CurrentVersion, "current-version", getenv("RAP_NODE_AGENT_VERSION", agent.Version), "Initial node-agent version before first successful update.")
fs.StringVar(&service.Channel, "channel", getenv("RAP_UPDATE_CHANNEL", ""), "Optional update channel override.")
fs.IntVar(&service.IntervalSeconds, "interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", 21600), "Emergency fallback plan poll interval in seconds. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&service.IntervalSeconds, "interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", hostagent.DefaultUpdateIntervalSec), "Emergency rescue plan poll interval in seconds. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&service.InitialDelaySeconds, "initial-delay-seconds", getenvInt("RAP_UPDATE_INITIAL_DELAY_SECONDS", 15), "Update-loop initial delay in seconds.")
fs.Float64Var(&service.Jitter, "jitter", getenvFloat("RAP_UPDATE_JITTER", 0.15), "Update-loop interval jitter, 0..1.")
fs.IntVar(&service.HealthTimeoutSec, "health-timeout-seconds", getenvInt("RAP_UPDATE_HEALTH_TIMEOUT_SECONDS", 30), "Updated container running-state timeout in seconds.")
@@ -637,7 +633,6 @@ func parseHostAgentUpdate(args []string) (hostagent.HostAgentUpdateRequest, int,
var maxRuns int
var jitter float64
var stopOnError bool
fs.StringVar(&req.BackendURL, "backend-url", getenv("RAP_BACKEND_URL", ""), "Control Plane API base URL.")
fs.StringVar(&req.ClusterID, "cluster-id", getenv("RAP_CLUSTER_ID", ""), "Cluster ID.")
fs.StringVar(&req.NodeID, "node-id", getenv("RAP_NODE_ID", ""), "Already enrolled node ID.")
fs.StringVar(&req.StateDir, "state-dir", getenv("RAP_NODE_STATE_DIR", ""), "Host path containing node-agent identity.json.")
@@ -651,7 +646,7 @@ func parseHostAgentUpdate(args []string) (hostagent.HostAgentUpdateRequest, int,
fs.StringVar(&req.InstallType, "install-type", getenv("RAP_HOST_AGENT_UPDATE_INSTALL_TYPE", hostagent.BinaryUpdateInstallType), "Host-agent artifact install type.")
fs.StringVar(&req.BinaryPath, "binary-path", getenv("RAP_HOST_AGENT_BINARY_PATH", hostagent.DefaultHostAgentInstallPath), "rap-host-agent binary path to replace atomically.")
fs.BoolVar(&req.DryRun, "dry-run", false, "Fetch and print the update plan without applying it.")
fs.IntVar(&intervalSeconds, "interval-seconds", getenvInt("RAP_HOST_AGENT_UPDATE_INTERVAL_SECONDS", 900), "Seconds between host-agent update plan polls.")
fs.IntVar(&intervalSeconds, "interval-seconds", getenvInt("RAP_HOST_AGENT_UPDATE_INTERVAL_SECONDS", hostagent.DefaultUpdateIntervalSec), "Seconds between host-agent update plan polls.")
fs.IntVar(&initialDelaySeconds, "initial-delay-seconds", getenvInt("RAP_HOST_AGENT_UPDATE_INITIAL_DELAY_SECONDS", 45), "Seconds to wait before the first poll.")
fs.Float64Var(&jitter, "jitter", getenvFloat("RAP_UPDATE_JITTER", 0.15), "Fractional random jitter for interval and initial delay, 0..1.")
fs.IntVar(&maxRuns, "max-runs", getenvInt("RAP_UPDATE_MAX_RUNS", 0), "Maximum loop iterations. Use 0 to run until stopped.")
@@ -663,7 +658,6 @@ func parseHostAgentUpdate(args []string) (hostagent.HostAgentUpdateRequest, int,
}
func registerUpdateFlags(fs *flag.FlagSet, req *hostagent.UpdateRequest, healthTimeoutSeconds *int) {
fs.StringVar(&req.BackendURL, "backend-url", getenv("RAP_BACKEND_URL", ""), "Control Plane API base URL.")
fs.StringVar(&req.ClusterID, "cluster-id", getenv("RAP_CLUSTER_ID", ""), "Cluster ID.")
fs.StringVar(&req.NodeID, "node-id", getenv("RAP_NODE_ID", ""), "Already enrolled node ID.")
fs.StringVar(&req.StateDir, "state-dir", getenv("RAP_NODE_STATE_DIR", ""), "Host path containing node-agent identity.json; used when node-id is not known yet.")
@@ -688,16 +682,15 @@ func parseInstall(args []string) (installCommandConfig, error) {
fs := flag.NewFlagSet("install", flag.ContinueOnError)
cfg := hostagent.RuntimeConfig{}
var dryRun bool
var profileURL string
var installToken string
var joinBundle string
var autoUpdateEnabled bool
autoUpdate := hostagent.UpdateServiceConfig{}
monitorContainers := repeatedFlag{}
fs.StringVar(&cfg.BackendURL, "backend-url", getenv("RAP_BACKEND_URL", ""), "Control Plane API base URL.")
fs.StringVar(&cfg.ClusterID, "cluster-id", getenv("RAP_CLUSTER_ID", ""), "Cluster ID.")
fs.StringVar(&cfg.ClusterAuthorityPublicKey, "cluster-authority-public-key", getenv("RAP_CLUSTER_AUTHORITY_PUBLIC_KEY", ""), "Pinned Ed25519 cluster authority public key for signed fabric registry records.")
fs.StringVar(&cfg.FabricRegistryRecordsJSON, "fabric-registry-records-json", getenv("RAP_FABRIC_REGISTRY_RECORDS_JSON", ""), "JSON array of signed QUIC-only fabric registry records used as bootstrap seeds.")
fs.StringVar(&cfg.JoinToken, "join-token", getenv("RAP_JOIN_TOKEN", ""), "One-time join token for first enrollment.")
fs.StringVar(&profileURL, "profile-url", getenv("RAP_INSTALL_PROFILE_URL", ""), "Control Plane API base URL or /node-agents/docker-install-profile URL for profile-based install.")
fs.StringVar(&installToken, "install-token", getenv("RAP_INSTALL_TOKEN", ""), "One-time install token used to fetch Docker install profile.")
fs.StringVar(&joinBundle, "join-bundle", getenv("RAP_JOIN_BUNDLE", ""), "Preferred local join bundle JSON with Docker install profile and QUIC fabric bootstrap seeds.")
fs.StringVar(&cfg.NodeName, "node-name", getenv("RAP_NODE_NAME", ""), "Node display name.")
fs.StringVar(&cfg.Image, "image", getenv("RAP_NODE_AGENT_IMAGE", hostagent.DefaultImage), "Docker image for rap-node-agent.")
fs.StringVar(&cfg.ContainerName, "container-name", getenv("RAP_NODE_AGENT_CONTAINER", hostagent.DefaultContainerName), "Docker container name.")
@@ -716,7 +709,7 @@ func parseInstall(args []string) (installCommandConfig, error) {
fs.StringVar(&autoUpdate.CurrentVersion, "auto-update-current-version", getenv("RAP_NODE_AGENT_VERSION", agent.Version), "Initial node-agent version used by update-loop before the first successful update.")
fs.StringVar(&autoUpdate.SelfUpdateVersion, "host-agent-current-version", getenv("RAP_HOST_AGENT_VERSION", agent.Version), "Initial host-agent binary version used by the self-updater.")
fs.StringVar(&autoUpdate.Channel, "auto-update-channel", getenv("RAP_UPDATE_CHANNEL", ""), "Optional update channel override for update-loop.")
fs.IntVar(&autoUpdate.IntervalSeconds, "auto-update-interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", 21600), "Emergency fallback plan poll interval in seconds. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&autoUpdate.IntervalSeconds, "auto-update-interval-seconds", getenvInt("RAP_UPDATE_INTERVAL_SECONDS", hostagent.DefaultUpdateIntervalSec), "Emergency rescue plan poll interval in seconds. Update-service/heartbeat hints trigger normal runs.")
fs.IntVar(&autoUpdate.InitialDelaySeconds, "auto-update-initial-delay-seconds", getenvInt("RAP_UPDATE_INITIAL_DELAY_SECONDS", 15), "Update-loop initial delay in seconds.")
fs.Float64Var(&autoUpdate.Jitter, "auto-update-jitter", getenvFloat("RAP_UPDATE_JITTER", 0.15), "Update-loop interval jitter, 0..1.")
fs.IntVar(&autoUpdate.HealthTimeoutSec, "auto-update-health-timeout-seconds", getenvInt("RAP_UPDATE_HEALTH_TIMEOUT_SECONDS", 30), "Updated container running-state timeout in seconds.")
@@ -728,23 +721,26 @@ func parseInstall(args []string) (installCommandConfig, error) {
fs.IntVar(&autoUpdate.MonitorDiskCritical, "monitor-disk-critical-percent", getenvInt("RAP_MONITOR_DISK_CRITICAL_PERCENT", hostagent.DefaultMonitorDiskCriticalPercent), "Disk used percent that reports failure after cleanup.")
fs.BoolVar(&autoUpdate.MonitorCleanupDocker, "monitor-cleanup-docker", getenvBool("RAP_MONITOR_CLEANUP_DOCKER", true), "Run safe docker prune cleanup when disk is above cleanup threshold.")
fs.BoolVar(&cfg.WorkloadSupervisionEnabled, "workload-supervision-enabled", getenvBool("RAP_WORKLOAD_SUPERVISION_ENABLED", false), "Enable node-agent workload status reporting.")
fs.BoolVar(&cfg.MeshSyntheticRuntimeEnabled, "mesh-synthetic-runtime-enabled", getenvBool("RAP_MESH_SYNTHETIC_RUNTIME_ENABLED", false), "Enable historical synthetic mesh runtime.")
fs.BoolVar(&cfg.FabricRuntimeEnabled, "fabric-runtime-enabled", getenvBool("RAP_FABRIC_RUNTIME_ENABLED", false), "Enable node-local synthetic fabric control runtime.")
fs.BoolVar(&cfg.MeshProductionForwardingEnabled, "mesh-production-forwarding-enabled", getenvBool("RAP_MESH_PRODUCTION_FORWARDING_ENABLED", false), "Enable production forwarding gate; runtime still fail-closed if unavailable.")
fs.BoolVar(&cfg.VPNFabricSessionTransportEnabled, "vpn-fabric-session-transport-enabled", getenvBool("RAP_VPN_FABRIC_SESSION_TRANSPORT_ENABLED", false), "Route VPN packet transport over persistent fabric sessions.")
fs.BoolVar(&cfg.MeshQUICFabricEnabled, "mesh-quic-fabric-enabled", getenvBool("RAP_MESH_QUIC_FABRIC_ENABLED", false), "Enable QUIC/UDP fabric listener.")
fs.StringVar(&cfg.MeshQUICFabricListenAddr, "mesh-quic-fabric-listen-addr", getenv("RAP_MESH_QUIC_FABRIC_LISTEN_ADDR", ""), "QUIC/UDP fabric listen address.")
fs.IntVar(&cfg.VPNFabricSessionStreamShards, "vpn-fabric-session-stream-shards", getenvInt("RAP_VPN_FABRIC_SESSION_STREAM_SHARDS", 4), "VPN fabric-session stream shards per traffic class.")
fs.IntVar(&cfg.VPNFabricSessionStreamShards, "vpn-fabric-session-stream-shards", getenvInt("RAP_VPN_FABRIC_SESSION_STREAM_SHARDS", 8), "VPN fabric-session stream shards per traffic class.")
fs.IntVar(&cfg.VPNFabricQUICMaxStreamsPerConn, "vpn-fabric-quic-max-streams-per-conn", getenvInt("RAP_VPN_FABRIC_QUIC_MAX_STREAMS_PER_CONN", 64), "Maximum logical fabric-session streams per cached VPN QUIC carrier connection.")
fs.IntVar(&cfg.VPNFabricQUICIdleTTLSeconds, "vpn-fabric-quic-idle-ttl-seconds", getenvInt("RAP_VPN_FABRIC_QUIC_IDLE_TTL_SECONDS", 300), "Idle TTL seconds for cached VPN QUIC carrier connections.")
fs.StringVar(&cfg.MeshListenAddr, "mesh-listen-addr", getenv("RAP_MESH_LISTEN_ADDR", ""), "Historical synthetic mesh HTTP listen address inside container.")
fs.StringVar(&cfg.MeshListenPortMode, "mesh-listen-port-mode", getenv("RAP_MESH_LISTEN_PORT_MODE", ""), "Mesh listen port behavior: manual, auto, or disabled.")
fs.IntVar(&cfg.MeshListenAutoPortStart, "mesh-listen-auto-port-start", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_START", 0), "First port used when mesh listen port mode is auto.")
fs.IntVar(&cfg.MeshListenAutoPortEnd, "mesh-listen-auto-port-end", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_END", 0), "Last port used when mesh listen port mode is auto.")
fs.StringVar(&cfg.FabricListenAddr, "fabric-listen-addr", getenv("RAP_FABRIC_LISTEN_ADDR", ""), "Optional node listener address for QUIC fabric runtime inside container.")
fs.StringVar(&cfg.FabricListenPortMode, "fabric-listen-port-mode", getenv("RAP_FABRIC_LISTEN_PORT_MODE", ""), "Mesh listen port behavior: manual, auto, or disabled.")
fs.IntVar(&cfg.FabricListenAutoPortStart, "fabric-listen-auto-port-start", getenvInt("RAP_FABRIC_LISTEN_AUTO_PORT_START", 0), "First port used when mesh listen port mode is auto.")
fs.IntVar(&cfg.FabricListenAutoPortEnd, "fabric-listen-auto-port-end", getenvInt("RAP_FABRIC_LISTEN_AUTO_PORT_END", 0), "Last port used when mesh listen port mode is auto.")
fs.StringVar(&cfg.MeshAdvertiseEndpoint, "mesh-advertise-endpoint", getenv("RAP_MESH_ADVERTISE_ENDPOINT", ""), "Advertised mesh endpoint.")
fs.StringVar(&cfg.MeshAdvertiseEndpointsJSON, "mesh-advertise-endpoints-json", getenv("RAP_MESH_ADVERTISE_ENDPOINTS_JSON", ""), "Advertised endpoint candidates JSON.")
fs.StringVar(&cfg.MeshAdvertiseTransport, "mesh-advertise-transport", getenv("RAP_MESH_ADVERTISE_TRANSPORT", "quic"), "Advertised transport.")
fs.StringVar(&cfg.MeshConnectivityMode, "mesh-connectivity-mode", getenv("RAP_MESH_CONNECTIVITY_MODE", ""), "Connectivity mode hint.")
fs.StringVar(&cfg.MeshNATType, "mesh-nat-type", getenv("RAP_MESH_NAT_TYPE", ""), "NAT type hint.")
fs.StringVar(&cfg.MeshSiteID, "mesh-site-id", getenv("RAP_MESH_SITE_ID", ""), "Physical/logical site identifier advertised with QUIC endpoints.")
fs.StringVar(&cfg.MeshLocalityGroupID, "mesh-locality-group-id", getenv("RAP_MESH_LOCALITY_GROUP_ID", ""), "Private locality group identifier used for LAN/private endpoint selection.")
fs.StringVar(&cfg.MeshNATGroupID, "mesh-nat-group-id", getenv("RAP_MESH_NAT_GROUP_ID", ""), "Shared NAT/ingress group identifier advertised with QUIC endpoints.")
fs.StringVar(&cfg.MeshRegion, "mesh-region", getenv("RAP_MESH_REGION", ""), "Region/site hint.")
fs.IntVar(&cfg.HeartbeatIntervalSeconds, "heartbeat-interval-seconds", getenvInt("RAP_HEARTBEAT_INTERVAL_SECONDS", 15), "Heartbeat interval seconds.")
fs.IntVar(&cfg.EnrollmentPollIntervalSeconds, "enrollment-poll-interval-seconds", getenvInt("RAP_ENROLLMENT_POLL_INTERVAL_SECONDS", 5), "Enrollment poll interval seconds.")
@@ -752,25 +748,20 @@ func parseInstall(args []string) (installCommandConfig, error) {
fs.IntVar(&cfg.ProductionObservationSinkCap, "production-observation-sink-capacity", getenvInt("RAP_MESH_PRODUCTION_OBSERVATION_SINK_CAPACITY", 0), "Production observation sink capacity.")
extraEnv := repeatedFlag{}
extraRunArg := repeatedFlag{}
imageArtifactURL := repeatedFlag{}
imageArtifactPath := repeatedFlag{}
fs.Var(&extraEnv, "env", "Extra KEY=VALUE env passed to node-agent container; may be repeated.")
fs.Var(&extraRunArg, "docker-run-arg", "Extra raw docker run argument; may be repeated.")
fs.Var(&imageArtifactURL, "image-artifact-url", "Docker image tar artifact URL to docker load before running; may be repeated.")
fs.Var(&imageArtifactPath, "image-artifact-path", "Local Docker image tar artifact path to docker load before running; may be repeated.")
fs.Var(&monitorContainers, "monitor-container", "Extra Docker container watched by monitor; may be repeated.")
if err := fs.Parse(args); err != nil {
return installCommandConfig{}, err
}
cfg.ExtraEnv = extraEnv
cfg.AdditionalDockerRunArgs = extraRunArg
cfg.ImageArtifactURLs = append(cfg.ImageArtifactURLs, imageArtifactURL...)
cfg.ImageArtifactURLs = append(cfg.ImageArtifactURLs, imageArtifactPath...)
autoUpdate.MonitorContainers = monitorContainers
if strings.TrimSpace(profileURL) != "" || strings.TrimSpace(installToken) != "" {
profile, err := hostagent.FetchDockerInstallProfile(context.Background(), hostagent.ProfileRequest{
URL: profileURL,
ClusterID: cfg.ClusterID,
InstallToken: installToken,
NodeName: cfg.NodeName,
})
if strings.TrimSpace(joinBundle) != "" {
profile, err := hostagent.LoadDockerJoinBundle(joinBundle)
if err != nil {
return installCommandConfig{}, err
}
@@ -778,8 +769,8 @@ func parseInstall(args []string) (installCommandConfig, error) {
profileCfg.ExtraEnv = cfg.ExtraEnv
profileCfg.AdditionalDockerRunArgs = cfg.AdditionalDockerRunArgs
profileCfg.DockerVPNGatewayEnabled = profileCfg.DockerVPNGatewayEnabled || cfg.DockerVPNGatewayEnabled
if len(imageArtifactURL) > 0 {
profileCfg.ImageArtifactURLs = append([]string(nil), imageArtifactURL...)
if len(imageArtifactPath) > 0 {
profileCfg.ImageArtifactURLs = append([]string(nil), imageArtifactPath...)
}
if cfg.ImageArtifactSHA256 != "" {
profileCfg.ImageArtifactSHA256 = cfg.ImageArtifactSHA256
@@ -867,16 +858,15 @@ func shellJoin(args []string) string {
func usage() {
fmt.Fprintln(os.Stderr, `usage:
rap-host-agent install -profile-url URL -install-token TOKEN [-node-name NAME] [docker options]
rap-host-agent install -backend-url URL -cluster-id ID -join-token TOKEN -node-name NAME [docker options]
rap-host-agent install-windows -profile-url URL -install-token TOKEN [-node-name NAME] [windows options]
rap-host-agent install-linux -profile-url URL -install-token TOKEN [-node-name NAME] [linux/systemd options]
rap-host-agent install-updater (-backend-url URL | -fabric-registry-records-json JSON) -cluster-id ID -state-dir DIR -container-name NAME
rap-host-agent update-host-agent (-backend-url URL | -fabric-registry-records-json JSON) -cluster-id ID -state-dir DIR
rap-host-agent update-host-agent-loop (-backend-url URL | -fabric-registry-records-json JSON) -cluster-id ID -state-dir DIR
rap-host-agent monitor-loop (-backend-url URL | -fabric-registry-records-json JSON) -cluster-id ID -state-dir DIR --watch-container NAME
rap-host-agent monitor-once (-backend-url URL | -fabric-registry-records-json JSON) -cluster-id ID -state-dir DIR --watch-container NAME
rap-host-agent update (-backend-url URL | -fabric-registry-records-json JSON) -cluster-id ID -node-id ID [-container-name NAME]
rap-host-agent update-loop (-backend-url URL | -fabric-registry-records-json JSON) -cluster-id ID -node-id ID [-container-name NAME]
rap-host-agent install -join-bundle FILE [docker options]
rap-host-agent install-windows -join-bundle FILE [windows options]
rap-host-agent install-linux -join-bundle FILE [linux/systemd options]
rap-host-agent install-updater -fabric-registry-records-json JSON -cluster-id ID -state-dir DIR -container-name NAME
rap-host-agent update-host-agent -fabric-registry-records-json JSON -cluster-id ID -state-dir DIR
rap-host-agent update-host-agent-loop -fabric-registry-records-json JSON -cluster-id ID -state-dir DIR
rap-host-agent monitor-loop -fabric-registry-records-json JSON -cluster-id ID -state-dir DIR --watch-container NAME
rap-host-agent monitor-once -fabric-registry-records-json JSON -cluster-id ID -state-dir DIR --watch-container NAME
rap-host-agent update -fabric-registry-records-json JSON -cluster-id ID -node-id ID [-container-name NAME]
rap-host-agent update-loop -fabric-registry-records-json JSON -cluster-id ID -node-id ID [-container-name NAME]
rap-host-agent status [-container-name NAME]`)
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff