diff --git a/.assets/provision/install_eza.sh b/.assets/provision/install_eza.sh index c6c97c04..c18bf15f 100755 --- a/.assets/provision/install_eza.sh +++ b/.assets/provision/install_eza.sh @@ -73,7 +73,9 @@ fedora) debian | ubuntu) export DEBIAN_FRONTEND=noninteractive mkdir -p /etc/apt/keyrings - wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | gpg --dearmor -o /etc/apt/keyrings/gierens.gpg + if [ ! -f /etc/apt/keyrings/gierens.gpg ]; then + wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | gpg --dearmor -o /etc/apt/keyrings/gierens.gpg + fi echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" | tee /etc/apt/sources.list.d/gierens.list chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list apt-get update >&2 && apt-get install -y $APP >&2 2>/dev/null || binary=true diff --git a/.assets/provision/install_kubectl.sh b/.assets/provision/install_kubectl.sh index 21cfbd5c..ba91fbda 100755 --- a/.assets/provision/install_kubectl.sh +++ b/.assets/provision/install_kubectl.sh @@ -15,9 +15,6 @@ case $SYS_ID in arch) pacman -Qqe $APP &>/dev/null && exit 0 || true ;; -fedora) - rpm -q $APP &>/dev/null && exit 0 || true - ;; esac REL=$1 @@ -48,17 +45,6 @@ case $SYS_ID in arch) pacman -Sy --needed --noconfirm kubectl >&2 2>/dev/null || binary=true ;; -fedora) - [ -f /etc/yum.repos.d/kubernetes.repo ] || cat <&2 2>/dev/null || binary=true - ;; *) binary=true ;; diff --git a/.assets/provision/install_miniforge.sh b/.assets/provision/install_miniforge.sh new file mode 100755 index 00000000..c101468e --- /dev/null +++ b/.assets/provision/install_miniforge.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +: ' +.assets/provision/install_miniforge.sh +.assets/provision/install_miniforge.sh --fix_certify true +' +if [ $EUID -eq 0 ]; then + printf '\e[31;1mDo not run the script as root.\e[0m\n' + exit 1 +fi + +# parse named parameters +fix_certify=${fix_certify:-false} +while [ $# -gt 0 ]; do + if [[ $1 == *"--"* ]]; then + param="${1/--/}" + declare $param="$2" + fi + shift +done + +# set script working directory to workspace folder +SCRIPT_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd) +pushd "$(cd "${SCRIPT_ROOT}/../../" && pwd)" >/dev/null + +# *conda init function. +function conda_init { + __conda_setup="$("$HOME/miniforge3/bin/conda" 'shell.bash' 'hook' 2>/dev/null)" + if [ $? -eq 0 ]; then + eval "$__conda_setup" + else + if [ -f "$HOME/miniforge3/etc/profile.d/conda.sh" ]; then + . "$HOME/miniforge3/etc/profile.d/conda.sh" + else + export PATH="$HOME/miniforge3/bin:$PATH" + fi + fi + unset __conda_setup +} + +# *Install conda. +if [ -d "$HOME/miniforge3" ]; then + conda_init +else + printf "\e[92minstalling \e[1mminiforge\e[0m\n" + TMP_DIR=$(mktemp -dp "$PWD") + retry_count=0 + while [[ ! -f "$TMP_DIR/miniforge.sh" && $retry_count -lt 10 ]]; do + curl -#Lko "$TMP_DIR/miniforge.sh" "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" + ((retry_count++)) + done + bash $TMP_DIR/miniforge.sh -b -p "$HOME/miniforge3" >/dev/null + rm -fr "$TMP_DIR" + # disable auto activation of the base conda environment + conda_init + conda config --set auto_activate_base false +fi +# disable conda env prompt if oh-my-posh is installed +if [ -f /usr/bin/oh-my-posh ]; then + conda config --set changeps1 false +fi + +# *Add certificates to conda base certifi. +if $fix_certify; then + conda activate base + .assets/provision/fix_certifi_certs.sh + conda deactivate +fi + +# *Update conda. +conda update --name base --channel defaults conda --yes --update-all +conda clean --yes --all + +# *Fix certificates after update. +if $fix_certify; then + conda activate base + .assets/provision/fix_certifi_certs.sh + conda deactivate +fi diff --git a/.assets/provision/install_terraform.sh b/.assets/provision/install_terraform.sh index 724d73a3..aa94cce2 100755 --- a/.assets/provision/install_terraform.sh +++ b/.assets/provision/install_terraform.sh @@ -60,9 +60,9 @@ fedora) ;; debian | ubuntu) export DEBIAN_FRONTEND=noninteractive - wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | tee /usr/share/keyrings/hashicorp-archive-keyring.gpg + wget -O- https://apt.releases.hashicorp.com/gpg 2>/dev/null | gpg --dearmor > /usr/share/keyrings/hashicorp-archive-keyring.gpg gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint - echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/hashicorp.list + echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/hashicorp.list apt-get update && apt-get install terraform ;; opensuse) diff --git a/.assets/provision/install_terrascan.sh b/.assets/provision/install_terrascan.sh new file mode 100755 index 00000000..dc64a433 --- /dev/null +++ b/.assets/provision/install_terrascan.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +: ' +sudo .assets/provision/install_terrascan.sh +' +if [ $EUID -ne 0 ]; then + printf '\e[31;1mRun the script as root.\e[0m\n' + exit 1 +fi + +APP='terrascan' +retry_count=0 +# try 10 times to get latest release if not provided as a parameter +while [ -z "$REL" ]; do + REL=$(curl -sk https://api.github.com/repos/tenable/terrascan/releases/latest | sed -En 's/.*"tag_name": "v?([^"]*)".*/\1/p') + ((retry_count++)) + if [ $retry_count -eq 10 ]; then + printf "\e[33m$APP version couldn't be retrieved\e[0m\n" >&2 + exit 0 + fi + [[ -n "$REL" || $i -eq 10 ]] || echo 'retrying...' >&2 +done + +if type $APP &>/dev/null; then + VER=$($APP version | sed -En 's/.*\sv([0-9\.]+)/\1/p') + if [ "$REL" = "$VER" ]; then + printf "\e[32m$APP v$VER is already latest\e[0m\n" >&2 + exit 0 + fi +fi + +printf "\e[92minstalling \e[1m$APP\e[22m v$REL\e[0m\n" >&2 +TMP_DIR=$(mktemp -dp "$PWD") +retry_count=0 +while [[ ! -f "$TMP_DIR/terrascan" && $retry_count -lt 10 ]]; do + curl -#Lk "https://github.com/tenable/terrascan/releases/download/v${REL}/terrascan_${REL}_Linux_x86_64.tar.gz" | tar -zx -C "$TMP_DIR" + ((retry_count++)) +done +install -m 0755 "$TMP_DIR/terrascan" /usr/bin/ +rm -fr "$TMP_DIR" + +exit 0 diff --git a/.assets/provision/install_tfswitch.sh b/.assets/provision/install_tfswitch.sh new file mode 100755 index 00000000..1a61971f --- /dev/null +++ b/.assets/provision/install_tfswitch.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +: ' +sudo .assets/provision/install_tfswitch.sh +' +if [ $EUID -ne 0 ]; then + printf '\e[31;1mRun the script as root.\e[0m\n' + exit 1 +fi + +APP='tfswitch' +retry_count=0 +# try 10 times to get latest release if not provided as a parameter +while [ -z "$REL" ]; do + REL=$(curl -sk https://api.github.com/repos/warrensbox/terraform-switcher/releases/latest | sed -En 's/.*"tag_name": "v?([^"]*)".*/\1/p') + ((retry_count++)) + if [ $retry_count -eq 10 ]; then + printf "\e[33m$APP version couldn't be retrieved\e[0m\n" >&2 + exit 0 + fi + [[ -n "$REL" || $i -eq 10 ]] || echo 'retrying...' >&2 +done + +if type $APP &>/dev/null; then + VER=$($APP --version | sed -En 's/.*\s([0-9\.]+)/\1/p') + if [ "$REL" = "$VER" ]; then + printf "\e[32m$APP v$VER is already latest\e[0m\n" >&2 + exit 0 + fi +fi + +printf "\e[92minstalling \e[1m$APP\e[22m v$REL\e[0m\n" >&2 +__install="curl -L https://raw.githubusercontent.com/warrensbox/terraform-switcher/release/install.sh | bash" +if type $APP &>/dev/null; then + eval $__install +else + retry_count=0 + while ! type $APP &>/dev/null && [ $retry_count -lt 10 ]; do + eval $__install + ((retry_count++)) + done +fi + +exit 0 diff --git a/wsl/wsl_install.ps1 b/wsl/wsl_install.ps1 index d44ec89f..660d3841 100644 --- a/wsl/wsl_install.ps1 +++ b/wsl/wsl_install.ps1 @@ -18,7 +18,13 @@ Name of the WSL distro to install and set up. List of installation scopes. Valid values: - az: azure-cli, do-az from ps-modules if pwsh scope specified; autoselects python scope - docker: docker, containerd buildx docker-compose (WSL2 only) +- k8s_base: kubectl, kubelogin, helm, k9s, kubeseal, flux, kustomize +- k8s_ext: minikube, k3d, argorollouts-cli (WSL2 only); autoselects docker and k8s_base scopes +- pwsh: PowerShell Core and corresponding PS modules; autoselects shell scope - python: pip, venv, miniconda +- shell: bat, eza, oh-my-posh, ripgrep, yq +- terraform: terraform, terrascan, tfswitch +- zsh: zsh shell with plugins .PARAMETER Repos List of GitHub repositories in format "Owner/RepoName" to clone into the WSL. .PARAMETER FixNetwork @@ -31,12 +37,14 @@ wsl/wsl_install.ps1 -Distro 'Ubuntu' wsl/wsl_install.ps1 -Distro 'Ubuntu' -FixNetwork # :set up WSL distro with specified installation scopes $Scope = @('python') -$Scope = @('az', 'docker') +$Scope = @('az', 'docker', 'shell') $Scope = @('az', 'docker', 'pwsh') -$Scope = @('az', 'docker', 'k8s_base', 'pwsh') +$Scope = @('az', 'docker', 'k8s_base', 'pwsh', 'terraform') wsl/wsl_install.ps1 -Distro 'Ubuntu' -s $Scope # :set up WSL distro and clone specified GitHub repositories -$Repos = @('szymonos/linux-setup-scripts') +$Repos = @('procter-gamble/de-cf-wsl-setup-scripts') +wsl/wsl_install.ps1 -Distro 'Ubuntu' -r $Repos +# with the specified scope wsl/wsl_install.ps1 -Distro 'Ubuntu' -r $Repos -s $Scope #> [CmdletBinding()] @@ -44,7 +52,7 @@ param ( [Parameter(Mandatory, Position = 0)] [string]$Distro, - [ValidateScript({ $_.ForEach({ $_ -in @('az', 'docker', 'k8s_base', 'k8s_ext', 'oh_my_posh', 'pwsh', 'python', 'shell', 'zsh') }) -notcontains $false })] + [ValidateScript({ $_.ForEach({ $_ -in @('az', 'docker', 'k8s_base', 'k8s_ext', 'oh_my_posh', 'pwsh', 'python', 'shell', 'terraform', 'zsh') }) -notcontains $false })] [string[]]$Scope, [ValidateScript({ $_.ForEach({ $_ -match '^[\w-]+/[\w-]+$' }) -notcontains $false })] @@ -63,7 +71,7 @@ begin { # import InstallUtils for the Update-SessionEnvironmentPath function Import-Module (Resolve-Path './modules/InstallUtils') - Write-Host "checking if the repository is up to date..." -ForegroundColor Cyan + Write-Host 'checking if the repository is up to date...' -ForegroundColor Cyan if ((Update-GitRepository) -eq 2) { Write-Host "`nRun the script again!" -ForegroundColor Yellow exit 0 @@ -86,7 +94,7 @@ process { } } - # *Check if WSL is updated + # *Perform WSL update wsl.exe --update # *Check the current default version diff --git a/wsl/wsl_restart.ps1 b/wsl/wsl_restart.ps1 index af608d4c..f0778816 100644 --- a/wsl/wsl_restart.ps1 +++ b/wsl/wsl_restart.ps1 @@ -3,6 +3,13 @@ .SYNOPSIS Restart WSL. +.DESCRIPTION +Running the script fixes issues with unresponsive WSL or user permissions issues. +The script stops all running wsl processes and then restarts the following services: +- LxssManagerUser: Linux Subsystem User Manager +- WSLService: WSL Service +- vmcompute: Hyper-V Host Compute Service + .PARAMETER StopDockerDesktop Flag whether to stop DockerDesktop process. @@ -27,8 +34,8 @@ if ($StopDockerDesktop) { Get-Process docker* | Stop-Process -Force } -# stop wsl processess +# stop WSL processess Get-Process wsl* | Stop-Process -Force -# restart LxssManagerUser service -Get-Service LxssManagerUser*, WSLService | Restart-Service -Force +# restart services related to WSL +Get-Service LxssManagerUser*, WSLService, vmcompute | Restart-Service -Force diff --git a/wsl/wsl_setup.ps1 b/wsl/wsl_setup.ps1 index 08bea79f..26a35bc1 100644 --- a/wsl/wsl_setup.ps1 +++ b/wsl/wsl_setup.ps1 @@ -27,6 +27,7 @@ List of installation scopes. Valid values: - python: pip, venv, miniconda - rice: btop, cmatrix, cowsay, fastfetch - shell: bat, eza, oh-my-posh, ripgrep, yq +- terraform: terraform, terrascan, tfswitch - zsh: zsh shell with plugins .PARAMETER OmpTheme Specify to install oh-my-posh prompt theme engine and name of the theme to be used. @@ -52,7 +53,7 @@ wsl/wsl_setup.ps1 $Distro -FixNetwork -AddCertificate $Scope = @('pwsh', 'python') $Scope = @('k8s_ext', 'pwsh', 'python', 'rice') $Scope = @('az', 'docker', 'shell') -$Scope = @('az', 'k8s_base', 'pwsh') +$Scope = @('az', 'k8s_base', 'pwsh', 'terraform') $Scope = @('az', 'k8s_ext', 'pwsh') wsl/wsl_setup.ps1 $Distro -s $Scope wsl/wsl_setup.ps1 $Distro -s $Scope -AddCertificate @@ -64,6 +65,8 @@ wsl/wsl_setup.ps1 $Distro -s $Scope -o $OmpTheme -AddCertificate $Repos = @('szymonos/linux-setup-scripts', 'szymonos/ps-modules') wsl/wsl_setup.ps1 $Distro -r $Repos -s $Scope -o $OmpTheme wsl/wsl_setup.ps1 $Distro -r $Repos -s $Scope -o $OmpTheme -AddCertificate +# :show SSH key during setup +wsl/wsl_setup.ps1 $Distro -ShowSSHKey # :update all existing WSL distros wsl/wsl_setup.ps1 #> @@ -78,7 +81,7 @@ param ( [Alias('s')] [Parameter(ParameterSetName = 'Setup')] [Parameter(ParameterSetName = 'GitHub')] - [ValidateScript({ $_.ForEach({ $_ -in @('az', 'distrobox', 'docker', 'k8s_base', 'k8s_ext', 'oh_my_posh', 'pwsh', 'python', 'rice', 'shell', 'zsh') }) -notcontains $false }, + [ValidateScript({ $_.ForEach({ $_ -in @('az', 'distrobox', 'docker', 'k8s_base', 'k8s_ext', 'oh_my_posh', 'pwsh', 'python', 'rice', 'shell', 'terraform', 'zsh') }) -notcontains $false }, ErrorMessage = 'Wrong scope provided. Valid values: az distrobox docker k8s_base k8s_ext python rice shell')] [string[]]$Scope, @@ -107,7 +110,9 @@ param ( [Parameter(ParameterSetName = 'GitHub')] [switch]$FixNetwork, - [switch]$SkipRepoUpdate + [switch]$SkipRepoUpdate, + + [switch]$ShowSSHKey ) begin { @@ -235,6 +240,7 @@ process { '[ -f /usr/bin/kubectl ] && k8s_base="true" || k8s_base="false";', '[ -f /usr/local/bin/k3d ] && k8s_ext="true" || k8s_ext="false";', '[ -f /usr/bin/oh-my-posh ] && omp="true" || omp="false";', + '[ -f /usr/bin/terraform ] && tf="true" || tf="false";', '[ -d $HOME/.local/share/powershell/Modules/Az ] && az="true" || az="false";', '[ -d $HOME/miniconda3 ] && python="true" || python="false";', '[ -f $HOME/.ssh/id_ed25519 ] && ssh_key="true" || ssh_key="false";', @@ -248,7 +254,7 @@ process { 'grep -Fqw "dark" /etc/profile.d/gtk_theme.sh 2>/dev/null && gtkd="true" || gtkd="false";', 'printf "{\"user\":\"$(id -un)\",\"shell\":$shell,\"k8s_base\":$k8s_base,\"k8s_ext\":$k8s_ext,\"omp\":$omp,', '\"az\":$az,\"wslg\":$wslg,\"wsl_boot\":$wsl_boot,\"python\":$python,\"systemd\":$systemd,\"gtkd\":$gtkd,', - '\"pwsh\":$pwsh,\"zsh\":$zsh,\"git_user\":$git_user,\"git_email\":$git_email,\"ssh_key\":$ssh_key}"' + '\"pwsh\":$pwsh,\"tf\":$tf,\"zsh\":$zsh,\"git_user\":$git_user,\"git_email\":$git_email,\"ssh_key\":$ssh_key}"' ) # check existing distro setup $chk = wsl.exe -d $Distro --exec sh -c $cmd | ConvertFrom-Json -AsHashtable @@ -263,6 +269,7 @@ process { { $_.pwsh } { $scopes.Add('pwsh') | Out-Null } { $_.python } { $scopes.Add('python') | Out-Null } { $_.shell } { $scopes.Add('shell') | Out-Null } + { $_.tf } { $scopes.Add('terraform') | Out-Null } } # add corresponding scopes switch (@($scopes)) { @@ -428,6 +435,13 @@ process { wsl.exe --distribution $Distro --exec .assets/provision/setup_profile_user.sh continue } + terraform { + Write-Host 'installing terraform utils...' -ForegroundColor Cyan + wsl.exe --distribution $Distro --user root --exec .assets/provision/install_terraform.sh + wsl.exe --distribution $Distro --user root --exec .assets/provision/install_terrascan.sh + wsl.exe --distribution $Distro --user root --exec .assets/provision/install_tfswitch.sh + continue + } zsh { Write-Host 'installing zsh...' -ForegroundColor Cyan wsl.exe --distribution $Distro --user root --exec .assets/provision/install_zsh.sh @@ -500,29 +514,32 @@ process { wsl.exe --distribution $Distro --exec bash -c $builder.ToString().Trim() } # *check ssh keys and create if necessary - if (-not $chk.ssh_key) { + if (-not $chk.ssh_key -or $ShowSSHKey) { $sshKey = '.ssh/id_ed25519' if (-not ((Test-Path "$HOME/$sshKey") -and (Test-Path "$HOME/$sshKey.pub"))) { + if (Test-Path "$HOME/$sshKey") { Remove-Item "$HOME/$sshKey" } ssh-keygen -t ed25519 -f "$HOME/$sshKey" -q -N '' - $idPub = [System.IO.File]::ReadAllLines("$HOME/$sshKey.pub") - $msg = [string]::Join("`n", - "`e[97mUse the following values to add new SSH Key on `e[34;4mhttps://github.com/settings/ssh/new`e[97;24m", - "`n`e[1;96mTitle`e[0m`n$($idPub.Split()[-1])", - "`n`e[1;96mKey type`e[30m`n", - "`n`e[1;96mKey`e[0m`n$idPub", - "`npress any key to continue..." - ) - Write-Host $msg - [System.Console]::ReadKey() | Out-Null } - Write-Host 'copying ssh keys...' -ForegroundColor Cyan - $mntHome = "/mnt/$($env:HOMEDRIVE.Replace(':', '').ToLower())$($env:HOMEPATH.Replace('\', '/'))" - $cmd = [string]::Join("`n", - 'mkdir -p $HOME/.ssh', - "install -m 0400 '$mntHome/$sshKey' `$HOME/.ssh", - "install -m 0400 '$mntHome/$sshKey.pub' `$HOME/.ssh" + $idPub = [System.IO.File]::ReadAllLines("$HOME/$sshKey.pub") + $msg = [string]::Join("`n", + "`e[97mUse the following values to add new SSH Key on `e[34;4mhttps://github.com/settings/ssh/new`e[97;24m", + "`n`e[1;96mTitle`e[0m`n$($idPub.Split()[-1])", + "`n`e[1;96mKey type`e[30m`n", + "`n`e[1;96mKey`e[0m`n$idPub", + "`npress any key to continue..." ) - wsl.exe --distribution $Distro --exec sh -c $cmd + Write-Host $msg + [System.Console]::ReadKey() | Out-Null + if (-not $chk.ssh_key) { + Write-Host 'copying ssh keys...' -ForegroundColor Cyan + $mntHome = "/mnt/$($env:HOMEDRIVE.Replace(':', '').ToLower())$($env:HOMEPATH.Replace('\', '/'))" + $cmd = [string]::Join("`n", + 'mkdir -p $HOME/.ssh', + "install -m 0400 '$mntHome/$sshKey' `$HOME/.ssh", + "install -m 0400 '$mntHome/$sshKey.pub' `$HOME/.ssh" + ) + wsl.exe --distribution $Distro --exec sh -c $cmd + } } }