Set up waybar and building ISOs.

This commit is contained in:
Tom Alexander 2024-12-21 10:18:28 -05:00
parent a7f3754d25
commit a0f9f4baa4
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
13 changed files with 500 additions and 131 deletions

View File

@ -1,3 +1,4 @@
# ISO does not work with systemd initrd yet https://github.com/NixOS/nixpkgs/pull/291750
{ {
config, config,
lib, lib,
@ -8,16 +9,43 @@
{ {
imports = [ ]; imports = [ ];
boot.loader.grub.enable = false; config = lib.mkIf (!config.me.buildingIso) {
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
# TODO: make not write bootx64.efi
boot.loader.efi.canTouchEfiVariables = false;
# Automatically delete old generations boot.loader.grub.enable = false;
boot.loader.systemd-boot.configurationLimit = 3; # Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
# TODO: make not write bootx64.efi
boot.loader.efi.canTouchEfiVariables = false;
# Automatically delete old generations
boot.loader.systemd-boot.configurationLimit = 3;
# Check what will be lost with `zfs diff zroot/linux/root@blank`
boot.initrd.systemd.enable = lib.mkDefault true;
boot.initrd.systemd.services.zfs-rollback = {
description = "Rollback ZFS root dataset to blank snapshot";
wantedBy = [
"initrd.target"
];
after = [
"zfs-import-zroot.service"
];
before = [
"sysroot.mount"
];
path = with pkgs; [
zfs
];
unitConfig.DefaultDependencies = "no";
serviceConfig.Type = "oneshot";
script = ''
zfs rollback -r zroot/linux/nix/root@blank
zfs rollback -r zroot/linux/nix/home@blank
echo "rollback complete"
'';
};
};
} }
# efibootmgr -c -d /dev/sda -p 1 -L NixOS-boot -l '\EFI\NixOS-boot\grubx64.efi' # efibootmgr -c -d /dev/sda -p 1 -L NixOS-boot -l '\EFI\NixOS-boot\grubx64.efi'
# Text-only: # Text-only:

View File

@ -10,6 +10,7 @@
{ {
imports = [ imports = [
./roles/reset ./roles/reset
./roles/iso
./hosts/odo ./hosts/odo
"${ "${
builtins.fetchTarball { builtins.fetchTarball {
@ -30,6 +31,8 @@
./roles/git ./roles/git
./roles/fonts ./roles/fonts
./roles/gpg ./roles/gpg
./roles/waybar
./roles/qemu
]; ];
nix.settings.experimental-features = [ nix.settings.experimental-features = [
@ -134,38 +137,17 @@
]; ];
}; };
# Check what will be lost with `zfs diff zroot/linux/root@blank` environment.persistence."/persist" = lib.mkIf (!config.me.buildingIso) {
boot.initrd.systemd.enable = lib.mkDefault true;
boot.initrd.systemd.services.zfs-rollback = {
description = "Rollback ZFS root dataset to blank snapshot";
wantedBy = [
"initrd.target"
];
after = [
"zfs-import-zroot.service"
];
before = [
"sysroot.mount"
];
path = with pkgs; [
zfs
];
unitConfig.DefaultDependencies = "no";
serviceConfig.Type = "oneshot";
script = ''
zfs rollback -r zroot/linux/nix/root@blank
zfs rollback -r zroot/linux/nix/home@blank
echo "rollback complete"
'';
};
environment.persistence."/persist" = {
hideMounts = true; hideMounts = true;
directories = [ directories = [
"/var/lib/iwd" # Wifi settings "/var/lib/iwd" # Wifi settings
"/var/lib/nixos" # Contains user information (uids/gids) "/var/lib/nixos" # Contains user information (uids/gids)
"/var/lib/systemd" # Systemd state directory for random seed, persistent timers, core dumps, persist hardware state like backlight and rfkill
"/var/log/journal" # Logs, alternatively set `services.journald.storage = "volatile";` to write to /run/log/journal
"/etc/zfs/zpool.cache" # Which zpools to import, the root zpool is already imported and does not need this cache file but this captures additional pools. TODO consider setting cachefile=none on main pool.
]; ];
files = [ files = [
"/etc/machine-id" # Systemd unique machine id "otherwise, the system journal may fail to list earlier boots, etc"
"/etc/ssh/ssh_host_rsa_key" "/etc/ssh/ssh_host_rsa_key"
"/etc/ssh/ssh_host_rsa_key.pub" "/etc/ssh/ssh_host_rsa_key.pub"
"/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key"

View File

@ -1,5 +1,30 @@
# Build ISO image # Build ISO image
# doas nix run github:nix-community/nixos-generators -- --flake .#odo --format iso # nix build --extra-experimental-features nix-command --extra-experimental-features flakes .#iso.odo
# output: result/iso/nixos.iso
# Run the ISO image
# "$(nix-build '<nixpkgs>' --no-out-link -A 'qemu')/bin/qemu-system-x86_64" \
# -accel kvm \
# -cpu host \
# -smp cores=8 \
# -m 32768 \
# -drive "file=$(nix-build '<nixpkgs>' --no-out-link -A 'OVMF.fd')/FV/OVMF.fd,if=pflash,format=raw,readonly=on" \
# -drive if=pflash,format=raw,file="/tmp/OVMF_VARS.fd" \
# -nic user,hostfwd=tcp::60022-:22 \
# -boot order=d \
# -cdrom "$(readlink -f ./result/iso/nixos.iso)" \
# -display vnc=127.0.0.1:0
#
# doas cp "$(nix-build '<nixpkgs>' --no-out-link -A 'OVMF.fd')/FV/OVMF_VARS.fd" /tmp/OVMF_VARS.fd
# doas "$(nix-build '<nixpkgs>' --no-out-link -A 'qemu')/bin/qemu-system-x86_64" -accel kvm -cpu host -smp cores=8 -m 32768 -drive "file=$(nix-build '<nixpkgs>' --no-out-link -A 'OVMF.fd')/FV/OVMF.fd,if=pflash,format=raw,readonly=on" -drive if=pflash,format=raw,file="/tmp/OVMF_VARS.fd" -nic user,hostfwd=tcp::60022-:22 -boot order=d -cdrom /persist/machine_setup/nix/configuration/result/iso/nixos.iso -display vnc=127.0.0.1:0
# Get a repl for this flake
# nix repl --expr "builtins.getFlake \"$PWD\""
# TODO maybe use `nix eval --raw .#iso.odo.outPath`
# iso.odo.isoName == "nixos.iso"
# full path = <outPath> / iso / <isoName>
{ {
description = "My system configuration"; description = "My system configuration";
@ -23,17 +48,14 @@
... ...
}@inputs: }@inputs:
let let
base-system = { }; base_x86_64_linux = rec {
odoqemu = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = { specialArgs = {
pkgs-b93b4e9b5 = import nixpkgs-b93b4e9b5 { pkgs-b93b4e9b5 = import nixpkgs-b93b4e9b5 {
inherit system; inherit system;
# config.allowUnfree = true;
}; };
pkgs-unstable = import nixpkgs-unstable { pkgs-unstable = import nixpkgs-unstable {
inherit system; inherit system;
# config.allowUnfree = true;
}; };
}; };
modules = [ modules = [
@ -44,88 +66,30 @@
home-manager.useUserPackages = true; home-manager.useUserPackages = true;
} }
./configuration.nix ./configuration.nix
(
{ lib, ... }:
{
imports = [ <nixpkgs/nixos/modules/virtualisation/qemu-vm.nix> ];
virtualisation.qemu.options = [
"-device virtio-vga"
];
virtualisation.vmVariant = {
# following configuration is added only when building VM with build-vm
virtualisation = {
memorySize = 2048; # Use 2048MiB memory.
cores = 3;
graphics = false;
};
};
networking.dhcpcd.enable = lib.mkForce true;
networking.useDHCP = lib.mkForce true;
boot.loader.efi.canTouchEfiVariables = lib.mkForce true;
# doas nixos-rebuild build-vm --flake .#odoqemu
#./result/bin/run-nixos-vm
}
)
]; ];
}; };
odo = nixpkgs.lib.nixosSystem rec { systems = {
system = "x86_64-linux"; odo = {
specialArgs = { main = nixpkgs.lib.nixosSystem (base_x86_64_linux // { });
pkgs-b93b4e9b5 = import nixpkgs-b93b4e9b5 { iso = nixpkgs.lib.nixosSystem (
inherit system; base_x86_64_linux
# config.allowUnfree = true; // {
}; modules = base_x86_64_linux.modules ++ [
pkgs-unstable = import nixpkgs-unstable { (nixpkgs + "/nixos/modules/installer/cd-dvd/iso-image.nix")
inherit system; # TODO: maybe? imports = [ "${modulesPath}/profiles/image-based-appliance.nix" ];
# config.allowUnfree = true; {
}; isoImage.makeEfiBootable = true;
isoImage.makeUsbBootable = true;
me.buildingIso = true;
}
];
}
);
}; };
modules = [
impermanence.nixosModules.impermanence
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
}
./configuration.nix
];
}; };
in in
{ {
# doas nix build --extra-experimental-features nix-command --extra-experimental-features flakes .#vms.odo nixosConfigurations.odo = systems.odo.main;
# ./result/bin/run-nixos-vim iso.odo = systems.odo.iso.config.system.build.isoImage;
vms.odo = odoqemu.config.system.build.vm;
odoiso = odo.config.system.build.isoImage;
nixosConfigurations.odo = odo;
nixosConfigurations.odovm = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux";
specialArgs = {
pkgs-b93b4e9b5 = import nixpkgs-b93b4e9b5 {
inherit system;
# config.allowUnfree = true;
};
pkgs-unstable = import nixpkgs-unstable {
inherit system;
# config.allowUnfree = true;
};
};
modules = [
impermanence.nixosModules.impermanence
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
}
./configuration.nix
(
{ lib, ... }:
{
networking.dhcpcd.enable = lib.mkForce true;
networking.useDHCP = lib.mkForce true;
boot.loader.efi.canTouchEfiVariables = lib.mkForce true;
}
)
];
};
}; };
} }

View File

@ -1,4 +1,11 @@
{ {
config,
lib,
pkgs,
...
}:
lib.mkIf (!config.me.buildingIso) {
disko.devices = { disko.devices = {
disk = { disk = {
main = { main = {

View File

@ -61,7 +61,7 @@ in
}; };
}; };
environment.persistence."/state" = { environment.persistence."/state" = lib.mkIf (!config.me.buildingIso) {
hideMounts = true; hideMounts = true;
users.talexander = { users.talexander = {
directories = [ directories = [

View File

@ -84,7 +84,7 @@
}; };
}; };
environment.persistence."/persist" = { environment.persistence."/persist" = lib.mkIf (!config.me.buildingIso) {
hideMounts = true; hideMounts = true;
users.talexander = { users.talexander = {
directories = [ directories = [
@ -97,7 +97,7 @@
]; ];
}; };
}; };
environment.persistence."/state" = { environment.persistence."/state" = lib.mkIf (!config.me.buildingIso) {
hideMounts = true; hideMounts = true;
users.talexander = { users.talexander = {
directories = [ directories = [

View File

@ -18,7 +18,7 @@
enableSSHSupport = true; enableSSHSupport = true;
}; };
environment.persistence."/persist" = { environment.persistence."/persist" = lib.mkIf (!config.me.buildingIso) {
hideMounts = true; hideMounts = true;
users.talexander = { users.talexander = {
directories = [ directories = [

View File

@ -0,0 +1,18 @@
{
config,
lib,
pkgs,
...
}:
{
imports = [ ];
options.me.buildingIso = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = "Whether we are building an ISO image.";
};
}

View File

@ -0,0 +1,14 @@
{
config,
lib,
pkgs,
...
}:
{
imports = [ ];
environment.systemPackages = with pkgs; [
qemu
];
}

View File

@ -44,6 +44,8 @@ let
include ${disable-focus-follows-mouse} include ${disable-focus-follows-mouse}
include ${background} include ${background}
include ${touchpad_input} include ${touchpad_input}
include ${waybar}
include ${announce_sway_start}
''; '';
}; };
base-hotkeys = pkgs.writeTextFile { base-hotkeys = pkgs.writeTextFile {
@ -229,6 +231,36 @@ let
} }
''; '';
}; };
waybar = pkgs.writeTextFile {
name = "waybar.conf";
text = ''
#
# Status Bar:
#
# Read `man 5 sway-bar` for more information about this section.
bar {
position top
font pango:Cascadia Mono, FontAwesome 10
swaybar_command waybar
colors {
statusline #ffffff
background #323232
inactive_workspace #32323200 #32323200 #5c5c5c
}
}
'';
};
announce_sway_start = pkgs.writeTextFile {
name = "announce_sway_start.conf";
text = ''
# announce a running sway session to systemd
exec systemctl --user import-environment XDG_SESSION_TYPE XDG_CURRENT_DESKTOP
exec dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
'';
};
start_screen_share = pkgs.writeShellScriptBin "start_screen_share" '' start_screen_share = pkgs.writeShellScriptBin "start_screen_share" ''
# Disable displaying notifications. This is useful for video conference screen sharing. # Disable displaying notifications. This is useful for video conference screen sharing.
set -euo pipefail set -euo pipefail
@ -261,23 +293,37 @@ in
stop_screen_share stop_screen_share
]; ];
environment.sessionVariables = { # Probably would be cleaner to use environment.sessionVariables but programs.sway.extraSessionCommands is sway-specific.
# WLR_RENDERER_ALLOW_SOFTWARE = "1"; programs.sway.extraSessionCommands =
WLR_RENDERER = "vulkan"; if config.me.buildingIso then
}; ''
export WLR_RENDERER_ALLOW_SOFTWARE=1;
''
else
''
export WLR_RENDERER=vulkan
'';
programs.sway = { programs.sway = {
enable = true; enable = true;
wrapperFeatures.gtk = true; wrapperFeatures.gtk = true;
extraOptions = [ extraOptions =
"--debug" if config.me.buildingIso then
"--config" [
"${sway-config}" "--debug"
# "--unsupported-gpu" "--config"
]; "${sway-config}"
"--unsupported-gpu"
]
else
[
"--debug"
"--config"
"${sway-config}"
];
}; };
environment.persistence."/state" = { environment.persistence."/state" = lib.mkIf (!config.me.buildingIso) {
hideMounts = true; hideMounts = true;
users.talexander = { users.talexander = {
files = [ files = [
@ -293,6 +339,20 @@ in
xdg-desktop-portal-wlr xdg-desktop-portal-wlr
xdg-desktop-portal-gtk xdg-desktop-portal-gtk
]; ];
wlr = {
enable = true;
settings = {
# uninteresting for this problem, for completeness only
screencast = {
# output_name = "eDP-1";
max_fps = 30;
exec_before = "${start_screen_share}";
exec_after = "${stop_screen_share}";
chooser_type = "simple";
chooser_cmd = "${pkgs.slurp}/bin/slurp -f %o -or";
};
};
};
}; };
}; };
} }

View File

@ -0,0 +1,28 @@
{
config,
lib,
pkgs,
...
}:
{
imports = [ ];
environment.systemPackages = with pkgs; [
waybar
];
home-manager.users.talexander =
{ pkgs, ... }:
{
home.file = {
".config/waybar/config" = {
source = ./files/waybar_config.json;
};
".config/waybar/style.css" = {
source = ./files/style.css;
};
};
};
}

View File

@ -0,0 +1,211 @@
/* Work-around for regressions introduced in 0.9.15 */
* {
all: unset;
}
/* Reset all styles */
* {
border: none;
border-radius: 0;
min-height: 0;
margin: 0;
padding: 0;
}
/* -----------------------------------------------------------------------------
* Keyframes
* -------------------------------------------------------------------------- */
@keyframes blink-warning {
70% {
color: white;
}
to {
color: white;
background-color: orange;
}
}
@keyframes blink-critical {
70% {
color: white;
}
to {
color: white;
background-color: red;
}
}
/* -----------------------------------------------------------------------------
* Base styles
* -------------------------------------------------------------------------- */
/* The whole bar */
#waybar {
background: #323232;
color: white;
font-family:
Cascadia Mono,
monospace;
font-size: 10px;
}
tooltip {
background-color: #323232;
}
/* Each module */
#battery,
#clock,
#cpu,
#custom-available_memory,
#custom-battery,
#custom-clock,
#custom-night_mode,
#custom-sound,
#custom-temperature,
#idle_inhibitor,
#memory,
#mode,
#network,
#pulseaudio,
#temperature,
#tray {
padding-left: 10px;
padding-right: 10px;
border: 1px solid white;
}
/* -----------------------------------------------------------------------------
* Module styles
* -------------------------------------------------------------------------- */
#battery {
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#custom-battery.warning {
color: orange;
}
#custom-battery.critical {
color: red;
}
#battery.warning.discharging {
animation-name: blink-warning;
animation-duration: 3s;
}
#battery.critical.discharging {
animation-name: blink-critical;
animation-duration: 2s;
}
#clock {
font-weight: bold;
}
#custom-clock {
font-weight: bold;
}
#cpu {
/* No styles */
}
#cpu.warning {
color: orange;
}
#cpu.critical {
color: red;
}
#memory {
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#memory.warning {
color: orange;
}
#memory.critical {
color: red;
animation-name: blink-critical;
animation-duration: 2s;
}
#mode {
background: #64727d;
border-top: 2px solid white;
/* To compensate for the top border and still have vertical centering */
padding-bottom: 2px;
}
#window {
padding-left: 10px;
padding-right: 10px;
}
#network {
/* No styles */
}
#network.disconnected {
color: orange;
}
#pulseaudio {
/* No styles */
}
#pulseaudio.muted {
/* No styles */
}
#custom-spotify {
color: rgb(102, 220, 105);
}
#temperature {
/* No styles */
}
#temperature.critical {
color: red;
}
#tray {
/* No styles */
}
#window {
font-weight: bold;
}
#workspaces button {
border-top: 2px solid transparent;
/* To compensate for the top border and still have vertical centering */
padding-bottom: 2px;
padding-left: 10px;
padding-right: 10px;
color: #888888;
}
#workspaces button.focused {
border-color: #4c7899;
color: white;
background-color: #285577;
}
#workspaces button.urgent {
border-color: #c9545d;
color: #c9545d;
}

View File

@ -0,0 +1,57 @@
{
// "height": 10, // Waybar height (to be removed for auto height)
"modules-left": ["sway/workspaces", "sway/mode"],
"modules-center": ["sway/window"],
"modules-right": ["custom/night_mode", "custom/temperature", "custom/sound", "custom/available_memory", "custom/battery", "idle_inhibitor", "custom/clock", "tray"],
"sway/workspaces": {
"disable-scroll": true
},
"sway/mode": {
"format": "<span style=\"italic\">{}</span>"
},
"sway/window": {
"format": "{title}"
},
"idle_inhibitor": {
"format": "{icon}",
"format-icons": {
"activated": "☕",//
"deactivated": "💤"//💤
}
},
"tray": {
// "icon-size": 21,
"spacing": 10
},
"custom/clock": {
"exec": "waybar_custom_clock",
"return-type": "json",
"restart-interval": 30
},
"custom/battery": {
"exec": "waybar_custom_battery",
"return-type": "json",
"restart-interval": 30
},
"custom/available_memory": {
"exec": "waybar_custom_available_memory",
"return-type": "json",
"restart-interval": 30
},
"custom/sound": {
"exec": "waybar_custom_sound",
"return-type": "json",
"restart-interval": 30
},
"custom/temperature": {
"exec": "waybar_custom_temperature",
"return-type": "json",
"restart-interval": 30
},
"custom/night_mode": {
"exec": "waybar_night_mode",
"return-type": "json",
"restart-interval": 30,
"on-click": "pkill -USR1 -f waybar_night_mode"
}
}