Skip to content

Commit ed35eb9

Browse files
fix(mxc): refresh stale demo gateway aliases (#4192)
* fix(mxc): refresh stale demo gateway aliases (NVBug 6870039) Signed-off-by: nv-vankit <nv-vankit@users.noreply.github.com> * fix(mxc): isolate demo CLI gateway state Signed-off-by: nv-vankit <nv-vankit@users.noreply.github.com> * fix(mxc): remove empty gateway overrides Signed-off-by: nv-vankit <nv-vankit@users.noreply.github.com> * fix(mxc): preserve exact runner environment state Signed-off-by: Shailendra Singh <shailendras@nvidia.com> --------- Signed-off-by: nv-vankit <nv-vankit@users.noreply.github.com> Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Co-authored-by: nv-vankit <nv-vankit@users.noreply.github.com> Co-authored-by: Shailendra Singh <shailendras@nvidia.com>
1 parent f6ecca2 commit ed35eb9

7 files changed

Lines changed: 535 additions & 83 deletions

File tree

‎crates/openshell-driver-mxc/examples/run-mxc-e2e.ps1‎

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,105 @@ $script:registered = $false
176176
$tomlBase = $null
177177
$gwLog = $null
178178
$gwErrLog = $null
179+
$cliStateRoot = $null
180+
$cliEnvironmentSnapshot = @{}
181+
$cliEnvironmentNames = @(
182+
"APPDATA",
183+
"LOCALAPPDATA",
184+
"XDG_CONFIG_HOME",
185+
"XDG_STATE_HOME",
186+
"XDG_DATA_HOME",
187+
"OPENSHELL_GATEWAY",
188+
"OPENSHELL_GATEWAY_ENDPOINT",
189+
"OPENSHELL_GATEWAY_INSECURE",
190+
"OPENSHELL_GATEWAY_CONFIG",
191+
"OPENSHELL_GATEWAY_NAME"
192+
)
179193

180194
# --- Helpers ------------------------------------------------------------------
181195

196+
function Set-ProcessEnvironmentVariableExact {
197+
param(
198+
[Parameter(Mandatory = $true)]
199+
[string] $Name,
200+
[Parameter(Mandatory = $true)]
201+
[bool] $Exists,
202+
[AllowNull()]
203+
[string] $Value
204+
)
205+
206+
if (-not $Exists) {
207+
Remove-Item "Env:$Name" -ErrorAction SilentlyContinue
208+
return
209+
}
210+
211+
if ($Value.Length -eq 0) {
212+
# Windows PowerShell 5.1 maps an empty value passed through
213+
# Environment.SetEnvironmentVariable to deletion. Call Win32 directly
214+
# so an inherited empty entry remains distinguishable from absence.
215+
if (-not ("OpenShellMxcProcessEnvironmentNative" -as [type])) {
216+
Add-Type -TypeDefinition @'
217+
using System.Runtime.InteropServices;
218+
219+
public static class OpenShellMxcProcessEnvironmentNative
220+
{
221+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
222+
[return: MarshalAs(UnmanagedType.Bool)]
223+
public static extern bool SetEnvironmentVariable(string name, string value);
224+
}
225+
'@
226+
}
227+
if (-not [OpenShellMxcProcessEnvironmentNative]::SetEnvironmentVariable($Name, [string]::Empty)) {
228+
$errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
229+
throw "failed to restore empty process environment variable '$Name' (Win32 error $errorCode)"
230+
}
231+
return
232+
}
233+
234+
[Environment]::SetEnvironmentVariable($Name, $Value, "Process")
235+
}
236+
237+
function Enter-IsolatedCliEnvironment {
238+
$processEnvironment = [Environment]::GetEnvironmentVariables("Process")
239+
foreach ($name in $cliEnvironmentNames) {
240+
$exists = $processEnvironment.Contains($name)
241+
$script:cliEnvironmentSnapshot[$name] = [pscustomobject]@{
242+
Exists = $exists
243+
Value = if ($exists) { [string] $processEnvironment[$name] } else { $null }
244+
}
245+
}
246+
$script:cliStateRoot = Join-Path ([IO.Path]::GetTempPath()) "openshell-mxc-e2e-cli-$PID-$([Guid]::NewGuid().ToString('N'))"
247+
$isolatedPaths = @{
248+
APPDATA = Join-Path $script:cliStateRoot "appdata"
249+
LOCALAPPDATA = Join-Path $script:cliStateRoot "localappdata"
250+
XDG_CONFIG_HOME = Join-Path $script:cliStateRoot "xdg-config"
251+
XDG_STATE_HOME = Join-Path $script:cliStateRoot "xdg-state"
252+
XDG_DATA_HOME = Join-Path $script:cliStateRoot "xdg-data"
253+
}
254+
try {
255+
New-Item -ItemType Directory -Force -Path @($isolatedPaths.Values) | Out-Null
256+
foreach ($entry in $isolatedPaths.GetEnumerator()) {
257+
[Environment]::SetEnvironmentVariable($entry.Key, $entry.Value, "Process")
258+
}
259+
foreach ($name in $cliEnvironmentNames | Where-Object { -not $isolatedPaths.ContainsKey($_) }) {
260+
Remove-Item "Env:$name" -ErrorAction SilentlyContinue
261+
}
262+
} catch {
263+
Exit-IsolatedCliEnvironment
264+
throw
265+
}
266+
}
267+
268+
function Exit-IsolatedCliEnvironment {
269+
foreach ($name in $cliEnvironmentNames) {
270+
$snapshot = $script:cliEnvironmentSnapshot[$name]
271+
Set-ProcessEnvironmentVariableExact -Name $name -Exists $snapshot.Exists -Value $snapshot.Value
272+
}
273+
if ($script:cliStateRoot -and (Test-Path -LiteralPath $script:cliStateRoot)) {
274+
Remove-Item -LiteralPath $script:cliStateRoot -Recurse -Force -ErrorAction SilentlyContinue
275+
}
276+
}
277+
182278
# Render host-runtime settings from the pristine base. Sandbox workload
183279
# settings are create-time driver config, not gateway-wide TOML.
184280
function Render-Toml {
@@ -233,14 +329,14 @@ function Stop-Gw($p) {
233329

234330
function Register-Cli {
235331
if ($script:registered) { return }
236-
$env:OPENSHELL_GATEWAY = ""
237332

333+
$expectedEndpoint = "http://127.0.0.1:$Port"
238334
$addResult = Invoke-NativeCaptured $cli @(
239-
"gateway", "add", "http://127.0.0.1:$Port", "--local", "--name", $GatewayName
335+
"gateway", "add", $expectedEndpoint, "--local", "--name", $GatewayName
240336
)
241337
$addText = ($addResult.Output -join "`n")
242338
if ($addText) { $addResult.Output | ForEach-Object { Info $_ } }
243-
if ($addResult.ExitCode -ne 0 -and $addText -notmatch '(?i)already exists') {
339+
if ($addResult.ExitCode -ne 0) {
244340
throw "gateway add failed (exit $($addResult.ExitCode)): $addText"
245341
}
246342

@@ -379,6 +475,8 @@ $backendProbe = @{ Live = $false; Reason = "not probed" }
379475
$runId = Get-Date -Format 'MMddHHmmss'
380476

381477
try {
478+
Enter-IsolatedCliEnvironment
479+
382480
# Start the transcript inside the guarded region so a Start-Transcript failure
383481
# is caught and the results bundle is still produced. Pre-flight runs
384482
# immediately below, so the transcript still captures the whole run.
@@ -750,14 +848,19 @@ try {
750848
}
751849
} finally {
752850
if ($gw -and -not $KeepRunning) { Stop-Gw $gw }
753-
if ($KeepRunning -and $gw) { Info "gateway pid $($gw.Id) left running (-KeepRunning)" }
851+
if ($KeepRunning -and $gw) {
852+
Info "gateway pid $($gw.Id) left running (-KeepRunning)"
853+
Info "CLI inspection endpoint: `$env:OPENSHELL_GATEWAY_ENDPOINT='http://127.0.0.1:$Port'"
854+
}
754855
}
755856
}
756857
catch {
757858
$harnessError = $_.Exception.Message
758859
Bad "harness error: $harnessError"
759860
}
760861
finally {
862+
Exit-IsolatedCliEnvironment
863+
761864
# --- Summary + results bundle ---------------------------------------------
762865
Step "Summary"
763866
$results | Format-Table -AutoSize

‎crates/openshell-driver-mxc/examples/run-ocsf-audit.ps1‎

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,10 @@ function Invoke-Cli([string[]]$CommandArgs, [switch]$AllowFailure) {
129129
if (-not $AllowFailure -and $process.ExitCode -ne 0) {
130130
throw "openshell $($CommandArgs -join ' ') failed (exit $($process.ExitCode)): $text"
131131
}
132-
return @{ ExitCode = $process.ExitCode; Text = $text }
132+
return @{
133+
ExitCode = $process.ExitCode
134+
Text = $text
135+
}
133136
}
134137

135138
function Resolve-Artifact([string]$explicit, [string]$leaf) {
@@ -152,6 +155,103 @@ function Get-MxcEtwSessions {
152155
}
153156
}
154157

158+
$cliStateRoot = $null
159+
$cliEnvironmentSnapshot = @{}
160+
$cliEnvironmentNames = @(
161+
"APPDATA",
162+
"LOCALAPPDATA",
163+
"XDG_CONFIG_HOME",
164+
"XDG_STATE_HOME",
165+
"XDG_DATA_HOME",
166+
"OPENSHELL_GATEWAY",
167+
"OPENSHELL_GATEWAY_ENDPOINT",
168+
"OPENSHELL_GATEWAY_INSECURE",
169+
"OPENSHELL_GATEWAY_CONFIG",
170+
"OPENSHELL_GATEWAY_NAME"
171+
)
172+
173+
function Set-ProcessEnvironmentVariableExact {
174+
param(
175+
[Parameter(Mandatory = $true)]
176+
[string] $Name,
177+
[Parameter(Mandatory = $true)]
178+
[bool] $Exists,
179+
[AllowNull()]
180+
[string] $Value
181+
)
182+
183+
if (-not $Exists) {
184+
Remove-Item "Env:$Name" -ErrorAction SilentlyContinue
185+
return
186+
}
187+
188+
if ($Value.Length -eq 0) {
189+
# Windows PowerShell 5.1 maps an empty value passed through
190+
# Environment.SetEnvironmentVariable to deletion. Call Win32 directly
191+
# so an inherited empty entry remains distinguishable from absence.
192+
if (-not ("OpenShellMxcProcessEnvironmentNative" -as [type])) {
193+
Add-Type -TypeDefinition @'
194+
using System.Runtime.InteropServices;
195+
196+
public static class OpenShellMxcProcessEnvironmentNative
197+
{
198+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
199+
[return: MarshalAs(UnmanagedType.Bool)]
200+
public static extern bool SetEnvironmentVariable(string name, string value);
201+
}
202+
'@
203+
}
204+
if (-not [OpenShellMxcProcessEnvironmentNative]::SetEnvironmentVariable($Name, [string]::Empty)) {
205+
$errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
206+
throw "failed to restore empty process environment variable '$Name' (Win32 error $errorCode)"
207+
}
208+
return
209+
}
210+
211+
[Environment]::SetEnvironmentVariable($Name, $Value, "Process")
212+
}
213+
214+
function Enter-IsolatedCliEnvironment {
215+
$processEnvironment = [Environment]::GetEnvironmentVariables("Process")
216+
foreach ($name in $cliEnvironmentNames) {
217+
$exists = $processEnvironment.Contains($name)
218+
$script:cliEnvironmentSnapshot[$name] = [pscustomobject]@{
219+
Exists = $exists
220+
Value = if ($exists) { [string] $processEnvironment[$name] } else { $null }
221+
}
222+
}
223+
$script:cliStateRoot = Join-Path ([IO.Path]::GetTempPath()) "openshell-mxc-ocsf-cli-$PID-$([Guid]::NewGuid().ToString('N'))"
224+
$isolatedPaths = @{
225+
APPDATA = Join-Path $script:cliStateRoot "appdata"
226+
LOCALAPPDATA = Join-Path $script:cliStateRoot "localappdata"
227+
XDG_CONFIG_HOME = Join-Path $script:cliStateRoot "xdg-config"
228+
XDG_STATE_HOME = Join-Path $script:cliStateRoot "xdg-state"
229+
XDG_DATA_HOME = Join-Path $script:cliStateRoot "xdg-data"
230+
}
231+
try {
232+
New-Item -ItemType Directory -Force -Path @($isolatedPaths.Values) | Out-Null
233+
foreach ($entry in $isolatedPaths.GetEnumerator()) {
234+
[Environment]::SetEnvironmentVariable($entry.Key, $entry.Value, "Process")
235+
}
236+
foreach ($name in $cliEnvironmentNames | Where-Object { -not $isolatedPaths.ContainsKey($_) }) {
237+
Remove-Item "Env:$name" -ErrorAction SilentlyContinue
238+
}
239+
} catch {
240+
Exit-IsolatedCliEnvironment
241+
throw
242+
}
243+
}
244+
245+
function Exit-IsolatedCliEnvironment {
246+
foreach ($name in $cliEnvironmentNames) {
247+
$snapshot = $script:cliEnvironmentSnapshot[$name]
248+
Set-ProcessEnvironmentVariableExact -Name $name -Exists $snapshot.Exists -Value $snapshot.Value
249+
}
250+
if ($script:cliStateRoot -and (Test-Path -LiteralPath $script:cliStateRoot)) {
251+
Remove-Item -LiteralPath $script:cliStateRoot -Recurse -Force -ErrorAction SilentlyContinue
252+
}
253+
}
254+
155255
$gateway = Resolve-Artifact $GatewayPath "openshell-gateway.exe"
156256
$cli = Resolve-Artifact $CliPath "openshell.exe"
157257
$policySrc = Join-Path $here "ocsf-audit.yaml"
@@ -167,6 +267,8 @@ $proxyOn = -not $NoProxy
167267
$oldMockWxc = $env:OPENSHELL_MXC_MOCK_WXC
168268

169269
try {
270+
Enter-IsolatedCliEnvironment
271+
170272
# 1. Validate artifacts + privilege.
171273
Step "Validate package artifacts"
172274
foreach ($f in @($gateway, $cli, $policySrc, $tomlSrc)) {
@@ -319,10 +421,10 @@ try {
319421

320422
# 9. Register CLI -> gateway.
321423
Step "Register CLI -> gateway"
322-
$env:OPENSHELL_GATEWAY = ""
323-
$gatewayAdd = Invoke-Cli @("gateway", "add", "http://127.0.0.1:$Port", "--local", "--name", $GatewayName) -AllowFailure
424+
$expectedEndpoint = "http://127.0.0.1:$Port"
425+
$gatewayAdd = Invoke-Cli @("gateway", "add", $expectedEndpoint, "--local", "--name", $GatewayName) -AllowFailure
324426
if ($gatewayAdd.Text) { Info $gatewayAdd.Text }
325-
if ($gatewayAdd.ExitCode -ne 0 -and $gatewayAdd.Text -notmatch '(?i)already exists') {
427+
if ($gatewayAdd.ExitCode -ne 0) {
326428
throw "gateway registration failed (exit $($gatewayAdd.ExitCode)): $($gatewayAdd.Text)"
327429
}
328430
$gatewaySelect = Invoke-Cli @("gateway", "select", $GatewayName)
@@ -364,6 +466,7 @@ finally {
364466
# Stop the gateway FIRST so it releases its log + JSONL file handles.
365467
if ($KeepRunning -and $gw -and -not $gw.HasExited) {
366468
Info "leaving gateway pid $($gw.Id) running (-KeepRunning); stop it with: Stop-Process -Id $($gw.Id) -Force"
469+
Info "CLI inspection endpoint: `$env:OPENSHELL_GATEWAY_ENDPOINT='http://127.0.0.1:$Port'"
367470
} elseif ($gw -and -not $gw.HasExited) {
368471
Step "Cleanup"
369472
Stop-Process -Id $gw.Id -Force -ErrorAction SilentlyContinue
@@ -382,6 +485,7 @@ finally {
382485
} else {
383486
$env:OPENSHELL_MXC_MOCK_WXC = $oldMockWxc
384487
}
488+
Exit-IsolatedCliEnvironment
385489

386490
# ---- summarise the OCSF audit trail --------------------------------------
387491
$logText = @()

‎crates/openshell-driver-mxc/tests/demo_examples.rs‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,25 @@ fn shipped_aggregate_e2e_assets_support_mock_wiring_validation() {
137137
assert!(runner.contains("not evidence of native MXC or OS enforcement"));
138138
}
139139

140+
#[test]
141+
fn shipped_runners_isolate_cli_state_and_gateway_overrides() {
142+
for name in ["run-mxc-e2e.ps1", "run-ocsf-audit.ps1"] {
143+
let runner = read_example(name);
144+
for required in [
145+
"Enter-IsolatedCliEnvironment",
146+
"Exit-IsolatedCliEnvironment",
147+
"APPDATA",
148+
"LOCALAPPDATA",
149+
"OPENSHELL_GATEWAY",
150+
"OPENSHELL_GATEWAY_ENDPOINT",
151+
"Remove-Item \"Env:$name\"",
152+
"CLI inspection endpoint:",
153+
] {
154+
assert!(runner.contains(required), "{name} is missing {required}");
155+
}
156+
}
157+
}
158+
140159
#[test]
141160
fn shipped_audit_and_websocket_configs_use_current_schema() {
142161
for name in ["mxc-ocsf-audit.toml", "mxc-ws-gateway.toml"] {

0 commit comments

Comments
 (0)