Skip to content

Commit

Permalink
Fix for missing linux executables and hanging PSSessions (#3698)
Browse files Browse the repository at this point in the history
Fix issue where linux executables are missing in the AL Language
Extension (use dotnet to execute the commands instead)

Fix issue where PowerShell sometimes hangs when trying to establish a
new PSSession shortly after removing another PSSession (Noticed during
end 2 end tests on AL-Go for GitHub)

---------

Co-authored-by: freddydk <[email protected]>
  • Loading branch information
freddydk and freddydk authored Oct 4, 2024
1 parent e77f25b commit a776b3a
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 61 deletions.
5 changes: 1 addition & 4 deletions AppHandling/Run-TestsInNavContainer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ try {
$navversion = Get-BcContainerNavversion -containerOrImageName $containerName
$version = [System.Version]($navversion.split('-')[0])
$PsTestToolFolder = Join-Path $bcContainerHelperConfig.hostHelperFolder "Extensions\$containerName\PsTestTool"

}
elseif ($compilerFolder) {
Write-Host "Using CompilerFolder"
Expand Down Expand Up @@ -318,7 +317,6 @@ try {
if ($containerName) {
if (!((Test-Path $newtonSoftDllPath) -and (Test-Path $clientDllPath))) {
Invoke-ScriptInBcContainer -containerName $containerName { Param([string] $myNewtonSoftDllPath, [string] $myClientDllPath)

if (!(Test-Path $myNewtonSoftDllPath)) {
$newtonSoftDllPath = "C:\Program Files\Microsoft Dynamics NAV\*\Service\Management\Newtonsoft.Json.dll"
if (!(Test-Path $newtonSoftDllPath)) {
Expand Down Expand Up @@ -410,7 +408,6 @@ try {
}
}
else {

$containerXUnitResultFileName = ""
if ($XUnitResultFileName) {
$containerXUnitResultFileName = Get-BcContainerPath -containerName $containerName -path $XUnitResultFileName
Expand Down Expand Up @@ -475,7 +472,7 @@ try {
if ($profile) {
$serviceUrl += "&profile=$([Uri]::EscapeDataString($profile))"
}

. $PsTestFunctionsPath -newtonSoftDllPath $newtonSoftDllPath -clientDllPath $clientDllPath -clientContextScriptPath $ClientContextPath

Write-Host "Connecting to $serviceUrl"
Expand Down
6 changes: 6 additions & 0 deletions CompilerFolderHandling/Compile-AppWithBcCompilerFolder.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,12 @@ try {
}
}

if (!(Test-Path -Path (Join-Path $alcPath $alcExe))) {
$alcCmd = "dotnet"
$alcExe = 'alc.dll'
$alcParameters += @((Join-Path $alcPath $alcExe))
Write-Host "No alc executable in $compilerPlatform. Using dotnet to run alc.dll."
}
$alcItem = Get-Item -Path (Join-Path $alcPath $alcExe)
[System.Version]$alcVersion = $alcItem.VersionInfo.FileVersion

Expand Down
40 changes: 16 additions & 24 deletions ContainerHandling/Get-NavContainerSession.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,29 @@ function Get-BcContainerSession {
Process {
$newsession = $false
$session = $null
if ($sessions.ContainsKey($containerName)) {
$session = $sessions[$containerName]
[System.Version]$platformVersion = Get-BcContainerPlatformVersion -containerOrImageName $containerName
if ($platformVersion.Major -lt 24) {
$usePwsh = $false
}
$configurationName = 'Microsoft.PowerShell'
if ($usePwsh) {
$configurationName = 'PowerShell.7'
}
$cacheName = "$containerName-$configurationName"
if ($sessions.ContainsKey($cacheName)) {
$session = $sessions[$cacheName]
try {
$platformVersion = Invoke-Command -Session $session -ScriptBlock { [System.Version](get-item 'C:\Program Files\Microsoft Dynamics NAV\*\Service\Microsoft.Dynamics.Nav.Server.exe').Versioninfo.FileVersion }
if ($platformVersion.Major -ge 24 -and ($usePwsh -xor $session.ConfigurationName -eq 'PowerShell.7')) {
# Cannot use existing session
Remove-PSSession -Session $session
$sessions.Remove($containerName)
$session = $null
}
else {
if (!$reinit) {
return $session
}
Invoke-Command -Session $session -ScriptBlock { $PID } | Out-Null
if (!$reinit) {
return $session
}
}
catch {
Remove-PSSession -Session $session
$sessions.Remove($containerName)
$sessions.Remove($cacheName)
$session = $null
}
}
if (!$session) {
[System.Version]$platformVersion = Get-BcContainerPlatformVersion -containerOrImageName $containerName
if ($platformVersion.Major -lt 24) {
$usePwsh = $false
}
$configurationName = 'Microsoft.PowerShell'
if ($usePwsh) {
$configurationName = 'PowerShell.7'
}
if ($isInsideContainer) {
$session = New-PSSession -Credential $bcContainerHelperConfig.WinRmCredentials -ComputerName $containerName -Authentication Basic -UseSSL -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck)
}
Expand Down Expand Up @@ -118,7 +110,7 @@ function Get-BcContainerSession {
Set-Location $runPath
} -ArgumentList $silent
if ($newsession) {
$sessions.Add($containerName, $session)
$sessions.Add($cacheName, $session)
}
return $session
}
Expand Down
38 changes: 20 additions & 18 deletions ContainerHandling/Remove-NavContainerSession.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,36 @@ function Remove-BcContainerSession {
)

Process {
if ($sessions.ContainsKey($containerName)) {
$session = $sessions[$containerName]
try {
if ($killPsSessionProcess -and !$isInsideContainer) {
$inspect = docker inspect $containerName | ConvertFrom-Json
if ($inspect.HostConfig.Isolation -eq "process") {
try {
$processID = Invoke-Command -Session $session -ScriptBlock { $PID }
Stop-Process -Id $processID -Force
foreach($configurationName in @('Microsoft.PowerShell','PowerShell.7')) {
$cacheName = "$containerName-$configurationName"
if ($sessions.ContainsKey($cacheName)) {
$session = $sessions[$cacheName]
try {
if ($killPsSessionProcess -and !$isInsideContainer) {
$inspect = docker inspect $containerName | ConvertFrom-Json
if ($inspect.HostConfig.Isolation -eq "process") {
try {
$processID = Invoke-Command -Session $session -ScriptBlock { $PID }
Stop-Process -Id $processID -Force
}
catch {
Write-Host "Error killing process in container"
Remove-PSSession -Session $session
}
}
catch {
Write-Host "Error killing process in container"
else {
Remove-PSSession -Session $session
}
}
else {
Remove-PSSession -Session $session
}
}
else {
Remove-PSSession -Session $session
catch {
Write-Host "Error removing session for container"
}
$sessions.Remove($cacheName)
}
catch {
Write-Host "Error removing session for container"
}

$sessions.Remove($containerName)
}
}
}
Expand Down
69 changes: 54 additions & 15 deletions HelperFunctions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1053,25 +1053,45 @@ function GetAppInfo {
}
Write-GroupStart -Message "Getting .app info $cacheAppInfoPath"
$binPath = Join-Path $compilerFolder 'compiler/extension/bin'
$alToolDll = ''
if ($isLinux) {
$alcPath = Join-Path $binPath 'linux'
$alToolExe = Join-Path $alcPath 'altool'
& /usr/bin/env sudo pwsh -command "& chmod +x $alToolExe"
$command = Join-Path $alcPath 'altool'
if (Test-Path $command) {
Write-Host "Setting execute permissions on altool"
& /usr/bin/env sudo pwsh -command "& chmod +x $command"
$alToolExists = $true
}
else {
Write-Host "No altool executable found. Using dotnet to run altool.dll."
$command = 'dotnet'
$alToolDll = Join-Path $alcPath 'altool.dll'
$alToolExists = Test-Path -Path $alToolDll -PathType Leaf
}
}
elseif ($isMacOS) {
$alcPath = Join-Path $binPath 'darwin'
$alToolExe = Join-Path $alcPath 'altool'
Write-Host "Setting execute permissions on altool"
& chmod +x $alToolExe
$command = Join-Path $alcPath 'altool'
if (Test-Path $command) {
Write-Host "Setting execute permissions on altool"
& chmod +x $command
$alToolExists = $true
}
else {
Write-Host "No altool executable found. Using dotnet to run altool.dll."
$command = 'dotnet'
$alToolDll = Join-Path $alcPath 'altool.dll'
$alToolExists = Test-Path -Path $alToolDll -PathType Leaf
}
}
else {
$alcPath = Join-Path $binPath 'win32'
$alToolExe = Join-Path $alcPath 'altool.exe'
$command = Join-Path $alcPath 'altool.exe'
$alToolExists = Test-Path -Path $command -PathType Leaf
}
if (-not (Test-Path $alcPath)) {
$alcPath = $binPath
}
$alToolExists = Test-Path -Path $alToolExe -PathType Leaf
$alcDllPath = $alcPath
if (!($isLinux -or $isMacOS) -and !$isPsCore) {
$alcDllPath = $binPath
Expand All @@ -1091,7 +1111,11 @@ function GetAppInfo {
}
else {
if ($alToolExists) {
$manifest = CmdDo -Command $alToolExe -arguments @('GetPackageManifest', """$path""") -returnValue -silent | ConvertFrom-Json
$arguments = @('GetPackageManifest', """$path""")
if ($alToolDll) {
$arguments = @($alToolDll) + $arguments
}
$manifest = CmdDo -Command $command -arguments $arguments -returnValue -silent | ConvertFrom-Json
$appInfo = @{
"appId" = $manifest.id
"publisher" = $manifest.publisher
Expand Down Expand Up @@ -1280,18 +1304,33 @@ function RunAlTool {
)
$path = DownloadLatestAlLanguageExtension -allowPrerelease:$usePrereleaseAlTool
if ($isLinux) {
$alToolExe = Join-Path $path 'extension/bin/linux/altool'
& /usr/bin/env sudo pwsh -command "& chmod +x $alToolExe"
$command = Join-Path $path 'extension/bin/linux/altool'
if (Test-Path $command) {
Write-Host "Setting execute permissions on altool"
& /usr/bin/env sudo pwsh -command "& chmod +x $command"
}
else {
Write-Host "No altool executable found. Using dotnet to run altool.dll."
$command = 'dotnet'
$arguments = @(Join-Path $path 'extension/bin/linux/altool.dll') + $arguments
}
}
elseif ($isMacOS) {
$alToolExe = Join-Path $path 'extension/bin/darwin/altool'
Write-Host "Setting execute permissions on altool"
& chmod +x $alToolExe
$command = Join-Path $path 'extension/bin/darwin/altool'
if (Test-Path $command) {
Write-Host "Setting execute permissions on altool"
& chmod +x $command
}
else {
Write-Host "No altool executable found. Using dotnet to run altool.dll."
$command = 'dotnet'
$arguments = @(Join-Path $path 'extension/bin/darwin/altool.dll') + $arguments
}
}
else {
$alToolExe = Join-Path $path 'extension/bin/win32/altool.exe'
$command = Join-Path $path 'extension/bin/win32/altool.exe'
}
CmdDo -Command $alToolExe -arguments $arguments -returnValue -silent
CmdDo -Command $command -arguments $arguments -returnValue -silent
}

function GetApplicationDependency( [string] $appFile, [string] $minVersion = "0.0" ) {
Expand Down
2 changes: 2 additions & 0 deletions ReleaseNotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Fix issue where generateDependencyArtifact doesn't result in dependencies if useCompilerFolder is true or filesonly containers are used in Run-AlPipeline
Issue 3686 PowerShell container shortcuts for >= BC24 using wrong PowerShell version
Issue 3666 Run-AlCops + Run-AlPipeline using outdated appsource default ruleset
Fix issue where linux executables are missing in the AL Language Extension (use dotnet to execute the commands instead)
Fix issue where PowerShell sometimes hangs when trying to establish a new PSSession shortly after removing another PSSession (Noticed during end 2 end tests on AL-Go for GitHub)

6.0.24
Use pre-release altool when running alcops (to be able to get runtime version of nextmajor)
Expand Down

0 comments on commit a776b3a

Please sign in to comment.