Modules/businessdev.ALbuild.Containers/Private/Get-BcContainerEnterArgument.ps1
|
function Get-BcContainerEnterArgument { <# .SYNOPSIS The 'docker exec' argument list for an interactive shell inside a container. .DESCRIPTION Split out from Enter-BcContainer because it is the only part that can be tested: the cmdlet itself hands the console to another process, which a test cannot do anything useful with. Pure - it builds a string array and touches nothing. '-it' is what makes the session interactive: '-i' keeps stdin attached, '-t' allocates a pseudo-terminal so the remote shell draws a prompt and line editing works. Without '-t' the shell runs but shows nothing and looks hung. '-NoExit' is the point of the whole thing: the setup command runs and the prompt stays. Without it the shell would execute the setup and exit immediately. .PARAMETER ContainerName Container to enter. .PARAMETER PowerShellExe The in-container shell, from Get-BcContainerPowerShellExe. .PARAMETER Command Optional command to run before the prompt appears. .PARAMETER WorkingDirectory Where the session starts. Default 'C:\run', which is where the generic image keeps its scripts. .PARAMETER SkipPrompt Do not dot-source the image's prompt.ps1 even when it exists. .OUTPUTS System.String[] - the arguments for the Docker executable. #> [CmdletBinding()] [OutputType([string[]])] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $ContainerName, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $PowerShellExe, [string] $Command, [string] $WorkingDirectory = 'C:\run', [switch] $SkipPrompt ) $setup = [System.Collections.Generic.List[string]]::new() # -LiteralPath, and only if it is there: a container whose working directory does not exist should # still give a usable shell rather than an error before the prompt. if ($WorkingDirectory) { $setup.Add("if (Test-Path -LiteralPath '$($WorkingDirectory.Replace("'", "''"))') { Set-Location -LiteralPath '$($WorkingDirectory.Replace("'", "''"))' }") } # The generic image ships C:\Run\prompt.ps1, which is what makes an interactive BC container feel # familiar. Guarded rather than assumed: it is an image detail, not a contract, and an image without # it must still open a shell. if (-not $SkipPrompt) { $setup.Add("if (Test-Path -LiteralPath 'C:\Run\prompt.ps1') { . 'C:\Run\prompt.ps1' }") } if ($Command) { $setup.Add($Command) } $arguments = @('exec', '-it', $ContainerName, $PowerShellExe, '-NoLogo') if ($setup.Count -gt 0) { # Not -EncodedCommand: with -NoExit an encoded command leaves the session in a state where the # prompt is drawn but the host's own initialisation has been skipped. A plain -Command keeps the # normal interactive host behaviour, and everything here is generated, not user text. $arguments += @('-NoExit', '-Command', ($setup -join '; ')) } return , [string[]]$arguments } |