Last active
November 30, 2023 07:00
-
-
Save loopyd/714df05343083a7f8cb6ed40a10b8484 to your computer and use it in GitHub Desktop.
[POLYGLOT] DeiGEAR - Bootstrapper for Windows Subsystem for Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ================================================================================= | |
# Title: Dei G. E. A. R. - Grossly Enormous Automated Runner | |
# WSL2 Polyglot Bootstrapping Script | |
# | |
# Description: This script configures WSL2 the easy way. It is useful from | |
# outside of a WSL container to configure the WSL2 environment. It is also | |
# useful from within a WSL container to configure the WSL2 environment. Thus it is | |
# an all-in-one single file solution to configure/manage WSL2. | |
# | |
# --------------------------------------------------------------------------------- | |
# Author: deitydragon <[email protected]> | |
# Version: 0.1 | |
# --------------------------------------------------------------------------------- | |
# License: Unilicense (https://unlicense.org) | |
# | |
# You are free to use, modify and distribute this software as per the license | |
# agreement in the gist stated here. However, I would appreciate it if you could | |
# give credit to the original author by linking to the gist. | |
# | |
# ================================================================================= | |
# --------------------------------------------------------------------------------- | |
# wsl2-prep.ps1: PowerShell portion of the script | |
# --------------------------------------------------------------------------------- | |
<# | |
.SYNOPSIS | |
wslprep.ps1: The PowerShell portion of the wsl2-prep script. | |
.DESCRIPTION | |
This script registers a WSL distribution and configures it for use. | |
.PARAMETER Distro | |
The name of the WSL distribution to register. Defaults to 'ubuntu-22.04'. | |
.PARAMETER Username | |
The default username to create. Defaults to the current user. | |
.PARAMETER Password | |
The password to assign to the default user. Defaults to 'p@55w0rd1234!'. | |
.RETURNS | |
None | |
#> | |
param( | |
[Parameter(Mandatory=$false, HelpMessage="The name of the distrobution to work with.")]$Distro, | |
[Parameter(Mandatory=$false, HelpMessage="The root folder used by the -Import/-Export actions.")][string]$WSLRoot, | |
[Parameter(Mandatory=$false, HelpMessage="The -Register action registers the distrobution into the WSL2 registry.")][switch]$Register, | |
[Parameter(Mandatory=$false, HelpMessage="The -Unregister action unregisters the distrobution from the WSL2 registry, and deletes the root filesystem.")][switch]$Unregister, | |
[Parameter(Mandatory=$false, HelpMessage="The -Import action imports a saved distrobution tarball from the disk into the WSL2 registry.")][switch]$Import, | |
[Parameter(Mandatory=$false, HelpMessage="The -Export action commits a distrobution's disk to the host filesystem as a tarball.")][switch]$Export, | |
[Parameter(Mandatory=$false, HelpMessage="The -Check action displays status for the distrobution, and outputs a parseable exit code.")][switch]$Check, | |
[Parameter(Mandatory=$false, HelpMessage="The -Configure action configures the WSL2 instance.")][switch]$Configure, | |
[Parameter(Mandatory=$false, HelpMessage="The -Shutdown action shuts down the WSL2 instance.")][switch]$Shutdown, | |
[Parameter(Mandatory=$false, HelpMessage="The -Startup action starts up the WSL2 instance by sending a simple echo command. This forces the state of the WSL2 instance to 'Running'.")][switch]$Startup, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: write proper /etc/wsl.conf and `$env:USERPROFILE\.wslconfig")][switch]$UpdateWSLConfig, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: choose a default non-root username.")][string]$Username, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: choose the password for the non-root username.")][string]$Password, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Update the base system and packages.")][switch]$UpdateSystem, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Install dependencies required to build software.")][switch]$InstallBuildDependencies, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Install the specified CUDA toolkit/runtime version.")][string]$InstallCudaVersion, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Install the specified CuDNN toolkit/runtime version.")][string]$InstallCudnnVersion, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Install the specified Anaconda3 version")][string]$InstallAnacondaVersion, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Install the specified Python version")][string]$InstallPythonVersion, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Build/Install OpenSSL at the specified version")][string]$InstallOpenSSLVersion, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Installs Rust and Cargo.")][switch]$InstallRust, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Installs Poetry.")][switch]$InstallPoetry, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Install Docker CLI/runtime/daemon.")][switch]$InstallDocker, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Install NVIDIA Container Toolkit for docker.")][switch]$InstallNVCT, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Shows the internal configure script's help screen. Normally used for testing that output.")][switch]$ShowHelp, | |
[Parameter(Mandatory=$false, HelpMessage="For -Configure: Keep a local copy of the internal configure script on disk, and reference it -- For testing and debug purposes.")][switch]$DebugMode | |
) | |
<# | |
.SYNOPSIS | |
Automate-StartProcess: Starts a process and redirects the output to the console. | |
.DESCRIPTION | |
This function starts a process and redirects the output to the console. | |
.PARAMETER Program | |
The program to start. | |
.PARAMETER Arguments | |
The arguments to pass to the program. | |
.RETURNS | |
The exit code of the process. | |
#> | |
Function Automate-StartProcess() { | |
Param ( | |
[string]$Program, | |
[string[]]$Arguments | |
) | |
$oldEncoding = [Console]::OutputEncoding | |
[Console]::OutputEncoding = [System.Text.Encoding]::Unicode | |
$processData = [PSCustomObject]@{ | |
OutputData = New-Object System.Collections.Concurrent.ConcurrentQueue[string] | |
ErrorData = New-Object System.Collections.Concurrent.ConcurrentQueue[string] | |
Distro = $Distro | |
} | |
$processInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo | |
$processInfo.FileName = "pwsh.exe" | |
$processInfo.UseShellExecute = $false | |
$processInfo.RedirectStandardOutput = $true | |
$processInfo.RedirectStandardError = $true | |
$processInfo.WorkingDirectory = $PWD | |
$processInfo.CreateNoWindow = $true | |
$ArgumentsCombined = $Arguments -join " " | |
$ArgumentsBuilt = "-NoProfile -ExecutionPolicy Bypass -Command `"$Program $ArgumentsCombined | Out-String -Stream; exit `$LASTEXITCODE`"" | |
$processInfo.Arguments = $ArgumentsBuilt | |
$process = New-Object -TypeName System.Diagnostics.Process | |
$process.StartInfo = $processInfo | |
Write-Host -NoNewLine -ForegroundColor Black -BackgroundColor White "[$Distro]" | |
Write-Host -NoNewLine -ForegroundColor Magenta -BackgroundColor Black ": " | |
Write-Host -NoNewLine -ForegroundColor White -BackgroundColor Black "$Program $ArgumentsCombined`n`r" | |
$outputAction = { | |
$recievedData = $EventArgs.Data | Out-String -Stream | |
$recievedData = $recievedData ` | |
-replace "\0", "" ` | |
-replace "\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]", "" ` | |
-replace "\x1B\[[0-9]{1,2}m", "" ` | |
-replace "[\x00-\x1F]", "" ` | |
-replace "[^\x20-\x7E]", "" | |
if (! [String]::IsNullOrEmpty($recievedData)) { | |
$Event.MessageData.OutputData.Enqueue($recievedData) | |
$Distro = $Event.MessageData.Distro | |
Write-Host -NoNewLine -ForegroundColor Black -BackgroundColor Green "[$Distro]" | |
Write-Host -NoNewLine -ForegroundColor Yellow -BackgroundColor Black ": " | |
Write-Host -ForegroundColor Green $recievedData | |
} | |
} | |
$errorAction = { | |
$recievedData = $EventArgs.Data | Out-String -Stream | |
$recievedData = $EventArgs.Data | Out-String -Stream | |
$recievedData = $recievedData ` | |
-replace "\0", "" ` | |
-replace "\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]", "" ` | |
-replace "\x1B\[[0-9]{1,2}m", "" ` | |
-replace "[\x00-\x1F]", "" ` | |
-replace "[^\x20-\x7E]", "" | |
if (! [String]::IsNullOrEmpty($recievedData)) { | |
$Event.MessageData.ErrorData.Enqueue($recievedData) | |
$Distro = $Event.MessageData.Distro | |
Write-Host -NoNewLine -ForegroundColor Black -BackgroundColor Yellow "[$Distro]" | |
Write-Host -NoNewLine -ForegroundColor DarkYellow -BackgroundColor Black ": " | |
Write-Host -ForegroundColor Yellow $recievedData | |
} | |
} | |
$outputDataEvent = Register-ObjectEvent -InputObject $process -EventName "OutputDataReceived" -Action $outputAction -MessageData $processData | |
$errorDataEvent = Register-ObjectEvent -InputObject $process -EventName "ErrorDataReceived" -Action $errorAction -MessageData $processData | |
[Void]$process.Start() | |
$process.BeginOutputReadLine() | |
$process.BeginErrorReadLine() | |
# Main loop | |
while (!$process.HasExited) { | |
[System.Threading.Thread]::Sleep(5) | |
} | |
# Unregister the event handlers | |
Unregister-Event -SourceIdentifier $outputDataEvent.Name | |
Unregister-Event -SourceIdentifier $errorDataEvent.Name | |
[Console]::OutputEncoding = $oldEncoding | |
$exitCode = $process.ExitCode | |
if ($exitCode -ne 0) { | |
Write-Host -NoNewLine -ForegroundColor Black -BackgroundColor Red "[$Distro]" | |
Write-Host -NoNewLine -ForegroundColor Magenta -BackgroundColor Black ": " | |
Write-Host -NoNewLine -ForegroundColor Red -BackgroundColor Black "Command returned non-zero exit status code: $exitCode`n`r" | |
} else { | |
Write-Host -NoNewLine -ForegroundColor Black -BackgroundColor Cyan "[$Distro]" | |
Write-Host -NoNewLine -ForegroundColor DarkCyan -BackgroundColor Black ": " | |
Write-Host -NoNewLine -ForegroundColor Cyan -BackgroundColor Black "Command ran successfully`n`r" | |
} | |
return $exitCode | |
} | |
<# | |
.SYNOPSIS | |
Convert-PathToWsl: Converts a Windows path to a WSL path. | |
.DESCRIPTION | |
This function converts a Windows path to a WSL path. | |
.PARAMETER WindowsPath | |
The Windows path to convert. | |
.RETURNS | |
The converted WSL path. | |
#> | |
function Convert-PathToWsl { | |
param ( | |
[string]$WindowsPath | |
) | |
$wslPath = $WindowsPath -replace ":", "" -replace "\\", "/" | |
$wslPath = $wslPath.Substring(0,1).ToLower() + $wslPath.Substring(1) | |
$wslPath = "/mnt/" + $wslPath | |
return $wslPath | |
} | |
<# | |
.SYNOPSIS | |
Check-WSL: Checks the status of a WSL distribution. | |
.DESCRIPTION | |
This function checks the status of a WSL distribution by parsing wsl tool outoput. | |
#> | |
function Check-WSL() { | |
param ( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro, | |
[Parameter(Mandatory=$true,Position=2)][string]$WSLVersion, | |
[Parameter(Mandatory=$true,Position=3)][bool]$IsRunning | |
) | |
try { | |
$wsls = (wsl -l -v | Out-String -Stream | Where-Object { $_ -match '\*|\w+' } | Select-Object -Skip 1) | ForEach-Object { | |
$result = $_ -split '\s+' | Where-Object { $_ -match '\*|\w+' } | |
if ($result[0] -eq '*') { | |
[PSCustomObject]@{ | |
Default = $true | |
Distro = $result[1].Trim() | |
State = $result[2].Trim() | |
WSLVersion = $result[3].Trim() | |
} | |
} else { | |
[PSCustomObject]@{ | |
Default = $false | |
Distro = $result[0].Trim() | |
State = $result[1].Trim() | |
WSLVersion = $result[2].Trim() | |
} | |
} | |
} | Where-Object { | |
$_.Distro.ToLower() -eq $Distro.ToLower() -and | |
$_.WSLVersion -eq $WSLVersion -and | |
$_.State.ToLower() -eq ($IsRunning ? 'running' : 'stopped') | |
} | |
if ($wsls.Count -eq 0) { | |
return $false | |
} | |
return $true | |
} catch { | |
return $false | |
} | |
} | |
<# | |
.SYNOPSIS | |
Shutdown-WSL: Shuts down a WSL distribution. | |
.DESCRIPTION | |
This function shuts down a WSL distribution. | |
.PARAMETER Distro | |
The name of the WSL distribution to shut down. | |
.RETURNS | |
true if the WSL distribution was shut down successfully; otherwise, false. | |
#> | |
function Shutdown-WSL() { | |
param( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro | |
) | |
try { | |
if ($(Check-WSL -Distro $Distro -WSLVersion 2 -IsRunning $true) -eq $true) { | |
Write-Host "Shutting down WSL distribution '$Distro'..." | |
$result = Automate-StartProcess -Program "wsl" -Arguments @("-d", $Distro, "--shutdown") | |
if ($result -ne 0) { | |
throw "E: Failed to shutdown WSL distribution '$Distro'." | |
} | |
Start-Sleep -s 8 | |
} | |
return $true | |
} catch { | |
Write-Error "$($_.Exception.Message)" | |
return $false | |
} | |
} | |
<# | |
.SYNOPSIS | |
Startup-WSL: Starts up a WSL distribution. | |
.DESCRIPTION | |
This function starts up a WSL distribution by issuing a simple echo command. | |
.PARAMETER Distro | |
The name of the WSL distribution to start up. | |
.RETURNS | |
true if the WSL distribution was started up successfully; otherwise, false. | |
#> | |
function Startup-WSL() { | |
param( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro | |
) | |
try { | |
if ($(Check-WSL -Distro $Distro -WSLVersion 2 -IsRunning $false) -eq $true) { | |
$lc = Automate-StartProcess -Program "wsl" -Arguments @("-d", $Distro, "--", "echo", "'OK'") | |
if ($lc -ne 0) { | |
throw "E: Failed to startup WSL distribution '$Distro'." | |
} | |
Start-Sleep -s 8 | |
if (-not $(Check-WSL -Distro $Distro -WSLVersion 2 -IsRunning $true) -eq $true) { | |
throw "E: Failed to startup WSL distribution '$Distro'." | |
} | |
} | |
return $true | |
} catch { | |
Write-Error "$($_.Exception.Message)" | |
return $false | |
} | |
} | |
<# | |
.SYNOPSIS | |
Register-WSL: Registers a WSL distribution. | |
.DESCRIPTION | |
This function registers a WSL distribution. | |
.PARAMETER Distro | |
The name of the WSL distribution to register. | |
.RETURNS | |
None | |
#> | |
function Register-WSL() { | |
param ( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro | |
) | |
try { | |
$lc = Automate-StartProcess -Program "wsl" -Arguments @("--install", $Distro, "--no-launch") | |
if ($lc -ne 0) { | |
throw "E: Failed to install WSL distribution '$Distro'." | |
} | |
$DistroShort = $Distro -replace "-.*", "" | |
$lc = Automate-StartProcess -Program "$DistroShort" -Arguments @("install", "--root") | |
if ($lc -ne 0) { | |
throw "E: Failed to initialize WSL distribution '$Distro'." | |
} | |
Start-Sleep -s 8 | |
return $true | |
} catch { | |
Write-Error "$($_.Exception.Message)" | |
return $false | |
} | |
} | |
<# | |
.SYNOPSIS | |
Unregister-WSL: Unregisters a WSL distribution. | |
.DESCRIPTION | |
This function unregisters a WSL distribution. | |
.PARAMETER Distro | |
The name of the WSL distribution to unregister. | |
.RETURNS | |
None | |
#> | |
function Unregister-WSL() { | |
param ( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro | |
) | |
try { | |
if ($(Check-WSL -Distro $Distro -WSLVersion 2 -IsRunning $true) -eq $true) { | |
if (-not $(Shutdown-WSL -Distro $Distro)) { | |
throw "E: Failed to shutdown WSL distribution '$Distro'." | |
} | |
} | |
Write-Host "Unregistering WSL distribution '$Distro'..." | |
$DistroShort = $Distro -replace "-.*", "" | |
$lc = Automate-StartProcess -Program "wsl" -Arguments @("--unregister", $DistroShort) | |
if ($lc -ne 0) { | |
throw "E: Failed to unregister WSL distribution '$Distro'." | |
} | |
return $true | |
} catch { | |
Write-Error "$($_.Exception.Message)" | |
return $false | |
} | |
} | |
<# | |
.SYNOPSIS | |
Ensure-WSLPaths: Ensures the WSL paths exist. | |
.DESCRIPTION | |
This function ensures the WSL paths exist. | |
.PARAMETER Distro | |
The name of the WSL distribution to register. | |
.PARAMETER WSLRoot | |
The root path for WSL installations. | |
.RETURNS | |
true if the WSL paths exist / where created successfully; otherwise, false. | |
#> | |
function Ensure-WSLPaths() { | |
param( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro, | |
[Parameter(Mandatory=$false)][string]$WSLRoot | |
) | |
try { | |
# Ensure apprioriate paths exist | |
if (-not $(Test-Path -Path $WSLRoot)) { | |
New-Item -Path $WSLRoot -ItemType Directory -Force | Out-Null | |
if (-not $(Test-Path -Path $WSLRoot)) { | |
throw "E: Failed to create WSL root directory: '$WSLRoot'." | |
} | |
} | |
$InstallPath = $WSLRoot + "\" + $Distro | |
if (-not $(Test-Path -Path $InstallPath)) { | |
New-Item -Path $InstallPath -ItemType Directory -Force | Out-Null | |
if (-not $(Test-Path -Path $InstallPath)) { | |
throw "E: Failed to create WSL installation directory: '$InstallPath'." | |
} | |
} | |
return $true | |
} catch { | |
Write-Error "$($_.Exception.Message)" | |
return $false | |
} | |
} | |
<# | |
.SYNOPSIS | |
Import-WSL: Imports a WSL distribution. | |
.DESCRIPTION | |
This function imports a WSL distribution. | |
.PARAMETER Distro | |
The name of the WSL distribution to import. | |
.PARAMETER WSLRoot | |
The root path for WSL installations. | |
.RETURNS | |
None | |
#> | |
Function Import-WSL() { | |
param( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro, | |
[Parameter(Mandatory=$false)][string]$WSLRoot | |
) | |
try { | |
if (-not $(Ensure-WSLPaths -Distro $Distro -WSLRoot $WSLRoot)) { | |
throw "E: Failed to ensure WSL paths exist." | |
} | |
$InstallPath = $WSLRoot + "\" + $Distro | |
$ExportPath = $InstallPath + "\" + $Distro + ".tar" | |
if ($(Check-WSL -Distro $Distro -WSLVersion 2 -IsRunning $true) -eq $true) { | |
throw "E: WSL distribution '$Distro' is already imported and running." | |
} | |
$lc = Automate-StartProcess -Program "wsl" -Arguments @("--import", $Distro, $InstallPath, "`"$ExportPath`"") | |
if ($lc -ne 0) { | |
throw "E: Failed to import WSL distribution '$Distro'." | |
} | |
return $true | |
} catch { | |
Write-Error "$($_.Exception.Message)" | |
return $false | |
} | |
} | |
<# | |
.SYNOPSIS | |
Export-WSL: Exports a WSL distribution. | |
.DESCRIPTION | |
This function exports a WSL distribution. | |
.PARAMETER Distro | |
The name of the WSL distribution to export. | |
.PARAMETER WSLRoot | |
The root path for WSL installations. | |
.RETURNS | |
None | |
#> | |
Function Export-WSL() { | |
param( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro, | |
[Parameter(Mandatory=$false)][string]$WSLRoot | |
) | |
try { | |
$InstallPath = $WSLRoot + "\" + $Distro | |
$ExportPath = $InstallPath + "\" + $Distro + ".tar" | |
if ($(Test-Path -Path $ExportPath -PathType File) -and $(Test-Path -Path $InstallPath --PathType Directory)) { | |
Remove-Item -Path $ExportPath -Force | Out-Null | |
if ($(Test-Path -Path $ExportPath)) { | |
throw "E: Failed to remove old WSL disk image: '$ExportPath'." | |
} | |
} | |
if (-not $(Ensure-WSLPaths -Distro $Distro -WSLRoot $WSLRoot)) { | |
throw "E: Failed to ensure WSL export paths exist." | |
} | |
$lc = Automate-StartProcess -Program "wsl" -Arguments @("--export", $Distro, "`"$ExportPath`"") | |
if ($lc -ne 0) { | |
throw "E: Failed to export WSL distribution '$Distro'." | |
} | |
return $true | |
} catch { | |
Write-Error "$($_.Exception.Message)" | |
return $false | |
} | |
} | |
<# | |
.SYNOPSIS | |
Configure-WSL: Configures a WSL distribution | |
.DESCRIPTION | |
This function configures a WSL distribution. It is a wrapper for the wsl2-prep.sh script. | |
.PARAMETER Distro | |
The name of the WSL distribution to configure. | |
.PARAMETER WSLRoot | |
The root path for WSL installations. | |
.PARAMETER Username | |
The default username to create. | |
.PARAMETER Password | |
The password to assign to the default user. | |
.PARAMETER OS | |
The OS to configure. | |
.PARAMETER UpdateSystem | |
Boolean to determine if system packages should be updated. | |
.PARAMETER CudaVersion | |
The version of CUDA to install. | |
.PARAMETER CudnnVersion | |
The version of cuDNN to install. | |
.PARAMETER PythonVersion | |
The version of Python to install. | |
.PARAMETER InstallRust | |
Boolean to determine if Rust should be installed. | |
.PARAMETER InstallPoetry | |
Boolean to determine if Poetry should be installed. | |
.PARAMETER InstallDocker | |
Boolean to determine if Docker should be installed. | |
.PARAMETER InstallNVCT | |
Boolean to determine if NVIDIA Container Toolkit should be installed. | |
.PARAMETER Help | |
Boolean to determine if the help message should be displayed. | |
.PARAMETER Debug | |
Boolean to determine if the WSL2 internal configure script should be saved to local disk / referenced from local disk for debugging purposes. | |
.RETURNS | |
None | |
#> | |
function Configure-WSL() { | |
param( | |
[Parameter(Mandatory=$true,Position=1)][string]$Distro, | |
[Parameter(Mandatory=$false)][switch]$UpdateWSLConfig, | |
[Parameter(Mandatory=$false)][string]$Username, | |
[Parameter(Mandatory=$false)][string]$Password, | |
[Parameter(Mandatory=$false)][switch]$UpdateSystem, | |
[Parameter(Mandatory=$false)][switch]$InstallBuildDependencies, | |
[Parameter(Mandatory=$false)][string]$InstallCudaVersion, | |
[Parameter(Mandatory=$false)][string]$InstallCudnnVersion, | |
[Parameter(Mandatory=$false)][string]$InstallPythonVersion, | |
[Parameter(Mandatory=$false)][string]$InstallAnacondaVersion, | |
[Parameter(Mandatory=$false)][string]$InstallOpenSSLVersion, | |
[Parameter(Mandatory=$false)][switch]$InstallRust, | |
[Parameter(Mandatory=$false)][switch]$InstallPoetry, | |
[Parameter(Mandatory=$false)][switch]$InstallDocker, | |
[Parameter(Mandatory=$false)][switch]$InstallNVCT, | |
[Parameter(Mandatory=$false)][switch]$ShowHelp, | |
[Parameter(Mandatory=$false)][switch]$DebugMode | |
) | |
try { | |
$ScriptPath = (Split-Path -Parent $PSCommandPath) + "\wsl2-prep.sh" | |
if ($(Test-Path -Path $ScriptPath) -eq $true -and $DebugMode -eq $false) { | |
Remove-Item -Path $ScriptPath | |
} | |
if ($(Test-Path -Path $ScriptPath) -eq $false) { | |
($global:BASH_SCRIPT -replace "`r`n", "`n" -replace "`n`r", "`n") | Set-Content -Path $ScriptPath -NoNewline -Encoding UTF8 | |
} | |
if ($(Test-Path -Path $ScriptPath) -eq $false) { | |
throw "E: Failed to create configure script: '$ScriptPath'." | |
} | |
$DistroShort = $Distro -replace "-.*", "" | |
$lc = Automate-StartProcess -Program "wsl" -Arguments @( | |
"-d", $DistroShort, "-u", "root", "--", "cp", | |
$(Convert-PathToWsl -WindowsPath "$ScriptPath"), | |
"/usr/local/bin/wsl2-prep.sh") | |
if ($(Test-Path -Path $ScriptPath) -eq $true -and $DebugMode -eq $false) { | |
Remove-Item -Path $ScriptPath | |
} | |
if ($lc -ne 0) { | |
throw "E: Failed to copy configure script to WSL distribution '$Distro'." | |
} | |
$lc = Automate-StartProcess -Program "wsl" -Arguments @("-d", $DistroShort, "-u", "root", "--", "chmod", "+x", "/usr/local/bin/wsl2-prep.sh") | |
if ($lc -ne 0) { | |
throw "E: Failed to set permissions for configure script in WSL distribution '$Distro'." | |
} | |
$argsList = @( | |
"-d", $DistroShort, "-u", "root", "--", "/usr/local/bin/wsl2-prep.sh" | |
) | |
$argsList += "-o", $Distro | |
if ($ShowHelp -eq $true) { $argsList += "-h" } | |
if ($UpdateWSLConfig -eq $true) { $argsList += "-w" } | |
if ($UpdateSystem -eq $true) { $argsList += "-x" } | |
if ($InstallBuildDependencies -eq $true) { $argsList += "-b" } | |
if ($InstallNVCT -eq $true) { $argsList += "-n" } | |
if ($InstallRust -eq $true) { $argsList += "-r" } | |
if ($InstallPoetry -eq $true) { $argsList += "-y" } | |
if ($InstallDocker -eq $true) { $argsList += "-k" } | |
if ([String]::IsNullOrEmpty($InstallOpenSSLVersion) -eq $false) { $argsList += "-g", "`"$InstallOpenSSLVersion`"" } | |
if ([String]::IsNullOrEmpty($Username) -eq $false -and [String]::IsNullOrEmpty($Password) -eq $false) { $argsList += "-i", "-a", "`"$Username`"", "-t", "`"$Password`"" } | |
if ([String]::IsNullOrEmpty($InstallCudaVersion) -eq $false) { $argsList += "-c", "`"$InstallCudaVersion`"" } | |
if ([String]::IsNullOrEmpty($InstallCudnnVersion) -eq $false) { $argsList += "-e", "`"$InstallCudnnVersion`"" } | |
if ([String]::IsNullOrEmpty($InstallPythonVersion) -eq $false) { $argsList += "-p", "`"$InstallPythonVersion`"" } | |
if ([String]::IsNullOrEmpty($InstallAnacondaVersion) -eq $false) { $argsList += "-m", "`"$InstallAnacondaVersion`"" } | |
$lc = Automate-StartProcess -Program "wsl" -Arguments $argsList | |
if ($lc -ne 0) { | |
throw "E: Failed to execute wsl2-prep.sh script in WSL distrobution '$Distro'." | |
} | |
return $true | |
} catch { | |
Write-Error "$($_.Exception.Message)" | |
return $false | |
} | |
} | |
$global:BASH_SCRIPT = @' | |
#!/bin/bash | |
# ================================================================================= | |
# wsl2-prep.sh: bash portion of the script | |
# --------------------------------------------------------------------------------- | |
# | |
# Supported linux distributions: | |
# | |
# - Debian - Ubuntu - Linux Mint | |
# - Fedora - Arch Linux - CentOS | |
# - RHEL - Alpine - Gentoo | |
# - Funtoo - Exherbo - Sabayon | |
# - Solus - Void Linux - Artix Linux | |
# - Calculate - Clear Linux | |
# | |
# Please report any bugs with supported distributions to the author. | |
# | |
# ================================================================================= | |
if [[ $EUID -ne 0 ]]; then | |
echo "This script must be run as root" | |
exit 1 | |
fi | |
# --------------------------------------------------------------------------------- | |
# usage: Displays the usage of the script | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
usage() { | |
printf "%s\n" "---------------------------------------------------------------------------------" >&2 | |
printf "%-50s%s\n" "WSL2 Preparation Script" "Version 0.1" >&2 | |
printf "%-50s%s\n" "Author: loopyd <[email protected]>" "License: Unilicense" >&2 | |
printf "%s\n" "---------------------------------------------------------------------------------" >&2 | |
printf "\n%s\n" "This sysprep script configures WSL2 the easy way." >&2 | |
printf "\nUsage: %s: [Arguments]" $(basename $0) >&2 | |
printf "\n%-25s%-40s%s\n" "Arguments:" "Description:" "Environment Variable:" >&2 | |
printf "%-25s%-40s%s\n" "-h | --help" "Display this help message and exit" "" >&2 | |
printf "\n%s\n\n" "Auto WSL Options:" >&2 | |
printf "%-25s%-40s%s\n" "-o | --os OS" "Specify the OS to configure" "OS=ubuntu-22.04" >&2 | |
printf "%-25s%-40s%s\n" "-w | --wslconf" "Configure wslconfig and other options" "WSL=true" >&2 | |
printf "%-25s%-40s%s\n" "-i | --init" "Perform initialization" "INITSYS=true" >&2 | |
printf "%-25s%-40s%s\n" "-a | --username USERNAME" "Specify the username for the default user account" "INIT_USERNAME" >&2 | |
printf "%-25s%-40s%s\n" "-t | --password PASSWORD" "Specify the password for the default user account" "INIT_PASSWORD" >&2 | |
printf "%-25s%-40s%s\n" "-x | --system-update" "Update system packages" "SYSTEM_UPDATE=true" >&2 | |
printf "\n%s\n\n" "NVIDIA Options:" >&2 | |
printf "%-25s%-40s%s\n" "-c | --cuda VERSION" "Install CUDA runtime / SDK" "CUDA_VERSION=11.3" >&2 | |
printf "%-25s%-40s%s\n" "-e | --cudnn VERSION" "Install cuDNN runtime / libraries" "CUDNN_VERSION=8" >&2 | |
printf "\n%s\n\n" "Developer Toolkit Options:" >&2 | |
printf "%-25s%-40s%s\n" "-b | --build" "Install additional build dependencies" "BUILD_DEPS=true" >&2 | |
printf "%-25s%-40s%s\n" "-r | --rust" "Install Rust and Cargo" "RUST=true" >&2 | |
printf "%-25s%-40s%s\n" "-y | --poetry" "Install Poetry" "POETRY=true" >&2 | |
printf "%-25s%-40s%s\n" "-g | --openssl-version VERSION" "Install OpenSSL" "OPENSSL_VERSION=3.1.3" >&2 | |
printf "%-25s%-40s%s\n" "-p | --python VERSION" "Install Python" "PYTHON_VERSION=3.11.6" >&2 | |
printf "\n%s\n\n" "Docker Options:" >&2 | |
printf "%-25s%-40s%s\n" "-k | --docker" "Install Docker" "DOCKER=true" >&2 | |
printf "%-25s%-40s%s\n" "-n | --nvck" "Install NVIDIA Container Toolkit" "NVCK=true" >&2 | |
return | |
} | |
# --------------------------------------------------------------------------------- | |
# validate_version: Validates a version string | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# version: The version string to validate | |
# | |
# Returns: | |
# 0 if the version string is invalid, 1 otherwise | |
# | |
validate_version() { | |
local version=$1 | |
local regex='^([0-9]+\.){1,3}[0-9]+(-[A-Za-z0-9]+)?$' | |
if ! [[ $version =~ $regex ]]; then | |
return 0 | |
fi | |
return 1 | |
} | |
# --------------------------------------------------------------------------------- | |
# validate_os: Validates an OS string | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# os: The OS string to validate | |
# | |
# Returns: | |
# 0 if the OS string is invalid, 1 otherwise | |
# | |
validate_os() { | |
local os=$1 | |
local regex='^([a-zA-Z]+)(\-[0-9]+\.?[0-9]?|latest|lts)?$' | |
if ! [[ $os =~ $regex ]]; then | |
return 0 | |
fi | |
return 1 | |
} | |
# --------------------------------------------------------------------------------- | |
# validate_username: Validates a username string | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# username: The username string to validate | |
# | |
# Returns: | |
# 0 if the username string is invalid, 1 otherwise | |
# | |
validate_username() { | |
local username=$1 | |
local regex='^[a-z_][a-z0-9_-]*[$]?$' | |
if ! [[ $username =~ $regex ]]; then | |
return 0 | |
fi | |
return 1 | |
} | |
# --------------------------------------------------------------------------------- | |
# validate_password: Validates a password string | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# password: The password string to validate | |
# | |
# Returns: | |
# 0 if the password string is invalid, 1 otherwise | |
# | |
# Notes: | |
# | |
# Strict policy: | |
# | |
# - The password must be at least 8 characters long | |
# - The password must contain at least one lowercase letter | |
# - The password must contain at least one uppercase letter | |
# - The password must contain at least one number | |
# - The password must contain at least one special character of the following: | |
# ! @ # $ % ^ & * ( ) _ - + | |
# | |
validate_password() { | |
local password=$1 | |
local regex='^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[\!\@\#\$\%\^\&\*\(\)\_\-\+]).{8,}$' | |
if ! [[ $password =~ $regex ]]; then | |
return 0 | |
fi | |
return 1 | |
} | |
# --------------------------------------------------------------------------------- | |
# generate_password: Generates a password string | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# length: The length of the password to generate | |
# | |
# Returns: | |
# The generated password string | |
# | |
# Notes: | |
# | |
# Strict policy: | |
# | |
# - The generated password is at least 8 characters long | |
# - The generated password contains at least one lowercase letter | |
# - The generated password contains at least one uppercase letter | |
# - The generated password contains at least one number | |
# - The generated password contains at least one special character of the following: | |
# ! @ # $ % ^ & * ( ) _ - + | |
generate_password() { | |
local length=${1:-8} | |
local password | |
if (( length < 8 )); then | |
echo "error" | |
return 0 | |
fi | |
while true; do | |
password=$(LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^&*()_-+' < /dev/urandom | fold -w $length | head -n 1) | |
if validate_password "$password"; then | |
echo "$password" | |
return 1 | |
fi | |
done | |
} | |
# --------------------------------------------------------------------------------- | |
# convert_version_format: Converts a version string to a specific format | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# version_string: The version string to convert | |
# format_type: The format to convert the version string to | |
# | |
# Returns: | |
# The converted version string | |
# | |
convert_version_format() { | |
local version_string=$1 | |
local format_type=$2 | |
case $format_type in | |
"concat") | |
echo "$version_string" | sed -E 's/^([0-9]+)\.([0-9]+).*$/\1\2/' | |
;; | |
"two-part") | |
echo "$version_string" | sed -E 's/^([0-9]+)\.([0-9]+).*$/\1-\2/' | |
;; | |
"major") | |
echo "$version_string" | sed -E 's/^([0-9]+).*/\1/' | |
;; | |
"minor") | |
echo "$version_string" | sed -E 's/^[0-9]+\.([0-9]+).*/\1/' | |
;; | |
"patch") | |
echo "$version_string" | sed -E 's/^[0-9]+\.[0-9]+\.([0-9]+).*/\1/' | |
;; | |
"build") | |
echo "$version_string" | sed -E 's/^[0-9]+\.[0-9]+\.[0-9]+-([A-Za-z0-9]+).*/\1/' | |
;; | |
esac | |
} | |
# --------------------------------------------------------------------------------- | |
# parse_args: Parses the command line arguments | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# $@: The command line arguments | |
# | |
# Returns: | |
# None | |
parse_args() { | |
# Define the options | |
OPTIONS=ho:wnc:e:p:ryxbkia:t:g:m: | |
LONGOPTIONS=help,os:,wslconf,nvck,cuda:,cudnn:,python-version:,rust,poetry,system-update,build,docker,init,username:,password:,openssl-version:,anaconda-version: | |
# Parse the options | |
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTIONS --name "$0" -- "$@") | |
if [[ $? -ne 0 ]]; then | |
exit 2 | |
fi | |
eval set -- "$PARSED" | |
unset -v sub | |
while true; do | |
case "$1" in | |
-h | --help) | |
usage | |
exit 0 | |
;; | |
-o | --os) | |
if [ -z "$2" ]; then | |
echo "E: OS not specified" | |
exit 3 | |
fi | |
if [ "$(validate_os "$2")" == "0" ]; then | |
echo "E: Invalid OS string format: $2" | |
exit 3 | |
fi | |
os_name=$(echo "$2" | tr '[:upper:]' '[:lower:]' | cut -d'-' -f1) | |
if [[ $os_name != "debian" && $os_name != "ubuntu" ]]; then | |
echo "E: Unsupported OS: $2" | |
exit 3 | |
fi | |
OS="$os_name" | |
shift 2 | |
;; | |
-w | --wsl) | |
WSL="true" | |
shift | |
;; | |
-n | --nvck) | |
NVCK="true" | |
shift | |
;; | |
-c | --cuda) | |
if [ -z "$2" ]; then | |
echo "E: CUDA version not specified" | |
exit 3 | |
fi | |
if [ "$(validate_version "$2")" == "0" ]; then | |
echo "E: Invalid CUDA version: $2" | |
exit 3 | |
fi | |
CUDA_VERSION="$2" | |
shift 2 | |
;; | |
-e | --cudnn) | |
if [ -z "$2" ]; then | |
echo "E: cuDNN version not specified" | |
exit 3 | |
fi | |
if [ "$(validate_version "$2")" == "0" ]; then | |
echo "E: Invalid cuDNN version: $2" | |
exit 3 | |
fi | |
CUDNN_VERSION="$2" | |
shift 2 | |
;; | |
-p | --python) | |
if [ -z "$2" ]; then | |
echo "E: Python version not specified" | |
exit 3 | |
fi | |
if [ "$(validate_version "$2")" == "0" ]; then | |
echo "E: Invalid Python version: $2" | |
exit 3 | |
fi | |
PYTHON_VERSION="$2" | |
shift 2 | |
;; | |
-g | --openssl-version) | |
if [ -z "$2" ]; then | |
echo "E: OpenSSL version not specified" | |
exit 3 | |
fi | |
if [ "$(validate_version "$2")" == "0" ]; then | |
echo "E: Invalid OpenSSL version: $2" | |
exit 3 | |
fi | |
OPENSSL_VERSION="$2" | |
shift 2 | |
;; | |
-r | --rust) | |
RUST="true" | |
shift | |
;; | |
-y | --poetry) | |
POETRY="true" | |
shift | |
;; | |
-x | --system-update) | |
SYSTEM_UPDATE="true" | |
shift | |
;; | |
-b | --build) | |
BUILD_DEPS="true" | |
shift | |
;; | |
-k | --docker) | |
DOCKER="true" | |
shift | |
;; | |
-i | --init) | |
INITSYS="true" | |
shift | |
;; | |
-a | --username) | |
if [ -z "$2" ]; then | |
echo "E: Username not specified" | |
exit 3 | |
fi | |
if [ "$(validate_username "$2")" == "0" ]; then | |
echo "E: Invalid username: $2" | |
exit 3 | |
fi | |
INIT_USERNAME="$2" | |
shift 2 | |
;; | |
-t | --password) | |
if [ -z "$2" ]; then | |
echo "E: Password not specified" | |
exit 3 | |
fi | |
if [ "$(validate_password "$2")" == "0" ]; then | |
echo "E: Invalid password: $2" | |
exit 3 | |
fi | |
INIT_PASSWORD="$2" | |
shift 2 | |
;; | |
-m | --anaconda-version) | |
if [ -z "$2" ]; then | |
echo "E: Anaconda3 version not specified" | |
exit 3 | |
fi | |
ANACONDA_VERSION="$2" | |
shift 2 | |
;; | |
--) | |
shift | |
break | |
;; | |
*) | |
echo "E: Unrecognized option: $1" | |
exit 3 | |
;; | |
esac | |
done | |
if [ -z "$OS" ]; then | |
echo "E: Please specify the OS using the -o or --os option" | |
exit 4 | |
fi | |
if [ -z "$WSL" ]; then | |
WSL="false" | |
fi | |
if [ -z "$NVCK" ]; then | |
NVCK="false" | |
fi | |
if [ -z "$RUST" ]; then | |
RUST="false" | |
fi | |
if [ -z "$POETRY" ]; then | |
POETRY="false" | |
fi | |
if [ -z "$SYSTEM_UPDATE" ]; then | |
SYSTEM_UPDATE="false" | |
fi | |
if [ -z "$BUILD_DEPS" ]; then | |
BUILD_DEPS="false" | |
fi | |
if [ -z "$DOCKER" ]; then | |
DOCKER="false" | |
fi | |
if [ -z "$INITSYS" ]; then | |
if [ -n "$INIT_USERNAME" ] || [ -n "$INIT_PASSWORD" ]; then | |
echo "E: Please specify the -i | --init option to create the default user account" | |
exit 4 | |
fi | |
INITSYS="false" | |
else | |
if [ -z "$INIT_USERNAME" ] && [ -z "$INIT_PASSWORD" ]; then | |
echo "E: Please specify both the username and password using the -a | --username and -t | --password options" | |
exit 4 | |
fi | |
fi | |
if [ -n "$PYTHON_VERSION" ]; then | |
if [ -z "$PIP_VERSION" ]; then | |
PIP_VERSION="23.2.1" | |
fi | |
if [ -z "$SETUPTOOLS_VERSION" ]; then | |
SETUPTOOLS_VERSION="65.5.1" | |
fi | |
fi | |
if [[ $NVCK == "false" && $WSL == "false" && $RUST == "false" && $POETRY == "false" && $SYSTEM_UPDATE == "false" && $BUILD_DEPS == "false" && $DOCKER == "false" && $INITSYS == "false" && -z $CUDA_VERSION && -z $CUDNN_VERSION && -z $PYTHON_VERSION && -z $OPENSSL_VERSION && -z $ANACONDA_VERSION ]]; then | |
echo "E: No action specified. The script will do nothing." | |
exit 5 | |
fi | |
} | |
# --------------------------------------------------------------------------------- | |
# create_user: Creates a user account | |
# --------------------------------------------------------------------------------- | |
# | |
# Arguments: | |
# username: The username of the user to create | |
# | |
# Returns: | |
# None | |
init_system() { | |
local username="$1" | |
local password="$2" | |
local passHash | |
passHash=$(perl -e 'print crypt($ARGV[0], "password")' "$password") | |
echo "Creating user account: $username" | |
useradd -m -s /bin/bash -G sudo -p $passHash -u 1000 $username | |
chown -R $username:$username /home/$username | |
echo "$username ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers | |
} | |
# --------------------------------------------------------------------------------- | |
# manage_packages: Manages packages on the system | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# command: The command to execute | |
# packages_ref: The array of packages to manage | |
# | |
# Returns: | |
# None | |
# | |
manage_packages() { | |
local command="$1" | |
shift | |
local packages_ref=("$@") | |
case "$command" in | |
"update") | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
apt-get update || { echo "Updating package list failed"; exit 1; } | |
;; | |
"fedora") | |
dnf update || { echo "Updating package list failed"; exit 1; } | |
;; | |
"arch") | |
pacman -Syu || { echo "Updating package list failed"; exit 1; } | |
;; | |
"centos" | "rhel") | |
yum update || { echo "Updating package list failed"; exit 1; } | |
;; | |
"alpine") | |
apk update || { echo "Updating package list failed"; exit 1; } | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
emerge --sync || { echo "Updating package list failed"; exit 1; } | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
;; | |
"upgrade") | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
apt-get upgrade -y || { echo "Upgrading packages failed"; exit 1; } | |
;; | |
"fedora") | |
dnf upgrade -y || { echo "Upgrading packages failed"; exit 1; } | |
;; | |
"arch") | |
pacman -Syu --noconfirm || { echo "Upgrading packages failed"; exit 1; } | |
;; | |
"centos" | "rhel") | |
yum upgrade -y || { echo "Upgrading packages failed"; exit 1; } | |
;; | |
"alpine") | |
apk upgrade || { echo "Upgrading packages failed"; exit 1; } | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
emerge --update --deep --with-bdeps=y @world || { echo "Upgrading packages failed"; exit 1; } | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
;; | |
"install") | |
for package in "${packages_ref[@]}"; do | |
if manage_packages query_notinstalled "$package"; then | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
apt-get install -y --no-install-recommends "$package" 2>/dev/null || { echo "Installation of $package failed"; exit 1; } | |
;; | |
"fedora") | |
dnf install -y "$package" 2>/dev/null || { echo "Installation of $package failed"; exit 1; } | |
;; | |
"arch") | |
pacman -S --noconfirm "$package" 2>/dev/null || { echo "Installation of $package failed"; exit 1; } | |
;; | |
"centos" | "rhel") | |
yum install -y "$package" 2>/dev/null || { echo "Installation of $package failed"; exit 1; } | |
;; | |
"alpine") | |
apk add "$package" 2>/dev/null || { echo "Installation of $package failed"; exit 1; } | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
emerge "$package" 2>/dev/null || { echo "Installation of $package failed"; exit 1; } | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
else | |
echo "$package is already installed" | |
fi | |
done | |
;; | |
"autoremove" | "remove" | "purge") | |
for package in "${packages_ref[@]}"; do | |
if manage_packages query_installed "$package"; then | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
apt-get "$command" -y "$package" || { echo "Removal of $package failed"; exit 1; } | |
;; | |
"fedora") | |
dnf "$command" -y "$package" || { echo "Removal of $package failed"; exit 1; } | |
;; | |
"arch") | |
pacman -R --noconfirm "$package" || { echo "Removal of $package failed"; exit 1; } | |
;; | |
"centos" | "rhel") | |
yum "$command" -y "$package" || { echo "Removal of $package failed"; exit 1; } | |
;; | |
"alpine") | |
apk del "$package" || { echo "Removal of $package failed"; exit 1; } | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
emerge --unmerge "$package" || { echo "Removal of $package failed"; exit 1; } | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
else | |
echo "$package is not installed" | |
fi | |
done | |
;; | |
"clean") | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
apt-get autoremove -y && apt-get clean || { echo "Cleaning up failed"; exit 1; } | |
;; | |
"fedora") | |
dnf autoremove -y && dnf clean all || { echo "Cleaning up failed"; exit 1; } | |
;; | |
"arch") | |
pacman -Rns $(pacman -Qtdq) || { echo "Cleaning up failed"; exit 1; } | |
;; | |
"centos" | "rhel") | |
yum autoremove -y && yum clean all || { echo "Cleaning up failed"; exit 1; } | |
;; | |
"alpine") | |
apk autoremove && apk clean || { echo "Cleaning up failed"; exit 1; } | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
emerge --depclean || { echo "Cleaning up failed"; exit 1; } | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
;; | |
"query_installed") | |
packages_len=${#packages_ref[@]} | |
for package in "${packages_ref[@]}"; do | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
if dpkg-query -W -f='${Status}' "$package" 2>/dev/null | grep -q "ok installed"; then | |
((packages_len--)) | |
fi | |
;; | |
"fedora") | |
if rpm -q "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
"arch") | |
if pacman -Q "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
"centos" | "rhel") | |
if yum list installed "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
"alpine") | |
if apk info "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
if eix -I "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
done | |
if (( packages_len == 0 )); then | |
return 0 | |
else | |
return 1 | |
fi | |
;; | |
"query_notinstalled") | |
packages_len=${#packages_ref[@]} | |
for package in "${packages_ref[@]}"; do | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
if ! dpkg-query -W -f='${Status}' "$package" 2>/dev/null | grep -q "ok installed"; then | |
((packages_len--)) | |
fi | |
;; | |
"fedora") | |
if ! rpm -q "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
"arch") | |
if ! pacman -Q "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
"centos" | "rhel") | |
if ! yum list installed "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
"alpine") | |
if ! apk info "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
if ! eix -I "$package" &>/dev/null ; then | |
((packages_len--)) | |
fi | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
done | |
if (( packages_len == 0 )); then | |
return 0 | |
else | |
return 1 | |
fi | |
;; | |
"query_available") | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
apt-cache search "${packages_ref[@]}" | grep -F -x -v -f <(printf '%s\n' "${packages_ref[@]}") && return 1 || return 0 | |
;; | |
"fedora") | |
dnf search "${packages_ref[@]}" | grep -F -x -v -f <(printf '%s\n' "${packages_ref[@]}") && return 1 || return 0 | |
;; | |
"arch") | |
pacman -Ss "${packages_ref[@]}" | grep -F -x -v -f <(printf '%s\n' "${packages_ref[@]}") && return 1 || return 0 | |
;; | |
"centos" | "rhel") | |
yum search "${packages_ref[@]}" | grep -F -x -v -f <(printf '%s\n' "${packages_ref[@]}") && return 1 || return 0 | |
;; | |
"alpine") | |
apk search "${packages_ref[@]}" | grep -F -x -v -f <(printf '%s\n' "${packages_ref[@]}") && return 1 || return 0 | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
eix "${packages_ref[@]}" | grep -F -x -v -f <(printf '%s\n' "${packages_ref[@]}") && return 1 || return 0 | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
;; | |
"blacklist") | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
for package in "${packages_ref[@]}"; do | |
echo "Package: $package" | |
echo "Pin: release *" | |
echo "Pin-Priority: -1" | |
done >> /etc/apt/preferences.d/01autoremove-blacklist | |
;; | |
"fedora") | |
for package in "${packages_ref[@]}"; do | |
echo "exclude=$package" >> /etc/dnf/dnf.conf | |
done | |
;; | |
"arch") | |
for package in "${packages_ref[@]}"; do | |
echo "IgnorePkg=$package" >> /etc/pacman.conf | |
done | |
;; | |
"centos" | "rhel") | |
for package in "${packages_ref[@]}"; do | |
echo "exclude=$package" >> /etc/yum.conf | |
done | |
;; | |
"alpine") | |
for package in "${packages_ref[@]}"; do | |
echo "$package" >> /etc/apk/world | |
done | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
for package in "${packages_ref[@]}"; do | |
echo "=$package" >> /etc/portage/package.mask | |
done | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
;; | |
"whitelist") | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
for package in "${packages_ref[@]}"; do | |
sed -i "/Package: $package/,+2d" /etc/apt/preferences.d/01autoremove-blacklist | |
done | |
;; | |
"fedora") | |
for package in "${packages_ref[@]}"; do | |
sed -i "/$package/d" /etc/dnf/dnf.conf | |
done | |
;; | |
"arch") | |
for package in "${packages_ref[@]}"; do | |
sed -i "/$package/d" /etc/pacman.conf | |
done | |
;; | |
"centos" | "rhel") | |
for package in "${packages_ref[@]}"; do | |
sed -i "/$package/d" /etc/yum.conf | |
done | |
;; | |
"alpine") | |
for package in "${packages_ref[@]}"; do | |
sed -i "/$package/d" /etc/apk/world | |
done | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
for package in "${packages_ref[@]}"; do | |
sed -i "/$package/d" /etc/portage/package.mask | |
done | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
;; | |
*) | |
echo "Unknown command: $command" | |
exit 1 | |
;; | |
esac | |
} | |
# --------------------------------------------------------------------------------- | |
# update_system: Updates the system | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
update_system() { | |
manage_packages update | |
manage_packages upgrade | |
manage_packages clean | |
} | |
# --------------------------------------------------------------------------------- | |
# install_build_deps: Installs additional build dependencies | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
install_build_deps() { | |
local distro_packages=() | |
case $OS in | |
"debian" | "ubuntu" | "mint") | |
distro_packages=( | |
build-essential wslu bc wget curl ca-certificates apt-utils apt-transport-https git gnupg2 | |
make pkg-config libssl-dev g++ llvm clang lld zlib1g-dev libbz2-dev libreadline-dev | |
zip unzip cmake ninja-build gawk valgrind libgmp-dev libmpfr-dev libmpc-dev | |
ffmpeg imagemagick libopencv-dev libopencv-core-dev libopencv-highgui-dev | |
libboost-dev libboost-filesystem-dev libboost-regex-dev | |
coreutils jq openssl rsync diffutils zip binutils patchutils opus-tools sox | |
patch libtool m4 automake lcov htop tmux vim nano emacs-nox neovim | |
clang autoconf bison flex gperf texinfo help2man | |
bzip2 xz-utils gzip tar p7zip-full cpio | |
) | |
;; | |
"fedora") | |
distro_packages=( | |
@development-tools wslu bc wget curl ca-certificates git gnupg2 | |
make pkg-config openssl-devel gcc-c++ llvm clang lld zlib-devel bzip2-devel readline-devel | |
zip unzip cmake ninja-build gawk valgrind gmp-devel mpfr-devel libmpc-devel | |
ffmpeg ImageMagick opencv-devel boost-devel | |
coreutils jq openssl rsync diffutils zip binutils patchutils opus-tools sox | |
patch libtool m4 automake lcov htop tmux vim nano emacs-nox neovim | |
clang autoconf bison flex gperf texinfo help2man | |
bzip2 xz gzip tar p7zip cpio | |
) | |
;; | |
"arch") | |
distro_packages=( | |
base-devel wslu bc wget curl ca-certificates git gnupg | |
make pkg-config openssl gcc llvm clang lld zlib bzip2 readline | |
zip unzip cmake ninja gawk valgrind gmp mpfr libmpc | |
ffmpeg imagemagick opencv boost | |
coreutils jq openssl rsync diffutils zip binutils patchutils opus-tools sox | |
patch libtool m4 automake lcov htop tmux vim nano emacs-nox neovim | |
clang autoconf bison flex gperf texinfo help2man | |
bzip2 xz gzip tar p7zip cpio | |
) | |
;; | |
"centos" | "rhel") | |
distro_packages=( | |
@development-tools wslu bc wget curl ca-certificates git gnupg2 | |
make pkg-config openssl-devel gcc-c++ llvm clang lld zlib-devel bzip2-devel readline-devel | |
zip unzip cmake ninja-build gawk valgrind gmp-devel mpfr-devel libmpc-devel | |
ffmpeg ImageMagick opencv-devel boost-devel | |
coreutils jq openssl rsync diffutils zip binutils patchutils opus-tools sox | |
patch libtool m4 automake lcov htop tmux vim nano emacs-nox neovim | |
clang autoconf bison flex gperf texinfo help2man | |
bzip2 xz gzip tar p7zip cpio | |
) | |
;; | |
"alpine") | |
distro_packages=( | |
build-base wslu bc wget curl ca-certificates git gnupg | |
make pkgconf openssl-dev gcc llvm clang lld zlib bzip2 readline | |
zip unzip cmake ninja gawk valgrind gmp mpfr libmpc | |
ffmpeg imagemagick opencv boost | |
coreutils jq openssl rsync diffutils zip binutils patchutils opus-tools sox | |
patch libtool m4 automake lcov htop tmux vim nano emacs-nox neovim | |
clang autoconf bison flex gperf texinfo help2man | |
bzip2 xz gzip tar p7zip cpio | |
) | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
distro_packages=( | |
wslu bc wget curl ca-certificates git gnupg | |
make pkgconf openssl gcc llvm clang lld zlib bzip2 readline | |
zip unzip cmake ninja gawk valgrind gmp mpfr libmpc | |
ffmpeg imagemagick opencv boost | |
coreutils jq openssl rsync diffutils zip binutils patchutils opus-tools sox | |
patch libtool m4 automake lcov htop tmux vim nano emacs-nox neovim | |
clang autoconf bison flex gperf texinfo help2man | |
bzip2 xz gzip tar p7zip cpio | |
) | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
manage_packages install "${distro_packages[@]}" | |
} | |
# --------------------------------------------------------------------------------- | |
# install_wslconf: Installs WSL utilities | |
install_anaconda() { | |
local ANACONDA_VERSION=${1:-2023.09-0} | |
local ANACONDA_DIR="/usr/local/anaconda3" | |
local ANACONDA_BUILD_DIR="$(mktemp -d)" | |
if [ -d "$ANACONDA_DIR" ]; then | |
echo "Anaconda3 is already installed" | |
return 0 | |
fi | |
if [ -f /var/log/anaconda-build.log ]; then | |
rm -f /var/log/anaconda-build.log | |
fi | |
anaconda_packages=() | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
anaconda_packages=( | |
libgl1-mesa-glx libegl1-mesa libxrandr2 libxrandr2 libxss1 libxcursor1 libxcomposite1 libasound2 libxi6 libxtst6 | |
) | |
;; | |
"fedora") | |
anaconda_packages=( | |
mesa-libGL mesa-libEGL libXrandr libXrandr libXScrnSaver libXcursor libXcomposite alsa-lib libXi libXtst | |
) | |
;; | |
"arch") | |
anaconda_packages=( | |
libglvnd libxrandr libxss libxcursor libxcomposite libxtst alsa-lib libxi | |
) | |
;; | |
"centos" | "rhel") | |
anaconda_packages=( | |
libXcomposite libXcursor libXi libXtst libXrandr alsa-lib mesa-libEGL libXdamage mesa-libGL libXScrnSaver | |
) | |
;; | |
"alpine") | |
anaconda_packages=( | |
mesa-gl mesa-egl libxrandr libxss libxcursor libxcomposite libxtst alsa-lib libxi | |
) | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
anaconda_packages=( | |
mesa libxrandr libxss libxcursor libxcomposite libxtst alsa-lib libxi | |
) | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
manage_packages install "${anaconda_packages[@]}" | |
echo "Downloading Anaconda3 build script..." | |
{ | |
mkdir -p "$ANACONDA_BUILD_DIR" | |
curl -S -L "https://repo.anaconda.com/archive/Anaconda3-${ANACONDA_VERSION}-Linux-x86_64.sh" -o "${ANACONDA_BUILD_DIR}/anaconda3-install.sh" | |
chmod +x "${ANACONDA_BUILD_DIR}/anaconda3-install.sh" | |
} 2>&1 | tee -a /var/log/anaconda-build.log | |
echo "Installing Anaconda3..." | |
{ | |
pushd "${ANACONDA_BUILD_DIR}" || { echo "Failed to change directory to $ANACONDA_BUILD_DIR"; exit 1; } | |
bash ./anaconda3-install.sh -b -p "$ANACONDA_DIR" -f | |
popd || { echo "Failed to change directory back"; exit 1; } | |
rm -rfv "$ANACONDA_BUILD_DIR" || { echo "Failed to remove $ANACONDA_BUILD_DIR"; exit 1; } | |
} 2>&1 | tee -a /var/log/anaconda-build.log | |
if [ ! -d "$ANACONDA_DIR" ]; then | |
echo "E: Anaconda3 installation failed" | |
exit 1 | |
fi | |
echo "Configuring anaconda3..." | tee -a /var/log/anaconda-build.log | |
{ | |
if ! getent group python >/dev/null; then | |
groupadd python | |
fi | |
chown -R root:root "$ANACONDA_DIR" | |
chgrp -R python "$ANACONDA_DIR" | |
chmod -R 750 "$ANACONDA_DIR" | |
if [ ! -f /etc/profile.d/anaconda3.sh ]; then | |
echo "Creating /etc/profile.d/anaconda3.sh..." | |
cat <<EOF | tee /etc/profile.d/anaconda3.sh | |
export ANACONDA_DIR="$ANACONDA_DIR" | |
if id -nG "\$USER" | grep -qw "python"; then | |
export PATH="$ANACONDA_DIR/bin:\$PATH" | |
source $ANACONDA_DIR/bin/activate | |
fi | |
EOF | |
export PATH="$ANACONDA_DIR/bin:\$PATH" | |
source $ANACONDA_DIR/bin/activate | |
conda init | |
coda config --set auto_activate_base false | |
conda deactivate | |
fi | |
} 2>&1 | tee -a /var/log/anaconda-build.log | |
# Variables to unset | |
variables_to_unset=( | |
ANACONDA_DIR | |
ANACONDA_BUILD_DIR | |
) | |
for var in "${variables_to_unset[@]}"; do | |
unset "$var" | |
done | |
} | |
# --------------------------------------------------------------------------------- | |
# install_rust: Installs Rust and Cargo | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
install_rust() { | |
echo "Installing Rust..." | |
export TMP_RUST_DIR="$(mktemp -d)" | |
pushd "${TMP_RUST_DIR}" | |
curl -sLf "https://static.rust-lang.org/dist/rust-${RUST_VERSION}-x86_64-unknown-linux-gnu.tar.gz" | \ | |
tar xvzf - -C "${TMP_RUST_DIR}" --strip-components=1 --exclude=rust-docs | |
./install.sh --verbose | |
popd | |
rm -rf "${TMP_RUST_DIR}" | |
} | |
# --------------------------------------------------------------------------------- | |
# install_poetry: Installs Poetry | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
install_poetry() { | |
echo "Installing Poetry..." | |
curl -sSL https://install.python-poetry.org | python3 - >&1 | |
local ntusername=$(basename "$(wslpath $(wslvar USERPROFILE))") | |
poetry completions bash >> /home/$ntusername/.bash_completion | |
chown $ntusername:$ntusername /home/$ntusername/.bash_completion | |
EOF | |
} | |
# --------------------------------------------------------------------------------- | |
# install_openssl: Installs OpenSSL | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
install_openssl() { | |
local OPENSSL_VERSION=${1:-3.1.3} | |
export OPENSSL_BUILD_DIR="$(mktemp -d)" | |
export NPROC=$(nproc) | |
# check installed version doesn't match requested version | |
if [ "$(openssl version | cut -d' ' -f2)" == "$OPENSSL_VERSION" ]; then | |
echo "OpenSSL $OPENSSL_VERSION is already installed" | |
return 0 | |
fi | |
echo "Installing OpenSSL..." | |
echo "Download OpenSSL" | tee -a /var/log/openssl-build.log | |
{ | |
openssl_tar=$(mktemp) | |
wget -O "$openssl_tar" --no-check-certificate https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz | |
tar --extract --gzip --directory "$OPENSSL_BUILD_DIR" --strip-components=1 --file "$openssl_tar" | |
rm -f "$openssl_tar" | |
} 2>&1 | tee -a /var/log/openssl-build.log | |
echo "Building OpenSSL" | tee -a /var/log/openssl-build.log | |
{ | |
pushd "$OPENSSL_BUILD_DIR" || { echo "Failed to change directory to $OPENSSL_BUILD_DIR"; exit 1; } | |
./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl --libdir=lib -shared | |
make -j "$NPROC" | |
make uninstall | |
make install | |
popd || { echo "Failed to change directory back"; exit 1; } | |
rm -rf "$OPENSSL_BUILD_DIR" | |
} 2>&1 | tee -a /var/log/openssl-build.log | |
variables_to_unset=( | |
OPENSSL_BUILD_DIR | |
NPROC | |
) | |
for var in "${variables_to_unset[@]}"; do | |
unset "$var" | |
done | |
} | |
# --------------------------------------------------------------------------------- | |
# install_python: Installs Python and PIP | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
install_pyenv() { | |
local PYTHON_VERSION=${1:-3.11.6} | |
local PYENV_DIR="/usr/local/pyenv" | |
export LANG=C.UTF-8 | |
export DEBIAN_FRONTEND=noninteractive | |
export NPROC=$(nproc) | |
if [ -f /usr/local/pyenv/bin/pyenv ]; then | |
echo "Pyenv is already installed" | |
return 0 | |
fi | |
if [ -f /var/log/python-build.log ]; then | |
rm -f /var/log/python-build.log | |
touch /var/log/python-build.log | |
fi | |
echo "Installing python build dependencies..." | tee -a /var/log/python-build.log | |
{ | |
case "$OS" in | |
"debian" | "ubuntu" | "mint") | |
python_deps=( | |
dpkg-dev dpkg-sig gpgv2 equivs | |
libbz2-dev libexpat1-dev libffi-dev liblzma-dev libncursesw5-dev | |
zlib1g-dev libbluetooth-dev libncurses-dev libz-dev tk-dev libsqlite3-dev | |
libreadline-dev libgdm-dev libgdbm-compat-dev llvm libssl-dev | |
) | |
;; | |
"fedora") | |
python_deps=( | |
rpm-build rpm-sign gnupg2 | |
bzip2-devel expat-devel libffi-devel lzma-devel ncurses-devel | |
zlib-devel bluez-libs-devel ncurses-devel zlib-devel tk-devel sqlite-devel | |
readline-devel gdbm-devel llvm libssl-devel | |
) | |
;; | |
"arch") | |
python_deps=( | |
base-devel gnupg | |
bzip2 expat libffi xz ncurses zlib tk sqlite readline gdbm llvm libssl | |
) | |
;; | |
"centos" | "rhel") | |
python_deps=( | |
rpm-build rpm-sign gnupg2 | |
bzip2-devel expat-devel libffi-devel lzma-devel ncurses-devel | |
zlib-devel bluez-libs-devel ncurses-devel zlib-devel tk-devel sqlite-devel | |
readline-devel gdbm-devel llvm libssl-devel | |
) | |
;; | |
"alpine") | |
python_deps=( | |
build-base gnupg | |
bzip2-dev expat-dev libffi-dev xz-dev ncurses-dev zlib-dev tk-dev sqlite-dev | |
readline-dev gdbm-dev llvm libssl-dev | |
) | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
python_deps=( | |
gnupg | |
bzip2 expat libffi xz ncurses zlib tk sqlite readline gdbm llvm libssl | |
) | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
manage_packages update | |
manage_packages install "${python_deps[@]}" | |
manage_packages clean | |
} 2>&1 | tee -a /var/log/python-build.log | |
# echo "Downloading and verifying Python source..." | tee -a /var/log/python-build.log | |
# { | |
# python_tar=$(mktemp) | |
# python_asc=$(mktemp) | |
# wget -O "$python_tar" "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz" | |
# wget -O "$python_asc" "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc" | |
# GNUPGHOME="$(mktemp -d)" | |
# export GNUPGHOME | |
# gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$GPG_KEY" | |
# gpg --batch --verify "$python_asc" "$python_tar" | |
# gpgconf --kill all | |
# rm -rf $GNUPGHOME | |
# tar --extract --directory "$PYTHON_BUILD_DIR" --strip-components=1 --file "$python_tar" | |
# rm -f "$python_tar" "$python_asc" | |
# for src in idle2 pydoc2 python2 python2-config idle3 pydoc3 python3 python3-config; do | |
# for ver in 2 3; do | |
# dst="$(echo "$src" | tr -d $ver)" | |
# [ -s "/usr/local/bin/$src" ] && [ -e "/usr/local/bin/$dst" ] && \ | |
# rm -v "/usr/local/bin/$dst" | |
# done | |
# done | |
# } 2>&1 | tee -a /var/log/python-build.log | |
# echo "Building Python..." | tee -a /var/log/python-build.log | |
# { | |
# pushd "$PYTHON_BUILD_DIR" || { echo "Failed to change directory to $PYTHON_BUILD_DIR"; exit 1; } | |
# gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ | |
# ./configure \ | |
# --build="$gnuArch" \ | |
# --enable-loadable-sqlite-extensions \ | |
# --enable-optimizations \ | |
# --enable-option-checking=fatal \ | |
# --enable-shared \ | |
# --with-lto \ | |
# --with-system-expat \ | |
# --without-ensurepip \ | |
# --prefix=/usr/local \ | |
# --with-openssl=/usr/local/ssl \ | |
# --with-openssl-rpath=/usr/local/lib \ | |
# --with-ssl-default-suites=openssl \ | |
# ; \ | |
# nproc="$(nproc)"; \ | |
# EXTRA_CFLAGS="$(dpkg-buildflags --get CFLAGS)"; \ | |
# LDFLAGS="$(dpkg-buildflags --get LDFLAGS)"; \ | |
# make -j "$nproc" \ | |
# "EXTRA_CFLAGS=${EXTRA_CFLAGS:-}" \ | |
# "LDFLAGS=${LDFLAGS:-}" ; \ | |
# rm python; \ | |
# make -j "$nproc" \ | |
# "EXTRA_CFLAGS=${EXTRA_CFLAGS:-}" \ | |
# "LDFLAGS=${LDFLAGS:--Wl},-rpath='\$\$ORIGIN/../lib'" \ | |
# python \ | |
# ; \ | |
# make install | |
# popd || { echo "Failed to change directory back"; exit 1; } | |
# } 2>&1 | tee -a /var/log/python-build.log | |
# echo "Configuring installation..." | tee -a /var/log/python-build.log | |
# { | |
# pushd "$PYTHON_BUILD_DIR" || { echo "Failed to change directory to $PYTHON_BUILD_DIR"; exit 1; } | |
# bin="$(readlink -ve /usr/local/bin/python$PYTHON_MAJOR_VERSION)" | |
# dir="$(dirname "$bin")" | |
# mkdir -p "/usr/share/gdb/auto-load/$dir" | |
# cp -vL Tools/gdb/libpython.py "/usr/share/gdb/auto-load/$bin-gdb.py" | |
# popd || { echo "Failed to change directory back"; exit 1; } | |
# rm -rf "$PYTHON_BUILD_DIR" | |
# find /usr/local/bin -depth \ | |
# \( \ | |
# \( -type d -a \( -name test -o -name tests -o -name idle_test \) \) \ | |
# -o \( -type f -a \( -name '*.pyc' -o -name '*.pyo' -o -name 'libpython*.a' \) \) \ | |
# \) -exec rm -rf '{}' + | |
# ldconfig | |
# for src in idle$PYTHON_MAJOR_VERSION pydoc$PYTHON_MAJOR_VERSION python$PYTHON_MAJOR_VERSION python$PYTHON_MAJOR_VERSION-config; do | |
# dst="$(echo "$src" | tr -d $PYTHON_MAJOR_VERSION)" | |
# if [ -s "/usr/local/bin/$src" ]; then | |
# if [ -e "/usr/local/bin/$dst" ]; then | |
# echo "Removing existing symlink: /usr/local/bin/$dst" | |
# rm "/usr/local/bin/$dst" | |
# fi | |
# echo "Creating new symlink: /usr/local/bin/$dst -> $src" | |
# ln -svT "$src" "/usr/local/bin/$dst" | |
# fi | |
# done | |
# } 2>&1 | tee -a /var/log/python-build.log | |
# echo "Installing and configuring pip..." | tee -a /var/log/python-build.log | |
# { | |
# pushd "$PIP_BUILD_DIR" || { echo "Failed to change directory to $PIP_BUILD_DIR"; exit 1; } | |
# wget -O get-pip.py "$PYTHON_GET_PIP_URL" | |
# echo "$PYTHON_GET_PIP_SHA256 *get-pip.py" | sha256sum -c - | |
# export PYTHONDONTWRITEBYTECODE=1 | |
# python get-pip.py --disable-pip-version-check --no-cache-dir --no-compile "pip==$PYTHON_PIP_VERSION" "setuptools==$PYTHON_SETUPTOOLS_VERSION" | |
# rm -f get-pip.py | |
# python -m pip install --disable-pip-version-check --no-cache-dir --no-compile --upgrade pip setuptools wheel | |
# popd || { echo "Failed to change directory back"; exit 1; } | |
# rm -rf "$PIP_BUILD_DIR" | |
# } 2>&1 | tee -a /var/log/python-build.log | |
if [[ ! -d "$PYENV_DIR" ]]; then | |
git clone https://github.com/pyenv/pyenv.git "$PYENV_DIR" | |
if ! getent group python >/dev/null; then | |
groupadd python | |
fi | |
chgrp -R python "$PYENV_DIR" | |
chmod -R 750 "$PYENV_DIR" | |
fi | |
if [[ ! -f "/etc/profile.d/pyenv.sh" ]]; then | |
echo "Creating /etc/profile.d/pyenv.sh..." | |
cat <<EOF | tee /etc/profile.d/pyenv.sh | |
if id -nG "\$USER" | grep -qw "python"; then | |
export PYENV_ROOT="$PYENV_DIR" | |
export PATH="\$PYENV_ROOT/bin:\$PATH" | |
eval "\$(\$PYENV_ROOT/bin/pyenv init --path)" | |
eval "\$(\$PYENV_ROOT/bin/pyenv init -)" | |
fi | |
EOF | |
fi | |
{ | |
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" | |
CONFIGURE_OPTS="--build=$gnuArch --enable-loadable-sqlite-extensions --enable-optimizations --enable-option-checking=fatal --enable-shared --with-lto --with-system-expat --with-ensurepip --with-openssl=/usr/local/ssl --with-openssl-rpath=/usr/local/lib --with-ssl-default-suites=openssl" | |
EXTRA_CFLAGS="$(dpkg-buildflags --get CFLAGS)" | |
LDFLAGS="$(dpkg-buildflags --get LDFLAGS)" | |
export PYENV_ROOT="$PYENV_DIR" | |
export PATH="$PYENV_ROOT/bin:$PATH" | |
/usr/local/pyenv/bin/pyenv install -v $PYTHON_VERSION | |
} 2>&1 | tee -a /var/log/python-build.log | |
variables_to_unset=( | |
PYTHON_MAJOR_VERSION | |
GPG_KEY | |
PYTHON_GET_PIP_URL | |
PYTHON_GET_PIP_SHA256 | |
PYTHON_PIP_VERSION | |
PYTHON_SETUPTOOLS_VERSION | |
LANG | |
DEBIAN_FRONTEND | |
PYTHON_BUILD_DIR | |
PIP_BUILD_DIR | |
NPROC | |
) | |
for var in "${variables_to_unset[@]}"; do | |
unset "$var" | |
done | |
} | |
# --------------------------------------------------------------------------------- | |
# install_cuda_cudnn: Installs CuDUNN runtime / libraries and / or CUDA SDK | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
# | |
# Notes: | |
# | |
# This is not gaurenteed to work in Gentoo or other compiler based distros | |
# as the CUDA SDK is not yet supported on those distros. Providing support | |
# for those distros is on the TODO list, if users are interested, comment | |
# working instructions for those distros, and they will be added by the | |
# script maintainer. | |
# | |
install_cuda_cudnn() { | |
local CUDA_VERSION=${1:-11.7} | |
local CUDNN_VERSION=${2:-8.0} | |
case "$OS" in | |
"ubuntu") | |
. /etc/os-release | |
UBUNTU_VERSION=$VERSION_ID | |
UBUNTU_VERSION=${UBUNTU_VERSION//./} | |
nvidia_deps=( | |
gnupg2 software-properties-common wget curl ca-certificates git | |
) | |
manage_packages install "${nvidia_deps[@]}" | |
if [ ! -f /etc/apt/preferences.d/cuda-repository-pin-600 ]; then | |
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu${UBUNTU_VERSION}/x86_64/cuda-ubuntu${UBUNTU_VERSION}.pin | |
mv cuda-ubuntu${UBUNTU_VERSION}.pin /etc/apt/preferences.d/cuda-repository-pin-600 | |
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu${UBUNTU_VERSION}/x86_64/cuda-keyring_1.1-1_all.deb | |
dpkg -i cuda-keyring_1.1-1_all.deb | |
rm -f cuda-keyring_1.1-1_all.deb | |
add-apt-repository -y "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu${UBUNTU_VERSION}/x86_64/ /" | |
# add-apt-repository -y "deb http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu${UBUNTU_VERSION}/x86_64/ /" | |
manage_packages update | |
fi | |
;; | |
"debian") | |
. /etc/os-release | |
DEBIAN_VERSION=$VERSION_ID | |
DEBIAN_VERSION=${DEBIAN_VERSION//./} | |
nvidia_deps=( | |
gnupg2 software-properties-common wget curl ca-certificates git | |
) | |
manage_packages install "${nvidia_deps[@]}" | |
if [ ! -f /etc/apt/preferences.d/cuda-repository-pin-600 ]; then | |
wget https://developer.download.nvidia.com/compute/cuda/repos/debian${DEBIAN_VERSION}/x86_64/cuda-debian${DEBIAN_VERSION}.pin | |
mv cuda-debian${DEBIAN_VERSION}.pin /etc/apt/preferences.d/cuda-repository-pin-600 | |
wget https://developer.download.nvidia.com/compute/cuda/repos/debian${DEBIAN_VERSION}/x86_64/cuda-keyring_1.1-1_all.deb | |
dpkg -i cuda-keyring_1.1-1_all.deb | |
rm -f cuda-keyring_1.1-1_all.deb | |
add-apt-repository -y "deb http://developer.download.nvidia.com/compute/cuda/repos/debian${DEBIAN_VERSION}/x86_64/ /" | |
# add-apt-repository -y "deb http://developer.download.nvidia.com/compute/machine-learning/repos/debian${DEBIAN_VERSION}/x86_64/ /" | |
apt-get update | |
fi | |
;; | |
"fedora") | |
nvidia_deps=( | |
gnupg2 wget curl ca-certificates git | |
) | |
manage_packages install "${nvidia_deps[@]}" | |
if [ ! -f /etc/yum.repos.d/cuda.repo ]; then | |
wget https://developer.download.nvidia.com/compute/cuda/repos/fedora32/x86_64/cuda-fedora32.repo | |
mv cuda-fedora32.repo /etc/yum.repos.d/cuda.repo | |
rpm --import https://developer.download.nvidia.com/compute/cuda/repos/fedora32/x86_64/7fa2af80.pub | |
wget https://developer.download.nvidia.com/compute/machine-learning/repos/fedora32/x86_64/nvidia-machine-learning-repo-fedora32-1.0.0-1.x86_64.rpm | |
# rpm -i nvidia-machine-learning-repo-fedora32-1.0.0-1.x86_64.rpm | |
# rm -f nvidia-machine-learning-repo-fedora32-1.0.0-1.x86_64.rpm | |
dnf update | |
fi | |
;; | |
"arch") | |
nvidia_deps=( | |
gnupg2 wget curl ca-certificates git | |
) | |
manage_packages install "${nvidia_deps[@]}" | |
if [ ! -f /etc/pacman.d/cuda-repo.conf ]; then | |
wget https://developer.download.nvidia.com/compute/cuda/repos/archlinux/x86_64/cuda-archlinux.pin | |
mv cuda-archlinux.pin /etc/pacman.d/cuda-repo.conf | |
pacman -Syu | |
fi | |
;; | |
"centos" | "rhel") | |
nvidia_deps=( | |
gnupg2 wget curl ca-certificates git | |
) | |
manage_packages install "${nvidia_deps[@]}" | |
if [ ! -f /etc/yum.repos.d/cuda.repo ]; then | |
wget https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo | |
mv cuda-rhel8.repo /etc/yum.repos.d/cuda.repo | |
rpm --import https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/7fa2af80.pub | |
# wget https://developer.download.nvidia.com/compute/machine-learning/repos/rhel8/x86_64/nvidia-machine-learning-repo-rhel8-1.0.0-1.x86_64.rpm | |
# rpm -i nvidia-machine-learning-repo-rhel8-1.0.0-1.x86_64.rpm | |
# rm -f nvidia-machine-learning-repo-rhel8-1.0.0-1.x86_64.rpm | |
yum update | |
fi | |
;; | |
"alpine") | |
nvidia_deps=( | |
gnupg2 wget curl ca-certificates git | |
) | |
manage_packages install "${nvidia_deps[@]}" | |
if [ ! -f /etc/apk/repositories ]; then | |
echo "http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories | |
echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories | |
echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories | |
apk update | |
fi | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
nvidia_deps=( | |
gnupg2 wget curl ca-certificates git | |
) | |
manage_packages install "${nvidia_deps[@]}" | |
# TODO: Add Gentoo support (https://wiki.gentoo.org/wiki/NVidia/nvidia-drivers) | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" >&2 | |
exit 1 | |
;; | |
esac | |
nvidia_deps=() | |
if [ -n "$CUDA_VERSION" ]; then | |
case "$OS" in | |
"ubuntu" | "debian" | "fedora" | "centos" | "rhel" | "alpine") | |
nvidia_deps+=( | |
cuda-$(convert_version_format "$CUDA_VERSION" "two-part") | |
) | |
;; | |
"arch") | |
nvidia_deps+=( | |
cuda-$(convert_version_format "$CUDA_VERSION" "two-part") | |
) | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
nvidia_deps+=( | |
nvidia-cuda-toolkit | |
) | |
# TODO: Add Gentoo support | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" >&2 | |
exit 1 | |
;; | |
esac | |
fi | |
if [ -n "$CUDNN_VERSION" ]; then | |
case "$OS" in | |
"ubuntu" | "debian" | "fedora" | "centos" | "rhel" | "alpine") | |
nvidia_deps+=( | |
libcudnn$(convert_version_format "$CUDNN_VERSION" "major") libcudnn$(convert_version_format "$CUDNN_VERSION" "major")-dev | |
) | |
;; | |
"arch") | |
nvidia_deps+=( | |
libcudnn$(convert_version_format "$CUDNN_VERSION" "major") libcudnn$(convert_version_format "$CUDNN_VERSION" "major")-dev | |
) | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
nvidia_deps+=( | |
nvidia-cuda-toolkit | |
) | |
# TODO: Add Gentoo support | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" >&2 | |
exit 1 | |
;; | |
esac | |
fi | |
if [[ "${#nvidia_deps[@]}" -gt 0 ]]; then | |
manage_packages install "${nvidia_deps[@]}" | |
fi | |
} | |
# --------------------------------------------------------------------------------- | |
# install_docker: Installs Docker | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
# Notes: | |
# | |
# Full Gento / compiler based distro support is not yet implemented. | |
# If you are using a Gentoo based distro, you will need to install Docker | |
# manually. Providing working instructions can be helpful to the script author | |
# in adding support for your compiler-based distro. | |
# | |
install_docker() { | |
case "$OS" in | |
"ubuntu" | "debian" | "mint") | |
export DEBIAN_FRONTEND=noninteractive | |
if [ ! -f /etc/apt/keyrings/docker.gpg ]; then | |
curl -fsSL https://download.docker.com/linux/$OS/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg | |
chmod a+r /etc/apt/keyrings/docker.gpg | |
fi | |
if [ ! -f /etc/apt/sources.list.d/docker.list ]; then | |
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ | |
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ | |
tee /etc/apt/sources.list.d/docker.list > /dev/null | |
fi | |
export DEBIAN_FRONTEND= | |
;; | |
"fedora") | |
if [ ! -f /etc/yum.repos.d/docker-ce.repo ]; then | |
curl -fsSL https://download.docker.com/linux/$OS/gpg | gpg --dearmor -o /etc/yum.repos.d/docker-ce.repo | |
chmod a+r /etc/yum.repos.d/docker-ce.repo | |
yum-config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo | |
fi | |
;; | |
"arch") | |
if [ ! -f /etc/pacman.d/docker-ce.gpg ]; then | |
curl -fsSL https://download.docker.com/linux/$OS/gpg | gpg --dearmor -o /etc/pacman.d/docker-ce.gpg | |
chmod a+r /etc/pacman.d/docker-ce.gpg | |
{ | |
echo "[docker]"; | |
echo "SigLevel = PackageRequired"; | |
echo "Server = https://download.docker.com/linux/arch/\$arch"; | |
echo ""; | |
} >> /etc/pacman.conf | |
fi | |
;; | |
"centos" | "rhel") | |
if [ ! -f /etc/yum.repos.d/docker-ce.repo ]; then | |
curl -fsSL https://download.docker.com/linux/$OS/gpg | gpg --dearmor -o /etc/yum.repos.d/docker-ce.repo | |
chmod a+r /etc/yum.repos.d/docker-ce.repo | |
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo | |
fi | |
;; | |
"alpine") | |
# TODO: Add alipine support | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
# TODO: Add Gentoo support | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
if manage_packages query_notinstalled docker-ce; then | |
manage_packages update | |
docker_packages=( docker-ce docker-ce-cli containerd docker-compose ) | |
manage_packages install "${docker_packages[@]}" | |
usermod -aG docker $USER | |
fi | |
} | |
# --------------------------------------------------------------------------------- | |
# install_nvidia_container_toolkit: Installs NVIDIA Container Toolkit | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
# Notes: | |
# | |
# Not implemented for Gentoo or other compiler based distros yet. | |
# Not implemented for Alpine yet. | |
# | |
# If you want to see this change, please provide working instructions | |
# for your distro, and they will be added by the script maintainer. | |
# | |
install_nvidia_container_toolkit() { | |
case "$OS" in | |
"ubuntu" | "debian" | "mint") | |
if [ ! -f /etc/apt/keyrings/nvidia-container-toolkit.gpg ]; then | |
curl -fsSL https://nvidia.github.io/nvidia-docker/gpgkey | gpg --dearmor -o /etc/apt/keyrings/nvidia-container-toolkit.gpg | |
chmod a+r /etc/apt/keyrings/nvidia-container-toolkit.gpg | |
fi | |
if [ ! -f /etc/apt/sources.list.d/nvidia-container-toolkit.list ]; then | |
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | | |
sed 's#deb https://#deb [signed-by=/etc/apt/keyrings/nvidia-container-toolkit.gpg] https://#g' | | |
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list | |
manage_packages update | |
fi | |
;; | |
"fedora") | |
if [ ! -f /etc/yum.repos.d/nvidia-container-toolkit.repo ]; then | |
curl -fsSL https://nvidia.github.io/nvidia-docker/$(. /etc/os-release; echo "$ID")/nvidia-docker.repo | \ | |
tee /etc/yum.repos.d/nvidia-container-toolkit.repo | |
manage_packages update | |
fi | |
;; | |
"arch") | |
if [ ! -f /etc/pacman.d/nvidia-container-toolkit.conf ]; then | |
curl -fsSL https://nvidia.github.io/nvidia-docker/arch/$ARCH/nvidia-container-toolkit.conf | \ | |
tee /etc/pacman.d/nvidia-container-toolkit.conf | |
manage_packages update | |
fi | |
;; | |
"centos" | "rhel") | |
if [ ! -f /etc/yum.repos.d/nvidia-container-toolkit.repo ]; then | |
curl -fsSL https://nvidia.github.io/nvidia-docker/$(. /etc/os-release; echo "$ID")/nvidia-docker.repo | \ | |
tee /etc/yum.repos.d/nvidia-container-toolkit.repo | |
manage_packages update | |
fi | |
;; | |
"alpine") | |
echo "Nothing to do for Apline (not implemented)" | |
;; | |
"gentoo" | "funtoo" | "exherbo" | "sabayon" | "calculate" | "clear" | "solus" | "void" | "artix" ) | |
echo "Nothing to do for Gentoo (not implemented)" | |
;; | |
*) | |
echo "Unsupported Linux distribution: $DISTRO" | |
exit 1 | |
;; | |
esac | |
if manage_packages query_notinstalled nvidia-container-toolkit; then | |
manage_packages install nvidia-container-toolkit | |
nvidia-ctk runtime configure --runtime=docker | |
systemctl restart docker | |
fi | |
} | |
# --------------------------------------------------------------------------------- | |
# configure_wsl: Configures WSL2 | |
# --------------------------------------------------------------------------------- | |
# Arguments: | |
# None | |
# | |
# Returns: | |
# None | |
# | |
configure_wsl() { | |
local wsl_packages=( wslu dos2unix ) | |
manage_packages install "${wsl_packages[@]}" | |
local userprofile=$(wslpath -au "$(wslvar USERPROFILE)") | |
local default_user=$(wslvar USERNAME) | |
local hostname="${default_user^^}-PC" | |
local swap_path=$(wslpath -au "$(wslvar LOCALAPPDATA)")/WSL2 | |
[ ! -d "$swap_path" ] && mkdir -p "$swap_path" | |
local ram_size=$(free -m | awk '/^Mem:/{print $2}') | |
local swap_size=0 | |
if [ "$ram_size" -lt 2048 ]; then | |
swap_size=$(($ram_size * 2)) | |
else | |
swap_size=$ram_size | |
fi | |
swap_path=$(echo $(wslpath -aw "$swap_path")\\swap.vhdx | sed 's/\\/\\\\/g') | |
cat >/etc/wsl.conf <<EOF | |
[boot] | |
systemd=true | |
[automount] | |
enabled = true | |
root = /mnt/ | |
options = "metadata,uid=1000,gid=1000,umask=077,fmask=11,case=off" | |
mountFsTab = true | |
[network] | |
hostname = $hostname | |
generateHosts = true | |
generateResolvConf = true | |
[user] | |
default = $default_user | |
[interop] | |
enabled = true | |
appendWindowsPath = false | |
EOF | |
cat >"$userprofile/.wslconfig" <<EOF | |
[wsl2] | |
memory = ${ram_size}MB | |
localhostForwarding = true | |
swap = ${swap_size}MB | |
swapFile = $swap_path | |
guiApplications = true | |
nestedVirtualization = true | |
vmIdleTimeout = 120000 | |
EOF | |
unix2dos "$userprofile/.wslconfig" 2>/dev/null | |
echo "WSL2 .wslconfig updated." | |
} | |
# Main execution | |
parse_args "$@" | |
if [[ $INITSYS == "true" ]]; then | |
echo "Initializing system..." | |
init_system "$INIT_USERNAME" "$INIT_PASSWORD" | |
fi | |
if [[ $SYSTEM_UPDATE == "true" ]]; then | |
echo "Updating system..." | |
update_system | |
fi | |
if [[ $BUILD_DEPS == "true" ]]; then | |
echo "Installing build dependencies..." | |
install_build_deps | |
fi | |
if [[ $WSL == "true" ]]; then | |
echo "Configuring WSL2..." | |
configure_wsl | |
fi | |
if [[ -n $OPENSSL_VERSION ]]; then | |
echo "Installing OpenSSL..." | |
install_openssl "$OPENSSL_VERSION" | |
fi | |
if [[ -n $PYTHON_VERSION ]]; then | |
echo "Installing Python and PIP..." | |
install_pyenv "$PYTHON_VERSION" | |
fi | |
if [[ -n $ANACONDA_VERSION ]]; then | |
echo "Installing Anaconda..." | |
install_anaconda "$ANACONDA_VERSION" | |
fi | |
if [[ -n $CUDA_VERSION || -n $CUDNN_VERSION ]]; then | |
echo "Installing CUDA and cuDNN..." | |
install_cuda_cudnn "$CUDA_VERSION" "$CUDNN_VERSION" | |
fi | |
if [[ $DOCKER == "true" ]]; then | |
echo "Installing Docker..." | |
install_docker | |
fi | |
if [[ $NVCK == "true" ]]; then | |
echo "Installing NVIDIA Container Toolkit..." | |
install_nvidia_container_toolkit | |
fi | |
if [[ $RUST == "true" ]]; then | |
echo "Installing Rust..." | |
install_rust | |
fi | |
if [[ $POETRY == "true" ]]; then | |
echo "Installing Poetry..." | |
install_poetry | |
fi | |
exit 0 | |
'@ | |
# Load defaults | |
if (-not $Distro) { | |
$Distro = "ubuntu-22.04" | |
} | |
if (-not $WSLRoot) { | |
$WSLRoot = $env:LOCALAPPDATA + '\WSL2' | |
} | |
# Ensure only one of actions | |
if (($Register, $Unregister, $Import, $Export, $Check, $Configure, $Shutdown, $Startup) -contains $true) { | |
$actionCount = 0 | |
if ($Register) { $actionCount++ } | |
if ($Unregister) { $actionCount++ } | |
if ($Import) { $actionCount++ } | |
if ($Export) { $actionCount++ } | |
if ($Check) { $actionCount++ } | |
if ($Configure) { $actionCount++ } | |
if ($Shutdown) { $actionCount++ } | |
if ($Startup) { $actionCount++ } | |
if ($actionCount -gt 1) { | |
Write-Error "E: Only one action can be specified." | |
exit 1 | |
} | |
} | |
if ($Register) { | |
$result = Register-WSL -Distro $Distro | |
exit | |
} | |
if ($Unregister) { | |
$result = Unregister-WSL -Distro $Distro | |
exit | |
} | |
if ($Import) { | |
$result = Import-WSL -Distro $Distro -WSLRoot $WSLRoot | |
exit | |
} | |
if ($Export) { | |
$result = Export-WSL -Distro $Distro -WSLRoot $WSLRoot | |
exit | |
} | |
if ($Configure) { | |
$result = Configure-WSL -Distro $Distro ` | |
-UpdateWSLConfig:$UpdateWSLConfig -Username:$Username ` | |
-Password:$Password -UpdateSystem:$UpdateSystem ` | |
-InstallBuildDependencies:$InstallBuildDependencies ` | |
-InstallCudaVersion:$InstallCudaVersion ` | |
-InstallCudnnVersion:$InstallCudnnVersion ` | |
-InstallPythonVersion:$InstallPythonVersion ` | |
-InstallOpenSSLVersion:$InstallOpenSSLVersion ` | |
-InstallRust:$InstallRust -InstallPoetry:$InstallPoetry ` | |
-InstallDocker:$InstallDocker -InstallNVCT:$InstallNVCT ` | |
-InstallAnacondaVersion:$InstallAnacondaVersion ` | |
-ShowHelp:$ShowHelp -DebugMode:$DebugMode | |
if ($result -ne $true) { | |
exit 1 | |
} | |
exit | |
} | |
if ($Startup) { | |
$result = Startup-WSL -Distro $Distro | |
exit | |
} | |
if ($Shutdown) { | |
$result = Shutdown-WSL -Distro $Distro | |
exit | |
} | |
if ($Check) { | |
if ($(Check-WSL -Distro $Distro -WSLVersion 2 -IsRunning $true) -eq $true) { | |
Write-Host "WSL distribution '$Distro' is running." | |
exit 0 | |
} else { | |
if ($(Check-WSL -Distro $Distro -WSLVersion 2 -IsRunning $false) -eq $true) { | |
Write-Host "WSL distribution '$Distro' is not running." | |
exit 1 | |
} else { | |
Write-Host "WSL distribution '$Distro' is not installed." | |
exit 2 | |
} | |
} | |
exit | |
} | |
exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dei G. E. A. R. - Grossly Enormous Automated Runner
Welcome
To the automated WSL bootstrapper. I doubt you've ever seen a single file solution to running python code everywhere. This is it
Installing
Download the script as RAW and save it as a file with a
.ps1
extension, in LF Linux line-ending format.Install PowerShell 7 (this will be automated in the future and auto-elevation will happen, for now that's manual)
Give yourself execution rights from PowerShell 7 command prompt and change to the directory where you downloaded the tool.
Reference the example below to use the tool. It makes managing your Windows Subsystem for Linux installation a lot easier. It provides an unattended solution to normally lengthy processes required to set up functioning development environments in WSL.
Example:
Create an
ubuntu-22.04
distribution, configure it, export it to a tarball, then re-import it to commit the filesystem to disk.The
-Configure
action in this example performs the following instructions:.wslconfig
and/etc/wsl.conf
taylored to available resources on system.password12345!
. Add this user to the sudoers group and the sudoers file, and assign it the UUID 1000Changelog
1.0.0 - Initial release
1.0.1 - Quality-of-life fixes/polish
-Help
flag to-ShowHelp
to avoid conflict with PS Builtin-Help
switch-DebugMode
flag that allows tool to work with locally saved copy of internal WSL configuration bash script (for testing and debug purposes)1.0.2 - The distrofork
manage_packages
:query_installed
,query_notinstalled
,query_available
Beta Options
These features are still in beta.
-Configure
option:-InstallRust
- Installs Rust and Cargo.-Configure
option:-InstallPoetry
- Install Poetry (python project-level version manager)