diff --git a/build_hm.sh b/build_hm.sh index b675d9d..08a672b 100755 --- a/build_hm.sh +++ b/build_hm.sh @@ -17,7 +17,7 @@ function help { echo " -h: Display this help message." } -while getopts "hvb" OPTION +while getopts "h" OPTION do case "$OPTION" in h) diff --git a/curacao/backup/backup.sh b/curacao/backup/backup.sh new file mode 100755 index 0000000..38448c2 --- /dev/null +++ b/curacao/backup/backup.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +# Parse arguments +function help { + echo "Usage: $0 [-h|-i] volume" + echo "Backup BTRFS subvolume on rapido to razmo." + echo + echo "Arguments:" + echo " volume: Name of the subvolume to backup" + echo + echo "Options:" + echo " -h: Display this help message." + echo " -i: Don't fail if the receiving subvolume doesn't exist." +} + +init=false +while getopts "hi" OPTION +do + case "$OPTION" in + h) + help + exit 0 + ;; + i) + init=true + ;; + ?) + help + exit 2 + ;; + esac +done +shift "$((OPTIND - 1))" + +if [ "$#" -ne 1 ] +then + help + exit 2 +fi +volume="$1" + +# Assertions +[ -d "/mnt/rapido/${volume}" ] +[ -d "/mnt/rapido/${volume}.bkp" ] || "$init" +[ ! -d "/mnt/rapido/${volume}.new" ] +[ -d "/mnt/razmo/${volume}.bkp" ] || "$init" +[ -d "/mnt/razmo/${volume}" ] || "$init" +[ ! -d "/mnt/razmo/${volume}.new" ] +[ ! -d "/mnt/razmo/${volume}.snapshots" ] + +# Taking a snapshot of the running subvolume +btrfs subvolume snapshot -r "/mnt/rapido/${volume}" "/mnt/rapido/${volume}.new" + +# Sending (the difference with) the last backup to the backup disk +function error_handler() { + btrfs subvolume delete "/mnt/rapido/${volume}.new" || true + btrfs subvolume delete "/mnt/razmo/${volume}.new" || true +} +trap error_handler ERR +if [ -d "/mnt/rapido/${volume}.bkp" ] +then + btrfs send -p "/mnt/rapido/${volume}.bkp" "/mnt/rapido/${volume}.new" | btrfs receive /mnt/razmo +else + btrfs send "/mnt/rapido/${volume}.new" | btrfs receive /mnt/razmo +fi +trap - ERR + +# Removing old backups and putting the new one in place +[ ! -d "/mnt/rapido/${volume}.bkp" ] || btrfs subvolume delete "/mnt/rapido/${volume}.bkp" +mv "/mnt/rapido/${volume}.new" "/mnt/rapido/${volume}.bkp" +[ ! -d "/mnt/razmo/${volume}.bkp" ] || btrfs subvolume delete "/mnt/razmo/${volume}.bkp" +mv "/mnt/razmo/${volume}.new" "/mnt/razmo/${volume}.bkp" + +# Create a writeable clone in case we need to boot on the HDD +# Needs to move away then back the .snapshots folder +[ ! -d "/mnt/razmo/${volume}/.snapshots" ] || mv "/mnt/razmo/${volume}/.snapshots" "/mnt/razmo/${volume}.snapshots" +[ ! -d "/mnt/razmo/${volume}" ] || btrfs subvolume delete "/mnt/razmo/${volume}" +btrfs subvolume snapshot "/mnt/razmo/${volume}.bkp" "/mnt/razmo/${volume}" +[ ! -d "/mnt/razmo/${volume}.snapshots" ] || mv "/mnt/razmo/${volume}.snapshots" "/mnt/razmo/${volume}/.snapshots" + +sync diff --git a/curacao/backup/default.nix b/curacao/backup/default.nix new file mode 100644 index 0000000..5041c60 --- /dev/null +++ b/curacao/backup/default.nix @@ -0,0 +1,64 @@ +{ pkgs, lib, ... }: +# MANU Snapper is not able to create the snapshot directory, so you'll need to do this after eventually running the backup script: +# sudo btrfs subvol create /mnt/razmo/$subvolume/.snapshots +let + backup_subvolumes = [ "nixos" "home.rapido" ]; + backup_app = pkgs.writeShellApplication { + name = "backup-subvolume"; + runtimeInputs = with pkgs; [ coreutils btrfs-progs ]; + text = builtins.readFile ./backup.sh; + }; + snapper_subvolumes = [ "nixos" "home.rapido" "home.razmo" ]; +in +{ + services = + let + default = { + # filesystem type + FSTYPE = "btrfs"; + + # run daily number cleanup + NUMBER_CLEANUP = true; + NUMBER_MIN_AGE = 1800; + NUMBER_LIMIT = 25; + + # create hourly snapshots + TIMELINE_CREATE = true; + + # cleanup hourly snapshots after some time + TIMELINE_CLEANUP = true; + TIMELINE_MIN_AGE = 1800; + TIMELINE_LIMIT_HOURLY = 24; + TIMELINE_LIMIT_DAILY = 31; + TIMELINE_LIMIT_WEEKLY = 8; + TIMELINE_LIMIT_MONTHLY = 0; + TIMELINE_LIMIT_YEARLY = 0; + + # cleanup empty pre-post-pairs + EMPTY_PRE_POST_CLEANUP = true; + }; + in + { + snapper.configs = lib.attrsets.mergeAttrsList (map (s: { "${s}" = default // { SUBVOLUME = "/mnt/razmo/${s}"; }; }) snapper_subvolumes); + }; + + + systemd = { + services.bkp_rapido = { + description = "Make a snapshot of the SSD to the HDD"; + before = [ "snapper-timeline.service" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = map (s: "${backup_app}/bin/backup-subvolume ${s}") backup_subvolumes; + }; + # TODO Harden + }; + timers.bkp_rapido = { + description = "Regular snapshot of SSD to HDD"; + timerConfig = { + OnCalendar = "hourly"; + }; + wantedBy = [ "timers.target" ]; + }; + }; +} diff --git a/curacao/dk.nix b/curacao/dk.nix new file mode 100644 index 0000000..d730d35 --- /dev/null +++ b/curacao/dk.nix @@ -0,0 +1,190 @@ +{ passwordFile ? "/should_not_be_needed_in_this_context", ... }: +# TODO Find a way to use keys in filesystem +# TODO Not relatime everywhere, thank you +# TODO Default options +let + btrfs_args_hdd = [ + "rw" + "relatime" + "compress=zstd:3" + "space_cache" + ]; + btrfs_args_ssd = btrfs_args_hdd ++ [ "ssd" ]; +in +{ + disko.devices = { + disk = { + razmo = { + type = "disk"; + device = "/dev/disk/by-id/ata-ST1000LM048-2E7172_WKP8925H"; + content = { + type = "gpt"; + partitions = { + swap = { + priority = 10; + start = "2048"; + size = "6G"; + content = { + type = "swap"; + randomEncryption = true; + # TODO NixOS documentation says not to use this with + # hibernation, as it can't set the partition where the + # hibernation image is saved. That's what I'm doing with Arch, + # but I'm setting resume=, should test if it actually works? + # Untranslated options from /etc/crypttab: swap,cipher=aes-xts-plain64,size=256 + # Untranslated options from /etc/fstab: defaults,pri=100 + }; + }; + nixosboot = { + priority = 15; + size = "2G"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + esp = { + priority = 20; + size = "128M"; + type = "EF00"; # EFI system partition + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/efi"; + mountOptions = [ + "rw" + "relatime" + "fmask=0022" + "dmask=0022" + "codepage=437" + "iocharset=iso8859-1" + "shortname=mixed" + "utf8" + "errors=remount-ro" + "noauto" + ]; + }; + }; + boot = { + priority = 30; + size = "128M"; + content = { + type = "luks"; + name = "boot"; + extraFormatArgs = [ "--type luks1" ]; + passwordFile = passwordFile; + settings = { + # keyFile = "/etc/keys/boot"; + }; + content = { + type = "filesystem"; + format = "ext2"; + mountpoint = "/mnt/old/boot"; + mountOptions = [ + "rw" + "relatime" + # "stripe=4" # For some reason doesn't work on NixOS + ]; + }; + }; + }; + main = { + priority = 40; + content = { + type = "luks"; + name = "razmo"; + passwordFile = passwordFile; + settings = { + # keyFile = "/etc/keys/razmo"; + }; + content = { + type = "btrfs"; + # extraArgs = [ "-f" ]; + mountpoint = "/mnt/razmo"; + mountOptions = btrfs_args_hdd; + subvolumes = { + "home.razmo" = { + mountpoint = "/home.heavy"; + mountOptions = btrfs_args_hdd; + }; + }; + }; + }; + }; + }; + }; + }; + rapido = { + type = "disk"; + device = "/dev/disk/by-id/nvme-GIGABYTE_GP-GSM2NE3256GNTD_SN204508906665"; + content = { + type = "gpt"; + partitions = { + swap = { + priority = 10; + start = "2048"; + size = "8G"; + type = "8200"; # Linux swap + content = { + type = "luks"; + name = "rapswap"; + passwordFile = passwordFile; + settings = { + # keyFile = "/etc/keys/rapswap"; + allowDiscards = true; + }; + content = { + type = "swap"; + resumeDevice = true; + # Untranslated options from /etc/fstab: defaults,pri=100 + }; + }; + }; + main = { + priority = 20; + content = { + type = "luks"; + name = "rapido"; + initrdUnlock = true; + passwordFile = passwordFile; + settings = { + # keyFile = "/etc/keys/rapido"; + allowDiscards = true; + }; + content = { + type = "btrfs"; + # extraArgs = [ "-f" ]; + mountpoint = "/mnt/rapido"; + mountOptions = btrfs_args_ssd; + subvolumes = { + archlinux = { + mountpoint = "/mnt/old"; + mountOptions = btrfs_args_ssd; + }; + # Should be temporary, to make sure we can revert to Arch anytime + "home.nixos" = { + mountpoint = "/home"; + mountOptions = btrfs_args_ssd; + }; + "home.rapido" = { + mountpoint = "/mnt/old/home"; + mountOptions = btrfs_args_ssd; + }; + nix = { + mountpoint = "/nix"; + mountOptions = btrfs_args_ssd; + }; + nixos = { + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/curacao/hardware.nix b/curacao/hardware.nix index 996cf10..f439fa7 100644 --- a/curacao/hardware.nix +++ b/curacao/hardware.nix @@ -10,6 +10,8 @@ grub = { enable = true; efiSupport = true; + device = "nodev"; # Don't install on MBR + # TODO Maybe we could? In case the HDD doesn't boot anymore? }; }; } diff --git a/curacao/options.nix b/curacao/options.nix index 6bed395..45ab31a 100644 --- a/curacao/options.nix +++ b/curacao/options.nix @@ -3,15 +3,14 @@ frogeye = { desktop = { xorg = true; - x11_screens = [ "HDMI-1-0" "eDP1" ]; + x11_screens = [ "HDMI-1-0" "eDP-1" ]; maxVideoHeight = 1440; numlock = true; phasesBrightness = { enable = true; - backlight = "intel_backlight"; - jour = 40000; - crepuscule = 10000; - nuit = 1; + jour = "40000"; + crepuscule = "10000"; + nuit = "1"; }; }; dev = { diff --git a/curacao/os.nix b/curacao/os.nix index 3bd283d..3f81444 100644 --- a/curacao/os.nix +++ b/curacao/os.nix @@ -5,7 +5,14 @@ ./options.nix ./hardware.nix ./dk.nix + ./backup ]; networking.hostName = "curacao"; + boot = { + initrd.luks.reusePassphrases = true; + loader = { + efi.efiSysMountPoint = "/efi"; + }; + }; } diff --git a/ensure_nix.sh b/ensure_nix.sh new file mode 100755 index 0000000..2e7d206 --- /dev/null +++ b/ensure_nix.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# Runs the command given in a Nix environment, and create it if it doesn't exist. +# Useful for environments where nix isn't installed / you do not have root access + +# If you need a fresh slate: +# chmod +w .nix -R +# rm -rf .nix .nix-defexpr .nix-profile .config/nix .local/state/nix .local/share/nix .cache/nix + +set -euo pipefail +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +if [ ! -d /nix ] +then + # Doesn't support architectures other than x86_64 + NIX_USER_CHROOT_URL=https://github.com/nix-community/nix-user-chroot/releases/download/1.2.2/nix-user-chroot-bin-1.2.2-x86_64-unknown-linux-musl + NIX_USER_CHROOT_SHA256SUM=e11aff604bb8d3ffd1d9c0c68cd636816d7eb8da540de18ee3a41ccad7ac0972 + + nix_user_chroot="$HOME/.local/bin/nix-user-chroot" + mkdir -p "$(dirname "$nix_user_chroot")" + + nix_directory="$HOME/.nix" + mkdir -p "$nix_directory" + + if [ ! -x "$nix_user_chroot" ] || ! echo "$NIX_USER_CHROOT_SHA256SUM $nix_user_chroot" | sha256sum --check --status + then + wget "$NIX_USER_CHROOT_URL" -O "$nix_user_chroot" + echo "$NIX_USER_CHROOT_SHA256SUM $nix_user_chroot" | sha256sum --check --status + chmod +x "$nix_user_chroot" + fi + exec "$nix_user_chroot" "$nix_directory" "$0" "$@" + exit 1 +fi + +nix_profile_path="$HOME/.nix-profile/etc/profile.d/nix.sh" + +if [ ! -f "$nix_profile_path" ] +then + NIX_INSTALLER_URL=https://releases.nixos.org/nix/nix-2.19.2/install + NIX_INSTALLER_SHA256SUM=435f0d7e11f7c7dffeeab0ec9cc55723f6d3c03352379d785633cf4ddb5caf90 + + nix_installer="$(mktemp)" + + wget "$NIX_INSTALLER_URL" -O "$nix_installer" + echo "$NIX_INSTALLER_SHA256SUM $nix_installer" | sha256sum --check --status + chmod +x "$nix_installer" + + "$nix_installer" --no-daemon --yes --no-channel-add --no-modify-profile +fi + +. "$nix_profile_path" + +"${SCRIPT_DIR}/add_channels.sh" + +exec "$@" diff --git a/hm/common.nix b/hm/common.nix index 4235502..b0bf872 100644 --- a/hm/common.nix +++ b/hm/common.nix @@ -54,13 +54,13 @@ in TIME_STYLE = "+%Y-%m-%d %H:%M:%S"; # Less colors LESS = "-R"; - LESS_TERMCAP_mb = "$'\E[1;31m'"; # begin blink - LESS_TERMCAP_md = "$'\E[1;36m'"; # begin bold - LESS_TERMCAP_me = "$'\E[0m'"; # reset bold/blink - LESS_TERMCAP_so = "$'\E[01;44;33m'"; # begin reverse video - LESS_TERMCAP_se = "$'\E[0m'"; # reset reverse video - LESS_TERMCAP_us = "$'\E[1;32m'"; # begin underline - LESS_TERMCAP_ue = "$'\E[0m'"; # reset underline + LESS_TERMCAP_mb = "$(echo $'\\E[1;31m')"; # begin blink + LESS_TERMCAP_md = "$(echo $'\\E[1;36m')"; # begin bold + LESS_TERMCAP_me = "$(echo $'\\E[0m')"; # reset bold/blink + LESS_TERMCAP_so = "$(echo $'\\E[01;44;33m')"; # begin reverse video + LESS_TERMCAP_se = "$(echo $'\\E[0m')"; # reset reverse video + LESS_TERMCAP_us = "$(echo $'\\E[1;32m')"; # begin underline + LESS_TERMCAP_ue = "$(echo $'\\E[0m')"; # reset underline # Fzf FZF_COMPLETION_OPTS = "${lib.strings.concatStringsSep " " config.programs.fzf.fileWidgetOptions}"; }; @@ -138,7 +138,7 @@ in # TODO Maybe make nixpkg wrapper instead? So it also works from dmenu # Could also accept my fate... Home-manager doesn't necessarily make it easy to put things out of the home directory historySize = 100000; - historyFile = "${config.xdg.cacheHome}/shell_history"; + historyFile = "${config.xdg.stateHome}/shell_history"; in { @@ -196,7 +196,10 @@ in duration = "$( test -n \"$__TIMER\" && echo $(( $EPOCHREALTIME - $\{__TIMER:-EPOCHREALTIME})) || echo 0 )"; # UPST Implement this properly in home-manager, would allow for bash support }; - extraUpdatePS1 = ''unset __TIMER''; + extraUpdatePS1 = '' + unset __TIMER + echo -en "\033]0; $USER@$HOST $PWD\007" + ''; }; gpg = { enable = true; @@ -245,6 +248,7 @@ in less.enable = true; git = { enable = true; + package = pkgs.gitFull; aliases = { "git" = "!exec git"; # In case I write one too many git }; @@ -339,9 +343,9 @@ in enableZshIntegration = true; pinentryFlavor = "gtk2"; # Falls back to curses when needed }; - # TODO Doesn't activate units by default. For now, we'll consider this as a safety feature. + # TODO Syncs a bit too often, also constantly asks for passphrase, which is annoying. git-sync = { - enable = true; + enable = false; repositories = { dotfiles = { path = "${config.xdg.configHome}/dotfiles"; @@ -408,6 +412,7 @@ in powerline-go # terminal essentials + file moreutils man unzip @@ -462,7 +467,6 @@ in khard khal todoman - syncthing # TODO Lots of redundancy with other way things are defined here @@ -472,8 +476,8 @@ in ]; sessionVariables = { # Favourite commands - PAGER = "${pkgs.less}/bin/less"; - EDITOR = "${pkgs.neovim}/bin/nvim"; + PAGER = "less"; + EDITOR = "nvim"; # Extra config BOOT9_PATH = "${config.xdg.dataHome}/citra-emu/sysdata/boot9.bin"; @@ -489,7 +493,7 @@ in YARN_DISABLE_SELF_UPDATE_CHECK = "true"; # This also disable the creation of a ~/.yarnrc file } // lib.optionalAttrs config.frogeye.desktop.xorg { # Favourite commands - VISUAL = "${pkgs.neovim}/bin/nvim"; + VISUAL = "nvim"; BROWSER = "${config.programs.qutebrowser.package}/bin/qutebrowser"; # Extra config @@ -503,7 +507,7 @@ in (builtins.toString ./scripts) ]; file = { - ".face" = { + ".face" = { # TODO Doesn't show on NixOS. See https://wiki.archlinux.org/title/LightDM#Changing_your_avatar ? source = pkgs.runCommand "face.png" { } "${pkgs.inkscape}/bin/inkscape ${./face.svg} -w 1024 -o $out"; }; }; diff --git a/hm/desktop.nix b/hm/desktop.nix index 926e14c..50ce109 100644 --- a/hm/desktop.nix +++ b/hm/desktop.nix @@ -37,7 +37,7 @@ in # lockColors = with config.lib.stylix.colors.withHashtag; { a = base00; b = base01; d = base00; }; # Black or White, depending on current theme # lockColors = with config.lib.stylix.colors.withHashtag; { a = base0A; b = base0B; d = base00; }; # Green + Yellow lockColors = { a = "#82a401"; b = "#466c01"; d = "#648901"; }; # Old - lockSvg = pkgs.writeText "lock.svg" ""; + lockSvg = pkgs.writeText "lock.svg" ""; lockPng = pkgs.runCommand "lock.png" { } "${pkgs.imagemagick}/bin/convert ${lockSvg} $out"; locker = pkgs.writeShellScript "i3-locker" '' @@ -48,6 +48,7 @@ in ${pkgs.lightdm}/bin/dm-tool lock # TODO Does that work for all DMs? + # TODO Might want to use i3lock on NixOS configs still? if [ $? -ne 0 ]; then if [ -d ${config.xdg.cacheHome}/lockpatterns ] then @@ -79,9 +80,13 @@ in mode_pres_sec = "Presentation (secondary display)"; mode_screen = "Screen setup [A] Auto [L] Load [S] Save [R] Remove [D] Default"; mode_temp = "Temperature [R] Red [D] Dust storm [C] Campfire [O] Normal [A] All nighter [B] Blue"; + fonts = config.stylix.fonts; in { modifier = "Mod4"; + fonts = { + names = [ fonts.sansSerif.name ]; + }; terminal = "alacritty"; colors = let ignore = "#ff00ff"; in with config.lib.stylix.colors.withHashtag; lib.mkForce { @@ -144,6 +149,9 @@ in "XF86AudioPrev" = "exec ${pkgs.mpc-cli}/bin/mpc prev"; "XF86AudioPlay" = "exec ${pkgs.mpc-cli}/bin/mpc toggle"; "XF86AudioNext" = "exec ${pkgs.mpc-cli}/bin/mpc next"; + # Backlight + "XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%"; + "XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-"; # Misc "${mod}+F10" = "exec ${ pkgs.writeShellScript "show-keyboard-layout" '' @@ -512,7 +520,7 @@ in autorandr = { enable = true; hooks.postswitch = { - background = "${pkgs.feh}/bin/feh --no-fehbg --bg-fill ${config.stylix.image}"; + background = "${pkgs.feh}/bin/feh --no-fehbg --bg-fill ${config.stylix.image}"; }; }; mpv = { @@ -520,12 +528,18 @@ in config = { audio-display = false; save-position-on-quit = true; - osc = false; # # Required by thumbnail script + osc = false; # Required by thumbnail script + # Hardware acceleration (from https://nixos.wiki/wiki/Accelerated_Video_Playback#MPV) + hwdec = "auto-safe"; + vo = "gpu"; + profile = "gpu-hq"; }; scripts = with pkgs.mpvScripts; [ thumbnail ]; scriptOpts = { mpv_thumbnail_script = { + autogenerate = false; # TODO It creates too many processes at once, crashing the system cache_directory = "/tmp/mpv_thumbs_${config.home.username}"; + mpv_hwdec = "auto-safe"; }; }; }; @@ -534,7 +548,7 @@ in xdg = { mimeApps = { enable = true; - associations.added = { + defaultApplications = { "text/html" = "org.qutebrowser.qutebrowser.desktop"; "x-scheme-handler/http" = "org.qutebrowser.qutebrowser.desktop"; "x-scheme-handler/https" = "org.qutebrowser.qutebrowser.desktop"; @@ -583,6 +597,7 @@ in }; }; services = { + blueman-applet.enable = true; unclutter.enable = true; dunst = { @@ -625,7 +640,6 @@ in network = { listenAddress = "0.0.0.0"; # So it can be controlled from home # TODO ... and whoever is the Wi-Fi network I'm using, which, not great - port = 8601; # FIXME Chose a different one for testing, should revert startWhenNeeded = true; }; extraConfig = '' @@ -637,6 +651,8 @@ in home = { packages = with pkgs; [ + pavucontrol # Because can't use Win+F1X on Pinebook 🙃 + # remote tigervnc @@ -673,7 +689,6 @@ in xclip keynav xorg.xinit - xorg.xbacklight # TODO Make this clean. Service? diff --git a/hm/dev.nix b/hm/dev.nix index f98bcf9..648d7a7 100644 --- a/hm/dev.nix +++ b/hm/dev.nix @@ -6,7 +6,6 @@ home.packages = with pkgs; [ # Common perf-tools - git jq yq universal-ctags diff --git a/hm/extra.nix b/hm/extra.nix index b346f05..84002cf 100644 --- a/hm/extra.nix +++ b/hm/extra.nix @@ -19,6 +19,9 @@ # android tools android-tools + # Communication + signal-desktop + # downloading # transmission TODO Collision if both transmissions are active? @@ -61,5 +64,8 @@ # https://hydra.nixos.org/job/nixos/release-23.11/nixpkgs.blender.aarch64-linux blender ]); + services = { + syncthing.enable = true; + }; }; } diff --git a/hm/scripts/bsh b/hm/scripts/bsh index 9ad639b..dc1780a 100755 --- a/hm/scripts/bsh +++ b/hm/scripts/bsh @@ -1,6 +1,4 @@ -#!/usr/bin/env nix-shell -#! nix-shell -i bash --pure -#! nix-shell -p bash openssh coreutils gawk gnused +#!/usr/bin/env bash # TODO More integrated with current config @@ -44,13 +42,17 @@ then grep -o '^\s*[^#]*' $SCRIPT_DIR/.bsh/inputrc | sed 's/^\s\+//' > "${WORK}/i" grep -o '^\s*[^"]*' $SCRIPT_DIR/.bsh/vimrc | sed 's/^\s\+//' > "${WORK}/v" - # Crafting command - b64="$(cd "$CACHE_DIR"; tar czf - "$FOLDER_NAME" | base64 -w 0)" - echo "echo $b64|base64 -d|tar xzC /tmp" > "${CACHE_DIR}/cmd" - echo "bash --rcfile ${DEST}/b" >> "${CACHE_DIR}/cmd" - echo "rm -rf ${DEST}" >> "${CACHE_DIR}/cmd" + # Creating entrypoint + echo "bash --rcfile ${DEST}/b" > "${WORK}/e" + echo "rm -rf ${DEST}" >> "${WORK}/e" # TODO Do not remove unless last one connected + # Crafting command + b64="$(cd "$CACHE_DIR"; tar czf - --sort=name "$FOLDER_NAME" | base64 -w 0)" + echo "echo $b64|base64 -d|tar xzC /tmp" > "${CACHE_DIR}/cmd" + # Due to magic, if the last command executed is bash, it disappears from the list of processes + echo "sh ${DEST}/e" >> "${CACHE_DIR}/cmd" + # Cleanup rm -rf "$WORK" diff --git a/hm/scripts/ter b/hm/scripts/ter index 01fbc3b..9fe1f59 100755 --- a/hm/scripts/ter +++ b/hm/scripts/ter @@ -2,6 +2,8 @@ #! nix-shell -i python3 --pure #! nix-shell -p python3 +# vim: set filetype=python : + import sys from math import inf @@ -14,11 +16,11 @@ if N < 2: sys.exit(1) -def trajet_str(a, b): +def trajet_str(a: int, b: int) -> str: return f"{gares[a]} → {gares[b]}" -def chemin_str(stack): +def chemin_str(stack: list[int]) -> str: return ", ".join( [trajet_str(stack[i], stack[i + 1]) for i in range(len(stack) - 1)] ) @@ -26,7 +28,7 @@ def chemin_str(stack): # Demande des prix des trajets -prices = dict() +prices: dict[int, dict[int, float]] = dict() for i in range(N): for j in range(N - 1, i, -1): @@ -50,7 +52,7 @@ maxiPrice = -inf maxiStack = None -def register_path(stack): +def register_path(stack: list[int]) -> None: price = sum([prices[stack[i]][stack[i + 1]] for i in range(len(stack) - 1)]) global miniPrice, maxiPrice, miniStack, maxiStack @@ -72,5 +74,7 @@ while stack[0] == 0: else: stack.append(stack[-1] + 1) +assert miniStack +assert maxiStack print(f"Prix minimum: {chemin_str(miniStack)} = {miniPrice:.2f} €") print(f"Prix maximum: {chemin_str(maxiStack)} = {maxiPrice:.2f} €") diff --git a/hm/style.nix b/hm/style.nix index a98707b..e73c6d1 100644 --- a/hm/style.nix +++ b/hm/style.nix @@ -3,7 +3,8 @@ let # Currently last commit in https://github.com/danth/stylix/pull/194 stylix = builtins.fetchTarball "https://github.com/willemml/stylix/archive/2ed2b0086b41d582aca26e083c19c0e47c8991e3.tar.gz"; polarityFile = "${config.xdg.stateHome}/theme_polarity"; - polarity = if builtins.pathExists polarityFile then lib.strings.fileContents polarityFile else "light"; + polarityFromFile = if builtins.pathExists polarityFile then lib.strings.fileContents polarityFile else "light"; + polarity = if config.frogeye.polarity == "dynamic" then polarityFromFile else config.frogeye.polarity; phases = [ { command = "jour"; polarity = "light"; } { command = "crepuscule"; polarity = "dark"; } @@ -47,19 +48,21 @@ in dconf.enable = false; # Otherwise standalone home-manager complains it can't find /etc/dbus-1/session.conf on Arch. # Symlinking it to /usr/share/dbus-1/session.conf goes further but not much. - # TODO Use xbacklight instead (pindakaas doesn't seem to support it OOTB) home.packages = map (phase: (pkgs.writeShellApplication { name = "${phase.command}"; + runtimeInputs = [ pkgs.brightnessctl ]; text = (lib.optionalString cfg.enable '' - echo ${builtins.toString (builtins.getAttr phase.command cfg)} | sudo tee /sys/class/backlight/${cfg.backlight}/brightness - '') + '' + brightnessctl set ${builtins.getAttr phase.command cfg} + '') + '' echo ${phase.polarity} > ${polarityFile} if command -v home-manager then home-manager switch else - sudo nixos-rebuild switch + # In two steps to get the visual changes slightly earlier + sudo /nix/var/nix/profiles/system/specialisation/${phase.polarity}/bin/switch-to-configuration test + sudo /nix/var/nix/profiles/system/specialisation/${phase.polarity}/bin/switch-to-configuration boot fi ''; }) diff --git a/install_os.sh b/install_os.sh index 577e688..0091fa9 100755 --- a/install_os.sh +++ b/install_os.sh @@ -96,13 +96,6 @@ echo "{ ... }: { imports = [ ./hardware-configuration.nix ${nixos_config} ]; }" # Install NixOS! Or create a new generation. sudo nixos-install --no-root-password --root "$mountpoint" -# Install dotfiles. Actually not needed by nixos-install since it doesn't rewrite global paths to the mountpoint. -# Without it no nixos-rebuild from the system itself once installed though. -# Should probably be replaced with something like git-sync -# sudo mkdir -p $mountpoint/home/geoffrey/.config/ -# sudo cp -a ../dotfiles $mountpoint/home/geoffrey/.config/ -# sudo chown geoffrey:geoffrey $mountpoint/home/geoffrey -R - set +x # Signal the installation is done! @@ -113,3 +106,4 @@ echo "- Boot into the system" echo "- Transfer necessary private keys (or use ssh -A for testing)" echo "- Run git-sync-init" echo "- Check that the system can build itself" +echo "- Change root and user password" diff --git a/options.nix b/options.nix index 4b2a554..0321786 100644 --- a/options.nix +++ b/options.nix @@ -3,11 +3,16 @@ options.frogeye = { extra = lib.mkEnableOption "Big software"; gaming = lib.mkEnableOption "Games"; + polarity = lib.mkOption { + default = "dynamic"; + description = "Whether to use light theme or dark theme."; + type = lib.types.enum [ "dynamic" "light" "dark" ]; + }; desktop = { xorg = lib.mkEnableOption "Enable X11 support"; numlock = lib.mkEnableOption "Auto-enable numlock"; x11_screens = lib.mkOption { - default = ["UNSET1"]; + default = [ "UNSET1" ]; description = "A list of xrandr screen names from left to right."; type = lib.types.listOf lib.types.str; }; @@ -19,10 +24,9 @@ }; phasesBrightness = { enable = lib.mkEnableOption "Set a specific brightness for the screen when running phases commands"; - backlight = lib.mkOption { type = lib.types.str; description = "Name of the backlight device"; }; - jour = lib.mkOption { type = lib.types.int; description = "brightness value for phase: jour"; }; - crepuscule = lib.mkOption { type = lib.types.int; description = "brightness value for phase: crepuscule"; }; - nuit = lib.mkOption { type = lib.types.int; description = "brightness value for phase: nuit"; }; + jour = lib.mkOption { type = lib.types.str; default = "100%"; description = "brightnessctl value for phase: jour"; }; + crepuscule = lib.mkOption { type = lib.types.str; default = "50%"; description = "brightnessctl value for phase: crepuscule"; }; + nuit = lib.mkOption { type = lib.types.str; default = "1%"; description = "brightnessctl value for phase: nuit"; }; }; }; dev = { diff --git a/os/common.nix b/os/common.nix index 5719d75..e4dd9a1 100644 --- a/os/common.nix +++ b/os/common.nix @@ -4,8 +4,7 @@ time.timeZone = "Europe/Amsterdam"; - # Might fill emptiness? - boot.consoleLogLevel = 6; # KERN_INFO + boot.tmp.cleanOnBoot = true; # TODO qwerty-fr for console @@ -25,10 +24,8 @@ environment.systemPackages = with pkgs; [ wget kexec-tools - openvpn - - # Needed for all the fetchFromGit in this repo on nixos-rebuild - git + neovim # So we have a working editor in rescue mode + git # Needed for all the fetchFromGit in this repo on nixos-rebuild ]; nixpkgs.config.allowUnfree = true; @@ -39,7 +36,7 @@ ccache.enable = true; # TODO Not enough, see https://nixos.wiki/wiki/CCache. # Might want to see if it's worth using on NixOS - gnupg.agent.enable = true; + less.lessopen = null; # Don't use lessopen # Let users mount disks udevil.enable = true; @@ -64,9 +61,6 @@ # TODO Hibernation? - # TEST - system.copySystemConfiguration = true; - # Use defaults from system.stateVersion = "23.11"; diff --git a/os/desktop.nix b/os/desktop.nix index ab3b08c..f361cc0 100644 --- a/os/desktop.nix +++ b/os/desktop.nix @@ -3,16 +3,18 @@ config = lib.mkIf config.frogeye.desktop.xorg { # Enable the X11 windowing system - services.xserver = { - enable = true; - windowManager.i3.enable = true; - displayManager.defaultSession = "none+i3"; + services = { + blueman.enable = true; + xserver = { + enable = true; + windowManager.i3.enable = true; + displayManager.defaultSession = "none+i3"; - # Keyboard layout - extraLayouts.qwerty-fr = { - description = "QWERTY-fr"; - languages = [ "fr" ]; - symbolsFile = "${pkgs.stdenv.mkDerivation { + # Keyboard layout + extraLayouts.qwerty-fr = { + description = "QWERTY-fr"; + languages = [ "fr" ]; + symbolsFile = "${pkgs.stdenv.mkDerivation { name = "qwerty-fr-keypad"; src = builtins.fetchGit { url = "https://github.com/qwerty-fr/qwerty-fr.git"; @@ -27,13 +29,17 @@ runHook postInstall ''; }}/linux/us_qwerty-fr"; + }; + layout = "qwerty-fr"; }; - layout = "qwerty-fr"; }; - # Enable sound + # Enable sound & bluetooth sound.enable = true; - hardware.pulseaudio.enable = true; + hardware = { + bluetooth.enable = true; + pulseaudio.enable = true; + }; # UPST # TODO Find a way to override packages either at NixOS level or HM level depending on what is used diff --git a/os/geoffrey.nix b/os/geoffrey.nix index cd27181..a860d42 100644 --- a/os/geoffrey.nix +++ b/os/geoffrey.nix @@ -1,9 +1,11 @@ -{ pkgs, config, ... }: +{ pkgs, lib, config, ... }: { imports = [ ]; + users.users.root.initialHashedPassword = "$y$j9T$e64bjL7iyVlniEKwKbM9g0$cCn74za0r6L9QMO20Fdxz3/SX0yvhz3Xd6.2BhtbRL1"; # Not a real password + users.users.geoffrey = { isNormalUser = true; extraGroups = [ "adbusers" "wheel" ]; @@ -32,6 +34,12 @@ useGlobalPkgs = true; }; + specialisation = { + dark.configuration.frogeye.polarity = "dark"; + light.configuration.frogeye.polarity = "light"; + }; + + # Because everything is encrypted and I'm the only user, this is fine. services.xserver.displayManager.autoLogin.user = "geoffrey"; } diff --git a/os/wireless/import.py b/os/wireless/import.py index 85ac1d5..d4535be 100755 --- a/os/wireless/import.py +++ b/os/wireless/import.py @@ -1,4 +1,6 @@ -#!/usr/bin/env python3 +#!/usr/bin/env nix-shell +#! nix-shell -i python3 +#! nix-shell -p python3 python3Packages.pyaml """ Exports Wi-Fi networks configuration stored in pass into a format readable by Nix. @@ -19,7 +21,7 @@ import yaml # passpy doesn't handle encoding properly, so doing this with calls -PASSWORD_STORE = os.path.expanduser("~/.password-store") +PASSWORD_STORE = os.path.expanduser("~/.local/share/pass") SUBFOLDER = "wifi" SEPARATE_PASSWORDS = False # TODO Find a way to make then env file available at whatever time it is needed diff --git a/pindakaas/options.nix b/pindakaas/options.nix index 2f7df32..56b5eba 100644 --- a/pindakaas/options.nix +++ b/pindakaas/options.nix @@ -7,10 +7,9 @@ maxVideoHeight = 720; phasesBrightness = { enable = true; - backlight = "edp-backlight"; - jour = 3500; - crepuscule = 3000; - nuit = 700; + jour = "3500"; + crepuscule = "3000"; + nuit = "700"; }; }; } diff --git a/unprocessed/config/automatrop/roles/system/files/getty.service b/unprocessed/config/automatrop/roles/system/files/getty.service deleted file mode 100644 index 1d6b77a..0000000 --- a/unprocessed/config/automatrop/roles/system/files/getty.service +++ /dev/null @@ -1,2 +0,0 @@ -[Service] -ExecStartPre=/bin/sh -c 'setleds +num < /dev/%I' diff --git a/unprocessed/config/automatrop/roles/system/files/xorg/intel_backlight.conf b/unprocessed/config/automatrop/roles/system/files/xorg/intel_backlight.conf deleted file mode 100644 index 36f6eb5..0000000 --- a/unprocessed/config/automatrop/roles/system/files/xorg/intel_backlight.conf +++ /dev/null @@ -1,5 +0,0 @@ -Section "Device" - Identifier "Intel Graphics" - Driver "intel" - Option "Backlight" "intel_backlight" -EndSection diff --git a/unprocessed/config/automatrop/roles/system/tasks/main.yml b/unprocessed/config/automatrop/roles/system/tasks/main.yml index 002d579..4a012d1 100644 --- a/unprocessed/config/automatrop/roles/system/tasks/main.yml +++ b/unprocessed/config/automatrop/roles/system/tasks/main.yml @@ -1,28 +1,5 @@ # Xorg configuration -- name: Check if there is Intel backlight - ansible.builtin.stat: - path: /sys/class/backlight/intel_backlight - register: intel_backlight - when: display_server == 'x11' - -- name: Install Intel video drivers (Arch based) - community.general.pacman: - name: xf86-video-intel - # state: "{{ intel_backlight.stat.exists }}" - state: present - become: true - when: display_server == 'x11' and intel_backlight.stat.exists and arch_based - # TODO With software role? Would permit other distributions - -- name: Configure Xorg Intel backlight - ansible.builtin.copy: - src: xorg/intel_backlight.conf - dest: "{{ item }}/20-intel_backlight.conf" - become: true - when: display_server == 'x11' and intel_backlight.stat.exists - loop: "{{ xorg_common_config_dirs }}" - - name: Configure Xorg joystick behaviour ansible.builtin.copy: src: xorg/joystick.conf @@ -48,23 +25,3 @@ vars: using_panfrost: "{{ 'panfrost' in (modules.content | b64decode) }}" notify: panfrost config changed - -# Numlock on boot - -- name: Set numlock on boot - ansible.builtin.copy: - src: getty.service - dest: /etc/systemd/system/getty@.service.d/override.conf - become: true - notify: - - systemd changed - when: auto_numlock - -- name: Unset numlock on boot - ansible.builtin.file: - path: /etc/systemd/system/getty@.service.d/override.conf - state: absent - become: true - notify: - - systemd changed - when: not auto_numlock