Capture the catalogue modules' remaining files directories and templates at mesh-catalog bb0fe93b for the moved catalogue tests (issue 1379)
Part 4 of 4 of go/testdata/beside.
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# On low battery the machine suspends rather than powering off, at 7 % — s2idle still draws a little,
|
||||
# so it leaves headroom. A drop-in over the package's own UPower.conf, which stays the package's.
|
||||
[UPower]
|
||||
UsePercentageForPolicy=true
|
||||
PercentageLow=15.0
|
||||
PercentageCritical=10.0
|
||||
PercentageAction=7.0
|
||||
CriticalPowerAction=Suspend
|
||||
AllowRiskyCriticalPowerAction=true
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# The touchpad's settings, applied by X every time the device appears — at login and after every
|
||||
# resume, when the device is initialised again. This replaces the predecessor's sleep hook, which ran
|
||||
# xinput after a resume as a named person on a guessed display.
|
||||
Section "InputClass"
|
||||
Identifier "asus-zephyrus-g14 touchpad"
|
||||
MatchIsTouchpad "on"
|
||||
Option "Tapping" "on"
|
||||
Option "NaturalScrolling" "true"
|
||||
Option "AccelSpeed" "0.15"
|
||||
EndSection
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
# The touchpad's settings again after waking, in the operator's session: X applies the module's
|
||||
# input class when the device appears, and this covers a wake that does not initialise it again.
|
||||
# Runs as root from the power module; the reset itself runs as the session's owner.
|
||||
sleep 2
|
||||
owner=$(ps -o user= -C i3 | head -n 1)
|
||||
[ -n "$owner" ] && runuser -u "$owner" -- /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-touchpad reset
|
||||
true
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
# The laptop's own lines in i3 (module asus-zephyrus-g14, novox/hq ADR 0208, ADR 0210). Owned by the
|
||||
# mesh: replaced at every push. Once the controller places contributions to node-display-session
|
||||
# (ADR 0210), these become the module's contribution instead of a file in i3's directory.
|
||||
#
|
||||
# The keys the firmware turns into ordinary key presses. The vendor keys that reach no X client are
|
||||
# triggerhappy's (/etc/triggerhappy/triggers.d/asus-g14.conf): M4 and Fn+F4/F5 for media, Fn+F7/F8 for
|
||||
# the panel, Fn+F10 for the touchpad. The keyboard backlight (Fn+F2/F3) is the firmware's and asusd's.
|
||||
|
||||
# Fn+F6, the screenshot key: the firmware sends Super+Shift+S. Released before it runs, because the
|
||||
# screenshot grabs the pointer to select a region, which fails while the key is still held.
|
||||
bindsym --release $mod+Shift+s exec --no-startup-id $XDG_CONFIG_HOME/i3/scripts/screenshot.sh
|
||||
|
||||
# Fn+F9, the display key: the firmware sends Super+P. Odd workspaces to the panel, even ones to the
|
||||
# external output.
|
||||
bindsym $mod+p exec --no-startup-id /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-display order
|
||||
|
||||
# The keyboard backlight's level, shown when it changes.
|
||||
exec --no-startup-id /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-kbd-notify
|
||||
# The laptop's own lines in i3 (module asus-zephyrus-g14, novox/hq ADR 0208, ADR 0210). Owned by the
|
||||
# mesh: replaced at every push. Once the controller places contributions to node-display-session
|
||||
# (ADR 0210), these become the module's contribution instead of a file in i3's directory.
|
||||
#
|
||||
# The model's panel and touchpad.
|
||||
|
||||
# The internal panel is the primary output, where the bars' tray goes. Which monitors are on and where
|
||||
# is the display server's (autorandr, run at every session start).
|
||||
exec --no-startup-id /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-display primary
|
||||
|
||||
# The touchpad's settings again, by hand. X applies them itself whenever the device appears.
|
||||
bindsym $mod+Shift+x exec --no-startup-id /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-touchpad reset
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# The ROG Zephyrus G14's vendor keys, which reach no X client: media (the M-keys), panel brightness,
|
||||
# and the touchpad key. Each runs this module's own script, as the operator's account.
|
||||
KEY_PROG1 1 /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-session /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-media play-pause
|
||||
KEY_PROG3 1 /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-session /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-media previous
|
||||
KEY_PROG4 1 /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-session /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-media next
|
||||
KEY_BRIGHTNESSDOWN 1 /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-backlight -
|
||||
KEY_BRIGHTNESSDOWN 2 /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-backlight -
|
||||
KEY_BRIGHTNESSUP 1 /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-backlight +
|
||||
KEY_BRIGHTNESSUP 2 /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-backlight +
|
||||
KEY_F21 1 /usr/local/lib/asus-zephyrus-g14/bin/zephyrus-touchpad reset
|
||||
go/testdata/beside/mesh-catalog/modules/asus-zephyrus-g14/templates/modprobe.d/g14-nvidia-power.conf
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# The discrete GPU's driver options on the ROG Zephyrus G14 (GA403, RTX 40 series, hybrid graphics).
|
||||
#
|
||||
# NVreg_DynamicPowerManagement=0x00 turns runtime D3 off. With it on, a change of power source sends
|
||||
# the driver an ACPI notification it fails to handle on this model ("RmHandleDNotifierEvent: Failed to
|
||||
# handle ACPI D-Notifier event, status=0x62"), and the GPU stops making progress until the machine is
|
||||
# powered off. Off costs a few idle watts in hybrid mode and keeps the machine up.
|
||||
#
|
||||
# NVreg_PreserveVideoMemoryAllocations=1 saves video memory across suspend, so what used the GPU still
|
||||
# works after waking. It needs nvidia-suspend, -hibernate and -resume to run around a sleep, which this
|
||||
# module's drop-ins on the sleep services ask for.
|
||||
#
|
||||
# A change here applies when the driver next loads: at the next boot.
|
||||
options nvidia NVreg_PreserveVideoMemoryAllocations=1
|
||||
options nvidia NVreg_DynamicPowerManagement=0x00
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# The ACPI video driver does not change the backlight itself on the brightness keys: on this model it
|
||||
# moves the wrong one. The keys are triggerhappy's (see /etc/triggerhappy/triggers.d/asus-g14.conf).
|
||||
# Applies when the module next loads: at the next boot.
|
||||
options video brightness_switch_enabled=0
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# nvidia-powerd (Dynamic Boost) was the first error in the chain that hung this model's GPU on a change
|
||||
# of power source, and asusd starts it on mains. It runs only when the kernel command line says
|
||||
# zephyrus.nvidia-powerd — an explicit opt-in, at boot.
|
||||
[Unit]
|
||||
ConditionKernelCommandLine=zephyrus.nvidia-powerd
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# The NVIDIA driver's own sleep actions, asked for by the sleep itself rather than enabled as
|
||||
# links: the mesh declares files and never makes links (novox/hq ADR 0012), and the host's service
|
||||
# shape must not start these units by hand, which would put the GPU to sleep with the machine awake.
|
||||
[Unit]
|
||||
Wants=nvidia-hibernate.service nvidia-resume.service
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# The NVIDIA driver's own sleep actions, asked for by the sleep itself rather than enabled as
|
||||
# links: the mesh declares files and never makes links (novox/hq ADR 0012), and the host's service
|
||||
# shape must not start these units by hand, which would put the GPU to sleep with the machine awake.
|
||||
[Unit]
|
||||
Wants=nvidia-suspend-then-hibernate.service nvidia-resume.service
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# The NVIDIA driver's own sleep actions, asked for by the sleep itself rather than enabled as
|
||||
# links: the mesh declares files and never makes links (novox/hq ADR 0012), and the host's service
|
||||
# shape must not start these units by hand, which would put the GPU to sleep with the machine awake.
|
||||
[Unit]
|
||||
Wants=nvidia-suspend.service nvidia-resume.service
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
# Managed by the mesh (module asus-zephyrus-g14). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# The backlights are writable by the video group, so the brightness keys and the module's brightness tool
|
||||
# move the panel without root.
|
||||
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/usr/bin/chgrp video /sys/class/backlight/%k/brightness", RUN+="/usr/bin/chmod g+w /sys/class/backlight/%k/brightness"
|
||||
@@ -0,0 +1,15 @@
|
||||
# Written by the mesh (modules/matrix). Conduit reads this file (CONDUIT_CONFIG); nothing comes
|
||||
# from the environment. server_name is the homeserver's permanent identity: every user id, room id
|
||||
# and signature in the database carries it, so it is the name this module is served under
|
||||
# (${bound:route:name-homeserver}) and never changes once a database exists.
|
||||
[global]
|
||||
server_name = "${bound:route:name-homeserver}"
|
||||
database_backend = "rocksdb"
|
||||
database_path = "/var/lib/matrix-conduit/"
|
||||
address = "0.0.0.0"
|
||||
port = 6167
|
||||
max_request_size = 20000000
|
||||
allow_registration = false
|
||||
allow_federation = true
|
||||
allow_check_for_updates = true
|
||||
trusted_servers = ["matrix.org"]
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"default_server_name": "${bound:route:name-homeserver}",
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://${bound:route:name-homeserver}"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": "https://vector.im"
|
||||
}
|
||||
},
|
||||
"brand": "Element",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
"integrations_widgets_urls": [
|
||||
"https://scalar.vector.im/_matrix/integrations/v1",
|
||||
"https://scalar.vector.im/api",
|
||||
"https://scalar-staging.vector.im/_matrix/integrations/v1",
|
||||
"https://scalar-staging.vector.im/api",
|
||||
"https://scalar-staging.riot.im/scalar/api"
|
||||
],
|
||||
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
|
||||
"uisi_autorageshake_app": "element-auto-uisi",
|
||||
"show_labs_settings": true,
|
||||
"room_directory": {
|
||||
"servers": [
|
||||
"${bound:route:name-homeserver}",
|
||||
"matrix.org",
|
||||
"gitter.im",
|
||||
"libera.chat"
|
||||
]
|
||||
},
|
||||
"enable_presence_by_hs_url": {
|
||||
"https://matrix.org": false,
|
||||
"https://matrix-client.matrix.org": false
|
||||
},
|
||||
"terms_and_conditions_links": [
|
||||
{
|
||||
"url": "https://element.io/privacy",
|
||||
"text": "Privacy Policy"
|
||||
},
|
||||
{
|
||||
"url": "https://element.io/cookie-policy",
|
||||
"text": "Cookie Policy"
|
||||
}
|
||||
],
|
||||
"features": {
|
||||
"feature_video_rooms": true,
|
||||
"feature_rust_crypto": true
|
||||
},
|
||||
"element_call": {
|
||||
"url": "https://call.element.dev"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# systemd-oomd kills the worst unit before the kernel's OOM killer freezes the machine: when swap is
|
||||
# 90 % used, or when a watched unit stalls on memory for 20 s above its limit.
|
||||
[OOM]
|
||||
SwapUsedLimit=90%
|
||||
DefaultMemoryPressureLimit=60%
|
||||
DefaultMemoryPressureDurationSec=20s
|
||||
@@ -0,0 +1,5 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# systemd-oomd may act on swap exhaustion across the whole machine.
|
||||
[Slice]
|
||||
ManagedOOMSwap=kill
|
||||
@@ -0,0 +1,9 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# Swap-in reads one page, not eight: read-ahead exists to amortise a disk's seek, and compressed swap in
|
||||
# RAM has none — the speculation only costs decompression and memory.
|
||||
vm.page-cluster = 0
|
||||
#
|
||||
# vm.swappiness is deliberately left alone. The usual zram advice (150-180) holds only while the
|
||||
# compressed swap has room; once it is full, a higher swappiness moves pages to the disk swap, the thing
|
||||
# being avoided. Raise it only together with zram-size.
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# systemd-oomd may kill the worst unit in a person's service manager when its memory pressure stays
|
||||
# above 80 % — instead of the kernel freezing the machine.
|
||||
[Service]
|
||||
ManagedOOMMemoryPressure=kill
|
||||
ManagedOOMMemoryPressureLimit=80%
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# Compressed swap in RAM: fast, at a higher priority than any swap on disk, so it takes the everyday
|
||||
# pressure before anything spills to a disk. Half the RAM, at most 16 GiB, compressed with zstd.
|
||||
# The swap on disk, its size and whether one exists at all are the machine's, not this module's.
|
||||
#
|
||||
# Read by the generator at boot: a change applies at the next boot.
|
||||
[zram0]
|
||||
zram-size = min(ram / 2, 16384)
|
||||
compression-algorithm = zstd
|
||||
swap-priority = 100
|
||||
@@ -0,0 +1 @@
|
||||
postgresql://${bound:postgres-database:as}:${secret:postgres-database}@${bound:postgres-database:at}:${bound:postgres-database:port}/${bound:postgres-database:as}
|
||||
@@ -0,0 +1,3 @@
|
||||
# The operator's command (module mesh-cli, novox/hq ADR 0272): nox is mesh-cli, in interactive zsh only.
|
||||
# A script, sudo and a document meant to work everywhere say mesh-cli.
|
||||
alias nox=mesh-cli
|
||||
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"first-number": 365,
|
||||
"owners": [
|
||||
"hq",
|
||||
"mesh-catalog",
|
||||
"mesh-catalog modules/adwaita",
|
||||
"mesh-catalog modules/artifact-store-tools",
|
||||
"mesh-catalog modules/asus-zephyrus-g14",
|
||||
"mesh-catalog modules/audit-logger",
|
||||
"mesh-catalog modules/avahi",
|
||||
"mesh-catalog modules/baserow",
|
||||
"mesh-catalog modules/betterbird",
|
||||
"mesh-catalog modules/blueman",
|
||||
"mesh-catalog modules/bluetooth",
|
||||
"mesh-catalog modules/ca-trust",
|
||||
"mesh-catalog modules/claude-code",
|
||||
"mesh-catalog modules/claude-licence-manager",
|
||||
"mesh-catalog modules/clipmenu",
|
||||
"mesh-catalog modules/confluence",
|
||||
"mesh-catalog modules/cups",
|
||||
"mesh-catalog modules/dbus",
|
||||
"mesh-catalog modules/desk-channel",
|
||||
"mesh-catalog modules/disk-load",
|
||||
"mesh-catalog modules/distribution",
|
||||
"mesh-catalog modules/dmenu",
|
||||
"mesh-catalog modules/dnsmasq",
|
||||
"mesh-catalog modules/docker",
|
||||
"mesh-catalog modules/docker-compose",
|
||||
"mesh-catalog modules/dunst",
|
||||
"mesh-catalog modules/fail2ban",
|
||||
"mesh-catalog modules/feh",
|
||||
"mesh-catalog modules/flatpak",
|
||||
"mesh-catalog modules/fonts",
|
||||
"mesh-catalog modules/forticlient",
|
||||
"mesh-catalog modules/gitea",
|
||||
"mesh-catalog modules/gitlab",
|
||||
"mesh-catalog modules/gnome-keyring",
|
||||
"mesh-catalog modules/grafana",
|
||||
"mesh-catalog modules/hello-web",
|
||||
"mesh-catalog modules/home-assistant",
|
||||
"mesh-catalog modules/hostname",
|
||||
"mesh-catalog modules/i3",
|
||||
"mesh-catalog modules/i3status-rust",
|
||||
"mesh-catalog modules/icecast",
|
||||
"mesh-catalog modules/influxdb",
|
||||
"mesh-catalog modules/invoicing",
|
||||
"mesh-catalog modules/jira",
|
||||
"mesh-catalog modules/keycloak",
|
||||
"mesh-catalog modules/lab",
|
||||
"mesh-catalog modules/lemurs",
|
||||
"mesh-catalog modules/letta",
|
||||
"mesh-catalog modules/local-model-consumer",
|
||||
"mesh-catalog modules/localization",
|
||||
"mesh-catalog modules/logrotate",
|
||||
"mesh-catalog modules/mailu",
|
||||
"mesh-catalog modules/marrytts",
|
||||
"mesh-catalog modules/matrix",
|
||||
"mesh-catalog modules/memory-pressure",
|
||||
"mesh-catalog modules/mesh-catalog",
|
||||
"mesh-catalog modules/mesh-cli",
|
||||
"mesh-catalog modules/mesh-delivery",
|
||||
"mesh-catalog modules/mesh-delivery-gate",
|
||||
"mesh-catalog modules/mesh-issues",
|
||||
"mesh-catalog modules/mesh-vault",
|
||||
"mesh-catalog modules/mesh-watcher",
|
||||
"mesh-catalog modules/messenger",
|
||||
"mesh-catalog modules/minio",
|
||||
"mesh-catalog modules/model-usage",
|
||||
"mesh-catalog modules/mongodb",
|
||||
"mesh-catalog modules/mosquitto",
|
||||
"mesh-catalog modules/mounts",
|
||||
"mesh-catalog modules/mssql",
|
||||
"mesh-catalog modules/n8n",
|
||||
"mesh-catalog modules/nats",
|
||||
"mesh-catalog modules/netcheck",
|
||||
"mesh-catalog modules/networkmanager",
|
||||
"mesh-catalog modules/nextcloud",
|
||||
"mesh-catalog modules/nextcloud-client",
|
||||
"mesh-catalog modules/nfs-server",
|
||||
"mesh-catalog modules/nftables",
|
||||
"mesh-catalog modules/nm-applet",
|
||||
"mesh-catalog modules/node-env",
|
||||
"mesh-catalog modules/nodered",
|
||||
"mesh-catalog modules/ollama",
|
||||
"mesh-catalog modules/only-office",
|
||||
"mesh-catalog modules/openai-consumer",
|
||||
"mesh-catalog modules/openrazer",
|
||||
"mesh-catalog modules/pacman",
|
||||
"mesh-catalog modules/photos-eef",
|
||||
"mesh-catalog modules/photos-filip",
|
||||
"mesh-catalog modules/picom",
|
||||
"mesh-catalog modules/polychromatic",
|
||||
"mesh-catalog modules/postgres",
|
||||
"mesh-catalog modules/power",
|
||||
"mesh-catalog modules/powerlevel10k",
|
||||
"mesh-catalog modules/records",
|
||||
"mesh-catalog modules/redis",
|
||||
"mesh-catalog modules/restic",
|
||||
"mesh-catalog modules/rofi",
|
||||
"mesh-catalog modules/route-adapter",
|
||||
"mesh-catalog modules/screen-lock",
|
||||
"mesh-catalog modules/searxng",
|
||||
"mesh-catalog modules/sensors",
|
||||
"mesh-catalog modules/showcase",
|
||||
"mesh-catalog modules/slack",
|
||||
"mesh-catalog modules/snapd",
|
||||
"mesh-catalog modules/ssh-client",
|
||||
"mesh-catalog modules/sshd",
|
||||
"mesh-catalog modules/step-ca",
|
||||
"mesh-catalog modules/sudo",
|
||||
"mesh-catalog modules/supabase",
|
||||
"mesh-catalog modules/systemd",
|
||||
"mesh-catalog modules/systemd-networkd",
|
||||
"mesh-catalog modules/systemd-resolved",
|
||||
"mesh-catalog modules/telegram",
|
||||
"mesh-catalog modules/time-sync",
|
||||
"mesh-catalog modules/triggerhappy",
|
||||
"mesh-catalog modules/umami",
|
||||
"mesh-catalog modules/unifi",
|
||||
"mesh-catalog modules/website",
|
||||
"mesh-catalog modules/xclip",
|
||||
"mesh-catalog modules/xdg",
|
||||
"mesh-catalog modules/xorg",
|
||||
"mesh-catalog modules/xterm",
|
||||
"mesh-catalog modules/zfs",
|
||||
"mesh-catalog modules/zsh",
|
||||
"mesh-catalog modules/zsh-autosuggestions",
|
||||
"mesh-catalog modules/zsh-syntax-highlighting",
|
||||
"mesh-controller",
|
||||
"mesh-controller modules/build-agent",
|
||||
"mesh-controller modules/route-proxy",
|
||||
"mesh-delivery",
|
||||
"mesh-host",
|
||||
"mesh-lab",
|
||||
"mesh-media-catalog",
|
||||
"mesh-sdk",
|
||||
"mesh-tools"
|
||||
],
|
||||
"duplicate-check": "on",
|
||||
"judge-model": "sonnet",
|
||||
"forge-owner": "novox",
|
||||
"stuck-after": "2h",
|
||||
"worker-stale-after": "24h",
|
||||
"delivered-not-resolved-after": "1h",
|
||||
"decision-floor": 293,
|
||||
"research-floor": 45
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
postgresql://${bound:postgres-database:as}:${secret:postgres-database}@${bound:postgres-database:at}:${bound:postgres-database:port}/${bound:postgres-database:as}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"judge-model": "sonnet",
|
||||
"drafting": "on",
|
||||
"reserved-for": "168h"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"client-id": "${bound:oidc-client:as}",
|
||||
"client-secret": "${secret:oidc-client}",
|
||||
"issuer": "${bound:oidc-client:issuer}"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"operators": []
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"accounts": {}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
postgresql://${bound:postgres-database:as}:${secret:postgres-database}@${bound:postgres-database:at}:${bound:postgres-database:port}/${bound:postgres-database:as}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"grants": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"scheme": "${bound:s3-bucket:scheme}",
|
||||
"at": "${bound:s3-bucket:at}",
|
||||
"port": "${bound:s3-bucket:port}",
|
||||
"bucket": "${bound:s3-bucket:bucket}",
|
||||
"region": "${bound:s3-bucket:region}",
|
||||
"key": "${bound:s3-bucket:as}",
|
||||
"secret": "${secret:s3-bucket}"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"telegram-chat-id": ""
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"time-zone": "",
|
||||
"only-what-needs-me": []
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
MINIO_ROOT_USER=meshroot
|
||||
MINIO_BROWSER_REDIRECT_URL=https://${bound:route:name-console}
|
||||
@@ -0,0 +1 @@
|
||||
postgresql://${bound:postgres-database:as}:${secret:postgres-database}@${bound:postgres-database:at}:${bound:postgres-database:port}/${bound:postgres-database:as}
|
||||
@@ -0,0 +1 @@
|
||||
${secret:root}
|
||||
@@ -0,0 +1,7 @@
|
||||
MESH_PROVISION_MQTT=127.0.0.1:${port:1883}
|
||||
MESH_PROVISION_ADMIN_USER=mesh-admin
|
||||
MESH_PROVISION_PASSWORD_FILE=${dir:mesh-state}/admin
|
||||
MESH_DYNSEC_FILE=${dir:data}/dynamic-security.json
|
||||
MESH_MQTT_CTRL_IMAGE=eclipse-mosquitto@sha256:38c0da4f2ef84284d47b3b3eeea1cb3bdeabe81ee10caf0cd5c5ff61ee3ea408
|
||||
MESH_MQTT_CTRL_CONTAINER=mosquitto
|
||||
MESH_MQTT_ADMIN_APPLIED_FILE=${dir:state}/admin.applied
|
||||
@@ -0,0 +1,20 @@
|
||||
persistence true
|
||||
persistence_location /mosquitto/data
|
||||
|
||||
log_dest stdout
|
||||
log_type warning
|
||||
log_type error
|
||||
log_type notice
|
||||
|
||||
# Every client authenticates; identities and their per-topic ACLs are managed
|
||||
# at runtime by the dynamic security plugin, whose store the plugin itself owns.
|
||||
allow_anonymous false
|
||||
plugin /usr/lib/mosquitto_dynamic_security.so
|
||||
plugin_opt_config_file /mosquitto/data/dynamic-security.json
|
||||
|
||||
# MQTT listener
|
||||
listener 1883
|
||||
|
||||
# MQTT-over-WebSockets listener
|
||||
listener 8081
|
||||
protocol websockets
|
||||
@@ -0,0 +1,11 @@
|
||||
# Written by the mesh (module mounts, novox/hq ADR 0263) from this machine's assignment: the settings
|
||||
# shares and sources, and the binding of nfs-share. Replaced on every push; change the settings, not this.
|
||||
# The module's process reads it as root every 30 seconds and writes one .mount and .automount per entry.
|
||||
shares=${config:shares}
|
||||
sources=${config:sources}
|
||||
server=${bound:nfs-share:from}
|
||||
at=${bound:nfs-share:at}
|
||||
account=${machine:account}
|
||||
node=${machine:name}
|
||||
passwords=${dir:state}
|
||||
state=${dir:state}
|
||||
@@ -0,0 +1,14 @@
|
||||
SET NOCOUNT ON;
|
||||
DECLARE @n sysname, @s nvarchar(max);
|
||||
DECLARE c CURSOR LOCAL FAST_FORWARD FOR
|
||||
SELECT name FROM sys.databases WHERE database_id > 4 AND state = 0 AND source_database_id IS NULL;
|
||||
OPEN c;
|
||||
FETCH NEXT FROM c INTO @n;
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
SET @s = N'BACKUP DATABASE ' + QUOTENAME(@n) + N' TO DISK = N''/var/opt/mssql/backup/' + REPLACE(@n, N'''', N'''''') + N'.bak'' WITH INIT, COPY_ONLY, CHECKSUM';
|
||||
EXEC (@s);
|
||||
FETCH NEXT FROM c INTO @n;
|
||||
END
|
||||
CLOSE c;
|
||||
DEALLOCATE c;
|
||||
@@ -0,0 +1,2 @@
|
||||
ACCEPT_EULA=Y
|
||||
MSSQL_SA_PASSWORD=${secret:sa}
|
||||
@@ -0,0 +1 @@
|
||||
${secret:postgres-database}
|
||||
@@ -0,0 +1,12 @@
|
||||
N8N_HOST=${bound:route:name}
|
||||
N8N_PORT=5678
|
||||
N8N_PROTOCOL=https
|
||||
WEBHOOK_URL=https://${bound:route:name}/
|
||||
NODE_FUNCTION_ALLOW_BUILTIN=*
|
||||
NODE_FUNCTION_ALLOW_EXTERNAL=*
|
||||
DB_TYPE=postgresdb
|
||||
DB_POSTGRESDB_HOST=${bound:postgres-database:at}
|
||||
DB_POSTGRESDB_PORT=${bound:postgres-database:port}
|
||||
DB_POSTGRESDB_DATABASE=${bound:postgres-database:as}
|
||||
DB_POSTGRESDB_USER=${bound:postgres-database:as}
|
||||
DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/database
|
||||
@@ -0,0 +1,46 @@
|
||||
# The nats module's own server settings. Declared by the module, because a port, a TLS path
|
||||
# and a store directory are properties of the container this module raises: they live in its
|
||||
# image and its mounts and change when it does.
|
||||
#
|
||||
# The mesh writes accounts.conf beside this one and nothing else. A controller that wrote the
|
||||
# whole file would have to be kept in step with a Dockerfile it never sees.
|
||||
|
||||
port: 4222
|
||||
# Monitoring on every interface *inside* the container, so the publish below can reach it; the publish
|
||||
# is 127.0.0.1:8222 on the machine, so nothing beyond the machine reaches it, and the module guards 8222
|
||||
# too. Bound to the container's own loopback until 2026-10-04, the published port answered nothing
|
||||
# (connection reset), and the only way in was `docker exec`.
|
||||
http: 0.0.0.0:8222
|
||||
|
||||
# The mesh's own broker certificate — the one every machine already pins by fingerprint and the
|
||||
# controller already trusts (MESH_BROKER_CERTIFICATE). Serving the new bus with it means no
|
||||
# machine's pin changes when it moves, and no second certificate exists to be wrong about.
|
||||
tls {
|
||||
cert_file: "/tls/tls.crt"
|
||||
key_file: "/tls/tls.key"
|
||||
}
|
||||
|
||||
# **No `verify`, deliberately, and it was `verify: true` until a probe ran this image.** That
|
||||
# setting makes the server demand a *client* certificate, and nothing in the mesh presents one: a
|
||||
# host pins this server's exact certificate and authenticates with the password the mesh minted
|
||||
# (novox/hq ADR 0004, design 25 §4), and so does a module's runtime. With it on, every connection
|
||||
# in the mesh is refused at the TLS handshake, before any password is looked at — and the error is
|
||||
# "client didn't provide a certificate", which reads as a client fault.
|
||||
#
|
||||
# TLS is still required: a tls block is what makes it required, and verify only decides whether
|
||||
# client certificates are checked. What is given up is a second factor the mesh has no machinery
|
||||
# to issue or rotate — a certificate per module per node — and what is kept is stronger than a
|
||||
# name check in both directions: an exact pin outward, a per-user password inward.
|
||||
|
||||
jetstream {
|
||||
store_dir: "/data"
|
||||
}
|
||||
|
||||
# Every user of the mesh, composed by the controller and rewritten whenever a module is
|
||||
# assigned, a node enrols or a person's access changes.
|
||||
#
|
||||
# **Relative, and in this same directory, because it has to be.** An absolute include path is
|
||||
# resolved relative to the including file's directory, not from the root: nats-server given
|
||||
# `include /etc/nats/accounts.conf` from /etc/nats-server/nats.conf looks for
|
||||
# /etc/nats-server/etc/nats/accounts.conf and refuses to start. Verified against the server.
|
||||
include accounts.conf
|
||||
@@ -0,0 +1,63 @@
|
||||
# Managed by the mesh (module networkmanager). Replaced on every push; edit the
|
||||
# catalogue instead.
|
||||
#
|
||||
# This machine's uplink is NetworkManager's, and this file is the whole of what
|
||||
# the mesh asks of it (novox/hq ADR 0117): leave the resolver file to the mesh,
|
||||
# and leave the private network's interface alone. Nothing more. The mesh never
|
||||
# declares a connection profile, an address, a route, a wireless network or its
|
||||
# credentials — those are joined at the machine, by the person using it, and
|
||||
# the link they make is the only channel the mesh reaches this machine over. A
|
||||
# push that got a link wrong could not be undone by the next one.
|
||||
#
|
||||
# A drop-in of the mesh's own, beside NetworkManager.conf and whatever else the
|
||||
# operator keeps in this directory. NetworkManager reads the files here sorted by
|
||||
# name and a later one wins a key it sets again — so a file of the operator's
|
||||
# that sorts after this one (any name starting with a letter does) and sets dns=
|
||||
# or unmanaged-devices= overrides it. That is the operator's to decide, and the
|
||||
# reason this file sets nothing but the two keys it must.
|
||||
#
|
||||
# NetworkManager itself is the machine's: the mesh never starts, stops, enables
|
||||
# or disables it (its service is declared with no state), because stopping it
|
||||
# takes every link down, this machine's channel to the mesh included — and a
|
||||
# module unassigned by mistake must not be able to do that. When this file
|
||||
# changes, a running NetworkManager is reloaded (its D-Bus Reload call, which
|
||||
# re-reads its configuration — NetworkManager(8)), never restarted.
|
||||
|
||||
[main]
|
||||
# The resolver file is the mesh's: this module writes /etc/resolv.conf itself,
|
||||
# listing the mesh's resolvers (novox/hq ADR 0223). Without this line
|
||||
# NetworkManager rewrites that file on
|
||||
# every connectivity change — every network joined, every lease renewed —
|
||||
# and the mesh's resolver is silently replaced while every surface of the mesh
|
||||
# still reads green. none: "NetworkManager will not modify resolv.conf. This
|
||||
# implies rc-manager unmanaged" (NetworkManager.conf(5), 1.58). On an adopted
|
||||
# machine the predecessor wrote the same line in a file of its own; both say one
|
||||
# thing, and the predecessor's is retired by hand after the take.
|
||||
#
|
||||
# Not NetworkManager's own global DNS ([global-dns-domain-*] with rc-manager=file):
|
||||
# it writes its own header and composes the options line itself, so it cannot
|
||||
# write the mesh's file byte for byte, and the three uplink modules would write
|
||||
# three different files for one fact. dns=none, and the file declared beside it.
|
||||
dns=none
|
||||
|
||||
[keyfile]
|
||||
# mesh0 is the private network's interface: the mesh brings it up and the mesh
|
||||
# alone configures it. A manager that considers every interface its own could
|
||||
# try to configure it, or tear it down on a profile change.
|
||||
#
|
||||
# unmanaged-devices rather than a [device-mesh0] section with managed=0, because
|
||||
# NetworkManager.conf(5) says a device unmanaged by this key "is strictly
|
||||
# unmanaged and cannot be overruled by using the API like nmcli device set
|
||||
# $IFNAME managed yes", while device*.managed "can be overruled at runtime via
|
||||
# D-Bus". The same page adds that device*.managed "may be a better choice" for
|
||||
# exactly those reasons — for an interface the operator might want to hand back
|
||||
# at runtime. For the mesh's own interface, strict is the point.
|
||||
#
|
||||
# += rather than =: the same page documents appending to a list-valued key set
|
||||
# earlier ("plugins+=another-plugin") as an extension of its key file format,
|
||||
# and unmanaged-devices is a device list. = would replace whatever devices the
|
||||
# operator already keeps NetworkManager away from; += adds this one to them
|
||||
# (novox/hq ADR 0102: a list is added to, never replaced). A file of the
|
||||
# operator's read after this one that sets the key with = replaces it again;
|
||||
# that is the operator's to decide.
|
||||
unmanaged-devices+=interface-name:mesh0
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,14 @@
|
||||
POSTGRES_HOST=${bound:postgres-database:at}:${bound:postgres-database:port}
|
||||
POSTGRES_DB=${bound:postgres-database:as}
|
||||
POSTGRES_USER=${bound:postgres-database:as}
|
||||
POSTGRES_PASSWORD=${secret:postgres-database}
|
||||
NEXTCLOUD_ADMIN_USER=mesh-admin
|
||||
NEXTCLOUD_ADMIN_PASSWORD=${secret:admin}
|
||||
OBJECTSTORE_S3_HOST=${bound:s3-bucket:at}
|
||||
OBJECTSTORE_S3_PORT=${bound:s3-bucket:port}
|
||||
OBJECTSTORE_S3_BUCKET=${bound:s3-bucket:bucket}
|
||||
OBJECTSTORE_S3_KEY=${bound:s3-bucket:as}
|
||||
OBJECTSTORE_S3_SECRET=${secret:s3-bucket}
|
||||
OBJECTSTORE_S3_SSL=false
|
||||
OBJECTSTORE_S3_USEPATH_STYLE=true
|
||||
OBJECTSTORE_S3_REGION=${bound:s3-bucket:region}
|
||||
@@ -0,0 +1,12 @@
|
||||
# Written by the mesh (module nfs-server, novox/hq ADR 0263). Replaced on every push; a drop-in of
|
||||
# the operator's that sorts after this one overrides it, and is theirs.
|
||||
#
|
||||
# NFS version 4 only: a client needs port 2049 and nothing else, so the module opens nothing more
|
||||
# than that, to the private network. Version 3 needs rpcbind and mountd, on ports the mesh does not open.
|
||||
[nfsd]
|
||||
vers2=n
|
||||
vers3=n
|
||||
vers4=y
|
||||
vers4.0=n
|
||||
vers4.1=y
|
||||
vers4.2=y
|
||||
@@ -0,0 +1,10 @@
|
||||
# Written by the mesh (module nfs-server, novox/hq ADR 0263) from this machine's assignment.
|
||||
# Replaced on every push; change the `shares` setting, never this file.
|
||||
#
|
||||
# The shares: name=folder, or name=folder:ro, one share per folder. The grants: share=node:rw|ro[,…],
|
||||
# which nodes may mount each and how. The module's process exports a share to a node's private address
|
||||
# only when it is granted here and that node's mounts module wants it, every client mapped to the
|
||||
# folder's owner, and only to addresses inside the range below.
|
||||
shares=${config:shares}
|
||||
grants=${config:grants}
|
||||
range=${machine:mesh-range}
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=The mesh's packet filter, derived from what is assigned to this node
|
||||
Wants=network-pre.target
|
||||
Before=network-pre.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=nft -f /etc/nftables.conf
|
||||
ExecReload=nft -f /etc/nftables.conf
|
||||
ExecStop=nft delete table inet mesh
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,5 @@
|
||||
# The mesh: stopping the stock unit deletes only the mesh's table, never the whole ruleset
|
||||
# (novox/hq ADR 0100) — a flush would take the container runtime's rules and any firewall with it.
|
||||
[Service]
|
||||
ExecStop=
|
||||
ExecStop=nft delete table inet mesh
|
||||
@@ -0,0 +1,4 @@
|
||||
# The operator account's environment for its service manager and graphical session, generated by
|
||||
# the mesh (module node-env, novox/hq ADR 0203). Do not edit: this file is replaced at every push.
|
||||
# The same facts as ~/.config/mesh/environment.sh, in environment.d(5) syntax.
|
||||
${collected:environment:systemd}
|
||||
@@ -0,0 +1,5 @@
|
||||
# The operator account's environment, generated by the mesh (module node-env, novox/hq ADR 0203).
|
||||
# Do not edit: this file is replaced at every push. Every line names the module that contributed it.
|
||||
# Sourced by the login shell from its always-read startup file (for zsh, ~/.zshenv), so a script, a
|
||||
# login and the shell's execute verb all see it. Your own variables belong in your shell's own lines.
|
||||
${collected:environment:posix}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"token": "${secret:api-token}"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
MESH_NODERED_URL=http://127.0.0.1:${port:1880}
|
||||
MESH_NODERED_CONFIG_FILE=${dir:mesh-state}/config.json
|
||||
MESH_PROVISIONS_DIR=${dir:state}
|
||||
MESH_WRITTEN_DIR=${dir:written}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Node-RED's settings, written by the mesh from the nodered module. What an assignment may change
|
||||
// is settings.json beside this file (merged key by key); the credentials are the mesh's secrets and
|
||||
// reach Node-RED only through this file. The flows' own credentials stay encrypted in the user
|
||||
// directory under the key Node-RED keeps there (.config.runtime.json), which is data, not this.
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const ADMIN_PASSWORD = "${secret:admin}";
|
||||
const API_TOKEN = "${secret:api-token}";
|
||||
const ADMIN = { username: "admin", permissions: "*" };
|
||||
|
||||
const settings = JSON.parse(fs.readFileSync(path.join(__dirname, "settings.json"), "utf8"));
|
||||
// The mesh's keys, not Node-RED's: endpoints lands in every merged file; timeZone is the
|
||||
// assignment's way to set the zone flows schedule and format in; mqtt names the broker nodes the
|
||||
// module's MQTT step keeps pointed at the mesh's broker; topics is what nodered asks the broker for.
|
||||
if (settings.timeZone) process.env.TZ = settings.timeZone;
|
||||
delete settings.timeZone;
|
||||
delete settings.endpoints;
|
||||
delete settings.mqtt;
|
||||
delete settings.topics;
|
||||
|
||||
function same(a, b) {
|
||||
const x = crypto.createHash("sha256").update(String(a)).digest();
|
||||
const y = crypto.createHash("sha256").update(String(b)).digest();
|
||||
return crypto.timingSafeEqual(x, y);
|
||||
}
|
||||
|
||||
// The admin secret is a password, or, accepted from an existing install, the bcrypt hash its
|
||||
// settings held, so the password people already use keeps working.
|
||||
function passwordMatches(given) {
|
||||
if (/^\$2[aby]\$\d\d\$/.test(ADMIN_PASSWORD)) return require("bcryptjs").compare(String(given), ADMIN_PASSWORD);
|
||||
return Promise.resolve(same(given, ADMIN_PASSWORD));
|
||||
}
|
||||
|
||||
module.exports = Object.assign(settings, {
|
||||
uiPort: 1880,
|
||||
adminAuth: {
|
||||
type: "credentials",
|
||||
users: (username) => Promise.resolve(username === ADMIN.username ? ADMIN : null),
|
||||
authenticate: (username, password) =>
|
||||
username === ADMIN.username
|
||||
? passwordMatches(password).then((ok) => (ok ? ADMIN : null))
|
||||
: Promise.resolve(null),
|
||||
// The module's own tools call the admin API with this bearer token.
|
||||
tokens: (token) => Promise.resolve(same(token, API_TOKEN) ? { username: "mesh", permissions: "*" } : null),
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"flowFile": "flows.json",
|
||||
"flowFilePretty": true,
|
||||
"diagnostics": { "enabled": true, "ui": true },
|
||||
"runtimeState": { "enabled": false, "ui": false },
|
||||
"logging": { "console": { "level": "info", "metrics": false, "audit": false } },
|
||||
"exportGlobalContextKeys": false,
|
||||
"externalModules": {},
|
||||
"editorTheme": { "projects": { "enabled": false } },
|
||||
"functionExternalModules": true,
|
||||
"debugMaxLength": 1000,
|
||||
"mqttReconnectTime": 15000,
|
||||
"serialReconnectTime": 15000
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
JWT_ENABLED=true
|
||||
JWT_SECRET=${secret:jwt}
|
||||
JWT_HEADER=Authorization
|
||||
JWT_IN_BODY=true
|
||||
ALLOW_PRIVATE_IP_ADDRESS=true
|
||||
@@ -0,0 +1,29 @@
|
||||
# The mesh's (module pacman, novox/hq to-be 42): the package manager's configuration. Written
|
||||
# whole at every push: an edit here is overwritten, and the file a machine had before is kept once by
|
||||
# the host. Owned whole because [options] cannot take a block by appending: anything added at the end
|
||||
# of the file lands in the last repository's section.
|
||||
#
|
||||
# The repositories are the union of what the machines had enabled when the module was written
|
||||
# (core, extra, multilib). The options are the distribution's defaults with four more: colour on a
|
||||
# terminal, parallel downloads, package lists in columns, and downloads run as the unprivileged
|
||||
# alpm user, which pacman 7 creates.
|
||||
|
||||
[options]
|
||||
HoldPkg = pacman glibc
|
||||
Architecture = auto
|
||||
CheckSpace
|
||||
Color
|
||||
VerbosePkgLists
|
||||
ParallelDownloads = 5
|
||||
DownloadUser = alpm
|
||||
SigLevel = Required DatabaseOptional
|
||||
LocalFileSigLevel = Optional
|
||||
|
||||
[core]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
[extra]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
[multilib]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
@@ -0,0 +1,8 @@
|
||||
# The mesh's (module pacman, novox/hq to-be 42): how reflector refreshes the mirror list, weekly,
|
||||
# through reflector.timer. Written whole at every push. Before the module, every machine's list was
|
||||
# generated once and never again.
|
||||
--save /etc/pacman.d/mirrorlist
|
||||
--protocol https
|
||||
--country Belgium,Netherlands,Luxembourg,Germany,France
|
||||
--latest 20
|
||||
--sort rate
|
||||
@@ -0,0 +1,38 @@
|
||||
# picom, the X compositor (module picom, novox/hq ADR 0208). Owned by the mesh: this file is
|
||||
# replaced at every push. Adopted from the two workstations' file of 2026-10-04 and moved to
|
||||
# picom's window rules, which supersede opacity-rule, inactive-opacity and inactive-dim.
|
||||
|
||||
# The backend and damage tracking are each machine's settings (backend, use-damage; novox/hq research
|
||||
# 037, issue 345): the right ones depend on the machine's graphics driver. The defaults are what every
|
||||
# machine ran before: glx, and picom's own default of repainting only what changed. xrender, or
|
||||
# use-damage false (repaint the whole screen each frame), is what to try on a machine where a window is
|
||||
# left unpainted or stale.
|
||||
backend = "${config:backend}";
|
||||
use-damage = ${config:use-damage};
|
||||
vsync = true;
|
||||
|
||||
fading = true;
|
||||
fade-in-step = 0.05;
|
||||
fade-out-step = 0.05;
|
||||
|
||||
# Tiled windows hide their shadows and corners, so neither is drawn.
|
||||
shadow = false;
|
||||
corner-radius = 0;
|
||||
blur-method = "none";
|
||||
|
||||
# "Focused" is i3's _NET_ACTIVE_WINDOW, not X focus events: under i3 those do not reliably reach
|
||||
# the toplevel picom tracks, and a terminal then never lifts to its focused opacity.
|
||||
use-ewmh-active-win = true;
|
||||
|
||||
# Window rules are applied in order, and a later match wins. Only terminals are translucent:
|
||||
# nothing else on screen (browsers, video, games) is touched. A terminal is matched by its class;
|
||||
# the node's terminal emulator today is xterm (class XTerm). A window's own opacity property is
|
||||
# used wherever no rule sets one, which is what the window-opacity tool sets.
|
||||
rules = (
|
||||
{ match = "window_type = 'tooltip'"; fade = false; opacity = 0.95; },
|
||||
{ match = "window_type = 'dock' || window_type = 'desktop'"; fade = false; },
|
||||
{ match = "class_g = 'XTerm' && focused"; opacity = 0.95; },
|
||||
{ match = "class_g = 'XTerm' && !focused"; opacity = 0.75; },
|
||||
# A full-screen window is opaque, a terminal included: a video or a game is never see-through.
|
||||
{ match = "fullscreen"; opacity = 1; }
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
# The Razer peripherals' tray (module polychromatic, novox/hq ADR 0208, ADR 0212). Owned by the mesh:
|
||||
# replaced at every push. This line is the tray's one start, at the session's start (exec, not
|
||||
# exec_always, so a reload starts nothing). The package's own login helper starts it too while the
|
||||
# application's setting "Start the tray applet when I log on" is ticked; polychromatic_check names
|
||||
# that as a second start.
|
||||
exec --no-startup-id polychromatic-tray-applet
|
||||
@@ -0,0 +1 @@
|
||||
${consumers:postgres-database}
|
||||
@@ -0,0 +1,90 @@
|
||||
#!/bin/sh
|
||||
# power-moment MOMENT [--force] — run every module's code for one power moment (novox/hq ADR 0211).
|
||||
# Shipped by the mesh's power module; edit the catalogue.
|
||||
#
|
||||
# MOMENT is after-boot, before-sleep, after-wake, before-shutdown, on-mains or on-battery, or
|
||||
# `supply`, which reads the machine's power source and runs on-mains or on-battery once per change.
|
||||
#
|
||||
# The moment's file holds what the controller placed: each module's code under a line `# <module>`.
|
||||
# Each module's piece runs on its own, with sh, as root, bounded by MESH_POWER_BOUND seconds
|
||||
# (default 30) and killed 5 s after that, so one module that hangs cannot hold the machine awake or
|
||||
# stop the next module. Every outcome goes to the journal under the tag mesh-power.
|
||||
set -u
|
||||
|
||||
moment=${1:-}
|
||||
force=${2:-}
|
||||
moments=/etc/mesh-power/moments
|
||||
bound=${MESH_POWER_BOUND:-30}
|
||||
runtime=/run/mesh-power
|
||||
|
||||
say() { logger -t mesh-power -- "$*" 2>/dev/null || true; printf '%s\n' "$*"; }
|
||||
|
||||
# The power source as the kernel says it: on mains when any Mains supply is online. A machine with
|
||||
# no Mains supply (a desktop, a server, a USB-C source only) has no source to change.
|
||||
source_now() {
|
||||
found=no
|
||||
for s in /sys/class/power_supply/*; do
|
||||
[ "$(cat "$s/type" 2>/dev/null)" = Mains ] || continue
|
||||
found=yes
|
||||
[ "$(cat "$s/online" 2>/dev/null)" = 1 ] && { echo on-mains; return; }
|
||||
done
|
||||
[ "$found" = yes ] && echo on-battery || echo none
|
||||
}
|
||||
|
||||
case "$moment" in
|
||||
supply)
|
||||
now=$(source_now)
|
||||
[ "$now" = none ] && exit 0
|
||||
mkdir -p "$runtime"
|
||||
last=$(cat "$runtime/source" 2>/dev/null || true)
|
||||
[ "$now" = "$last" ] && [ "$force" != --force ] && exit 0
|
||||
echo "$now" >"$runtime/source"
|
||||
moment=$now
|
||||
;;
|
||||
after-boot | before-sleep | after-wake | on-mains | on-battery) ;;
|
||||
before-shutdown)
|
||||
# Run only while the machine is really going down. The unit that runs it is stopped at shutdown,
|
||||
# and also when the module is taken off the machine; the second must not run anyone's shutdown code.
|
||||
state=$(systemctl is-system-running 2>/dev/null || true)
|
||||
if [ "$state" != stopping ] && [ "$force" != --force ]; then
|
||||
say "moment=before-shutdown skipped: the system is $state, not stopping"
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "power-moment: no moment $moment (after-boot, before-sleep, after-wake, before-shutdown, on-mains, on-battery, supply)" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
file="$moments/$moment"
|
||||
[ -r "$file" ] || { say "moment=$moment: nothing placed"; exit 0; }
|
||||
|
||||
work=$(mktemp -d) || exit 1
|
||||
trap 'rm -rf "$work"' EXIT
|
||||
|
||||
# One file per module piece, in the order the controller placed them. A line that is exactly
|
||||
# "# <module name>" opens a piece; lines before the first are the holder's own header.
|
||||
awk -v dir="$work" '
|
||||
/^# [a-z0-9][a-z0-9-]*$/ { n++; name = substr($0, 3); out = sprintf("%s/%03d-%s", dir, n, name); next }
|
||||
n > 0 { print > out }
|
||||
' "$file"
|
||||
|
||||
ran=0 failed=0
|
||||
for piece in "$work"/*; do
|
||||
[ -e "$piece" ] || continue
|
||||
module=${piece##*/}
|
||||
module=${module#*-}
|
||||
start=$(date +%s)
|
||||
timeout --kill-after=5 "$bound" sh "$piece" </dev/null >"$piece.out" 2>&1
|
||||
rc=$?
|
||||
took=$(($(date +%s) - start))
|
||||
ran=$((ran + 1))
|
||||
case $rc in
|
||||
0) say "moment=$moment module=$module ok in ${took}s" ;;
|
||||
124 | 137) failed=$((failed + 1)); say "moment=$moment module=$module ended after ${bound}s: it did not finish" ;;
|
||||
*) failed=$((failed + 1)); say "moment=$moment module=$module exited $rc: $(tail -n 3 "$piece.out" | tr '\n' ' ')" ;;
|
||||
esac
|
||||
done
|
||||
say "moment=$moment: $ran piece(s), $failed failed"
|
||||
exit 0
|
||||
@@ -0,0 +1,9 @@
|
||||
[[block]]
|
||||
block = "battery"
|
||||
format = "$icon $percentage{ $time|}"
|
||||
charging_format = "$icon $percentage{ $time|}"
|
||||
not_charging_format = "$icon $percentage"
|
||||
full_format = "$icon $percentage"
|
||||
empty_format = "$icon $percentage"
|
||||
missing_format = ""
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
[[block]]
|
||||
block = "custom"
|
||||
command = "~/.local/bin/i3status-value power.draw ${machine:name}"
|
||||
interval = 5
|
||||
hide_when_empty = true
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
# What every module on this machine runs at the moment after-boot, as the mesh placed it (module power,
|
||||
# novox/hq ADR 0211). Replaced on every push: code is added by the module it belongs to, as a
|
||||
# contribution for this moment. Each module's piece runs on its own, as root, bounded in time.
|
||||
${shell:after-boot:first}${shell:after-boot:normal}${shell:after-boot:last}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
# What every module on this machine runs at the moment after-wake, as the mesh placed it (module power,
|
||||
# novox/hq ADR 0211). Replaced on every push: code is added by the module it belongs to, as a
|
||||
# contribution for this moment. Each module's piece runs on its own, as root, bounded in time.
|
||||
${shell:after-wake:first}${shell:after-wake:normal}${shell:after-wake:last}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
# What every module on this machine runs at the moment before-shutdown, as the mesh placed it (module power,
|
||||
# novox/hq ADR 0211). Replaced on every push: code is added by the module it belongs to, as a
|
||||
# contribution for this moment. Each module's piece runs on its own, as root, bounded in time.
|
||||
${shell:before-shutdown:first}${shell:before-shutdown:normal}${shell:before-shutdown:last}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
# What every module on this machine runs at the moment before-sleep, as the mesh placed it (module power,
|
||||
# novox/hq ADR 0211). Replaced on every push: code is added by the module it belongs to, as a
|
||||
# contribution for this moment. Each module's piece runs on its own, as root, bounded in time.
|
||||
${shell:before-sleep:first}${shell:before-sleep:normal}${shell:before-sleep:last}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
# What every module on this machine runs at the moment on-battery, as the mesh placed it (module power,
|
||||
# novox/hq ADR 0211). Replaced on every push: code is added by the module it belongs to, as a
|
||||
# contribution for this moment. Each module's piece runs on its own, as root, bounded in time.
|
||||
${shell:on-battery:first}${shell:on-battery:normal}${shell:on-battery:last}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
# What every module on this machine runs at the moment on-mains, as the mesh placed it (module power,
|
||||
# novox/hq ADR 0211). Replaced on every push: code is added by the module it belongs to, as a
|
||||
# contribution for this moment. Each module's piece runs on its own, as root, bounded in time.
|
||||
${shell:on-mains:first}${shell:on-mains:normal}${shell:on-mains:last}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
#
|
||||
# The power key and the lid, from this module's settings: the mesh's, then this machine's.
|
||||
[Login]
|
||||
HandlePowerKey=${config:handle-power-key}
|
||||
HandleLidSwitch=${config:handle-lid-switch}
|
||||
HandleLidSwitchExternalPower=${config:handle-lid-switch-external-power}
|
||||
HandleLidSwitchDocked=${config:handle-lid-switch-docked}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
[Unit]
|
||||
Wants=mesh-power-after-wake.service
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
[Unit]
|
||||
Wants=mesh-power-after-wake.service
|
||||
go/testdata/beside/mesh-catalog/modules/power/templates/systemd/system/mesh-power-after-boot.service
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
[Unit]
|
||||
Description=Every module's code after boot (mesh power)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/local/lib/mesh-power/bin/power-moment after-boot
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
go/testdata/beside/mesh-catalog/modules/power/templates/systemd/system/mesh-power-after-wake.service
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
#
|
||||
# Pulled in by the four sleep targets through this module's drop-ins on them, and ordered after
|
||||
# them, so it runs once the machine is awake again. Never enabled.
|
||||
[Unit]
|
||||
Description=Every module's code after waking (mesh power)
|
||||
After=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/lib/mesh-power/bin/power-moment after-wake
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
#
|
||||
# Started at boot and left active; stopping it is the shutdown. Ordered after the network, so at
|
||||
# shutdown it stops, and runs every module's code, while the network is still up.
|
||||
[Unit]
|
||||
Description=Every module's code before shutdown (mesh power)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/true
|
||||
ExecStop=/usr/local/lib/mesh-power/bin/power-moment before-shutdown
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
#
|
||||
# Pulled in by sleep.target through this module's drop-in on it, never enabled: a one-shot waiting
|
||||
# for a sleep is not a service whose state the mesh can declare.
|
||||
[Unit]
|
||||
Description=Every module's code before sleep (mesh power)
|
||||
Before=sleep.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/lib/mesh-power/bin/power-moment before-sleep
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
#
|
||||
# Started by the module's udev rule when a power supply changes; runs on-mains or on-battery once per
|
||||
# change of source.
|
||||
[Unit]
|
||||
Description=Every module's code for the power source (mesh power)
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/lib/mesh-power/bin/power-moment supply
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
[Unit]
|
||||
Wants=mesh-power-before-sleep.service
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
[Unit]
|
||||
Wants=mesh-power-after-wake.service
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
[Unit]
|
||||
Wants=mesh-power-after-wake.service
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.
|
||||
# Only the charger's change can switch the machine between mains and battery. A battery reports its
|
||||
# level many times a minute, and USB-C supplies come and go; matching them started the supply unit
|
||||
# every second or two on the laptop.
|
||||
SUBSYSTEM=="power_supply", ACTION=="change", ATTR{type}=="Mains", RUN+="/usr/bin/systemctl --no-block start mesh-power-supply.service"
|
||||
@@ -0,0 +1,3 @@
|
||||
# The prompt: powerlevel10k v1.20.0, pinned in this module (novox/hq ADR 0205), and its configuration.
|
||||
[[ ! -f ~/.local/share/powerlevel10k/powerlevel10k.zsh-theme ]] || source ~/.local/share/powerlevel10k/powerlevel10k.zsh-theme
|
||||
[[ ! -f ~/.config/powerlevel10k/p10k.zsh ]] || source ~/.config/powerlevel10k/p10k.zsh
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
${bound:git:scheme}://${bound:git:at}:${bound:git:port}
|
||||
@@ -0,0 +1,3 @@
|
||||
requirepass ${secret:secret}
|
||||
appendonly yes
|
||||
dir /data
|
||||
@@ -0,0 +1,2 @@
|
||||
# What the modules on this machine back up, composed by the mesh (novox/hq to-be 43). Do not edit.
|
||||
${backup:lines}
|
||||
@@ -0,0 +1,2 @@
|
||||
# The data the modules on this machine declare, composed by the mesh (novox/hq ADR 0233). Do not edit.
|
||||
${backup:data}
|
||||
@@ -0,0 +1,6 @@
|
||||
# How many restore points the night keeps, written by the mesh from this machine's settings keep-daily,
|
||||
# keep-weekly, keep-monthly (novox/hq issue 416) and keep-hand-taken-days (novox/hq issue 453). Replaced on every push; change the settings, never this file.
|
||||
daily=${config:keep-daily}
|
||||
weekly=${config:keep-weekly}
|
||||
monthly=${config:keep-monthly}
|
||||
hand=${config:keep-hand-taken-days}
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
# dmenu, as this node's launcher answers it (module rofi, novox/hq ADR 0208). The node-launcher
|
||||
# seat's dmenu-compatible command: choices on standard input, the chosen one on standard output,
|
||||
# exit 1 when nothing was chosen. A script calls `dmenu` and works whichever module holds the seat.
|
||||
#
|
||||
# rofi understands dmenu's -p, -l and -i. dmenu's look options (-fn, -nb, -nf, -sb, -sf, -m, -w)
|
||||
# take a value rofi would misread, so they are dropped with it; -b and -f are dropped alone. The
|
||||
# look is the launcher's theme.
|
||||
set -u
|
||||
n=$#
|
||||
while [ "$n" -gt 0 ]; do
|
||||
arg=$1
|
||||
shift
|
||||
n=$((n - 1))
|
||||
case $arg in
|
||||
-fn | -nb | -nf | -sb | -sf | -m | -w)
|
||||
if [ "$n" -gt 0 ]; then
|
||||
shift
|
||||
n=$((n - 1))
|
||||
fi
|
||||
;;
|
||||
-b | -f) ;;
|
||||
*) set -- "$@" "$arg" ;;
|
||||
esac
|
||||
done
|
||||
exec rofi -dmenu "$@"
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
# rofi-launch drun|run|window|filebrowser|sudo (module rofi, novox/hq ADR 0208): what the launcher's
|
||||
# key bindings run.
|
||||
#
|
||||
# After a resume the keyboard grab can fail for a moment, and rofi then exits at once: a key press
|
||||
# that opens nothing. So a failure within half a second is tried again, up to five times. A person
|
||||
# closing the menu takes longer than that, and is never shown it a second time.
|
||||
set -u
|
||||
mode=${1:-drun}
|
||||
|
||||
now_ms() { date +%s%3N; }
|
||||
|
||||
attempt() {
|
||||
i=0
|
||||
while [ "$i" -lt 5 ]; do
|
||||
start=$(now_ms)
|
||||
"$@" && return 0
|
||||
[ $(($(now_ms) - start)) -ge 500 ] && return 1
|
||||
i=$((i + 1))
|
||||
sleep 0.1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
case $mode in
|
||||
drun | run | window | filebrowser)
|
||||
attempt rofi -show "$mode"
|
||||
;;
|
||||
sudo)
|
||||
# A command line, run with sudo in the node's terminal.
|
||||
command=$(attempt rofi -dmenu -p sudo </dev/null) || exit 0
|
||||
[ -n "$command" ] || exit 0
|
||||
exec rofi-sensible-terminal -e sudo sh -c "$command"
|
||||
;;
|
||||
*)
|
||||
echo "rofi-launch: no mode $mode (drun, run, window, filebrowser, sudo)" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# rofi-powermenu (module rofi, novox/hq ADR 0208): lock, suspend, log out, reboot, shut down.
|
||||
#
|
||||
# It belongs to the session, and it is the launcher's: its whole face is rofi's. Every action is a
|
||||
# verb of logind or the service manager, so nothing here names a window manager or a locker:
|
||||
# - lock asks logind to lock the session, which the holder of node-lock-screen answers;
|
||||
# - log out ends this login session, whichever window manager runs in it.
|
||||
# Adopted from the workstations' power menu of 2026-10-04 (after adi1090x's powermenu type-2).
|
||||
set -u
|
||||
|
||||
theme=mesh-powermenu
|
||||
uptime="$(uptime -p | sed -e 's/^up //')"
|
||||
|
||||
shutdown=''
|
||||
reboot=''
|
||||
lock=''
|
||||
suspend=''
|
||||
logout=''
|
||||
yes=''
|
||||
no=''
|
||||
|
||||
menu() {
|
||||
rofi -dmenu -p "Uptime: $uptime" -mesg "Uptime: $uptime" -theme "$theme"
|
||||
}
|
||||
|
||||
confirm() {
|
||||
printf '%s\n%s\n' "$yes" "$no" | rofi -dmenu -p 'Confirmation' -mesg 'Are you sure?' -theme "$theme" \
|
||||
-theme-str 'window {location: center; anchor: center; fullscreen: false; width: 350px;}' \
|
||||
-theme-str 'mainbox {children: [ "message", "listview" ];}' \
|
||||
-theme-str 'listview {columns: 2; lines: 1;}' \
|
||||
-theme-str 'element-text {horizontal-align: 0.5;}' \
|
||||
-theme-str 'textbox {horizontal-align: 0.5;}'
|
||||
}
|
||||
|
||||
session() {
|
||||
# The login session this menu runs in: the session's own id, else logind's answer for this process.
|
||||
if [ -n "${XDG_SESSION_ID:-}" ]; then
|
||||
echo "$XDG_SESSION_ID"
|
||||
else
|
||||
loginctl show-session auto -p Id --value 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
confirmed() { [ "$(confirm)" = "$yes" ]; }
|
||||
|
||||
chosen="$(printf '%s\n' "$lock" "$suspend" "$logout" "$reboot" "$shutdown" | menu)" || exit 0
|
||||
case $chosen in
|
||||
"$lock") loginctl lock-session "$(session)" ;;
|
||||
"$suspend") confirmed && systemctl suspend ;;
|
||||
"$logout") confirmed && loginctl terminate-session "$(session)" ;;
|
||||
"$reboot") confirmed && systemctl reboot ;;
|
||||
"$shutdown") confirmed && systemctl poweroff ;;
|
||||
esac
|
||||
exit 0
|
||||
@@ -0,0 +1,54 @@
|
||||
/* rofi, the launcher (module rofi, novox/hq ADR 0208). Owned by the mesh: this file is replaced at
|
||||
* every push. Adopted from the two workstations' file of 2026-10-04: the settings that differ from
|
||||
* rofi's defaults, nothing else. Its look is the theme "mesh", in themes/ beside this file. */
|
||||
|
||||
configuration {
|
||||
modi: "drun,run,window,filebrowser";
|
||||
show-icons: true;
|
||||
case-sensitive: false;
|
||||
normalize-match: true;
|
||||
matching: "normal";
|
||||
tokenize: true;
|
||||
cycle: true;
|
||||
steal-focus: false;
|
||||
click-to-exit: true;
|
||||
sort: false;
|
||||
|
||||
/* Applications: the user's and the system's desktop entries, read fresh each time so a
|
||||
* program installed a minute ago is there. */
|
||||
drun-match-fields: "name,generic,exec,categories,keywords";
|
||||
drun-display-format: "{name} [<span weight='light' size='small'><i>({generic})</i></span>]";
|
||||
drun-show-actions: false;
|
||||
drun-url-launcher: "xdg-open";
|
||||
drun-use-desktop-cache: false;
|
||||
drun-reload-desktop-cache: false;
|
||||
run,drun {
|
||||
fallback-icon: "application-x-addon";
|
||||
}
|
||||
|
||||
/* A command run from `run` opens in the node's terminal when it asks for one. */
|
||||
terminal: "rofi-sensible-terminal";
|
||||
run-shell-command: "{terminal} -e {cmd}";
|
||||
ssh-command: "{terminal} -e {ssh-client} {host} [-p {port}]";
|
||||
parse-hosts: true;
|
||||
parse-known-hosts: true;
|
||||
|
||||
window-match-fields: "title,class,role,name,desktop";
|
||||
window-format: "{w} - {c} - {t:0}";
|
||||
|
||||
disable-history: false;
|
||||
max-history-size: 25;
|
||||
|
||||
filebrowser {
|
||||
directories-first: true;
|
||||
sorting-method: "name";
|
||||
}
|
||||
|
||||
display-window: "Windows";
|
||||
display-run: "Run";
|
||||
display-ssh: "SSH";
|
||||
display-drun: "Apps";
|
||||
display-filebrowser: "Files";
|
||||
}
|
||||
|
||||
@theme "mesh"
|
||||
@@ -0,0 +1,8 @@
|
||||
# The launcher's key bindings (module rofi, novox/hq ADR 0208). Owned by the mesh: replaced at every
|
||||
# push. i3 reads this file through its configuration's `include ~/.config/i3/config.d/*.conf`, after
|
||||
# the variables it sets, so $mod is i3's.
|
||||
bindsym $mod+d exec --no-startup-id ~/.local/bin/rofi-launch drun
|
||||
bindsym $mod+t exec --no-startup-id ~/.local/bin/rofi-launch run
|
||||
bindsym $mod+Shift+t exec --no-startup-id ~/.local/bin/rofi-launch sudo
|
||||
bindsym $mod+Shift+w exec --no-startup-id ~/.local/bin/rofi-launch window
|
||||
bindsym $mod+Escape exec --no-startup-id ~/.local/bin/rofi-powermenu
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* The theme "mesh-powermenu" (module rofi, novox/hq ADR 0208): the power menu's five buttons.
|
||||
* Owned by the mesh; replaced at every push. Adopted from the workstations' power menu theme of
|
||||
* 2026-10-04 (after adi1090x's powermenu type-2, style-1), its colours inlined.
|
||||
**/
|
||||
|
||||
/*****----- Configuration -----*****/
|
||||
configuration {
|
||||
show-icons: false;
|
||||
}
|
||||
|
||||
/*****----- Global Properties -----*****/
|
||||
* {
|
||||
background: #000000FF;
|
||||
background-alt: #282B31FF;
|
||||
foreground: #FFFFFFFF;
|
||||
selected: #DE5200FF;
|
||||
active: #DE5200FF;
|
||||
urgent: #CC0000FF;
|
||||
|
||||
font: "JetBrainsMono Nerd Font 11";
|
||||
}
|
||||
|
||||
|
||||
/*****----- Main Window -----*****/
|
||||
window {
|
||||
/* properties for window widget */
|
||||
transparency: "real";
|
||||
location: center;
|
||||
anchor: center;
|
||||
fullscreen: false;
|
||||
width: 800px;
|
||||
x-offset: 0px;
|
||||
y-offset: 0px;
|
||||
|
||||
/* properties for all widgets */
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
cursor: "default";
|
||||
background-color: @background;
|
||||
}
|
||||
|
||||
/*****----- Main Box -----*****/
|
||||
mainbox {
|
||||
enabled: true;
|
||||
spacing: 15px;
|
||||
margin: 0px;
|
||||
padding: 30px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: transparent;
|
||||
children: [ "inputbar", "listview" ];
|
||||
}
|
||||
|
||||
/*****----- Inputbar -----*****/
|
||||
inputbar {
|
||||
enabled: true;
|
||||
spacing: 15px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: transparent;
|
||||
text-color: @foreground;
|
||||
children: [ "textbox-prompt-colon", "prompt"];
|
||||
}
|
||||
|
||||
dummy {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
textbox-prompt-colon {
|
||||
enabled: true;
|
||||
expand: false;
|
||||
str: "";
|
||||
padding: 12px 16px;
|
||||
border-radius: 0px;
|
||||
background-color: @urgent;
|
||||
text-color: @background;
|
||||
}
|
||||
prompt {
|
||||
enabled: true;
|
||||
padding: 12px;
|
||||
border-radius: 0px;
|
||||
background-color: @active;
|
||||
text-color: @background;
|
||||
}
|
||||
|
||||
/*****----- Message -----*****/
|
||||
message {
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 12px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: @background-alt;
|
||||
text-color: @foreground;
|
||||
}
|
||||
textbox {
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.5;
|
||||
placeholder-color: @foreground;
|
||||
blink: true;
|
||||
markup: true;
|
||||
}
|
||||
error-message {
|
||||
padding: 12px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: @background;
|
||||
text-color: @foreground;
|
||||
}
|
||||
|
||||
/*****----- Listview -----*****/
|
||||
listview {
|
||||
enabled: true;
|
||||
columns: 5;
|
||||
lines: 1;
|
||||
cycle: true;
|
||||
dynamic: true;
|
||||
scrollbar: false;
|
||||
layout: vertical;
|
||||
reverse: false;
|
||||
fixed-height: true;
|
||||
fixed-columns: true;
|
||||
|
||||
spacing: 15px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: transparent;
|
||||
text-color: @foreground;
|
||||
cursor: "default";
|
||||
}
|
||||
|
||||
/*****----- Elements -----*****/
|
||||
element {
|
||||
enabled: true;
|
||||
spacing: 0px;
|
||||
margin: 0px;
|
||||
padding: 40px 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @selected;
|
||||
background-color: @background-alt;
|
||||
text-color: @foreground;
|
||||
cursor: pointer;
|
||||
}
|
||||
element-text {
|
||||
font: "JetBrainsMono Nerd Font Bold 32";
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
cursor: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.5;
|
||||
}
|
||||
element selected.normal {
|
||||
background-color: var(selected);
|
||||
text-color: var(background);
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* The theme "mesh" (module rofi, novox/hq ADR 0208): every rofi window unless a caller names
|
||||
* another. Owned by the mesh; replaced at every push. Adopted from the workstations' theme of
|
||||
* 2026-10-04 (after adi1090x's launcher type-4, style-1), its colour file inlined so the theme is
|
||||
* one file, and its face the monospace one every desktop module names.
|
||||
**/
|
||||
|
||||
/*****----- Global Properties -----*****/
|
||||
* {
|
||||
background: #000000FF;
|
||||
background-alt: #282B31FF;
|
||||
foreground: #FFFFFFFF;
|
||||
selected: #DE5200FF;
|
||||
active: #DE5200FF;
|
||||
urgent: #CC0000FF;
|
||||
|
||||
font: "JetBrainsMono Nerd Font 11";
|
||||
|
||||
border-colour: var(selected);
|
||||
handle-colour: var(selected);
|
||||
background-colour: var(background);
|
||||
foreground-colour: var(foreground);
|
||||
alternate-background: var(background-alt);
|
||||
normal-background: var(background);
|
||||
normal-foreground: var(foreground);
|
||||
urgent-background: var(urgent);
|
||||
urgent-foreground: var(background);
|
||||
active-background: var(active);
|
||||
active-foreground: var(background);
|
||||
selected-normal-background: var(selected);
|
||||
selected-normal-foreground: var(background);
|
||||
selected-urgent-background: var(active);
|
||||
selected-urgent-foreground: var(background);
|
||||
selected-active-background: var(urgent);
|
||||
selected-active-foreground: var(background);
|
||||
alternate-normal-background: var(background);
|
||||
alternate-normal-foreground: var(foreground);
|
||||
alternate-urgent-background: var(urgent);
|
||||
alternate-urgent-foreground: var(background);
|
||||
alternate-active-background: var(active);
|
||||
alternate-active-foreground: var(background);
|
||||
}
|
||||
|
||||
/*****----- Main Window -----*****/
|
||||
window {
|
||||
transparency: "real";
|
||||
location: center;
|
||||
anchor: center;
|
||||
fullscreen: false;
|
||||
width: 600px;
|
||||
x-offset: 0px;
|
||||
y-offset: 0px;
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 1px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
cursor: "default";
|
||||
background-color: @background-colour;
|
||||
}
|
||||
|
||||
/*****----- Main Box -----*****/
|
||||
mainbox {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
children: [ "inputbar", "message", "listview", "mode-switcher" ];
|
||||
}
|
||||
|
||||
/*****----- Inputbar -----*****/
|
||||
inputbar {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0px 0px 1px 0px;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: @alternate-background;
|
||||
text-color: @foreground-colour;
|
||||
children: [ "prompt", "entry" ];
|
||||
}
|
||||
|
||||
prompt {
|
||||
enabled: true;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
textbox-prompt-colon {
|
||||
enabled: true;
|
||||
expand: false;
|
||||
str: "::";
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
entry {
|
||||
enabled: true;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
cursor: text;
|
||||
placeholder: "Search...";
|
||||
placeholder-color: inherit;
|
||||
}
|
||||
|
||||
/*****----- Listview -----*****/
|
||||
listview {
|
||||
enabled: true;
|
||||
columns: 1;
|
||||
lines: 8;
|
||||
cycle: true;
|
||||
dynamic: true;
|
||||
scrollbar: false;
|
||||
layout: vertical;
|
||||
reverse: false;
|
||||
fixed-height: true;
|
||||
fixed-columns: true;
|
||||
spacing: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
cursor: "default";
|
||||
}
|
||||
scrollbar {
|
||||
handle-width: 5px;
|
||||
handle-color: @handle-colour;
|
||||
border-radius: 0px;
|
||||
background-color: @alternate-background;
|
||||
}
|
||||
|
||||
/*****----- Elements -----*****/
|
||||
element {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
cursor: pointer;
|
||||
}
|
||||
element normal.normal {
|
||||
background-color: var(normal-background);
|
||||
text-color: var(normal-foreground);
|
||||
}
|
||||
element normal.urgent {
|
||||
background-color: var(urgent-background);
|
||||
text-color: var(urgent-foreground);
|
||||
}
|
||||
element normal.active {
|
||||
background-color: var(active-background);
|
||||
text-color: var(active-foreground);
|
||||
}
|
||||
element selected.normal {
|
||||
background-color: var(selected-normal-background);
|
||||
text-color: var(selected-normal-foreground);
|
||||
}
|
||||
element selected.urgent {
|
||||
background-color: var(selected-urgent-background);
|
||||
text-color: var(selected-urgent-foreground);
|
||||
}
|
||||
element selected.active {
|
||||
background-color: var(selected-active-background);
|
||||
text-color: var(selected-active-foreground);
|
||||
}
|
||||
element alternate.normal {
|
||||
background-color: var(alternate-normal-background);
|
||||
text-color: var(alternate-normal-foreground);
|
||||
}
|
||||
element alternate.urgent {
|
||||
background-color: var(alternate-urgent-background);
|
||||
text-color: var(alternate-urgent-foreground);
|
||||
}
|
||||
element alternate.active {
|
||||
background-color: var(alternate-active-background);
|
||||
text-color: var(alternate-active-foreground);
|
||||
}
|
||||
element-icon {
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
size: 24px;
|
||||
cursor: inherit;
|
||||
}
|
||||
element-text {
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
highlight: inherit;
|
||||
cursor: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.0;
|
||||
}
|
||||
|
||||
/*****----- Mode Switcher -----*****/
|
||||
mode-switcher {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
button {
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: @alternate-background;
|
||||
text-color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
button selected {
|
||||
background-color: var(selected-normal-background);
|
||||
text-color: var(selected-normal-foreground);
|
||||
}
|
||||
|
||||
/*****----- Message -----*****/
|
||||
message {
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
textbox {
|
||||
font: "Inter 11";
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: @alternate-background;
|
||||
text-color: @foreground-colour;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.0;
|
||||
highlight: none;
|
||||
placeholder-color: @foreground-colour;
|
||||
blink: true;
|
||||
markup: true;
|
||||
}
|
||||
error-message {
|
||||
padding: 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: @background-colour;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"dynamic": "/services/traefik/dynamic",
|
||||
"entrypoint": "websecure",
|
||||
"certificate-resolver": "le",
|
||||
"machine": "host.docker.internal"
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# screen-lock (module screen-lock, novox/hq ADR 0208): the locker. xss-lock runs it on idle, before
|
||||
# suspend and on logind's Lock, and node-lock-screen's `lock` ends in it.
|
||||
#
|
||||
# The operator's look, adopted from the predecessor's my-i3lock: the screen as it was, blurred, with
|
||||
# an orange ring, the time and the date. That needs i3lock-color, from the distribution's user
|
||||
# repository, kept as found until the mesh carries such software (novox/hq research 027, question 1).
|
||||
# On a machine without it the distribution's i3lock shows the same blurred screen, taken here, with
|
||||
# its own plain ring; failing that, black.
|
||||
#
|
||||
# Before a suspend, xss-lock hands this script a lock on the sleep (XSS_SLEEP_LOCK_FD) and suspends
|
||||
# once it is released. The locker must not inherit it, or the machine would wait for the unlock
|
||||
# before sleeping; it is released once i3lock is up, so the machine never sleeps unlocked. This is
|
||||
# xss-lock's own documented pattern for i3lock.
|
||||
set -u
|
||||
|
||||
# One locker: a second press of the key, or a lock while locked, changes nothing.
|
||||
if pgrep -xu "$EUID" i3lock >/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# The colour build numbers its versions <n>.c.<n> (2.13.c.5); its version line never says "color".
|
||||
if i3lock --version 2>&1 | grep -qE '[0-9]\.c\.[0-9]'; then
|
||||
blank='#00000000' clear='#ffffff22' accent='#ca4a00' wrong='#880000bb' verifying='#bb00bbbb'
|
||||
options=(
|
||||
--insidever-color="$clear" --ringver-color="$verifying"
|
||||
--insidewrong-color="$clear" --ringwrong-color="$wrong"
|
||||
--inside-color="$blank" --ring-color="$accent" --line-color="$blank" --separator-color="$accent"
|
||||
--verif-color="$accent" --wrong-color="$accent" --time-color="$accent" --date-color="$accent"
|
||||
--layout-color="$accent" --keyhl-color="$wrong" --bshl-color="$wrong"
|
||||
--screen 1 --blur 5 --ring-width=7.0 --clock --indicator
|
||||
--time-str="%H:%M:%S" --date-str="%A, %Y-%m-%d"
|
||||
--time-font=sans-serif --date-font=sans-serif --verif-font=sans-serif
|
||||
--wrong-font=sans-serif --layout-font=sans-serif --keylayout 1
|
||||
--show-failed-attempts --ignore-empty-password
|
||||
)
|
||||
else
|
||||
options=(--color=000000 --show-failed-attempts --ignore-empty-password)
|
||||
shot="${XDG_RUNTIME_DIR:-/tmp}/screen-lock.png"
|
||||
if command -v magick >/dev/null && magick import -window root -resize 25% -blur 0x3 -resize 400% "$shot" 2>/dev/null; then
|
||||
options+=(--image="$shot")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -e /dev/fd/${XSS_SLEEP_LOCK_FD:--1} ]]; then
|
||||
kill_i3lock() { pkill -xu "$EUID" "$@" i3lock; }
|
||||
trap kill_i3lock TERM INT
|
||||
i3lock "${options[@]}" {XSS_SLEEP_LOCK_FD}<&-
|
||||
exec {XSS_SLEEP_LOCK_FD}<&-
|
||||
while kill_i3lock -0; do
|
||||
sleep 0.5
|
||||
done
|
||||
else
|
||||
trap 'kill %%' TERM INT
|
||||
i3lock --nofork "${options[@]}" &
|
||||
wait
|
||||
fi
|
||||
@@ -0,0 +1,8 @@
|
||||
# The lock screen (module screen-lock, novox/hq ADR 0208): the session locks after 30 minutes idle,
|
||||
# the displays go to standby and suspend then and off after an hour, and xss-lock runs the locker on
|
||||
# idle, before suspend and on logind's Lock. xss-lock needs this login session, so it starts here and
|
||||
# not as a unit. It is started again if it exits, for as long as this session lasts ($$ is the
|
||||
# session's own process, which becomes the window manager).
|
||||
xset s 1800 1800
|
||||
xset dpms 1800 1800 3600
|
||||
(while kill -0 $$ 2>/dev/null; do xss-lock --transfer-sleep-lock -- "$HOME/.local/bin/screen-lock"; sleep 2; done) &
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user