mirror of
https://github.com/fscotto/infra.git
synced 2026-05-30 15:39:58 +00:00
Split workstation profiles for Linux and Windows WSL
This commit is contained in:
@@ -91,6 +91,17 @@
|
||||
+ (ubuntu_packages_base | default([]))
|
||||
+ (ubuntu_docker_packages | default([]))
|
||||
+ (profile_packages | default([]))
|
||||
+ (workstation_dev_packages | default([]))
|
||||
+ (
|
||||
(workstation_host_linux_packages | default([]))
|
||||
if 'workstation_host_linux' in group_names
|
||||
else []
|
||||
)
|
||||
+ (
|
||||
(workstation_dev_wsl_packages | default([]))
|
||||
if 'workstation_dev_wsl' in group_names
|
||||
else []
|
||||
)
|
||||
+ (desktop_common_packages | default([]))
|
||||
+ (
|
||||
(desktop_i3_packages | default([]))
|
||||
@@ -103,7 +114,13 @@
|
||||
else []
|
||||
)
|
||||
+ (host_packages | default([]))
|
||||
) | unique
|
||||
)
|
||||
| difference(
|
||||
(workstation_dev_wsl_excluded_packages | default([]))
|
||||
if 'workstation_dev_wsl' in group_names
|
||||
else []
|
||||
)
|
||||
| unique
|
||||
}}
|
||||
state: present
|
||||
|
||||
|
||||
124
ansible/roles/profile_workstation_dev_common/tasks/main.yml
Normal file
124
ansible/roles/profile_workstation_dev_common/tasks/main.yml
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
- name: Ensure workstation user directories exist
|
||||
tags: [dotfiles, dotfiles:workstation]
|
||||
ansible.builtin.file:
|
||||
path: "{{ item.path }}"
|
||||
state: directory
|
||||
owner: "{{ username }}"
|
||||
group: "{{ user_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
loop: "{{ workstation_user_directories | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.path }}"
|
||||
|
||||
- name: Copy workstation dotfiles
|
||||
tags: [dotfiles, dotfiles:workstation]
|
||||
ansible.builtin.copy:
|
||||
src: "{{ playbook_dir }}/../dotfiles/workstation/{{ item.src }}"
|
||||
dest: "{{ user_home }}/{{ item.dest }}"
|
||||
owner: "{{ username }}"
|
||||
group: "{{ user_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
loop: "{{ workstation_dotfiles | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.dest }}"
|
||||
|
||||
- name: Render workstation templates
|
||||
tags: [dotfiles, dotfiles:workstation]
|
||||
ansible.builtin.template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ user_home }}/{{ item.dest }}"
|
||||
owner: "{{ username }}"
|
||||
group: "{{ user_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
loop: "{{ workstation_templates | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.dest }}"
|
||||
|
||||
- name: Set workstation external tool release metadata
|
||||
tags: [packages]
|
||||
ansible.builtin.set_fact:
|
||||
workstation_tools_tmp_dir: /tmp/workstation-tools
|
||||
opencode_asset_name: >-
|
||||
{{
|
||||
'opencode-linux-x64-baseline.tar.gz' if ansible_facts['architecture'] == 'x86_64'
|
||||
else 'opencode-linux-arm64.tar.gz' if ansible_facts['architecture'] in ['aarch64', 'arm64']
|
||||
else ''
|
||||
}}
|
||||
when: workstation_manage_opencode | default(false)
|
||||
|
||||
- name: Ensure architecture is supported for OpenCode binary
|
||||
tags: [packages]
|
||||
ansible.builtin.fail:
|
||||
msg: "Unsupported architecture {{ ansible_facts['architecture'] }} for OpenCode release binary"
|
||||
when:
|
||||
- workstation_manage_opencode | default(false)
|
||||
- opencode_asset_name == ''
|
||||
|
||||
- name: Ensure temporary directory exists for workstation external tools
|
||||
tags: [packages]
|
||||
ansible.builtin.file:
|
||||
path: "{{ workstation_tools_tmp_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
when: workstation_manage_opencode | default(false)
|
||||
|
||||
- name: Fetch latest OpenCode release metadata
|
||||
tags: [packages]
|
||||
ansible.builtin.uri:
|
||||
url: https://api.github.com/repos/anomalyco/opencode/releases/latest
|
||||
headers:
|
||||
Accept: application/vnd.github+json
|
||||
return_content: true
|
||||
register: opencode_latest_release
|
||||
changed_when: false
|
||||
when: workstation_manage_opencode | default(false)
|
||||
|
||||
- name: Set OpenCode release asset metadata
|
||||
tags: [packages]
|
||||
ansible.builtin.set_fact:
|
||||
opencode_version: "{{ opencode_latest_release.json.tag_name }}"
|
||||
opencode_asset: >-
|
||||
{{
|
||||
opencode_latest_release.json.assets
|
||||
| selectattr('name', 'equalto', opencode_asset_name)
|
||||
| first
|
||||
| default({})
|
||||
}}
|
||||
when: workstation_manage_opencode | default(false)
|
||||
|
||||
- name: Ensure latest OpenCode asset metadata is available
|
||||
tags: [packages]
|
||||
ansible.builtin.fail:
|
||||
msg: "Could not find OpenCode asset {{ opencode_asset_name }} in release {{ opencode_version }}"
|
||||
when:
|
||||
- workstation_manage_opencode | default(false)
|
||||
- opencode_asset == {}
|
||||
|
||||
- name: Download OpenCode release archive
|
||||
tags: [packages]
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ opencode_asset.browser_download_url }}"
|
||||
dest: "{{ workstation_tools_tmp_dir }}/{{ opencode_asset.name }}"
|
||||
checksum: "{{ opencode_asset.digest | default(omit) }}"
|
||||
mode: "0644"
|
||||
when: workstation_manage_opencode | default(false)
|
||||
|
||||
- name: Extract OpenCode release archive
|
||||
tags: [packages]
|
||||
ansible.builtin.unarchive:
|
||||
src: "{{ workstation_tools_tmp_dir }}/{{ opencode_asset.name }}"
|
||||
dest: "{{ workstation_tools_tmp_dir }}"
|
||||
remote_src: true
|
||||
when: workstation_manage_opencode | default(false)
|
||||
|
||||
- name: Install OpenCode binary
|
||||
tags: [packages]
|
||||
ansible.builtin.copy:
|
||||
src: "{{ workstation_tools_tmp_dir }}/opencode"
|
||||
dest: /usr/local/bin/opencode
|
||||
remote_src: true
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
when: workstation_manage_opencode | default(false)
|
||||
30
ansible/roles/profile_workstation_dev_wsl/tasks/main.yml
Normal file
30
ansible/roles/profile_workstation_dev_wsl/tasks/main.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
- name: Ensure WSL boot configuration file exists
|
||||
tags: [packages, services]
|
||||
ansible.builtin.file:
|
||||
path: /etc/wsl.conf
|
||||
state: touch
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
when: workstation_wsl_systemd_enabled | default(false)
|
||||
|
||||
- name: Enable systemd in WSL
|
||||
tags: [packages, services]
|
||||
community.general.ini_file:
|
||||
path: /etc/wsl.conf
|
||||
section: boot
|
||||
option: systemd
|
||||
value: 'true'
|
||||
mode: "0644"
|
||||
register: workstation_wsl_systemd_config
|
||||
when: workstation_wsl_systemd_enabled | default(false)
|
||||
|
||||
- name: Note when WSL must be restarted
|
||||
tags: [packages, services]
|
||||
ansible.builtin.debug:
|
||||
msg: "Restart the WSL distro with 'wsl --shutdown' from Windows to apply /etc/wsl.conf changes."
|
||||
changed_when: false
|
||||
when:
|
||||
- workstation_wsl_systemd_enabled | default(false)
|
||||
- workstation_wsl_systemd_config is changed
|
||||
@@ -1,117 +1,4 @@
|
||||
---
|
||||
- name: Ensure workstation user directories exist
|
||||
tags: [dotfiles, dotfiles:workstation]
|
||||
ansible.builtin.file:
|
||||
path: "{{ item.path }}"
|
||||
state: directory
|
||||
owner: "{{ username }}"
|
||||
group: "{{ user_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
loop: "{{ workstation_user_directories | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.path }}"
|
||||
|
||||
- name: Copy workstation dotfiles
|
||||
tags: [dotfiles, dotfiles:workstation]
|
||||
ansible.builtin.copy:
|
||||
src: "{{ playbook_dir }}/../dotfiles/workstation/{{ item.src }}"
|
||||
dest: "{{ user_home }}/{{ item.dest }}"
|
||||
owner: "{{ username }}"
|
||||
group: "{{ user_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
loop: "{{ workstation_dotfiles | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.dest }}"
|
||||
|
||||
- name: Render workstation templates
|
||||
tags: [dotfiles, dotfiles:workstation]
|
||||
ansible.builtin.template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ user_home }}/{{ item.dest }}"
|
||||
owner: "{{ username }}"
|
||||
group: "{{ user_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
loop: "{{ workstation_templates | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.dest }}"
|
||||
|
||||
- name: Set workstation external tool release metadata
|
||||
tags: [packages]
|
||||
ansible.builtin.set_fact:
|
||||
workstation_tools_tmp_dir: /tmp/workstation-tools
|
||||
opencode_asset_name: >-
|
||||
{{
|
||||
'opencode-linux-x64-baseline.tar.gz' if ansible_facts['architecture'] == 'x86_64'
|
||||
else 'opencode-linux-arm64.tar.gz' if ansible_facts['architecture'] in ['aarch64', 'arm64']
|
||||
else ''
|
||||
}}
|
||||
|
||||
- name: Ensure architecture is supported for OpenCode binary
|
||||
tags: [packages]
|
||||
ansible.builtin.fail:
|
||||
msg: "Unsupported architecture {{ ansible_facts['architecture'] }} for OpenCode release binary"
|
||||
when: opencode_asset_name == ''
|
||||
|
||||
- name: Ensure temporary directory exists for workstation external tools
|
||||
tags: [packages]
|
||||
ansible.builtin.file:
|
||||
path: "{{ workstation_tools_tmp_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Fetch latest OpenCode release metadata
|
||||
tags: [packages]
|
||||
ansible.builtin.uri:
|
||||
url: https://api.github.com/repos/anomalyco/opencode/releases/latest
|
||||
headers:
|
||||
Accept: application/vnd.github+json
|
||||
return_content: true
|
||||
register: opencode_latest_release
|
||||
changed_when: false
|
||||
|
||||
- name: Set OpenCode release asset metadata
|
||||
tags: [packages]
|
||||
ansible.builtin.set_fact:
|
||||
opencode_version: "{{ opencode_latest_release.json.tag_name }}"
|
||||
opencode_asset: >-
|
||||
{{
|
||||
opencode_latest_release.json.assets
|
||||
| selectattr('name', 'equalto', opencode_asset_name)
|
||||
| first
|
||||
| default({})
|
||||
}}
|
||||
|
||||
- name: Ensure latest OpenCode asset metadata is available
|
||||
tags: [packages]
|
||||
ansible.builtin.fail:
|
||||
msg: "Could not find OpenCode asset {{ opencode_asset_name }} in release {{ opencode_version }}"
|
||||
when: opencode_asset == {}
|
||||
|
||||
- name: Download OpenCode release archive
|
||||
tags: [packages]
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ opencode_asset.browser_download_url }}"
|
||||
dest: "{{ workstation_tools_tmp_dir }}/{{ opencode_asset.name }}"
|
||||
checksum: "{{ opencode_asset.digest | default(omit) }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Extract OpenCode release archive
|
||||
tags: [packages]
|
||||
ansible.builtin.unarchive:
|
||||
src: "{{ workstation_tools_tmp_dir }}/{{ opencode_asset.name }}"
|
||||
dest: "{{ workstation_tools_tmp_dir }}"
|
||||
remote_src: true
|
||||
|
||||
- name: Install OpenCode binary
|
||||
tags: [packages]
|
||||
ansible.builtin.copy:
|
||||
src: "{{ workstation_tools_tmp_dir }}/opencode"
|
||||
dest: /usr/local/bin/opencode
|
||||
remote_src: true
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
|
||||
- name: Ensure GNOME extension directories exist
|
||||
tags: [packages, gnome]
|
||||
ansible.builtin.file:
|
||||
|
||||
108
ansible/roles/profile_workstation_host_windows/tasks/main.yml
Normal file
108
ansible/roles/profile_workstation_host_windows/tasks/main.yml
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
- name: Enable required Windows features for WSL
|
||||
tags: [packages, services, wsl]
|
||||
ansible.windows.win_optional_feature:
|
||||
name:
|
||||
- Microsoft-Windows-Subsystem-Linux
|
||||
- VirtualMachinePlatform
|
||||
state: present
|
||||
include_parent: true
|
||||
|
||||
- name: Ensure winget is available on Windows host
|
||||
tags: [packages]
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$winget = Get-Command winget.exe -ErrorAction SilentlyContinue
|
||||
if ($null -eq $winget) {
|
||||
throw 'winget.exe is not available on the Windows host. Install App Installer or rerun the bootstrap script.'
|
||||
}
|
||||
$Ansible.Changed = $false
|
||||
|
||||
- name: Ensure WSL 2 is the default backend
|
||||
tags: [packages, services, wsl]
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$status = & wsl --status 2>$null
|
||||
if ($LASTEXITCODE -eq 0 -and $status -match 'Default Version:\s*2') {
|
||||
$Ansible.Changed = $false
|
||||
return
|
||||
}
|
||||
|
||||
& wsl --set-default-version 2
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw 'Failed to set WSL default version to 2.'
|
||||
}
|
||||
|
||||
$Ansible.Changed = $true
|
||||
|
||||
- name: Check whether target WSL distribution exists
|
||||
tags: [packages, services, wsl]
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$distributions = @(wsl --list --quiet) | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' }
|
||||
$ubuntuDistribution = $distributions | Where-Object { $_ -like '{{ windows_wsl_distribution_name }}*' } | Select-Object -First 1
|
||||
if ($null -ne $ubuntuDistribution) {
|
||||
$Ansible.Result = @{ exists = $true; distribution = $ubuntuDistribution }
|
||||
$Ansible.Changed = $false
|
||||
return
|
||||
}
|
||||
|
||||
$Ansible.Result = @{ exists = $false; distribution = $null }
|
||||
$Ansible.Changed = $false
|
||||
register: windows_wsl_distribution_state
|
||||
|
||||
- name: Fail when target WSL distribution is missing
|
||||
tags: [packages, services, wsl]
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
No WSL Ubuntu distribution matching {{ windows_wsl_distribution_name }}* is installed on the Windows host.
|
||||
Run scripts/bootstrap_windows_workstation.ps1 first and launch the distro once before applying the Windows play.
|
||||
when: not (windows_wsl_distribution_state.result.exists | default(false))
|
||||
|
||||
- name: Install Windows workstation applications with winget
|
||||
tags: [packages]
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$packageId = '{{ item.id }}'
|
||||
$packageName = '{{ item.name | default(item.id) }}'
|
||||
$installed = & winget list --id $packageId --exact --accept-source-agreements --disable-interactivity 2>$null
|
||||
if ($LASTEXITCODE -eq 0 -and $installed -match [regex]::Escape($packageId)) {
|
||||
$Ansible.Changed = $false
|
||||
return
|
||||
}
|
||||
|
||||
& winget install --id $packageId --exact --silent --accept-package-agreements --accept-source-agreements --disable-interactivity
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to install $packageName with winget"
|
||||
}
|
||||
|
||||
$Ansible.Changed = $true
|
||||
loop: "{{ windows_winget_packages | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.id }}"
|
||||
|
||||
- name: Install VS Code WSL extensions on Windows host
|
||||
tags: [packages, vscode]
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$extensionId = '{{ item }}'
|
||||
$code = Get-Command code.cmd -ErrorAction SilentlyContinue
|
||||
if ($null -eq $code) {
|
||||
throw 'code.cmd is not available. Ensure Visual Studio Code is installed before managing extensions.'
|
||||
}
|
||||
|
||||
$installedExtensions = & $code.Source --list-extensions
|
||||
if ($installedExtensions -contains $extensionId) {
|
||||
$Ansible.Changed = $false
|
||||
return
|
||||
}
|
||||
|
||||
& $code.Source --install-extension $extensionId --force
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to install VS Code extension $extensionId"
|
||||
}
|
||||
|
||||
$Ansible.Changed = $true
|
||||
loop: "{{ windows_vscode_extensions | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item }}"
|
||||
Reference in New Issue
Block a user