Skip to content

Commit d58f547

Browse files
authored
Refactor Show-ContainerTools (#55)
- Refactor Show-ContainerTools to reuse functions and rewrite the unit tests - Bug fixes - Spelling issues and omit words (param names or variable names) from spellchecker
1 parent e2ffb29 commit d58f547

File tree

9 files changed

+211
-52
lines changed

9 files changed

+211
-52
lines changed

.textlintrc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@
2525
"/Cmdlet/gi",
2626
"cni",
2727
"/Containerd/gi",
28+
"/buildctl/gi",
29+
"/BuildctlPath/gi",
2830
"/BuildKit/gi",
2931
"/buildkitd/gi",
32+
"/DaemonStatus/gi",
3033
"/H(ost)?N(etworking)?S(ervice)?/g",
3134
"/Hyper[\\s-]?V/g",
3235
"/moby/gi",
@@ -39,6 +42,7 @@
3942
"/unregisters/gi",
4043
"WinCNIPlugin",
4144
// Parameter names
45+
"ToolName",
4246
"DownloadPath",
4347
"InstallPath",
4448
"LatestVersion",

Tests/AllToolsUtilities.Tests.ps1

Lines changed: 108 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,121 @@ Describe "AllToolsUtilities.psm1" {
3030

3131
Context "Show-ContainerTools" -Tag "Show-ContainerTools" {
3232
BeforeAll {
33-
Mock Get-InstalledVersion -ModuleName 'AllToolsUtilities'
33+
# Mock get version
34+
$mockConfigStdOut = New-MockObject -Type 'System.IO.StreamReader' -Methods @{ ReadToEnd = { return "tool version v1.0.1" } }
35+
$mockConfigProcess = New-MockObject -Type 'System.Diagnostics.Process' -Properties @{
36+
ExitCode = 0
37+
StandardOutput = $mockConfigStdOut
38+
}
39+
Mock Invoke-ExecutableCommand -ModuleName "AllToolsUtilities" `
40+
-ParameterFilter { $Arguments -eq "--version" } `
41+
-MockWith { return $mockConfigProcess }
42+
}
43+
44+
It "Should get containerd version" {
45+
$executablePath = "TestDrive:\Program Files\Containerd\bin\containerd.exe"
46+
Mock Get-Command -ModuleName 'AllToolsUtilities' -MockWith { @{ Name = 'containerd.exe'; Source = $executablePath } }
47+
Mock Get-Service -ModuleName 'AllToolsUtilities'
48+
49+
$containerdVersion = Show-ContainerTools -ToolName 'containerd'
50+
51+
# Check the output
52+
$expectedOutput = [PSCustomObject]@{
53+
Tool = 'containerd'
54+
Path = $executablePath
55+
Installed = $true
56+
Version = 'v1.0.1'
57+
Daemon = 'containerd'
58+
DaemonStatus = 'Unregistered'
59+
}
60+
# $containerdVersion | Should -Be $expectedOutput
61+
# HACK: Should -Be does not work with PSCustomObject in PSv5.
62+
# However PSv6 has support for this. To be investigated further.
63+
foreach ($key in $expectedOutput.Keys) {
64+
$expectedValue = $expectedOutput[$key]
65+
$actualValue = $containerdVersion.$key
66+
$actualValue | Should -Be $expectedValue
67+
}
68+
69+
# Check the invocation
70+
Should -Invoke Get-Command -ModuleName 'AllToolsUtilities' `
71+
-Times 1 -Exactly -Scope It -ParameterFilter { $Name -eq 'containerd.exe' }
72+
}
73+
74+
It "Should get buildkit version" {
75+
$executablePath = "TestDrive:\Program Files\Buildkit\bin\buildkitd.exe"
76+
$buildctlPath = "TestDrive:\Program Files\Buildkit\bin\buildctl.exe"
77+
78+
Mock Get-Service -ModuleName 'AllToolsUtilities' -MockWith { @{ Status = "Running" } }
79+
Mock Get-Command -ModuleName 'AllToolsUtilities' -MockWith { @(
80+
@{ Name = 'buildkitd.exe'; Source = $executablePath }
81+
@{ Name = 'buildctl.exe'; Source = $buildctlPath }
82+
) }
83+
84+
$buildkitVersion = Show-ContainerTools -ToolName 'buildkit'
85+
86+
# Check the output
87+
$expectedOutput = [PSCustomObject]@{
88+
Tool = 'buildkit'
89+
Path = $executablePath
90+
Installed = $true
91+
Version = 'v1.0.1'
92+
Daemon = 'buildkitd'
93+
DaemonStatus = 'Running'
94+
BuildctlPath = $buildctlPath
95+
}
96+
foreach ($key in $expectedOutput.Keys) {
97+
$expectedValue = $expectedOutput[$key]
98+
$actualValue = $buildkitVersion.$key
99+
$actualValue | Should -Be $expectedValue
100+
}
101+
102+
# Check the invocation
103+
Should -Invoke Get-Command -ModuleName 'AllToolsUtilities' `
104+
-Times 1 -Exactly -Scope It -ParameterFilter { $Name -eq "build*.exe" }
34105
}
35106

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

39-
@("containerd", "buildkit", "nerdctl") | ForEach-Object {
40-
Should -Invoke Get-InstalledVersion -ModuleName 'AllToolsUtilities' `
41-
-Times 1 -Exactly -Scope It `
42-
-ParameterFilter { $Feature -eq $_ }
110+
$toolInfo = Show-ContainerTools
111+
112+
# Check the output
113+
$expectedOutput = @(
114+
[PSCustomObject]@{ Tool = 'containerd'; Installed = $false; Daemon = 'containerd'; DaemonStatus = 'Unregistered' }
115+
[PSCustomObject]@{ Tool = 'buildkit'; Installed = $false; Daemon = 'buildkitd'; DaemonStatus = 'Unregistered' }
116+
[PSCustomObject]@{ Tool = 'nerdctl'; Installed = $false }
117+
)
118+
$expectedOutput | ForEach-Object {
119+
$tool = $_.Tool
120+
$actualOutput = $toolInfo | Where-Object { $_.Tool -eq $tool }
121+
foreach ($key in $_.Keys) {
122+
$expectedValue = $_[$key]
123+
$actualValue = $actualOutput.$key
124+
$actualValue | Should -Be $expectedValue
125+
}
43126
}
44127
}
45128

46-
It "Should list the latest available version for each tool" {
47-
Show-ContainerTools -Latest
129+
It "Should return latest version if Latest flag is specified" {
130+
Mock Get-Command -ModuleName 'AllToolsUtilities'
131+
132+
$toolInfo = Show-ContainerTools -Latest
48133

49-
@("containerd", "buildkit", "nerdctl") | ForEach-Object {
50-
Should -Invoke Get-InstalledVersion -ModuleName 'AllToolsUtilities' `
51-
-Times 1 -Exactly -Scope It `
52-
-ParameterFilter { $Feature -eq $_ -and $Latest -eq $true }
134+
# Check the output
135+
$expectedOutput = @(
136+
[PSCustomObject]@{ Tool = 'containerd'; Installed = $false; Daemon = 'buildkitd'; DaemonStatus = 'Unregistered'; LatestVersion = 'v1.0.1' }
137+
[PSCustomObject]@{ Tool = 'buildkit'; Installed = $false; Daemon = 'buildkitd'; DaemonStatus = 'Unregistered'; LatestVersion = 'v1.0.1' }
138+
[PSCustomObject]@{ Tool = 'nerdctl'; Installed = $false; LatestVersion = 'v1.0.1' }
139+
)
140+
$expectedOutput | ForEach-Object {
141+
$tool = $_.Tool
142+
$actualOutput = $toolInfo | Where-Object { $_.Tool -eq $tool }
143+
foreach ($key in $_.Keys) {
144+
$expectedValue = $_[$key]
145+
$actualValue = $actualOutput.$key
146+
$actualValue | Should -Be $expectedValue
147+
}
53148
}
54149
}
55150
}

containers-toolkit/Public/AllToolsUtilities.psm1

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ Import-Module -Name "$ModuleParentPath\Private\CommonToolUtilities.psm1" -Force
1414
function Show-ContainerTools {
1515
param (
1616
[Parameter(HelpMessage = "Show latest release version")]
17-
[Switch]$Latest
17+
[Switch]$Latest,
18+
19+
[Parameter(HelpMessage = "Tool to show")]
20+
[ValidateSet("containerd", "buildkit", "nerdctl")]
21+
[String[]]$ToolName
1822
)
1923

20-
$tools = @("containerd", "buildkit", "nerdctl")
24+
$tools = if ($ToolName) { $ToolName } else { @("containerd", "buildkit", "nerdctl") }
2125

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

175179
function Get-InstalledVersion($feature, $Latest) {
176-
$executable = $null
180+
$sourceLocation = $null
177181
$daemon = $null
182+
$buildctlPath = $null
178183
switch ($feature) {
179184
"buildkit" {
180-
$bktdExecutable = (Get-Command "build*.exe" | Where-Object { $_.Source -like "*buildkit*" }) | Select-Object Name
181-
if ($bktdExecutable) {
182-
$executable = ($bktdExecutable[0]).Name
185+
$blktCommandInfo = Get-Command "build*.exe" | Where-Object { $_.Source -like "*buildkit*" }
186+
if ($null -ne $blktCommandInfo) {
187+
# Get buildkitd executable
188+
$buldkitdCommandInfo = $blktCommandInfo | Where-Object { $_.Name -like "buildkitd.exe" }
189+
$sourceLocation = $buldkitdCommandInfo.Source
183190
}
191+
$daemon = 'buildkitd'
184192

185-
if ($null -ne ($bktdExecutable | Where-Object { $_.Name -contains "buildkitd.exe" })) {
186-
$daemon = 'buildkitd'
187-
}
193+
$buildctlPath = ($blktCommandInfo | Where-Object { $_.Name -like "buildctl.exe" }).Source
188194
}
189195
Default {
190-
$executable = (Get-Command "$feature.exe" -ErrorAction Ignore).Name
196+
$commandInfo = Get-Command "$feature.exe" -ErrorAction Ignore
197+
198+
if ($null -ne $commandInfo) {
199+
$sourceLocation = $commandInfo.Source
200+
}
191201

192202
if ($feature -eq 'containerd') {
193203
$daemon = 'containerd'
@@ -199,16 +209,21 @@ function Get-InstalledVersion($feature, $Latest) {
199209
Tool = $feature
200210
Installed = $False
201211
}
202-
if ($executable) {
203-
$result = getToolVersion -Executable $executable
212+
if ($sourceLocation) {
213+
$result = getToolVersion -Executable $sourceLocation
204214
Add-Member -InputObject $result -Name 'Tool' -Value $feature -MemberType 'NoteProperty'
205-
$result = $result | Select-Object Tool, Installed, Version
215+
Add-Member -InputObject $result -Name 'Path' -Value $sourceLocation -MemberType 'NoteProperty'
216+
$result = $result | Select-Object Tool, Path, Installed, Version
206217

207218
if ($daemon) {
208219
Add-Member -InputObject $result -Name 'Daemon' -Value $daemon -MemberType 'NoteProperty'
209220
Add-Member -InputObject $result -Name 'DaemonStatus' -MemberType 'NoteProperty' `
210221
-Value (getDaemonStatus -Daemon $daemon)
211222
}
223+
224+
if ($buildctlPath) {
225+
$result | Add-Member -Name 'BuildctlPath' -Value $buildctlPath -MemberType 'NoteProperty'
226+
}
212227
}
213228

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

225240
function getToolVersion($executable) {
241+
$toolName = [System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetFileName($executable))
242+
226243
$installedVersion = $null
227244
try {
228-
$version = & $executable -v
245+
$cmdOutput = Invoke-ExecutableCommand -Executable $executable -Arguments '--version'
246+
if ($cmdOutput.ExitCode -ne 0) {
247+
Throw "Couldn't get $toolName version. $($cmdOutput.StandardError.ReadToEnd())"
248+
}
249+
250+
$version = $cmdOutput.StandardOutput.ReadToEnd()
229251

230252
$pattern = "(\d+\.)(\d+\.)(\*|\d+)"
231253
$installedVersion = ($version | Select-String -Pattern $pattern).Matches.Value

containers-toolkit/Public/ContainerNetworkTools.psm1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ using module "..\Private\CommonToolUtilities.psm1"
1212
$ModuleParentPath = Split-Path -Parent $PSScriptRoot
1313
Import-Module -Name "$ModuleParentPath\Private\CommonToolUtilities.psm1" -Force
1414

15+
$WINCNI_PLUGIN_REPO = "microsoft/windows-container-networking"
16+
$CLOUDNATIVE_CNI_REPO = "containernetworking/plugins"
17+
1518
function Get-WinCNILatestVersion {
1619
param (
1720
[String]$repo = "microsoft/windows-container-networking"

containers-toolkit/Public/NerdctlTools.psm1

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,13 @@ function Install-Nerdctl {
8181
$OSArchitecture = $env:PROCESSOR_ARCHITECTURE,
8282

8383
[Switch]
84-
[parameter(HelpMessage = "Installs nerdctl (and its dependecies if specified) even if the tool already exists at the specified path")]
84+
[parameter(HelpMessage = "Installs nerdctl (and its dependencies if specified) even if the tool already exists at the specified path")]
8585
$Force
8686
)
8787

8888
begin {
89-
# Check if Containerd is alread installed
89+
# Check if nerdctl is already installed
9090
$isInstalled = -not (Test-EmptyDirectory -Path $InstallPath)
91-
9291
$toInstall = @("nerdctl")
9392

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

9998
$WhatIfMessage = "nerdctl will be installed at $installPath"
10099
if ($isInstalled) {
101-
$WhatIfMessage = "nerdctl will be uninstalled from and reinstalled at $installPath"
100+
$WhatIfMessage = "nerdctl will be uninstalled and reinstalled at $InstallPath"
102101
}
103102
if ($dependencies) {
104-
<# Action when this condition is true #>
105103
$WhatIfMessage = "nerdctl and its dependencies (Containerd, Buildkit, WinCNIPlugin) will be installed"
106104
}
107105
}
108106

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

125-
# Get nerdctl version to install
123+
# Get nerdctl version to install if not specified
126124
if (!$Version) {
127125
$Version = Get-NerdctlLatestVersion
128126
}
129127
$Version = $Version.TrimStart('v')
130128

131-
Write-Output "Downloading and installing nerdctl v$version at $InstallPath"
129+
Write-Output "Downloading and installing nerdctl v$Version at $InstallPath"
132130

133131
# Download files
134132
$downloadParams = @{
135-
ToolName = "nerdctl"
136-
Repository = "$NERDCTL_REPO"
137-
Version = $version
138-
OSArchitecture = $OSArchitecture
139-
DownloadPath = $DownloadPath
133+
ToolName = "nerdctl"
134+
Repository = "$NERDCTL_REPO"
135+
Version = $Version
136+
OSArchitecture = $OSArchitecture
137+
DownloadPath = $DownloadPath
140138
ChecksumSchemaFile = $null
141-
FileFilterRegEx = $null
139+
FileFilterRegEx = $null
142140
}
143141
$downloadParamsProperties = [FileDownloadParameters]::new(
144142
$downloadParams.ToolName,

containers-toolkit/en-US/containers-toolkit-help.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,6 +2156,18 @@
21562156
</dev:type>
21572157
<dev:defaultValue>False</dev:defaultValue>
21582158
</command:parameter>
2159+
<command:parameter required="false" variableLength="true" globbing="false"
2160+
pipelineInput="False" position="named" aliases="none">
2161+
<maml:name>ToolName</maml:name>
2162+
<maml:description>
2163+
<maml:para>Tool to show the version of.</maml:para>
2164+
</maml:description>
2165+
<dev:type>
2166+
<maml:name>String</maml:name>
2167+
<maml:uri />
2168+
</dev:type>
2169+
<dev:defaultValue>null</dev:defaultValue>
2170+
</command:parameter>
21592171
</command:syntaxItem>
21602172
</command:syntax>
21612173
<command:parameters>
@@ -2172,6 +2184,19 @@
21722184
</dev:type>
21732185
<dev:defaultValue>False</dev:defaultValue>
21742186
</command:parameter>
2187+
<command:parameter required="false" variableLength="true" globbing="false"
2188+
pipelineInput="False" position="named" aliases="none">
2189+
<maml:name>ToolName</maml:name>
2190+
<maml:description>
2191+
<maml:para>Tool to show the version of.</maml:para>
2192+
</maml:description>
2193+
<command:parameterValue required="false" variableLength="false">String</command:parameterValue>
2194+
<dev:type>
2195+
<maml:name>String</maml:name>
2196+
<maml:uri />
2197+
</dev:type>
2198+
<dev:defaultValue>null (When null, it returns the version of containerd, buildkit, and nerdctl)</dev:defaultValue>
2199+
</command:parameter>
21752200
</command:parameters>
21762201
<command:returnValues>
21772202
<command:returnValue>
@@ -2189,6 +2214,10 @@
21892214
Installed Boolean Specifies whether the tool is installed or not.
21902215
Version String Installed version.
21912216
LatestVersion String Latest available version
2217+
Path String Path to the binary
2218+
BuildctlPath String Path to the buildctl binary
2219+
Daemon String containerd or buildkitd
2220+
DaemonStatus String Status of the tool service
21922221
</maml:para>
21932222
</maml:description>
21942223
</command:returnValue>

docs/About/Install-Buildkit.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ Downloads and installs BuildKit.
1515

1616
### Install (Default)
1717

18-
```
18+
```PowerShell
1919
Install-Buildkit [-Version <String>] [-InstallPath <String>] [-DownloadPath <String>] [-OSArchitecture <string>] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]
2020
```
2121

2222
### Setup
2323

24-
```
24+
```PowerShell
2525
Install-Buildkit [-Version <String>] [-InstallPath <String>] [-DownloadPath <String>] [-Setup]
2626
[-WinCNIPath <String>] [-OSArchitecture <string>] [-Force] [-Confirm] [-WhatIf] [<CommonParameters>]
2727
```

0 commit comments

Comments
 (0)