]> code.delx.au - monosys/commitdiff
notes: fix raspi install notes, also @home -> @username master
authorJames Bunton <jamesbunton@delx.au>
Sat, 6 Apr 2024 23:42:16 +0000 (09:42 +1000)
committerJames Bunton <jamesbunton@delx.au>
Sat, 6 Apr 2024 23:42:16 +0000 (09:42 +1000)
89 files changed:
.category [new file with mode: 0644]
.gitignore [new file with mode: 0644]
README.md [new file with mode: 0644]
archpkg/makechrootpkgx
archpkg/repo-sign
bin/check-local-updates
bin/dates
bin/hexhost [new file with mode: 0755]
bin/wifi-scan
bsnap/README.md [new file with mode: 0644]
bsnap/bsnap [new file with mode: 0755]
etc/bluetooth/main.conf [new file with mode: 0644]
etc/default/grub [new file with mode: 0644]
etc/modprobe.d/apple-keyboard.conf [new file with mode: 0644]
etc/nginx/nginx.conf [new file with mode: 0644]
etc/nginx/sites-available/default [new file with mode: 0644]
etc/nginx/sites-available/example.com [new file with mode: 0644]
etc/nginx/sites-enabled/0000_default [new symlink]
etc/nginx/snippets/listen-http.conf [new file with mode: 0644]
etc/nginx/snippets/listen-tls.conf [new file with mode: 0644]
etc/nginx/snippets/standard-server.conf [new file with mode: 0644]
etc/smartd.conf [new file with mode: 0644]
etc/ssh/sshd_config [new file with mode: 0644]
etc/sudoers.d/10_env_keep [new file with mode: 0644]
etc/sudoers.d/20_sudo_group [new file with mode: 0644]
etc/sudoers.d/30_aptitude [new file with mode: 0644]
etc/sudoers.d/30_pacman [new file with mode: 0644]
etc/sudoers.d/40_podman [new file with mode: 0644]
etc/systemd/network/ethernet.network [new file with mode: 0644]
etc/systemd/resolved.conf [new file with mode: 0644]
etc/systemd/system/my-overrides/10-security.conf [new file with mode: 0644]
etc/udev/rules.d/10-network.rules [new file with mode: 0644]
hacks/backup-openwrt [new file with mode: 0755]
hacks/dmsetup-hack [new file with mode: 0755]
hacks/fix-openwrt-hairpin [new file with mode: 0755]
hacks/git-no-husky [new file with mode: 0755]
hacks/lib-ext-backup
hacks/multiboot-setup
hacks/ssh-screen-wrapper
hacks/syncthing-healthcheck [new file with mode: 0755]
healthcheck/run-all
healthcheck/systemd-user-timers [deleted file]
healthcheck/systemd-user-units
hw/MacBookPro11,5/refind.conf [new file with mode: 0644]
hw/MacBookPro11,5/set-intel-gpu-in-efi.sh [new file with mode: 0644]
hw/lenovo-m93p/etc/fancontrol [new file with mode: 0755]
hw/lenovo-m93p/etc/modprobe.d/it87.conf [new file with mode: 0644]
hw/lenovo-m93p/etc/systemd/system/fancontrol.service [new file with mode: 0644]
notes/desktop:debian-bookworm.txt [new file with mode: 0644]
notes/flathub.txt [new file with mode: 0644]
notes/raspi-headless:debian-bookworm.txt [new file with mode: 0644]
notes/raspi-headless:raspian-bookworm.txt [new file with mode: 0644]
notes/snapper.txt [new file with mode: 0644]
package-lists/arch/base [new file with mode: 0644]
package-lists/arch/base-devel [new file with mode: 0644]
package-lists/arch/base-hw [new file with mode: 0644]
package-lists/arch/bluetooth [new file with mode: 0644]
package-lists/arch/desktop-base [new file with mode: 0644]
package-lists/arch/desktop-gnome [new file with mode: 0644]
package-lists/arch/desktop-printing [new file with mode: 0644]
package-lists/arch/desktop-pulseaudio [new file with mode: 0644]
package-lists/arch/desktop-video [new file with mode: 0644]
package-lists/arch/desktop-xfce [new file with mode: 0644]
package-lists/arch/desktop-xorg [new file with mode: 0644]
package-lists/arch/emacs [new file with mode: 0644]
package-lists/arch/filesystems [new file with mode: 0644]
package-lists/arch/podman [new file with mode: 0644]
package-lists/arch/sanoid [new file with mode: 0644]
package-lists/arch/system-efi-amd64 [new file with mode: 0644]
package-lists/arch/transcoding [new file with mode: 0644]
package-lists/arch/wifi [new file with mode: 0644]
package-lists/debian/base [new file with mode: 0644]
package-lists/debian/base-devel [new file with mode: 0644]
package-lists/debian/base-hw [new file with mode: 0644]
package-lists/debian/bluetooth [new file with mode: 0644]
package-lists/debian/desktop-base [new file with mode: 0644]
package-lists/debian/desktop-gnome [new file with mode: 0644]
package-lists/debian/desktop-gnome-software [new file with mode: 0644]
package-lists/debian/desktop-plymouth [new file with mode: 0644]
package-lists/debian/desktop-printing [new file with mode: 0644]
package-lists/debian/desktop-video [new file with mode: 0644]
package-lists/debian/desktop-xfce [new file with mode: 0644]
package-lists/debian/desktop-xorg [new file with mode: 0644]
package-lists/debian/filesystems [new file with mode: 0644]
package-lists/debian/system-efi-amd64 [new file with mode: 0644]
package-lists/debian/system-raspi [new file with mode: 0644]
package-lists/debian/wifi [new file with mode: 0644]
package-lists/ubuntu/base-ubuntu [new file with mode: 0644]
package-lists/ubuntu/desktop-base-ubuntu [new file with mode: 0644]

diff --git a/.category b/.category
new file mode 100644 (file)
index 0000000..04204c7
--- /dev/null
+++ b/.category
@@ -0,0 +1 @@
+config
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..4083037
--- /dev/null
@@ -0,0 +1 @@
+local
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..6f72827
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+# monosys
+
+Monorepo for system configuration.
+
index 1f00cd986ca620ada132b1bec309e5fd5626c3e3..bbff0c0fe22fc16dccf3d92813d479e16a5c500d 100755 (executable)
@@ -2,4 +2,4 @@
 
 set -xeu
 sudo arch-nspawn /var/cache/pacman/chroot/root pacman -Syu
-makechrootpkg -c -l "$(basename "$PWD")" -T -r /var/cache/pacman/chroot
+makechrootpkg -c -l "$(basename "$PWD")" -T -r /var/cache/pacman/chroot -U pacman-builder
index 97303cd73bd6314e71c1c601ed826d71c72fa3d4..f72d8ea9cc2087917718d9110ce0c0bfb1901605 100755 (executable)
@@ -5,7 +5,10 @@ set -eu
 cd /var/cache/pacman/abs
 
 tosign=()
-for pkg in *.pkg.tar.xz; do
+for pkg in *.pkg.*; do
+    if [[ "$pkg" =~ .*\.sig ]]; then
+        continue
+    fi
     if ! [ -f "${pkg}.sig" ]; then
         tosign+=("$pkg")
     fi
@@ -22,7 +25,7 @@ if [ "${#tosign[@]}" -gt 0 ]; then
     echo
     set -x
     # Preload the agent
-    gpg --output /dev/null --detach-sign /dev/null
+    gpg --output - --detach-sign <(echo) > /dev/null
     echo "${tosign[@]}" | xargs -n1 gpg --detach-sign
     echo "${tosign[@]}" | xargs -n1 repo-add delx.db.tar.xz -R
 else
index 64059295f656587ed83b9f618f7bec77b159db62..806c58fe63ce9a5b9ff43e6127d80e2036778be1 100755 (executable)
@@ -17,5 +17,5 @@ if is_debian; then
 fi
 
 if is_arch; then
-    checkupdates
+    checkupdates || true
 fi
index da607d2d9b5a27ce195703283a0100ba3489c024..f4708d3a252595548fd285d0ded432df7ca43f08 100755 (executable)
--- a/bin/dates
+++ b/bin/dates
@@ -6,8 +6,10 @@ America/Chicago
 America/New_York
 Europe/London
 UTC
+Asia/Kolkata
 Asia/Ho_Chi_Minh
 Australia/Perth
+Australia/Brisbane
 Australia/Sydney
 "
 
diff --git a/bin/hexhost b/bin/hexhost
new file mode 100755 (executable)
index 0000000..ef6240f
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/env node
+
+'use strict';
+
+const BLOCKSIZE = 3;
+const CHARS1 = [
+    ' ',
+    ...'0123456789'.split(''),
+    ...'abcdefghijklmnopqrstuvwxyz'.split(''),
+    '_',
+    '-',
+];
+const SHIFT = BigInt(Math.ceil(Math.log2(CHARS1.length ** BLOCKSIZE)));
+const MASK = 2n**SHIFT - 1n;
+
+const CHARSN = [...Array(BLOCKSIZE - 1)].reduce((acc) => acc.map((v1) => CHARS1.map((v2) => ''+v1+v2)).flat(), CHARS1);
+const FMAP = new Map(CHARSN.map((v, i) => [''+v, BigInt(i)]));
+const RMAP = new Map(CHARSN.map((v, i) => [BigInt(i), ''+v]));
+
+function main(arg1, arg2) {
+    if (!arg1) {
+        console.error('Usage: hexhost fdxx::4a59954e');
+        console.error('Usage: hexhost fdxx:: hostname');
+        process.exit(1);
+    }
+
+    if (arg2) {
+        const prefix = arg1;
+        const suffix = encode(arg2).replaceAll(/(.{4})/g, '$1:').replace(/:$/, '');
+        console.log(prefix + suffix);
+    } else {
+        const [, suffix] = arg1.split(/::|:0:/);
+        console.log(decode(suffix));
+    }
+}
+
+function decode(input) {
+    input = input && input.replaceAll(':', '');
+    if (!input) {
+        throw new Error('No suffix found');
+    }
+    input = BigInt('0x' + input);
+    let output = [];
+    while (input > 0) {
+        const encodedBlock = input & MASK;
+        input >>= SHIFT;
+        const block = RMAP.get(encodedBlock);
+        if (block !== undefined) {
+            output.push(block);
+        }
+    }
+    return output.reverse().join('').trim();
+}
+
+function encode(input) {
+    if (input.length / BLOCKSIZE > (64n / SHIFT)) {
+        throw new Error('Input is too long to fit in a /64!');
+    }
+
+    input = input.toLowerCase();
+
+    let out = BigInt(0);
+    for (let i = 0; i < input.length; i += BLOCKSIZE) {
+        const block = input.substring(i, i + BLOCKSIZE).padEnd(BLOCKSIZE);
+        const encodedBlock = FMAP.get(block);
+        if (encodedBlock !== undefined) {
+            out = (out << SHIFT) + encodedBlock;
+        }
+    }
+    return out.toString(16);
+}
+
+main(process.argv[2], process.argv[3]);
index 9b3b17c467f691f5f5e77c8c26d8a6820ad14eb1..12c3240e34af533262ebaaa12bf024f0511590e8 100755 (executable)
@@ -43,6 +43,7 @@ function formatScanResult(scanResult) {
             finishPartial();
             partial = {};
             partial.bssid = line.match(/[a-z0-9:]+/)[0];
+            partial.associated = line.indexOf('associated') >= 0 ? '**' : '';
         }
 
         line = line.trim()
@@ -63,6 +64,8 @@ function formatScanResult(scanResult) {
         }
     }
 
+    finishPartial();
+
     function finishPartial() {
         if (!partial) {
             return;
@@ -81,10 +84,10 @@ function formatScanResult(scanResult) {
 
     return results
         .sort()
-        .map(([, {bssid, ssid, signal, channel}]) => {
+        .map(([, {bssid, ssid, signal, channel, associated}]) => {
             ssid = ssid.padStart(40, ' ').substr(0, 40);
             channel = channel.padEnd(12, ' ');
-            return `${signal}  ${channel}  ${ssid}  ${bssid}`;
+            return `${signal}  ${channel}  ${ssid}  ${bssid}  ${associated}`;
         })
         .join('\n') + '\n';
 }
diff --git a/bsnap/README.md b/bsnap/README.md
new file mode 100644 (file)
index 0000000..e4e7322
--- /dev/null
@@ -0,0 +1,25 @@
+# bsnap
+
+Manage snapshots for backups using LVM or btrfs. This is intended for use with [borg](https://www.borgbackup.org) or [rsync](https://rsync.samba.org).
+
+## Usage
+
+Running `bsnap on` will do the following:
+- Create a new directory `/a` where the snapshots will be mounted.
+- Take snapshots as configured in your `/etc/fstab`.
+- Mount the snapshots into `/a`.
+
+At this point you can run something like [borg](https://www.borgbackup.org) or [rsync](https://rsync.samba.org) on `/a` to create your backup. Once that's completed you then run `bsnap off` to unmount, remove the snapshots and cleanup `/a`.
+
+You must configure your `/etc/fstab` by setting the second last column for each entry:
+- `0` -- no snapshot will be taken and the filesystem will not be mounted into `/a`
+- `1` -- no snapshot will be taken but the filesystem will be bind mounted into `/a`
+- `2` -- a snapshot will be taken and the snapshot will be mounted into `/a`
+
+```
+# Snapshot the LVM root filesystem
+/dev/mapper/vg-root  /      ext4  defaults  2 0
+
+# Mount it into /a so it's included in the backup without snapshotting it
+UUID="ABCD-1234"     /boot  vfat  defaults  1 0
+```
diff --git a/bsnap/bsnap b/bsnap/bsnap
new file mode 100755 (executable)
index 0000000..af77d1f
--- /dev/null
@@ -0,0 +1,133 @@
+#!/bin/bash
+
+set -eu
+
+function snap {
+    unsnap
+
+    mkdir -p /a
+
+    dispatch snap < /etc/fstab
+}
+
+function unsnap {
+    tac /etc/fstab | dispatch unsnap
+
+    if [ -d "/a" ]; then
+        rmdir /a
+    fi
+}
+
+function dispatch {
+    local action="" snaptype=""
+    local dev="" mnt="" fstype="" opts="" dump=""
+
+    while read -r dev mnt fstype opts dump pass; do
+        snaptype="$(get_snaptype "$fstype" "$dump")"
+        if [ -z "$snaptype" ]; then
+            continue
+        fi
+        action="${1}_${snaptype}"
+        echo "$action $mnt"
+        "$action" "$dev" "$mnt" "$opts"
+    done
+}
+
+function get_snaptype {
+    local fstype="$1" dump="$2"
+    if [ "$dump" = "1" ]; then
+        echo bind
+    elif [ "$dump" = "2" ] && [ "$fstype" = "btrfs" ]; then
+        echo btrfs
+    elif [ "$dump" = "2" ]; then
+        echo lvm
+    fi
+}
+
+function snap_bind {
+    local mnt="$2"
+    mount --bind "${mnt}" "/a${mnt}"
+}
+
+function unsnap_bind {
+    local snapmnt="/a$2"
+    if mountpoint -q "$snapmnt"; then
+        umount "$snapmnt"
+    fi
+}
+
+function snap_lvm {
+    local mnt="$2"
+    local lvname="" vgname=""
+    read -r lvname vgname _ < <(get_lvm_vgname_lvname "${mnt}")
+
+    echo "snapshot ${vgname}/${lvname}"
+    lvcreate -L1G --snapshot --name "${lvname}-snap" "${vgname}/${lvname}"
+    mount -o ro "/dev/${vgname}/${lvname}-snap" "/a${mnt}"
+}
+
+function unsnap_lvm {
+    local mnt="$2"
+    local lvname="" vgname=""
+
+    if mountpoint -q "/a$mnt"; then
+        umount "/a$mnt"
+    fi
+
+    read -r lvname vgname _ < <(get_lvm_vgname_lvname "${mnt}")
+    if lvdisplay "${vgname}/${lvname}-snap" &> /dev/null; then
+        lvremove -f "${vgname}/${lvname}-snap"
+    fi
+}
+
+function get_lvm_vgname_lvname {
+    local mnt="$1" subvol=""
+    lvdisplay --noheadings -C "$(findmnt -n -o source "$mnt")"
+}
+
+function snap_btrfs {
+    local mnt="$2" opts="$3" snapdir=""
+
+    snapdir="$(get_btrfs_snapshot_dir "$opts" "$mnt")"
+    btrfs subvolume snapshot "$mnt" "$snapdir"
+
+    mount --bind "$snapdir" "/a${mnt}"
+}
+
+function unsnap_btrfs {
+    local mnt="$2" opts="$3" snapdir=""
+
+    local snapmnt="/a$2"
+    if mountpoint -q "$snapmnt"; then
+        umount "$snapmnt"
+    fi
+
+    snapdir="$(get_btrfs_snapshot_dir "$opts" "$mnt")"
+    if [ -d "$snapdir" ]; then
+        btrfs subvolume delete "$snapdir"
+    fi
+}
+
+function get_btrfs_snapshot_dir {
+    local opts="$1" mnt="$2" subvol=""
+    subvol="$(echo "$opts" | sed -nE 's/^.*\bsubvol=([^,]+)\b.*$/\1/p')"
+    if [ -z "$subvol" ]; then
+        echo "Unknown subvol for mountpoint: $mnt"
+        exit 1
+    fi
+    echo "/.snapshots/tmp-bsnap-${subvol}"
+}
+
+if [ "$(id -u)" -ne 0 ]; then
+    echo "Must be root"
+    exit 1
+fi
+
+if [ "${1:-}" = "off" ]; then
+    unsnap
+elif [ "${1:-}" = "on" ]; then
+    snap
+else
+    echo "Usage: $0 on|off"
+    exit 1
+fi
diff --git a/etc/bluetooth/main.conf b/etc/bluetooth/main.conf
new file mode 100644 (file)
index 0000000..6b22089
--- /dev/null
@@ -0,0 +1,6 @@
+[General]
+Name = %h
+#Class = 0x200420 # Bluetooth audio receiver
+
+[Policy]
+AutoEnable = true
diff --git a/etc/default/grub b/etc/default/grub
new file mode 100644 (file)
index 0000000..636e90b
--- /dev/null
@@ -0,0 +1,6 @@
+GRUB_DEFAULT=0
+GRUB_TIMEOUT=3
+GRUB_GFXMODE=1024x768x32,auto
+GRUB_GFXPAYLOAD_LINUX=keep
+GRUB_CMDLINE_LINUX="root=LABEL=btrfsroot cryptopts=target=crypt-btrfsroot,source=/dev/disk/by-partlabel/LUKSROOT,luks,discard"
+GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
diff --git a/etc/modprobe.d/apple-keyboard.conf b/etc/modprobe.d/apple-keyboard.conf
new file mode 100644 (file)
index 0000000..3fe75a7
--- /dev/null
@@ -0,0 +1 @@
+options hid_apple fnmode=2 swap_opt_cmd=1
diff --git a/etc/nginx/nginx.conf b/etc/nginx/nginx.conf
new file mode 100644 (file)
index 0000000..cd5cf36
--- /dev/null
@@ -0,0 +1,21 @@
+user http;
+worker_processes 1;
+
+events {
+    worker_connections 1024;
+}
+
+http {
+    include mime.types;
+    default_type application/octet-stream;
+
+    sendfile on;
+    tcp_nopush on;
+    tcp_nodelay on;
+    keepalive_timeout 65;
+
+    access_log syslog:server=unix:/dev/log,tag=nginx,nohostname,severity=info combined;
+    error_log  syslog:server=unix:/dev/log,tag=nginx,nohostname,severity=error;
+
+    include sites-enabled/*;
+}
diff --git a/etc/nginx/sites-available/default b/etc/nginx/sites-available/default
new file mode 100644 (file)
index 0000000..e79ef07
--- /dev/null
@@ -0,0 +1,6 @@
+server {
+    include snippets/listen-http.conf;
+    include snippets/listen-tls.conf;
+
+    return 404;
+}
diff --git a/etc/nginx/sites-available/example.com b/etc/nginx/sites-available/example.com
new file mode 100644 (file)
index 0000000..f40514b
--- /dev/null
@@ -0,0 +1,15 @@
+server {
+    include snippets/listen-tls.conf;
+    server_name example.com;
+
+    root /srv/http/example.com;
+
+    include snippets/standard-server.conf;
+}
+
+server {
+    include snippets/listen-http.conf;
+    server_name example.com;
+
+    return 301 https://example.com$request_uri;
+}
diff --git a/etc/nginx/sites-enabled/0000_default b/etc/nginx/sites-enabled/0000_default
new file mode 120000 (symlink)
index 0000000..6d9ba33
--- /dev/null
@@ -0,0 +1 @@
+../sites-available/default
\ No newline at end of file
diff --git a/etc/nginx/snippets/listen-http.conf b/etc/nginx/snippets/listen-http.conf
new file mode 100644 (file)
index 0000000..76cb18d
--- /dev/null
@@ -0,0 +1,2 @@
+listen 80;
+listen [::]:80;
diff --git a/etc/nginx/snippets/listen-tls.conf b/etc/nginx/snippets/listen-tls.conf
new file mode 100644 (file)
index 0000000..26eb327
--- /dev/null
@@ -0,0 +1,14 @@
+listen 443 ssl;
+listen [::]:443 ssl;
+
+ssl_certificate /home/letsencrypt/output/latest.pem;
+ssl_certificate_key /home/letsencrypt/domain-key.pem;
+
+# https://wiki.mozilla.org/Security/Server_Side_TLS
+ssl_protocols TLSv1.2;
+ssl_prefer_server_ciphers on;
+ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
+
+add_header "Strict-Transport-Security" "max-age=7776000; includeSubdomains" always;
+add_header X-Frame-Options "DENY" always;
+add_header Content-Security-Policy "upgrade-insecure-requests" always;
diff --git a/etc/nginx/snippets/standard-server.conf b/etc/nginx/snippets/standard-server.conf
new file mode 100644 (file)
index 0000000..46fa4c2
--- /dev/null
@@ -0,0 +1,28 @@
+location ~ /\.git/ {
+    return 403;
+}
+
+
+location = /favicon.ico {
+    log_not_found off;
+    access_log off;
+}
+
+location ~ /apple-touch-icon[^/]*.png {
+    log_not_found off;
+    access_log off;
+}
+
+location = /robots.txt {
+    log_not_found off;
+    access_log off;
+}
+
+location /.well-known/acme-challenge {
+    alias /home/letsencrypt/web-acme-challenge;
+    auth_basic off;
+}
+
+location /healthcheck {
+    return 200;
+}
diff --git a/etc/smartd.conf b/etc/smartd.conf
new file mode 100644 (file)
index 0000000..aef7dc4
--- /dev/null
@@ -0,0 +1 @@
+DEVICESCAN -d removable -H -l error -l selftest -f -s (O/../.././(00|06|12|18)|S/../.././01|L/../../6/03) -m root
diff --git a/etc/ssh/sshd_config b/etc/ssh/sshd_config
new file mode 100644 (file)
index 0000000..5815f44
--- /dev/null
@@ -0,0 +1,15 @@
+LogLevel INFO
+Port 22
+
+
+AuthenticationMethods publickey
+HostKey /etc/ssh/ssh_host_ed25519_key
+HostKeyAlgorithms ssh-ed25519
+PubkeyAcceptedKeyTypes ssh-ed25519
+UsePAM yes
+
+AllowUsers root
+PermitRootLogin prohibit-password
+
+Subsystem sftp internal-sftp
+AcceptEnv LANG LC_* COLORFGBG
diff --git a/etc/sudoers.d/10_env_keep b/etc/sudoers.d/10_env_keep
new file mode 100644 (file)
index 0000000..7d84d0e
--- /dev/null
@@ -0,0 +1,9 @@
+Defaults umask=0022
+Defaults umask_override
+
+Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET"
+Defaults env_keep += "COLORFGBG"
+Defaults env_keep += "EDITOR"
+
+Defaults>root env_keep += "HOME"
+Defaults>root env_keep += "SSH_AUTH_SOCK SSH_AGENT_PID"
diff --git a/etc/sudoers.d/20_sudo_group b/etc/sudoers.d/20_sudo_group
new file mode 100644 (file)
index 0000000..5e3c1bb
--- /dev/null
@@ -0,0 +1 @@
+%sudo ALL=(ALL) ALL
diff --git a/etc/sudoers.d/30_aptitude b/etc/sudoers.d/30_aptitude
new file mode 100644 (file)
index 0000000..6390ee8
--- /dev/null
@@ -0,0 +1 @@
+%sudo ALL = NOPASSWD: /usr/bin/aptitude update, /usr/bin/aptitude full-upgrade
diff --git a/etc/sudoers.d/30_pacman b/etc/sudoers.d/30_pacman
new file mode 100644 (file)
index 0000000..7d0460c
--- /dev/null
@@ -0,0 +1 @@
+%sudo ALL = NOPASSWD: /usr/bin/pacman -Syu
diff --git a/etc/sudoers.d/40_podman b/etc/sudoers.d/40_podman
new file mode 100644 (file)
index 0000000..3029bfc
--- /dev/null
@@ -0,0 +1 @@
+%sudo ALL = NOPASSWD: /usr/bin/podman *
diff --git a/etc/systemd/network/ethernet.network b/etc/systemd/network/ethernet.network
new file mode 100644 (file)
index 0000000..0e8ac70
--- /dev/null
@@ -0,0 +1,8 @@
+[Match]
+Name=en* eth*
+
+[Network]
+DHCP=yes
+IPv6PrivacyExtensions=yes
+
+#Address=fdXX:YYYY:YYYY::XXXX/64
diff --git a/etc/systemd/resolved.conf b/etc/systemd/resolved.conf
new file mode 100644 (file)
index 0000000..99b029b
--- /dev/null
@@ -0,0 +1,6 @@
+# See resolved.conf(5) for details
+
+[Resolve]
+DNSSEC=no
+LLMNR=no
+MulticastDNS=no
diff --git a/etc/systemd/system/my-overrides/10-security.conf b/etc/systemd/system/my-overrides/10-security.conf
new file mode 100644 (file)
index 0000000..c8fe6e2
--- /dev/null
@@ -0,0 +1,27 @@
+[Service]
+# Never accessible to any services
+InaccessiblePaths=/mnt
+
+# By default inaccessible, may be overriden with BindPaths/BindReadOnlyPaths
+TemporaryFileSystem=/home:ro
+
+NoNewPrivileges=yes
+
+MountFlags=private
+ProtectSystem=strict
+ProtectKernelTunables=yes
+ProtectKernelModules=yes
+ProtectControlGroups=yes
+PrivateTmp=yes
+PrivateDevices=yes
+
+RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+RestrictRealtime=yes
+RestrictNamespaces=yes
+MemoryDenyWriteExecute=yes
+RestrictSUIDSGID=yes
+
+CapabilityBoundingSet=~CAP_SYS_ADMIN
+SystemCallFilter=@system-service
+SystemCallErrorNumber=EPERM
+SystemCallArchitectures=native
diff --git a/etc/udev/rules.d/10-network.rules b/etc/udev/rules.d/10-network.rules
new file mode 100644 (file)
index 0000000..07d5859
--- /dev/null
@@ -0,0 +1,2 @@
+SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:00:00:00:00:00", NAME="ethernet"
+SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:00:00:00:00:00", NAME="wifi"
diff --git a/hacks/backup-openwrt b/hacks/backup-openwrt
new file mode 100755 (executable)
index 0000000..59b8640
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+BACKUP_HOSTS="$(awk '/^Host.*openwrt/ {print $2}' < ~/.ssh/config)"
+
+cd ~/backup-openwrt/
+
+for host in $BACKUP_HOSTS; do
+    file="${host}.backup.tar.gz"
+    ssh "$host" sysupgrade -b - > "${file}.new" && mv "${file}.new" "${file}"
+done
+
diff --git a/hacks/dmsetup-hack b/hacks/dmsetup-hack
new file mode 100755 (executable)
index 0000000..a4a334c
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+DEVNAME="ST3000DM001-Z1F4RTWN_then_WD15EADS-WMAVU0714940"
+echo -e '0 5858433934 linear /dev/disk/by-id/ata-ST3000DM001-1CH166_Z1F4RTWN-part3 0\n5858433934 2928175821 linear /dev/nbd0 0' > "/tmp/$DEVNAME"
+dmsetup create "$DEVNAME" --verbose --table "/tmp/$DEVNAME"
+
diff --git a/hacks/fix-openwrt-hairpin b/hacks/fix-openwrt-hairpin
new file mode 100755 (executable)
index 0000000..7428461
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# /etc/crontabs/root
+# m  h dom mon dow command
+# *  *  *   *   *  /root/fix-openwrt-hairpin
+
+for f in /sys/devices/virtual/net/*/*wlan*/brport/hairpin_mode; do
+    if [ -f $f ]; then
+        echo 1 > "$f"
+    fi
+done
diff --git a/hacks/git-no-husky b/hacks/git-no-husky
new file mode 100755 (executable)
index 0000000..7ed9144
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if [ "$1" = "config" ] && [ -z "${GIT_CONFIG_ENABLE}" ] && ! [[ "$2" =~ --get ]]; then
+    echo "Ignoring git $*"
+    exit 0
+fi
+
+/usr/bin/git "$@"
index f90faba007b2719b37a8b2a6eecf0f00b88b4dfb..4a1d11988e925546687963da232871e84ac235fb 100644 (file)
@@ -7,6 +7,9 @@ function cryptsetup_open {
         fi
         DISKNAME="$(basename "$DEVICE")"
         CRYPTNAME="crypt-$DISKNAME"
+        if [ -L "/run/ext-backup-crypt/$CRYPTNAME" ]; then
+            continue
+        fi
         echo "> cryptsetup luksOpen $DEVICE $CRYPTNAME"
         cryptsetup luksOpen "$DEVICE" "$CRYPTNAME" --key-file "/etc/lukskeys/${DISKNAME}"
         mkdir -p /run/ext-backup-crypt/
@@ -48,7 +51,7 @@ function pool_export {
 }
 
 function pool_setup {
-    zpool set failmode=continue "$ZPOOLNAME"
+    zpool set failmode=wait "$ZPOOLNAME"
     zfs set mountpoint="/mnt/$ZPOOLNAME" "$ZPOOLNAME"
     chmod 0700 "/mnt/$ZPOOLNAME"
     zfs set compression=lz4 "$ZPOOLNAME"
@@ -74,11 +77,16 @@ function pool_maybe_scrub {
     echo "> zpool scrub $ZPOOLNAME"
     zpool scrub "$ZPOOLNAME"
 
-    while zpool status "$ZPOOLNAME" | grep -q "scrub in progress"; do
+    while zpool status "$ZPOOLNAME" | awk '/state: ONLINE|scan: scrub in progress/ {x++} END {exit x-2}'; do
         echo -n .
         sleep 60
     done
     echo " done"
+
+    if zpool list -H -o health "$ZPOOLNAME" | grep -qv ONLINE; then
+        zpool status -v "$ZPOOLNAME"
+        return 1
+    fi
 }
 
 function syncoidw {
@@ -96,6 +104,19 @@ function snapshot_cleanup {
         | xargs -rn1 zfs destroy -v
 }
 
+function snapshot_convert_to_bookmarks {
+    local fs
+    local snap
+
+    for fs in "$@"; do
+        for snap in $(zfs list -H -o name -t snapshot -r "$fs"); do
+            echo "> zfs bookmark $snap"
+            zfs bookmark "$snap" "${snap/@/#}"
+            zfs destroy "$snap"
+        done
+    done
+}
+
 function main {
     zfs get all -s local -H > /root/zfs-props.txt
     cryptsetup_open
index 93842dbbeeb61cc8bc218b4277096052bd8d71f3..30bbe589cf04b9cc88da6662f944f2310568e324 100755 (executable)
@@ -2,8 +2,9 @@
 
 set -eu
 
-PARTITION_LABEL="multiboot"
-MULTIBOOT_MNT="/mnt/multiboot"
+PARTITION_LABEL_ESP="multibt-esp"
+PARTITION_LABEL_DATA="multiboot"
+MULTIBOOT_MNT="${MULTIBOOT_MNT:-/mnt/multiboot}"
 
 function cmd_format {
     if [ ! -b "${1:-}" ]; then
@@ -14,9 +15,21 @@ function cmd_format {
 
     sudo -k
     DISK_DEVICE="$1"
-    PARTITION_DEVICE="${DISK_DEVICE}1"
-    echo -ne 'label: dos\ntype=c, bootable\n' | sudo sfdisk "$DISK_DEVICE"
-    sudo mkfs.vfat -n "$PARTITION_LABEL" "$PARTITION_DEVICE"
+    print_sfdisk_command | sudo sfdisk --wipe always --wipe-partitions always "$DISK_DEVICE"
+    udevadm settle
+    sudo mkfs.vfat -n "${PARTITION_LABEL_ESP}" "/dev/disk/by-partlabel/${PARTITION_LABEL_ESP}"
+    sudo mkfs.ext4 -L "${PARTITION_LABEL_DATA}" -E "root_owner=$(id -u):$(id -g)" "/dev/disk/by-partlabel/${PARTITION_LABEL_DATA}"
+}
+
+function print_sfdisk_command {
+    cat <<EOT
+label: gpt
+unit: sectors
+
+size=10M, type=uefi, name="$PARTITION_LABEL_ESP"
+size=1M, type=21686148-6449-6E6F-744E-656564454649
+type=linux, name="$PARTITION_LABEL_DATA"
+EOT
 }
 
 function cmd_grub {
@@ -51,29 +64,37 @@ function install_grub_efi {
             --target="$arch" \
             --no-nvram \
             --removable \
-            --efi-directory="$MULTIBOOT_MNT" \
+            --efi-directory="${MULTIBOOT_MNT}/EFI" \
             --boot-directory="$MULTIBOOT_MNT" \
             "$DISK_DEVICE"
     done
 }
 
 function install_grub_cfg {
-    print_grub_cfg | sudo tee "${MULTIBOOT_MNT}/grub/grub.cfg" > /dev/null
+    if [[ -w "${MULTIBOOT_MNT}/grub/" ]]; then
+        # We already have write access, no need to use sudo
+        print_grub_cfg > "${MULTIBOOT_MNT}/grub/grub.cfg"
+    else
+        print_grub_cfg | sudo tee "${MULTIBOOT_MNT}/grub/grub.cfg" > /dev/null
+    fi
 }
 
 function cmd_mount {
     set -x
 
-    PARTITION_DEVICE="$(readlink -f "/dev/disk/by-label/${PARTITION_LABEL}")"
+    while sudo umount "/dev/disk/by-partlabel/${PARTITION_LABEL_ESP}" &> /dev/null; do true; done
+    while sudo umount "/dev/disk/by-partlabel/${PARTITION_LABEL_DATA}" &> /dev/null; do true; done
     sudo mkdir -p "$MULTIBOOT_MNT"
-    while sudo umount "$PARTITION_DEVICE" &> /dev/null; do true; done
-    sudo mount "$PARTITION_DEVICE" "$MULTIBOOT_MNT" -o "uid=$(whoami)"
+    sudo mount "/dev/disk/by-partlabel/${PARTITION_LABEL_DATA}" "$MULTIBOOT_MNT"
+    mkdir -p "${MULTIBOOT_MNT}/EFI"
+    sudo mount "/dev/disk/by-partlabel/${PARTITION_LABEL_ESP}" "${MULTIBOOT_MNT}/EFI"
 }
 
 function cmd_umount {
     set -x
 
-    sudo umount "$MULTIBOOT_MNT"
+    sudo umount "${MULTIBOOT_MNT}/EFI" || true
+    sudo umount "$MULTIBOOT_MNT" || true
     sudo rmdir "$MULTIBOOT_MNT"
 }
 
@@ -82,7 +103,7 @@ function cmd_freedos {
 
     local SYSLINUX_VERSION="6.03"
     local SYSLINUX_URL="https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz"
-    local FREEDOS_URL="http://www.freedos.org/download/download/FD12LITE.zip"
+    local FREEDOS_URL="https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.2/official/FD12LITE.zip"
 
     curl -fL "$SYSLINUX_URL" | \
         tar xz --no-same-owner --strip-components=3 -C "$MULTIBOOT_MNT" \
@@ -92,26 +113,48 @@ function cmd_freedos {
 }
 
 function cmd_memtest {
-    curl -fL "https://www.memtest.org/download/5.01/memtest86+-5.01.bin.gz" | \
-        zcat - > "${MULTIBOOT_MNT}/memtest.bin"
+    curl -fL -o "${MULTIBOOT_MNT}/memtest.tmp.zip" "https://memtest.org/download/v6.20/mt86plus_6.20_64.grub.iso.zip"
+    unzip -d "$MULTIBOOT_MNT" "${MULTIBOOT_MNT}/memtest.tmp.zip"
+    rm "${MULTIBOOT_MNT}/memtest.tmp.zip"
 }
 
 function print_grub_cfg {
     cat <<EOT
+search --set=root --label $PARTITION_LABEL_DATA
+
 insmod all_video
+insmod gfxterm
+loadfont unicode
+set gfxmode=1024x768
+terminal_output gfxterm
+
 insmod part_msdos
 insmod progress
 insmod regexp
-search --set=root --label $PARTITION_LABEL
+
+set maybe_quiet='quiet splash'
+set maybe_to_ram=''
+
+menuentry "! Copy ISO image to ram before booting" {
+  # copytoram is used by arch
+  # toram is used by casper based images (tails, Ubuntu, etc)
+  set maybe_to_ram="copytoram toram"
+}
+
+menuentry "! Verbose" {
+  set maybe_quiet=''
+}
 
 function setup_arch {
   menuentry "\$1" {
     loopback loop \$1
-    linux (loop)/arch/boot/x86_64/vmlinuz img_label=${PARTITION_LABEL} img_loop=\$1 archisobasedir=arch earlymodules=loop
-    initrd (loop)/arch/boot/x86_64/archiso.img
+    echo "Loading kernel..."
+    linux (loop)/arch/boot/x86_64/vmlinuz-* img_label=${PARTITION_LABEL_DATA} img_loop=\$1 archisobasedir=arch earlymodules=loop \$maybe_to_ram \$maybe_quiet
+    echo "Loading initrd (and microcode if they exist)..."
+    initrd (loop)/arch/boot/*.img (loop)/arch/boot/x86_64/initramfs-*.img
   }
 }
-for iso in /archlinux-*.iso; do
+for iso in /archlinux-*.iso /isos/archlinux-*.iso; do
   if [ -f "\$iso" ]; then
     setup_arch \$iso
   fi
@@ -119,13 +162,16 @@ done
 
 function setup_debian {
   menuentry "\$1" {
-    linux \$1/vmlinuz
-    initrd \$1/initrd.gz
+    loopback loop \$1
+    echo "Loading kernel..."
+    linux (loop)/live/vmlinuz* boot=live components findiso=\$1 \$maybe_to_ram \$maybe_quiet
+    echo "Loading initrd..."
+    initrd (loop)/live/initrd*
   }
 }
-for d in /debian-*-hd-media; do
-  if [ -d "\$d" ]; then
-    setup_debian \$d
+for iso in /debian-live-*.iso /isos/debian-live-*.iso; do
+  if [ -f "\$iso" ]; then
+    setup_debian \$iso
   fi
 done
 
@@ -141,21 +187,35 @@ if [ -f /memdisk -a -f /FD12LITE.zip ]; then
   }
 fi
 
-if [ -f /memtest.bin ]; then
-  menuentry "/memtest" {
-    linux16 /memtest.bin
+
+function setup_memtest {
+  menuentry "\$1" {
+    loopback loop \$1
+    if [ \${grub_platform} = pc ]; then
+      linux (loop)/boot/memtest
+    else
+      linux (loop)/EFI/BOOT/memtest
+    fi
   }
-fi
+}
+for iso in /mt86plus*.grub.iso /isos/mt86plus*.grub.iso; do
+  if [ -f "\$iso" ]; then
+    setup_memtest \$iso
+  fi
+done
+
 
 function setup_fedora {
   menuentry "\$1" {
     loopback loop \$1
     probe -s iso_label -l (loop)
-    linux (loop)/isolinux/vmlinuz root=live:CDLABEL=\$iso_label rd.live.image quiet iso-scan/filename=\$1
-    initrd (loop)/isolinux/initrd.img
+    echo "Loading kernel..."
+    linux (loop)/images/pxeboot/vmlinuz root=live:CDLABEL=\$iso_label rd.live.image iso-scan/filename=\$1 \$maybe_quiet
+    echo "Loading initrd..."
+    initrd (loop)/images/pxeboot/initrd.img
   }
 }
-for iso in /Fedora-Workstation-Live-*.iso; do
+for iso in /Fedora-Workstation-Live-*.iso /isos/Fedora-Workstation-Live-*.iso; do
   if [ -f "\$iso" ]; then
     setup_fedora \$iso
   fi
@@ -164,16 +224,41 @@ done
 function setup_ubuntu {
   menuentry "\$1" {
     loopback loop \$1
-    linux (loop)/casper/vmlinuz* boot=casper quiet iso-scan/filename=\$1
+    set maybe_layerfs_path=''
+    for f in minimal.standard.live.squashfs; do
+      if [ -f "(loop)/casper/\$f" ]; then
+        echo " \$f"
+        set maybe_layerfs_path="layerfs-path=\$f"
+        echo "Setting \$maybe_layerfs_path"
+      fi
+    done
+    echo "Loading kernel..."
+    linux (loop)/casper/vmlinuz* \$maybe_layerfs_path boot=casper iso-scan/filename=\$1 \$maybe_to_ram \$maybe_quiet
+    echo "Loading initrd..."
     initrd (loop)/casper/initrd*
   }
 }
-for iso in /ubuntu-*-desktop-*.iso; do
+for iso in /ubuntu-*-desktop-*.iso /isos/ubuntu-*-desktop-*.iso; do
   if [ -f "\$iso" ]; then
     setup_ubuntu \$iso
   fi
 done
 
+function setup_tails {
+  menuentry "\$1" {
+    loopback loop \$1
+    echo "Loading kernel..."
+    linux (loop)/live/vmlinuz* initrd=/live/initrd.img boot=live config iso-scan/filename=\$1 findiso=\$1 nopersistence noprompt timezone=Etc/UTC noautologin module=Tails slab_nomerge slub_debug=FZP mce=0 vsyscall=none page_poison=1 init_on_free=1 mds=full,nosmt \$maybe_to_ram \$maybe_quiet
+    echo "Loading initrd..."
+    initrd (loop)/live/initrd*
+  }
+}
+for iso in /tails-*.iso /isos/tails-*.iso; do
+  if [ -f "\$iso" ]; then
+    setup_tails \$iso
+  fi
+done
+
 EOT
 }
 
index fe083cc5eb0206c50ea5d461bde7efa428390fba..c40a490e357b6aa1abbbbf0a84345f5b0c4eb3ac 100755 (executable)
@@ -3,16 +3,6 @@
 set -eu
 
 hostname="$(basename "$0")"
-local_hostname="${hostname}.localnet"
-public_hostname="p${hostname}"
-
-if grep -Eq "^Host ${hostname}\b" ~/.ssh/config; then
-    true
-elif ping -c1 -t1 "$local_hostname" &> /dev/null; then
-    hostname="$local_hostname"
-else
-    hostname="$public_hostname"
-fi
 
 while true; do
     clear
diff --git a/hacks/syncthing-healthcheck b/hacks/syncthing-healthcheck
new file mode 100755 (executable)
index 0000000..ffc668e
--- /dev/null
@@ -0,0 +1,94 @@
+#!/usr/bin/env node
+
+/* eslint-env es2020 */
+
+const API_URL = process.env.API_URL;
+const API_KEY = process.env.API_KEY;
+const VERBOSE = !!process.env.VERBOSE;
+
+async function main() {
+    const config = await fetchConfig();
+    const devicesStatus = await fetchDevicesStatus();
+    const connectionsStatus = await fetchConnections();
+
+    for (const {deviceID, name} of config.devices) {
+        const {connected} = connectionsStatus.connections[deviceID];
+        const {lastSeen: lastSeenString} = devicesStatus[deviceID];
+        const lastSeenDate = new Date(lastSeenString);
+        const {completion, needItems} = await fetchCompletion(deviceID);
+        //console.log(name, await fetchCompletion(deviceID));
+
+        checkDevice({name, connected, lastSeenDate, completion, needItems});
+    }
+}
+
+async function checkDevice({name, connected, lastSeenDate, completion, needItems}) {
+    if (VERBOSE) {
+        console.error('checkDevice', {name, connected, lastSeenDate, completion, needItems});
+    }
+
+    if (lastSeenDate.getTime() === 0 || connected) {
+        return;
+    }
+
+    if (lastSeenDate < newDateDays(-10)) {
+        console.log(`Alert! '${name}' has been missing since ` +
+                lastSeenDate.toISOString().replace(/T.*/, ''));
+    }
+    if (needItems > 0 || completion < 100) {
+        console.log(`Alert! '${name}' is out of sync! ` +
+                `${Math.round(completion)}%, missing ${needItems} files.`);
+    }
+}
+
+function newDateDays(days) {
+    return new Date(Date.now() + days * 24 * 3600 * 1000);
+}
+
+async function fetchConfig() {
+    const response = await fetchSyncthing('/rest/config');
+    await assertResponseOk(response);
+    return response.json();
+}
+
+async function fetchDevicesStatus() {
+    const response = await fetchSyncthing('/rest/stats/device');
+    await assertResponseOk(response);
+    return response.json();
+}
+
+async function fetchConnections() {
+    const response = await fetchSyncthing('/rest/system/connections');
+    await assertResponseOk(response);
+    return response.json();
+}
+
+async function fetchCompletion(deviceID) {
+    const response = await fetchSyncthing(`/rest/db/completion?device=${deviceID}`);
+    await assertResponseOk(response);
+    return response.json();
+}
+
+async function fetchSyncthing(path) {
+    return fetch(`${API_URL}${path}`, {
+        headers: {
+            'X-API-Key': API_KEY,
+        }
+    });
+}
+
+async function assertResponseOk(response) {
+    if (response.ok) {
+        return;
+    }
+    throw new Error(
+        'Response error! ' +
+            response.status + ' ' + response.statusText +
+            ' -- ' + (await response.text())
+    );
+}
+
+main().catch((err) => {
+    console.error('Exiting due to error!', err);
+    process.exit(1);
+});
index 12eac5e5f9048422231561f6b89cd03928299667..e5a12c3a1cfeffe39fe672a51920a8183b298579 100755 (executable)
@@ -9,7 +9,7 @@ cd "$(dirname "$(readlink -f "$0")")"
 for i in ./*; do
     if [ "$(basename "$i")" != "$(basename "$0")" ]; then
         if ! "$i"; then
-            echo -e "\n^^ FAILED! $(hostname) $PRETTY_NAME -- $i ^^\n"
+            echo -e "\n^^ FAILED! $(cat /etc/hostname) $PRETTY_NAME -- $i ^^\n"
             exit 1
         fi
     fi
diff --git a/healthcheck/systemd-user-timers b/healthcheck/systemd-user-timers
deleted file mode 100755 (executable)
index e4679e7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-cd ~/.config/systemd/user/ &> /dev/null || exit 0
-
-error=0
-for timer in *.timer; do
-    if ! systemctl --user is-enabled "$timer" > /dev/null; then
-        echo "disabled timer $timer"
-        error=1
-    fi
-    if ! systemctl --user is-active "$timer" > /dev/null; then
-        echo "inactive timer $timer"
-        error=1
-    fi
-done
-
-exit "$error"
index ddc155189a74046793146a3b7d7f9ea4e21ffd8d..4322734ff9f2e4b795bb8a7018c81737b6b7c18f 100755 (executable)
@@ -1,9 +1,34 @@
 #!/bin/bash
 
-if systemctl --user is-system-running > /dev/null; then
-    exit 0
-fi
+users="$(systemctl list-units | \
+    sed -nE 's/.*user@([0-9]+)\.service .*loaded active running.*/\1/p' | \
+    xargs -n1 id -un)"
 
-echo -e "# systemctl --user --failed"
-systemctl --user --failed
-exit 1
+error=0
+for user in $users; do
+    homedir="$(getent passwd "$user"|cut -d: -f6)"
+    for timer in "$homedir"/.config/systemd/user/*.timer; do
+        if ! [ -f "$timer" ]; then
+            continue
+        fi
+        timerunit="$(basename "$timer")"
+        if ! systemctl --user -M"$user@" is-enabled "$timerunit" > /dev/null; then
+            echo "disabled timer $timer"
+            error=1
+        fi
+        if ! systemctl --user -M"$user@" is-active "$timerunit" > /dev/null; then
+            echo "inactive timer $timer"
+            error=1
+        fi
+    done
+
+    if systemctl --user -M "$user@" is-system-running > /dev/null; then
+        continue
+    fi
+
+    echo -e "# systemctl --user -M "$user@" --failed"
+    systemctl --user -M "$user@" --failed
+    error=1
+done
+
+exit "$error"
diff --git a/hw/MacBookPro11,5/refind.conf b/hw/MacBookPro11,5/refind.conf
new file mode 100644 (file)
index 0000000..55e31c8
--- /dev/null
@@ -0,0 +1,6 @@
+timeout 3
+use_nvram false
+use_graphics_for linux
+
+# Activate Intel integrated GPU
+spoof_osx_version 10.11
diff --git a/hw/MacBookPro11,5/set-intel-gpu-in-efi.sh b/hw/MacBookPro11,5/set-intel-gpu-in-efi.sh
new file mode 100644 (file)
index 0000000..a5a5436
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+EFIVAR='/sys/firmware/efi/efivars/gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9'
+printf '\x07\x00\x00\x00\x00\x00\x00\x00' > "$EFIVAR"
diff --git a/hw/lenovo-m93p/etc/fancontrol b/hw/lenovo-m93p/etc/fancontrol
new file mode 100755 (executable)
index 0000000..19b199d
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# https://www.kernel.org/doc/html/latest/hwmon/it87.html
+# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2cbb9c370fe32b5de5243f7338dc6ce8747d495b
+
+set -eux
+
+modprobe it87
+
+CT="$(grep -l coretemp /sys/class/hwmon/hwmon*/name | head -n1 | xargs dirname)/temp1_input"
+cd "$(grep -l it8792 /sys/class/hwmon/hwmon*/name | head -n1 | xargs dirname)"
+
+grep . pwm1* temp1*
+
+# automatic fan control - the chip seems to ignore these settings
+#echo 2          > pwm1_enable                  # automatic mode
+#echo 1          > pwm1_auto_channels_temp      # temperature channel
+#echo 127000     > pwm1_auto_point1_temp_hyst   # ??
+#echo 127000     > pwm1_auto_point1_temp        # fan off temp
+#echo 127000     > pwm1_auto_point2_temp        # fan start temp
+#echo 127000     > pwm1_auto_point3_temp        # fan max temperature
+#echo 100        > pwm1_auto_start              # start pwm value
+#echo 0          > pwm1_auto_slope              # pwm slope, 1/8th pwm
+
+# manual fan control - magic incantation
+echo 1          > pwm1_enable                   # manual mode
+echo 200000     > pwm1_freq                     # quieter fan
+echo 0          > temp3_type                    # disabled unused sensor
+echo 4          > temp1_type                    # switch sensor to thermistor
+sleep 1                                         # wait for driver to write to chip
+echo 0          > temp1_type                    # disable the sensor
+echo 42         > pwm1                          # set the fan speed
+
+grep . *pwm1* temp1*
+
+set +x
+OLDPWM="$(cat pwm1)"
+while sleep 1; do
+    TEMPC="$(cat "$CT")"
+    if [ "$TEMPC" -ge 85000 ]; then
+        NEWPWM=255
+    elif [ "$TEMPC" -ge 80000 ]; then
+        NEWPWM=180
+    elif [ "$TEMPC" -ge 60000 ]; then
+        NEWPWM=130
+    else
+        NEWPWM=100
+    fi
+    if [ "$OLDPWM" -ne "$NEWPWM" ]; then
+        echo "Fan speed change: OLDPWM=$OLDPWM TEMPC=$TEMPC NEWPWM=$NEWPWM"
+        echo "$NEWPWM" > pwm1
+        OLDPWM="$NEWPWM"
+        sleep 30
+    fi
+done
diff --git a/hw/lenovo-m93p/etc/modprobe.d/it87.conf b/hw/lenovo-m93p/etc/modprobe.d/it87.conf
new file mode 100644 (file)
index 0000000..ea7f363
--- /dev/null
@@ -0,0 +1 @@
+options it87 ignore_resource_conflict=1
diff --git a/hw/lenovo-m93p/etc/systemd/system/fancontrol.service b/hw/lenovo-m93p/etc/systemd/system/fancontrol.service
new file mode 100644 (file)
index 0000000..c5bdb5c
--- /dev/null
@@ -0,0 +1,5 @@
+[Service]
+ExecStart=/etc/fancontrol
+
+[Install]
+WantedBy=multi-user.target
diff --git a/notes/desktop:debian-bookworm.txt b/notes/desktop:debian-bookworm.txt
new file mode 100644 (file)
index 0000000..ce4150e
--- /dev/null
@@ -0,0 +1,109 @@
+THE_DEV=/dev/sda
+THE_HOSTNAME=somehost
+THE_USERNAME=someuser
+
+
+gdisk $THE_DEV
+ESP 200M ef00
+XBOOTLDR 824M
+LUKSROOT
+
+
+vgcreate $THE_HOSTNAME /dev/disk/by-partlabel/LUKSROOT
+lvcreate -L16G -nswap $THE_HOSTNAME
+lvcreate -l100%FREE -nroot $THE_HOSTNAME
+
+mount /dev/mapper/$THE_HOSTNAME-root /mnt/
+cd /mnt/
+btrfs fi label /mnt/ btrfsroot
+btrfs subv create @root
+btrfs subv set-default /mnt/@root
+btrfs subv create @$THE_USERNAME
+btrfs subv create @apt
+btrfs subv create @varlog
+btrfs subv create @vartmp; chmod 1777 @vartmp ; chmod 0755 @root/var/tmp
+umount /mnt/
+mount /dev/mapper/$THE_HOSTNAME-root /mnt/
+
+mkdir -p /mnt/etc/
+cat <<EOT > /mnt/etc/fstab
+LABEL=btrfsroot             /                   btrfs   subvol=@root,discard,compress,nodev             0 0
+LABEL=btrfsroot             /btrfs              btrfs   subvol=/,discard,compress,nodev,nosuid          0 0
+LABEL=btrfsroot             /home/$THE_USERNAME btrfs   subvol=@$THE_USERNAME,discard,compress,nodev,nosuid      0 0
+LABEL=btrfsroot             /var/cache/apt      btrfs   subvol=@apt,discard,compress,nodev,nosuid       0 0
+LABEL=btrfsroot             /var/log            btrfs   subvol=@varlog,discard,compress,nodev,nosuid    0 0
+LABEL=btrfsroot             /var/tmp            btrfs   subvol=@vartmp,discard,compress,nodev,nosuid    0 0
+PARTLABEL=XBOOTLDR          /boot               ext4    discard,nodev,nosuid,noexec                     0 0
+PARTLABEL=ESP               /boot/efi           vfat    discard,nodev,nosuid,noexec                     0 0
+LABEL=swap                  swap                swap    discard                                         0 0
+tmpfs                       /tmp                tmpfs   nosuid,nodev                                    0 0
+EOT
+
+
+debootstrap bookworm /mnt/ https://deb.debian.org/debian
+
+cat <<EOT > /mnt/etc/apt/sources.list
+deb https://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
+deb https://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware
+deb https://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
+EOT
+
+
+for i in /dev /proc /sys /run /tmp; do mount --rbind $i /mnt$i; done
+chroot /mnt/
+mkdir -p /btrfs/ /boot/efi/ /home/$THE_USERNAME /var/cache/apt/ /var/tmp/
+
+
+mkdir /run/systemd/resolve/
+[ -f /run/systemd/resolve/stub-resolv.conf ] || echo 'nameserver 1.1.1.1' > /run/systemd/resolve/stub-resolv.conf
+
+
+echo $THE_HOSTNAME > /etc/hostname
+ln -sf /usr/share/zoneinfo/Australia/Sydney /etc/localtime
+echo do_symlinks=no > /etc/kernel-img.conf
+
+
+dpkg-reconfigure locales
+apt-get install aptitude curl git python3 vim
+
+
+cd /root/
+curl -sSfL https://code.delx.au/p/dotfiles | bash
+exit
+
+
+chroot /mnt/
+cd /root
+
+mkdir /root/bin/
+git clone https://code.delx.au/monosys
+ln -s /root/monosys/bin /root/bin/monosys-bin
+
+mkdir /root/monosys/package-lists/local
+ln -s /root/monosys/package-lists/local /root/.aptorphan
+cd /root/monosys/package-lists/local
+for i in base base-hw desktop-base desktop-gnome desktop-gnome-software desktop-plymouth desktop-printing filesystems multimedia-players wifi; do ln -s ../debian/$i; done
+cp ../debian/system-efi-amd64 .
+
+apt-get update
+aptorphan
+
+systemctl disable ssh
+find /etc/systemd/system -xtype l -delete
+
+mv /etc/default/grub{,.bak}
+cp /root/monosys/etc/default/grub /etc/default/grub
+grub-install
+update-grub
+
+passwd root
+adduser $THE_USER
+gpasswd -a $THE_USER sudo
+
+plymouth-set-default-theme spinner
+
+
+
+# reboot
+
+flatpak remote-add flathub https://dl.flathub.org/repo/flathub.flatpakrepo
diff --git a/notes/flathub.txt b/notes/flathub.txt
new file mode 100644 (file)
index 0000000..272fd08
--- /dev/null
@@ -0,0 +1,5 @@
+flatpak install
+- firefox
+- flatseal
+- libreoffice
+- keepassxc
diff --git a/notes/raspi-headless:debian-bookworm.txt b/notes/raspi-headless:debian-bookworm.txt
new file mode 100644 (file)
index 0000000..db1f0a6
--- /dev/null
@@ -0,0 +1,88 @@
+THE_DEV=/dev/mmcblk0
+THE_HOSTNAME=somehost
+
+
+raspi.debian.net
+xzcat image.xz | pv > $THE_DEV
+
+
+fdisk $THE_DEV
+# resize partition 2
+
+
+btrfs-convert ${THE_DEV}p2
+mount ${THE_DEV}p2 /mnt
+btrfs fi resize max /mnt
+cd /mnt
+rmdir lost+found
+
+btrfs subv create @root
+mv ./* @root/
+mv @root/ext2_saved/ @ext2_saved
+mkdir @root/btrfs
+btrfs subv create @apt; mv @root/var/cache/apt/archives/* @apt/
+btrfs subv create @varlog
+btrfs subv create @vartmp; chmod 1777 @vartmp ; chmod 0755 @root/var/tmp
+btrfs subv set-default @root
+
+cat <<EOT >| @root/etc/fstab
+# <file system>         <dir>                   <type>  <options>                                       <dump><pass>
+LABEL=RASPIROOT         /                       btrfs   subvol=@root,discard,compress,nodev                 2   0
+LABEL=RASPIROOT         /btrfs                  btrfs   subvol=/,discard,compress,nodev,nosuid              0   0
+LABEL=RASPIROOT         /var/cache/apt/archives btrfs   subvol=@apt,discard,compress,nodev,nosuid           0   0
+LABEL=RASPIROOT         /var/log                btrfs   subvol=@varlog,discard,compress,nodev,nosuid        0   0
+LABEL=RASPIROOT         /var/tmp                btrfs   subvol=@vartmp,discard,compress,nodev,nosuid        0   0
+LABEL=RASPIFIRM         /boot/firmware          vfat    discard,nodev,nosuid,noexec                         1   0
+EOT
+
+
+rm @root/initrd.img @root/initrd.img.old @root/vmlinuz @root/vmlinuz.old
+echo 'do_symlinks=no' > @root/etc/kernel-img.conf
+
+rmdir @root/var/log/journal
+find @root/usr/local -type f -print -delete
+find @root/etc/systemd/system -name 'rpi*' -print -delete
+find @root/etc/systemd/system -type d -empty -print -delete
+
+
+echo $THE_HOSTNAME >| @root/etc/hostname
+ln -sf /usr/share/zoneinfo/Australia/Sydney @root/etc/localtime
+echo -n >| @root/etc/motd
+
+
+cp ~/monosys/etc/ssh/sshd_config @root/etc/ssh/sshd_config
+ssh-keygen -f @root/etc/ssh/ssh_host_ed25519_key -t ed25519 -N '' -C ''
+cp ~/.ssh/id_ed25519.pub @root/root/.ssh/authorized_keys
+
+
+# boot
+
+ssh root@192.168.1.XXX
+
+passwd -l root
+dpkg-reconfigure raspi-firmware
+apt-get update
+apt-get install locales
+dpkg-reconfigure locales
+
+apt-get install aptitude curl git python3 vim
+curl -sSfL https://code.delx.au/p/dotfiles | bash
+exit
+ssh root@192.168.1.XXX
+
+mkdir /root/bin/
+git clone https://code.delx.au/monosys
+ln -s /root/monosys/bin /root/bin/monosys-bin
+
+
+cp monosys/etc/systemd/network/ethernet.network /etc/systemd/network/
+systemctl stop networking ; systemctl restart systemd-networkd
+systemctl disable networking ; systemctl enable systemd-networkd
+
+apt-get install aptitude
+mkdir /root/monosys/package-lists/local
+ln -s /root/monosys/package-lists/local /root/.aptorphan
+cd /root/monosys/package-lists/local
+ln -s ../debian/base
+cp ../debian/system-raspi system
+aptorphan
diff --git a/notes/raspi-headless:raspian-bookworm.txt b/notes/raspi-headless:raspian-bookworm.txt
new file mode 100644 (file)
index 0000000..12adc9f
--- /dev/null
@@ -0,0 +1,45 @@
+# https://www.raspberrypi.com/documentation/computers/configuration.html#set-up-a-headless-raspberry-pi
+# https://www.raspberrypi.com/software/operating-systems/
+
+xzcat image.xz | pv > /dev/mmcblk0
+
+mount /dev/mmcblk0p1 /mnt
+touch /mnt/ssh
+echo "pitmp:$(echo 'password1A!' | openssl passwd -6 -stdin)" > /mnt/userconf.txt
+
+# boot
+THE_IP=192.168.1.XXX
+
+ssh-copy-id pitmp@$THE_IP
+ssh pitmp@$THE_IP sudo cp -R ~pitmp/.ssh /root/.ssh
+
+ssh root@$THE_IP
+
+deluser pitmp
+rm -rf /home/pitmp
+
+hostnamectl set-hostname XYZ
+timedatectl set-timezone Australia/Sydney
+localectl set-locale en_AU.UTF-8
+
+rm -rf /var/log/journal
+systemctl restart systemd-journald
+
+rm /initrd.img /initrd.img.old /vmlinuz /vmlinuz.old
+echo 'do_symlinks=no' > /etc/kernel-img.conf
+
+apt-get install git python3 screen vim
+curl -sSfL https://code.delx.au/p/dotfiles | bash
+
+git clone https://code.delx.au/monosys
+
+cp monosys/etc/ssh/sshd_config sshd_config
+(cd /etc/ssh/; rm ssh_host_ecdsa_key ssh_host_ecdsa_key.pub ssh_host_rsa_key ssh_host_rsa_key.pub)
+
+cp monosys/etc/systemd/network/ethernet.network /etc/systemd/network/ethernet.network
+systemctl stop networking
+systemctl start systemd-networkd
+systemctl enable systemd-networkd
+for i in ModemManager NetworkManager avahi-daemon{,.socket} triggerhappy{,.socket} wpa_supplicant udisks2; do systemctl disable --now $i; done
+
+find /etc/systemd/system -xtype l -delete
diff --git a/notes/snapper.txt b/notes/snapper.txt
new file mode 100644 (file)
index 0000000..add3159
--- /dev/null
@@ -0,0 +1,20 @@
+snapper -c root create-config /
+snapper -c $USERNAME create-config /home/$USERNAME
+
+vim /etc/snapper/configs/*
+```
+SUBVOLUME="/"
+FSTYPE="btrfs"
+
+SPACE_LIMIT="0.5"
+FREE_LIMIT="0.2"
+
+TIMELINE_CREATE="yes"
+TIMELINE_CLEANUP="yes"
+TIMELINE_MIN_AGE="1800"
+TIMELINE_LIMIT_HOURLY="10"
+TIMELINE_LIMIT_DAILY="60"
+TIMELINE_LIMIT_WEEKLY="0"
+TIMELINE_LIMIT_MONTHLY="0"
+TIMELINE_LIMIT_YEARLY="0"
+```
diff --git a/package-lists/arch/base b/package-lists/arch/base
new file mode 100644 (file)
index 0000000..57d347e
--- /dev/null
@@ -0,0 +1,73 @@
+# My base
+base
+bash
+bash-completion
+busybox
+coreutils
+cronie
+diffutils
+fdupes
+file
+findutils
+gawk
+git
+grep
+hexedit
+jq
+less
+logrotate
+lsof
+m4
+make
+man-db
+man-pages
+moreutils
+nodejs
+openssh
+pacman
+pacman-contrib
+patch
+perl
+procps-ng
+psmisc
+pv
+python
+python-virtualenv
+renameutils
+ripgrep
+rsync
+screen
+sed
+sqlite
+strace
+sudo
+vim
+which
+yq
+
+# Compression
+bzip2
+cpio
+gzip
+p7zip
+tar
+unrar
+unzip
+xz
+zip
+
+# Network
+curl
+dog
+fping
+iftop
+iperf3
+iproute2
+iputils
+mtr
+nmap
+openbsd-netcat
+speedtest-cli
+tcpdump
+wget
+whois
diff --git a/package-lists/arch/base-devel b/package-lists/arch/base-devel
new file mode 100644 (file)
index 0000000..fbf90cc
--- /dev/null
@@ -0,0 +1,12 @@
+autoconf
+automake
+bison
+cmake
+fakeroot
+flex
+gcc
+gcc-libs
+gdb
+intltool
+libtool
+pkgconf
diff --git a/package-lists/arch/base-hw b/package-lists/arch/base-hw
new file mode 100644 (file)
index 0000000..ae1c443
--- /dev/null
@@ -0,0 +1,15 @@
+atop
+ddrescue
+dmidecode
+ethtool
+fwupd
+gptfdisk
+hdparm
+iotop
+lm_sensors
+lshw
+pciutils
+smartmontools
+sysfsutils
+sysstat
+usbutils
diff --git a/package-lists/arch/bluetooth b/package-lists/arch/bluetooth
new file mode 100644 (file)
index 0000000..991f4fc
--- /dev/null
@@ -0,0 +1,4 @@
+bluez
+bluez-hid2hci
+bluez-libs
+bluez-utils
diff --git a/package-lists/arch/desktop-base b/package-lists/arch/desktop-base
new file mode 100644 (file)
index 0000000..5f75225
--- /dev/null
@@ -0,0 +1,27 @@
+# Desktop base
+d-feet
+dconf-editor
+flatpak
+wev
+xorg-xeyes
+zenity
+
+# Audio
+alsa-firmware
+alsa-lib
+alsa-plugins
+alsa-utils
+pavucontrol
+pipewire-alsa
+pipewire-pulse
+wireplumber
+
+# Fonts
+ttf-dejavu
+ttf-liberation
+ttf-ubuntu-font-family
+
+# Wallpapers
+deepin-wallpapers
+gnome-backgrounds
+mate-backgrounds
diff --git a/package-lists/arch/desktop-gnome b/package-lists/arch/desktop-gnome
new file mode 100644 (file)
index 0000000..9c65ebe
--- /dev/null
@@ -0,0 +1,41 @@
+baobab
+cheese
+eog
+evince
+file-roller
+gdm
+gedit
+gnome-calculator
+gnome-characters
+gnome-color-manager
+gnome-control-center
+gnome-font-viewer
+gnome-keyring
+gnome-menus
+gnome-power-manager
+gnome-screenshot
+gnome-session
+gnome-settings-daemon
+gnome-shell
+gnome-shell-extension-appindicator
+gnome-shell-extensions
+gnome-sound-recorder
+gnome-system-monitor
+gnome-terminal
+gnome-tweaks
+gvfs
+gvfs-afc
+gvfs-gphoto2
+gvfs-mtp
+gvfs-smb
+libappindicator-gtk3
+mutter
+nautilus
+seahorse
+sushi
+tracker3
+tracker3-miners
+qt5-wayland
+qt6-wayland
+wl-clipboard
+xdg-desktop-portal-gnome
diff --git a/package-lists/arch/desktop-printing b/package-lists/arch/desktop-printing
new file mode 100644 (file)
index 0000000..6ca852e
--- /dev/null
@@ -0,0 +1,12 @@
+cups
+ghostscript
+gsfonts
+avahi
+nss-mdns
+
+# drivers
+foomatic-db
+foomatic-db-engine
+foomatic-db-nonfree
+gutenprint
+splix
diff --git a/package-lists/arch/desktop-pulseaudio b/package-lists/arch/desktop-pulseaudio
new file mode 100644 (file)
index 0000000..13283cd
--- /dev/null
@@ -0,0 +1,6 @@
+~pipewire-alsa
+~pipewire-pulse
+~wireplumber
+pulseaudio
+pulseaudio-alsa
+pulseaudio-bluetooth
diff --git a/package-lists/arch/desktop-video b/package-lists/arch/desktop-video
new file mode 100644 (file)
index 0000000..eb790a7
--- /dev/null
@@ -0,0 +1,6 @@
+gst-libav
+gst-plugins-good
+gst-plugins-ugly
+mplayer
+mpv
+vlc
diff --git a/package-lists/arch/desktop-xfce b/package-lists/arch/desktop-xfce
new file mode 100644 (file)
index 0000000..e560b47
--- /dev/null
@@ -0,0 +1,25 @@
+eog
+evince
+file-roller
+gedit
+gnome-system-monitor
+gtk-xfce-engine
+gvfs
+gvfs-mtp
+gvfs-smb
+lightdm
+lightdm-gtk-greeter
+thunar
+thunar-volman
+tumbler
+xfce4-appfinder
+xfce4-datetime-plugin
+xfce4-notifyd
+xfce4-panel
+xfce4-pulseaudio-plugin
+xfce4-session
+xfce4-settings
+xfce4-terminal
+xfdesktop
+xfwm4
+xfwm4-themes
diff --git a/package-lists/arch/desktop-xorg b/package-lists/arch/desktop-xorg
new file mode 100644 (file)
index 0000000..1075a7e
--- /dev/null
@@ -0,0 +1,48 @@
+xdotool
+xf86-input-libinput
+xf86-input-void
+xorg-bdftopcf
+xorg-docs
+xorg-font-util
+xorg-fonts-100dpi
+xorg-fonts-encodings
+xorg-fonts-misc
+xorg-iceauth
+xorg-luit
+xorg-mkfontscale
+xorg-server
+xorg-sessreg
+xorg-setxkbmap
+xorg-smproxy
+xorg-x11perf
+xorg-xauth
+xorg-xbacklight
+xorg-xcmsdb
+xorg-xcursorgen
+xorg-xdpyinfo
+xorg-xdriinfo
+xorg-xev
+xorg-xfontsel
+xorg-xgamma
+xorg-xhost
+xorg-xinput
+xorg-xkbcomp
+xorg-xkbevd
+xorg-xkbutils
+xorg-xkill
+xorg-xlsatoms
+xorg-xlsclients
+xorg-xmodmap
+xorg-xpr
+xorg-xprop
+xorg-xrandr
+xorg-xrdb
+xorg-xrefresh
+xorg-xset
+xorg-xsetroot
+xorg-xvinfo
+xorg-xwd
+xorg-xwininfo
+xorg-xwud
+xsel
+xterm
diff --git a/package-lists/arch/emacs b/package-lists/arch/emacs
new file mode 100644 (file)
index 0000000..815d2b2
--- /dev/null
@@ -0,0 +1,10 @@
+emacs-wayland
+aspell-en
+python-markdown
+shellcheck-bin
+
+python-lsp-server
+python-lsp-black
+python-pyflakes
+
+typescript-language-server
diff --git a/package-lists/arch/filesystems b/package-lists/arch/filesystems
new file mode 100644 (file)
index 0000000..73750e2
--- /dev/null
@@ -0,0 +1,8 @@
+btrfs-progs
+cryptsetup
+dosfstools
+e2fsprogs
+exfat-utils
+lvm2
+ntfs-3g
+xfsprogs
diff --git a/package-lists/arch/podman b/package-lists/arch/podman
new file mode 100644 (file)
index 0000000..4dfeff5
--- /dev/null
@@ -0,0 +1,5 @@
+podman
+buildah
+netavark
+aardvark-dns
+catatonit
diff --git a/package-lists/arch/sanoid b/package-lists/arch/sanoid
new file mode 100644 (file)
index 0000000..e5814f7
--- /dev/null
@@ -0,0 +1,3 @@
+lzop
+mbuffer
+sanoid
diff --git a/package-lists/arch/system-efi-amd64 b/package-lists/arch/system-efi-amd64
new file mode 100644 (file)
index 0000000..7a6d312
--- /dev/null
@@ -0,0 +1,8 @@
+# bootloader
+efibootmgr
+grub
+
+# kernel/drivers
+intel-ucode
+linux-firmware
+linux-lts
diff --git a/package-lists/arch/transcoding b/package-lists/arch/transcoding
new file mode 100644 (file)
index 0000000..bd1a38b
--- /dev/null
@@ -0,0 +1,9 @@
+atomicparsley
+libdvdcss
+exiv2
+fdkaac
+ffmpeg
+handbrake-cli
+imagemagick
+mkvtoolnix-cli
+sox
diff --git a/package-lists/arch/wifi b/package-lists/arch/wifi
new file mode 100644 (file)
index 0000000..ebcfed9
--- /dev/null
@@ -0,0 +1,4 @@
+iw
+networkmanager
+wireguard-tools
+wireless-regdb
diff --git a/package-lists/debian/base b/package-lists/debian/base
new file mode 100644 (file)
index 0000000..8ac919e
--- /dev/null
@@ -0,0 +1,87 @@
+# My base
+acl
+apt-config-auto-update
+apt-utils
+aptitude
+bash-completion
+busybox-static
+ca-certificates
+dbus
+dbus-user-session
+debian-keyring
+debian-security-support
+diffutils
+doc-debian
+eject
+fdupes
+file
+gawk
+git
+hexedit
+info
+initramfs-tools
+jq
+less
+libpam-systemd
+locales
+logrotate
+lsof
+man-db
+manpages
+moreutils
+nano
+netbase
+nodejs
+openssh-client
+openssh-server
+patch
+popularity-contest
+psmisc
+pv
+python3
+renameutils
+ripgrep
+rsync
+screen
+sed
+sqlite3
+strace
+sudo
+systemd-container
+systemd-timesyncd
+time
+tzdata
+uuid-runtime
+vim
+virtualenv
+whiptail
+xxd
+
+# Compression
+bzip2
+cpio
+gzip
+p7zip
+tar
+unzip
+xz-utils
+zip
+
+# Network
+bind9-dnsutils
+curl
+fping
+iftop
+iperf3
+iproute2
+iputils-ping
+mtr-tiny
+netcat-openbsd
+nftables
+nmap
+speedtest-cli
+systemd-resolved
+tcpdump
+telnet
+wget
+whois
diff --git a/package-lists/debian/base-devel b/package-lists/debian/base-devel
new file mode 100644 (file)
index 0000000..d1d2e2d
--- /dev/null
@@ -0,0 +1,4 @@
+build-essential
+fakeroot
+libbsd-dev
+libssl-dev
diff --git a/package-lists/debian/base-hw b/package-lists/debian/base-hw
new file mode 100644 (file)
index 0000000..eac931b
--- /dev/null
@@ -0,0 +1,14 @@
+atop
+dmidecode
+ethtool
+fwupd
+gddrescue
+gdisk
+hdparm
+iotop
+lm-sensors
+lshw
+pciutils
+smartmontools
+sysstat
+usbutils
diff --git a/package-lists/debian/bluetooth b/package-lists/debian/bluetooth
new file mode 100644 (file)
index 0000000..e19ef99
--- /dev/null
@@ -0,0 +1,3 @@
+bluez
+bluez-tools
+pulseaudio-module-bluetooth
diff --git a/package-lists/debian/desktop-base b/package-lists/debian/desktop-base
new file mode 100644 (file)
index 0000000..b586b14
--- /dev/null
@@ -0,0 +1,24 @@
+# Desktop base
+d-feet
+dconf-editor
+flatpak
+wev
+xdg-utils
+zenity
+
+# Audio
+alsa-utils
+paprefs
+pavucontrol
+pulseaudio
+pulseaudio-utils
+
+# Fonts
+fonts-dejavu
+fonts-liberation
+fonts-ubuntu
+ttf-mscorefonts-installer
+
+# Wallpapers
+gnome-backgrounds
+mate-backgrounds
diff --git a/package-lists/debian/desktop-gnome b/package-lists/debian/desktop-gnome
new file mode 100644 (file)
index 0000000..acd247d
--- /dev/null
@@ -0,0 +1,32 @@
+adwaita-icon-theme
+baobab
+cheese
+eog
+evince
+file-roller
+gdm3
+gedit
+gnome-calculator
+gnome-characters
+gnome-color-manager
+gnome-control-center
+gnome-font-viewer
+gnome-keyring
+gnome-menus
+gnome-power-manager
+gnome-screenshot
+gnome-session
+gnome-settings-daemon
+gnome-shell
+gnome-sound-recorder
+gnome-sushi
+gnome-system-monitor
+gnome-terminal
+gnome-tweaks
+gvfs
+gvfs-backends
+gvfs-fuse
+mutter
+nautilus
+nautilus-extension-gnome-terminal
+seahorse
diff --git a/package-lists/debian/desktop-gnome-software b/package-lists/debian/desktop-gnome-software
new file mode 100644 (file)
index 0000000..9ffcbd4
--- /dev/null
@@ -0,0 +1,2 @@
+gnome-software
+gnome-software-plugin-flatpak
diff --git a/package-lists/debian/desktop-plymouth b/package-lists/debian/desktop-plymouth
new file mode 100644 (file)
index 0000000..3045f84
--- /dev/null
@@ -0,0 +1,3 @@
+plymouth
+plymouth-label
+plymouth-themes
diff --git a/package-lists/debian/desktop-printing b/package-lists/debian/desktop-printing
new file mode 100644 (file)
index 0000000..c5b2986
--- /dev/null
@@ -0,0 +1,5 @@
+avahi-daemon
+libnss-mdns
+cups
+cups-pk-helper
+system-config-printer
diff --git a/package-lists/debian/desktop-video b/package-lists/debian/desktop-video
new file mode 100644 (file)
index 0000000..02bd379
--- /dev/null
@@ -0,0 +1,5 @@
+gstreamer1.0-libav
+gstreamer1.0-plugins-good
+gstreamer1.0-plugins-ugly
+mpv
+vlc
diff --git a/package-lists/debian/desktop-xfce b/package-lists/debian/desktop-xfce
new file mode 100644 (file)
index 0000000..ce7aca1
--- /dev/null
@@ -0,0 +1,33 @@
+accountsservice
+desktop-base
+eog
+evince
+file-roller
+gedit
+gnome-icon-theme
+gnome-system-monitor
+gnome-themes-extra
+gtk2-engines-pixbuf
+gtk2-engines-xfce
+gtk3-engines-xfce
+gvfs
+gvfs-backends
+gvfs-bin
+gvfs-fuse
+lightdm
+lightdm-gtk-greeter
+policykit-1
+policykit-1-gnome
+thunar
+thunar-volman
+tumbler
+xfce4-appfinder
+xfce4-datetime-plugin
+xfce4-notifyd
+xfce4-panel
+xfce4-pulseaudio-plugin
+xfce4-session
+xfce4-settings
+xfce4-terminal
+xfdesktop4
+xfwm4
diff --git a/package-lists/debian/desktop-xorg b/package-lists/debian/desktop-xorg
new file mode 100644 (file)
index 0000000..6a434a9
--- /dev/null
@@ -0,0 +1,9 @@
+x11-session-utils
+x11-xserver-utils
+xauth
+xdotool
+xfonts-base
+xsel
+xserver-xorg
+xserver-xorg-video-all
+xterm
diff --git a/package-lists/debian/filesystems b/package-lists/debian/filesystems
new file mode 100644 (file)
index 0000000..36f29cb
--- /dev/null
@@ -0,0 +1,8 @@
+btrfs-progs
+cryptsetup
+dosfstools
+e2fsprogs
+exfatprogs
+lvm2
+ntfs-3g
+xfsprogs
diff --git a/package-lists/debian/system-efi-amd64 b/package-lists/debian/system-efi-amd64
new file mode 100644 (file)
index 0000000..a5cfde2
--- /dev/null
@@ -0,0 +1,11 @@
+# bootloader
+efibootmgr
+grub-efi-amd64
+
+# kernel/drivers
+linux-image-amd64
+intel-microcode
+firmware-linux
+
+# filesystems
+cryptsetup-initramfs
diff --git a/package-lists/debian/system-raspi b/package-lists/debian/system-raspi
new file mode 100644 (file)
index 0000000..a3ae2b7
--- /dev/null
@@ -0,0 +1,6 @@
+# kernel/boot
+linux-image-arm64
+raspi-firmware
+
+# filesystems
+btrfs-progs
diff --git a/package-lists/debian/wifi b/package-lists/debian/wifi
new file mode 100644 (file)
index 0000000..e790093
--- /dev/null
@@ -0,0 +1,5 @@
+iw
+network-manager
+network-manager-gnome
+wireless-regdb
+wpasupplicant
diff --git a/package-lists/ubuntu/base-ubuntu b/package-lists/ubuntu/base-ubuntu
new file mode 100644 (file)
index 0000000..6ab3f2f
--- /dev/null
@@ -0,0 +1,4 @@
+language-pack-en
+software-properties-common
+update-notifier-common
+~apt-config-auto-update
diff --git a/package-lists/ubuntu/desktop-base-ubuntu b/package-lists/ubuntu/desktop-base-ubuntu
new file mode 100644 (file)
index 0000000..c77b4ce
--- /dev/null
@@ -0,0 +1,18 @@
+# Ubuntu desktop base
+language-pack-gnome-en
+
+# Ubuntu wallpapers
+ubuntu-wallpapers-karmic
+ubuntu-wallpapers-lucid
+ubuntu-wallpapers-maverick
+ubuntu-wallpapers-natty
+ubuntu-wallpapers-oneiric
+ubuntu-wallpapers-precise
+ubuntu-wallpapers-quantal
+ubuntu-wallpapers-raring
+ubuntu-wallpapers-saucy
+ubuntu-wallpapers-trusty
+ubuntu-wallpapers-utopic
+ubuntu-wallpapers-vivid
+ubuntu-wallpapers-wily
+ubuntu-wallpapers-xenial