mirror of
https://github.com/actions/runner-images.git
synced 2026-01-02 16:24:24 +08:00
Add Ubuntu-Slim image definition (#13423)
Add ubuntu-slim image definition
This commit is contained in:
152
images/ubuntu-slim/scripts/docs-gen/Common.Helpers.psm1
Normal file
152
images/ubuntu-slim/scripts/docs-gen/Common.Helpers.psm1
Normal file
@@ -0,0 +1,152 @@
|
||||
function Get-CommandResult {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Runs a command in bash and returns the output and exit code.
|
||||
|
||||
.DESCRIPTION
|
||||
Function runs a provided command in bash and returns the output and exit code as hashtable.
|
||||
|
||||
.PARAMETER Command
|
||||
The command to run.
|
||||
|
||||
.PARAMETER ExpectedExitCode
|
||||
The expected exit code. If the actual exit code does not match, an exception is thrown.
|
||||
|
||||
.PARAMETER Multiline
|
||||
If true, the output is returned as an array of strings. Otherwise, the output is returned as a single string.
|
||||
|
||||
.PARAMETER ValidateExitCode
|
||||
If true, the actual exit code is compared to the expected exit code.
|
||||
|
||||
.EXAMPLE
|
||||
$result = Get-CommandResult "ls -la"
|
||||
|
||||
This command runs "ls -la" in bash and returns the output and exit code as hashtable.
|
||||
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $Command,
|
||||
[int[]] $ExpectedExitCode = 0,
|
||||
[switch] $Multiline,
|
||||
[bool] $ValidateExitCode = $true
|
||||
)
|
||||
|
||||
# Bash trick to suppress and show error output because some commands write to stderr (for example, "python --version")
|
||||
$stdout = & bash -c "$Command 2>&1"
|
||||
$exitCode = $LASTEXITCODE
|
||||
|
||||
if ($ValidateExitCode) {
|
||||
if ($ExpectedExitCode -notcontains $exitCode) {
|
||||
try {
|
||||
throw "StdOut: '$stdout' ExitCode: '$exitCode'"
|
||||
} catch {
|
||||
Write-Host $_.Exception.Message
|
||||
Write-Host $_.ScriptStackTrace
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return @{
|
||||
Output = If ($Multiline -eq $true) { $stdout } else { [string] $stdout }
|
||||
ExitCode = $exitCode
|
||||
}
|
||||
}
|
||||
|
||||
function Test-IsUbuntu22 {
|
||||
return (lsb_release -rs) -eq "22.04"
|
||||
}
|
||||
|
||||
function Test-IsUbuntu24 {
|
||||
return (lsb_release -rs) -eq "24.04"
|
||||
}
|
||||
|
||||
function Get-ToolsetContent {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieves the content of the toolset.json file.
|
||||
|
||||
.DESCRIPTION
|
||||
This function reads the toolset.json in path provided by INSTALLER_SCRIPT_FOLDER
|
||||
environment variable and returns the content as a PowerShell object.
|
||||
#>
|
||||
|
||||
$toolsetPath = Join-Path $env:INSTALLER_SCRIPT_FOLDER "toolset.json"
|
||||
$toolsetJson = Get-Content -Path $toolsetPath -Raw
|
||||
ConvertFrom-Json -InputObject $toolsetJson
|
||||
}
|
||||
|
||||
function Invoke-DownloadWithRetry {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Downloads a file from a given URL with retry functionality.
|
||||
|
||||
.DESCRIPTION
|
||||
The Invoke-DownloadWithRetry function downloads a file from the specified URL
|
||||
to the specified path. It includes retry functionality in case the download fails.
|
||||
|
||||
.PARAMETER Url
|
||||
The URL of the file to download.
|
||||
|
||||
.PARAMETER Path
|
||||
The path where the downloaded file will be saved. If not provided, a temporary path
|
||||
will be used.
|
||||
|
||||
.EXAMPLE
|
||||
Invoke-DownloadWithRetry -Url "https://example.com/file.zip" -Path "/usr/local/bin"
|
||||
Downloads the file from the specified URL and saves it to the specified path.
|
||||
|
||||
.EXAMPLE
|
||||
Invoke-DownloadWithRetry -Url "https://example.com/file.zip"
|
||||
Downloads the file from the specified URL and saves it to a temporary path.
|
||||
|
||||
.OUTPUTS
|
||||
The path where the downloaded file is saved.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $Url,
|
||||
[Alias("Destination")]
|
||||
[string] $DestinationPath
|
||||
)
|
||||
|
||||
if (-not $DestinationPath) {
|
||||
$invalidChars = [IO.Path]::GetInvalidFileNameChars() -join ''
|
||||
$re = "[{0}]" -f [RegEx]::Escape($invalidChars)
|
||||
$fileName = [IO.Path]::GetFileName($Url) -replace $re
|
||||
|
||||
if ([String]::IsNullOrEmpty($fileName)) {
|
||||
$fileName = [System.IO.Path]::GetRandomFileName()
|
||||
}
|
||||
$DestinationPath = Join-Path -Path "/tmp" -ChildPath $fileName
|
||||
}
|
||||
|
||||
Write-Host "Downloading package from $Url to $DestinationPath..."
|
||||
|
||||
$interval = 30
|
||||
$downloadStartTime = Get-Date
|
||||
for ($retries = 20; $retries -gt 0; $retries--) {
|
||||
try {
|
||||
$attemptStartTime = Get-Date
|
||||
Invoke-WebRequest -Uri $Url -Outfile $DestinationPath
|
||||
$attemptSeconds = [math]::Round(($(Get-Date) - $attemptStartTime).TotalSeconds, 2)
|
||||
Write-Host "Package downloaded in $attemptSeconds seconds"
|
||||
break
|
||||
} catch {
|
||||
$attemptSeconds = [math]::Round(($(Get-Date) - $attemptStartTime).TotalSeconds, 2)
|
||||
Write-Warning "Package download failed in $attemptSeconds seconds"
|
||||
Write-Warning $_.Exception.Message
|
||||
}
|
||||
|
||||
if ($retries -eq 0) {
|
||||
$totalSeconds = [math]::Round(($(Get-Date) - $downloadStartTime).TotalSeconds, 2)
|
||||
throw "Package download failed after $totalSeconds seconds"
|
||||
}
|
||||
|
||||
Write-Warning "Waiting $interval seconds before retrying (retries left: $retries)..."
|
||||
Start-Sleep -Seconds $interval
|
||||
}
|
||||
|
||||
return $DestinationPath
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using module ../software-report-base/SoftwareReport.psm1
|
||||
using module ../software-report-base/SoftwareReport.Nodes.psm1
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[string] $OutputDirectory
|
||||
)
|
||||
|
||||
$global:ErrorActionPreference = "Stop"
|
||||
$global:ErrorView = "NormalView"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Common.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Helpers.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "Common.Helpers.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Tools.psm1") -DisableNameChecking
|
||||
|
||||
# Restore file owner in user profile
|
||||
sudo chown -R ${env:USER}: $env:HOME
|
||||
|
||||
# Software report
|
||||
$softwareReport = [SoftwareReport]::new("Ubuntu-Slim")
|
||||
$softwareReport.Root.AddToolVersion("OS Version:", $(Get-OSVersionFull))
|
||||
$softwareReport.Root.AddToolVersion("Kernel Version:", $(Get-KernelVersion))
|
||||
$softwareReport.Root.AddToolVersion("Image Version:", $env:IMAGE_VERSION)
|
||||
$softwareReport.Root.AddToolVersion("Systemd version:", $(Get-SystemdVersion))
|
||||
|
||||
$installedSoftware = $softwareReport.Root.AddHeader("Installed Software")
|
||||
|
||||
# Language and Runtime
|
||||
$languageAndRuntime = $installedSoftware.AddHeader("Language and Runtime")
|
||||
$languageAndRuntime.AddToolVersion("Bash", $(Get-BashVersion))
|
||||
$languageAndRuntime.AddToolVersion("Dash", $(Get-DashVersion))
|
||||
$languageAndRuntime.AddToolVersion("Node.js", $(Get-NodeVersion))
|
||||
$languageAndRuntime.AddToolVersion("Perl", $(Get-PerlVersion))
|
||||
$languageAndRuntime.AddToolVersion("Python", $(Get-PythonVersion))
|
||||
|
||||
# Package Management
|
||||
$packageManagement = $installedSoftware.AddHeader("Package Management")
|
||||
$packageManagement.AddToolVersion("Npm", $(Get-NpmVersion))
|
||||
$packageManagement.AddToolVersion("Pip", $(Get-PipVersion))
|
||||
$packageManagement.AddToolVersion("Pip3", $(Get-Pip3Version))
|
||||
$packageManagement.AddToolVersion("Pipx", $(Get-PipxVersion))
|
||||
|
||||
# Tools
|
||||
$tools = $installedSoftware.AddHeader("Tools")
|
||||
$tools.AddToolVersion("AzCopy", $(Get-AzCopyVersion))
|
||||
$tools.AddToolVersion("Bicep", $(Get-BicepVersion))
|
||||
$tools.AddToolVersion("Git", $(Get-GitVersion))
|
||||
$tools.AddToolVersion("Git LFS", $(Get-GitLFSVersion))
|
||||
$tools.AddToolVersion("Git-ftp", $(Get-GitFTPVersion))
|
||||
$tools.AddToolVersion("jq", $(Get-JqVersion))
|
||||
$tools.AddToolVersion("nvm", $(Get-NvmVersion))
|
||||
$tools.AddToolVersion("OpenSSL", $(Get-OpensslVersion))
|
||||
$tools.AddToolVersion("yq", $(Get-YqVersion))
|
||||
$tools.AddToolVersion("zstd", $(Get-ZstdVersion))
|
||||
|
||||
# CLI Tools
|
||||
$cliTools = $installedSoftware.AddHeader("CLI Tools")
|
||||
$cliTools.AddToolVersion("AWS CLI", $(Get-AWSCliVersion))
|
||||
$cliTools.AddToolVersion("AWS CLI Session Manager Plugin", $(Get-AWSCliSessionManagerPluginVersion))
|
||||
$cliTools.AddToolVersion("AWS SAM CLI", $(Get-AWSSAMVersion))
|
||||
$cliTools.AddToolVersion("Azure CLI", $(Get-AzureCliVersion))
|
||||
$cliTools.AddToolVersion("Azure CLI (azure-devops)", $(Get-AzureDevopsVersion))
|
||||
$cliTools.AddToolVersion("GitHub CLI", $(Get-GitHubCliVersion))
|
||||
$cliTools.AddToolVersion("Google Cloud CLI", $(Get-GoogleCloudCLIVersion))
|
||||
|
||||
# PowerShell Tools
|
||||
$powerShellTools = $installedSoftware.AddHeader("PowerShell Tools")
|
||||
$powerShellTools.AddToolVersion("PowerShell", $(Get-PowershellVersion))
|
||||
|
||||
$installedSoftware.AddHeader("Installed apt packages").AddTable($(Get-AptPackages))
|
||||
|
||||
$softwareReport.ToJson() | Out-File -FilePath "${OutputDirectory}/software-report.json" -Encoding UTF8NoBOM
|
||||
$softwareReport.ToMarkdown() | Out-File -FilePath "${OutputDirectory}/software-report.md" -Encoding UTF8NoBOM
|
||||
@@ -0,0 +1,81 @@
|
||||
function Get-BashVersion {
|
||||
$version = bash -c 'echo ${BASH_VERSION}'
|
||||
return $version
|
||||
}
|
||||
|
||||
function Get-DashVersion {
|
||||
$version = dpkg-query -W -f '${Version}' dash
|
||||
return $version
|
||||
}
|
||||
|
||||
function Get-NodeVersion {
|
||||
$nodeVersion = $(node --version).Substring(1)
|
||||
return $nodeVersion
|
||||
}
|
||||
|
||||
function Get-OpensslVersion {
|
||||
$opensslVersion = $(dpkg-query -W -f '${Version}' openssl)
|
||||
return $opensslVersion
|
||||
}
|
||||
|
||||
function Get-PerlVersion {
|
||||
$version = $(perl -e 'print substr($^V,1)')
|
||||
return $version
|
||||
}
|
||||
|
||||
function Get-PythonVersion {
|
||||
$result = Get-CommandResult "python --version"
|
||||
$version = $result.Output | Get-StringPart -Part 1
|
||||
return $version
|
||||
}
|
||||
|
||||
function Get-PowershellVersion {
|
||||
$pwshVersion = $(pwsh --version) | Get-StringPart -Part 1
|
||||
return $pwshVersion
|
||||
}
|
||||
|
||||
function Get-NpmVersion {
|
||||
$npmVersion = npm --version
|
||||
return $npmVersion
|
||||
}
|
||||
|
||||
function Get-PipVersion {
|
||||
$pipVersion = pip --version | Get-StringPart -Part 1
|
||||
return $pipVersion
|
||||
}
|
||||
|
||||
function Get-Pip3Version {
|
||||
$pip3Version = pip3 --version | Get-StringPart -Part 1
|
||||
return $pip3Version
|
||||
}
|
||||
|
||||
function Get-AptPackages {
|
||||
$apt = (Get-ToolsetContent).Apt
|
||||
$output = @()
|
||||
ForEach ($pkg in ($apt.vital_packages + $apt.common_packages + $apt.cmd_packages)) {
|
||||
$version = $(dpkg-query -W -f '${Version}' $pkg)
|
||||
if ($null -eq $version) {
|
||||
$version = $(dpkg-query -W -f '${Version}' "$pkg*")
|
||||
}
|
||||
|
||||
$version = $version -replace '~','\~'
|
||||
|
||||
$output += [PSCustomObject] @{
|
||||
Name = $pkg
|
||||
Version = $version
|
||||
}
|
||||
}
|
||||
return ($output | Sort-Object Name)
|
||||
}
|
||||
|
||||
function Get-PipxVersion {
|
||||
$result = (Get-CommandResult "pipx --version").Output
|
||||
$result -match "(?<version>\d+\.\d+\.\d+\.?\d*)" | Out-Null
|
||||
return $Matches.Version
|
||||
}
|
||||
|
||||
function Get-SystemdVersion {
|
||||
$matchCollection = [regex]::Matches((systemctl --version | head -n 1), "\((.*?)\)")
|
||||
$result = foreach ($match in $matchCollection) {$match.Groups[1].Value}
|
||||
return $result
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
function Get-StringPart {
|
||||
param (
|
||||
[Parameter(ValueFromPipeline)]
|
||||
[string] $ToolOutput,
|
||||
[string] $Delimiter = " ",
|
||||
[int[]] $Part
|
||||
)
|
||||
|
||||
$parts = $ToolOutput.Split($Delimiter, [System.StringSplitOptions]::RemoveEmptyEntries)
|
||||
$selectedParts = $parts[$Part]
|
||||
return [string]::Join($Delimiter, $selectedParts)
|
||||
}
|
||||
|
||||
function Get-PathWithLink {
|
||||
param (
|
||||
[string] $InputPath
|
||||
)
|
||||
|
||||
$link = Get-Item $InputPath | Select-Object -ExpandProperty Target
|
||||
if (-not [string]::IsNullOrEmpty($link)) {
|
||||
return "${InputPath} -> ${link}"
|
||||
}
|
||||
return "${InputPath}"
|
||||
}
|
||||
|
||||
function Get-OSVersionShort {
|
||||
$(Get-OSVersionFull) | Get-StringPart -Delimiter '.' -Part 0,1
|
||||
}
|
||||
|
||||
function Get-OSVersionFull {
|
||||
lsb_release -ds | Get-StringPart -Part 1, 2
|
||||
}
|
||||
|
||||
function Get-KernelVersion {
|
||||
$kernelVersion = uname -r
|
||||
return $kernelVersion
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
function Get-AzCopyVersion {
|
||||
$azcopyVersion = [string]$(azcopy --version) | Get-StringPart -Part 2
|
||||
return "$azcopyVersion - available by ``azcopy`` and ``azcopy10`` aliases"
|
||||
}
|
||||
|
||||
function Get-BicepVersion {
|
||||
(bicep --version | Out-String) -match "bicep cli version (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
return $Matches.Version
|
||||
}
|
||||
|
||||
function Get-GitVersion {
|
||||
$gitVersion = git --version | Get-StringPart -Part -1
|
||||
return $gitVersion
|
||||
}
|
||||
|
||||
function Get-GitLFSVersion {
|
||||
$result = Get-CommandResult "git-lfs --version"
|
||||
$gitlfsversion = $result.Output | Get-StringPart -Part 0 | Get-StringPart -Part 1 -Delimiter "/"
|
||||
return $gitlfsversion
|
||||
}
|
||||
|
||||
function Get-GitFTPVersion {
|
||||
$gitftpVersion = git-ftp --version | Get-StringPart -Part 2
|
||||
return $gitftpVersion
|
||||
}
|
||||
|
||||
function Get-GoogleCloudCLIVersion {
|
||||
return (gcloud --version | Select-Object -First 1) | Get-StringPart -Part 3
|
||||
}
|
||||
|
||||
function Get-NvmVersion {
|
||||
$nvmVersion = bash -c "source /etc/skel/.nvm/nvm.sh && nvm --version"
|
||||
return $nvmVersion
|
||||
}
|
||||
|
||||
function Get-JqVersion {
|
||||
$jqVersion = jq --version | Get-StringPart -Part 1 -Delimiter "-"
|
||||
return $jqVersion
|
||||
}
|
||||
|
||||
function Get-AzureCliVersion {
|
||||
$azcliVersion = (az version | ConvertFrom-Json).'azure-cli'
|
||||
return $azcliVersion
|
||||
}
|
||||
|
||||
function Get-AzureDevopsVersion {
|
||||
$azdevopsVersion = (az version | ConvertFrom-Json).extensions.'azure-devops'
|
||||
return $azdevopsVersion
|
||||
}
|
||||
|
||||
function Get-AWSCliVersion {
|
||||
$result = Get-CommandResult "aws --version"
|
||||
$awsVersion = $result.Output | Get-StringPart -Part 0 | Get-StringPart -Part 1 -Delimiter "/"
|
||||
return $awsVersion
|
||||
}
|
||||
|
||||
function Get-AWSCliSessionManagerPluginVersion {
|
||||
$result = (Get-CommandResult "session-manager-plugin --version").Output
|
||||
return $result
|
||||
}
|
||||
|
||||
function Get-AWSSAMVersion {
|
||||
return $(sam --version | Get-StringPart -Part -1)
|
||||
}
|
||||
|
||||
function Get-GitHubCliVersion {
|
||||
$ghVersion = gh --version | Select-String "gh version" | Get-StringPart -Part 2
|
||||
return $ghVersion
|
||||
}
|
||||
|
||||
function Get-ZstdVersion {
|
||||
$zstdVersion = zstd --version | Get-StringPart -Part 1 -Delimiter "v" | Get-StringPart -Part 0 -Delimiter ","
|
||||
return "$zstdVersion"
|
||||
}
|
||||
|
||||
function Get-YqVersion {
|
||||
$yqVersion = $(yq -V) | Get-StringPart -Part 3
|
||||
return $yqVersion.TrimStart("v").Trim()
|
||||
}
|
||||
Reference in New Issue
Block a user