|
using namespace System.Collections.Generic |
|
|
|
# Write verbose messages on import |
|
if ((Get-PSCallStack)[1].Arguments -imatch 'Verbose=True') { $PSDefaultParameterValues['*:Verbose'] = $true } |
|
|
|
|
|
if ((Test-ApplicationExistsInPath -ApplicationName 'docker') -eq $false) { |
|
Write-Verbose 'docker does not exist in the Path. Skipping the import of docker ProfileUtility commands.' |
|
# Do not export any module commands. |
|
Export-ModuleMember |
|
exit |
|
} |
|
# https://github.com/PowerShell/PowerShell/issues/17730#issuecomment-1190678484 |
|
$ExportedMembers = [List[string]]::new() |
|
|
|
|
|
class MountPoint { |
|
<# |
|
.SYNOPSIS |
|
Holds the HostPath and ContainerPath for use connecting to a given docker image. |
|
#> |
|
[string]$HostPath |
|
[string]$ContainerPath |
|
|
|
MountPoint( |
|
[string]$hostPath = (Read-Host -Prompt 'Enter the local mount path'), |
|
[string]$containerPath = (Read-Host -Prompt 'Enter the containers mount path') |
|
) { |
|
$this.HostPath = $hostPath |
|
$this.ContainerPath = $containerPath |
|
} |
|
|
|
MountPoint() { |
|
$this.HostPath = Read-Host -Prompt 'Enter the local mount path' |
|
$this.ContainerPath = Read-Host -Prompt 'Enter the containers mount path' |
|
} |
|
|
|
[string]ToString() { return "-v ""$($this.HostPath)`:$($this.ContainerPath)"" " } |
|
} |
|
|
|
|
|
function New-MountPoint { |
|
<# |
|
.SYNOPSIS |
|
Create a new MountPoint object. |
|
|
|
.DESCRIPTION |
|
This function allows the user to create a new MountPoint object from the TM-DockerUtility module. |
|
MountPoint objects should be used with the Enter-DockerImageWithNewEntryPoint function's MountPoints parameter. |
|
|
|
.PARAMETER HostPath |
|
The path to a directory that exists on the local machine. |
|
|
|
.PARAMETER ContainerPath |
|
The path to create and mount the HostPath to inside the container. |
|
|
|
.EXAMPLE |
|
Enter-DockerImageWithNewEntryPoint -EntryPoint '/bin/bash' -DeleteDebugImage -MountPoints @( |
|
(New-MountPoint -HostPath 'C:\Path\To\Folder1' -ContainerPath '/workspace/Folder1'), |
|
(New-MountPoint -HostPath 'C:\Path\To\Folder2' -ContainerPath '/workspace/Folder2') |
|
) |
|
#> |
|
[CmdletBinding()] |
|
param ( |
|
[Parameter(Mandatory)] |
|
[Validation.ValidatePathExists('Folder')] |
|
[string]$HostPath, |
|
|
|
[Parameter(Mandatory)] |
|
[ValidateNotNullOrEmpty()] |
|
[string]$ContainerPath |
|
) |
|
|
|
return [MountPoint]::New($HostPath, $ContainerPath) |
|
} |
|
$ExportedMembers.Add('New-MountPoint') |
|
|
|
|
|
function Enter-DockerImageWithNewEntryPoint { |
|
<# |
|
.SYNOPSIS |
|
Enters a Docker container image with a new entry point. |
|
|
|
.DESCRIPTION |
|
This function allows you to enter a selected Docker container with a specified entry point. |
|
This can be useful if your containers default entrypoint is causing errors and the container |
|
will not stay running long enough for you to exec into it and debug the issue. |
|
|
|
.PARAMETER EntryPoint |
|
The entry point command to use with the debug image. |
|
If no EntryPoint is provided then the user will be prompt to enter an EntryPoint instead. |
|
|
|
.PARAMETER DeleteDebugImage |
|
A boolean value that indicates whether to delete the debug image after exiting the container. |
|
The default value is $true. |
|
|
|
.PARAMETER MountPoints |
|
An array of mount points to add to the Docker container. |
|
Use the New-MountPoint function to create new mountpoint objects. |
|
|
|
.EXAMPLE |
|
Enter-DockerImageWithNewEntryPoint -EntryPoint '/bin/bash' -DeleteDebugImage -MountPoints @( |
|
(New-MountPoint -HostPath 'C:\Path\To\Folder1' -ContainerPath '/workspace/Folder1'), |
|
(New-MountPoint -HostPath 'C:\Path\To\Folder2' -ContainerPath '/workspace/Folder2') |
|
) |
|
#> |
|
[CmdletBinding()] |
|
param ( |
|
[Parameter(Mandatory = $false)] |
|
[string]$EntryPoint = ( |
|
Read-Host -Prompt "Provide the entrypoint command to use with '$DebugName'.`nexample: /bin/bash "), |
|
|
|
[Parameter(Mandatory = $false)] |
|
[bool]$DeleteDebugImage = $true, |
|
|
|
[Parameter(Mandatory = $false)] |
|
[MountPoint[]]$MountPoints |
|
) |
|
|
|
if (($env:OS -eq 'Windows_NT') -and ($null -eq (Get-Process -Name 'Docker Desktop' -ErrorAction Ignore))) { |
|
Write-Warning -Message 'Start Docker Desktop before trying to enter a docker image' |
|
return |
|
} |
|
|
|
$DockerPSOut = docker ps -a --format '{{json .}}' | ConvertFrom-Json -ErrorAction Ignore |
|
|
|
# Exit early if there are no containers to copy and enter. |
|
if ($null -eq $DockerPSOut) { |
|
Write-Warning 'Docker did not return any output from the ''docker ps -a'' command.' |
|
return |
|
} |
|
|
|
Write-Host 'Select a container to enter:' |
|
$Count = 0 |
|
$Container = $DockerPSOut | ForEach-Object { |
|
Select-Object -InputObject $_ -Property @{n = '#'; e = { $Count } }, ID, Names, Status, Image |
|
$Count++ |
|
} | Out-GridView -Title 'Available Containers' -OutputMode Single |
|
|
|
# Make a copy of the selected container image |
|
$ContainerImage = $Container.Image.Split('/')[-1] |
|
$DebugName = "debug/$ContainerImage" |
|
docker commit $Container.ID $DebugName | Write-Host |
|
|
|
# Create start process arguments: |
|
$dockerMount = '' |
|
foreach ($MountPoint in $MountPoints) { |
|
$dockerMount += $MountPoint.ToString() |
|
} |
|
$StartDockerRun = @{ |
|
FilePath = 'docker' |
|
PassThru = $true |
|
Wait = $true |
|
NoNewWindow = $true |
|
ArgumentList = @('run', '-it', $dockerMount, '--rm', '--entrypoint', $EntryPoint, $DebugName) |
|
} |
|
|
|
# Run the process in a try block in case something in the container sends a terminating error. |
|
try { |
|
$Process = Start-Process @StartDockerRun |
|
if ($Process.ExitCode -ne 0) { |
|
Write-Warning "Docker ExitCode is not 0. ExitCode: $($Process.ExitCode)" |
|
} |
|
} finally { |
|
# Cleanup, Don't forget to delete the debug image if requested. |
|
if ($DeleteDebugImage) { |
|
$DockerImagesOut = docker images -a --format '{{json .}}' | ConvertFrom-Json -ErrorAction Ignore |
|
$ImageName = "$DebugName".Split(':')[0] |
|
$ImageId = $DockerImagesOut | Where-Object { $_.Repository -eq $ImageName } | Select-Object -ExpandProperty ID |
|
docker.exe image rm $ImageId |
|
} |
|
} |
|
} |
|
$ExportedMembers.Add('Enter-DockerImageWithNewEntryPoint') |
|
|
|
|
|
function Remove-DockerResources { |
|
<# |
|
.SYNOPSIS |
|
Removes Docker resources, including unused containers, networks, images, and optionally volumes. |
|
|
|
.DESCRIPTION |
|
This function removes unused Docker resources such as containers, networks, images, and optionally volumes. |
|
It serves as a cleanup tool to reset the docker environment state back to the default install state. |
|
|
|
.PARAMETER IncludeVolumes |
|
A boolean value that indicates whether to include volumes in the Docker resource removal. |
|
The default value is $true. |
|
#> |
|
[Alias('Prune-DockerResources')] |
|
[CmdletBinding()] |
|
[OutputType([Void])] |
|
param ( |
|
[Parameter(Mandatory = $false)] |
|
[bool]$IncludeVolumes = $true |
|
) |
|
|
|
[List[string]]$DockerArgs = [List[string]]::new() |
|
$DockerArgs.AddRange([string[]]@('system', 'prune', '--all', '--force')) |
|
if ($IncludeVolumes) { $DockerArgs.Add('--volumes') } |
|
docker @DockerArgs |
|
} |
|
$ExportedMembers.Add('Remove-DockerResources') |
|
|
|
|
|
Export-ModuleMember -Function $ExportedMembers.ToArray() |