Skip to content
Draft
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
92 changes: 46 additions & 46 deletions containers-toolkit/Private/CommonToolUtilities.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# #
###########################################################################

using module "..\Private\logger.psm1"

$ModuleParentPath = Split-Path -Parent $PSScriptRoot
Import-Module -Name "$ModuleParentPath\Private\UpdateEnvironmentPath.psm1" -Force
Expand Down Expand Up @@ -94,7 +95,7 @@ function Get-LatestToolVersion($tool) {
# Get the latest release version URL string
$uri = "https://api.github.com/repos/$repository/releases/latest"

Write-Debug "Getting the latest $tool version from $uri"
[Logger]::Debug("Getting the latest $tool version from $uri")

# Get the latest release version
try {
Expand Down Expand Up @@ -133,7 +134,7 @@ function Get-ReleaseAssets {
function Invoke-GitHubApi {
param($uri)
try {
Write-Debug "Invoking GitHub API. URI: $uri"
[Logger]::Debug("Invoking GitHub API. URI: $uri")
$response = Invoke-RestMethod -Uri "$uri" -Headers @{ "User-Agent" = "PowerShell" }
return $response
}
Expand All @@ -142,7 +143,7 @@ function Get-ReleaseAssets {
}
}

Write-Debug "Getting release assets:`n`trepo: $repo`n`trelease version: $version`n`trelease architecture: $OSArch "
[Logger]::Debug("Getting release assets:`n`trepo: $repo`n`trelease version: $version`n`trelease architecture: $OSArch ")
$baseApiUrl = "https://api.github.com/repos/$repo"
if ($version -eq "latest") {
$apiUrl = "$baseApiUrl/releases/latest"
Expand All @@ -164,13 +165,13 @@ function Get-ReleaseAssets {
}

if ($releaseTag.Count -gt 1) {
Write-Warning "Found multiple release tags for the provided version: '$version'. Using the first tag."
[Logger]::Warning("Found multiple release tags for the provided version: '$version'. Using the first tag.")
}

$releaseTagName = $releaseTag | Select-Object -First 1 -ExpandProperty name

# Get the release with the specified tag
Write-Debug "Release tag: $releaseTagName"
[Logger]::Debug("Release tag: $releaseTagName")
$apiUrl = "$baseApiUrl/releases/tags/$releaseTagName"
}
$response = Invoke-GitHubApi -Uri "$apiUrl"
Expand All @@ -193,7 +194,7 @@ function Get-ReleaseAssets {
)
} |
ForEach-Object {
Write-Debug ("Asset name: {0}" -f $_.Name)
[Logger]::Debug(("Asset name: {0}" -f $_.Name))
[PSCustomObject]@{
"asset_name" = $_.name
"asset_download_url" = $_.browser_download_url
Expand All @@ -210,7 +211,7 @@ function Get-ReleaseAssets {
}

if ($archReleaseAssets.Count -lt 2) {
Write-Warning "Some assets may be missing for the release. Expected at least 2 assets, found $($archReleaseAssets.Count)."
[Logger]::Warning("Some assets may be missing for the release. Expected at least 2 assets, found $($archReleaseAssets.Count).")
}

# Return the assets for the release. Includes the archive file for the binaries and the checksum files.
Expand Down Expand Up @@ -239,7 +240,7 @@ function Get-InstallationFile {
}
catch {
$lastError = $_ # Store the last error for proper exception handling
Write-Warning "Failed to download `"$($params.Feature)`" release assets. Retrying... ($MaximumRetryCount retries left)"
[Logger]::Warning("Failed to download `"$($params.Feature)`" release assets. Retrying... ($MaximumRetryCount retries left)")
Start-Sleep -Seconds $RetryIntervalSec
$MaximumRetryCount -= 1
}
Expand Down Expand Up @@ -277,13 +278,12 @@ function Get-InstallationFile {
DownloadPath = $destPath
}

Write-Debug "Downloading asset $($asset_params.asset_name)...`n`tVersion: $version`n`tURI: $($downloadParams.Uri)`n`tDestination path: $($downloadParams.DownloadPath)"
[Logger]::Debug("Downloading asset $($asset_params.asset_name)...`n`tVersion: $version`n`tURI: $($downloadParams.Uri)`n`tDestination path: $($downloadParams.DownloadPath)")
try {
Receive-File -Params $downloadParams
}
catch {
Write-Error "Failed to download $($downloadParams.Feature) release assets. $($_.Exception.Message)"
Throw $_ # Re-throw the exception to halt execution if a download fails
[Logger]::Fatal($_.Exception.Message)
}
}

Expand All @@ -305,8 +305,7 @@ function Get-InstallationFile {
}
}
catch {
Write-Error "Checksum verification process failed: $($_.Exception.Message)"
Throw $_ # Re-throw the exception if checksum verification fails
[Logger]::Fatal("Checksum verification process failed: $($_.Exception.Message)")
}

# Remove the checksum file after verification
Expand All @@ -315,7 +314,7 @@ function Get-InstallationFile {
}

if (-not $isValidChecksum) {
Write-Error "Checksum verification failed for $archiveFile. The file will be deleted."
[Logger]::Error("Checksum verification failed for $archiveFile. The file will be deleted.")

# Remove the checksum file after verification
if (Test-Path -Path $archiveFile) {
Expand Down Expand Up @@ -351,7 +350,7 @@ function Get-InstallationFile {
else {
# Use the provided regex to filter the archive and checksum files
$fileFilterRegEx = $fileParameters.FileFilterRegEx -replace "<__VERSION__>", "v?$($releaseAssets.version.TrimStart('v'))"
Write-Debug "File filter: `"$fileFilterRegEx`""
[Logger]::Debug("File filter: `"$fileFilterRegEx`"")
$filteredAssets = $releaseAssets.release_assets | Where-Object { $_.asset_name -match $fileFilterRegEx }
}

Expand Down Expand Up @@ -380,7 +379,7 @@ function Get-InstallationFile {
}

if (-not $checksumAsset) {
Write-Error "Checksum file for $assetFileName not found. Skipping download."
[Logger]::Error("Checksum file for $assetFileName not found. Skipping download.")
$failedDownloads += $asset.asset_name
continue
}
Expand All @@ -403,17 +402,17 @@ function Get-InstallationFile {

# Download the archive and verify checksum
$archiveFiles = $failedDownloads = @()
Write-Debug "Assets to download count: $($assetsToDownload.ReleaseAssets.Count)"
[Logger]::Debug("Assets to download count: $($assetsToDownload.ReleaseAssets.Count)")
foreach ($asset in $assetsToDownload) {
try {
Write-Debug "Downloading $($asset.FeatureName) assets..."
[Logger]::Debug("Downloading $($asset.FeatureName) assets...")
$archiveFile = DownloadAssets @asset

Write-Debug "Downloaded archive file: `"$archiveFile`""
[Logger]::Debug("Downloaded archive file: `"$archiveFile`"")
$archiveFiles += $archiveFile
}
catch {
Write-Error "Failed to download assets for `"$($asset.FeatureName)`". $_"
[Logger]::Error("Failed to download assets for `"$($asset.FeatureName)`". $_")
$failedDownloads += $asset.FeatureName
}
}
Expand All @@ -432,7 +431,7 @@ function Get-InstallationFile {
}

end {
Write-Information "File download and verification process completed."
[Logger]::Info("File download and verification process completed.")
}
}

Expand Down Expand Up @@ -462,7 +461,7 @@ function Test-CheckSum {
[System.Array]$ExtractDigestArguments
)

Write-Debug "Checksum verification...`n`tSource file: $DownloadedFile`n`tChecksum file: $ChecksumFile"
[Logger]::Debug("Checksum verification...`n`tSource file: $DownloadedFile`n`tChecksum file: $ChecksumFile")

if (-not (Test-Path -Path $downloadedFile)) {
Throw "Couldn't find source file: `"$downloadedFile`"."
Expand All @@ -473,8 +472,8 @@ function Test-CheckSum {
}

if ($JSON) {
Write-Debug "Checksum file format: JSON"
Write-Debug "SchemaFile: $SchemaFile"
[Logger]::Debug("Checksum file format: JSON")
[Logger]::Debug("SchemaFile: $SchemaFile")
return (
Test-JSONChecksum `
-DownloadedFile $downloadedFile `
Expand All @@ -485,7 +484,7 @@ function Test-CheckSum {
)
}

Write-Debug "Checksum file format: Text"
[Logger]::Debug("Checksum file format: Text")
return Test-FileChecksum -DownloadedFile $DownloadedFile -ChecksumFile $ChecksumFile
}

Expand Down Expand Up @@ -513,7 +512,7 @@ function Test-FileChecksum {
Throw "Invalid hash function. Supported hash functions: $($HASH_FUNCTIONS -join ', ')"
}
$algorithm = $matches.hashfunction
Write-Debug "Algorithm: $algorithm"
[Logger]::Debug("Algorithm: $algorithm")
$downloadedChecksum = Get-FileHash -Path $DownloadedFile -Algorithm $algorithm

# checksum is stored in a file named SHA256SUMS
Expand Down Expand Up @@ -547,13 +546,13 @@ function Test-FileChecksum {
}
finally {
# Delete checksum file
Write-Debug "Deleting checksum file $checksumFile"
[Logger]::Debug("Deleting checksum file $checksumFile")
if (Test-Path -Path $checksumFile) {
Remove-Item -Path $checksumFile -Force -ErrorAction Ignore
}
}

Write-Debug "Checksum verification status. {success: $isValid}"
[Logger]::Debug("Checksum verification status. {success: $isValid}")
return $isValid
}

Expand All @@ -578,16 +577,16 @@ function Test-JSONChecksum {

# Validate the checksum file
$isJsonValid = ValidateJSONChecksumFile -ChecksumFilePath $checksumFile -SchemaFile $SchemaFile
Write-Debug "Checksum JSON file validation status. {success: $isJsonValid}"
[Logger]::Debug("Checksum JSON file validation status. {success: $isJsonValid}")

if ($null -eq $ExtractDigestScriptBlock) {
Write-Debug "Using default JSON checksum extraction script block"
[Logger]::Debug("Using default JSON checksum extraction script block")
$ExtractDigestScriptBlock = ${function:GenericExtractDigest}
$ExtractDigestArguments = @($DownloadedFile, $checksumFile)
}

# Invoke the script block to extract the file digest
Write-Debug "Extracting file digest from $checksumFile"
[Logger]::Debug("Extracting file digest from $checksumFile")
$extractedFileDigest = & $ExtractDigestScriptBlock @ExtractDigestArguments

# Since Invoke() returns a collection, we need to extract the first item
Expand Down Expand Up @@ -618,13 +617,13 @@ function Test-JSONChecksum {
}
finally {
# Delete checksum checksumFile
Write-Debug "Deleting checksum file $checksumFile"
[Logger]::Debug("Deleting checksum file $checksumFile")
if (Test-Path -Path $checksumFile) {
Remove-Item -Path $checksumFile -Force -ErrorAction Ignore
}
}

Write-Debug "Checksum verification status. {success: $isValid}"
[Logger]::Debug("Checksum verification status. {success: $isValid}")
return $isValid
}

Expand All @@ -636,7 +635,7 @@ function ValidateJSONChecksumFile {
[String]$SchemaFile
)

Write-Debug "Validating JSON checksum file...`n`tChecksum file path: $ChecksumFilePath`n`tSchema file: $SchemaFile"
[Logger]::Debug("Validating JSON checksum file...`n`tChecksum file path: $ChecksumFilePath`n`tSchema file: $SchemaFile")

# Check if the schema file exists
if (-not (Test-Path -Path $SchemaFile)) {
Expand Down Expand Up @@ -667,7 +666,7 @@ function GenericExtractDigest {
[String]$ChecksumFile
)

Write-Debug "Extracting digest from $checksumFile using default script block for in-toto SBOM format"
[Logger]::Debug("Extracting digest from $checksumFile using default script block for in-toto SBOM format")

# Read the JSON file and get the checksum
$jsonContent = Get-Content -Path $ChecksumFile -Raw | ConvertFrom-Json
Expand Down Expand Up @@ -730,7 +729,7 @@ function Install-RequiredFeature {
[boolean] $UpdateEnvPath = $true
)
# Create the directory to untar to
Write-Information -InformationAction Continue -MessageData "Extracting $Feature to $InstallPath"
[Logger]::Info("Extracting $Feature to $InstallPath")
if (!(Test-Path $InstallPath)) {
New-Item -ItemType Directory -Force -Path $InstallPath | Out-Null
}
Expand All @@ -742,10 +741,10 @@ function Install-RequiredFeature {
Throw "Couldn't find source file: `"$file`"."
}

Write-Debug "Expand archive:`n`tSource file: $file`n`tDestination Path: $InstallPath"
[Logger]::Debug("Expand archive:`n`tSource file: $file`n`tDestination Path: $InstallPath")
$cmdOutput = Invoke-ExecutableCommand -executable "tar.exe" -arguments "-xf `"$file`" -C `"$InstallPath`"" -timeout (60 * 2)
if ($cmdOutput.ExitCode -ne 0) {
Write-Error "Failed to expand archive `"$file`" at `"$InstallPath`". Exit code: $($cmdOutput.ExitCode). $($cmdOutput.StandardError.ReadToEnd())"
[Logger]::Error("Failed to expand archive `"$file`" at `"$InstallPath`". Exit code: $($cmdOutput.ExitCode). $($cmdOutput.StandardError.ReadToEnd())")
$failed += $file
}
}
Expand All @@ -761,7 +760,7 @@ function Install-RequiredFeature {

# Clean up
if ($CleanUp) {
Write-Output "Cleanup to remove downloaded files"
[Logger]::Info("Cleanup to remove downloaded files")
if (Test-Path -Path $SourceFile -ErrorAction SilentlyContinue) {
Remove-Item -Path $SourceFile -Force -ErrorAction Ignore
}
Expand Down Expand Up @@ -828,7 +827,7 @@ function Invoke-StartService($service) {
# Waiting for the service to come to a steady state
(Get-Service -Name $service -ErrorAction Ignore).WaitForStatus('Running', '00:00:30')

Write-Debug "Success: { Service: $service, Action: 'Start' }"
[Logger]::Debug("Success: { Service: $service, Action: 'Start' }")
}
catch {
Throw "Couldn't start $service service. $_"
Expand All @@ -844,7 +843,7 @@ function Invoke-StopService($service) {
# Waiting for the service to come to a steady state
(Get-Service -Name $service -ErrorAction Ignore).WaitForStatus('Stopped', '00:00:30')

Write-Debug "Success: { Service: $service, Action: 'Stop' }"
[Logger]::Debug("Success: { Service: $service, Action: 'Stop' }")
}
catch {
Throw "Couldn't stop $service service. $_"
Expand All @@ -868,10 +867,10 @@ function Uninstall-ProgramFiles($path) {
catch {
$errMsg = $_
if ($errMsg -match "denied") {
Write-Error "Failed to delete directory: '$path'. Access to path denied. To resolve this issue, see https://github.com/microsoft/containers-toolkit/blob/main/docs/docs/FAQs.md#resolving-uninstallation-error-access-to-path-denied"
[Logger]::Error("Failed to delete directory: '$path'. Access to path denied. To resolve this issue, see https://github.com/microsoft/containers-toolkit/blob/main/docs/docs/FAQs.md#resolving-uninstallation-error-access-to-path-denied")
}
else {
Write-Error "Failed to delete directory: '$path'. $_"
[Logger]::Error("Failed to delete directory: '$path'. $_")
}
}
}
Expand All @@ -887,7 +886,7 @@ function Invoke-ExecutableCommand {
[Int32] $timeout = 15
)

Write-Debug "Executing '$executable $arguments'"
[Logger]::Debug("Executing '$executable $arguments'")

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = $executable
Expand All @@ -902,10 +901,10 @@ function Invoke-ExecutableCommand {
$p.WaitForExit($timeout * 1000) | Out-Null

if (-not $p.HasExited) {
Write-Debug "Execution did not complete in $timeout seconds."
[Logger]::Debug("Execution did not complete in $timeout seconds.")
}
else {
Write-Debug "Command execution completed. Exit code: $($p.ExitCode)"
[Logger]::Debug("Command execution completed. Exit code: $($p.ExitCode)")
}

return $p
Expand All @@ -925,3 +924,4 @@ Export-ModuleMember -Function Invoke-ServiceAction
Export-ModuleMember -Function Test-ConfFileEmpty
Export-ModuleMember -Function Uninstall-ProgramFiles
Export-ModuleMember -Function Test-CheckSum
Export-ModuleMember -Variable Log