Set real values for genericized git-config/encryption/send-alert/printing
Mirrors the azos-core change: drops the now-fully-migrated
features/{git-config,encryption,printing}, rewrites features/homey-alert
down to just the azos-homey-ntfy-alert overlay package (the ntfy-specific
remote-notification command plugged into azos.send-alert.remoteCommand),
and sets every real personal value (name/email/signing key, GPG key id,
YubiKey/browserpass/gpg-ssh toggles and keygrip/pubkey, printing username)
directly in home-manager/home.nix and nixos/configuration.nix, same place
the other personal values (azos.name, azos.headphones.devices) already
live.
This commit is contained in:
+1
-1
Submodule azos-core updated: e39b517168...3b4cb38990
@@ -1,80 +0,0 @@
|
||||
{...}: {
|
||||
config.flake.modules.homeManager.encryption = {
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
options.azos.encryption.enable = lib.mkOption {
|
||||
default = true;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
config = lib.mkIf config.azos.encryption.enable {
|
||||
programs.password-store = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PASSWORD_STORE_KEY = "26B851F81F8F7C55";
|
||||
};
|
||||
};
|
||||
home.packages = with pkgs; [
|
||||
yubikey-personalization
|
||||
];
|
||||
programs.gpg = {
|
||||
enable = true;
|
||||
};
|
||||
programs.browserpass = {
|
||||
enable = true;
|
||||
browsers = ["chromium"];
|
||||
};
|
||||
services.gpg-agent = {
|
||||
enable = true;
|
||||
enableSshSupport = true;
|
||||
grabKeyboardAndMouse = false;
|
||||
pinentry.package = pkgs.pinentry-emacs;
|
||||
extraConfig = ''
|
||||
allow-emacs-pinentry
|
||||
allow-loopback-pinentry
|
||||
'';
|
||||
};
|
||||
|
||||
# pinentry-emacs needs INSIDE_EMACS set, but NOT on gpg-agent itself:
|
||||
# gpg-agent calls gnupg_unsetenv("INSIDE_EMACS") on its own process at
|
||||
# startup (agent/gpg-agent.c, both supervised and daemon mode) -- by
|
||||
# design, it expects this to arrive per-connection from the CLIENT,
|
||||
# not statically from its own daemon environment. Each gpg/git
|
||||
# invocation reads INSIDE_EMACS from its own env and forwards it to
|
||||
# gpg-agent via "OPTION putenv=INSIDE_EMACS=..." (common/asshelp.c:
|
||||
# send_pinentry_environment); gpg-agent stores that per-session and
|
||||
# copies it into the forked pinentry's actual env for that one
|
||||
# request (agent/call-pinentry.c:atfork_core). So the var has to be
|
||||
# set on whatever shell/process runs git or gpg -- a prior attempt
|
||||
# at this set it on gpg-agent.service's systemd Environment instead,
|
||||
# which gpg-agent silently discards before it can ever be read.
|
||||
#
|
||||
# Only safe to set globally when Emacs is structurally guaranteed to
|
||||
# be up and responsive -- i.e. under EXWM, where Emacs *is* the
|
||||
# window manager. Elsewhere Emacs may not be running (fine: the
|
||||
# loopback socket connect fails instantly, same fast fallback as
|
||||
# today) or may be running but transiently busy (not fine: pinentry
|
||||
# then blocks on the Assuan handshake for up to its 60s timeout
|
||||
# before falling back, which is strictly worse than today's instant
|
||||
# failure).
|
||||
home.sessionVariables = lib.mkIf config.azos.suites.exwm.enable {
|
||||
INSIDE_EMACS = "t";
|
||||
};
|
||||
|
||||
home.file.".ssh/config".source = ./ssh-config;
|
||||
home.file.".ssh/gpg-as-ssh.pub".source = ./gpg-as-ssh.pub;
|
||||
home.file.".gnupg/sshcontrol".source = ./sshcontrol;
|
||||
|
||||
# home-manager creates ~/.gnupg (via the files above) with the default
|
||||
# umask, which can leave it group/other-readable. gpg refuses to trust
|
||||
# a homedir like that and prints an "unsafe permissions" warning on
|
||||
# every invocation, which pollutes anything that captures gpg/pass
|
||||
# output (e.g. shell-command-to-string). Enforce 700 on every switch.
|
||||
home.activation.gnupgPerms = lib.hm.dag.entryAfter ["writeBoundary"] ''
|
||||
$DRY_RUN_CMD chmod 700 "$HOME/.gnupg"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDMdozJewuuqG4VuwGhI5Uw2xDIUrkQwyPGQ2q3tvnPq/VoV+zfdnou42I6XYEfOGd6xfLR0byOGCk1Ia1F/picBsxADEaJFBnTny5MWNA5MxwJIYUPW5+kFN1TmxdNGmj0WJ8qZeKkS3ffixdHlHTVu4Rzrlu8qDdw8TmgcvD7sHpNaBB+hwG9B/s5BAozfXvyXtW51lLLrEZdmUXJxAP51ubVgysZ985PA89o4G7LUE20IKAj3rgylLwq+Lz2PoGmVCptPTknLLzGlxTy2mU/tESJtS4iUvshSYiKak73BSen88xLWL/eZGFzOLW4TNem/qT0ykqK1s1BaGWCcQiDWN+Lpa3XqTbFN054MfhLdEMp+NjrdsCbZORzp9p2ZPDqi5jI1Hy7IN/8VzzB+T13MX6YhW7CBBqUZaivGhVQGsNjrFusPGhCaZrzNJ1l4qssLAlOh9qdaYzqDe+BIHsty55vw4Ph+Axou82babpLoiQzkCol2TWjPr7JSfHFkm6CmoTQ7mK8m7jRCodmxF+BEe4Usr+HrTKDc9fr5P4mdfL0O+ZPrlkPuG1zBTMal9MPxeCk4emzOZf7vBMNzb0aKHbOtSdVk/IcjatlDd2EIo34e5A6anLRMAdxb7901mnCAcjvCn6+ArNV8nr+NBk1+UvumZ+Q59LTrAkgRt3rBw== openpgp:0x13E0C25D
|
||||
@@ -1 +0,0 @@
|
||||
IdentityAgent ${XDG_RUNTIME_DIR}/gnupg/S.gpg-agent.ssh
|
||||
@@ -1 +0,0 @@
|
||||
37710BAB5F6DC9878A450CDA8A4661D932C04ACB
|
||||
@@ -1,32 +0,0 @@
|
||||
{...}: {
|
||||
config.flake.modules.homeManager.git-config = {
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
options.azos.git-config.enable = lib.mkOption {
|
||||
default = true;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
config = lib.mkIf config.azos.git-config.enable {
|
||||
home.packages = with pkgs; [pass-git-helper unzip];
|
||||
programs.git = {
|
||||
enable = true;
|
||||
signing = {
|
||||
key = "BB141234A3DD953D";
|
||||
signByDefault = true;
|
||||
};
|
||||
settings = {
|
||||
credential.helper = "!pass-git-helper $@";
|
||||
user = {
|
||||
name = "Aner Zakobar";
|
||||
email = "aner@zakobar.com";
|
||||
};
|
||||
};
|
||||
};
|
||||
home.file.".config/pass-git-helper/git-pass-mapping.ini".source =
|
||||
./pass-git-mapping.ini;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
[*git.zakobar.com*]
|
||||
target=zakobar.com
|
||||
@@ -1,191 +1,28 @@
|
||||
{...}: {
|
||||
config.flake.modules.homeManager.homey-alert = {
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
options.azos.homey-alert.enable = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
options.azos.homey-alert.longCommandThresholdSeconds = lib.mkOption {
|
||||
default = 300;
|
||||
example = 600;
|
||||
type = lib.types.int;
|
||||
description = ''
|
||||
Installs a global PreToolUse hook (matcher "Bash") in
|
||||
~/.claude/settings.json that transparently wraps every Bash command
|
||||
Claude Code runs: it times the command, and if it ran at or past
|
||||
this threshold, fires homey-alert with the elapsed time and exit
|
||||
code once it finishes. Commands that finish faster are unaffected.
|
||||
config.flake.overlayPkgs.azos-homey-ntfy-alert = pkgs:
|
||||
pkgs.writeShellApplication {
|
||||
name = "azos-homey-ntfy-alert";
|
||||
runtimeInputs = with pkgs; [curl pass];
|
||||
text = ''
|
||||
TOKEN="$(pass zakobar-homecenter/ntfy-token)"
|
||||
|
||||
This exists so long-running commands (big rclone transfers, builds)
|
||||
notify automatically even when Claude never thinks to chain
|
||||
homey-alert itself, and even if the harness moves the command to
|
||||
the background partway through.
|
||||
CMD=(
|
||||
curl -sf
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
-H "Priority: ''${PRIORITY:-default}"
|
||||
)
|
||||
[[ -n "''${TITLE:-}" ]] && CMD+=(-H "Title: $TITLE")
|
||||
[[ -n "''${TAGS:-}" ]] && CMD+=(-H "Tags: $TAGS")
|
||||
CMD+=(-d "''${MESSAGE:-}" https://ntfy.zakobar.com/alerts)
|
||||
|
||||
The hook only adds timing + notification around the command as
|
||||
given -- it does not change permissions, so normal confirmation
|
||||
prompts for risky commands still happen exactly as before.
|
||||
'';
|
||||
};
|
||||
|
||||
config = lib.mkIf config.azos.homey-alert.enable (let
|
||||
threshold = toString config.azos.homey-alert.longCommandThresholdSeconds;
|
||||
# Rewrites every Bash tool command to time itself and fire
|
||||
# homey-alert if it ran at or past the threshold. The original
|
||||
# command is spliced in verbatim (not eval'd from an encoded blob)
|
||||
# so it stays human-readable in any permission prompt, and it's run
|
||||
# in a subshell so the wrapper's own timing/notify code still runs
|
||||
# even if the original command uses `set -e` or calls `exit`.
|
||||
# permissionDecision is deliberately omitted from the hook's JSON
|
||||
# output: supplying it (even as "allow") would bypass the normal
|
||||
# confirmation flow, which must stay untouched here.
|
||||
bashNotifyHook = pkgs.writeShellApplication {
|
||||
name = "azos-bash-notify-hook";
|
||||
runtimeInputs = [pkgs.jq];
|
||||
text = ''
|
||||
input=$(cat)
|
||||
command=$(printf '%s' "$input" | jq -r '.tool_input.command // empty' 2>/dev/null) || command=""
|
||||
|
||||
if [ -z "$command" ]; then
|
||||
echo '{}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
wrapped="__azos_notify_start=\$(date +%s)
|
||||
(
|
||||
$command
|
||||
)
|
||||
__azos_notify_rc=\$?
|
||||
__azos_notify_dur=\$(( \$(date +%s) - __azos_notify_start ))
|
||||
if [ \"\$__azos_notify_dur\" -ge ${threshold} ]; then
|
||||
__azos_notify_tag=\$([ \"\$__azos_notify_rc\" -eq 0 ] && echo white_check_mark || echo x)
|
||||
homey-alert -t \"Long command\" -T \"\$__azos_notify_tag\" \"Finished in \$__azos_notify_dur s (exit \$__azos_notify_rc)\" >/dev/null 2>&1 || true
|
||||
fi
|
||||
exit \"\$__azos_notify_rc\""
|
||||
|
||||
jq -n --arg cmd "$wrapped" \
|
||||
'{hookSpecificOutput: {hookEventName: "PreToolUse", updatedInput: {command: $cmd}}}' 2>/dev/null || echo '{}'
|
||||
'';
|
||||
};
|
||||
in {
|
||||
azos.claude.globalSkills.notify = ./notify-skill.md;
|
||||
|
||||
home.activation.configureBashNotifyHook = lib.hm.dag.entryAfter ["writeBoundary"] ''
|
||||
SETTINGS_JSON="$HOME/.claude/settings.json"
|
||||
HOOK_ENTRY=$(${pkgs.jq}/bin/jq -n \
|
||||
--arg cmd "${bashNotifyHook}/bin/azos-bash-notify-hook" \
|
||||
'{
|
||||
matcher: "Bash",
|
||||
hooks: [{type: "command", command: $cmd}]
|
||||
}')
|
||||
|
||||
if [ -f "$SETTINGS_JSON" ]; then
|
||||
tmp=$(mktemp)
|
||||
${pkgs.jq}/bin/jq --argjson entry "$HOOK_ENTRY" \
|
||||
'.hooks.PreToolUse = ((.hooks.PreToolUse // []) | map(select(.matcher != $entry.matcher))) + [$entry]' \
|
||||
"$SETTINGS_JSON" > "$tmp" && mv "$tmp" "$SETTINGS_JSON"
|
||||
if [[ -n "''${AZOS_SEND_ALERT_PRINT_REMOTE:-}" ]]; then
|
||||
# Shell-quote each element so the output is safe to embed in SSH commands --
|
||||
# the token is already resolved above, so the remote host only needs curl.
|
||||
printf '%q ' "''${CMD[@]}"
|
||||
printf '\n'
|
||||
else
|
||||
${pkgs.jq}/bin/jq -n --argjson entry "$HOOK_ENTRY" \
|
||||
'{hooks: {PreToolUse: [$entry]}}' > "$SETTINGS_JSON"
|
||||
"''${CMD[@]}"
|
||||
fi
|
||||
'';
|
||||
|
||||
home.packages = [
|
||||
bashNotifyHook
|
||||
(pkgs.writeShellApplication {
|
||||
name = "homey-alert";
|
||||
runtimeInputs = with pkgs; [curl pass libnotify];
|
||||
text = ''
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: homey-alert [OPTIONS] [MESSAGE]
|
||||
|
||||
Send a notification to the homey ntfy server (ntfy.zakobar.com/alerts),
|
||||
and (when run locally, not with --print-remote) also via notify-send --
|
||||
the ntfy server isn't always reachable, so the local desktop notification
|
||||
always fires too, independent of whether the ntfy push succeeds.
|
||||
MESSAGE can be given as a positional argument or piped via stdin.
|
||||
|
||||
Options:
|
||||
-t, --title TITLE notification title
|
||||
-p, --priority PRIO priority: min|low|default|high|urgent (default: default)
|
||||
-T, --tags TAGS comma-separated emoji shortcodes (e.g. warning,rotating_light)
|
||||
-r, --print-remote print the curl command instead of running it
|
||||
(for pasting into SSH commands to remote machines)
|
||||
-h, --help show this help
|
||||
|
||||
Examples:
|
||||
# Local
|
||||
long_cmd && homey-alert -t "Training" -p high -T white_check_mark "done"
|
||||
|
||||
# Remote — expands locally, runs on the remote machine
|
||||
ssh user@host "python train.py && \$(homey-alert -r -t 'Training' 'done')"
|
||||
EOF
|
||||
}
|
||||
|
||||
TITLE=""
|
||||
PRIORITY="default"
|
||||
TAGS=""
|
||||
PRINT_REMOTE=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-t|--title) TITLE="$2"; shift 2 ;;
|
||||
-p|--priority) PRIORITY="$2"; shift 2 ;;
|
||||
-T|--tags) TAGS="$2"; shift 2 ;;
|
||||
-r|--print-remote) PRINT_REMOTE=true; shift ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
--) shift; break ;;
|
||||
-*) echo "Unknown option: $1" >&2; usage >&2; exit 1 ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
MESSAGE="$*"
|
||||
elif [[ ! -t 0 ]]; then
|
||||
MESSAGE="$(cat)"
|
||||
else
|
||||
echo "homey-alert: no message provided" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN="$(pass zakobar-homecenter/ntfy-token)"
|
||||
|
||||
# Build the curl invocation as an array — single source of truth for both modes
|
||||
CMD=(
|
||||
curl -sf
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
-H "Priority: $PRIORITY"
|
||||
)
|
||||
[[ -n "$TITLE" ]] && CMD+=(-H "Title: $TITLE")
|
||||
[[ -n "$TAGS" ]] && CMD+=(-H "Tags: $TAGS")
|
||||
CMD+=(-d "$MESSAGE" https://ntfy.zakobar.com/alerts)
|
||||
|
||||
if $PRINT_REMOTE; then
|
||||
# Shell-quote each element so the output is safe to embed in SSH commands
|
||||
printf '%q ' "''${CMD[@]}"
|
||||
printf '\n'
|
||||
else
|
||||
"''${CMD[@]}" || true
|
||||
|
||||
# Local desktop notification, independent of the ntfy push above --
|
||||
# the server isn't always up, so this always fires as a fallback.
|
||||
URGENCY="normal"
|
||||
case "$PRIORITY" in
|
||||
min|low) URGENCY="low" ;;
|
||||
high|urgent) URGENCY="critical" ;;
|
||||
esac
|
||||
notify-send -u "$URGENCY" "''${TITLE:-homey-alert}" "$MESSAGE" || true
|
||||
fi
|
||||
'';
|
||||
})
|
||||
];
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# Homey Alert — sending ntfy notifications when tasks finish
|
||||
|
||||
Use `homey-alert` to push notifications to Aner's homelab ntfy server when long tasks complete.
|
||||
|
||||
## When to use proactively
|
||||
|
||||
When running (or suggesting) a command that will take more than ~30 seconds — training runs,
|
||||
builds, deploys, downloads, test suites — append a notification automatically. Don't wait to
|
||||
be asked.
|
||||
|
||||
## Background / async tasks (Claude Code specifically)
|
||||
|
||||
If you (the agent) are running a command via Bash that could take longer than
|
||||
~10 minutes — large rclone/rsync transfers, builds, training runs — and it
|
||||
might run in the background (either because you set `run_in_background`, or
|
||||
because the harness auto-backgrounds it after its timeout), chain the
|
||||
`homey-alert` call **into that same command string from the start**. Don't
|
||||
wait until you notice it's taking a while and then think about notifying —
|
||||
by then the command is already running without it, and the harness's own
|
||||
"task finished" signal only reaches this session, not Aner's phone. Chaining
|
||||
upfront is the only way to get a real ntfy push the moment it actually
|
||||
finishes:
|
||||
|
||||
```bash
|
||||
rclone copy ... ; homey-alert -t "Backup" -p default -T "$([ $? -eq 0 ] && echo white_check_mark || echo x)" "rclone copy finished (exit $?)"
|
||||
```
|
||||
|
||||
## Local commands
|
||||
|
||||
Append after the command so it fires on success only (`&&`) or always (`;`):
|
||||
|
||||
```bash
|
||||
# Notify on success only
|
||||
long_cmd && homey-alert "Task done"
|
||||
|
||||
# Always notify (even on failure) — prefer this for deploys/training
|
||||
long_cmd; homey-alert -t "Training" -p high -T "$([ $? -eq 0 ] && echo white_check_mark || echo x)" "Exited $?"
|
||||
```
|
||||
|
||||
## Remote commands (SSH / training machines)
|
||||
|
||||
Remote machines don't have `homey-alert`. Use `-r`/`--print-remote` to get a self-contained
|
||||
`curl` command with the token already embedded. The `$(...)` expands **locally**; the resulting
|
||||
command string is what the remote machine executes.
|
||||
|
||||
```bash
|
||||
ssh user@host "python train.py && $(homey-alert -r -t 'Training' -p high -T white_check_mark 'Model finished')"
|
||||
```
|
||||
|
||||
The remote machine only needs `curl` (universally available).
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Short | Values / notes |
|
||||
|------|-------|----------------|
|
||||
| `--title TITLE` | `-t` | Notification title |
|
||||
| `--priority PRIO` | `-p` | `min` / `low` / `default` / `high` / `urgent` |
|
||||
| `--tags TAGS` | `-T` | Comma-separated emoji shortcodes: `white_check_mark`, `x`, `warning`, `rotating_light`, `tada` |
|
||||
| `--print-remote` | `-r` | Print curl command instead of running (embed token locally, run remotely) |
|
||||
|
||||
## Choosing priority and tags
|
||||
|
||||
- Routine completion (backup, build): `default` priority, `white_check_mark`
|
||||
- Training / long job: `high` priority, `white_check_mark` on success / `x` on failure
|
||||
- Something broke: `urgent` priority, `rotating_light`
|
||||
@@ -23,12 +23,12 @@
|
||||
nextcloudMountSafe = pkgs.writeShellScript "nextcloud-mount-safe" ''
|
||||
set -eu
|
||||
mountpoint="$HOME/${mountDir}"
|
||||
mkdir -p "$mountpoint"
|
||||
${pkgs.coreutils}/bin/mkdir -p "$mountpoint"
|
||||
while ! ${pkgs.azos-card-present}/bin/azos-card-present; do
|
||||
${pkgs.coreutils}/bin/sleep 10
|
||||
done
|
||||
password=$(${pkgs.pass}/bin/pass zakobar.com | head -1)
|
||||
uid=$(${pkgs.pass}/bin/pass nextcloud-username/aner | head -1)
|
||||
password=$(${pkgs.pass}/bin/pass zakobar.com | ${pkgs.coreutils}/bin/head -1)
|
||||
uid=$(${pkgs.pass}/bin/pass nextcloud-username/aner | ${pkgs.coreutils}/bin/head -1)
|
||||
export RCLONE_CONFIG_${remoteNameEnv}_TYPE=webdav
|
||||
export RCLONE_CONFIG_${remoteNameEnv}_URL="https://nextcloud.zakobar.com/remote.php/dav/files/$uid/"
|
||||
export RCLONE_CONFIG_${remoteNameEnv}_VENDOR=nextcloud
|
||||
@@ -63,9 +63,9 @@
|
||||
Unit.Description = "Mount Nextcloud ${remoteSubfolder} via rclone (waits silently for YubiKey)";
|
||||
Service = {
|
||||
Type = "simple";
|
||||
Environment = "PATH=${pkgs.fuse3}/bin:${pkgs.fuse}/bin";
|
||||
Environment = "PATH=/run/wrappers/bin:${pkgs.fuse3}/bin:${pkgs.fuse}/bin";
|
||||
ExecStart = "${nextcloudMountSafe}";
|
||||
ExecStop = "${pkgs.fuse3}/bin/fusermount3 -u %h/${mountDir}";
|
||||
ExecStop = "/run/wrappers/bin/fusermount3 -u %h/${mountDir}";
|
||||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
{...}: {
|
||||
config.flake.modules.nixos.printing = {
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
webpFilter = pkgs.writeShellScript "webptopdf" ''
|
||||
if [ $# -ge 6 ]; then
|
||||
INPUT="$6"
|
||||
TMPFILE=""
|
||||
else
|
||||
TMPFILE=$(mktemp /tmp/cups-webp-XXXXXX.webp)
|
||||
cat > "$TMPFILE"
|
||||
INPUT="$TMPFILE"
|
||||
fi
|
||||
TMPOUT=$(mktemp /tmp/cups-webp-XXXXXX.pdf)
|
||||
${pkgs.imagemagick}/bin/magick "$INPUT" "$TMPOUT"
|
||||
cat "$TMPOUT"
|
||||
rm -f "$TMPOUT"
|
||||
[ -n "$TMPFILE" ] && rm -f "$TMPFILE"
|
||||
'';
|
||||
|
||||
webpCupsMime = pkgs.runCommand "webp-cups-mime" {} ''
|
||||
mkdir -p $out/lib/cups/filter $out/share/cups/mime
|
||||
cp ${webpFilter} $out/lib/cups/filter/webptopdf
|
||||
chmod +x $out/lib/cups/filter/webptopdf
|
||||
echo 'image/webp webp string(0,"RIFF") string(8,"WEBP")' > $out/share/cups/mime/webp.types
|
||||
echo 'image/webp application/pdf 0 webptopdf' > $out/share/cups/mime/webp.convs
|
||||
'';
|
||||
in {
|
||||
options.azos.printing.enable = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
config = lib.mkIf config.azos.printing.enable {
|
||||
services.printing = {
|
||||
enable = true;
|
||||
drivers = [pkgs.hplip webpCupsMime];
|
||||
};
|
||||
|
||||
environment.systemPackages = [pkgs.hplip];
|
||||
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
users.users.aner.extraGroups = ["lp"];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -10,6 +10,14 @@
|
||||
};
|
||||
config = lib.mkIf config.azos.steam.enable {
|
||||
programs.steam.enable = true;
|
||||
|
||||
# HORI STICK A fight stick (0f0d:0040) is missing from Steam's bundled
|
||||
# 60-steam-input.rules, so Steam can't open its hidraw node for Steam
|
||||
# Input and falls back to a generic joystick mapping that drops BTN_C
|
||||
# (Circle). Grant the same uaccess the other HORI devices get.
|
||||
services.udev.extraRules = ''
|
||||
KERNEL=="hidraw*", ATTRS{idVendor}=="0f0d", ATTRS{idProduct}=="0040", MODE="0660", TAG+="uaccess"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
+20
-5
@@ -16,9 +16,6 @@
|
||||
suiteModules.homeManager.exwm
|
||||
suiteModules.homeManager.lauretta
|
||||
suiteModules.homeManager.claude
|
||||
suiteModules.homeManager.encryption
|
||||
suiteModules.homeManager.git-config
|
||||
suiteModules.homeManager.hfsprogs
|
||||
suiteModules.homeManager.hyprland
|
||||
suiteModules.homeManager.mail
|
||||
suiteModules.homeManager.mpris-proxy
|
||||
@@ -29,7 +26,6 @@
|
||||
suiteModules.homeManager.snx-rs
|
||||
suiteModules.homeManager.roam-backup
|
||||
suiteModules.homeManager.ytdl
|
||||
suiteModules.homeManager.homey-alert
|
||||
suiteModules.homeManager.leetcode
|
||||
];
|
||||
|
||||
@@ -56,7 +52,26 @@
|
||||
}
|
||||
];
|
||||
azos.roam-backup.enable = true;
|
||||
azos.homey-alert.enable = true;
|
||||
|
||||
azos.send-alert.enable = true;
|
||||
azos.send-alert.remoteCommand = "${pkgs.azos-homey-ntfy-alert}/bin/azos-homey-ntfy-alert";
|
||||
|
||||
azos.git-config.userName = "Aner Zakobar";
|
||||
azos.git-config.userEmail = "aner@zakobar.com";
|
||||
azos.git-config.signing.enable = true;
|
||||
azos.git-config.signing.key = "BB141234A3DD953D";
|
||||
azos.git-config.passCredentialHelper.enable = true;
|
||||
azos.git-config.passCredentialHelper.mapping = ''
|
||||
[*git.zakobar.com*]
|
||||
target=zakobar.com
|
||||
'';
|
||||
|
||||
azos.encryption.passwordStore.gpgKeyId = "26B851F81F8F7C55";
|
||||
azos.encryption.yubikey.enable = true;
|
||||
azos.encryption.browserpass.enable = true;
|
||||
azos.encryption.gpgSsh.enable = true;
|
||||
azos.encryption.gpgSsh.keygrip = "37710BAB5F6DC9878A450CDA8A4661D932C04ACB";
|
||||
azos.encryption.gpgSsh.publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDMdozJewuuqG4VuwGhI5Uw2xDIUrkQwyPGQ2q3tvnPq/VoV+zfdnou42I6XYEfOGd6xfLR0byOGCk1Ia1F/picBsxADEaJFBnTny5MWNA5MxwJIYUPW5+kFN1TmxdNGmj0WJ8qZeKkS3ffixdHlHTVu4Rzrlu8qDdw8TmgcvD7sHpNaBB+hwG9B/s5BAozfXvyXtW51lLLrEZdmUXJxAP51ubVgysZ985PA89o4G7LUE20IKAj3rgylLwq+Lz2PoGmVCptPTknLLzGlxTy2mU/tESJtS4iUvshSYiKak73BSen88xLWL/eZGFzOLW4TNem/qT0ykqK1s1BaGWCcQiDWN+Lpa3XqTbFN054MfhLdEMp+NjrdsCbZORzp9p2ZPDqi5jI1Hy7IN/8VzzB+T13MX6YhW7CBBqUZaivGhVQGsNjrFusPGhCaZrzNJ1l4qssLAlOh9qdaYzqDe+BIHsty55vw4Ph+Axou82babpLoiQzkCol2TWjPr7JSfHFkm6CmoTQ7mK8m7jRCodmxF+BEe4Usr+HrTKDc9fr5P4mdfL0O+ZPrlkPuG1zBTMal9MPxeCk4emzOZf7vBMNzb0aKHbOtSdVk/IcjatlDd2EIo34e5A6anLRMAdxb7901mnCAcjvCn6+ArNV8nr+NBk1+UvumZ+Q59LTrAkgRt3rBw== openpgp:0x13E0C25D";
|
||||
|
||||
home = {
|
||||
username = "aner";
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
suiteModules.nixos.dev
|
||||
suiteModules.nixos.steam
|
||||
suiteModules.nixos.attic
|
||||
suiteModules.nixos.printing
|
||||
suiteModules.nixos.hardware-auth
|
||||
];
|
||||
|
||||
@@ -94,6 +93,7 @@
|
||||
azos.suites.exwm.enable = true;
|
||||
azos.attic.enable = true;
|
||||
azos.printing.enable = true;
|
||||
azos.printing.username = "aner";
|
||||
azos.hardware-auth.enable = true;
|
||||
|
||||
# Needed for unprivileged FUSE mounts (e.g. rclone mount) -- without this,
|
||||
|
||||
Reference in New Issue
Block a user