Wsl.ps1

$Wsl_Path = "wsl/noble/current" 
$Wsl_File = "ubuntu-noble-wsl-amd64-wsl.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)) { 
    mkdir -Path $instancePath | Out-Null 
  } 

  Write-WslLog $Name
  Write-Host("Important la màquina virtual ") -NoNewline
  if ($Docker) {
    Write-Host -ForegroundColor Yellow "amb docker " -NoNewline
  }
  Write-Host(" ...")

  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."
  }
}

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,docker,users,netdev,audio
    sudo: ALL=(ALL) NOPASSWD:ALL
    plain_text_passwd: password
    lock_passwd: false
    shell: /bin/bash
 
runcmd:
  - hostnamectl --transient set-hostname ${Name}
 
write_files:
 
  - path: /etc/wsl.conf
    append: true
    content: |
      [user]
      default=box
      [network]
      hostname=${Name}
      generateHosts=false
 
  - path: /home/box/.hushlogin
    owner: box:box
    defer: true
 
  - 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/install-docker.sh
    owner: box:box
    permissions: '0744'
    defer: true
    content: |
      #!/bin/bash
      apt update
      apt install ca-certificates curl
      install -m 0755 -d /etc/apt/keyrings
      curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
      chmod a+r /etc/apt/keyrings/docker.asc
 
      echo \
        `"deb [arch=`$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
        `$(. /etc/os-release && echo `"`$VERSION_CODENAME`") stable`" | \
      tee /etc/apt/sources.list.d/docker.list > /dev/null
      apt update
 
      apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
      sudo usermod -aG docker `${USER}
"@

  return $config
}

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

  $configDir = Join-Path $env:USERPROFILE ".cloud-init"
  if (-Not(Test-Path $configDir)) {
    mkdir $configDir
  }

  $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
}