Some beginning works for component customization

This commit is contained in:
Hoang Nguyen 2022-10-01 21:15:29 +07:00
parent 7bc355fef6
commit 8e61893c93
No known key found for this signature in database
GPG Key ID: 813CF484F4993419
27 changed files with 316 additions and 200 deletions

View File

@ -8,14 +8,14 @@ This is an Ansible playbook to deploy my system configurations for desktop usage
- Install `ansible-core` and `git`
- Clone this repository
- Install needed external modules (e.g. `apk`, `pamd`, `mount`):
```bash
ansible-galaxy collection install -r requirements/collections.yml
```
- Clone this repository
- Create an encrypted file to store your user password:
```bash
@ -26,6 +26,10 @@ This is an Ansible playbook to deploy my system configurations for desktop usage
```
The file should look like this: `vault_password: <strong_&_secure_password>`
- Customize the variables in [group_vars/all.yml](./group_vars/all.yml).
Some variables only accept a list of defined values. They are listed in [requirements/accepted_variables.yml](./requirements/accepted_variables.yml).
- Run the playbook:
```bash

19
TODO.md
View File

@ -4,21 +4,24 @@ Stuff that are planned to be changed.
## Configuration
- [ ] ZFS on root
- [ ] EFI secure boot (also sign fwupd efi binary)
- [ ] /etc/security/access.conf (maybe?)
- [ ] snapper / btrbk (rootfs=btrfs)
- [ ] sanoid (rootfs=zfs)
- [ ] auditd
- [ ] booster
- [ ] Refactor grub role (to support other bootloader options)
- [ ] refind / efistub / zfsbootmenu
- [ ] Other options than udhcp (connman / networkmanager)
- [ ] auditd / go-audit
- [ ] incron
- [ ] bees
- [ ] Option for other bootloaders (refind / efistub / limine / zfsbootmenu)
- [ ] Refactor grub role
- [ ] Option for other dhcp clients (connman / networkmanager)
- [ ] Option for other initramfs generators (booster)
- [ ] docker rootless (no zfs support)
## Cosmetic
- [ ] Vagrantfiles --> Packer + Terraform (zfs + btrfs VMs)
- [ ] Vagrantfiles --> Packer + Terraform / Pulumi (zfs + btrfs VMs)
- [ ] Self-built kernels (e.g. RT kernels)
- [ ] ZFS on root
- [ ] EFI secure boot (also sign fwupd efi binary)
## Just in case I forget

View File

@ -3,6 +3,7 @@ from ansible.module_utils.six import string_types
# Ansible's "quote" filter is only applied to shell module
def quote_single(str):
"""
Quote a string with single quote.
@ -15,9 +16,20 @@ def quote_single(str):
raise AnsibleFilterTypeError(
"|quote_single expects string, got %s instead." % type(str))
def quote_double(str):
"""
Quote a string with double quote.
Example: a string -> "a string"
"""
if isinstance(str, string_types):
return '"' + str + '"'
else:
raise AnsibleFilterTypeError(
"|quote_double expects string, got %s instead." % type(str))
class FilterModule(object):
"""Custom Ansible jinja2 filters for sysconfig playbook."""
def filters(self):
return {'quote_single': quote_single}
return {'quote_single': quote_single, 'quote_double': quote_double}

View File

@ -1,14 +1,35 @@
---
# Custom variables ────────────────────────────────────────────────────────────
# NOTE: for variables checked in `reqirements/accepted_variables.yml`, keep them as top-level
repository: https://mirror.math.princeton.edu/pub/alpinelinux
rootfs: btrfs
bootloader: grub
initramfs_generator: mkinitfs
username: follie
# See roles/user/defaults/main.yml for a list of accepted shells
usershell: fish
repository: https://mirror.math.princeton.edu/pub/alpinelinux
seat_manager: seatd
dhcp_client: udhcpc
# acpid implementation to use when elogind is not present
acpid_daemon: busybox
device_manager: mdevd
audit_daemon: auditd
crond_provider: cronie
syslog_provider: busybox
rootless_container_cli: podman
# Additional kernel command-line parameters (added to the bootloader)
additional_kernel_parameters:
@ -16,29 +37,15 @@ additional_kernel_parameters:
- page_alloc.shuffle=1
- lockdown=integrity
# Disable access to /sys/firmware/efi/efivars
disable_uefi_access: true
ntp_client: ntpsec
ntp_options:
pool: # https://www.ntppool.org/en/use.html
- 0.pool.ntp.org
- 1.pool.ntp.org
- 2.pool.ntp.org
- 3.pool.ntp.org
# 'seatd' or 'elogind'
seat_manager: seatd
# acpid implementation to use when elogind is not present
# 'busybox' or 'acpid'
acpid_daemon: busybox
# busybox's mdev, skarnet's mdevd or eudev's udev
device_manager: mdevd
# Should polkit be used for stuff
# (have no effect when seat_manager == 'elogind')
polkit: false
# Should be a file name in /usr/share/consolefonts/
console_font: ter-h22b.psf.gz
# 'dnscrypt-proxy' or 'unbound'
dns_resolver: dnscrypt-proxy
dnscrypt:
adblock: true
server_names:
@ -68,7 +75,6 @@ dnscrypt:
- anon-tiarap-ipv6
- anon-cs-tokyo
- anon-cs-sk
unbound_upstream_nameservers:
- 9.9.9.9@853#dns.quad9.net
- 149.112.112.112@853#dns.quad9.net
@ -79,7 +85,17 @@ unbound_upstream_nameservers:
- 2606:4700:4700::1111@853#cloudflare-dns.com
- 2606:4700:4700::1001@853#cloudflare-dns.com
# 'virtlockd' and 'virtlogd' will always be started. Don't list them here
# Enable/Disable access to /sys/firmware/efi/efivars
disable_uefi_access: true
# Should polkit be used
# (have no effect when seat_manager == 'elogind')
polkit: false
# Should be a file name in /usr/share/consolefonts/
console_font: ter-h22b.psf.gz
# 'virtlockd' and 'virtlogd' will always be started so don't list them here
libvirt_daemons:
- virtinterfaced
- virtnetworkd
@ -106,9 +122,6 @@ opened_ports:
tcp: []
udp: []
# 'podman' or 'nerdctl'
rootless_container_cli: podman
# earlyoom kills processes on its own so make it optional
earlyoom:
set_priority: true

View File

@ -1,2 +1,5 @@
[local]
localhost ansible_connection=local
---
local:
hosts:
localhost:
ansible_connection: local

View File

@ -0,0 +1,68 @@
---
# NOTE: Keep this in sync with `shell_mappings` in roles/user/defaults/main.yml
bootloader:
- grub
- limine
- efistub
initramfs_generator:
- mkinitfs
- dracut
- booster
usershell:
- ash
- bash
- fish
- hilbish
- ion-shell
- nushell
- sh
- xonsh
- zsh
seat_manager:
- seatd
- elogind
acpid_daemon:
- busybox
- acpid
device_manager:
- mdev
- mdevd
- udev
dhcp_client:
- udhcpc # from busybox
- dhcpcd
- connman
audit_daemon:
- auditd
- go-audit
crond_provider:
- busybox
- cronie
- dcron
- fcron
syslog_provider:
- busybox
- rsyslog
ntp_client:
- ntpsec
- busybox
- openntpd
- chrony
dns_resolver:
- dnscrypt-proxy
- unbound
rootless_container_cli:
- podman
- nerdctl

View File

@ -0,0 +1,23 @@
---
- name: acpi | Install acpid and acpi-utils
apk:
name: acpid, acpi-utils
state: present
- name: acpi | Copy acpid event handler script
copy:
src: handler.sh
dest: /etc/acpi/handler.sh
mode: 0755
owner: root
group: root
- name: acpi | Use process supervisor for acpid service
lineinfile:
path: /etc/conf.d/acpid
search_string: supervisor=
line: supervisor="supervise-daemon"
state: present
owner: root
group: root
mode: 0644

View File

@ -0,0 +1,16 @@
---
- name: acpi | Create directory for Lid Close event
file:
path: /etc/acpi/LID
state: directory
mode: 0755
owner: root
group: root
- name: acpi | Copy event handler for Lid Close
copy:
src: acpid_lid_close
dest: /etc/acpi/LID/00000080
mode: 0755
owner: root
group: root

View File

@ -0,0 +1,24 @@
---
- name: acpi | Do not run acpid service
service:
name: acpid
enabled: no
state: stopped
- block:
- name: acpi | Create custom config directory for logind.conf
file:
path: /etc/elogind/logind.conf.d
state: directory
mode: 0755
owner: root
group: root
- name: acpi | Copy logind.conf
copy:
src: logind.conf
dest: /etc/elogind/logind.conf.d/custom.conf
mode: 0644
owner: root
group: root
tags: laptop

View File

@ -1,75 +1,18 @@
---
# elogind also handles acpi events
- block:
- name: acpi | Do not run acpid service
service:
name: acpid
enabled: no
state: stopped
- block:
- name: acpi | Create custom config directory for logind.conf
file:
path: /etc/elogind/logind.conf.d
state: directory
mode: 0755
owner: root
group: root
- name: acpi | Copy logind.conf
copy:
src: logind.conf
dest: /etc/elogind/logind.conf.d/custom.conf
mode: 0644
owner: root
group: root
tags: laptop
- name: acpi | Configure elogind
import_tasks: elogind.yml
when: seat_manager == 'elogind'
- block:
- block:
- name: acpi | Install acpid and acpi-utils
apk:
name: acpid, acpi-utils
state: present
- name: acpi | Copy acpid event handler script
copy:
src: handler.sh
dest: /etc/acpi/handler.sh
mode: 0755
owner: root
group: root
- name: acpi | Use process supervisor for acpid service
lineinfile:
path: /etc/conf.d/acpid
search_string: supervisor=
line: supervisor="supervise-daemon"
state: present
owner: root
group: root
mode: 0644
- name: acpi | Configure acpid
import_tasks: acpid.yml
when: acpid_daemon == 'acpid'
- block:
- name: acpi | Create directory for Lid Close event
file:
path: /etc/acpi/LID
state: directory
mode: 0755
owner: root
group: root
- name: acpi | Copy event handler for Lid Close
copy:
src: acpid_lid_close
dest: /etc/acpi/LID/00000080
mode: 0755
owner: root
group: root
tags: laptop
- name: acpi | Configure busybox's apicd
import_tasks: busybox.yml
when: acpid_daemon == 'busybox'
tags: laptop
- name: acpi | Enable acpid service on runlevel 'default'
service:

View File

@ -0,0 +1,22 @@
---
- name: apparmor | Check whether apparmor kernel parameters is presented
lineinfile:
backup: yes
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX_DEFAULT=".*apparmor=.*'
state: absent
check_mode: yes
register: apparmor_cmdline_check
changed_when: no
- name: apparmor | Add apparmor to grub boot command if missing
lineinfile:
backrefs: yes
path: /etc/default/grub
regexp: '^(GRUB_CMDLINE_LINUX_DEFAULT=".*)"$'
line: '\1 apparmor=1 security=apparmor"'
owner: root
group: root
mode: 0644
when: apparmor_cmdline_check.found == 0
notify: Update grub config

View File

@ -24,24 +24,6 @@
runlevel: boot
enabled: yes
- name: apparmor | Check whether apparmor kernel parameters is presented
lineinfile:
backup: yes
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX_DEFAULT=".*apparmor=.*'
state: absent
check_mode: yes
register: apparmor_cmdline_check
changed_when: no
- name: apparmor | Add apparmor to grub boot command if missing
lineinfile:
backrefs: yes
path: /etc/default/grub
regexp: '^(GRUB_CMDLINE_LINUX_DEFAULT=".*)"$'
line: '\1 apparmor=1 security=apparmor"'
owner: root
group: root
mode: 0644
when: apparmor_cmdline_check.found == 0
notify: Update grub config
- name: apparmor | Configure kernel parameters in GRUB config file
import_tasks: grub.yml
when: bootloader == 'grub'

View File

@ -16,31 +16,5 @@
- subgid
- subuid
- name: container | Set podman storage driver to btrfs
lineinfile:
path: /etc/containers/storage.conf
search_string: driver =
line: driver = "btrfs"
state: present
owner: root
group: root
mode: 0644
when:
- rootless_container_cli == 'podman'
- rootfs == 'btrfs'
# FIX: still requires manual setup for rootless containerd daemon
# https://github.com/containerd/nerdctl/blob/master/docs/rootless.md
- name: container | Set containerd snapshotter backend to btrfs
lineinfile:
backrefs: yes
path: /etc/containerd/config.toml
regexp: '^(\s*snapshotter =) ".*$'
line: '\1 "btrfs"'
state: present
owner: root
group: root
mode: 0644
when:
- rootless_container_cli == 'nerdctl'
- rootfs == 'btrfs'
- name: container | Configure {{ rootless_container_cli }} system-wide
include_tasks: '{{ rootless_container_cli }}.yml'

View File

@ -0,0 +1,14 @@
---
# FIX: still requires manual setup for rootless containerd daemon
# https://github.com/containerd/nerdctl/blob/master/docs/rootless.md
- name: container | Set containerd snapshotter backend to {{ rootfs }}
lineinfile:
backrefs: yes
path: /etc/containerd/config.toml
regexp: '^(\s*snapshotter =) ".*$'
line: '\1 "{{ rootfs }}"'
state: present
owner: root
group: root
mode: 0644
when: rootfs in ['btrfs', 'zfs']

View File

@ -0,0 +1,11 @@
---
- name: container | Set podman storage driver to {{ rootfs }}
lineinfile:
path: /etc/containers/storage.conf
search_string: driver =
line: driver = "{{ rootfs }}"
state: present
owner: root
group: root
mode: 0644
when: rootfs in ['btrfs', 'zfs']

View File

@ -1,3 +1,5 @@
#!/bin/sh
/sbin/btrfs scrub start /
# Use flock to ensure the cron job won't start a 2nd time
# Ref: https://wiki.archlinux.org/title/Cron#Ensuring_exclusivity
/usr/bin/flock -nx /tmp/btrfs_scrub.lock /sbin/btrfs scrub start /

View File

@ -1,6 +1,5 @@
#!/bin/sh
# This needs fstrim (which will be pulled by installing tlp anyway)
/sbin/fstrim -a
# For busybox's fstrim, using multiple 'fstrim /mount_point' is more feasible
/sbin/fstrim -a

View File

@ -15,19 +15,3 @@
owner: root
group: root
mode: 0644
- name: dns | Overwrite /etc/netconfig/interfaces
template:
src: interfaces.j2
dest: /etc/network/interfaces
owner: root
group: root
mode: 0644
- name: dns | Overwrite /etc/hosts to support IPv6
copy:
src: hosts
dest: /etc/hosts
owner: root
group: root
mode: 0644

View File

@ -7,9 +7,10 @@
fstype: tmpfs
opts: rw,nosuid,nodev,size=4G,mode=1777
state: present
when: rootfs != 'zfs'
# /run is mounted with exec by default
- name: fstab | Hardent mount options for /run
- name: fstab | Harden mount options for /run
mount:
src: tmpfs
path: /run

View File

@ -1,18 +1,18 @@
---
- name: iwd | Install iwd package
- name: networking | Install iwd package
apk:
name: iwd
state: present
- name: iwd | Copy configuration
- name: networking | Copy configuration
copy:
src: main.conf
src: iwd/main.conf
dest: /etc/iwd/main.conf
owner: root
group: root
mode: 0644
- name: iwd | Start iwd service on runlevel 'default'
- name: networking | Start iwd service on runlevel 'default'
service:
name: iwd
runlevel: default

View File

@ -0,0 +1,20 @@
---
- name: networking | Configure /etc/netconfig/interfaces
template:
src: interfaces.j2
dest: /etc/network/interfaces
owner: root
group: root
mode: 0644
- name: networking | Overwrite /etc/hosts to support IPv6
copy:
src: hosts
dest: /etc/hosts
owner: root
group: root
mode: 0644
- name: networking | Configure iwd
import_tasks: iwd.yml
tags: laptop

View File

@ -10,7 +10,7 @@ realtime_pam_limits:
- item: rtprio
value: '95'
shells_list:
shells_mappings:
ash: /bin/ash
bash: /bin/bash
fish: /usr/bin/fish

View File

@ -32,7 +32,7 @@
- '{{ realtime_group }}'
create_home: yes
home: '/home/{{ username }}'
shell: '{{ shells_list[usershell] }}'
shell: '{{ shell_mappings[usershell] }}'
state: present
comment: Kawaii Linux user

View File

@ -1,29 +1,26 @@
---
- name: Sanity checks for variables
- name: Gathering facts
hosts: all
gather_facts: yes
tags: always
- name: Sanity checks
hosts: all
tags: always
tasks:
- name: Check whether the current user is 'root'
- name: Check user ID
fail:
msg: This playbook should only be run as 'root'
when: ansible_real_user_id != 0
- name: Check seat manager name
- name: Import list of accepted values for defined variables
include_vars:
name: accepted_values
file: ./requirements/accepted_variables.yml
- name: Check defined values of top-level variables
fail:
msg: seat_manager needs to be 'elogind' or 'seatd'
when: not seat_manager in ['elogind', 'seatd']
- name: Check device manager name
fail:
msg: device_manager needs to be 'mdev', 'mdevd' or 'udev'
when: not device_manager in ['mdev', 'mdevd', 'udev']
- name: Check DNS resolver name
fail:
msg: dns_resolver needs to be 'dnscrypt-proxy' or 'unbound'
when: not dns_resolver in ['dnscrypt-proxy', 'unbound']
- name: Check rootless container CLI application
fail:
msg: rootless_container_cli needs to be 'podman' or 'nerdctl'
when: not rootless_container_cli in ['podman', 'nerdctl']
msg: 'Variable `{{ item }}` needs to be 1 of {{ accepted_values[item] }}'
when: not vars[item] in accepted_values[item]
loop: '{{ accepted_values | flatten }}'
- name: Setup the system
hosts: all
@ -50,8 +47,9 @@
tags: cron
- role: grub
tags: grub
- role: iwd
tags: [laptop, iwd]
when: bootloader == 'grub'
- role: networking
tags: networking
- role: libvirt
tags: libvirt
- role: tlp
@ -69,4 +67,4 @@
- role: container
tags: container
- role: waydroid
tags: waydroid
tags: [waydroid, never]