diff --git a/AppHandling/Publish-NavContainerApp.ps1 b/AppHandling/Publish-NavContainerApp.ps1 index f3ebb534b..c26647df0 100644 --- a/AppHandling/Publish-NavContainerApp.ps1 +++ b/AppHandling/Publish-NavContainerApp.ps1 @@ -213,8 +213,8 @@ try { } $sslVerificationDisabled = ($protocol -eq "https://") if ($sslVerificationDisabled) { - Write-Host "Disabling SSL Verification" - $handler.ServerCertificateCustomValidationCallback = [SslVerification]::DisabledServerCertificateValidationCallback + Write-Host "Disabling SSL Verification on HttpClient" + [SslVerification]::DisableSsl($handler) } if ($customConfig.ClientServicesCredentialType -eq "Windows") { $handler.UseDefaultCredentials = $true @@ -286,13 +286,14 @@ try { throw $message } } + catch { + GetExtendedErrorMessage -errorRecord $_ | Out-Host + throw + } finally { $FileStream.Close() } - if ($sslverificationdisabled) { - Write-Host "Restoring SSL Verification" # no action required - only to enforce blocks consistency - } if ($bcContainerHelperConfig.NoOfSecondsToSleepAfterPublishBcContainerApp -gt 0) { # Avoid race condition Start-Sleep -Seconds $bcContainerHelperConfig.NoOfSecondsToSleepAfterPublishBcContainerApp diff --git a/ContainerHandling/Flush-ContainerHelperCache.ps1 b/ContainerHandling/Flush-ContainerHelperCache.ps1 index 1e412ec87..87c032a9b 100644 --- a/ContainerHandling/Flush-ContainerHelperCache.ps1 +++ b/ContainerHandling/Flush-ContainerHelperCache.ps1 @@ -14,6 +14,8 @@ - sandboxartifacts are artifacts downloaded for spinning up containers - images are images built on artifacts using New-BcImage or New-BcContainer - compilerFolders are folders used for Dockerless builds + - exitedContainers are containers which have been stopped + - all is all of the above (except for exited Containers) .Parameter keepDays When specifying a value in keepDays, the function will try to keep cached information, which has been used during the last keepDays days. Default is 0 - to flush all cache. .Example @@ -46,6 +48,33 @@ try { $artifactsCacheFolder = $bcContainerHelperConfig.bcartifactsCacheFolder $caches = $cache.ToLowerInvariant().Split(',') + if ($caches.Contains('exitedcontainers')) { + docker container ls --format "{{.ID}}:{{.Names}}" --no-trunc -a --filter "status=exited" | ForEach-Object { + $containerID = $_.Split(':')[0] + $containerName = $_.Split(':')[1] + $inspect = docker inspect $containerID | ConvertFrom-Json + try { + $finishedAt = [DateTime]::Parse($inspect.state.FinishedAt) + $exitedDaysAgo = [DateTime]::Now.Subtract($finishedAt).Days + if ($exitedDaysAgo -ge $keepDays) { + if (($inspect.Config.Labels.psobject.Properties.Match('maintainer').Count -ne 0 -and $inspect.Config.Labels.maintainer -eq "Dynamics SMB")) { + Write-Host "Removing container $containerName" + docker rm $containerID -f + } + else { + Write-Host "Container $containerName (exited $exitedDaysAgo day$(if($exitedDaysAgo -ne 1){'s'}) ago) is not recognized as a Business Central Container - not removing" + } + } + else { + Write-Host "Keeping container $containerName (exited $exitedDaysAgo day$(if($exitedDaysAgo -ne 1){'s'}) ago) - removing after $keepDays day$(if($keepDays -ne 1){'s'})" + } + } + catch { + # ignore any errors + } + } + } + $folders = @() if ($caches.Contains('all') -or $caches.Contains('calSourceCache')) { $folders += @("extensions\original-*-??","extensions\original-*-??-newsyntax") diff --git a/ContainerHandling/Remove-NavContainerSession.ps1 b/ContainerHandling/Remove-NavContainerSession.ps1 index c4c0f7371..c3bec2fd6 100644 --- a/ContainerHandling/Remove-NavContainerSession.ps1 +++ b/ContainerHandling/Remove-NavContainerSession.ps1 @@ -22,18 +22,29 @@ function Remove-BcContainerSession { Process { if ($sessions.ContainsKey($containerName)) { $session = $sessions[$containerName] - if ($killPsSessionProcess -and !$isInsideContainer) { - $inspect = docker inspect $containerName | ConvertFrom-Json - if ($inspect.HostConfig.Isolation -eq "process") { - $processID = Invoke-Command -Session $session -ScriptBlock { $PID } - Stop-Process -Id $processID -Force + 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 + } + } + 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($containerName) diff --git a/HelperFunctions.ps1 b/HelperFunctions.ps1 index 478f48afb..04efc8269 100644 --- a/HelperFunctions.ps1 +++ b/HelperFunctions.ps1 @@ -1,5 +1,5 @@ $useTimeOutWebClient = $false -if ($PSVersionTable.PSVersion -lt "6.0.0" -and !$useTimeOutWebClient) { +if ($PSVersionTable.PSVersion -lt "6.0.0" -or $useTimeOutWebClient) { $timeoutWebClientCode = @" using System.Net; @@ -23,31 +23,32 @@ if ($PSVersionTable.PSVersion -lt "6.0.0" -and !$useTimeOutWebClient) { } } "@; - - try { - Add-Type -TypeDefinition $timeoutWebClientCode -Language CSharp -WarningAction SilentlyContinue | Out-Null - $useTimeOutWebClient = $true - } - catch {} +if (-not ([System.Management.Automation.PSTypeName]"TimeoutWebClient").Type) { + Add-Type -TypeDefinition $timeoutWebClientCode -Language CSharp -WarningAction SilentlyContinue | Out-Null + $useTimeOutWebClient = $true +} } $sslCallbackCode = @" - using System.Net.Security; - using System.Security.Cryptography.X509Certificates; - - public static class SslVerification - { - public static bool DisabledServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } - public static void Disable() { System.Net.ServicePointManager.ServerCertificateValidationCallback = DisabledServerCertificateValidationCallback; } - public static void Enable() { System.Net.ServicePointManager.ServerCertificateValidationCallback = null; } - } +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; + +public static class SslVerification +{ + public static bool DisabledServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } + public static void Disable() { System.Net.ServicePointManager.ServerCertificateValidationCallback = DisabledServerCertificateValidationCallback; } + public static void Enable() { System.Net.ServicePointManager.ServerCertificateValidationCallback = null; } + public static void DisableSsl(System.Net.Http.HttpClientHandler handler) { handler.ServerCertificateCustomValidationCallback = DisabledServerCertificateValidationCallback; } +} "@ -try { - if (-not ([System.Management.Automation.PSTypeName]"SslVerification").Type) { +if (-not ([System.Management.Automation.PSTypeName]"SslVerification").Type) { + if ($isPsCore) { Add-Type -TypeDefinition $sslCallbackCode -Language CSharp -WarningAction SilentlyContinue | Out-Null } + else { + Add-Type -TypeDefinition $sslCallbackCode -Language CSharp -ReferencedAssemblies @('System.Net.Http') -WarningAction SilentlyContinue | Out-Null + } } -catch {} function Get-DefaultCredential { Param( @@ -1039,8 +1040,8 @@ function DownloadFileLow { $handler = New-Object System.Net.Http.HttpClientHandler if ($skipCertificateCheck) { - Write-Host "Disabling SSL Verification" - $handler.ServerCertificateCustomValidationCallback = [SslVerification]::DisabledServerCertificateValidationCallback + Write-Host "Disabling SSL Verification on HttpClient" + [SslVerification]::DisableSsl($handler) } if ($useDefaultCredentials) { $handler.UseDefaultCredentials = $true @@ -1071,9 +1072,6 @@ function DownloadFileLow { if ($stream) { $stream.Dispose() } - if ($skipCertificateCheck) { - Write-Host "Restoring SSL Verification" # no action required - only to enforce blocks consistency - } } } } diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index fe01b186d..967732aae 100644 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -1,4 +1,7 @@ 5.0.5 +Add new option (exitedContainers) on Flush-ContainerHelperCache. Note that exited containers are NOT remove by the all flag, you need all,exitedContainers +Add resilience to Remove-BcContainerSession +Issue #3116 Publish-NavContainerApp: Exception setting "ServerCertificateCustomValidationCallback": "Cannot convert the "static bool DisabledServerCertificateValidationCallback Add new parameter -useEnvironmentUpdateWindow to Install-BcAppFromAppSource, to schedule installation of apps to run inside update window 5.0.4