640 lines
20 KiB
YAML
640 lines
20 KiB
YAML
- hosts: localhost
|
|
become: true
|
|
|
|
vars:
|
|
|
|
# Debian packages that must be installed
|
|
debian_packages:
|
|
- acl
|
|
- bat
|
|
- bind9
|
|
- build-essential
|
|
- console-common
|
|
- console-setup
|
|
- containerd.io
|
|
- curl
|
|
- dialog
|
|
- docker-buildx-plugin
|
|
- docker-ce
|
|
- docker-ce-cli
|
|
- docker-compose-plugin
|
|
- firefox-esr
|
|
- fzf
|
|
- gawk
|
|
- git
|
|
- htop
|
|
- ipcalc
|
|
- iptables-persistent
|
|
- keepassxc
|
|
- ldap-utils
|
|
- libldap2-dev
|
|
- libsasl2-dev
|
|
- libvirt-clients
|
|
- libvirt-daemon
|
|
- libvirt-daemon-config-network
|
|
- libvirt-daemon-driver-qemu
|
|
- libvirt-daemon-system
|
|
- libvirt-daemon-system-systemd
|
|
- libvirt-dbus
|
|
- lua5.4
|
|
- net-tools
|
|
- psmisc
|
|
- python3-dev
|
|
- python3-pip
|
|
- qemu-guest-agent
|
|
- qemu-kvm
|
|
- remmina
|
|
- spice-vdagent
|
|
- sshpass
|
|
- task-xfce-desktop
|
|
- unzip
|
|
- vim-gtk3
|
|
- virt-manager
|
|
- zsh
|
|
# Version of ASDF itself
|
|
asdf_version: 0.15.0
|
|
# Tools that will be installed using asdf
|
|
asdf_tools:
|
|
- java
|
|
- golang
|
|
- nodejs
|
|
- opentofu
|
|
- packer
|
|
- terragrunt
|
|
# If some asdf-installed tools require specific versions, they must be
|
|
# listed here. Tools that are not listed will default to the latest
|
|
# version.
|
|
asdf_tool_versions:
|
|
java: openjdk-17
|
|
nodejs: 22.12.0
|
|
opentofu: 1.8.1
|
|
packer: 1.11.0
|
|
terragrunt: 0.66.9
|
|
# Python packages to install
|
|
python_packages:
|
|
- ansible>=9,<10
|
|
- dnspython
|
|
- netaddr
|
|
- python-ldap
|
|
- xmltodict
|
|
- pyvmomi
|
|
- requests
|
|
- git+https://github.com/vmware/vsphere-automation-sdk-python.git
|
|
- pywinrm
|
|
# Version of the git-delta utility
|
|
git_delta_version: 0.18.2
|
|
# Version of the atuin utility
|
|
atuin_version: 18.4.0
|
|
# Vim plugins that need to be installed
|
|
vim_plugins:
|
|
- airblade/vim-gitgutter
|
|
- bling/vim-airline
|
|
- cespare/vim-toml
|
|
- ctrlpvim/ctrlp.vim
|
|
- elzr/vim-json
|
|
- Exafunction/codeium.vim
|
|
- fatih/vim-go
|
|
- Glench/Vim-Jinja2-Syntax
|
|
- hashivim/vim-terraform
|
|
- liuchengxu/vim-which-key
|
|
- mattn/vim-lsp-settings
|
|
- mbbill/undotree
|
|
- octol/vim-cpp-enhanced-highlight
|
|
- PProvost/vim-ps1
|
|
- prabirshrestha/asyncomplete-lsp.vim
|
|
- prabirshrestha/asyncomplete.vim
|
|
- prabirshrestha/async.vim
|
|
- prabirshrestha/vim-lsp
|
|
- rbong/vim-flog
|
|
- rust-lang/rust.vim
|
|
- scrooloose/nerdtree
|
|
- Shougo/dein.vim
|
|
- skywind3000/asyncrun.vim
|
|
- tikhomirov/vim-glsl
|
|
- tpope/vim-fugitive
|
|
- vim-airline/vim-airline-themes
|
|
- vim-perl/vim-perl
|
|
- vim-test/vim-test
|
|
- wsdjeg/dein-ui.vim
|
|
- Xuyuanp/nerdtree-git-plugin
|
|
|
|
# Various parameters need to be fetched from env variables
|
|
domain_name: >-
|
|
{{ lookup( "env", "VMNET_DOMAIN" ) }}
|
|
update_key: >-
|
|
{{ lookup( "env", "VMNET_BIND_KEY_ID" ) }}
|
|
back_net: >-
|
|
{{ lookup( "env" , "VMNET_BACK_ADDR" ) }}
|
|
front_net: >-
|
|
{{ lookup( "env" , "VMNET_FRONT_ADDR" ) }}
|
|
back_arpa: >-
|
|
{{ back_net.split( "." )[0:3] | reverse | join( "." ) }}.in-addr.arpa
|
|
front_arpa: >-
|
|
{{ front_net.split( "." )[0:3] | reverse | join( "." ) }}.in-addr.arpa
|
|
locale: >-
|
|
{{ lookup( "env", "VM_LOCALE" ) }}
|
|
chezmoi_source: >-
|
|
{{ lookup( "env", "CHEZMOI_SOURCE" ) }}
|
|
|
|
tasks:
|
|
|
|
# Configure grub
|
|
- name: Reduce boot delay to 1s
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/default/grub
|
|
regexp: ^GRUB_TIMEOUT=
|
|
line: GRUB_TIMEOUT=1
|
|
|
|
- name: Update Grub configuration
|
|
ansible.builtin.command:
|
|
cmd: update-grub2
|
|
|
|
# Ensure ext4 filesystems are mounted with discard enabled
|
|
- name: Add discard option to mount points
|
|
loop: [ "/" , "/boot" ]
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/fstab
|
|
backrefs: true
|
|
regexp: '^(\S+\s+{{ item }}\s+\S+\s+)(?!(?:\S*,)?discard(?:,\S*)?\s+)(\S+)(\s+.+)$'
|
|
line: '\1discard,\2\3'
|
|
|
|
# Prepare for docker installation
|
|
- name: Get APT key for the Docker repo
|
|
ansible.builtin.shell:
|
|
cmd: wget -O- https://download.docker.com/linux/debian/gpg > /etc/apt/keyrings/docker.asc
|
|
- name: Add Docker APT repo
|
|
ansible.builtin.shell:
|
|
cmd: |
|
|
echo \
|
|
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] http://download.docker.com/linux/debian \
|
|
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
|
> /etc/apt/sources.list.d/docker.list
|
|
|
|
# Install various required packages
|
|
- name: Remove unnecessary packages
|
|
ansible.builtin.command:
|
|
cmd: apt-get autoremove -y
|
|
- name: Install packages
|
|
ansible.builtin.apt:
|
|
update_cache: true
|
|
name: "{{ debian_packages }}"
|
|
|
|
# Keyboard / locale configuration
|
|
- name: Copy keyboard config
|
|
ansible.builtin.copy:
|
|
src: files/keyboard
|
|
dest: /etc/default/keyboard
|
|
force: true
|
|
- name: Copy locale config
|
|
ansible.builtin.template:
|
|
src: files/locale.j2
|
|
dest: /etc/default/locale
|
|
force: true
|
|
- name: Change locale to {{ locale }}
|
|
community.general.locale_gen:
|
|
name: "{{ locale }}"
|
|
state: present
|
|
- name: Set timezone
|
|
community.general.timezone:
|
|
name: Europe/Paris
|
|
- name: dpkg-reconfigure
|
|
ansible.builtin.shell: >
|
|
dpkg-reconfigure -f noninteractive keyboard-configuration &&
|
|
localectl set-locale LANG={{ locale }} LANGUAGE={{ locale }} &&
|
|
timedatectl set-timezone Europe/Paris &&
|
|
update-locale LANG={{ locale }}
|
|
|
|
# Desktop resizing
|
|
- name: Create desktop resizing logs directory
|
|
ansible.builtin.file:
|
|
path: /var/log/autores
|
|
state: directory
|
|
mode: "0700"
|
|
- name: Copy desktop resizing script
|
|
ansible.builtin.copy:
|
|
src: files/resize.sh
|
|
dest: /usr/local/bin/x-resize
|
|
mode: "0755"
|
|
- name: Create udev rule
|
|
ansible.builtin.copy:
|
|
content: >
|
|
ACTION=="change",KERNEL=="card0", SUBSYSTEM=="drm", RUN+="/usr/local/bin/x-resize"
|
|
dest: /etc/udev/rules.d/50-x-resize.rules
|
|
mode: "0644"
|
|
- name: Reload udev rules
|
|
ansible.builtin.command:
|
|
cmd: udevadm control --reload-rules
|
|
|
|
# Prevent XFCE from creating random dirs in the user home
|
|
- name: Create user config directory
|
|
ansible.builtin.file:
|
|
path: /home/vagrant/.config
|
|
state: directory
|
|
owner: vagrant
|
|
group: vagrant
|
|
|
|
- name: Configure XDG user dirs
|
|
ansible.builtin.copy:
|
|
src: files/user-dirs.dirs
|
|
dest: /home/vagrant/.config/user-dirs.dirs
|
|
owner: vagrant
|
|
group: vagrant
|
|
|
|
# Configure VM networks
|
|
- name: Configure dummy module
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/modprobe.d/local.conf
|
|
create: true
|
|
line: options dummy numdummies=0
|
|
|
|
- name: Configure bridge network devices
|
|
loop: [0, 1]
|
|
ansible.builtin.copy:
|
|
content: |
|
|
[NetDev]
|
|
Name=br{{ item }}
|
|
Kind=bridge
|
|
dest: /etc/systemd/network/bridge{{ item }}.netdev
|
|
|
|
- name: Configure bridge networks
|
|
loop:
|
|
- { id: 0, addr: "{{ back_net }}" }
|
|
- { id: 1, addr: "{{ front_net }}" }
|
|
ansible.builtin.copy:
|
|
content: |
|
|
[Match]
|
|
Name=br{{ item.id }}
|
|
[Network]
|
|
ConfigureWithoutCarrier=yes
|
|
LinkLocalAddressing=no
|
|
Address={{ item.addr }}/24
|
|
dest: /etc/systemd/network/bridge{{ item.id }}.network
|
|
|
|
- name: Configure dummy network devices
|
|
loop: [0, 1]
|
|
ansible.builtin.copy:
|
|
content: |
|
|
[NetDev]
|
|
Name=dummy{{ item }}
|
|
Kind=dummy
|
|
dest: /etc/systemd/network/dummy{{ item }}.netdev
|
|
|
|
- name: Enslave dummy network devices to bridges
|
|
loop: [0, 1]
|
|
ansible.builtin.copy:
|
|
content: |
|
|
[Match]
|
|
Name=dummy{{ item }}
|
|
[Network]
|
|
Bridge=br{{ item }}
|
|
ConfigureWithoutCarrier=yes
|
|
dest: /etc/systemd/network/dummy{{ item }}.network
|
|
|
|
- name: Ensure IPv4 forwarding is enabled
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/systemd/network/eth0.network
|
|
line: IPForward=ipv4
|
|
insertafter: ^\[Network\]$
|
|
|
|
- name: Configure NAT
|
|
ansible.builtin.copy:
|
|
src: files/iptables
|
|
dest: /etc/iptables/rules.v4
|
|
|
|
# Configure DNS server
|
|
- name: Disable IPv6 for Bind
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/default/named
|
|
line: OPTIONS="-u bind -4"
|
|
regexp: ^OPTIONS=
|
|
|
|
- name: Generate dynamic update key
|
|
when: lookup( "env", "VMNET_BIND_KEY" ) == ""
|
|
ansible.builtin.shell:
|
|
cmd: >-
|
|
tsig-keygen -a hmac-sha512 {{ update_key }}.
|
|
> /etc/bind/tf-key.conf
|
|
creates: /etc/bind/tf-key.conf
|
|
|
|
- name: Copy dynamic update key
|
|
when: lookup( "env", "VMNET_BIND_KEY" ) != ""
|
|
ansible.builtin.template:
|
|
src: files/tf-key.conf.j2
|
|
dest: /etc/bind/tf-key.conf
|
|
|
|
- name: Configure Bind options
|
|
ansible.builtin.template:
|
|
src: files/bind-options
|
|
dest: /etc/bind/named.conf.options
|
|
owner: root
|
|
group: bind
|
|
|
|
- name: Configure local domains
|
|
ansible.builtin.template:
|
|
src: files/domains.j2
|
|
dest: /etc/bind/named.conf.local
|
|
owner: root
|
|
group: bind
|
|
|
|
- name: Initialize zone for domain
|
|
ansible.builtin.template:
|
|
src: files/zf-domain.j2
|
|
dest: /var/lib/bind/db.{{ domain_name }}
|
|
owner: bind
|
|
group: bind
|
|
|
|
- name: Initialize reverse DNS zones
|
|
loop:
|
|
- { arpa: "{{ back_arpa }}" , host: vm-host }
|
|
- { arpa: "{{ front_arpa }}" , host: vm-host-f }
|
|
ansible.builtin.template:
|
|
src: files/zf-reverse.j2
|
|
dest: /var/lib/bind/db.{{ item.arpa }}
|
|
owner: bind
|
|
group: bind
|
|
|
|
- name: Ensure resolution is enabled for external domains
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/systemd/network/eth0.network
|
|
line: Domains=~.
|
|
insertafter: ^\[Network\]$
|
|
|
|
- name: Configure systemd-resolved so it queries the local DNS server
|
|
ansible.builtin.template:
|
|
src: files/resolved.conf.j2
|
|
dest: /etc/systemd/resolved.conf
|
|
|
|
# Download and install delta. The asdf-provided version doesn't work on
|
|
# Debian.
|
|
- name: Download git-delta
|
|
ansible.builtin.get_url:
|
|
url: https://github.com/dandavison/delta/releases/download/{{ git_delta_version }}/git-delta-musl_{{ git_delta_version }}_amd64.deb
|
|
dest: /root
|
|
|
|
- name: Install git-delta
|
|
ansible.builtin.command:
|
|
cmd: dpkg -i /root/git-delta-musl_{{ git_delta_version }}_amd64.deb
|
|
|
|
# Download and install atuin.
|
|
- name: Download atuin
|
|
ansible.builtin.get_url:
|
|
url: https://github.com/atuinsh/atuin/releases/download/v{{ atuin_version }}/atuin-x86_64-unknown-linux-gnu.tar.gz
|
|
dest: /tmp
|
|
|
|
- name: Install atuin
|
|
ansible.builtin.command:
|
|
cmd: tar xzf /tmp/atuin-x86_64-unknown-linux-gnu.tar.gz --strip-components=1 atuin-x86_64-unknown-linux-gnu/atuin
|
|
chdir: /usr/local/bin
|
|
|
|
# Ensure virtualization and docker can be used
|
|
- name: Add the vagrant user to various group
|
|
ansible.builtin.user:
|
|
name: vagrant
|
|
groups: kvm,libvirt,docker
|
|
append: true
|
|
|
|
- name: Make the QEMU bridge helper setuid
|
|
ansible.builtin.file:
|
|
path: /usr/lib/qemu/qemu-bridge-helper
|
|
group: kvm
|
|
mode: "6750"
|
|
|
|
- name: Allow QEMU tu use br0
|
|
ansible.builtin.copy:
|
|
content: allow br0
|
|
dest: /etc/qemu/bridge.conf
|
|
|
|
- name: Disable libvirt security driver
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/libvirt/qemu.conf
|
|
regexp: ^security_driver\s*=
|
|
line: >-
|
|
security_driver = "none"
|
|
|
|
# Set the shell to zsh for the vagrant user
|
|
- name: Set default shell
|
|
ansible.builtin.user:
|
|
name: vagrant
|
|
shell: /bin/zsh
|
|
|
|
# "Fix" X11 forwarding
|
|
- name: Fix X11 forwarding through SSH
|
|
ansible.builtin.copy:
|
|
dest: /etc/ssh/sshd_config.d/x11forwarding.conf
|
|
content: |
|
|
X11UseLocalhost no
|
|
|
|
- name: Configure user account
|
|
become: false
|
|
block:
|
|
|
|
- name: Create directories for zsh and other tools
|
|
loop:
|
|
- .local/share/zsh
|
|
- .local/bin
|
|
- .config/atuin
|
|
- .ssh
|
|
ansible.builtin.file:
|
|
state: directory
|
|
path: /home/vagrant/{{ item }}
|
|
mode: "0755"
|
|
owner: vagrant
|
|
group: vagrant
|
|
|
|
# Install ASDF
|
|
- name: Install ASDF
|
|
ansible.builtin.git:
|
|
repo: https://github.com/asdf-vm/asdf.git
|
|
dest: /home/vagrant/.asdf
|
|
single_branch: true
|
|
version: v{{ asdf_version }}
|
|
|
|
# Install and run Chezmoi
|
|
- name: Install chezmoi
|
|
ansible.builtin.shell:
|
|
cmd: >-
|
|
set -e ;
|
|
export ASDF_DIR=/home/vagrant/.asdf ;
|
|
. $ASDF_DIR/asdf.sh ;
|
|
asdf plugin-add chezmoi ;
|
|
asdf install chezmoi latest ;
|
|
asdf global chezmoi latest
|
|
chdir: /home/vagrant
|
|
- name: Check for known host
|
|
when: >-
|
|
chezmoi_source is match( "^ssh://" )
|
|
check_mode: true
|
|
ansible.builtin.lineinfile:
|
|
path: /home/vagrant/.ssh/known_hosts
|
|
line: "^{{ chezmoi_source | urlsplit( 'hostname' ) }} "
|
|
regex: true
|
|
state: absent
|
|
register: ssh_key_present
|
|
- name: Add SSH key for chezmoi's Git repo
|
|
when: >-
|
|
chezmoi_source is match( "^ssh://" ) and
|
|
ssh_key_present is not changed
|
|
ansible.builtin.shell:
|
|
cmd: >-
|
|
ssh-keyscan {{ chezmoi_source | urlsplit( 'hostname' ) }} \
|
|
>> /home/vagrant/.ssh/known_hosts
|
|
- name: Check for chezmoi repo
|
|
when: chezmoi_source != ""
|
|
ansible.builtin.stat:
|
|
path: /home/vagrant/.local/share/chezmoi
|
|
register: chezmoi_stat
|
|
- name: Initialize chezmoi
|
|
when: chezmoi_source != "" and not chezmoi_stat.stat.exists
|
|
ansible.builtin.shell:
|
|
cmd: >-
|
|
set -e ;
|
|
export ASDF_DIR=/home/vagrant/.asdf ;
|
|
. $ASDF_DIR/asdf.sh ;
|
|
chezmoi init {{ chezmoi_source }} ;
|
|
chezmoi apply
|
|
chdir: /home/vagrant
|
|
|
|
# If there's not .zshrc, use default config files
|
|
- name: Check for zshrc
|
|
ansible.builtin.stat:
|
|
path: /home/vagrant/.zshrc
|
|
register: zshrc_stat
|
|
|
|
- when: not zshrc_stat.stat.exists
|
|
block:
|
|
|
|
# Create the zsh configuration for the vagrant user
|
|
- name: Copy configuration files
|
|
loop:
|
|
- {s: antigen.zsh, d: .local/share/zsh/antigen.zsh}
|
|
- {s: p10k.zsh, d: .local/share/zsh/p10k.zsh}
|
|
- {s: atuin.toml, d: .config/atuin/config.toml}
|
|
- {s: gitconfig, d: .gitconfig}
|
|
ansible.builtin.copy:
|
|
src: files/{{ item.s }}
|
|
dest: /home/vagrant/{{ item.d }}
|
|
mode: "0644"
|
|
owner: vagrant
|
|
group: vagrant
|
|
|
|
- name: Update configuration files
|
|
loop:
|
|
- {s: zshrc, d: .zshrc}
|
|
ansible.builtin.template:
|
|
src: files/{{ item.s }}
|
|
dest: /home/vagrant/{{ item.d }}
|
|
mode: "0644"
|
|
owner: vagrant
|
|
group: vagrant
|
|
|
|
# Initialize shell
|
|
- name: Run shell initialization
|
|
ansible.builtin.command:
|
|
cmd: zsh .zshrc
|
|
chdir: /home/vagrant
|
|
|
|
# Install various tools using asdf
|
|
- name: Install asdf plugins
|
|
loop: "{{ asdf_tools }}"
|
|
ansible.builtin.shell:
|
|
cmd: >-
|
|
source .zshrc &&
|
|
asdf plugin-add {{ item }}
|
|
chdir: /home/vagrant
|
|
executable: /bin/zsh
|
|
register: asdf_out
|
|
failed_when: >-
|
|
asdf_out.rc != 0 and
|
|
'already added' not in asdf_out.stderr
|
|
- name: Install tools using asdf
|
|
loop: "{{ asdf_tools }}"
|
|
ansible.builtin.shell:
|
|
cmd: >-
|
|
source .zshrc &&
|
|
asdf install {{ item }} {{ asdf_tool_versions[ item ] | default( "latest" ) }} &&
|
|
asdf global {{ item }} {{ asdf_tool_versions[ item ] | default( "latest" ) }}
|
|
chdir: /home/vagrant
|
|
executable: /bin/zsh
|
|
|
|
# Install Ansible 9 and various packages in a Python venv
|
|
- name: Ensure vagrant user has a .local directory
|
|
loop: [ bin, share ]
|
|
ansible.builtin.file:
|
|
path: /home/vagrant/.local/{{ item }}
|
|
state: directory
|
|
|
|
- name: Create Ansible virtual environment
|
|
ansible.builtin.shell:
|
|
executable: /bin/zsh
|
|
cmd: >-
|
|
source .zshrc && {
|
|
[ -d /home/vagrant/.local/share/ansible ] ||
|
|
python -m venv /home/vagrant/.local/share/ansible;
|
|
}
|
|
chdir: /home/vagrant
|
|
|
|
- name: Install Ansible and related Python packages
|
|
ansible.builtin.shell:
|
|
executable: /bin/zsh
|
|
cmd: >-
|
|
source /home/vagrant/.zshrc &&
|
|
source /home/vagrant/.local/share/ansible/bin/activate &&
|
|
pip install "{{ python_packages | join('" "') }}"
|
|
chdir: /home/vagrant/.local/share
|
|
|
|
- name: List Ansible executables
|
|
ansible.builtin.find:
|
|
paths: /home/vagrant/.local/share/ansible/bin
|
|
file_type: file
|
|
patterns: [ "ansible*" ]
|
|
register: ansible_exes
|
|
|
|
- name: Create Ansible symlinks
|
|
loop: "{{ ansible_exes.files }}"
|
|
ansible.builtin.file:
|
|
state: link
|
|
src: "{{ item.path }}"
|
|
dest: /home/vagrant/.local/bin/{{ item.path | basename }}
|
|
|
|
# Configure SSH for the vagrant user
|
|
- name: Configure SSH for the vagrant user
|
|
ansible.builtin.copy:
|
|
src: files/ssh_config
|
|
dest: /home/vagrant/.ssh/config
|
|
|
|
# Configure Vim
|
|
- name: Remove default vimrc
|
|
ansible.builtin.file:
|
|
path: /home/vagrant/.vimrc
|
|
state: absent
|
|
|
|
- name: Install vim configuration
|
|
ansible.builtin.git:
|
|
repo: https://git@git.nocternity.net/tseeker-pub/heavim.git
|
|
dest: /home/vagrant/.vim
|
|
|
|
- name: Create vim cache directory
|
|
ansible.builtin.file:
|
|
path: /home/vagrant/.cache/vim
|
|
state: directory
|
|
mode: "0700"
|
|
|
|
- name: Create vim plugin directories
|
|
loop: "{{ vim_plugins | map( 'dirname' ) | unique }}"
|
|
ansible.builtin.file:
|
|
path: /home/vagrant/.cache/vim/bundles/repos/github.com/{{ item }}
|
|
state: directory
|
|
|
|
- name: Clone vim plugins
|
|
loop: "{{ vim_plugins }}"
|
|
ansible.builtin.git:
|
|
repo: https://github.com/{{ item }}
|
|
dest: /home/vagrant/.cache/vim/bundles/repos/github.com/{{ item }}
|
|
|
|
# Install Rust
|
|
- name: Install Rust
|
|
ansible.builtin.shell:
|
|
cmd: >-
|
|
set -e ;
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /tmp/rustinit.sh ;
|
|
sh /tmp/rustinit.sh -y -c rust-analyzer,rust-src,rust-analysis
|