diff options
52 files changed, 956 insertions, 230 deletions
diff --git a/configs/alacritty.nix b/configs/alacritty.nix index 1a8eb92..473592a 100644 --- a/configs/alacritty.nix +++ b/configs/alacritty.nix @@ -36,11 +36,6 @@ let mouse.hide_when_typing = true; scrolling.multiplier = 8; }; - configs.root = lib.recursiveUpdate configs.default { - colors.primary.background = "#230000"; - colors.primary.foreground = "#e0c0c0"; - colors.normal.black = "#800000"; - }; configs.fzmenu = lib.recursiveUpdate configs.default { colors.primary.background = "#2A172A"; window.dimensions.columns = 70; diff --git a/configs/bash/default.nix b/configs/bash/default.nix index 0ec6bf0..70c94da 100644 --- a/configs/bash/default.nix +++ b/configs/bash/default.nix @@ -23,18 +23,7 @@ case $UID in ${mylib.shell.escape (toString config.krebs.users.tv.uid)}) if test ''${SHLVL-1} = 1 && test -n "''${DISPLAY-}"; then - _CURRENT_DESKTOP_NAME=''${_CURRENT_DESKTOP_NAME-$( - ${pkgs.xorg.xprop}/bin/xprop -notype -root \ - 32i _NET_CURRENT_DESKTOP \ - 8s _NET_DESKTOP_NAMES \ - | - ${pkgs.gnused}/bin/sed -r 's/.* = //;s/"//g;s/, /\a/g' | - { - read -r _NET_CURRENT_DESKTOP - IFS=$'\a' read -ra _NET_DESKTOP_NAMES - echo "''${_NET_DESKTOP_NAMES[$_NET_CURRENT_DESKTOP]}" - } - )} + _CURRENT_DESKTOP_NAME=''${_CURRENT_DESKTOP_NAME-$(${pkgs.xextras}/bin/net-current-desktop)} case $_CURRENT_DESKTOP_NAME in hrm) cd ~/hrm diff --git a/configs/default.nix b/configs/default.nix index 06fd83a..fb8627d 100644 --- a/configs/default.nix +++ b/configs/default.nix @@ -19,6 +19,7 @@ ./ssh.nix ./sshd.nix ./tmux.nix + ./variables.nix ./vim.nix ./xdg.nix { diff --git a/configs/earlyoom.nix b/configs/earlyoom.nix new file mode 100644 index 0000000..1249c7a --- /dev/null +++ b/configs/earlyoom.nix @@ -0,0 +1,10 @@ +{ lib, ... }: { + services.earlyoom.enable = true; + systemd.services.earlyoom.environment.EARLYOOM_ARGS = lib.mkForce (toString [ + "-m 5" + "-s 10" + "-r 0" + "--prefer '(^|/)chromium$'" + ]); + +} diff --git a/configs/gitconfig.nix b/configs/gitconfig.nix index c4111ed..1965427 100644 --- a/configs/gitconfig.nix +++ b/configs/gitconfig.nix @@ -6,7 +6,7 @@ markEmptyLines = false stripLeadingSymbols = false [pager] - diff = ${pkgs.gitAndTools.diff-so-fancy}/bin/diff-so-fancy \ + diff = ${pkgs.diff-so-fancy}/bin/diff-so-fancy \ | ${pkgs.less}/bin/less -FRX [user] email = tv@krebsco.de diff --git a/configs/gitrepos.nix b/configs/gitrepos.nix index 0e61989..174e303 100644 --- a/configs/gitrepos.nix +++ b/configs/gitrepos.nix @@ -126,7 +126,7 @@ hc = {}; mime = {}; quipper = {}; - scanner = {}; + terminal-scanner = {}; wai-middleware-time = {}; web-routes-wai-custom = {}; xintmap = {}; diff --git a/configs/hw/AO753.nix b/configs/hw/AO753.nix index ea58c01..5e91564 100644 --- a/configs/hw/AO753.nix +++ b/configs/hw/AO753.nix @@ -41,7 +41,4 @@ ''; krebs.nixpkgs.allowUnfreePredicate = pkg: packageName pkg == "broadcom-sta"; - - tv.hw.screens.primary.width = 1366; - tv.hw.screens.primary.height = 768; } diff --git a/configs/hw/winmax2.nix b/configs/hw/winmax2.nix index 4bcd6f1..7edad5a 100644 --- a/configs/hw/winmax2.nix +++ b/configs/hw/winmax2.nix @@ -21,10 +21,6 @@ hardware.enableRedistributableFirmware = true; hardware.graphics.enable = true; - hardware.graphics.extraPackages = [ - pkgs.amdvlk - pkgs.rocmPackages.clr - ]; networking.wireless.enable = true; networking.wireless.interfaces = [ @@ -36,12 +32,9 @@ services.illum.enable = true; - services.logind.extraConfig = /* ini */ '' - HandlePowerKey=ignore - ''; + services.logind.settings.Login = { + HandlePowerKey = "ignore"; + }; tv.lidControl.enable = true; - - tv.hw.screens.primary.width = 2560; - tv.hw.screens.primary.height = 1600; } diff --git a/configs/hw/x220.nix b/configs/hw/x220.nix index 6ae6cec..6cd9641 100644 --- a/configs/hw/x220.nix +++ b/configs/hw/x220.nix @@ -49,7 +49,12 @@ # Required for Centrino. hardware.enableRedistributableFirmware = true; - hardware.graphics.extraPackages = [ pkgs.vaapiIntel pkgs.vaapiVdpau ]; + hardware.graphics = { + extraPackages = [ + pkgs.intel-vaapi-driver + pkgs.libva-vdpau-driver + ]; + }; hardware.trackpoint = { enable = true; @@ -64,25 +69,17 @@ services.tlp.enable = true; services.tlp.settings = { START_CHARGE_THRESH_BAT0 = 80; + WOL_DISABLE = false; }; - - services.logind.extraConfig = '' - HandleHibernateKey=ignore - HandleLidSwitch=ignore - HandlePowerKey=ignore - HandleSuspendKey=ignore - ''; - - # because extraConfig is not extra enough: - services.logind.lidSwitch = "ignore"; - services.logind.lidSwitchDocked = "ignore"; - services.logind.lidSwitchExternalPower = "ignore"; + services.logind.settings.Login.HandleHibernateKey = "ignore"; + services.logind.settings.Login.HandleLidSwitch = "ignore"; + services.logind.settings.Login.HandleLidSwitchDocked = "ignore"; + services.logind.settings.Login.HandleLidSwitchExternalPower = "ignore"; + services.logind.settings.Login.HandlePowerKey = "ignore"; + services.logind.settings.Login.HandleSuspendKey = "ignore"; services.xserver = { videoDriver = "intel"; }; - - tv.hw.screens.primary.width = lib.mkDefault 1366; - tv.hw.screens.primary.height = lib.mkDefault 768; } diff --git a/configs/pulse.nix b/configs/pulse.nix index 9c317ae..1ccbf82 100644 --- a/configs/pulse.nix +++ b/configs/pulse.nix @@ -75,7 +75,7 @@ in ]; }; - hardware.pulseaudio = { + services.pulseaudio = { inherit support32Bit; }; @@ -94,11 +94,10 @@ in }; serviceConfig = { ExecStart = "${pkg}/bin/pulseaudio --exit-idle-time=-1"; - ExecStartPre = pkgs.writeDash "pulse-start" '' + ExecStartPre = "+${pkgs.writeDash "pulse-start" '' install -o pulse -g pulse -m 0750 -d ${runDir} install -o pulse -g pulse -m 0700 -d ${runDir}/home - ''; - PermissionsStartOnly = "true"; + ''}"; User = "pulse"; }; }; diff --git a/configs/repo-sync/wiki.nix b/configs/repo-sync/wiki.nix index 94f7e80..01e03f0 100644 --- a/configs/repo-sync/wiki.nix +++ b/configs/repo-sync/wiki.nix @@ -1,6 +1,7 @@ { config, lib, mylib, pkgs, ... }: { krebs.repo-sync.enable = true; krebs.repo-sync.repos.wiki.branches.hotdog = { + smart = true; origin.url = "http://cgit.hotdog.r/wiki"; mirror.url = "git@${config.krebs.build.host.name}.r:wiki"; }; diff --git a/configs/variables.nix b/configs/variables.nix new file mode 100644 index 0000000..cdfaceb --- /dev/null +++ b/configs/variables.nix @@ -0,0 +1,19 @@ +{ config, lib, ... }: { + options.hrm.environment.variables = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = {}; + description = '' + This is a stricter version of `environment.variables`, using + `escapeShellArg` instead of `"` for quoting. + + Use this when you don't have the need to reference other variables or + inject code into `/nix/store/*-set-environment`. This is also useful + for variables that need be used in contexts that don't perform shell + initialization, like e.g. `systemd.services.*.environment`; + ''; + }; + config.environment.variables = + lib.mapAttrs + (_name: value: ''"${lib.escapeShellArg value}"'') + config.hrm.environment.variables; +} diff --git a/configs/wiregrill.nix b/configs/wiregrill.nix index 55bb6f5..ee73061 100644 --- a/configs/wiregrill.nix +++ b/configs/wiregrill.nix @@ -8,8 +8,8 @@ in lib.mkIf cfg.enable { networking.wireguard.interfaces.wiregrill = { ips = - lib.optional (cfg.net.ip4 != null) cfg.net.ip4.addr ++ - lib.optional (cfg.net.ip6 != null) cfg.net.ip6.addr; + lib.optional (cfg.net.ip4 != null) (toCidrNotation cfg.net.ip4) ++ + lib.optional (cfg.net.ip6 != null) (toCidrNotation cfg.net.ip6); listenPort = 51820; privateKeyFile = "${config.krebs.secret.directory}/wiregrill.key"; allowedIPsAsRoutes = true; diff --git a/configs/xserver/default.nix b/configs/xserver/default.nix index 884a982..88c1afb 100644 --- a/configs/xserver/default.nix +++ b/configs/xserver/default.nix @@ -6,13 +6,11 @@ user = config.krebs.build.user; xmonad.pkg = pkgs.haskellPackages.xmonad-tv.overrideAttrs (_: { au = { - XMONAD_BUILD_SCREEN_WIDTH = 1920; XMONAD_BUILD_TERM_FONT_WIDTH = 10; XMONAD_BUILD_TERM_FONT = "xft:Input Mono:size=12:style=Regular"; XMONAD_BUILD_TERM_PADDING = 2; }; }.${config.krebs.build.host.name} or { - XMONAD_BUILD_SCREEN_WIDTH = 1366; XMONAD_BUILD_TERM_FONT_WIDTH = 6; XMONAD_BUILD_TERM_FONT = "-*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1"; XMONAD_BUILD_TERM_PADDING = 2; diff --git a/modules/backup.nix b/modules/backup.nix new file mode 100644 index 0000000..37f8e67 --- /dev/null +++ b/modules/backup.nix @@ -0,0 +1,252 @@ +{ config, lib, pkgs, ... }: +with import ../lib/pure.nix { inherit lib; }; +let + out = { + options.krebs.backup = api; + config = lib.mkIf cfg.enable imp; + }; + + cfg = config.krebs.backup; + + api = { + enable = mkEnableOption "krebs.backup" // { default = true; }; + plans = mkOption { + default = {}; + type = types.attrsOf (types.submodule ({ config, ... }: { + options = { + enable = mkEnableOption "krebs.backup.${config._module.args.name}" // { + default = true; + }; + method = mkOption { + type = types.enum ["pull" "push"]; + }; + name = mkOption { + type = types.str; + default = config._module.args.name; + defaultText = "‹name›"; + }; + src = mkOption { + type = types.krebs.file-location; + }; + dst = mkOption { + type = types.krebs.file-location; + }; + startAt = mkOption { + default = "hourly"; + type = with types; nullOr str; # TODO systemd.time(7)'s calendar event + }; + snapshots = mkOption { + default = { + hourly = { format = "%Y-%m-%dT%H"; retain = 4; }; + daily = { format = "%Y-%m-%d"; retain = 7; }; + weekly = { format = "%YW%W"; retain = 4; }; + monthly = { format = "%Y-%m"; retain = 12; }; + yearly = { format = "%Y"; }; + }; + type = types.attrsOf (types.submodule { + options = { + format = mkOption { + type = types.str; # TODO date's +FORMAT + }; + retain = mkOption { + type = types.nullOr types.int; + default = null; # null = retain all snapshots + }; + }; + }); + }; + timerConfig = mkOption { + type = with types; attrsOf str; + default = optionalAttrs (config.startAt != null) { + OnCalendar = config.startAt; + }; + }; + }; + })); + }; + }; + + imp = { + krebs.on-failure.plans = + listToAttrs (map (plan: nameValuePair "backup.${plan.name}" { + }) (filter (plan: build-host-is "pull" "dst" plan || + build-host-is "push" "src" plan) + enabled-plans)); + + systemd.services = + listToAttrs (map (plan: nameValuePair "backup.${plan.name}" { + # TODO if there is plan.user, then use its privkey + # TODO push destination users need a similar path + path = with pkgs; [ + coreutils + gnused + openssh + rsync + util-linux + ]; + restartIfChanged = false; + serviceConfig = rec { + ExecStart = start plan; + SyslogIdentifier = ExecStart.name; + Type = "oneshot"; + }; + }) (filter (plan: build-host-is "pull" "dst" plan || + build-host-is "push" "src" plan) + enabled-plans)); + + systemd.timers = + listToAttrs (map (plan: nameValuePair "backup.${plan.name}" { + wantedBy = [ "timers.target" ]; + timerConfig = plan.timerConfig; + }) (filter (plan: plan.timerConfig != {} && ( + build-host-is "pull" "dst" plan || + build-host-is "push" "src" plan)) + enabled-plans)); + + users.groups.backup.gid = genid "backup"; + users.users.root.openssh.authorizedKeys.keys = + map (plan: getAttr plan.method { + push = plan.src.host.ssh.pubkey; + pull = plan.dst.host.ssh.pubkey; + }) (filter (plan: build-host-is "pull" "src" plan || + build-host-is "push" "dst" plan) + enabled-plans); + }; + + enabled-plans = filter (getAttr "enable") (attrValues cfg.plans); + + build-host-is = method: side: plan: + plan.method == method && + config.krebs.build.host.name == plan.${side}.host.name; + + start = plan: let + login-name = "root"; + identity = local.host.ssh.privkey.path; + ssh = "ssh -i ${shell.escape identity}"; + local = getAttr plan.method { + push = plan.src // { rsync = src-rsync; }; + pull = plan.dst // { rsync = dst-rsync; }; + }; + remote = getAttr plan.method { + push = plan.dst // { rsync = dst-rsync; }; + pull = plan.src // { rsync = src-rsync; }; + }; + src-rsync = "rsync"; + dst-rsync = concatStringsSep " && " [ + "stat ${shell.escape plan.dst.path} >/dev/null" + "mkdir -m 0700 -p ${shell.escape plan.dst.path}/current" + "flock -n ${shell.escape plan.dst.path} rsync" + ]; + in pkgs.writeBash "backup.${plan.name}" '' + set -efu + start_date=$(date +%s) + ssh_target=${shell.escape login-name}@$(${fastest-address remote.host}) + ${getAttr plan.method { + push = '' + rsync_src=${shell.escape plan.src.path} + rsync_dst=$ssh_target:${shell.escape plan.dst.path} + echo >&2 "update snapshot current; $rsync_src -> $rsync_dst" + ''; + pull = '' + rsync_src=$ssh_target:${shell.escape plan.src.path} + rsync_dst=${shell.escape plan.dst.path} + echo >&2 "update snapshot current; $rsync_dst <- $rsync_src" + ''; + }} + # In `dst-rsync`'s `mkdir m 0700 -p` above, we care only about permission + # of the deepest directory: + # shellcheck disable=SC2174 + ${local.rsync} >&2 \ + -aAX --delete \ + --filter='dir-merge /.backup-filter' \ + --rsh=${shell.escape ssh} \ + --rsync-path=${shell.escape remote.rsync} \ + --link-dest=${shell.escape plan.dst.path}/current \ + "$rsync_src/" \ + "$rsync_dst/.partial" + + dst_exec() { + ${getAttr plan.method { + push = ''exec ${ssh} "$ssh_target" -T "exec$(printf ' %q' "$@")"''; + pull = ''exec "$@"''; + }} + } + dst_exec env \ + start_date="$start_date" \ + flock -n ${shell.escape plan.dst.path} \ + /bin/sh < ${toFile "backup.${plan.name}.take-snapshots" '' + set -efu + : $start_date + + dst_path=${shell.escape plan.dst.path} + + mv "$dst_path/current" "$dst_path/.previous" + mv "$dst_path/.partial" "$dst_path/current" + rm -fR "$dst_path/.previous" + echo >&2 + + snapshot() {( + : $ns $format $retain + name=$(date --date="@$start_date" +"$format") + if ! test -e "$dst_path/$ns/$name"; then + echo >&2 "create snapshot: $ns/$name" + mkdir -m 0700 -p "$dst_path/$ns" + rsync >&2 \ + -aAX --delete \ + --filter='dir-merge /.backup-filter' \ + --link-dest="$dst_path/current" \ + "$dst_path/current/" \ + "$dst_path/$ns/.partial.$name" + mv "$dst_path/$ns/.partial.$name" "$dst_path/$ns/$name" + echo >&2 + fi + case $retain in + ([0-9]*) + delete_from=$(($retain + 1)) + ls -r "$dst_path/$ns" \ + | sed -n "$delete_from,\$p" \ + | while read old_name; do + echo >&2 "delete snapshot: $ns/$old_name" + rm -fR "$dst_path/$ns/$old_name" + done + ;; + (ALL) + : + ;; + esac + )} + + ${concatStringsSep "\n" (mapAttrsToList (ns: { format, retain, ... }: + toString (map shell.escape [ + "ns=${ns}" + "format=${format}" + "retain=${if retain == null then "ALL" else toString retain}" + "snapshot" + ])) + plan.snapshots)} + ''} + ''; + + # XXX Is one ping enough to determine fastest address? + fastest-address = host: '' + { ${pkgs.fping}/bin/fping </dev/null -a -e \ + ${concatMapStringsSep " " shell.escape + (mapAttrsToList (_: net: head net.aliases) host.nets)} \ + | ${pkgs.gnused}/bin/sed -r 's/^(\S+) \(([0-9.]+) ms\)$/\2\t\1/' \ + | ${pkgs.coreutils}/bin/sort -n \ + | ${pkgs.coreutils}/bin/cut -f2 \ + | ${pkgs.coreutils}/bin/head -n 1 + } + ''; + +in out +# TODO ionice +# TODO mail on missing push +# TODO don't cancel plans on activation +# also, don't hang while deploying at: +# starting the following units: backup.wu-home-xu.push.service, backup.wu-home-xu.push.timer +# TODO make sure that secure hosts cannot backup to insecure ones +# TODO optionally only backup when src and dst are near enough :) +# TODO try using btrfs for snapshots (configurable) +# TODO warn if partial snapshots are found +# TODO warn if unknown stuff is found in dst path diff --git a/modules/ejabberd/default.nix b/modules/ejabberd/default.nix index 02c060d..9607741 100644 --- a/modules/ejabberd/default.nix +++ b/modules/ejabberd/default.nix @@ -131,6 +131,9 @@ in { systemd.services.ejabberd = { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; + environment = { + HOME = cfg.stateDir; + }; reloadTriggers = [ config.environment.etc."ejabberd/ejabberd.yaml".source config.environment.etc."ejabberd/ejabberdctl.cfg".source @@ -139,6 +142,17 @@ in { ExecStartPre = [ "${pkgs.coreutils}/bin/ln -s \${CREDENTIALS_DIRECTORY} /tmp/credentials" "${gen-dhparam} ${cfg.stateDir}/dhfile" + (pkgs.writeDash "ejabberd-ensure-PREVIOUS.LOG" '' + set -efu + cd ${cfg.stateDir} + if ! test -e PREVIOUS.LOG; then + if test -f LATEST.LOG; then + ${pkgs.coreutils}/bin/ln LATEST.LOG PREVIOUS.LOG + else + ${pkgs.coreutils}/bin/touch PREVIOUS.LOG + fi + fi + '') ]; ExecStart = "${cfg.pkgs.ejabberd}/bin/ejabberdctl foreground"; ExecStop = [ @@ -155,7 +169,7 @@ in { PrivateDevices = true; PrivateTmp = true; SyslogIdentifier = "ejabberd"; - StateDirectory = "ejabberd"; + StateDirectory = lib.removePrefix "/var/lib/" cfg.stateDir; User = "ejabberd"; DynamicUser = true; TimeoutSec = 60; diff --git a/modules/hw.nix b/modules/hw.nix deleted file mode 100644 index 653b04f..0000000 --- a/modules/hw.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ lib, mylib, ... }: let - local.types.screen = lib.types.submodule { - options.width = lib.mkOption { - type = mylib.types.uint; - }; - options.height = lib.mkOption { - type = mylib.types.uint; - }; - }; -in { - options.tv.hw.screens = lib.mkOption { - type = lib.types.attrsOf local.types.screen; - default = {}; - }; -} diff --git a/modules/lidControl.nix b/modules/lid-handler.nix index a35e178..d89aced 100644 --- a/modules/lidControl.nix +++ b/modules/lid-handler.nix @@ -1,13 +1,13 @@ { config, lib, pkgs, ... }: { options = { - tv.lidControl.enable = lib.mkEnableOption "tv.lidControl"; + hrm.lid-handler.enable = lib.mkEnableOption "hrm.lid-handler"; }; config = let - cfg = config.tv.lidControl; + cfg = config.hrm.lid-handler; in lib.mkIf cfg.enable { services.acpid.enable = true; services.acpid.lidEventCommands = /* sh */ '' - set -- $1 + lid_state=$(${pkgs.gawk}/bin/awk '{print$2}' /proc/acpi/button/lid/*/state) # usage: vt_is_xserver NUMBER vt_is_xserver() { @@ -27,18 +27,31 @@ --uid=$owner \ "$@" } - case $3 in + case $lid_state in open) run_on_display ${pkgs.xorg.xset}/bin/xset dpms force on ;; - close) + closed) run_on_display ${pkgs.xorg.xset}/bin/xset dpms force off ;; esac + else + case $lid_state in + open) + ${pkgs.brightnessctl}/bin/brightnessctl --restore >/dev/null 2>&1 + ;; + closed) + brightness=$(${pkgs.brightnessctl}/bin/brightnessctl --quiet get) + if test "$brightness" -gt 0; then + ${pkgs.brightnessctl}/bin/brightnessctl --save >/dev/null 2>&1 + ${pkgs.brightnessctl}/bin/brightnessctl --quiet set 0 + fi + ;; + esac fi ''; - services.logind.lidSwitch = "ignore"; - services.logind.lidSwitchDocked = "ignore"; - services.logind.lidSwitchExternalPower = "ignore"; + services.logind.settings.Login.HandleLidSwitch = "ignore"; + services.logind.settings.Login.HandleLidSwitchDocked = "ignore"; + services.logind.settings.Login.HandleLidSwitchExternalPower = "ignore"; }; } diff --git a/modules/org.freedesktop.machine1.host-shell.nix b/modules/org.freedesktop.machine1.host-shell.nix index 73825a5..3491453 100644 --- a/modules/org.freedesktop.machine1.host-shell.nix +++ b/modules/org.freedesktop.machine1.host-shell.nix @@ -1,4 +1,4 @@ -{ config, lib, mylib, ... }: { +{ config, lib, mylib, pkgs, ... }: { options.org.freedesktop.machine1.host-shell.access = lib.mkOption { default = {}; type = @@ -12,17 +12,21 @@ (name: value: [name] ++ lib.attrNames value) x))); }; - config.security.polkit.extraConfig = let + config.environment.etc."polkit-1/rules.d/30-hrm-access.rules" = let cfg = config.org.freedesktop.machine1.host-shell; + in { enable = cfg.access != {}; - in lib.optionalString enable /* js */ '' - polkit.addRule(function () { - const access = ${builtins.toJSON cfg.access}; - return function(action, subject) { - if (action.id === "org.freedesktop.machine1.host-shell" - && (access[subject.user]||{})[action.lookup("user")]) - return polkit.Result.YES; - } - }()); - ''; + source = pkgs.writePolkitRules "30-hrm-access.rules" /* js */ '' + polkit.addRule(function () { + const access = ${builtins.toJSON cfg.access}; + return function (action, subject) { + if (action.id === "org.freedesktop.machine1.host-shell") { + if ((access[subject.user]||{})[action.lookup("user")]) { + return polkit.Result.YES; + } + } + } + }()); + ''; + }; } diff --git a/pkgs/haskell/blessings.nix b/pkgs/haskell/blessings.nix index 65661aa..9ed1664 100644 --- a/pkgs/haskell/blessings.nix +++ b/pkgs/haskell/blessings.nix @@ -1,16 +1,18 @@ -{ mkDerivation, base, bytestring, fetchgit, hspec, QuickCheck, lib, mylib, text }: - +{ mkDerivation, base, dlist, extra, fetchgit, hspec, lib +, mono-traversable, QuickCheck, seq2, text +}: mkDerivation { pname = "blessings"; - version = "2.3.0"; + version = "3.0.0"; src = fetchgit { - url = http://cgit.ni.krebsco.de/blessings; - rev = "refs/tags/v2.3.0"; - hash = "sha256-fS79UOHBMfJHyz7E0Rx4lKZSZOD2G99h2zuDT+SOUJQ="; + url = "https://cgit.krebsco.de/blessings"; + sha256 = "1x4wa9v9kgd8z11pxf9clsbk1527bqq86zvk1mp26dzwkbw8kgpk"; + rev = "2e33bc5ac86c81f0c9ee823b4913bce776ba5a0d"; + fetchSubmodules = true; }; - libraryHaskellDepends = [ base bytestring text ]; - testHaskellDepends = [ base hspec QuickCheck ]; - doHaddock = false; - # WTFPL is the true license, which is unknown to cabal. - license = lib.licenses.wtfpl; + libraryHaskellDepends = [ + base dlist extra mono-traversable seq2 text + ]; + testHaskellDepends = [ base hspec mono-traversable QuickCheck ]; + license = lib.licenses.mit; } diff --git a/pkgs/haskell/desktop-pager.nix b/pkgs/haskell/desktop-pager.nix index 3b96159..fd90c1e 100644 --- a/pkgs/haskell/desktop-pager.nix +++ b/pkgs/haskell/desktop-pager.nix @@ -1,15 +1,15 @@ { mkDerivation, aeson, base, blessings, bytestring, containers -, data-default, extra, fetchgit, hack, lib, optparse-applicative -, probability, scanner, speculate, split, terminal-size, text, unix -, utf8-string, X11 +, data-default, extra, fetchgit, hack, lib, mono-traversable +, optparse-applicative, probability, speculate, split +, terminal-scanner, terminal-size, text, unix, utf8-string, X11 }: mkDerivation { pname = "desktop-pager"; - version = "1.0.0"; + version = "1.0.2"; src = fetchgit { url = "https://cgit.krebsco.de/desktop-pager"; - sha256 = "11v4f2sz6p69fx2804w0akb8xqv56g89chjyx77jhwqcng2bn6pw"; - rev = "0894fbe50ee2f63b510d32ab8c524134e450f20d"; + sha256 = "1dvqm8a0d8lh227ck0dhyfxkjknhjgjpcwjh3dvps3721p1qldjn"; + rev = "f792f1db052afd4f4af9bca568fe2b8fb96ea7e8"; fetchSubmodules = true; }; isLibrary = true; @@ -17,8 +17,8 @@ mkDerivation { libraryHaskellDepends = [ base extra utf8-string X11 ]; executableHaskellDepends = [ aeson base blessings bytestring containers data-default hack - optparse-applicative probability scanner speculate split - terminal-size text unix X11 + mono-traversable optparse-applicative probability speculate split + terminal-scanner terminal-size text unix X11 ]; license = lib.licenses.mit; } diff --git a/pkgs/haskell/hack.nix b/pkgs/haskell/hack.nix index f1b22b5..b6c3ca6 100644 --- a/pkgs/haskell/hack.nix +++ b/pkgs/haskell/hack.nix @@ -1,21 +1,23 @@ { mkDerivation, base, blessings, containers, data-default, fetchgit -, lens, lib, mtl, old-locale, process, input-scanner, time, unix, zippers +, lens, lib, mono-traversable, mtl, old-locale, process +, terminal-scanner, time, unix, zippers }: mkDerivation { pname = "hack"; - version = "1.0.2"; + version = "1.0.4"; src = fetchgit { url = "https://cgit.krebsco.de/hack"; - hash = "sha256-QHSGF4wFwLyn8W8jYbN1QajMnmQqUI+7VWk7yVvJgIg="; - rev = "refs/tags/1.0.2"; + sha256 = "1in95j2fx12kh994ajd5wpzsf5nrk7bs1rqjjnn7gq5zal216kkq"; + rev = "4f81ea639fb7754b1169f358bdae8225e6e4e2b3"; fetchSubmodules = true; }; isLibrary = true; isExecutable = true; libraryHaskellDepends = [ base ]; executableHaskellDepends = [ - base blessings containers data-default lens mtl old-locale process - input-scanner time unix zippers + base blessings containers data-default lens mono-traversable mtl + old-locale process terminal-scanner time unix zippers ]; license = lib.licenses.mit; + mainProgram = "hack"; } diff --git a/pkgs/haskell/mailaids.nix b/pkgs/haskell/mailaids.nix new file mode 100644 index 0000000..815613c --- /dev/null +++ b/pkgs/haskell/mailaids.nix @@ -0,0 +1,22 @@ +{ mkDerivation, aeson, aeson-pretty, base, bytestring +, case-insensitive, either, fetchgit, lens, lib +, optparse-applicative, purebred-email, text, vector, word8 +}: +mkDerivation { + pname = "mailaids"; + version = "1.1.0+parts"; + src = fetchgit { + url = "https://cgit.krebsco.de/mailaids"; + sha256 = "0xwd196zrgfv2d7x1pgp1yzqj1hrpwr0m54i6mnrmk6022yx46hl"; + rev = "02d8996bb6aaeb2881e2df33da5167b649edb822"; + fetchSubmodules = true; + }; + isLibrary = false; + isExecutable = true; + executableHaskellDepends = [ + aeson aeson-pretty base bytestring case-insensitive either lens + optparse-applicative purebred-email text vector word8 + ]; + license = lib.licenses.mit; + mainProgram = "mailaid"; +} diff --git a/pkgs/haskell/much.nix b/pkgs/haskell/much.nix index 865294d..cdfe011 100644 --- a/pkgs/haskell/much.nix +++ b/pkgs/haskell/much.nix @@ -2,18 +2,19 @@ , blaze-builder, blessings, bytestring, case-insensitive , containers, data-default, deepseq, directory, either , email-header, fetchgit, filepath, friendly-time, http-types -, hyphenation, lib, linebreak, network, old-locale -, optparse-applicative, process, random, rosezipper, safe, scanner -, servant-server, split, terminal-size, text, time, transformers +, hyphenation, lib, linebreak, mono-traversable, network +, old-locale, optparse-applicative, process, process-extras, random +, rosezipper, safe, servant-server, split, terminal-scanner +, terminal-size, text, text-wcwidth, time, transformers , transformers-compat, unix, vector, wai, warp }: -mkDerivation rec { +mkDerivation { pname = "much"; - version = "1.3.2"; + version = "1.4.2"; src = fetchgit { url = "https://cgit.krebsco.de/much"; - hash = "sha256-q65EYO1d3NYVv2NECkGWPb1TyHGdARNi/GX4pgQmljc="; - rev = "refs/tags/${version}"; + sha256 = "088cbzlvh23625617qyp1s3q0qb4il4b3f4ji061gq3bikycrhkf"; + rev = "36184551980eb59b67189c2a782c7f4461285d23"; fetchSubmodules = true; }; isLibrary = true; @@ -22,15 +23,18 @@ mkDerivation rec { aeson attoparsec base base64-bytestring blaze-builder blessings bytestring case-insensitive containers data-default deepseq directory either email-header filepath friendly-time http-types - hyphenation linebreak network old-locale optparse-applicative - process random rosezipper safe scanner servant-server split - terminal-size text time transformers transformers-compat unix - vector wai warp + hyphenation linebreak mono-traversable network old-locale + optparse-applicative process process-extras random rosezipper safe + servant-server split terminal-scanner terminal-size text + text-wcwidth time transformers transformers-compat unix vector wai + warp ]; executableHaskellDepends = [ aeson base blessings bytestring case-insensitive containers - data-default deepseq directory filepath hyphenation linebreak - process rosezipper safe scanner text time transformers unix + data-default deepseq directory hyphenation linebreak + mono-traversable process rosezipper safe terminal-scanner text + text-wcwidth time transformers ]; license = lib.licenses.mit; + mainProgram = "much"; } diff --git a/pkgs/haskell/purebred-email/default.nix b/pkgs/haskell/purebred-email/default.nix new file mode 100644 index 0000000..34c3ed6 --- /dev/null +++ b/pkgs/haskell/purebred-email/default.nix @@ -0,0 +1,31 @@ +{ mkDerivation, attoparsec, base, base64-bytestring, bytestring +, case-insensitive, concise, deepseq, fetchgit, hedgehog, lens, lib +, QuickCheck, quickcheck-instances, random, semigroupoids +, stringsearch, tasty, tasty-golden, tasty-hedgehog, tasty-hunit +, tasty-quickcheck, text, time +}: +mkDerivation { + pname = "purebred-email"; + version = "0.6.0.2"; + src = fetchgit { + url = "https://github.com/purebred-mua/purebred-email"; + hash = "sha256-P9RmQZ4fvQ1LGdQXFAAP/43VR8TZtQASs2cDK/zjHWg="; + rev = "23c69d5c923a91581c366e23fc7de3992dd81e27"; + fetchSubmodules = true; + }; + isLibrary = true; + isExecutable = true; + libraryHaskellDepends = [ + attoparsec base base64-bytestring bytestring case-insensitive + concise deepseq lens random semigroupoids stringsearch text time + ]; + testHaskellDepends = [ + attoparsec base bytestring case-insensitive hedgehog lens + QuickCheck quickcheck-instances random tasty tasty-golden + tasty-hedgehog tasty-hunit tasty-quickcheck text time + ]; + homepage = "https://github.com/purebred-mua/purebred-email"; + description = "types and parser for email messages (including MIME)"; + license = lib.licenses.agpl3Plus; + jailbreak = true; +} diff --git a/pkgs/haskell/purebred-email/untweak-mime-version-header.patch b/pkgs/haskell/purebred-email/untweak-mime-version-header.patch new file mode 100644 index 0000000..97baf7a --- /dev/null +++ b/pkgs/haskell/purebred-email/untweak-mime-version-header.patch @@ -0,0 +1,65 @@ +diff --git a/src/Data/MIME.hs b/src/Data/MIME.hs +index 19af53e..be8cbd4 100644 +--- a/src/Data/MIME.hs ++++ b/src/Data/MIME.hs +@@ -810,7 +810,6 @@ multipart takeTillEnd boundary = + -- | Sets the @MIME-Version: 1.0@ header. + -- + instance RenderMessage MIME where +- tweakHeaders = set (headers . at "MIME-Version") (Just "1.0") + buildBody h z = Just $ case z of + Part partbody -> Builder.byteString partbody + Encapsulated msg -> buildMessage msg +diff --git a/tests/Generator.hs b/tests/Generator.hs +index 9e1f166..23bd122 100644 +--- a/tests/Generator.hs ++++ b/tests/Generator.hs +@@ -64,7 +64,7 @@ exampleMailsParseSuccessfully = + textPlain7bit :: MIMEMessage + textPlain7bit = + let m = createTextPlainMessage "This is a simple mail." +- in over headers (\(Headers xs) -> Headers $ (CI.mk "Subject", "Hello there") : xs) m ++ in over headers (\(Headers xs) -> Headers $ (CI.mk "MIME-Version", "1.0") : (CI.mk "Subject", "Hello there") : xs) m + + multiPartMail :: MIMEMessage + multiPartMail = +@@ -72,13 +72,16 @@ multiPartMail = + to' = Single $ Mailbox Nothing (AddrSpec "bar" (DomainDotAtom $ pure "bar.com")) + subject = "Hello there" + p = createTextPlainMessage "This is a simple mail." ++ & set (headers . at "MIME-Version") (Just "1.0") + a = createAttachment + contentTypeApplicationOctetStream + (Just "foo.bin") + "fileContentsASDF" ++ & set (headers . at "MIME-Version") (Just "1.0") + now = UTCTime (ModifiedJulianDay 123) (secondsToDiffTime 123) + in createMultipartMixedMessage "asdf" (fromList [p, a]) +- & set (headers . at "From") (Just $ renderMailboxes [from']) ++ & set (headers . at "MIME-Version") (Just "1.0") ++ . set (headers . at "From") (Just $ renderMailboxes [from']) + . set (headers . at "To") (Just $ renderAddresses [to']) + . set (headers . at "Date") (Just $ renderRFC5422Date now) + . set (headers . at "Subject") (Just $ T.encodeUtf8 subject) +diff --git a/tests/Message.hs b/tests/Message.hs +index 6711519..3e40397 100644 +--- a/tests/Message.hs ++++ b/tests/Message.hs +@@ -29,7 +29,7 @@ import Data.Char (isPrint) + import Data.Foldable (fold) + import Data.List.NonEmpty (NonEmpty(..), intersperse) + +-import Control.Lens (set, view) ++import Control.Lens ((&), at, set, view) + import qualified Data.ByteString as B + import qualified Data.Text as T + +@@ -99,7 +99,7 @@ genMessage = Gen.choice [ genTextPlain, genMultipart, encapsulate <$> genMessage + prop_messageRoundTrip :: Property + prop_messageRoundTrip = property $ do + msg <- forAll genMessage +- parse (message mime) (renderMessage msg) === Right msg ++ parse (message mime) (renderMessage $ msg & set (headers . at "MIME-Version") (Just "1.0")) === Right msg + + prop_messageFromRoundTrip :: Property + prop_messageFromRoundTrip = property $ do diff --git a/pkgs/haskell/seq2.nix b/pkgs/haskell/seq2.nix new file mode 100644 index 0000000..9d18f92 --- /dev/null +++ b/pkgs/haskell/seq2.nix @@ -0,0 +1,14 @@ +{ mkDerivation, base, fetchgit, lib }: +mkDerivation { + pname = "seq2"; + version = "1.0.0"; + src = fetchgit { + url = "https://cgit.krebsco.de/seq2"; + sha256 = "03b90b68xpk00v13cc45aw148z1spph8vyqga8vmif9iv5g0lfjn"; + rev = "6aeb56c36a9a47c9216c8f9252ca26d091506c73"; + fetchSubmodules = true; + }; + libraryHaskellDepends = [ base ]; + homepage = "https://cgit.krebsco.de/seq2"; + license = lib.licenses.mit; +} diff --git a/pkgs/haskell/terminal-scanner.nix b/pkgs/haskell/terminal-scanner.nix new file mode 100644 index 0000000..ca16644 --- /dev/null +++ b/pkgs/haskell/terminal-scanner.nix @@ -0,0 +1,13 @@ +{ mkDerivation, base, fetchgit, lib }: +mkDerivation { + pname = "terminal-scanner"; + version = "1.1.0"; + src = fetchgit { + url = "https://cgit.krebsco.de/terminal-scanner"; + sha256 = "0x37g62km90pgamrn3slr513jw29cb9zmrnb9frs8j8r9yq50fz0"; + rev = "a77acbcc13f8eb50e1277d07cf2a10004b58af71"; + fetchSubmodules = true; + }; + libraryHaskellDepends = [ base ]; + license = lib.licenses.mit; +} diff --git a/pkgs/haskell/terminal-utilities.nix b/pkgs/haskell/terminal-utilities.nix new file mode 100644 index 0000000..eeab32f --- /dev/null +++ b/pkgs/haskell/terminal-utilities.nix @@ -0,0 +1,13 @@ +{ mkDerivation, base, fetchgit, lib }: +mkDerivation { + pname = "terminal-utilities"; + version = "1.0.0"; + src = fetchgit { + url = "https://cgit.krebsco.de/terminal-utilities"; + sha256 = "0kpkm87g5ab0s22zly994ql8hfc0gbqc5s7ln4ngav2k91a0wp7j"; + rev = "e2c0cc11a71c785b268f31f60bed2a79e00a4d61"; + fetchSubmodules = true; + }; + libraryHaskellDepends = [ base ]; + license = lib.licenses.mit; +} diff --git a/pkgs/haskell/text-wcwidth.nix b/pkgs/haskell/text-wcwidth.nix new file mode 100644 index 0000000..e6a43d6 --- /dev/null +++ b/pkgs/haskell/text-wcwidth.nix @@ -0,0 +1,15 @@ +{ mkDerivation, base, fetchgit, lib, mono-traversable, text +, wcwidth +}: +mkDerivation { + pname = "text-wcwidth"; + version = "1.0.0"; + src = fetchgit { + url = "https://cgit.krebsco.de/text-wcwidth"; + sha256 = "1x51za2vpxgdz05arks3a98v9mz12s64rcncgg34fmir42f27li1"; + rev = "d70945bdfcf1bebf3dadb6b6c8ac7c75b4d3e9d0"; + fetchSubmodules = true; + }; + libraryHaskellDepends = [ base mono-traversable text wcwidth ]; + license = lib.licenses.mit; +} diff --git a/pkgs/haskell/xmonad-tv/src/main.hs b/pkgs/haskell/xmonad-tv/src/main.hs index e3090a3..05817af 100644 --- a/pkgs/haskell/xmonad-tv/src/main.hs +++ b/pkgs/haskell/xmonad-tv/src/main.hs @@ -9,6 +9,7 @@ import XMonad.Hooks.EwmhDesktops (ewmh) import XMonad.Hooks.EwmhDesktops.Extra (ewmhExtra) import XMonad.Hooks.RefocusLast (refocusLastLayoutHook, toggleFocus) +import Control.Monad (void) import Control.Monad.Extra (whenJustM) import qualified Data.Aeson import qualified Data.ByteString.Char8 @@ -23,10 +24,10 @@ import System.Posix.Process (executeFile) import XMonad.Actions.DynamicWorkspaces (removeEmptyWorkspace) import XMonad.Actions.CycleWS (toggleWS) import XMonad.Layout.Gaps (Direction2D(U,R,D,L), gaps) -import XMonad.Layout.NoBorders ( smartBorders ) +import XMonad.Layout.FocusTracking (focusTracking) +import XMonad.Layout.NoBorders (noBorders) import XMonad.Layout.ResizableTile (ResizableTall(ResizableTall)) import XMonad.Layout.ResizableTile (MirrorResize(MirrorExpand,MirrorShrink)) -import XMonad.Layout.StateFull (pattern StateFull) import qualified XMonad.StackSet as W import Data.Map (Map) import qualified Data.Map as Map @@ -44,6 +45,11 @@ import XMonad.Hooks.Place (placeHook, smart) import XMonad.Actions.PerWorkspaceKeys (chooseAction) import Shutdown (shutdown, newShutdownEventHandler) +import System.IO.Unsafe (unsafePerformIO) + + +sliceEnvPath :: FilePath +sliceEnvPath = unsafePerformIO (getEnv "XMONAD_CACHE_DIR") <> "/slice.env" main :: IO () @@ -70,10 +76,12 @@ readEnv' defaultValue name = mainNoArgs :: IO () mainNoArgs = do + getEnvironment >>= \env -> writeFile sliceEnvPath $ unlines [ k <> "=" <> v | (k, v) <- env] myMasterDelta <- readEnv' (1 / 20) "XMONAD_MASTER_DELTA" :: IO Rational myMasterWidth <- readEnv' (1 / 2) "XMONAD_MASTER_WIDTH" :: IO Rational myScreenGaps <- readEnv' [] "XMONAD_SCREEN_GAPS" :: IO [Int] - myScreenWidth <- readEnv "XMONAD_SCREEN_WIDTH" :: IO Dimension + myScreenWidth <- + bracket (getEnv "DISPLAY" >>= openDisplay) closeDisplay (return . widthOfScreen . defaultScreenOfDisplay) handleShutdownEvent <- newShutdownEventHandler config <- ewmhExtra @@ -94,14 +102,13 @@ mainNoArgs = do , layoutHook = refocusLastLayoutHook $ gaps (zip [U,R,D,L] myScreenGaps) $ - smartBorders $ - ResizableTall - 1 - myMasterDelta - (myMasterWidth + 2 * fromIntegral (borderWidth def) / fromIntegral myScreenWidth) - [] - ||| - StateFull + ResizableTall + 1 + myMasterDelta + (myMasterWidth + 2 * fromIntegral (borderWidth def) / fromIntegral myScreenWidth) + [] + ||| + noBorders (focusTracking Full) , manageHook = composeAll [ appName =? "fzmenu-urxvt" --> doCenterFloat @@ -133,16 +140,22 @@ handleFocusChangeEvent = \case forkFile :: FilePath -> [String] -> Maybe [(String, String)] -> X () -forkFile path args env = - xfork (executeFile path True args env) >> return () +forkFile path args env = void . xfork $ do + environment <- getEnvironment + executeFile path True args (env <> Just environment) -spawnRootTerm :: X () -spawnRootTerm = - forkFile - {-pkg:alacritty-tv-}"alacritty" - ["--profile=root", "-e", "/run/wrappers/bin/su", "-"] - Nothing +forkFileInSlice :: String -> FilePath -> [String] -> X () +forkFileInSlice sliceName path args = void . xfork $ + executeFile {-pkg:systemd-}"systemd-run" True + ( "--collect" + : "--user" + : "--slice=" <> sliceName + : "--property=EnvironmentFile=" <> sliceEnvPath + : path + : args + ) + Nothing myKeys :: XConfig Layout -> Map (KeyMask, KeySym) (X ()) @@ -151,10 +164,12 @@ myKeys conf = Map.fromList $ , ((_4S , xK_c ), kill) , ((_4 , xK_o ), forkFile {-pkg:fzmenu-}"otpmenu" [] Nothing) + , ((_4C , xK_o ), forkFile {-pkg:fzmenu-}"otpmenu" ["--phase2-method=copy"] Nothing) , ((_4 , xK_p ), forkFile {-pkg:fzmenu-}"passmenu" [] Nothing) + , ((_4C , xK_p ), forkFile {-pkg:fzmenu-}"passmenu" ["--phase2-method=copy"] Nothing) - , ((_4 , xK_x ), forkFile {-pkg:alacritty-tv-}"alacritty" ["--singleton"] Nothing) - , ((_4C , xK_x ), spawnRootTerm) + , ((_4 , xK_x ), forkFileInSlice "alacritty" {-pkg:alacritty-tv-}"alacritty" ["--dtach", "--singleton"]) + , ((_4C , xK_x ), forkFileInSlice "alacritty" {-pkg:alacritty-tv-}"alacritty" ["--profile=root", "-e", "/run/wrappers/bin/su", "-"]) , ((_C , xK_Menu ), toggleWS) diff --git a/pkgs/haskell/xoutinfo.nix b/pkgs/haskell/xoutinfo.nix index 64b6f87..fc983d6 100644 --- a/pkgs/haskell/xoutinfo.nix +++ b/pkgs/haskell/xoutinfo.nix @@ -1,11 +1,11 @@ { mkDerivation, aeson, base, bytestring, fetchgit, lib, X11 }: mkDerivation { pname = "xoutinfo"; - version = "0.1.0.0"; + version = "0.1.1.0"; src = fetchgit { url = "https://cgit.ni.krebsco.de/xoutinfo"; - sha256 = "1g3s9vyy7bpsl2zjiq6kk16c8hhf3n2yz4lv3ic0qy0n6wn6qqi8"; - rev = "cf7377886a55e36701bd0d5ce7c723aa6d7bd9bd"; + hash = "sha256-QSyCal5E7O1JBlZ7OV3aM8j68YozKyKgYhL2HYFTsvg="; + rev = "0.1.1.0"; fetchSubmodules = true; }; isLibrary = false; diff --git a/pkgs/shell/dtach-list b/pkgs/shell/dtach-list new file mode 100755 index 0000000..1e77a3d --- /dev/null +++ b/pkgs/shell/dtach-list @@ -0,0 +1,32 @@ +#! /bin/sh +#!buildShellBin path=coreutils:findutils:gawk:gnugrep:gnused:iproute2:psmisc +# +# NAME +# dtach-list - list dtach sessions +# +# SYNOPSIS +# dtach-list +# +set -efu + +workdir=$(mktemp -d -t dtach-list.XXXXXXXX) +readonly workdir +trap 'cd / && rm -r "$workdir"' EXIT +cd "$workdir" + +ss -HQpx > ssclients + +ss -HQlpx | sed -nr 's/ +/ /g; s/^u_str LISTEN ([^ ]+) [0-9]+ \* 0 users:\(\("dtach",pid=([0-9]+),fd=3\)\) $/\2 \1/p' | sort -n > sockets + +while read -r pid sock; do + connections=$(awk -v sock="$sock" '$3==sock{n++}BEGIN{n=0}END{print n}' ssclients) + pstree -TUalp "$pid" >pstree + if test "$connections" = 0; then + sed ' + 1s/$/ (detached)/ + s/.*/\x1b[38;5;202m&\x1b[m/ + ' pstree + else + cat pstree + fi +done <sockets diff --git a/pkgs/simple/alacritty-tv.nix b/pkgs/simple/alacritty-tv.nix index bea5776..ebf609e 100644 --- a/pkgs/simple/alacritty-tv.nix +++ b/pkgs/simple/alacritty-tv.nix @@ -5,18 +5,33 @@ pkgs.symlinkJoin { paths = [ (pkgs.writeDashBin "alacritty" '' # usage: - # alacritty [--profile=PROFILE] [--singleton] [ARGS...] + # alacritty [--dtach] [--profile=PROFILE] [--singleton] [COMMAND [ARGS...]] # where # PROFILE must have a corresponding file /etc/alacritty/PROFILE.toml set -efu + dtach= profile=default - case ''${1-} in - --profile=*) - profile=''${1#--profile=} - shift - esac + singleton= + while :; do + case ''${1-} in + --dtach) + dtach=1 + shift + ;; + --profile=*) + profile=''${1#--profile=} + shift + ;; + --singleton) + singleton=1 + shift + ;; + *) + break + esac + done config=/etc/alacritty/$profile.toml @@ -26,17 +41,29 @@ pkgs.symlinkJoin { config=/etc/alacritty/default.toml fi - case ''${1-} in - --singleton) - shift - if ! ${pkgs.alacritty}/bin/alacritty --config-file "$config" msg create-window "$@"; then - ${pkgs.alacritty}/bin/alacritty --config-file "$config" "$@" & - fi - ;; - *) - exec ${pkgs.alacritty}/bin/alacritty --config-file "$config" "$@" - ;; - esac + export WINIT_X11_SCALE_FACTOR=$( + ${pkgs.haskellPackages.xoutinfo}/bin/xoutinfo | + ${pkgs.jq}/bin/jq .device_scale_factor + ) + + if test "$dtach" = 1; then + if test $# = 0; then + _CURRENT_DESKTOP_NAME=''${_CURRENT_DESKTOP_NAME-$(${pkgs.xextras}/bin/net-current-desktop)} + SHELL=''${SHELL-${pkgs.bash}/bin/bash} + sock=$XDG_RUNTIME_DIR/Alacritty-$DISPLAY-dtach-$_CURRENT_DESKTOP_NAME-$$.sock + set -- -e ${pkgs.dtach}/bin/dtach -c "$sock" -r winch -z "$SHELL" + else + echo 'alacritty-tv: warning: option --dtach ignored: arguments provided' >&2 + fi + fi + + if test "$singleton" = 1; then + if ! ${pkgs.alacritty}/bin/alacritty --config-file "$config" msg create-window "$@"; then + ${pkgs.alacritty}/bin/alacritty --config-file "$config" "$@" & + fi + else + exec ${pkgs.alacritty}/bin/alacritty --config-file "$config" "$@" + fi '') pkgs.alacritty ]; diff --git a/pkgs/simple/dic.nix b/pkgs/simple/dic.nix new file mode 100644 index 0000000..0875c73 --- /dev/null +++ b/pkgs/simple/dic.nix @@ -0,0 +1,37 @@ +{ lib, pkgs, stdenv }: + +stdenv.mkDerivation { + name = "dic"; + + src = pkgs.fetchgit { + url = https://cgit.ni.krebsco.de/dic; + rev = "refs/tags/v1.1.1"; + sha256 = "1gbj967a5hj53fdkkxijqgwnl9hb8kskz0cmpjq7v65ffz3v6vag"; + }; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = + let + path = lib.makeBinPath [ + pkgs.coreutils + pkgs.curl + pkgs.gnused + pkgs.gnugrep + pkgs.util-linux + ]; + in + '' + mkdir -p $out/bin + + sed \ + 's,^main() {$,&\n PATH=${path}; export PATH,' \ + < ./dic \ + > $out/bin/dic + + chmod +x $out/bin/dic + ''; +} diff --git a/pkgs/simple/editor-input.nix b/pkgs/simple/editor-input.nix index 536084d..0591f2f 100644 --- a/pkgs/simple/editor-input.nix +++ b/pkgs/simple/editor-input.nix @@ -1,7 +1,7 @@ { pkgs }: pkgs.writeDashBin "editor-input" '' exec \ - ${pkgs.utillinux}/bin/setsid -f \ + ${pkgs.util-linux}/bin/setsid -f \ ${pkgs.with-tmpdir}/bin/with-tmpdir -t editor-input.XXXXXXXX \ ${pkgs.writeDash "editor-input.sh" '' f=$TMPDIR/input diff --git a/pkgs/simple/fzmenu/bin/otpmenu b/pkgs/simple/fzmenu/bin/otpmenu index 714ab7c..59706c1 100755 --- a/pkgs/simple/fzmenu/bin/otpmenu +++ b/pkgs/simple/fzmenu/bin/otpmenu @@ -1,8 +1,22 @@ #! /bin/sh +# usage: otpmenu [--phase2-method=METHOD] +# where METHOD is either copy or type, type being the default. set -efu #PATH= +while test $# -gt 0; do + case $1 in + --phase2-method=copy|--phase2-method=type) + export FZMENU_PHASE2_METHOD=${1#*=} + shift 1 + ;; + *) + echo "$0: error: bad argument: $1" >&2 + exit 1 + esac +done + case ${FZMENU_PHASE-0} in 0) export FZMENU_PHASE=1 @@ -25,7 +39,7 @@ case ${FZMENU_PHASE-0} in exec fzf \ --history=/dev/null \ --no-sort \ - --prompt='OTP: ' \ + --prompt="${FZMENU_PHASE2_METHOD-type} otp: " \ ) then export FZMENU_PHASE=2 @@ -38,8 +52,19 @@ case ${FZMENU_PHASE-0} in # lucidatypewriter, causing a warning to be printed to stderr. font='-*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1' pass=$(pass otp code "$FZMENU_RESULT/otp") - printf %s "$pass" | - xvkbd -xrm "xvkbd*Font: $font" -xsendevent -file - + case ${FZMENU_PHASE2_METHOD-type} in + copy) + printf %s "$pass" | + xsel -p -i -t 60000 + ;; + type) + printf %s "$pass" | + xvkbd -xrm "xvkbd*Font: $font" -xsendevent -file - + ;; + *) + echo "$0: error: bad phase2 method: $FZMENU_PHASE2_METHOD" >&2 + exit -1 + esac ;; *) echo "$0: error: bad phase: $FZMENU_PHASE" >&2 diff --git a/pkgs/simple/fzmenu/bin/passmenu b/pkgs/simple/fzmenu/bin/passmenu index a798925..0b07174 100755 --- a/pkgs/simple/fzmenu/bin/passmenu +++ b/pkgs/simple/fzmenu/bin/passmenu @@ -1,8 +1,22 @@ #! /bin/sh +# usage: passmenu [--phase2-method=METHOD] +# where METHOD is either copy or type, type being the default. set -efu #PATH= +while test $# -gt 0; do + case $1 in + --phase2-method=copy|--phase2-method=type) + export FZMENU_PHASE2_METHOD=${1#*=} + shift 1 + ;; + *) + echo "$0: error: bad argument: $1" >&2 + exit 1 + esac +done + case ${FZMENU_PHASE-0} in 0) export FZMENU_PHASE=1 @@ -26,7 +40,7 @@ case ${FZMENU_PHASE-0} in exec fzf \ --history=/dev/null \ --no-sort \ - --prompt='pass: ' \ + --prompt="${FZMENU_PHASE2_METHOD-type} pass: " \ ) then export FZMENU_PHASE=2 @@ -39,8 +53,19 @@ case ${FZMENU_PHASE-0} in # lucidatypewriter, causing a warning to be printed to stderr. font='-*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1' pass=$(pass show "$FZMENU_RESULT") - printf %s "$pass" | - xvkbd -xrm "xvkbd*Font: $font" -xsendevent -file - + case ${FZMENU_PHASE2_METHOD-type} in + copy) + printf %s "$pass" | + xsel -p -i -t 60000 + ;; + type) + printf %s "$pass" | + xvkbd -xrm "xvkbd*Font: $font" -xsendevent -file - + ;; + *) + echo "$0: error: bad phase2 method: $FZMENU_PHASE2_METHOD" >&2 + exit -1 + esac ;; *) echo "$0: error: bad phase: $FZMENU_PHASE" >&2 diff --git a/pkgs/simple/fzmenu/default.nix b/pkgs/simple/fzmenu/default.nix index c4dccbf..9a9bda6 100644 --- a/pkgs/simple/fzmenu/default.nix +++ b/pkgs/simple/fzmenu/default.nix @@ -17,8 +17,8 @@ pkgs.runCommand "fzmenu" { cp -r ${./bin} $out/bin substituteInPlace $out/bin/otpmenu \ - --replace '#! /bin/sh' '#! ${pkgs.dash}/bin/dash' \ - --replace '#PATH=' PATH=${lib.makeBinPath [ + --replace-fail '#! /bin/sh' '#! ${pkgs.dash}/bin/dash' \ + --replace-fail '#PATH=' PATH=${lib.makeBinPath [ pkgs.coreutils pkgs.dash pkgs.findutils @@ -27,14 +27,15 @@ pkgs.runCommand "fzmenu" { (pkgs.pass.withExtensions (ext: [ ext.pass-otp ])) - pkgs.utillinux + pkgs.util-linux + pkgs.xsel pkgs.xvkbd terminal ]} substituteInPlace $out/bin/passmenu \ - --replace '#! /bin/sh' '#! ${pkgs.dash}/bin/dash' \ - --replace '#PATH=' PATH=${lib.makeBinPath [ + --replace-fail '#! /bin/sh' '#! ${pkgs.dash}/bin/dash' \ + --replace-fail '#PATH=' PATH=${lib.makeBinPath [ pkgs.coreutils pkgs.dash pkgs.findutils @@ -43,7 +44,8 @@ pkgs.runCommand "fzmenu" { (pkgs.pass.withExtensions (ext: [ ext.pass-otp ])) - pkgs.utillinux + pkgs.util-linux + pkgs.xsel pkgs.xvkbd terminal ]} diff --git a/pkgs/simple/hc.nix b/pkgs/simple/hc.nix index 086445e..15550dc 100644 --- a/pkgs/simple/hc.nix +++ b/pkgs/simple/hc.nix @@ -1,5 +1,5 @@ { fetchgit, lib, makeWrapper, stdenv -, coreutils, findutils, gawk, gnugrep, qrencode, texlive, utillinux, zbar +, coreutils, findutils, gawk, gnugrep, qrencode, texlive, util-linux, zbar }: stdenv.mkDerivation rec { @@ -28,7 +28,7 @@ stdenv.mkDerivation rec { gnugrep qrencode texlive.combined.scheme-full - utillinux + util-linux zbar ]} ''; diff --git a/pkgs/simple/otherutils.nix b/pkgs/simple/otherutils.nix new file mode 100644 index 0000000..5c946d2 --- /dev/null +++ b/pkgs/simple/otherutils.nix @@ -0,0 +1,15 @@ +{ pkgs, stdenv }: + +stdenv.mkDerivation rec { + pname = "otherutils"; + version = "1.1.0"; + src = pkgs.fetchgit { + url = "https://cgit.krebsco.de/otherutils"; + rev = "refs/tags/${version}"; + hash = "sha256-eiMTIXTEsq+DGlOw+fcU2cgRkuPWTy5lm/L5heuhDxM="; + }; + env = { + PREFIX = placeholder "out"; + }; +} + diff --git a/pkgs/simple/pinentry-urxvt/default.nix b/pkgs/simple/pinentry-urxvt/default.nix index 808d00a..e79b09f 100644 --- a/pkgs/simple/pinentry-urxvt/default.nix +++ b/pkgs/simple/pinentry-urxvt/default.nix @@ -51,7 +51,7 @@ in trap cleanup EXIT cleanup() { - ${pkgs.utillinux}/bin/kill -- $(${pkgs.coreutils}/bin/cat "$displayers") + ${pkgs.util-linux}/bin/kill -- $(${pkgs.coreutils}/bin/cat "$displayers") rm "$displayers" rm "$screenshot" } diff --git a/pkgs/simple/q/default.nix b/pkgs/simple/q/default.nix index ca4a466..5944dd9 100644 --- a/pkgs/simple/q/default.nix +++ b/pkgs/simple/q/default.nix @@ -17,11 +17,11 @@ let in /* sh */ '' cols=$(${pkgs.ncurses}/bin/tput cols) if test $cols -ge ${toString (need_width 3)}; then - ${pkgs.utillinux}/bin/cal --color=always -mw3 + ${pkgs.util-linux}/bin/cal --color=always -mw3 elif test $cols -ge ${toString (need_width 2)}; then - ${pkgs.utillinux}/bin/cal --color=always -mw -n 2 + ${pkgs.util-linux}/bin/cal --color=always -mw -n 2 elif test $cols -ge ${toString (need_width 1)}; then - ${pkgs.utillinux}/bin/cal --color=always -mw1 + ${pkgs.util-linux}/bin/cal --color=always -mw1 else : fi | diff --git a/pkgs/simple/viljetic-pages/index.html b/pkgs/simple/viljetic-pages/index.html index c268cb9..9394cf7 100644 --- a/pkgs/simple/viljetic-pages/index.html +++ b/pkgs/simple/viljetic-pages/index.html @@ -4,6 +4,7 @@ <i>This page intentionally left blank.</i> <!-- mailto:tomislav@viljetic.de + matrix:u/@tomislav:viljetic.de https://github.com/4z3 irc://irc.hackint.org/tv,isnick irc://irc.libera.chat/tv,isnick diff --git a/pkgs/simple/with-tmpdir.nix b/pkgs/simple/with-tmpdir.nix new file mode 100644 index 0000000..9862671 --- /dev/null +++ b/pkgs/simple/with-tmpdir.nix @@ -0,0 +1,29 @@ +{ stdenv, fetchgit, coreutils, dash, ... }: + +stdenv.mkDerivation { + name = "with-tmpdir-1"; + + src = fetchgit { + url = http://cgit.ni.krebsco.de/with-tmpdir; + rev = "3243c02ed8cd27a04c080bd39560204980f6c16a"; + sha256 = "80ee6cafb2c337999ddcd1e41747d6256b7cfcea605358c2046eb7e3729555c6"; + }; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = '' + mkdir -p $out/bin + + { echo '#! ${dash}/bin/dash' + echo 'OLDPATH=$PATH' + echo 'PATH=${coreutils}/bin' + sed '$s/^/#/' ./with-tmpdir + echo '(PATH=$OLDPATH; exec "$@")' + } > $out/bin/with-tmpdir + + chmod +x $out/bin/with-tmpdir + ''; +} diff --git a/pkgs/simple/writePolkitRules.nix b/pkgs/simple/writePolkitRules.nix new file mode 100644 index 0000000..af4cb49 --- /dev/null +++ b/pkgs/simple/writePolkitRules.nix @@ -0,0 +1,72 @@ +{ lib, pkgs, ... }: + +name: text: + +pkgs.runCommand name { + nativeBuildInputs = [ + pkgs.eslint + ]; + eslintConfig = /* js */ '' + // ESLint flat config for Polkit rules (Duktape 2.7) + export default [ + { + files: [${builtins.toJSON name}], + languageOptions: { + ecmaVersion: 2016, + sourceType: 'script', + globals: { + polkit: 'readonly', + }, + }, + linterOptions: { + reportUnusedDisableDirectives: true, + }, + rules: { + 'no-unused-vars': 'warn', + 'no-undef': 'error', + 'no-console': 'off', + 'prefer-const': 'warn', + 'no-confusing-arrow': [ + 'error', + { allowParens: true }, + ], + 'no-constant-condition': 'warn', + 'no-restricted-syntax': [ + 'error', + { + selector: 'AwaitExpression', + message: 'Async/await is not supported in Polkit rules.', + }, + { + selector: 'ImportDeclaration', + message: 'Modules are not supported.', + }, + { + selector: 'ExportNamedDeclaration', + message: 'Modules are not supported.', + }, + { + selector: 'NewExpression[callee.name="Promise"]', + message: 'Promises are not supported in Duktape.', + }, + { + selector: 'ClassDeclaration', + message: 'Class syntax may behave inconsistently in Duktape.', + }, + ] + } + } + ]; + ''; + polkitRules = text; + passAsFile = [ + "eslintConfig" + "polkitRules" + ]; +} /* sh */ '' + name=${lib.escapeShellArg name} + ln -s "$polkitRulesPath" "$name" + ln -s "$eslintConfigPath" eslint.config.js + eslint "$name" + cp -L "$name" "$out" +'' diff --git a/pkgs/simple/xextras.nix b/pkgs/simple/xextras.nix new file mode 100644 index 0000000..c9c0308 --- /dev/null +++ b/pkgs/simple/xextras.nix @@ -0,0 +1,19 @@ +{ pkgs }: + +pkgs.write "xextras" { + "/bin/net-current-desktop".link = + pkgs.writeDash "net-current-desktop" '' + # SYNOPSIS + # net-current-desktop + # + ${pkgs.xorg.xprop}/bin/xprop -notype -root 32i _NET_CURRENT_DESKTOP 8s _NET_DESKTOP_NAMES | + ${pkgs.jq}/bin/jq -Rrs ' + split("\n") | map(select(.!="") | split(" = ") | { name: .[0], value: .[1] }) | from_entries | + { + _NET_CURRENT_DESKTOP: (._NET_CURRENT_DESKTOP | tonumber), + _NET_DESKTOP_NAMES: (._NET_DESKTOP_NAMES | "[\(ltrimstr("._NET_DESKTOP_NAMES = "))]" | fromjson) + } | + ._NET_DESKTOP_NAMES[._NET_CURRENT_DESKTOP] + ' + ''; +} diff --git a/pkgs/vim/fzf.nix b/pkgs/vim/fzf.nix deleted file mode 100644 index e24bee5..0000000 --- a/pkgs/vim/fzf.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ pkgs }: - -# cannot use pkgs.vimPlugins.fzf-vim as it's missing :Rg -pkgs.vimUtils.buildVimPlugin { - name = "fzf-2023-01-16"; - src = pkgs.fetchgit { - url = https://github.com/junegunn/fzf.vim; - rev = "bdf48c282ad2174c25c059b3cdb7956427b07a99"; - hash = "sha256-eCCk+Q596Ljjdtjd0cYGqR77K3Me5gf+ts5icP22S3Y="; - }; -} diff --git a/systems/alnus/config.nix b/systems/alnus/config.nix index 8af12fe..a3d1e9a 100644 --- a/systems/alnus/config.nix +++ b/systems/alnus/config.nix @@ -1,6 +1,7 @@ { config, lib, pkgs, ... }: { imports = [ ../../configs/hw/x220.nix + ../../configs/earlyoom.nix ../../configs/exim-retiolum.nix ../../configs/retiolum.nix ]; @@ -48,12 +49,6 @@ networking.networkmanager.enable = true; - services.earlyoom.enable = true; - services.earlyoom.freeMemThreshold = 5; - systemd.services.earlyoom.environment.EARLYOOM_ARGS = toString [ - "--prefer '^(Web Content|Privileged Cont)$'" # firefox tabs - ]; - services.libinput.enable = false; services.xserver = { diff --git a/systems/mu/config.nix b/systems/mu/config.nix index b3d3e99..f9debe4 100644 --- a/systems/mu/config.nix +++ b/systems/mu/config.nix @@ -38,8 +38,6 @@ nixpkgs.config.allowUnfree = true; hardware.opengl.driSupport32Bit = true; - hardware.pulseaudio.enable = true; - hardware.enableRedistributableFirmware = true; boot.loader.efi.canTouchEfiVariables = true; @@ -98,6 +96,8 @@ pkgs.xorg.fontschumachermisc ]; + services.pulseaudio.enable = true; + services.xserver.enable = true; services.xserver.xkb.layout = "de"; services.xserver.xkb.options = "eurosign:e"; diff --git a/systems/querel/config.nix b/systems/querel/config.nix index 08ad71c..f2ce280 100644 --- a/systems/querel/config.nix +++ b/systems/querel/config.nix @@ -1,6 +1,6 @@ { config, lib, pkgs, ... }: { imports = [ - ../../configs/retiolum.nix + ../../configs/retiolum.nix ]; krebs.build.host = config.krebs.hosts.querel; @@ -11,7 +11,6 @@ allowDiscards = true; device = "/dev/sda2"; }; - boot.kernelModules = [ "kvm-intel" ]; boot.loader = { efi.canTouchEfiVariables = true; systemd-boot.enable = true; @@ -20,15 +19,9 @@ environment.systemPackages = [ pkgs.firefox pkgs.gimp - pkgs.kate + pkgs.kdePackages.kate pkgs.libreoffice - (pkgs.pidgin.override { - plugins = [ pkgs.pidgin-otr ]; - }) pkgs.nsxiv - pkgs.texlive.combined.scheme-full - pkgs.vim - pkgs.xsane pkgs.zathura ]; @@ -48,8 +41,8 @@ }; }; + hardware.cpu.intel.updateMicrocode = true; hardware.enableRedistributableFirmware = true; - hardware.pulseaudio.enable = true; i18n.defaultLocale = "de_DE.UTF-8"; @@ -58,19 +51,13 @@ programs.ssh.startAgent = false; services.xserver.enable = true; - services.xserver.layout = "de"; - services.xserver.xkbOptions = "eurosign:e"; + services.xserver.xkb.layout = "de"; + services.xserver.xkb.options = "eurosign:e"; - services.xserver.libinput.enable = false; - services.xserver.synaptics = { - enable = true; - twoFingerScroll = true; - }; - - services.xserver.desktopManager.plasma5.enable = true; + services.desktopManager.plasma6.enable = true; - services.xserver.displayManager.autoLogin.enable = true; - services.xserver.displayManager.autoLogin.user = "itak"; + services.displayManager.autoLogin.user = "itak"; + services.displayManager.defaultSession = "plasma"; users.users.itak = { inherit (config.krebs.users.itak) home uid; @@ -81,4 +68,6 @@ "networkmanager" ]; }; + + system.stateVersion = "25.11"; } diff --git a/systems/xu/config.nix b/systems/xu/config.nix index ee7ae46..abf433c 100644 --- a/systems/xu/config.nix +++ b/systems/xu/config.nix @@ -4,6 +4,7 @@ imports = [ ../../configs/autotether.nix ../../configs/hw/x220.nix + ../../configs/earlyoom.nix ../../configs/exim-retiolum.nix ../../configs/gitconfig.nix ../../configs/gitrepos.nix @@ -140,8 +141,13 @@ gptfdisk ]; + networking.usePredictableInterfaceNames = false; + networking.wireless.enable = true; + networking.interfaces.eth0.useDHCP = true; + networking.interfaces.eth0.wakeOnLan.enable = true; + #services.bitlbee.enable = true; #services.tor.client.enable = true; #services.tor.enable = true; |
