First commit

This commit is contained in:
2026-01-14 17:59:45 +01:00
commit 5e30040898
7 changed files with 268 additions and 0 deletions

3
DECISIONS.md Normal file
View File

@@ -0,0 +1,3 @@
# DECISIONS
This document some decisions made for the system setup

29
README.md Normal file
View File

@@ -0,0 +1,29 @@
# System specification
The goal of this repository is to document and codify my system setup.
This repository defines:
- how a system is bootstrapped
- which system packages and services are installed
- which system-level configuration is applied
- why certain decisions were made (when relevant)
## Arch bootstrap
After writing the [iso](https://archlinux.org/download/) file to a bootable media and booted on the device, archinstall can be used with the profile located in the `installer` directory. It will create the minimal setup for ansible to work on.
Some helper:
```bash
loadkeys be-latin1 #load the belgian keyboard keys
```
## Ansible replication
## Personal config
See dotfiles [repo]()

3
ansible/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Ansible
Ansible is used to easily replicate most of the system

27
installer/README.md Normal file
View File

@@ -0,0 +1,27 @@
# Archinstall
The goal of archinstall is to easily and reproducibly create a minimal arch install.
Ansible is then used to do the heavy lifting.
The `./patch-disk-config.sh` scripts goal is to help <ith disk setup. More information inside it.
## VM -> Host file transfer (QEMU user networking)
When using QEMU user-mode networking (`10.0.2.0/24`), the host cannot reach the VM directly.
To transfer files from the VM to the host, use `nc`.
On the host (receive):
```sh
nc -l -p 8001 > archinstall.json
````
On the VM (send):
```sh
nc 10.0.2.2 8001 < /root/archinstall.json
```
`10.0.2.2` is the host address in QEMU user networking.

72
installer/patch-disk-config.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/usr/bin/env bash
# This wrapper script dynamically adapts the archinstall configuration to the target machine.
#
# The target disk MUST be provided as a parameter (e.g. /dev/nvme0n1 or a
# /dev/disk/by-id/* path)
#
# This avoids hardcoding device names (e.g. /dev/sda, /dev/nvme0n1) and disk sizes,
# making the same archinstall config usable across multiple devices.
# Usage:
# ./patch-disk-config.sh /dev/nvme0n1
set -euo pipefail
CFG_IN="user_config_base.json"
CFG_OUT="user_config.json"
MIN_GIB=80
die() { echo "Error: $*" >&2; exit 1; }
if [[ $# -ne 1 ]]; then
echo "Usage: $0 <disk-device>"
exit 1
fi
DISK="$1"
# Basic validation
[[ -b "$DISK" ]] || die "'$DISK' is not a block device."
# Refuse removable devices
[[ "$(lsblk -dn -o RM "$DISK")" == "0" ]] || die "'$DISK' is removable. Refusing."
# Minimum size check (bytes)
SIZE_BYTES="$(lsblk -dn -o SIZE -b "$DISK")"
(( SIZE_BYTES >= MIN_GIB * 1024 * 1024 * 1024 )) || die "'$DISK' is smaller than ${MIN_GIB}GiB."
# Sanity: ensure expected JSON structure exists
jq -e '
.disk_config.device_modifications
| type == "array" and length >= 1
and (. [0].partitions | type == "array" and length >= 2)
and (. [0].partitions[1].start.value | type == "number")
and (. [0].partitions[1].size.value | type == "number")
' "$CFG_IN" >/dev/null || die "Unexpected JSON structure in $CFG_IN (cannot locate partitions[1].start/size)."
# Compute "root = remaining space" in bytes based on the configured root partition start offset
ROOT_START_BYTES="$(jq -r '.disk_config.device_modifications[0].partitions[1].start.value' "$CFG_IN")"
[[ "$ROOT_START_BYTES" =~ ^[0-9]+$ ]] || die "Root start offset is not a number: $ROOT_START_BYTES"
ROOT_SIZE_BYTES=$(( SIZE_BYTES - ROOT_START_BYTES ))
(( ROOT_SIZE_BYTES > 0 )) || die "Computed root size is not positive. Disk may be smaller than the configured start offset."
# Patch:
# - set target disk
# - set root partition size to fill to end of disk (bytes)
jq --arg d "$DISK" --argjson root_size "$ROOT_SIZE_BYTES" '
.disk_config.device_modifications[0].device = $d
| .disk_config.device_modifications[0].partitions[1].size.unit = "B"
| .disk_config.device_modifications[0].partitions[1].size.value = $root_size
' "$CFG_IN" > "$CFG_OUT"
# Report
BOOT_SIZE_UNIT="$(jq -r '.disk_config.device_modifications[0].partitions[0].size.unit' "$CFG_OUT")"
BOOT_SIZE_VALUE="$(jq -r '.disk_config.device_modifications[0].partitions[0].size.value' "$CFG_OUT")"
echo "Prepared archinstall config: $CFG_OUT"
echo " Disk : $DISK"
echo " Disk bytes : $SIZE_BYTES"
echo " /boot size : ${BOOT_SIZE_VALUE}${BOOT_SIZE_UNIT}"
echo " Root start : $ROOT_START_BYTES B"
echo " Root size : $ROOT_SIZE_BYTES B (fills remaining space)"

View File

@@ -0,0 +1,133 @@
{
"app_config": {},
"archinstall-language": "English",
"auth_config": {},
"bootloader_config": {
"bootloader": "Grub",
"removable": false,
"uki": false
},
"custom_commands": [],
"disk_config": {
"btrfs_options": {
"snapshot_config": {
"type": "Snapper"
}
},
"config_type": "default_layout",
"device_modifications": [
{
"device": "/dev/vda",
"partitions": [
{
"btrfs": [],
"dev_path": null,
"flags": [
"boot"
],
"fs_type": "fat32",
"mount_options": [],
"mountpoint": "/boot",
"obj_id": "66709eb4-7172-4edd-b2ea-add010dad2ea",
"size": {
"sector_size": {
"unit": "B",
"value": 512
},
"unit": "GiB",
"value": 1
},
"start": {
"sector_size": {
"unit": "B",
"value": 512
},
"unit": "MiB",
"value": 1
},
"status": "create",
"type": "primary"
},
{
"btrfs": [
{
"mountpoint": "/",
"name": "@"
},
{
"mountpoint": "/home",
"name": "@home"
},
{
"mountpoint": "/var/log",
"name": "@log"
},
{
"mountpoint": "/var/cache/pacman/pkg",
"name": "@pkg"
}
],
"dev_path": null,
"flags": [],
"fs_type": "btrfs",
"mount_options": [],
"mountpoint": null,
"obj_id": "596c1c52-a12a-4015-9b1b-86483e57174c",
"size": {
"sector_size": {
"unit": "B",
"value": 512
},
"unit": "B",
"value": 63349719040
},
"start": {
"sector_size": {
"unit": "B",
"value": 512
},
"unit": "B",
"value": 1074790400
},
"status": "create",
"type": "primary"
}
],
"wipe": true
}
],
"disk_encryption": {
"encryption_type": "luks",
"lvm_volumes": [],
"partitions": [
"596c1c52-a12a-4015-9b1b-86483e57174c"
]
}
},
"hostname": "archlinux",
"kernels": [
"linux"
],
"locale_config": {
"kb_layout": "be-latin1",
"sys_enc": "UTF-8",
"sys_lang": "en_US.UTF-8"
},
"network_config": {
"type": "nm"
},
"ntp": true,
"packages": [
"git",
"ansible-core"
],
"parallel_downloads": 0,
"script": null,
"services": [],
"swap": {
"algorithm": "zstd",
"enabled": true
},
"timezone": "Europe/Brussels",
"version": "3.0.15"
}

1
installer/user_cred.json Normal file
View File

@@ -0,0 +1 @@
$argon2id$rqnG-ofpluTBwMEUy7pV3w==$Z0FBQUFBQnBaOHM3eTR6WkVlZ3RUX2JPakZycXNIdFJHN0lQMGxLeDRaUmRJdVRZbkZZOFhHdnpYbHBQUmxMQUNSTUNYWGxaczROaTktMGNXbklHcklWWmY2TnJRMUlxazZmZFE0UGN2V2Vud0VkQmY5RE5nMjRPeVdGclBMNEItNjRLMjFQTjdUeTRXZTJEZ3NtdGNxTEE4dXZDZklkbXZ3Y1hTWGQ4eFpFeVJuODFDUWMybW5wYlB3RlcwTGQxWFp3UThYN0lPQkJRXzBEX1loSUNHekdJOEtRc3N3T1FRWUY1T3B1cTRvd0lUaHlSblVJaDNhVVZGejFLLTd6ckRnZkxkaVE3TnAwUGdIaGRYNVZWYWY3WElGaTVWZm5QalpnWG0tdEdILThRQXBYdUc0RVJKQjA3cDVrZmNaM3RPQUVEZFdEX3lpdTZoNkxVRXRMMkZuYjdxaTM3a2lkbGpZbWV1MEs0c2RwWG9qcGcySDRPNDNUWHpSaFRXTUlpM2wzUFRJQnNHZFFSbm9YOEJpNTZIVXFXTHp6Z3ZNd05ZUVRsUDFqOVpqbmFIV3hjZVdXWFBaVnBiRWVJcndMTF9Hd1MtQ3paQm1Xa01DWGFGMnNOM3dDdnl2WW40MTB5bERwd0pKM0pUU2dkMllsTGxZX3lHRjlfUWFzLXBKMzdmeWsyQUFpQXQzaEo4MWlWMjZmMzRhX3lDalh3M21rU1BQNWhUaXU4dU0wdWdTV2pLVjVYbTJvZUdfUVkwT2QzakZXQXNGTzdodFhp