├── vagrant ├── .gitignore ├── download_iso.sh ├── README.md └── Vagrantfile ├── ansible ├── hosts ├── roles │ ├── zfs │ │ ├── files │ │ │ ├── zscrub │ │ │ └── zrepl.yml │ │ ├── handlers │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ ├── power │ │ ├── handlers │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ ├── bluetooth │ │ ├── handlers │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ ├── runit │ │ ├── handlers │ │ │ └── main.yml │ │ ├── templates │ │ │ └── run.j2 │ │ └── tasks │ │ │ └── main.yml │ ├── appimage │ │ └── tasks │ │ │ └── main.yml │ ├── desktop │ │ └── tasks │ │ │ ├── runtimedir.yml │ │ │ ├── main.yml │ │ │ ├── steam.yml │ │ │ ├── swaylock.yml │ │ │ ├── eww.yml │ │ │ ├── pipewire.yml │ │ │ └── desktop.yml │ ├── virtualization │ │ ├── handlers │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ ├── containers │ │ ├── handlers │ │ │ └── main.yml │ │ ├── files │ │ │ ├── registries.conf │ │ │ └── storage.conf │ │ └── tasks │ │ │ └── main.yml │ ├── zram │ │ └── tasks │ │ │ └── main.yml │ ├── acpi │ │ └── tasks │ │ │ └── main.yml │ ├── temp │ │ └── tasks │ │ │ └── main.yml │ ├── network-simulation │ │ └── tasks │ │ │ └── main.yml │ ├── ansible │ │ └── tasks │ │ │ └── main.yml │ ├── flatpak │ │ └── tasks │ │ │ └── main.yml │ ├── kernel │ │ └── tasks │ │ │ └── main.yml │ ├── themes-fonts │ │ └── tasks │ │ │ └── main.yml │ └── base │ │ └── tasks │ │ └── main.yml ├── ansible.cfg ├── README.md └── install.yml ├── scripts ├── virt │ ├── 02-restart.sh │ ├── README.md │ ├── 01-clean.sh │ └── 00-create.sh ├── install │ ├── TODO │ ├── README.md │ ├── 01-configure.sh │ └── 02-install.sh ├── migration │ ├── README.md │ └── 01-zfs-send.sh └── recover │ ├── 02-umount.sh │ └── 01-mount.sh ├── .pre-commit-config.yaml ├── README.md └── TODO.md /vagrant/.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | -------------------------------------------------------------------------------- /ansible/hosts: -------------------------------------------------------------------------------- 1 | localhost ansible_connection=local ansible_user=user 2 | -------------------------------------------------------------------------------- /ansible/roles/zfs/files/zscrub: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | zpool scrub zroot 4 | -------------------------------------------------------------------------------- /scripts/virt/02-restart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./01-clean.sh 4 | ./00-create.sh hrmpf 5 | -------------------------------------------------------------------------------- /scripts/install/TODO: -------------------------------------------------------------------------------- 1 | - FIX: blackscreen at first boot, need to reboot live/mount/chroot and xbps-reconfigure -fa to be able to boot 2 | -------------------------------------------------------------------------------- /ansible/roles/power/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart tlp 3 | community.general.runit: 4 | name: tlp 5 | enabled: yes 6 | state: restarted 7 | -------------------------------------------------------------------------------- /ansible/roles/zfs/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart zrepl 3 | community.general.runit: 4 | name: zrepl 5 | enabled: yes 6 | state: restarted 7 | -------------------------------------------------------------------------------- /ansible/roles/bluetooth/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart bluetoothd 3 | community.general.runit: 4 | name: bluetoothd 5 | enabled: yes 6 | state: restarted 7 | -------------------------------------------------------------------------------- /ansible/roles/runit/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: enable runit-user 3 | community.general.runit: 4 | name: runsvdir-user 5 | enabled: yes 6 | state: restarted 7 | -------------------------------------------------------------------------------- /ansible/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | inventory = ./hosts 3 | display_skipped_hosts = False 4 | host_key_checking = False 5 | library = ./plugins/modules 6 | interpreter_python = auto_silent 7 | -------------------------------------------------------------------------------- /scripts/migration/README.md: -------------------------------------------------------------------------------- 1 | # Send home from first host 2 | 3 | Boot client after using install scripts 4 | 5 | On sending client 6 | 7 | ```bash 8 | $ ./01-zfs-send.sh 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /ansible/roles/appimage/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install molotov appimage 3 | get_url: 4 | url: http://desktop-auto-upgrade.molotov.tv/linux/4.4.4/molotov.AppImage 5 | dest: /usr/local/bin/ 6 | mode: 0755 7 | -------------------------------------------------------------------------------- /ansible/roles/runit/templates/run.j2: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export USER="{{ user }}" 4 | export HOME="/home/{{ user }}" 5 | 6 | groups="$(id -Gn "$USER" | tr ' ' ':')" 7 | svdir="$HOME/service" 8 | 9 | exec chpst -u "$USER:$groups" runsvdir "$svdir" 10 | -------------------------------------------------------------------------------- /ansible/roles/desktop/tasks/runtimedir.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: configure runtime dir 3 | lineinfile: 4 | path: /etc/pam.d/system-login 5 | regexp: 'pam_dumb_runtime_dir.so' 6 | line: 'session optional pam_dumb_runtime_dir.so' 7 | state: present 8 | -------------------------------------------------------------------------------- /ansible/roles/virtualization/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart libvirt 3 | community.general.runit: 4 | name: '{{ item }}' 5 | enabled: yes 6 | state: restarted 7 | loop: 8 | - libvirtd 9 | - virtlockd 10 | - virtlogd 11 | -------------------------------------------------------------------------------- /ansible/roles/power/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: detect laptop 3 | stat: 4 | path: /sys/module/battery 5 | register: laptop 6 | 7 | - name: install tlp 8 | community.general.xbps: 9 | name: tlp 10 | notify: restart tlp 11 | when: laptop.stat.islnk is defined 12 | -------------------------------------------------------------------------------- /ansible/README.md: -------------------------------------------------------------------------------- 1 | ### Configure 2 | 3 | 1. Install ansible temp with xbps 4 | 2. Install xbps ansible module 5 | ``` 6 | ansible-galaxy collection install community.general 7 | ``` 8 | 3. Then run 9 | ``` 10 | ansible-playbook install.yml -K 11 | ``` 12 | 4. Remove Ansible xbps package 13 | -------------------------------------------------------------------------------- /ansible/roles/desktop/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: include tasks 3 | include_tasks: 4 | file: '{{ item }}.yml' 5 | apply: 6 | tags: '{{ item }}' 7 | tags: always 8 | loop: 9 | - desktop 10 | - pipewire 11 | - swaylock 12 | - steam 13 | - eww 14 | - runtimedir 15 | -------------------------------------------------------------------------------- /ansible/roles/runit/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create runit user directory 3 | file: 4 | path: /etc/sv/runsvdir-user/ 5 | state: directory 6 | 7 | - name: per user services 8 | template: 9 | src: run.j2 10 | dest: /etc/sv/runsvdir-user/run 11 | mode: 0755 12 | notify: enable runit-user 13 | -------------------------------------------------------------------------------- /ansible/roles/containers/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: enable dockerd 3 | community.general.runit: 4 | name: '{{ item }}' 5 | enabled: yes 6 | state: stopped 7 | loop: 8 | - docker 9 | 10 | - name: disable dockerd at startup 11 | file: 12 | path: /var/service/docker/down 13 | state: touch 14 | -------------------------------------------------------------------------------- /scripts/virt/README.md: -------------------------------------------------------------------------------- 1 | ### Create VM 2 | 3 | It will download iso, create UEFI VM and run it for Qemu/KVM. 4 | 5 | ``` 6 | #glibc 7 | sudo ./00-create.sh 8 | #musl 9 | sudo ./00-create.sh musl 10 | #hrmpf 11 | sudo ./00-create.sh hrmpf 12 | ``` 13 | 14 | ### Clean 15 | 16 | It removes VMs 17 | 18 | ``` 19 | sudo ./01-clean.sh 20 | ``` 21 | -------------------------------------------------------------------------------- /scripts/recover/02-umount.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | print () { 6 | echo -e "\n\033[1m> $1\033[0m\n" 7 | } 8 | 9 | print "Umount /boot/efi" 10 | umount /mnt/efi 11 | umount -l /mnt/{dev,proc,sys} 12 | zfs umount -a 13 | 14 | print "Export zpool" 15 | zpool export zroot 16 | 17 | # Finish 18 | echo -e '\e[32mAll OK\033[0m' 19 | -------------------------------------------------------------------------------- /ansible/roles/bluetooth/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install bluez 3 | community.general.xbps: 4 | name: 5 | - bluez 6 | - libspa-bluetooth 7 | notify: restart bluetoothd 8 | 9 | - name: configure bluez 10 | copy: 11 | content: | 12 | [Policy] 13 | AutoEnable=false 14 | dest: /etc/bluetooth/main.conf 15 | notify: restart bluetoothd 16 | -------------------------------------------------------------------------------- /ansible/roles/zram/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install zramen 3 | community.general.xbps: 4 | name: zramen 5 | 6 | - name: configure zramen init 7 | blockinfile: 8 | path: /etc/rc.local 9 | block: | 10 | zramen -a zstd make 11 | 12 | - name: configure zramen destroy 13 | blockinfile: 14 | path: /etc/rc.shutdown 15 | block: | 16 | zramen toss 17 | -------------------------------------------------------------------------------- /ansible/roles/acpi/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: disable suspend to ram when lid close 3 | replace: 4 | path: /etc/acpi/handler.sh 5 | after: 'logger "LID closed, suspending..."' 6 | regexp: '^(.*\t)(zzz)' 7 | replace: '\1#\2' 8 | 9 | - name: zzz for all users 10 | lineinfile: 11 | path: /etc/sudoers 12 | regexp: 'zzz' 13 | line: 'user ALL=(ALL) NOPASSWD: /bin/zzz' 14 | state: present 15 | -------------------------------------------------------------------------------- /ansible/roles/desktop/tasks/steam.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install steam packages 3 | community.general.xbps: 4 | name: '{{ item }}' 5 | loop: 6 | - steam # games manager 7 | - xrandr # some games requires it 8 | - mono 9 | - libgcc-32bit 10 | - libstdc++-32bit 11 | - libdrm-32bit 12 | - libglvnd-32bit 13 | - mesa-dri-32bit 14 | - mesa-vulkan-intel 15 | - mesa-vulkan-intel-32bit 16 | -------------------------------------------------------------------------------- /ansible/roles/temp/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: download kubectx 3 | git: 4 | repo: https://github.com/ahmetb/kubectx 5 | dest: /opt/kubectx 6 | 7 | - name: install kubectx and kubens 8 | file: 9 | src: '{{ item.src }}' 10 | dest: '{{ item.dest }}' 11 | state: link 12 | loop: 13 | - {src: /opt/kubectx/kubectx, dest: /usr/local/bin/kubectx} 14 | - {src: /opt/kubectx/kubens, dest: /usr/local/bin/kubens} 15 | -------------------------------------------------------------------------------- /ansible/roles/desktop/tasks/swaylock.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: test swaylock-fancy 3 | stat: 4 | path: /bin/swaylock-fancy 5 | register: swaylock 6 | 7 | - name: clone swaylock-fancy 8 | git: 9 | repo: https://github.com/eoli3n/swaylock-fancy 10 | dest: /tmp/swaylock-fancy 11 | when: not swaylock.stat.exists 12 | 13 | - name: install swaylock-fancy 14 | shell: make install 15 | args: 16 | chdir: /tmp/swaylock-fancy 17 | when: not swaylock.stat.exists 18 | -------------------------------------------------------------------------------- /ansible/roles/network-simulation/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://github.com/void-linux/void-packages/issues/43766 3 | # https://openclassrooms.com/fr/courses/2581701-simulez-des-architectures-reseaux-avec-gns3/4823146-installez-configurez-et-exploitez-un-logiciel-d-emulation-systemes-et-reseaux 4 | 5 | - name: install gns3 packages 6 | community.general.xbps: 7 | name: '{{item}}' 8 | loop: 9 | - gns3-gui 10 | - gns3-server 11 | - vpcs 12 | - ubridge 13 | -------------------------------------------------------------------------------- /ansible/roles/desktop/tasks/eww.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install eww packages 3 | community.general.xbps: 4 | name: '{{ item }}' 5 | loop: 6 | - rustup 7 | - gtk-layer-shell 8 | - gtk-layer-shell-devel 9 | - pango 10 | - pango-devel 11 | - gdk-pixbuf 12 | - gdk-pixbuf-devel 13 | - cairo 14 | - cairo-devel 15 | - glib 16 | - glib-devel 17 | - libgcc 18 | - libgcc-devel 19 | - glibc 20 | - glibc-devel 21 | -------------------------------------------------------------------------------- /vagrant/download_iso.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dest_file="/tmp/hrmpf.iso" 4 | 5 | if [[ "$1" == start ]] 6 | then 7 | iso=$(curl -s "https://api.github.com/repos/leahneukirchen/hrmpf/releases/latest" | jq -r '.assets[0].browser_download_url') 8 | if [[ ! -f "$dest_file" ]] 9 | then 10 | echo "-> Download latest hrmpf iso" 11 | wget "$iso" --quiet -O "$dest_file" 12 | fi 13 | elif [[ "$1" == "stop" ]] 14 | then 15 | echo "-> Delete hrmpf iso" 16 | rm "$dest_file" 17 | else 18 | echo "Please use $0 [start|stop]" 19 | fi 20 | -------------------------------------------------------------------------------- /scripts/virt/01-clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | clean (){ 4 | echo "-> Destroy $1" 5 | virsh destroy "$1" 6 | echo "-> Undefine $1" 7 | virsh undefine --nvram "$1" 8 | echo "-> Remove $1 qcow" 9 | rm "/var/lib/libvirt/images/$1.img" 10 | } 11 | 12 | if virsh list | grep void-linux-glibc &>/dev/null 13 | then 14 | clean "void-linux-glibc" 15 | elif virsh list | grep void-linux-musl &>/dev/null 16 | then 17 | clean "void-linux-musl" 18 | elif virsh list | grep void-linux-hrmpf &>/dev/null 19 | then 20 | clean "void-linux-hrmpf" 21 | fi 22 | -------------------------------------------------------------------------------- /ansible/roles/zfs/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install zrepl 3 | community.general.xbps: 4 | name: zrepl # zfs snapshot manager 5 | 6 | - name: create zrepl dir 7 | file: 8 | path: /etc/zrepl 9 | state: directory 10 | 11 | - name: configure zrepl 12 | blockinfile: 13 | block: "{{ lookup('file', 'zrepl.yml') }}" 14 | marker: "# {mark} snapshot config" 15 | dest: /etc/zrepl/zrepl.yml 16 | create: yes 17 | notify: restart zrepl 18 | 19 | - name: setup daily zfs scrub 20 | copy: 21 | src: zscrub 22 | dest: /etc/cron.weekly/ 23 | mode: 0755 24 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v4.0.1 4 | hooks: 5 | - id: check-yaml 6 | - id: trailing-whitespace 7 | args: [--markdown-linebreak-ext=md] 8 | - repo: https://github.com/shellcheck-py/shellcheck-py 9 | rev: v0.9.0.6 10 | hooks: 11 | - id: shellcheck 12 | - repo: local 13 | hooks: 14 | - id: ansible-syntax-check 15 | name: Ansible syntax check 16 | entry: "ansible-playbook --syntax-check ansible/install.yml" 17 | pass_filenames: no 18 | types_or: [yaml, jinja] 19 | language: system 20 | -------------------------------------------------------------------------------- /vagrant/README.md: -------------------------------------------------------------------------------- 1 | # Using vagrant 2 | 3 | ## Run 4 | 5 | It will automatically download latest [hrmpf](https://github.com/leahneukirchen/hrmpf) iso in /tmp and use it. 6 | 7 | ```bash 8 | # Run 9 | $ vagrant plugin install vagrant-libvirt 10 | $ vagrant up voidlinux 11 | ``` 12 | 13 | ## Remove 14 | 15 | ``destroy`` subcommand will automatically remove the iso file in /tmp 16 | 17 | nvram file is not properly removed, you need to remove it manually before destroying. 18 | https://github.com/vagrant-libvirt/vagrant-libvirt/issues/1371 19 | ```bash 20 | $ sudo rm /var/lib/libvirt/qemu/nvram/voidlinux-vagrant.fd 21 | $ vagrant destroy voidlinux 22 | ``` 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) 2 | 3 | ### ZFS root install 4 | 5 | - Native encryption aes-256-gcm 6 | - Zstd compression on all datasets 7 | - Boot Environments managed with [zfsbootmenu](https://github.com/zdykstra/zfsbootmenu) 8 | - No swap 9 | 10 | ### Install 11 | 12 | - Clone me 13 | ``` 14 | git clone https://github.com/eoli3n/void-config 15 | ``` 16 | - Run OS installer at [scripts/install/](scripts/install/) 17 | - Install packages and configurations with [ansible](ansible/) 18 | - Use [dotfiles](https://github.com/eoli3n/dotfiles) 19 | -------------------------------------------------------------------------------- /scripts/migration/01-zfs-send.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # See https://unix.stackexchange.com/a/265492 3 | 4 | if ! which syncoid 5 | then 6 | echo "Please install sanoid." 7 | exit 0 8 | fi 9 | 10 | # Stop zrepl during transfert 11 | sudo sv stop zrepl 12 | 13 | # Ask for dest IP 14 | read -rp "Host ip : " ip 15 | 16 | # Authorize ssh key 17 | sudo ssh-copy-id "root@$ip" 18 | 19 | # Send all datasets/snapshots on the destpool 20 | sudo syncoid --force-delete -r zroot/data "root@$ip":zroot/data 21 | 22 | # Restore mountpoints 23 | sudo ssh "root@$ip" zfs set mountpoint=/ zroot/data 24 | sudo ssh "root@$ip" zfs set mountpoint=/root zroot/data/home/root 25 | 26 | # Restart zrepl 27 | sudo sv start zrepl 28 | -------------------------------------------------------------------------------- /ansible/roles/zfs/files/zrepl.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: local 3 | type: snap 4 | filesystems: { 5 | "zroot/ROOT<": true 6 | } 7 | snapshotting: 8 | type: periodic 9 | prefix: zrepl_system_ 10 | interval: 10m 11 | pruning: 12 | keep: 13 | - type: grid 14 | grid: 1x1h(keep=all) | 24x1h | 7x1d 15 | regex: "^zrepl_system_" 16 | - type: regex 17 | regex: "^kernel_upgrade_.*" 18 | 19 | - name: home 20 | type: snap 21 | filesystems: { 22 | "zroot/data/home/user<": true, 23 | "zroot/data/home/user/downloads": false 24 | } 25 | snapshotting: 26 | type: periodic 27 | prefix: zrepl_home_ 28 | interval: 10m 29 | pruning: 30 | keep: 31 | - type: grid 32 | grid: 1x1h(keep=all) | 24x1h | 7x1d 33 | regex: "^zrepl_home_" 34 | -------------------------------------------------------------------------------- /ansible/roles/ansible/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create pipx install dir 3 | file: 4 | path: /opt/pipx 5 | state: directory 6 | 7 | - name: configure pipx bin dir 8 | lineinfile: 9 | path: /etc/environment 10 | create: yes 11 | regexp: '{{ item.regexp }}' 12 | line: '{{ item.line }}' 13 | loop: 14 | - regexp: '^PIPX_BIN_DIR=' 15 | line: 'PIPX_BIN_DIR=/usr/local/bin' 16 | - regexp: '^PIPX_HOME=' 17 | line: 'PIPX_HOME=/opt/pipx' 18 | 19 | - name: install ansible 20 | community.general.pipx: 21 | name: ansible 22 | install_deps: yes 23 | state: install 24 | system_site_packages: yes 25 | 26 | - name: install ansible 27 | community.general.pipx: 28 | name: ansible 29 | state: inject 30 | inject_packages: 31 | - pywinrm 32 | - requests-credssp 33 | - dnspython 34 | - pyvmomi 35 | -------------------------------------------------------------------------------- /ansible/roles/desktop/tasks/pipewire.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install pipewire packages 3 | community.general.xbps: 4 | name: '{{ item }}' 5 | loop: 6 | #- pulseaudio # audio server 7 | - pipewire # audio server 8 | - alsa-pipewire 9 | - wireplumber 10 | #- libao-pulse # fix bt for pipewire 11 | - pavucontrol # pulseaudio ui 12 | - pulseaudio-utils 13 | - pamixer # alsa ui 14 | - alsa-utils # alsa toolbox 15 | 16 | - name: configure pipewire alsa 17 | file: 18 | path: /etc/alsa/conf.d 19 | state: directory 20 | recurse: yes 21 | 22 | - name: symlink pipewire alsa 23 | file: 24 | src: '{{ item.src }}' 25 | dest: '{{ item.dest }}' 26 | state: link 27 | loop: 28 | - { src: /usr/share/alsa/alsa.conf.d/50-pipewire.conf, dest: /etc/alsa/conf.d/50-pipewire.conf } 29 | - { src: /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf, dest: /etc/alsa/conf.d/99-pipewire-default.conf } 30 | -------------------------------------------------------------------------------- /ansible/roles/virtualization/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install virt packages 3 | community.general.xbps: 4 | name: '{{item}}' 5 | loop: 6 | - qemu 7 | - libvirt 8 | - virt-manager 9 | - virt-manager-tools 10 | - dnsmasq 11 | - vagrant 12 | # For vagrant-libvirt 13 | - libvirt-devel 14 | - libguestfs 15 | - libxslt-devel 16 | - libxml2-devel 17 | - pkg-config 18 | notify: restart libvirt 19 | 20 | - name: add user to libvirt group 21 | user: 22 | name: '{{user}}' 23 | groups: libvirt 24 | append: yes 25 | 26 | - name: enable nested virtualization 27 | copy: 28 | dest: /etc/modprobe.d/kvm.conf 29 | content: | 30 | options kvm_intel nested=1 31 | 32 | - name: create isos directory 33 | file: 34 | path: /var/lib/libvirt/isos 35 | state: directory 36 | 37 | - name: configure isos in libvirt 38 | shell: virsh pool-create-as --name isos --type dir --target /var/lib/libvirt/isos || true 39 | -------------------------------------------------------------------------------- /ansible/roles/containers/files/registries.conf: -------------------------------------------------------------------------------- 1 | # This is a system-wide configuration file used to 2 | # keep track of registries for various container backends. 3 | # It adheres to TOML format and does not support recursive 4 | # lists of registries. 5 | 6 | # The default location for this configuration file is /etc/containers/registries.conf. 7 | 8 | # The only valid categories are: 'registries.search', 'registries.insecure', 9 | # and 'registries.block'. 10 | 11 | [registries.search] 12 | registries = ['docker.io', 'registry.fedoraproject.org', 'quay.io', 'registry.access.redhat.com', 'registry.centos.org'] 13 | 14 | # If you need to access insecure registries, add the registry's fully-qualified name. 15 | # An insecure registry is one that does not have a valid SSL certificate or only does HTTP. 16 | [registries.insecure] 17 | registries = [] 18 | 19 | 20 | # If you need to block pull access from a registry, uncomment the section below 21 | # and add the registries fully-qualified name. 22 | # 23 | # Docker only 24 | [registries.block] 25 | registries = [] 26 | -------------------------------------------------------------------------------- /ansible/install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | become: yes 4 | vars: 5 | user: user 6 | shell: /usr/bin/fish 7 | 8 | pre_tasks: 9 | - name: Enable multilib 10 | community.general.xbps: 11 | name: 12 | - void-repo-multilib 13 | - void-repo-multilib-nonfree 14 | 15 | roles: 16 | - { role: base, tags: base } 17 | - { role: kernel, tags: kernel } 18 | - { role: desktop, tags: desktop } 19 | - { role: flatpak, tags: flatpak } 20 | - { role: appimage, tags: appimage } 21 | - { role: temp, tags: temp } 22 | - { role: runit, tags: runit } 23 | - { role: power, tags: power } 24 | - { role: themes-fonts, tags: themes-fonts } 25 | - { role: virtualization, tags: virtualization } 26 | - { role: ansible, tags: ansible } 27 | - { role: containers, tags: containers } 28 | - { role: zfs, tags: zfs } 29 | - { role: zram, tags: zram } 30 | - { role: acpi, tags: acpi } 31 | - { role: bluetooth, tags: bluetooth } 32 | - { role: network-simulation, tags: network-simulation } 33 | -------------------------------------------------------------------------------- /scripts/recover/01-mount.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | print () { 6 | echo -e "\n\033[1m> $1\033[0m\n" 7 | } 8 | 9 | # Set DISK 10 | select ENTRY in $(ls /dev/disk/by-id/); 11 | do 12 | DISK="/dev/disk/by-id/$ENTRY" 13 | echo "Mounting $ENTRY." 14 | break 15 | done 16 | 17 | print "Load ZFS module" 18 | modprobe zfs 19 | 20 | print "Reimport zpool" 21 | if zpool status zroot &>/dev/null 22 | then 23 | zpool export zroot 24 | fi 25 | zpool import -d /dev/disk/by-id -R /mnt zroot -N -f 26 | 27 | print "Load ZFS keys" 28 | zfs load-key -L prompt zroot 29 | 30 | print "Mount ROOT dataset" 31 | select ENTRY in $(zfs list | awk '/ROOT\// {print $1}') 32 | do 33 | echo "Mount $ENTRY as slash dataset." 34 | zfs mount "$ENTRY" 35 | break 36 | done 37 | 38 | print "Mount datasets" 39 | zfs mount -a 40 | 41 | print "Mount EFI part" 42 | EFI="$DISK-part1" 43 | mount "$EFI" /mnt/efi 44 | 45 | # Init chroot 46 | mount --rbind /sys /mnt/sys 47 | mount --make-rslave /mnt/sys 48 | mount --rbind /dev /mnt/dev 49 | mount --make-rslave /mnt/dev 50 | mount --rbind /proc /mnt/proc 51 | mount --make-rslave /mnt/proc 52 | 53 | # Finish 54 | echo -e '\e[32mAll OK\033[0m' 55 | -------------------------------------------------------------------------------- /scripts/install/README.md: -------------------------------------------------------------------------------- 1 | ### How to Use 2 | 3 | Boot latest [hrmpf void linux iso](https://github.com/leahneukirchen/hrmpf/releases/latest) 4 | 5 | ```bash 6 | $ loadkeys fr 7 | $ git clone https://github.com/eoli3n/void-config 8 | $ cd void-config/scripts/install 9 | $ ./01-configure.sh 10 | $ ./02-install.sh 11 | ``` 12 | 13 | 14 | ### DualBoot Support 15 | 16 | After installing Arch Linux with [arch-config](https://github.com/eoli3n/arch-config/tree/master/scripts/zfs/install), run ``01-configure.sh`` and select ``dualboot`` in the menu. 17 | 18 | ### EFI install 19 | 20 | - sda1 21 | /efi 22 | FAT used as esp 23 | - sda2 24 | ZFS pool 25 | 26 | 27 | ##### Installation 28 | 29 | ``01-configure.sh`` will 30 | - Create partition scheme 31 | - Format everything 32 | - Mount partitions 33 | 34 | ``02-install.sh`` will 35 | - Configure mirrors 36 | - Install Void Linux and kernel 37 | - Generate initramfs 38 | - Configure hostname, locales, keymap, network 39 | - Install and configure [zfsbootmenu](https://github.com/zbm-dev/zfsbootmenu) 40 | - Generate users and passwords 41 | 42 | ### Debug 43 | 44 | ```bash 45 | $ ./01-configure.sh debug 46 | $ ./02-install.sh debug 47 | $ xbps-install -S pastebinit 48 | $ pastebinit -b sprunge.us configure.log 49 | $ pastebinit -b sprunge.us install.log 50 | ``` 51 | -------------------------------------------------------------------------------- /ansible/roles/flatpak/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install flatpak 3 | community.general.xbps: 4 | name: flatpak 5 | 6 | - name: Add the flathub flatpak repo 7 | community.general.flatpak_remote: 8 | name: "{{ item.name }}" 9 | state: present 10 | flatpakrepo_url: "{{ item.repo }}" 11 | loop: 12 | - { name: 'flathub', repo: 'https://dl.flathub.org/repo/flathub.flatpakrepo' } 13 | - { name: 'flathub-beta', repo: 'https://flathub.org/beta-repo/flathub-beta.flatpakrepo' } 14 | 15 | - name: Install flatpak packages 16 | community.general.flatpak: 17 | name: '{{ item }}' 18 | state: present 19 | remote: flathub 20 | loop: 21 | - com.spotify.Client 22 | - com.vscodium.codium 23 | - com.mojang.Minecraft 24 | - com.github.Anuken.Mindustry 25 | - us.zoom.Zoom 26 | - fi.skyjake.Lagrange # gemini browser 27 | - net.xmind.XMind # mind mapping 28 | #- com.microsoft.Teams 29 | 30 | - name: Install flatpak beta packages 31 | community.general.flatpak: 32 | name: '{{ item }}' 33 | state: present 34 | remote: flathub-beta 35 | loop: 36 | - org.freecadweb.FreeCAD 37 | 38 | #- name: Override Teams perms 39 | # shell: | 40 | # flatpak override com.microsoft.Teams \ 41 | # --filesystem=~/desktop:ro \ 42 | # --filesystem=~/img:ro \ 43 | # --filesystem=~/downloads:ro \ 44 | # --filesystem=~/share:ro 45 | -------------------------------------------------------------------------------- /vagrant/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | 3 | config.trigger.before :up, :provision do |trigger| 4 | trigger.run = {inline: "./download_iso.sh start"} 5 | end 6 | 7 | config.trigger.after :destroy do |trigger| 8 | trigger.run = {inline: "./download_iso.sh stop"} 9 | end 10 | 11 | config.vm.define :voidlinux do |voidlinux| 12 | voidlinux.vm.hostname = "voidlinux" 13 | voidlinux.vm.provider :libvirt do |libvirt| 14 | libvirt.cpu_mode = 'host-passthrough' 15 | libvirt.memory = '2048' 16 | libvirt.cpus = '4' 17 | libvirt.graphics_type = 'spice' 18 | # Create a disk 19 | libvirt.storage :file, 20 | size: '50G', 21 | type: 'qcow2', 22 | bus: 'sata' 23 | # Set fr keyboard for vnc connection 24 | libvirt.keymap = 'fr' 25 | libvirt.boot 'cdrom' 26 | libvirt.storage :file, :device => :cdrom, :path => '/tmp/hrmpf.iso', :bus => 'sata' 27 | # Set UEFI boot, comment for legacy 28 | ### On Arch Linux with OVMF package, use 29 | #libvirt.loader = '/usr/share/edk2-ovmf/x64/OVMF.fd' 30 | #libvirt.nvram = '/usr/share/edk2-ovmf/x64/OVMF_VARS_voidlinux.fd' 31 | ### On Void Linux, use qemu edk2 firmwares 32 | # For secure boot, use "secure" firmware and force Q35 chipset 33 | #libvirt.machine_type = 'q35' 34 | #libvirt.loader = '/usr/share/qemu/edk2-x86_64-secure-code.fd' 35 | libvirt.loader = '/usr/share/qemu/edk2-x86_64-code.fd' 36 | libvirt.nvram = '/var/lib/libvirt/qemu/nvram/voidlinux-vagrant.fd' 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /ansible/roles/kernel/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: copy pre-install zfs snapshot kernel hook 3 | copy: 4 | dest: /etc/kernel.d/pre-install/10-zfs 5 | mode: 0755 6 | content: | 7 | # Find the name of the current boot environment 8 | BOOTENV="$(awk '$2 == "/" && $3 == "zfs" {print $1}' /proc/mounts)" 9 | [ -n "${BOOTENV}" ] || exit 10 | 11 | # Create a snapshot of the current state, differntiated by time 12 | zfs snapshot "${BOOTENV}@kernel_upgrade_$(date +%Y-%m-%d_%H:%M:%S)" || exit 13 | 14 | # Prune all except 2 last kernel_upgrade snapshots 15 | zfs list -t snapshot -s creation -o name -H "${BOOTENV}" | \ 16 | grep @kernel_upgrade_ | head -n -2 | \ 17 | while read -r snapname; do 18 | zfs destroy "${snapname}" 19 | done 20 | 21 | - name: copy pre-install vkpurge kernel hook 22 | copy: 23 | dest: /etc/kernel.d/pre-install/20-vkpurge 24 | mode: 0755 25 | content: | 26 | #!/bin/sh 27 | vkpurge rm all 28 | 29 | - name: copy pre-install clean_xbps_flatpak kernel hook 30 | copy: 31 | dest: /etc/kernel.d/pre-install/30-clean_xbps_flatpak 32 | mode: 0755 33 | content: | 34 | #!/bin/sh 35 | flatpak uninstall --unused -y 36 | 37 | - name: automatically boot latest lts version 38 | copy: 39 | dest: /etc/kernel.d/pre-install/40-boot_latest_lts 40 | mode: 0755 41 | content: | 42 | #!/bin/sh 43 | kernel_version=$(basename $(xbps-query -f linux$(xbps-query -x linux-lts | grep -Po 'linux\K[0-9.]+') | grep vmlinuz)) 44 | zfs set org.zfsbootmenu:kernel=${kernel_version} zroot/ROOT/voidlinux 45 | -------------------------------------------------------------------------------- /ansible/roles/containers/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install containers packages 3 | community.general.xbps: 4 | name: '{{item}}' 5 | loop: 6 | - docker # high level container runtime 7 | - docker-compose # multi-container docker apps 8 | - podman # docker alternative without dockerd 9 | - kubectl # kubernetes api cli client 10 | - minikube # virtualized local kubernetes cluster 11 | - k9s # UI to interact with Kubernetes clusters 12 | - kubernetes-helm # kubernetes package manager 13 | # - packer # golden images creator 14 | - terraform # infrastructure as code 15 | - k3s # Lightweight Kubernetes in a signle binary 16 | - stern # tail multiple pods on Kubernetes 17 | - podman-compose # mutli-container podman apps 18 | #- kubectx # switch clusters/namespaces 19 | #- kustomize # yaml templator 20 | #- kompose-bin # docker-compose to manifest convertor 21 | #- kubespy # observe Kubernetes resources in real time 22 | # https://github.com/kubernetes-sigs/krew 23 | 24 | - name: copy subuid files for podman rootless 25 | copy: 26 | dest: /etc/subuid 27 | content: "{{ user }}:100000:65536" 28 | 29 | - name: copy subgid files for podman rootless 30 | copy: 31 | dest: /etc/subgid 32 | content: "{{ user }}:100000:65536" 33 | 34 | - name: configure podman registries 35 | copy: 36 | src: registries.conf 37 | dest: /etc/containers/ 38 | 39 | - name: configure podman storage 40 | copy: 41 | src: storage.conf 42 | dest: /etc/containers/ 43 | 44 | - name: Add user to docker group 45 | user: 46 | name: '{{ user }}' 47 | groups: docker 48 | append: yes 49 | notify: 50 | - enable dockerd 51 | - disable dockerd at startup 52 | -------------------------------------------------------------------------------- /ansible/roles/themes-fonts/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install packages 3 | community.general.xbps: 4 | name: '{{item}}' 5 | loop: 6 | # Fonts 7 | - noto-fonts-ttf # unicode font 8 | - nerd-fonts # Iconic font aggregator 9 | - noto-fonts-emoji # emojis 10 | - font-awesome5 # Icon font 11 | - Adapta # theme for tiny waybar 12 | 13 | ### Equilux 14 | 15 | - name: stat equilux theme 16 | stat: 17 | path: /usr/share/themes/Equilux 18 | register: equilux 19 | 20 | - name: download equilux theme 21 | unarchive: 22 | src: https://github.com/ddnexus/equilux-theme/archive/equilux-v20181029.tar.gz 23 | dest: /tmp/ 24 | remote_src: yes 25 | when: equilux.stat.islnk is not defined 26 | 27 | - name: install equilux theme 28 | shell: bash /tmp/equilux-theme-equilux-v20181029/install.sh -d /usr/share/themes 29 | when: equilux.stat.islnk is not defined 30 | 31 | ### Jetbrains 32 | 33 | - name: stat jetbrains font 34 | stat: 35 | path: /usr/share/fonts/TTF/JetBrainsMono-Regular.ttf 36 | register: jetbrains 37 | 38 | - name: create font dir 39 | file: 40 | path: /tmp/jetbrains 41 | state: directory 42 | when: jetbrains.stat.islnk is not defined 43 | 44 | - name: download jetbrains font 45 | unarchive: 46 | src: https://download.jetbrains.com/fonts/JetBrainsMono-2.001.zip 47 | dest: /tmp/jetbrains/ 48 | remote_src: yes 49 | creates: /tmp/jetbrains/ttf 50 | when: jetbrains.stat.islnk is not defined 51 | 52 | - name: install jetbrains font 53 | copy: 54 | src: '{{ item }}' 55 | dest: /usr/share/fonts/TTF/ 56 | remote_src: yes 57 | with_fileglob: /tmp/jetbrains/ttf/* 58 | when: jetbrains.stat.islnk is not defined 59 | 60 | ### Cabin 61 | 62 | - name: stat cabin font 63 | stat: 64 | path: /usr/share/fonts/OTF/Cabin-Regular.otf 65 | register: cabin 66 | 67 | - name: create font dir 68 | file: 69 | path: /tmp/cabin 70 | state: directory 71 | when: cabin.stat.islnk is not defined 72 | 73 | - name: download imparallari-cabin font 74 | unarchive: 75 | src: https://codeload.github.com/impallari/Cabin/zip/master 76 | dest: /tmp/cabin/ 77 | remote_src: yes 78 | creates: /tmp/cabin/Cabin-master 79 | when: cabin.stat.islnk is not defined 80 | 81 | - name: install imparallari-cabin font 82 | copy: 83 | src: '{{ item }}' 84 | dest: /usr/share/fonts/OTF/ 85 | remote_src: yes 86 | with_fileglob: /tmp/cabin/Cabin-master/fonts/OTF/* 87 | when: cabin.stat.islnk is not defined 88 | -------------------------------------------------------------------------------- /scripts/virt/00-create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # List os-variant: osinfo-query os 6 | iso_path="/var/lib/libvirt/isos" 7 | 8 | # With musl base iso 9 | if [[ "$1" == "musl" ]] 10 | then 11 | 12 | # Get latest musl iso name 13 | base_musl_iso=$(curl -s https://alpha.de.repo.voidlinux.org/live/current/ | grep -m 1 -Eo 'void-live-x86_64-musl-[0-9]{8}.iso' | head -n1) 14 | # Download musl iso 15 | base_musl_iso_path="${iso_path}/${base_musl_iso}" 16 | if ! test -f "${base_musl_iso_path}" 17 | then 18 | echo "-> Download latest musl iso" 19 | wget "https://alpha.de.repo.voidlinux.org/live/current/${base_musl_iso}" -O "${base_musl_iso_path}" 20 | fi 21 | 22 | # Set VM vars 23 | name="void-linux-musl" 24 | description="Test Void Linux with musl" 25 | iso="${base_musl_iso_path}" 26 | 27 | # With hrmpf iso 28 | elif [[ "$1" == "hrmpf" ]] 29 | then 30 | 31 | # Get latest musl iso name 32 | hrmpf_iso=$(curl -s "https://api.github.com/repos/leahneukirchen/hrmpf/releases/latest" | jq -r '.assets[0].browser_download_url') 33 | hrmpf_iso_name=$(curl -s "https://api.github.com/repos/leahneukirchen/hrmpf/releases/latest" | jq -r '.assets[0].name') 34 | # Download musl iso 35 | hrmpf_iso_path="${iso_path}/${hrmpf_iso_name}" 36 | if ! test -f "${hrmpf_iso_path}" 37 | then 38 | echo "-> Download latest hrmpf iso" 39 | wget "${hrmpf_iso}" -O "${hrmpf_iso_path}" 40 | fi 41 | 42 | # Set VM vars 43 | name="void-linux-hrmpf" 44 | description="Test Void Linux with glibc" 45 | iso="${hrmpf_iso_path}" 46 | 47 | # With glibc base iso 48 | elif [[ "$1" == "glibc" ]] 49 | then 50 | 51 | # Get latest glibc iso name 52 | base_iso=$(curl -s https://alpha.de.repo.voidlinux.org/live/current/ | grep -m 1 -Eo 'void-live-x86_64-[0-9]{8}.iso' | head -n1) 53 | # Download glibc iso 54 | base_iso_path="${iso_path}/${base_iso}" 55 | if ! test -f "${base_iso_path}" 56 | then 57 | echo "-> Download latest glibc iso" 58 | wget "https://alpha.de.repo.voidlinux.org/live/current/${base_iso}" -O "${base_iso_path}" 59 | fi 60 | 61 | # Set VM vars 62 | name="void-linux-glibc" 63 | description="Test Void Linux with glibc" 64 | iso="${base_iso_path}" 65 | 66 | else 67 | 68 | echo "usage: 00-create.sh {hrmpf|glibc|musl}" 69 | exit 0 70 | 71 | fi 72 | 73 | # Create VM 74 | echo "-> Create VM ${name}" 75 | virt-install \ 76 | -n "${name}" \ 77 | --description "${description}" \ 78 | --os-type=Linux \ 79 | --os-variant=voidlinux \ 80 | --ram=2048 \ 81 | --vcpus=2 \ 82 | --cpu host \ 83 | --boot uefi \ 84 | --disk path=/var/lib/libvirt/images/${name}.img,bus=sata,size=30 \ 85 | --graphics spice \ 86 | --video qxl \ 87 | --channel spicevmc \ 88 | --check all=off \ 89 | --noautoconsole \ 90 | --cdrom "${iso}" 91 | # --network bridge:br0 92 | -------------------------------------------------------------------------------- /ansible/roles/desktop/tasks/desktop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install desktop packages 3 | community.general.xbps: 4 | name: '{{ item }}' 5 | loop: 6 | # DE 7 | - sway # wayland wm and compositor 8 | - swaybg # background manager for sway 9 | - swaylock # session locker 10 | - xorg-server-xwayland # xorg backend for wayland 11 | - Waybar # bar for sway 12 | - mako # notification daemon 13 | - kanshi # autorandr for wayland 14 | - grim # screenshots 15 | - slurp # region selector 16 | - wl-clipboard # clipboard manager 17 | - wdisplays # arandr for wayland 18 | - wf-recorder # screen recorder for wayland 19 | - grimshot # grim+slurp wrapper 20 | - waypipe # ssh -X for wayland 21 | - wofi # rofi for wayland 22 | - wob # bars for wayland 23 | - xdg-desktop-portal-wlr # screen sharing for wayland 24 | - xdg-desktop-portal-gtk # fallback portal 25 | - brightnessctl # brightness manager 26 | - qt5-wayland # enable qt5 wayland backend 27 | - libappindicator # tray sway 28 | - swayidle 29 | - xdg-user-dirs 30 | - xdg-utils 31 | - glfw-wayland 32 | - dumb_runtime_dir # XDG_RUNTIME_DIR when seatd 33 | - wlsunset # day/night gamma adjustments 34 | - iwgtk # gui for iwd 35 | # Video 36 | - mesa # DRI 3D acceleration 37 | - mesa-dri # DRI 3D acceleration 38 | - mesa-demos # glxgears command 39 | - intel-media-driver # intel driver iHD 40 | - libva-utils # hardware video acceleration 41 | # Graphical apps 42 | - imv # img visualizer 43 | - wezterm # terminal emulator 44 | - firefox-i18n-fr # web browser 45 | - chromium # web browser 46 | - gimp # img editor 47 | - thunderbird # mail/contact/agenda client 48 | - seahorse # gnome keyring manager 49 | - kolourpaint # img editor 50 | - shotwell # photo manager 51 | - swappy # screenshot editor 52 | - libreoffice # libreoffice 53 | - libreoffice-i18n-fr # libreoffice suite fr 54 | - lxappearance # theme manager 55 | - gnome-themes-extra # adwaita-dark theme 56 | - mpv # video player 57 | - nemo # file manager 58 | - tumbler # thumbnailer 59 | - openvpn # vpn client 60 | - openconnect # globalprotect vpn client 61 | - playerctl # music player cli controller 62 | - rdesktop # remote desktop client 63 | - remmina # remote desktop client 64 | - transmission-gtk # torrent downloader 65 | - typst # replace texlive 66 | - variety # random backgrounds 67 | - papirus-icon-theme # icon theme 68 | - youtube-dl 69 | - gnome-ssh-askpass # ssh askpass gui 70 | - android-tools # android dir sync 71 | - android-udev-rules # flash android 72 | - scrcpy # remote desktop for android 73 | - Signal-Desktop # messaging app 74 | - x2goclient # linux remote desktop client 75 | - torbrowser-launcher 76 | - gnuplot # plot tool 77 | - xournalpp # pdf editor, no form 78 | - okular # pdf editor, no img 79 | # Jekyll 80 | - libmagick-devel # jekyll dep 81 | - libxcrypt-compat # jekyll dep 82 | - rbenv # ruby version manager 83 | - openssl-devel 84 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ### TODO 2 | - [x] virt-install scripts 3 | - [x] git pre-commit hooks shellcheck 4 | - [x] install scripts 5 | - [x] periodic zfs scrub 6 | - [x] port arch-config playbook 7 | - [ ] README init install git + ansible 8 | - [ ] travis/github actions on playbook run 9 | - [x] backups to cronie for arch/void 10 | - [x] move from pulseaudio to pipewire: https://github.com/void-linux/void-docs/pull/540/commits/33343cbfba36ccd3597d36ee4e983650969b0c7a 11 | - [x] pam_rundir for sway with seatd 12 | - [x] acpid in install script 13 | - [ ] netboot.xyz 14 | - [ ] neomutt, mutt-wizard 15 | - [ ] packages 16 | - [ ] config 17 | - [x] vdirsyncer, khal, khard 18 | - [x] packages 19 | - [x] config 20 | - [x] pass, gopass 21 | - [ ] DoT with stubby and applied-privacy.net 22 | - [ ] upgrade kernel without reboot with kexec 23 | 24 | 25 | ### TOPACKAGE 26 | - [ ] swaylock-fancy: https://github.com/void-linux/void-packages/issues/27224 27 | - [ ] kubectx: https://github.com/void-linux/void-packages/pull/17088 28 | - [ ] kompose: https://github.com/void-linux/void-packages/issues/27231 29 | - [ ] veyon 30 | - [x] gopass-jsonapi: https://github.com/void-linux/void-packages/issues/31155 31 | - [ ] ydotool: https://github.com/void-linux/void-packages/issues/31163 32 | 33 | ### TOMERGE 34 | - [x] x2goclient: 35 | - https://github.com/void-linux/void-packages/issues/2091 36 | - https://github.com/void-linux/void-packages/issues/9779 37 | - [ ] x2goserver 38 | - [x] tiny: https://github.com/void-linux/void-packages/issues/27180 39 | - [x] pre-commit: https://github.com/void-linux/void-packages/issues/27225 40 | - [ ] ovmf: https://github.com/void-linux/void-packages/pull/29074 41 | - [x] local build 42 | 43 | ### TOTEST 44 | - [x] auto zfs sanoid snapshots with cronie 45 | - [x] ntp 46 | - [x] check daemons log with socklog 47 | ``` 48 | less /var/log/socklog/everything/current 49 | ``` 50 | - [x] vpn and openresolv update dns script 51 | - [x] backups 52 | - [x] hibernation with zzz 53 | - [x] pipewire 54 | - [x] qemu/kvm 55 | - [x] podman 56 | - [x] flatpaks 57 | - [x] firmware updater 58 | - [ ] lid switch 59 | 60 | ### TOFIX 61 | - [x] flatpak not showing in wofi 62 | - [x] flatpak app no access to home 63 | - [x] $ fwupdmgr get-devices: https://github.com/fwupd/fwupd/issues/3255 64 | - [ ] vpn: ssh delay 65 | - [ ] pipewire warnings : "RTKit error: org.freedesktop.DBus.Error.AccessDenied" 66 | - [ ] rtkit service error : "pthread_create failed: Resource temporarily unavailable" 67 | - [ ] pipewire killed after hibernation ? 68 | - [ ] libgl1 32bit missing for steam 69 | - [ ] freebox vpn: connection ok, but no network 70 | - [ ] dht/pex ? 71 | 72 | ### ISSUES 73 | - [ ] xbps role with hooks: https://github.com/void-linux/xbps/issues/304 74 | - [ ] pre upgrade snapshot hook 75 | - [x] periodic zfs snapshots with sanoid 76 | - [ ] post upgrade flatpak upgrade hook 77 | - [x] keyboard not released with swaymsg exit: https://github.com/void-linux/void-packages/issues/27132 78 | - [ ] wrong missing package reported by xbps module: https://github.com/ansible-collections/community.general/issues/2478 79 | - [x] workaround by using loop 80 | 81 | ### RESOURCES 82 | 83 | - https://docs.voidlinux.org/installation/guides/chroot.html 84 | - https://wiki.voidlinux.org/Manual_install_with_ZFS_root 85 | - https://github.com/nightah/void-install 86 | - neffi@freenode#voidlinux zfsbootmenu config: http://ix.io/2I4m 87 | 88 | ``` 89 | podman run --rm -it voidlinux/voidlinux /bin/sh 90 | podman run --rm -it voidlinux/voidlinux-musl /bin/sh 91 | ``` 92 | -------------------------------------------------------------------------------- /ansible/roles/base/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install packages 3 | community.general.xbps: 4 | name: '{{item}}' 5 | loop: 6 | # Shell 7 | - starship # shell prompt 8 | - fish-shell # powerful shell 9 | - go # programming language 10 | - exa # powerful ls 11 | - lsd # another powerful ls 12 | - bc # maths 13 | - jq # json processor 14 | - most # colorized pager 15 | - bat # colorized cat 16 | - neovim # futur of vim 17 | - tree 18 | - tmux # terminal multiplexer 19 | - screen # terminal multiplexer 20 | - asciinema # term recorder 21 | - expect # automation tool 22 | - glow # render markdown cli 23 | - tiny # irc client 24 | - senpai # irc client with ircv3/chathistory for soju bouncer 25 | - termdown # cli countdown timer 26 | - nnn # terminal file manager 27 | # System 28 | - xtools # helpers for working with XBPS 29 | - xmirror # easily select xbps mirror 30 | - htop # system monitor 31 | - net-tools # netstat 32 | - mtr # ping/traceroute diag tool 33 | - fwupd # dell firmware updater 34 | - nmap # port scanner 35 | - tcpdump # packet analyzer 36 | - whois # query registry 37 | - stress # stress test tool 38 | - efivar # tool to manipulate efi vars 39 | - vsv # list runit services 40 | # Disk 41 | - iotop # disk "top" 42 | - ncdu # disk usage analyzer 43 | - smartmontools # S.M.A.R.T Monitoring Tools 44 | - gparted # partitionning tool 45 | - mtools # gparted dep 46 | # Network 47 | - nethogs # net "top" 48 | - openssh 49 | - sshpass # allow ansible -k 50 | - sshuttle # vpn through ssh 51 | - fuse-sshfs # mount a remote filesystem using SFTP 52 | - keychain # ssh-agent wrapper 53 | - wget # downloader 54 | - bind-utils # dns tools 55 | - openbsd-netcat # network utility 56 | - speedtest-cli 57 | # Utils 58 | - at # scheduler 59 | - borg # backup utility 60 | - borgmatic # backup utility automation 61 | - pwgen # random password generator 62 | - gopass # unix password manager 63 | - gopass-jsonapi 64 | - pinentry-gnome # gtk gpg pinentry 65 | - rsync # sync tool 66 | - syncthing # sync tool 67 | - rclone # sync tool 68 | - vdirsyncer # sync tool 69 | - khard # cli contacts manager 70 | - khal # cli calendar manager 71 | - fzf # fuzzy finder 72 | - neofetch 73 | - unzip # uncompress zip 74 | - cifs-utils 75 | - shellcheck # sh linter 76 | - pastel # color viewer 77 | - python-pip # python2 package manager 78 | - python3-pip # python3 package manager 79 | - python3-netaddr # ipmath for ansible 80 | - python3-devel 81 | - dmidecode # dump dmi table content 82 | - oath-toolkit # otp tool 83 | - pastebinit # pastebin wrapper 84 | - zim # wiki app 85 | - ipcalc # ipv4 network calculator 86 | - pre-commit # git pre-commit hooks manager 87 | - pv # progress bar 88 | - lzop # compression tool 89 | - mailx # bsd mail client 90 | #- arch-audit # list vulnerabilities 91 | #- reflector # mirror sorter 92 | 93 | - name: Configure root 94 | user: 95 | name: root 96 | shell: '{{shell}}' 97 | 98 | - name: Configure user 99 | user: 100 | name: '{{user}}' 101 | shell: '{{shell}}' 102 | 103 | - name: add hostname to /etc/hosts 104 | lineinfile: 105 | path: /etc/hosts 106 | regexp: '{{ ansible_hostname }}' 107 | line: '127.0.0.1 {{ ansible_hostname }}' 108 | state: present 109 | -------------------------------------------------------------------------------- /ansible/roles/containers/files/storage.conf: -------------------------------------------------------------------------------- 1 | # This file is is the configuration file for all tools 2 | # that use the containers/storage library. 3 | # See man 5 containers-storage.conf for more information 4 | # The "container storage" table contains all of the server options. 5 | [storage] 6 | 7 | # Default Storage Driver 8 | driver = "zfs" 9 | 10 | # Temporary storage location 11 | runroot = "/var/run/containers/storage" 12 | 13 | # Primary Read/Write location of container storage 14 | graphroot = "/var/lib/containers/storage" 15 | 16 | [storage.options] 17 | # Storage options to be passed to underlying storage drivers 18 | 19 | # AdditionalImageStores is used to pass paths to additional Read/Only image stores 20 | # Must be comma separated list. 21 | additionalimagestores = [ 22 | ] 23 | 24 | # Size is used to set a maximum size of the container image. Only supported by 25 | # certain container storage drivers. 26 | size = "" 27 | 28 | # Path to an helper program to use for mounting the file system instead of mounting it 29 | # directly. 30 | mount_program = "/usr/bin/fuse-overlayfs" 31 | 32 | # OverrideKernelCheck tells the driver to ignore kernel checks based on kernel version 33 | override_kernel_check = "true" 34 | 35 | # mountopt specifies comma separated list of extra mount options 36 | mountopt = "nodev" 37 | 38 | # Remap-UIDs/GIDs is the mapping from UIDs/GIDs as they should appear inside of 39 | # a container, to UIDs/GIDs as they should appear outside of the container, and 40 | # the length of the range of UIDs/GIDs. Additional mapped sets can be listed 41 | # and will be heeded by libraries, but there are limits to the number of 42 | # mappings which the kernel will allow when you later attempt to run a 43 | # container. 44 | # 45 | # remap-uids = 0:1668442479:65536 46 | # remap-gids = 0:1668442479:65536 47 | 48 | # Remap-User/Group is a name which can be used to look up one or more UID/GID 49 | # ranges in the /etc/subuid or /etc/subgid file. Mappings are set up starting 50 | # with an in-container ID of 0 and the a host-level ID taken from the lowest 51 | # range that matches the specified name, and using the length of that range. 52 | # Additional ranges are then assigned, using the ranges which specify the 53 | # lowest host-level IDs first, to the lowest not-yet-mapped container-level ID, 54 | # until all of the entries have been used for maps. 55 | # 56 | # remap-user = "storage" 57 | # remap-group = "storage" 58 | 59 | [storage.options.thinpool] 60 | # Storage Options for thinpool 61 | 62 | # autoextend_percent determines the amount by which pool needs to be 63 | # grown. This is specified in terms of % of pool size. So a value of 20 means 64 | # that when threshold is hit, pool will be grown by 20% of existing 65 | # pool size. 66 | # autoextend_percent = "20" 67 | 68 | # autoextend_threshold determines the pool extension threshold in terms 69 | # of percentage of pool size. For example, if threshold is 60, that means when 70 | # pool is 60% full, threshold has been hit. 71 | # autoextend_threshold = "80" 72 | 73 | # basesize specifies the size to use when creating the base device, which 74 | # limits the size of images and containers. 75 | # basesize = "10G" 76 | 77 | # blocksize specifies a custom blocksize to use for the thin pool. 78 | # blocksize="64k" 79 | 80 | # directlvm_device specifies a custom block storage device to use for the 81 | # thin pool. Required if you setup devicemapper. 82 | # directlvm_device = "" 83 | 84 | # directlvm_device_force wipes device even if device already has a filesystem. 85 | # directlvm_device_force = "True" 86 | 87 | # fs specifies the filesystem type to use for the base device. 88 | # fs="xfs" 89 | 90 | # log_level sets the log level of devicemapper. 91 | # 0: LogLevelSuppress 0 (Default) 92 | # 2: LogLevelFatal 93 | # 3: LogLevelErr 94 | # 4: LogLevelWarn 95 | # 5: LogLevelNotice 96 | # 6: LogLevelInfo 97 | # 7: LogLevelDebug 98 | # log_level = "7" 99 | 100 | # min_free_space specifies the min free space percent in a thin pool require for 101 | # new device creation to succeed. Valid values are from 0% - 99%. 102 | # Value 0% disables 103 | # min_free_space = "10%" 104 | 105 | # mkfsarg specifies extra mkfs arguments to be used when creating the base. 106 | # device. 107 | # mkfsarg = "" 108 | 109 | # use_deferred_removal marks devicemapper block device for deferred removal. 110 | # If the thinpool is in use when the driver attempts to remove it, the driver 111 | # tells the kernel to remove it as soon as possible. Note this does not free 112 | # up the disk space, use deferred deletion to fully remove the thinpool. 113 | # use_deferred_removal = "True" 114 | 115 | # use_deferred_deletion marks thinpool device for deferred deletion. 116 | # If the device is busy when the driver attempts to delete it, the driver 117 | # will attempt to delete device every 30 seconds until successful. 118 | # If the program using the driver exits, the driver will continue attempting 119 | # to cleanup the next time the driver is used. Deferred deletion permanently 120 | # deletes the device and all data stored in device will be lost. 121 | # use_deferred_deletion = "True" 122 | 123 | # xfs_nospace_max_retries specifies the maximum number of retries XFS should 124 | # attempt to complete IO when ENOSPC (no space) error is returned by 125 | # underlying storage device. 126 | # xfs_nospace_max_retries = "0" 127 | 128 | # If specified, use OSTree to deduplicate files with the overlay backend 129 | ostree_repo = "" 130 | 131 | # Set to skip a PRIVATE bind mount on the storage home directory. Only supported by 132 | # certain container storage drivers 133 | skip_mount_home = "false" 134 | -------------------------------------------------------------------------------- /scripts/install/01-configure.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | exec &> >(tee "configure.log") 6 | 7 | print () { 8 | echo -e "\n\033[1m> $1\033[0m\n" 9 | } 10 | 11 | ask () { 12 | read -p "> $1 " -r 13 | echo 14 | } 15 | 16 | menu () { 17 | PS3="> Choose a number: " 18 | select i in "$@" 19 | do 20 | echo "$i" 21 | break 22 | done 23 | } 24 | 25 | # Tests 26 | tests () { 27 | ls /sys/firmware/efi/efivars > /dev/null && \ 28 | ping voidlinux.org -c 1 > /dev/null && \ 29 | modprobe zfs && \ 30 | print "Tests ok" 31 | } 32 | 33 | select_disk () { 34 | # Set DISK 35 | select ENTRY in $(ls /dev/disk/by-id/); 36 | do 37 | DISK="/dev/disk/by-id/$ENTRY" 38 | echo "$DISK" > /tmp/disk 39 | echo "Installing on $ENTRY." 40 | break 41 | done 42 | } 43 | 44 | wipe () { 45 | ask "Do you want to wipe all datas on $ENTRY ?" 46 | if [[ $REPLY =~ ^[Yy]$ ]] 47 | then 48 | # Clear disk 49 | dd if=/dev/zero of="$DISK" bs=512 count=1 50 | wipefs -af "$DISK" 51 | sgdisk -Zo "$DISK" 52 | fi 53 | } 54 | 55 | partition () { 56 | # EFI part 57 | print "Creating EFI part" 58 | sgdisk -n1:1M:+512M -t1:EF00 "$DISK" 59 | EFI="$DISK-part1" 60 | 61 | # ZFS part 62 | print "Creating ZFS part" 63 | sgdisk -n3:0:0 -t3:bf01 "$DISK" 64 | 65 | # Inform kernel 66 | partprobe "$DISK" 67 | 68 | # Format efi part 69 | sleep 1 70 | print "Format EFI part" 71 | mkfs.vfat "$EFI" 72 | } 73 | 74 | zfs_passphrase () { 75 | # Generate key 76 | print "Set ZFS passphrase" 77 | read -r -p "> ZFS passphrase: " -s pass 78 | echo 79 | echo "$pass" > /etc/zfs/zroot.key 80 | chmod 000 /etc/zfs/zroot.key 81 | } 82 | 83 | create_pool () { 84 | # ZFS part 85 | ZFS="$DISK-part3" 86 | 87 | # Create ZFS pool 88 | print "Create ZFS pool" 89 | zpool create -f -o ashift=12 \ 90 | -o autotrim=on \ 91 | -O acltype=posixacl \ 92 | -O compression=zstd \ 93 | -O relatime=on \ 94 | -O xattr=sa \ 95 | -O dnodesize=legacy \ 96 | -O encryption=aes-256-gcm \ 97 | -O keyformat=passphrase \ 98 | -O keylocation=file:///etc/zfs/zroot.key \ 99 | -O normalization=formD \ 100 | -O mountpoint=none \ 101 | -O canmount=off \ 102 | -O devices=off \ 103 | -R /mnt \ 104 | zroot "$ZFS" 105 | } 106 | 107 | create_root_dataset () { 108 | # Slash dataset 109 | print "Create root dataset" 110 | zfs create -o mountpoint=none zroot/ROOT 111 | 112 | # Set cmdline 113 | zfs set org.zfsbootmenu:commandline="ro quiet" zroot/ROOT 114 | } 115 | 116 | create_system_dataset () { 117 | print "Create slash dataset" 118 | zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/"$1" 119 | 120 | # Generate zfs hostid 121 | print "Generate hostid" 122 | zgenhostid 123 | 124 | # Set bootfs 125 | print "Set ZFS bootfs" 126 | zpool set bootfs="zroot/ROOT/$1" zroot 127 | 128 | # Manually mount slash dataset 129 | zfs mount zroot/ROOT/"$1" 130 | } 131 | 132 | create_home_dataset () { 133 | print "Create home dataset" 134 | zfs create -o mountpoint=/ -o canmount=off zroot/data 135 | zfs create zroot/data/home 136 | zfs create -o mountpoint=/root zroot/data/home/root 137 | } 138 | 139 | export_pool () { 140 | print "Export zpool" 141 | zpool export zroot 142 | } 143 | 144 | import_pool () { 145 | print "Import zpool" 146 | zpool import -d /dev/disk/by-id -R /mnt zroot -N -f 147 | zfs load-key zroot 148 | } 149 | 150 | mount_system () { 151 | print "Mount slash dataset" 152 | zfs mount zroot/ROOT/"$1" 153 | zfs mount -a 154 | 155 | # Mount EFI part 156 | print "Mount EFI part" 157 | EFI="$DISK-part1" 158 | mkdir -p /mnt/efi 159 | mount "$EFI" /mnt/efi 160 | } 161 | 162 | copy_zpool_cache () { 163 | # Copy ZFS cache 164 | print "Generate and copy zfs cache" 165 | mkdir -p /mnt/etc/zfs 166 | zpool set cachefile=/etc/zfs/zpool.cache zroot 167 | } 168 | 169 | # Main 170 | 171 | tests 172 | 173 | print "Is this the first install or a second install to dualboot ?" 174 | install_reply=$(menu first dualboot) 175 | 176 | select_disk 177 | zfs_passphrase 178 | 179 | # If first install 180 | if [[ $install_reply == "first" ]] 181 | then 182 | # Wipe the disk 183 | wipe 184 | # Create partition table 185 | partition 186 | # Create ZFS pool 187 | create_pool 188 | # Create root dataset 189 | create_root_dataset 190 | fi 191 | 192 | ask "Name of the slash dataset ?" 193 | name_reply="$REPLY" 194 | echo "$name_reply" > /tmp/root_dataset 195 | 196 | if [[ $install_reply == "dualboot" ]] 197 | then 198 | import_pool 199 | fi 200 | 201 | create_system_dataset "$name_reply" 202 | 203 | if [[ $install_reply == "first" ]] 204 | then 205 | create_home_dataset 206 | fi 207 | 208 | export_pool 209 | import_pool 210 | mount_system "$name_reply" 211 | copy_zpool_cache 212 | 213 | # Finish 214 | echo -e "\e[32mAll OK" 215 | -------------------------------------------------------------------------------- /scripts/install/02-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | exec &> >(tee "install.log") 5 | 6 | # Debug 7 | if [[ "$1" == "debug" ]] 8 | then 9 | set -x 10 | debug=1 11 | fi 12 | 13 | print () { 14 | echo -e "\n\033[1m> $1\033[0m\n" 15 | if [[ -n "$debug" ]] 16 | then 17 | read -rp "press enter to continue" 18 | fi 19 | } 20 | 21 | # Root dataset 22 | root_dataset=$(cat /tmp/root_dataset) 23 | 24 | # Set mirror and architecture 25 | REPO=https://alpha.de.repo.voidlinux.org/current 26 | ARCH=x86_64 27 | 28 | # Copy keys 29 | print 'Copy xbps keys' 30 | mkdir -p /mnt/var/db/xbps/keys 31 | cp /var/db/xbps/keys/* /mnt/var/db/xbps/keys/ 32 | 33 | ### Install base system 34 | print 'Install Void Linux' 35 | XBPS_ARCH=$ARCH xbps-install -y -S -r /mnt -R "$REPO" \ 36 | base-system \ 37 | void-repo-nonfree \ 38 | 39 | # Init chroot 40 | print 'Init chroot' 41 | mount --rbind /sys /mnt/sys && mount --make-rslave /mnt/sys 42 | mount --rbind /dev /mnt/dev && mount --make-rslave /mnt/dev 43 | mount --rbind /proc /mnt/proc && mount --make-rslave /mnt/proc 44 | 45 | # Disable gummiboot post install hooks, only installs for generate-zbm 46 | echo "GUMMIBOOT_DISABLE=1" > /mnt/etc/default/gummiboot 47 | 48 | # Install packages 49 | print 'Install packages' 50 | packages=( 51 | intel-ucode 52 | zfs 53 | zfsbootmenu 54 | efibootmgr 55 | gummiboot # required by zfsbootmenu 56 | chrony # ntp 57 | cronie # cron 58 | seatd # minimal seat management daemon, required by sway 59 | acpid # power management 60 | socklog-void # syslog daemon 61 | iwd # wifi daemon 62 | dhclient 63 | openresolv # dns 64 | git 65 | ansible 66 | linux-firmware 67 | ) 68 | 69 | XBPS_ARCH=$ARCH xbps-install -y -S -r /mnt -R "$REPO" "${packages[@]}" 70 | 71 | # Set hostname 72 | read -r -p 'Please enter hostname : ' hostname 73 | echo "$hostname" > /mnt/etc/hostname 74 | 75 | # Configure zfs 76 | print 'Copy ZFS files' 77 | cp /etc/hostid /mnt/etc/hostid 78 | cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache 79 | cp /etc/zfs/zroot.key /mnt/etc/zfs 80 | 81 | # Configure iwd 82 | cat > /mnt/etc/iwd/main.conf <<"EOF" 83 | [General] 84 | UseDefaultInterface=true 85 | EnableNetworkConfiguration=true 86 | EOF 87 | 88 | # Configure DNS 89 | cat >> /mnt/etc/resolvconf.conf <<"EOF" 90 | resolv_conf=/etc/resolv.conf 91 | name_servers_append="1.1.1.1 9.9.9.9" 92 | name_server_blacklist="192.168.*" 93 | EOF 94 | 95 | # Enable ip forward 96 | cat > /mnt/etc/sysctl.conf <<"EOF" 97 | net.ipv4.ip_forward = 1 98 | EOF 99 | 100 | # Prepare locales and keymap 101 | print 'Prepare locales and keymap' 102 | echo 'KEYMAP=fr' > /mnt/etc/vconsole.conf 103 | echo 'fr_FR.UTF-8 UTF-8' > /mnt/etc/default/libc-locales 104 | echo 'LANG="fr_FR.UTF-8"' > /mnt/etc/locale.conf 105 | 106 | # Configure system 107 | cat >> /mnt/etc/rc.conf << EOF 108 | KEYMAP="fr" 109 | TIMEZONE="Europe/Paris" 110 | HARDWARECLOCK="UTC" 111 | EOF 112 | 113 | # Configure dracut 114 | print 'Configure dracut' 115 | cat > /mnt/etc/dracut.conf.d/zol.conf <<"EOF" 116 | hostonly="yes" 117 | nofsck="yes" 118 | add_dracutmodules+=" zfs " 119 | omit_dracutmodules+=" btrfs resume " 120 | install_items+=" /etc/zfs/zroot.key " 121 | EOF 122 | 123 | ### Configure username 124 | print 'Set your username' 125 | read -r -p "Username: " user 126 | 127 | ### Chroot 128 | print 'Chroot to configure services' 129 | chroot /mnt/ /bin/bash -e < /etc/fstab 154 | EOF 155 | 156 | # Configure fstab 157 | print 'Configure fstab' 158 | cat >> /mnt/etc/fstab <<"EOF" 159 | tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec,inode64 0 0 160 | tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0 161 | efivarfs /sys/firmware/efi/efivars efivarfs defaults 0 0 162 | EOF 163 | 164 | # Set root passwd 165 | print 'Set root password' 166 | chroot /mnt /bin/passwd 167 | 168 | # Set user passwd 169 | print 'Set user password' 170 | chroot /mnt /bin/passwd "$user" 171 | 172 | # Configure sudo 173 | print 'Configure sudo' 174 | cat > /mnt/etc/sudoers < /mnt/etc/zfsbootmenu/config.yaml < /mnt/etc/zfsbootmenu/dracut.conf.d/keymap.conf < /mnt/etc/cmdline.d/keymap.conf <