Private/State/NAVGitContainerState.ps1
|
function Get-NAVGitContainerStatePath { [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [string] $ContainerName ) return Join-Path (Get-NAVGitDataPath -Name 'containers') "$ContainerName.json" } function Get-NAVGitContainerState { <# .SYNOPSIS Reads the saved state of a container (%LOCALAPPDATA%\NAVGit\containers\<name>.json), or $null when there is none. #> [CmdletBinding()] [OutputType([hashtable])] param( [Parameter(Mandatory)] [string] $ContainerName ) $path = Get-NAVGitContainerStatePath -ContainerName $ContainerName if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { return $null } return ConvertTo-NAVGitHashtable (Get-Content -LiteralPath $path -Raw -Encoding UTF8 | ConvertFrom-Json) } function Save-NAVGitContainerState { <# .SYNOPSIS Reads the container's server configuration (requires elevation and BcContainerHelper) and saves everything the client commands need, so those can later run without elevation or docker access. testsImported is only written when -TestsImported is given; see Test-NAVGitTestsImported. #> [CmdletBinding()] [OutputType([hashtable])] param( [Parameter(Mandatory)] [hashtable] $Config, [string] $ArtifactUrl, [string] $BackupPath, [bool] $TestsImported ) $containerName = $Config.containerName $server = Get-BcContainerServerConfiguration -ContainerName $containerName if (-not $server -or -not $server.ServerInstance) { throw "Could not read the server configuration of container '$containerName'." } if (-not $ArtifactUrl) { $ArtifactUrl = Get-BcContainerArtifactUrl -containerName $containerName } # "11.0.43274.0-no" $navVersion = (Get-BcContainerNavVersion -containerOrImageName $containerName) -replace '-.*$', '' $state = [ordered]@{ containerName = $containerName repositoryPath = $Config.repositoryPath artifactUrl = $ArtifactUrl navVersion = $navVersion backupFile = $BackupPath auth = $server.ClientServicesCredentialType serverInstance = $server.ServerInstance databaseServer = $server.DatabaseServer databaseInstance = $server.DatabaseInstance databaseName = $server.DatabaseName hostDatabaseServer = Get-NAVGitHostDatabaseServer -ContainerName $containerName -DatabaseServer $server.DatabaseServer -DatabaseInstance $server.DatabaseInstance clientServicesPort = [int]$server.ClientServicesPort managementServicesPort = [int]$server.ManagementServicesPort enableSymbolLoading = ($server.EnableSymbolLoadingAtServerStartup -eq 'True') clientFolder = Get-NAVGitClientFolder -ContainerName $containerName savedAt = (Get-Date).ToString('o') } if ($PSBoundParameters.ContainsKey('TestsImported')) { $state.testsImported = $TestsImported } $path = Get-NAVGitContainerStatePath -ContainerName $containerName $state | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $path -Encoding UTF8 Write-NAVGitLog "Container state saved to $path" -Level Detail return Get-NAVGitContainerState -ContainerName $containerName } function Set-NAVGitContainerStateValue { <# .SYNOPSIS Sets one value in the saved state of a container. Does nothing when there is no saved state: a partial state file would make the client commands fail with a misleading message. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string] $ContainerName, [Parameter(Mandatory)] [string] $Name, $Value ) $path = Get-NAVGitContainerStatePath -ContainerName $ContainerName if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { Write-NAVGitLog "No saved state for '$ContainerName', so $Name was not saved. Run Update-NAVGitContainerState to create it." -Level Detail return } # Kept as PSCustomObject so the property order of the file stays the same. $state = Get-Content -LiteralPath $path -Raw -Encoding UTF8 | ConvertFrom-Json $current = $state.PSObject.Properties[$Name] if ($current -and $current.Value -eq $Value) { return } $state | Add-Member -NotePropertyName $Name -NotePropertyValue $Value -Force $state | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $path -Encoding UTF8 } function Test-NAVGitTestsImported { <# .SYNOPSIS True when the objects in the Tests folder have been imported into the container (testsImported in the saved state, set by Import-NAVGitObjects and Import-NAVGitTestToolkit). Without the value - a state saved by an older NAVGit, or no state at all - includeTestToolkit decides, as that is what earlier imports went by. #> [CmdletBinding()] [OutputType([bool])] param( [Parameter(Mandatory)] [string] $ContainerName, [Parameter(Mandatory)] [hashtable] $Config ) $state = Get-NAVGitContainerState -ContainerName $ContainerName if ($state -and $state.ContainsKey('testsImported')) { return [bool]$state.testsImported } return [bool]$Config.includeTestToolkit } function Remove-NAVGitContainerState { [CmdletBinding()] param( [Parameter(Mandatory)] [string] $ContainerName ) $path = Get-NAVGitContainerStatePath -ContainerName $ContainerName if (Test-Path -LiteralPath $path -PathType Leaf) { Remove-Item -LiteralPath $path -Force } } function Get-NAVGitHostDatabaseServer { <# .SYNOPSIS SQL server name as seen from the host, using the same rules as BcContainerHelper's C/SIDE shortcut: a database on localhost\SQLEXPRESS inside the container is reached as '<containerName>' from the host. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [string] $ContainerName, [string] $DatabaseServer, [string] $DatabaseInstance ) if ($DatabaseServer -eq 'host.containerhelper.internal') { $server = 'localhost' if ($DatabaseInstance) { $server += "\$DatabaseInstance" } return $server } if (-not $DatabaseServer -or $DatabaseServer -eq 'localhost') { $server = $ContainerName if ($DatabaseInstance -and $DatabaseInstance -ne 'SQLEXPRESS') { $server += "\$DatabaseInstance" } return $server } $server = $DatabaseServer if ($DatabaseInstance) { $server += "\$DatabaseInstance" } return $server } function Get-NAVGitClientFolder { <# .SYNOPSIS Host folder with the Windows client and finsql.exe, copied there by New-BcContainer -includeCSide: <hostHelperFolder>\Extensions\<container>\Program Files\<version>\RoleTailored Client. $null when missing. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [string] $ContainerName, [string] $HostHelperFolder ) if (-not $HostHelperFolder) { $helperConfig = Get-Variable -Name bcContainerHelperConfig -Scope Global -ValueOnly -ErrorAction SilentlyContinue if ($helperConfig -and $helperConfig.hostHelperFolder) { $HostHelperFolder = $helperConfig.hostHelperFolder } else { $HostHelperFolder = Join-Path $env:ProgramData 'BcContainerHelper' } } $programFiles = Join-Path $HostHelperFolder "Extensions\$ContainerName\Program Files" $folder = Get-Item -Path (Join-Path $programFiles '*\RoleTailored Client') -ErrorAction SilentlyContinue | Select-Object -First 1 if ($folder) { return $folder.FullName } return $null } |