Skip to content

Refactor Show-ContainerTools to add flag -ToolName (2/4) #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 12, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .textlintrc.json
Original file line number Diff line number Diff line change
@@ -25,8 +25,11 @@
"/Cmdlet/gi",
"cni",
"/Containerd/gi",
"/buildctl/gi",
"/BuildctlPath/gi",
"/BuildKit/gi",
"/buildkitd/gi",
"/DaemonStatus/gi",
"/H(ost)?N(etworking)?S(ervice)?/g",
"/Hyper[\\s-]?V/g",
"/moby/gi",
@@ -39,6 +42,7 @@
"/unregisters/gi",
"WinCNIPlugin",
// Parameter names
"ToolName",
"DownloadPath",
"InstallPath",
"LatestVersion",
121 changes: 108 additions & 13 deletions Tests/AllToolsUtilities.Tests.ps1
Original file line number Diff line number Diff line change
@@ -30,26 +30,121 @@ Describe "AllToolsUtilities.psm1" {

Context "Show-ContainerTools" -Tag "Show-ContainerTools" {
BeforeAll {
Mock Get-InstalledVersion -ModuleName 'AllToolsUtilities'
# Mock get version
$mockConfigStdOut = New-MockObject -Type 'System.IO.StreamReader' -Methods @{ ReadToEnd = { return "tool version v1.0.1" } }
$mockConfigProcess = New-MockObject -Type 'System.Diagnostics.Process' -Properties @{
ExitCode = 0
StandardOutput = $mockConfigStdOut
}
Mock Invoke-ExecutableCommand -ModuleName "AllToolsUtilities" `
-ParameterFilter { $Arguments -eq "--version" } `
-MockWith { return $mockConfigProcess }
}

It "Should get containerd version" {
$executablePath = "TestDrive:\Program Files\Containerd\bin\containerd.exe"
Mock Get-Command -ModuleName 'AllToolsUtilities' -MockWith { @{ Name = 'containerd.exe'; Source = $executablePath } }
Mock Get-Service -ModuleName 'AllToolsUtilities'

$containerdVersion = Show-ContainerTools -ToolName 'containerd'

# Check the output
$expectedOutput = [PSCustomObject]@{
Tool = 'containerd'
Path = $executablePath
Installed = $true
Version = 'v1.0.1'
Daemon = 'containerd'
DaemonStatus = 'Unregistered'
}
# $containerdVersion | Should -Be $expectedOutput
# HACK: Should -Be does not work with PSCustomObject in PSv5.
# However PSv6 has support for this. To be investigated further.
foreach ($key in $expectedOutput.Keys) {
$expectedValue = $expectedOutput[$key]
$actualValue = $containerdVersion.$key
$actualValue | Should -Be $expectedValue
}

# Check the invocation
Should -Invoke Get-Command -ModuleName 'AllToolsUtilities' `
-Times 1 -Exactly -Scope It -ParameterFilter { $Name -eq 'containerd.exe' }
}

It "Should get buildkit version" {
$executablePath = "TestDrive:\Program Files\Buildkit\bin\buildkitd.exe"
$buildctlPath = "TestDrive:\Program Files\Buildkit\bin\buildctl.exe"

Mock Get-Service -ModuleName 'AllToolsUtilities' -MockWith { @{ Status = "Running" } }
Mock Get-Command -ModuleName 'AllToolsUtilities' -MockWith { @(
@{ Name = 'buildkitd.exe'; Source = $executablePath }
@{ Name = 'buildctl.exe'; Source = $buildctlPath }
) }

$buildkitVersion = Show-ContainerTools -ToolName 'buildkit'

# Check the output
$expectedOutput = [PSCustomObject]@{
Tool = 'buildkit'
Path = $executablePath
Installed = $true
Version = 'v1.0.1'
Daemon = 'buildkitd'
DaemonStatus = 'Running'
BuildctlPath = $buildctlPath
}
foreach ($key in $expectedOutput.Keys) {
$expectedValue = $expectedOutput[$key]
$actualValue = $buildkitVersion.$key
$actualValue | Should -Be $expectedValue
}

# Check the invocation
Should -Invoke Get-Command -ModuleName 'AllToolsUtilities' `
-Times 1 -Exactly -Scope It -ParameterFilter { $Name -eq "build*.exe" }
}

It "Should list all container tools and their install status" {
Show-ContainerTools
It "Should return basic info if the tool is not installed" {
Mock Get-Command -ModuleName 'AllToolsUtilities'

@("containerd", "buildkit", "nerdctl") | ForEach-Object {
Should -Invoke Get-InstalledVersion -ModuleName 'AllToolsUtilities' `
-Times 1 -Exactly -Scope It `
-ParameterFilter { $Feature -eq $_ }
$toolInfo = Show-ContainerTools

# Check the output
$expectedOutput = @(
[PSCustomObject]@{ Tool = 'containerd'; Installed = $false; Daemon = 'containerd'; DaemonStatus = 'Unregistered' }
[PSCustomObject]@{ Tool = 'buildkit'; Installed = $false; Daemon = 'buildkitd'; DaemonStatus = 'Unregistered' }
[PSCustomObject]@{ Tool = 'nerdctl'; Installed = $false }
)
$expectedOutput | ForEach-Object {
$tool = $_.Tool
$actualOutput = $toolInfo | Where-Object { $_.Tool -eq $tool }
foreach ($key in $_.Keys) {
$expectedValue = $_[$key]
$actualValue = $actualOutput.$key
$actualValue | Should -Be $expectedValue
}
}
}

It "Should list the latest available version for each tool" {
Show-ContainerTools -Latest
It "Should return latest version if Latest flag is specified" {
Mock Get-Command -ModuleName 'AllToolsUtilities'

$toolInfo = Show-ContainerTools -Latest

@("containerd", "buildkit", "nerdctl") | ForEach-Object {
Should -Invoke Get-InstalledVersion -ModuleName 'AllToolsUtilities' `
-Times 1 -Exactly -Scope It `
-ParameterFilter { $Feature -eq $_ -and $Latest -eq $true }
# Check the output
$expectedOutput = @(
[PSCustomObject]@{ Tool = 'containerd'; Installed = $false; Daemon = 'buildkitd'; DaemonStatus = 'Unregistered'; LatestVersion = 'v1.0.1' }
[PSCustomObject]@{ Tool = 'buildkit'; Installed = $false; Daemon = 'buildkitd'; DaemonStatus = 'Unregistered'; LatestVersion = 'v1.0.1' }
[PSCustomObject]@{ Tool = 'nerdctl'; Installed = $false; LatestVersion = 'v1.0.1' }
)
$expectedOutput | ForEach-Object {
$tool = $_.Tool
$actualOutput = $toolInfo | Where-Object { $_.Tool -eq $tool }
foreach ($key in $_.Keys) {
$expectedValue = $_[$key]
$actualValue = $actualOutput.$key
$actualValue | Should -Be $expectedValue
}
}
}
}
50 changes: 36 additions & 14 deletions containers-toolkit/Public/AllToolsUtilities.psm1
Original file line number Diff line number Diff line change
@@ -14,10 +14,14 @@ Import-Module -Name "$ModuleParentPath\Private\CommonToolUtilities.psm1" -Force
function Show-ContainerTools {
param (
[Parameter(HelpMessage = "Show latest release version")]
[Switch]$Latest
[Switch]$Latest,

[Parameter(HelpMessage = "Tool to show")]
[ValidateSet("containerd", "buildkit", "nerdctl")]
[String[]]$ToolName
)

$tools = @("containerd", "buildkit", "nerdctl")
$tools = if ($ToolName) { $ToolName } else { @("containerd", "buildkit", "nerdctl") }

$installedTools = @()
foreach ($tool in $tools) {
@@ -173,21 +177,27 @@ To register containerd and buildkitd services and create a NAT network, see help
}

function Get-InstalledVersion($feature, $Latest) {
$executable = $null
$sourceLocation = $null
$daemon = $null
$buildctlPath = $null
switch ($feature) {
"buildkit" {
$bktdExecutable = (Get-Command "build*.exe" | Where-Object { $_.Source -like "*buildkit*" }) | Select-Object Name
if ($bktdExecutable) {
$executable = ($bktdExecutable[0]).Name
$blktCommandInfo = Get-Command "build*.exe" | Where-Object { $_.Source -like "*buildkit*" }
if ($null -ne $blktCommandInfo) {
# Get buildkitd executable
$buldkitdCommandInfo = $blktCommandInfo | Where-Object { $_.Name -like "buildkitd.exe" }
$sourceLocation = $buldkitdCommandInfo.Source
}
$daemon = 'buildkitd'

if ($null -ne ($bktdExecutable | Where-Object { $_.Name -contains "buildkitd.exe" })) {
$daemon = 'buildkitd'
}
$buildctlPath = ($blktCommandInfo | Where-Object { $_.Name -like "buildctl.exe" }).Source
}
Default {
$executable = (Get-Command "$feature.exe" -ErrorAction Ignore).Name
$commandInfo = Get-Command "$feature.exe" -ErrorAction Ignore

if ($null -ne $commandInfo) {
$sourceLocation = $commandInfo.Source
}

if ($feature -eq 'containerd') {
$daemon = 'containerd'
@@ -199,16 +209,21 @@ function Get-InstalledVersion($feature, $Latest) {
Tool = $feature
Installed = $False
}
if ($executable) {
$result = getToolVersion -Executable $executable
if ($sourceLocation) {
$result = getToolVersion -Executable $sourceLocation
Add-Member -InputObject $result -Name 'Tool' -Value $feature -MemberType 'NoteProperty'
$result = $result | Select-Object Tool, Installed, Version
Add-Member -InputObject $result -Name 'Path' -Value $sourceLocation -MemberType 'NoteProperty'
$result = $result | Select-Object Tool, Path, Installed, Version

if ($daemon) {
Add-Member -InputObject $result -Name 'Daemon' -Value $daemon -MemberType 'NoteProperty'
Add-Member -InputObject $result -Name 'DaemonStatus' -MemberType 'NoteProperty' `
-Value (getDaemonStatus -Daemon $daemon)
}

if ($buildctlPath) {
$result | Add-Member -Name 'BuildctlPath' -Value $buildctlPath -MemberType 'NoteProperty'
}
}

# Get latest version
@@ -223,9 +238,16 @@ function Get-InstalledVersion($feature, $Latest) {
}

function getToolVersion($executable) {
$toolName = [System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetFileName($executable))

$installedVersion = $null
try {
$version = & $executable -v
$cmdOutput = Invoke-ExecutableCommand -Executable $executable -Arguments '--version'
if ($cmdOutput.ExitCode -ne 0) {
Throw "Couldn't get $toolName version. $($cmdOutput.StandardError.ReadToEnd())"
}

$version = $cmdOutput.StandardOutput.ReadToEnd()

$pattern = "(\d+\.)(\d+\.)(\*|\d+)"
$installedVersion = ($version | Select-String -Pattern $pattern).Matches.Value
3 changes: 3 additions & 0 deletions containers-toolkit/Public/ContainerNetworkTools.psm1
Original file line number Diff line number Diff line change
@@ -12,6 +12,9 @@ using module "..\Private\CommonToolUtilities.psm1"
$ModuleParentPath = Split-Path -Parent $PSScriptRoot
Import-Module -Name "$ModuleParentPath\Private\CommonToolUtilities.psm1" -Force

$WINCNI_PLUGIN_REPO = "microsoft/windows-container-networking"
$CLOUDNATIVE_CNI_REPO = "containernetworking/plugins"

function Get-WinCNILatestVersion {
param (
[String]$repo = "microsoft/windows-container-networking"
26 changes: 12 additions & 14 deletions containers-toolkit/Public/NerdctlTools.psm1
Original file line number Diff line number Diff line change
@@ -81,14 +81,13 @@ function Install-Nerdctl {
$OSArchitecture = $env:PROCESSOR_ARCHITECTURE,

[Switch]
[parameter(HelpMessage = "Installs nerdctl (and its dependecies if specified) even if the tool already exists at the specified path")]
[parameter(HelpMessage = "Installs nerdctl (and its dependencies if specified) even if the tool already exists at the specified path")]
$Force
)

begin {
# Check if Containerd is alread installed
# Check if nerdctl is already installed
$isInstalled = -not (Test-EmptyDirectory -Path $InstallPath)

$toInstall = @("nerdctl")

$dependencies = Get-NerdctlDependencies -Dependencies $dependencies
@@ -98,17 +97,16 @@ function Install-Nerdctl {

$WhatIfMessage = "nerdctl will be installed at $installPath"
if ($isInstalled) {
$WhatIfMessage = "nerdctl will be uninstalled from and reinstalled at $installPath"
$WhatIfMessage = "nerdctl will be uninstalled and reinstalled at $InstallPath"
}
if ($dependencies) {
<# Action when this condition is true #>
$WhatIfMessage = "nerdctl and its dependencies (Containerd, Buildkit, WinCNIPlugin) will be installed"
}
}

process {
if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, $WhatIfMessage)) {
# Check if tool already exists at specified location
# Check if nerdctl already exists at specified location
if ($isInstalled) {
$errMsg = "nerdctl already exists at $InstallPath or the directory is not empty"
Write-Warning $errMsg
@@ -122,23 +120,23 @@ function Install-Nerdctl {
}
}

# Get nerdctl version to install
# Get nerdctl version to install if not specified
if (!$Version) {
$Version = Get-NerdctlLatestVersion
}
$Version = $Version.TrimStart('v')

Write-Output "Downloading and installing nerdctl v$version at $InstallPath"
Write-Output "Downloading and installing nerdctl v$Version at $InstallPath"

# Download files
$downloadParams = @{
ToolName = "nerdctl"
Repository = "$NERDCTL_REPO"
Version = $version
OSArchitecture = $OSArchitecture
DownloadPath = $DownloadPath
ToolName = "nerdctl"
Repository = "$NERDCTL_REPO"
Version = $Version
OSArchitecture = $OSArchitecture
DownloadPath = $DownloadPath
ChecksumSchemaFile = $null
FileFilterRegEx = $null
FileFilterRegEx = $null
}
$downloadParamsProperties = [FileDownloadParameters]::new(
$downloadParams.ToolName,
29 changes: 29 additions & 0 deletions containers-toolkit/en-US/containers-toolkit-help.xml
Original file line number Diff line number Diff line change
@@ -2156,6 +2156,18 @@
</dev:type>
<dev:defaultValue>False</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false"
pipelineInput="False" position="named" aliases="none">
<maml:name>ToolName</maml:name>
<maml:description>
<maml:para>Tool to show the version of.</maml:para>
</maml:description>
<dev:type>
<maml:name>String</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>null</dev:defaultValue>
</command:parameter>
</command:syntaxItem>
</command:syntax>
<command:parameters>
@@ -2172,6 +2184,19 @@
</dev:type>
<dev:defaultValue>False</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false"
pipelineInput="False" position="named" aliases="none">
<maml:name>ToolName</maml:name>
<maml:description>
<maml:para>Tool to show the version of.</maml:para>
</maml:description>
<command:parameterValue required="false" variableLength="false">String</command:parameterValue>
<dev:type>
<maml:name>String</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>null (When null, it returns the version of containerd, buildkit, and nerdctl)</dev:defaultValue>
</command:parameter>
</command:parameters>
<command:returnValues>
<command:returnValue>
@@ -2189,6 +2214,10 @@
Installed Boolean Specifies whether the tool is installed or not.
Version String Installed version.
LatestVersion String Latest available version
Path String Path to the binary
BuildctlPath String Path to the buildctl binary
Daemon String containerd or buildkitd
DaemonStatus String Status of the tool service
</maml:para>
</maml:description>
</command:returnValue>
4 changes: 2 additions & 2 deletions docs/About/Install-Buildkit.md
Original file line number Diff line number Diff line change
@@ -15,13 +15,13 @@ Downloads and installs BuildKit.

### Install (Default)

```
```PowerShell
Install-Buildkit [-Version <String>] [-InstallPath <String>] [-DownloadPath <String>] [-OSArchitecture <string>] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]
```

### Setup

```
```PowerShell
Install-Buildkit [-Version <String>] [-InstallPath <String>] [-DownloadPath <String>] [-Setup]
[-WinCNIPath <String>] [-OSArchitecture <string>] [-Force] [-Confirm] [-WhatIf] [<CommonParameters>]
```
Loading
Oops, something went wrong.
Loading
Oops, something went wrong.