Add Linux development station role with systemd services for code-server and OpenCode

- Implemented handlers for restarting code-server and OpenCode services.
- Created main tasks for setting up a Linux development station, including user management, package installation, and configuration.
- Added validation for OpenCode server credentials and code-server password.
- Introduced tool package management for npm, uv, and go installers.
- Developed templates for systemd service units for code-server and OpenCode.
- Included scripts for starting code-server and OpenCode with SSH agent support.
- Updated inventory and Terraform configuration to include new development host.
This commit is contained in:
2026-07-10 15:44:18 +02:00
parent e1ebe7d139
commit 59b2c10c43
24 changed files with 1523 additions and 28 deletions
@@ -0,0 +1,452 @@
---
- name: Ensure host is Fedora
ansible.builtin.assert:
that:
- ansible_facts['distribution'] == "Fedora"
fail_msg: "Role linux_dev_station supports Fedora hosts only"
- name: Ensure OpenCode server credentials are provided
ansible.builtin.assert:
that:
- linux_dev_station_opencode_server_username | length > 0
- linux_dev_station_opencode_server_password | length > 0
fail_msg: >-
Set OPENCODE_SERVER_USERNAME and OPENCODE_SERVER_PASSWORD
in environment (recommended via sectool)
before running the playbook.
when: linux_dev_station_opencode_systemd_enabled | bool
- name: Ensure code-server password is provided
ansible.builtin.assert:
that:
- linux_dev_station_code_server_password | length > 0
fail_msg: >-
Set CODE_SERVER_PASSWORD in environment
(recommended via sectool) before running the playbook.
when:
- linux_dev_station_code_server_systemd_enabled | bool
- linux_dev_station_code_server_auth == "password"
- name: Install dnf packages
become: true
ansible.builtin.dnf:
name: "{{ linux_dev_station_dnf_packages }}"
state: present
- name: Ensure dedicated service user exists
become: true
ansible.builtin.user:
name: "{{ linux_dev_station_service_user }}"
shell: >-
{{ (linux_dev_station_service_user_ssh_enabled | bool) |
ternary(linux_dev_station_service_user_ssh_shell, linux_dev_station_service_shell) }}
home: "{{ linux_dev_station_service_home }}"
create_home: true
state: present
when: linux_dev_station_service_user_enabled | bool
- name: Ensure service user cache directory exists for tool installs
become: true
ansible.builtin.file:
path: "{{ linux_dev_station_service_home }}/.cache"
state: directory
mode: "0750"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
when: linux_dev_station_service_user_enabled | bool
- name: Install tool-managed packages
ansible.builtin.include_tasks: tool_packages.yml
- name: Discover npm executable path
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: /bin/sh -lc "command -v npm"
register: __linux_dev_station_npm_path
changed_when: false
failed_when: false
environment:
PATH: "{{ linux_dev_station_path }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_npm_packages | length > 0
- name: Install global npm packages
become: true
become_user: "{{ linux_dev_station_service_user }}"
community.general.npm:
name: "{{ item.name }}"
version: "{{ item.version }}"
executable: "{{ __linux_dev_station_npm_path.stdout | trim }}"
global: true
environment:
PATH: "{{ linux_dev_station_path }}"
loop: "{{ linux_dev_station_npm_packages }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_npm_packages | length > 0
- __linux_dev_station_npm_path.rc | default(1) == 0
- name: Ensure required user directories exist
become: true
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0750"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
loop:
- "{{ linux_dev_station_service_home }}"
- "{{ linux_dev_station_workspace_dir }}"
- "{{ linux_dev_station_scripts_dir }}"
- "{{ linux_dev_station_logs_dir }}"
- name: Ensure service home permissions are restrictive
become: true
ansible.builtin.file:
path: "{{ linux_dev_station_service_home }}"
state: directory
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0700"
- name: Ensure service user config directories exist
become: true
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0750"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
loop:
- "{{ linux_dev_station_service_home }}/.local"
- "{{ linux_dev_station_service_home }}/.local/bin"
- "{{ linux_dev_station_service_home }}/.local/lib"
- "{{ linux_dev_station_service_home }}/.local/lib/node_modules"
- "{{ linux_dev_station_service_home }}/.config"
- "{{ linux_dev_station_service_home }}/.config/opencode"
when: linux_dev_station_service_user_enabled | bool
- name: Ensure OpenCode config object is valid when provided
ansible.builtin.assert:
that:
- linux_dev_station_opencode_config is mapping
fail_msg: "linux_dev_station_opencode_config must be a mapping (dictionary)."
- name: Render OpenCode config from host vars
become: true
ansible.builtin.template:
src: opencode.json.j2
dest: "{{ linux_dev_station_opencode_config_path }}"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0600"
notify: Restart opencode
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_opencode_config | length > 0
- name: Download Oh My Zsh installer
become: true
ansible.builtin.get_url:
url: "{{ linux_dev_station_oh_my_zsh_install_url }}"
dest: "{{ linux_dev_station_service_home }}/.cache/ohmyzsh-install.sh"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0755"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_oh_my_zsh_enabled | bool
- name: Install Oh My Zsh for service user
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: >-
/bin/sh {{ linux_dev_station_service_home }}/.cache/ohmyzsh-install.sh --unattended
args:
creates: "{{ linux_dev_station_service_home }}/.oh-my-zsh"
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
RUNZSH: "no"
CHSH: "no"
KEEP_ZSHRC: "yes"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_oh_my_zsh_enabled | bool
- name: Ensure .zshrc has ssh-agent startup for devstation
become: true
ansible.builtin.blockinfile:
path: "{{ linux_dev_station_service_home }}/.zshrc"
block: |
# ansible: linux_dev_station ssh-agent
export SSH_AUTH_SOCK="{{ linux_dev_station_ssh_agent_socket }}"
if [ -S "$SSH_AUTH_SOCK" ] && ssh-add -l &>/dev/null; then
# Agent socket exists and has keys — nothing to do
true
else
if [ -S "$SSH_AUTH_SOCK" ]; then
# Socket exists but agent is dead or has no keys — restart
rm -f "$SSH_AUTH_SOCK"
eval "$(ssh-agent -a "$SSH_AUTH_SOCK" 2>/dev/null)" || true
else
# No socket — start fresh agent
eval "$(ssh-agent -a "$SSH_AUTH_SOCK" 2>/dev/null)" || true
fi
if [ -f "{{ linux_dev_station_scripts_dir }}/ssh-agent-start.sh" ]; then
source "{{ linux_dev_station_scripts_dir }}/ssh-agent-start.sh"
fi
fi
marker: "# {mark} ansible: linux_dev_station ssh-agent"
create: true
mode: "0644"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_ssh_agent_enabled | bool
- name: Install managed MCP server runtimes
ansible.builtin.include_tasks: mcp_installers.yml
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_mcp_installers_enabled | bool
- linux_dev_station_mcp_installers | length > 0
- name: Run MCP bootstrap commands
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.shell: "{{ item }}"
register: __linux_dev_station_mcp_bootstrap_result
changed_when: __linux_dev_station_mcp_bootstrap_result.rc == 0
args:
executable: /bin/sh
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}"
loop: "{{ linux_dev_station_mcp_bootstrap_commands }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_mcp_bootstrap_commands | length > 0
- name: List installed code-server extensions for service user
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: code-server --list-extensions
register: __linux_dev_station_code_server_extensions_installed
changed_when: false
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_code_server_extensions_enabled | bool
- linux_dev_station_code_server_extensions | length > 0
- name: Install base code-server extensions for service user
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: >-
code-server --install-extension {{ item }}
register: __linux_dev_station_code_server_extension_install
changed_when: __linux_dev_station_code_server_extension_install.rc == 0
failed_when: >-
(linux_dev_station_code_server_extensions_fail_on_error | bool)
and (__linux_dev_station_code_server_extension_install.rc != 0)
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}"
notify: Restart code-server
loop: "{{ linux_dev_station_code_server_extensions }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_code_server_extensions_enabled | bool
- item not in (__linux_dev_station_code_server_extensions_installed.stdout_lines | default([]))
- name: Report skipped code-server extensions that are unavailable
ansible.builtin.debug:
msg: >-
Skipping unavailable code-server extension '{{ item.item }}':
{{ (item.stderr_lines | default([])) | join(' ') }}
loop: "{{ __linux_dev_station_code_server_extension_install.results | default([]) }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_code_server_extensions_enabled | bool
- not (linux_dev_station_code_server_extensions_fail_on_error | bool)
- item.rc is defined
- item.rc != 0
- name: Copy Copilot installer script
become: true
ansible.builtin.copy:
src: install-copilot.sh
dest: "{{ linux_dev_station_service_home }}/.cache/install-copilot.sh"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0755"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_copilot_enabled | bool
- name: Install GitHub Copilot extensions via compatible VSIX
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: "{{ linux_dev_station_service_home }}/.cache/install-copilot.sh"
register: __linux_dev_station_copilot_install_result
changed_when: __linux_dev_station_copilot_install_result.rc == 0
failed_when: >-
(linux_dev_station_copilot_fail_on_error | bool)
and (__linux_dev_station_copilot_install_result.rc != 0)
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_copilot_enabled | bool
- name: Ensure devstation SSH directory exists when SSH access is enabled
become: true
ansible.builtin.file:
path: "{{ linux_dev_station_service_home }}/.ssh"
state: directory
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0700"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_service_user_ssh_enabled | bool
- name: Ensure devstation authorized keys are present when SSH access is enabled
become: true
ansible.posix.authorized_key:
user: "{{ linux_dev_station_service_user }}"
key: "{{ item }}"
state: present
loop: "{{ linux_dev_station_service_user_ssh_authorized_keys }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_service_user_ssh_enabled | bool
- name: Render ssh-agent starter script
become: true
ansible.builtin.template:
src: ssh-agent-start.sh.j2
dest: "{{ linux_dev_station_scripts_dir }}/ssh-agent-start.sh"
mode: "0755"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_ssh_agent_enabled | bool
- name: Ensure ssh_config has ssh-agent settings for devstation
become: true
ansible.builtin.blockinfile:
path: "{{ linux_dev_station_service_home }}/.ssh/config"
block: |
Host *
AddKeysToAgent yes
ServerAliveInterval 60
ServerAliveCountMax 3
marker: "# {mark} ansible: linux_dev_station ssh-agent"
create: true
mode: "0600"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_ssh_agent_enabled | bool
- name: Generate SSH key if missing
ansible.builtin.command: >-
ssh-keygen -t ed25519 -C {{ linux_dev_station_ssh_key_comment }}
-f {{ linux_dev_station_ssh_key_path }} -N ''
args:
creates: "{{ linux_dev_station_ssh_key_path }}"
- name: Configure Git init default branch
community.general.git_config:
name: init.defaultBranch
scope: global
value: "{{ linux_dev_station_git_init_default_branch }}"
- name: Configure Git pull.rebase
community.general.git_config:
name: pull.rebase
scope: global
value: "{{ linux_dev_station_git_pull_rebase | ternary('true', 'false') }}"
- name: Render code-server launcher script
become: true
ansible.builtin.template:
src: start-ide.sh.j2
dest: "{{ linux_dev_station_scripts_dir }}/start-ide.sh"
mode: "0755"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
- name: Render opencode launcher script
become: true
ansible.builtin.template:
src: start-opencode.sh.j2
dest: "{{ linux_dev_station_scripts_dir }}/start-opencode.sh"
mode: "0755"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
- name: Render tmux configuration
ansible.builtin.copy:
dest: "{{ ansible_facts['env']['HOME'] }}/.tmux.conf"
mode: "0644"
content: |
set -g mouse on
set -g history-limit 100000
- name: Render code-server systemd unit
become: true
ansible.builtin.template:
src: code-server.service.j2
dest: "{{ linux_dev_station_systemd_unit_dir }}/code-server.service"
mode: "0644"
when: linux_dev_station_code_server_systemd_enabled | bool
notify: Restart code-server
- name: Render opencode systemd unit
become: true
ansible.builtin.template:
src: opencode.service.j2
dest: "{{ linux_dev_station_systemd_unit_dir }}/opencode.service"
mode: "0644"
when: linux_dev_station_opencode_systemd_enabled | bool
notify: Restart opencode
- name: Ensure code-server service is started and enabled
become: true
ansible.builtin.systemd:
name: code-server
state: started
enabled: true
daemon_reload: true
when:
- linux_dev_station_manage_systemd | bool
- linux_dev_station_code_server_systemd_enabled | bool
- name: Ensure opencode service is started and enabled
become: true
ansible.builtin.systemd:
name: opencode
state: started
enabled: true
daemon_reload: true
when:
- linux_dev_station_manage_systemd | bool
- linux_dev_station_opencode_systemd_enabled | bool
- name: Ensure systemd services are started
ansible.builtin.meta: flush_handlers
when: linux_dev_station_manage_systemd | bool
@@ -0,0 +1,138 @@
---
- name: Ensure MCP installer definitions list is valid
ansible.builtin.assert:
that:
- linux_dev_station_mcp_installers is iterable
fail_msg: "linux_dev_station_mcp_installers must be a list of installer definitions."
- name: Validate MCP installer kind values
ansible.builtin.assert:
that:
- item.kind is defined
- item.kind in ['npm', 'uv', 'go']
fail_msg: >-
MCP installer '{{ item.name | default('unnamed') }}'
has unsupported kind '{{ item.kind | default('undefined') }}'.
Supported: npm, uv, go.
loop: "{{ linux_dev_station_mcp_installers }}"
when: item.enabled | default(true) | bool
- name: Validate npm MCP installers
ansible.builtin.assert:
that:
- item.package is defined
- item.package | length > 0
fail_msg: "npm MCP installer '{{ item.name | default('unnamed') }}' requires 'package'."
loop: "{{ linux_dev_station_mcp_installers }}"
when:
- item.enabled | default(true) | bool
- item.kind == 'npm'
- name: Validate uv MCP installers
ansible.builtin.assert:
that:
- item.package is defined
- item.package | length > 0
- item.binary is defined
- item.binary | length > 0
fail_msg: "uv MCP installer '{{ item.name | default('unnamed') }}' requires 'package' and 'binary'."
loop: "{{ linux_dev_station_mcp_installers }}"
when:
- item.enabled | default(true) | bool
- item.kind == 'uv'
- name: Validate go MCP installers
ansible.builtin.assert:
that:
- item.module is defined
- item.module | length > 0
- item.binary is defined
- item.binary | length > 0
fail_msg: "go MCP installer '{{ item.name | default('unnamed') }}' requires 'module' and 'binary'."
loop: "{{ linux_dev_station_mcp_installers }}"
when:
- item.enabled | default(true) | bool
- item.kind == 'go'
- name: Discover npm executable path for MCP installers
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: /bin/sh -lc "command -v npm"
register: __linux_dev_station_mcp_npm_path
changed_when: false
failed_when: false
environment:
PATH: "{{ linux_dev_station_path }}"
when: (linux_dev_station_mcp_installers | selectattr('kind', 'equalto', 'npm') | list | length) > 0
- name: Install npm MCP packages for service user
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command:
argv:
- "{{ __linux_dev_station_mcp_npm_path.stdout | trim }}"
- install
- --prefix
- "{{ linux_dev_station_service_home }}/.local"
- --global
- "{{ item.package }}@{{ item.version | default('latest') }}"
args:
creates: "{{ linux_dev_station_service_home }}/.local/lib/node_modules/{{ item.package }}"
register: __linux_dev_station_mcp_npm_install
changed_when: __linux_dev_station_mcp_npm_install.rc == 0
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}"
notify: Restart opencode
loop: "{{ linux_dev_station_mcp_installers }}"
when:
- item.enabled | default(true) | bool
- item.kind == 'npm'
- __linux_dev_station_mcp_npm_path.rc | default(1) == 0
- name: Install uv MCP tools for service user
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command:
argv:
- uv
- tool
- install
- "{{ item.package }}@{{ item.version | default('latest') }}"
args:
creates: "{{ linux_dev_station_service_home }}/.local/bin/{{ item.binary }}"
register: __linux_dev_station_mcp_uv_install
changed_when: __linux_dev_station_mcp_uv_install.rc == 0
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}"
notify: Restart opencode
loop: "{{ linux_dev_station_mcp_installers }}"
when:
- item.enabled | default(true) | bool
- item.kind == 'uv'
- name: Install go MCP binaries for service user
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command:
argv:
- go
- install
- "{{ item.module }}@{{ item.version | default('latest') }}"
args:
creates: "{{ linux_dev_station_service_home }}/.local/bin/{{ item.binary }}"
register: __linux_dev_station_mcp_go_install
changed_when: __linux_dev_station_mcp_go_install.rc == 0
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}"
GOBIN: "{{ linux_dev_station_service_home }}/.local/bin"
notify: Restart opencode
loop: "{{ linux_dev_station_mcp_installers }}"
when:
- item.enabled | default(true) | bool
- item.kind == 'go'
@@ -0,0 +1,268 @@
---
- name: Ensure tool packages list is valid
ansible.builtin.assert:
that:
- linux_dev_station_tool_packages is iterable
fail_msg: "linux_dev_station_tool_packages must be a list of tool definitions."
- name: Download uv installer
become: true
ansible.builtin.get_url:
url: https://astral.sh/uv/install.sh
dest: "{{ linux_dev_station_service_home }}/.cache/uv-install.sh"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0755"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'uv') | list | length > 0
- name: Install uv
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: >-
/bin/sh {{ linux_dev_station_service_home }}/.cache/uv-install.sh
args:
creates: "{{ linux_dev_station_service_home }}/.local/bin/uv"
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}"
UV_UNINSTALL_MISSING_PACKAGES: "1"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'uv') | list | length > 0
- name: Download rustup installer
become: true
ansible.builtin.get_url:
url: https://sh.rustup.rs
dest: "{{ linux_dev_station_service_home }}/.cache/rustup-install.sh"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0755"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'rust') | list | length > 0
- name: Install rustup
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: >-
/bin/sh {{ linux_dev_station_service_home }}/.cache/rustup-install.sh -y --default-toolchain stable
args:
creates: "{{ linux_dev_station_service_home }}/.cargo/bin/rustc"
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}:{{ linux_dev_station_service_home }}/.cargo/bin"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'rust') | list | length > 0
- name: Download fnm (Fast Node Manager) binary
become: true
ansible.builtin.get_url:
url: "https://github.com/Schniz/fnm/releases/download/{{ fnm_version }}/fnm-linux.zip"
dest: "{{ linux_dev_station_service_home }}/.cache/fnm.zip"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0644"
vars:
fnm_version: v1.38.1
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'node') | list | length > 0
- name: Create .fnm directory
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.file:
path: "{{ linux_dev_station_service_home }}/.fnm"
state: directory
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0755"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'node') | list | length > 0
- name: Extract fnm to .fnm directory
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.unarchive:
src: "{{ linux_dev_station_service_home }}/.cache/fnm.zip"
dest: "{{ linux_dev_station_service_home }}/.fnm"
remote_src: true
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'node') | list | length > 0
- name: Ensure fnm binary is executable
become: true
ansible.builtin.file:
path: "{{ linux_dev_station_service_home }}/.fnm/fnm"
mode: "0755"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'node') | list | length > 0
- name: Install LTS Node.js version via fnm
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: >-
{{ linux_dev_station_service_home }}/.fnm/fnm install --lts
args:
creates: "{{ linux_dev_station_service_home }}/.fnm/node-versions"
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}:{{ linux_dev_station_service_home }}/.fnm"
FNM_DIR: "{{ linux_dev_station_service_home }}/.fnm"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'node') | list | length > 0
- name: Get installed Node.js version from fnm node-versions directory
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: ls "{{ linux_dev_station_service_home }}/.fnm/node-versions"
register: fnm_versions_list
changed_when: false
environment:
FNM_DIR: "{{ linux_dev_station_service_home }}/.fnm"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'node') | list | length > 0
- name: Set default Node.js version via fnm
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.command: >-
{{ linux_dev_station_service_home }}/.fnm/fnm default {{ node_version }}
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
PATH: "{{ linux_dev_station_path }}:{{ linux_dev_station_service_home }}/.fnm"
FNM_DIR: "{{ linux_dev_station_service_home }}/.fnm"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'node') | list | length > 0
- fnm_versions_list is defined
- fnm_versions_list.stdout | trim | length > 0
vars:
node_version: "{{ fnm_versions_list.stdout | trim }}"
- name: Download code-server tarball
become: true
ansible.builtin.get_url:
url: "https://github.com/coder/code-server/releases/download/v{{ tool.version }}/code-server-{{ tool.version }}-linux-amd64.tar.gz"
dest: "{{ linux_dev_station_service_home }}/.cache/code-server.tar.gz"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0644"
vars:
tool: "{{ linux_dev_station_tool_packages | selectattr('name', 'equalto', 'code-server') | first }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'code-server') | list | length > 0
- name: Create code-server installation directories
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0755"
loop:
- "{{ linux_dev_station_service_home }}/.local/lib"
- "{{ linux_dev_station_service_home }}/.local/bin"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'code-server') | list | length > 0
- name: Extract code-server tarball to lib directory
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.unarchive:
src: "{{ linux_dev_station_service_home }}/.cache/code-server.tar.gz"
dest: "{{ linux_dev_station_service_home }}/.local/lib"
remote_src: true
environment:
HOME: "{{ linux_dev_station_service_home }}"
USER: "{{ linux_dev_station_service_user }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'code-server') | list | length > 0
- name: Create symlink for code-server binary
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.file:
src: "{{ linux_dev_station_service_home }}/.local/lib/code-server-{{ tool.version }}-linux-amd64/bin/code-server"
dest: "{{ linux_dev_station_service_home }}/.local/bin/code-server"
state: link
vars:
tool: "{{ linux_dev_station_tool_packages | selectattr('name', 'equalto', 'code-server') | first }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'code-server') | list | length > 0
- name: Create opencode installation directories
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0755"
loop:
- "{{ linux_dev_station_service_home }}/.local/lib"
- "{{ linux_dev_station_service_home }}/.local/lib/opencode-{{ tool.version }}"
- "{{ linux_dev_station_service_home }}/.local/bin"
vars:
tool: "{{ linux_dev_station_tool_packages | selectattr('name', 'equalto', 'opencode') | first }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'opencode') | list | length > 0
- name: Download opencode tarball
become: true
ansible.builtin.get_url:
url: "https://github.com/anomalyco/opencode/releases/download/v{{ tool.version }}/opencode-linux-x64.tar.gz"
dest: "{{ linux_dev_station_service_home }}/.cache/opencode-{{ tool.version }}.tar.gz"
owner: "{{ linux_dev_station_service_user }}"
group: "{{ linux_dev_station_service_user }}"
mode: "0644"
vars:
tool: "{{ linux_dev_station_tool_packages | selectattr('name', 'equalto', 'opencode') | first }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'opencode') | list | length > 0
- name: Extract opencode tarball to versioned directory
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.unarchive:
src: "{{ linux_dev_station_service_home }}/.cache/opencode-{{ tool.version }}.tar.gz"
dest: "{{ linux_dev_station_service_home }}/.local/lib/opencode-{{ tool.version }}"
remote_src: true
vars:
tool: "{{ linux_dev_station_tool_packages | selectattr('name', 'equalto', 'opencode') | first }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'opencode') | list | length > 0
- name: Create symlink for opencode binary
become: true
become_user: "{{ linux_dev_station_service_user }}"
ansible.builtin.file:
src: "{{ linux_dev_station_service_home }}/.local/lib/opencode-{{ tool.version }}/opencode"
dest: "{{ linux_dev_station_service_home }}/.local/bin/opencode"
state: link
vars:
tool: "{{ linux_dev_station_tool_packages | selectattr('name', 'equalto', 'opencode') | first }}"
when:
- linux_dev_station_service_user_enabled | bool
- linux_dev_station_tool_packages | selectattr('name', 'equalto', 'opencode') | list | length > 0