Wsl.ps1

$Wsl_Path = "wsl/noble/current" 
$Wsl_File = "ubuntu-noble-wsl-amd64-ubuntu.rootfs.tar.gz" 

function Connect-Wsl() {
  param(
    [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Nom de la màquina virtual")]
    [string] $Name,
    [switch] $New
  )

  if ($New) {
    New-Wsl $Name
  }

  if (-Not(Test-WslRegistered $Name)) {
    Write-WslLog $Name
    Write-Host -ForegroundColor Yellow "La màquina no està registrada"
    return
  }

  if (-Not(Test-WslRunning $Name)) {
    Start-Wsl $Name
  }

  wsl --distribution $Name --cd '~' --user 'box'

}

# TODO
function Install-Wsl {
  wsl --set-default-version 2
  wsl --update
  Write-Host -ForegroundColor Green "Fet" 
}

function Get-Wsl() {
  wsl -l -v
}

function New-Wsl() {
  param(
    [Parameter(Mandatory = $true, HelpMessage = "Nom de la màquina virtual")]
    [string] $Name
  )

  $instancePath = Get-WslPath $Name

  # Verifica que la màquina no està registrada
  
  if (Test-WslRegistered $Name ) {
    Write-WslLog $Name
    Write-Host -ForegroundColor Red "Ja està registrada !"
    return
  }

  # Get image
  
  $imagePath = Get-Ubuntu -Path $Wsl_Path -File $Wsl_File -Update $False

  # Create config file

  $file = Get-WslConfigFile $Name
  $userData = Get-WslConfig $Name $Docker
  $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False

  [System.IO.File]::WriteAllLines($file, $userData, $Utf8NoBomEncoding)

  # Create virtual machine

  if (-Not(Test-Path $instancePath)) { 
    New-Item -Path $instancePath -ItemType Directory | Out-Null
  } 

  Write-WslLog $Name
  Write-Host("Important la màquina virtual ...")

  wsl --import $name $instancePath $imagePath
}

function Remove-Wsl() {
  param(
    [Parameter(Mandatory = $true)]
    [string] $Name
  )

  if (-Not(Test-WslRegistered $Name)) {
    Write-WslLog $Name
    Write-Host -ForegroundColor Yellow "La màquina no està registrada"
    return
  }

  Write-WslLog $Name
  Write-Host "Eliminant la màquina virtual"

  wsl --unregister $Name

  $instancePath = Get-WslPath $Name
  if (Test-Path $instancePath) { 
    Remove-Item -Path $instancePath | Out-Null 
  }

  $configFile = Get-WslConfigFile $Name
  if (Test-Path $configFile) { 
    Remove-Item -Path (Get-WslConfigFile $Name) | Out-Null
  }
}

function Start-Wsl() {
  param(
    [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Nom de la màquina virtual")]
    [string] $Name
  )

  if (Test-WslRunning $Name) {
    Write-Host -ForegroundColor Yellow "${Name}: Ja està en execució!"
  }
  else {
    Write-WslLog $Name
    Write-Host "Arrencant ..." -NoNewline
    wsl --distribution $Name --exec dbus-launch true
    Write-Host -ForegroundColor Green " Fet."
  }

  # La configuració de [user] default a wsl.conf no funciona
  Get-ItemProperty Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\*\ DistributionName | Where-Object -Property DistributionName -eq $Name  | Set-ItemProperty -Name DefaultUid -Value 1000

}

function Stop-Wsl() {
  param(
    [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Nom de la màquina virtual")]
    [string] $Name
  )

  wsl --terminate $Name
}

function Update-Wsl() {

  Update-Ubuntu -Path $Wsl_Path -File $Wsl_File | Out-Null
}


##### Private

function Get-WslConfig {
  param(
    [string] $Name
  )

  $config = @"
#cloud-config
 
users:
 
  - name: box
    groups: sudo,users,netdev,audio
    sudo: ALL=(ALL) NOPASSWD:ALL
    plain_text_passwd: password
    lock_passwd: false
    shell: /bin/bash
 
write_files:
 
  - path: /etc/wsl.conf
    append: true
    content: |
      [user]
      default=box
      [network]
      hostname=${Name}
      generateHosts=false
 
  - path: /etc/hostname
    defer: true
    content: |
      ${Name}
 
  - path: /etc/hosts
    content: |
      127.0.0.1 localhost
      127.0.1.1 ${Name}. ${Name}
 
  - path: /home/box/.hushlogin
    owner: box:box
    defer: true
 
  - path: /home/box/.bash_aliases
    owner: box:box
    defer: true
    content: |
      alias install-docker="curl -L sh.xtec.dev/docker.sh | sh"
 
runcmd:
  - hostnamectl --transient set-hostname ${Name}
 
"@

  return $config
}

function Get-WslConfigFile {
  param(
    [string] $Name
  )

  $configDir = Join-Path $env:USERPROFILE ".cloud-init"
  if (-Not(Test-Path $configDir)) {
    New-Item -Path $configDir -ItemType Directory | Out-Null
  }

  $file = Join-Path $configDir "${Name}.user-data"

  return $file
  
}

function Get-WslPath {
  param(
    [string] $Name
  )

  $path = Get-BoxPath -Path "wsl"

  if ($Name) {
    $path = Join-Path $path $Name
  }
  return $path
}

function Test-WslRegistered {
  param(
    [string] $Name
  )

  $instancePath = Get-WslPath $Name
  Test-Path (Join-Path $instancePath "ext4.vhdx") -PathType Leaf

  # TODO verificar que màquina no creada per usuari directament
}

function Test-WslRunning {

  param(
    [string] $Name
  )

  $running = wsl --list --running

  return $running.Contains($Name)
}

function Write-WslLog {
  param(
    [string] $Name
  )

  Write-Host -ForegroundColor Blue -NoNewline $Name 
  Write-Host ": " -NoNewline
}