Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,15 @@

[CmdletBinding(DefaultParameterSetName="Standard")]
param(

[string]
[ValidateNotNullOrEmpty()]
$ContainerDVersion = "1.6.6",
$ContainerDVersion,

[string]
[ValidateNotNullOrEmpty()]
$NerdCTLVersion = "0.21.0",
$NerdCTLVersion,

[string]
[ValidateNotNullOrEmpty()]
$WinCNIVersion = "0.3.0",
$WinCNIVersion,

[string]
$ExternalNetAdapter,
Expand Down Expand Up @@ -252,8 +250,10 @@ New-ContainerTransparentNetwork
# Download and Install powershell module HNS-Network
$containerdPath='C:\Program Files\containerd\cni\bin\'
if (-not (Test-Path $containerdPath)){
curl.exe -LO https://github.com/microsoft/windows-container-networking/releases/download/v0.3.0/windows-container-networking-cni-amd64-v0.3.0.zip
Expand-Archive -Path .\windows-container-networking-cni-amd64-v0.3.0.zip -DestinationPath $containerdPath
$ReleaseAssets = Invoke-RestMethod "https://api.github.com/repos/microsoft/windows-container-networking/releases/latest"
$url = ($ReleaseAssets.assets | ? name -Match "64.+zip$")
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

($ReleaseAssets.assets | ? ...) can return multiple matching assets; in that case $url.browser_download_url / $url.name become arrays and curl.exe / Expand-Archive will receive System.Object[] (or otherwise fail). Select a single deterministic asset (e.g., Select-Object -First 1, or stronger filtering on an exact asset name) and consider failing fast with a clear error if no matches are found.

Suggested change
$url = ($ReleaseAssets.assets | ? name -Match "64.+zip$")
$matchingAssets = $ReleaseAssets.assets | Where-Object { $_.name -match "64.+zip$" } | Sort-Object -Property name
if (-not $matchingAssets) {
throw "No windows-container-networking release asset matching '64.+zip$' was found."
}
$url = $matchingAssets | Select-Object -First 1

Copilot uses AI. Check for mistakes.
curl.exe -LO $url.browser_download_url
Expand-Archive -Path .\$($url.name) -DestinationPath $containerdPath
}
curl.exe -LO https://raw.githubusercontent.com/microsoft/SDN/master/Kubernetes/windows/hns.psm1
Import-Module -Force ./hns.psm1
Expand Down Expand Up @@ -545,16 +545,13 @@ Install-Containerd()
[CmdletBinding()]
param(
[string]
[ValidateNotNullOrEmpty()]
$ContainerdVersion = "1.6.6",
$ContainerdVersion,

[string]
[ValidateNotNullOrEmpty()]
$NerdCTLVersion = "0.21.0",
$NerdCTLVersion,

[string]
[ValidateNotNullOrEmpty()]
$WinCNIVersion = "0.3.0",
$WinCNIVersion,

[string]
$ContainerBaseImage
Expand All @@ -573,20 +570,45 @@ Install-Containerd()
if (!(Test-Path $NerdCTLPath)) { mkdir -Force -Path $NerdCTLPath | Out-Null }
if (!(Test-Path $WinCNIPath)) { mkdir -Force -Path $WinCNIPath | Out-Null }

$ContainerdZip = "containerd-$ContainerDVersion-windows-amd64.tar.gz"
Copy-File "https://github.com/containerd/containerd/releases/download/v$ContainerDVersion/$ContainerdZip" "$ContainerdPath\$ContainerdZip"

if ($ContainerdVersion) {
$ContainerdZip = "containerd-$ContainerDVersion-windows-amd64.tar.gz"
$URL = "https://github.com/containerd/containerd/releases/download/v$ContainerDVersion/$ContainerdZip"
} else {
$ReleaseAssets = Invoke-RestMethod "https://api.github.com/repos/containerd/containerd/releases/latest"
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on unauthenticated GitHub API calls makes the script vulnerable to rate limiting (especially in CI or shared NAT environments). Consider supporting an optional GITHUB_TOKEN (Authorization header) or documenting the rate-limit behavior and adding retries/backoff so installs don’t fail intermittently.

Copilot uses AI. Check for mistakes.
$Release = ($ReleaseAssets.assets | ? name -Match "Windows.+64.+gz$")
$URL = $Release.browser_download_url
$ContainerdZip = $Release.Name
Comment on lines +578 to +581
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as above: the asset filter can match multiple items, making $Release.browser_download_url / $Release.Name arrays and breaking Copy-File. Make the selection deterministic (pick exactly one asset) and handle the 'no asset matched' case explicitly so failures are understandable.

Copilot uses AI. Check for mistakes.
}
Comment on lines +573 to +582
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'pinned version vs latest release' logic is duplicated three times with only repo/regex/filename differences. Consider extracting a small helper (e.g., 'resolve release asset URL + filename') to reduce repetition and ensure any future fixes (like deterministic asset selection and error handling) are applied consistently.

Suggested change
if ($ContainerdVersion) {
$ContainerdZip = "containerd-$ContainerDVersion-windows-amd64.tar.gz"
$URL = "https://github.com/containerd/containerd/releases/download/v$ContainerDVersion/$ContainerdZip"
} else {
$ReleaseAssets = Invoke-RestMethod "https://api.github.com/repos/containerd/containerd/releases/latest"
$Release = ($ReleaseAssets.assets | ? name -Match "Windows.+64.+gz$")
$URL = $Release.browser_download_url
$ContainerdZip = $Release.Name
}
function Resolve-GitHubReleaseAsset {
param(
[string]
$Repository,
[string]
$Version,
[string]
$PinnedAssetName,
[string]
$LatestAssetPattern
)
if ($Version) {
return @{
Url = "https://github.com/$Repository/releases/download/v$Version/$PinnedAssetName"
Name = $PinnedAssetName
}
}
$ReleaseAssets = Invoke-RestMethod "https://api.github.com/repos/$Repository/releases/latest"
$Release = $ReleaseAssets.assets | Where-Object name -Match $LatestAssetPattern | Select-Object -First 1
return @{
Url = $Release.browser_download_url
Name = $Release.Name
}
}
$ContainerdRelease = Resolve-GitHubReleaseAsset `
-Repository "containerd/containerd" `
-Version $ContainerdVersion `
-PinnedAssetName "containerd-$ContainerDVersion-windows-amd64.tar.gz" `
-LatestAssetPattern "Windows.+64.+gz$"
$URL = $ContainerdRelease.Url
$ContainerdZip = $ContainerdRelease.Name

Copilot uses AI. Check for mistakes.
Copy-File $URL "$ContainerdPath\$ContainerdZip"
tar.exe -xvf "$ContainerdPath\$ContainerdZip" -C $ContainerdPath
Write-Output "Containerd binaries added to $ContainerdPath"

#Download and extract nerdctl binaries
$NerdCTLZip = "nerdctl-$NerdCTLVersion-windows-amd64.tar.gz"
Copy-File "https://github.com/containerd/nerdctl/releases/download/v$NerdCTLVersion/$NerdCTLZip" "$NerdCTLPath\$NerdCTLZip"
if ($NerdCTLVersion) {
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'pinned version vs latest release' logic is duplicated three times with only repo/regex/filename differences. Consider extracting a small helper (e.g., 'resolve release asset URL + filename') to reduce repetition and ensure any future fixes (like deterministic asset selection and error handling) are applied consistently.

Copilot uses AI. Check for mistakes.
$NerdCTLZip = "nerdctl-$NerdCTLVersion-windows-amd64.tar.gz"
$URL = "https://github.com/containerd/nerdctl/releases/download/v$NerdCTLVersion/$NerdCTLZip"
} else {
$ReleaseAssets = Invoke-RestMethod "https://api.github.com/repos/containerd/nerdctl/releases/latest"
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on unauthenticated GitHub API calls makes the script vulnerable to rate limiting (especially in CI or shared NAT environments). Consider supporting an optional GITHUB_TOKEN (Authorization header) or documenting the rate-limit behavior and adding retries/backoff so installs don’t fail intermittently.

Copilot uses AI. Check for mistakes.
$Release = ($ReleaseAssets.assets | ? name -Match "Windows.+64.+gz$")
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has the same multi-match failure mode as the containerd block. Ensure exactly one asset is selected (or tighten the regex to match a single expected filename) and error out clearly if none/too many matches are found.

Suggested change
$Release = ($ReleaseAssets.assets | ? name -Match "Windows.+64.+gz$")
$Matches = @($ReleaseAssets.assets | ? name -Match "Windows.+64.+gz$")
if ($Matches.Count -eq 0) {
throw "Could not find a matching nerdctl Windows x64 .gz asset in the latest release."
}
if ($Matches.Count -gt 1) {
throw "Expected exactly one matching nerdctl Windows x64 .gz asset in the latest release, but found $($Matches.Count)."
}
$Release = $Matches[0]

Copilot uses AI. Check for mistakes.
$URL = $Release.browser_download_url
$NerdCTLZip = $Release.Name
}
Copy-File $URL "$NerdCTLPath\$NerdCTLZip"
tar.exe -xvf "$NerdCTLPath\$NerdCTLZip" -C $NerdCTLPath
Write-Output "NerdCTL binary added to $NerdCTLPath"

#Download and extract win cni binaries
$WinCNIZip = "windows-container-networking-cni-amd64-v$WinCNIVersion.zip"
Copy-File "https://github.com/microsoft/windows-container-networking/releases/download/v$WinCNIVersion/$WinCNIZip" "$WinCNIPath\$WinCNIZip"
#Download and extract cni binaries
if ($WinCNIVersion) {
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'pinned version vs latest release' logic is duplicated three times with only repo/regex/filename differences. Consider extracting a small helper (e.g., 'resolve release asset URL + filename') to reduce repetition and ensure any future fixes (like deterministic asset selection and error handling) are applied consistently.

Copilot uses AI. Check for mistakes.
$WinCNIZip = "windows-container-networking-cni-amd64-v$WinCNIVersion.zip"
$URL = "https://github.com/microsoft/windows-container-networking/releases/download/v$WinCNIVersion/$WinCNIZip"
} else {
$ReleaseAssets = Invoke-RestMethod "https://api.github.com/repos/microsoft/windows-container-networking/releases/latest"
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on unauthenticated GitHub API calls makes the script vulnerable to rate limiting (especially in CI or shared NAT environments). Consider supporting an optional GITHUB_TOKEN (Authorization header) or documenting the rate-limit behavior and adding retries/backoff so installs don’t fail intermittently.

Copilot uses AI. Check for mistakes.
$Release = ($ReleaseAssets.assets | ? name -Match "Windows.+64.+zip$")
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This filter is likely to match multiple zip assets over time (different variants/builds). If it returns more than one result, $URL and $WinCNIZip become arrays and downstream steps will fail. Select a single asset deterministically (or match the exact expected WinCNI asset name) and handle the empty result case.

Suggested change
$Release = ($ReleaseAssets.assets | ? name -Match "Windows.+64.+zip$")
$MatchingAssets = @(
$ReleaseAssets.assets |
? name -Match "^windows-container-networking-cni-amd64-v.+\.zip$" |
Sort-Object -Property Name
)
if ($MatchingAssets.Count -eq 0) {
throw "Unable to find a WinCNI release asset matching 'windows-container-networking-cni-amd64-v*.zip' in the latest release."
}
$Release = $MatchingAssets | Select-Object -First 1

Copilot uses AI. Check for mistakes.
$URL = $Release.browser_download_url
$WinCNIZip = $Release.Name
}
Copy-File $URL "$WinCNIPath\$WinCNIZip"
tar.exe -xvf "$WinCNIPath\$WinCNIZip" -C $WinCNIPath
Write-Output "CNI plugin binaries added to $WinCNIPath"

Expand Down