aboutsummaryrefslogtreecommitdiff
path: root/home/programs
diff options
context:
space:
mode:
authorFranck Cuny <franck@fcuny.net>2025-12-30 10:33:31 -0800
committerFranck Cuny <franck@fcuny.net>2025-12-30 11:33:46 -0800
commit7281f05669e92e3568f837591912350b32951555 (patch)
tree61964e392409ab188599af47e58d9a9154ab33ce /home/programs
parentinstall mkv related tools (diff)
downloadinfra-7281f05669e92e3568f837591912350b32951555.tar.gz
organize programs in a way that makes sense to me
Diffstat (limited to 'home/programs')
-rw-r--r--home/programs/backups/restic.nix196
-rw-r--r--home/programs/cli/bat.nix16
-rw-r--r--home/programs/cli/core.nix43
-rw-r--r--home/programs/cli/eza.nix21
-rw-r--r--home/programs/cli/fd.nix16
-rw-r--r--home/programs/cli/tmux.nix16
-rw-r--r--home/programs/dev/delta.nix7
-rw-r--r--home/programs/dev/direnv.nix13
-rw-r--r--home/programs/dev/gh.nix15
-rw-r--r--home/programs/dev/git.nix86
-rw-r--r--home/programs/dev/go.nix19
-rw-r--r--home/programs/dev/k8s.nix43
-rw-r--r--home/programs/media/mpv.nix16
-rw-r--r--home/programs/media/videos.nix11
-rw-r--r--home/programs/media/yt-dlp.nix17
-rw-r--r--home/programs/messengers/matrix.nix6
-rw-r--r--home/programs/security/age.nix13
-rw-r--r--home/programs/security/hashi.nix54
-rw-r--r--home/programs/security/onepassword.nix9
-rw-r--r--home/programs/security/sapi.nix20
-rw-r--r--home/programs/security/ssh.nix48
-rw-r--r--home/programs/security/yubikey.nix6
-rw-r--r--home/programs/shell/fish.nix22
-rw-r--r--home/programs/term/kitty.nix24
24 files changed, 737 insertions, 0 deletions
diff --git a/home/programs/backups/restic.nix b/home/programs/backups/restic.nix
new file mode 100644
index 0000000..a27270f
--- /dev/null
+++ b/home/programs/backups/restic.nix
@@ -0,0 +1,196 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ nasHost = "nas";
+ repoPath = "/backups/workstation";
+
+ resticRepository = "sftp:${nasHost}:${repoPath}";
+
+ backupPaths = [
+ "${config.home.homeDirectory}/Documents"
+ "${config.home.homeDirectory}/Pictures"
+ ];
+
+ excludeFile = "${config.home.homeDirectory}/.config/restic/exclude";
+ includeFile = "${config.home.homeDirectory}/.config/restic/includes";
+in
+{
+ home.packages = with pkgs; [ restic ];
+
+ age.secrets.restic-password = {
+ file = ../../../secrets/restic-pw.age;
+ path = "${config.home.homeDirectory}/.config/restic/password";
+ mode = "400";
+ };
+
+ home.sessionVariables = {
+ RESTIC_REPOSITORY = resticRepository;
+ RESTIC_PASSWORD_FILE = config.age.secrets.restic-password.path;
+ };
+
+ home.file.".config/restic/includes" = {
+ text = lib.concatStringsSep "\n" backupPaths;
+ onChange = ''
+ echo "Restic backup paths updated"
+ '';
+ };
+
+ home.file.".config/restic/exclude" = {
+ text = ''
+ # macOS specific
+ .DS_Store
+ .Trash
+ .Spotlight-V100
+ .fseventsd
+ .TemporaryItems
+ .DocumentRevisions-V100
+ .VolumeIcon.icns
+ .AppleDouble
+ .LSOverride
+ Library/Caches
+ Library/Logs
+
+ # Development artifacts
+ **/node_modules
+ **/.venv
+ **/__pycache__
+ **/*.pyc
+ **/venv
+ **/target # Rust
+ **/dist
+ **/build
+ **/.tox
+ **/.pytest_cache
+ **/.coverage
+ **/.mypy_cache
+
+ # Large files that might not need backup
+ *.dmg
+ *.iso
+ *.pkg
+
+ # Version control
+ **/.git/objects
+ **/.git/lfs
+
+ # IDE
+ **/.idea
+ **/.vscode
+ *.swp
+ *~
+ '';
+ };
+
+ home.file.".local/bin/restic-now" = {
+ executable = true;
+ text = ''
+ #!/usr/bin/env bash
+ set -euo pipefail
+
+ # Colors for output
+ RED='\033[0;31m'
+ GREEN='\033[0;32m'
+ YELLOW='\033[1;33m'
+ NC='\033[0m' # No Color
+
+ echo -e "''${GREEN}Starting restic backup...''${NC}"
+
+ # Check if repository exists, initialize if not
+ echo -e "''${YELLOW}Checking repository...''${NC}"
+ if ! ${pkgs.restic}/bin/restic cat config > /dev/null 2>&1; then
+ echo -e "''${YELLOW}Repository not found. Initializing...''${NC}"
+ ${pkgs.restic}/bin/restic init
+ fi
+
+ # Run backup
+ echo -e "''${GREEN}Running backup...''${NC}"
+ ${pkgs.restic}/bin/restic backup \
+ --compression max \
+ --files-from="${includeFile}" \
+ --exclude-file="${excludeFile}" \
+ --verbose=1 \
+ --host="$(hostname -s)"
+
+ # Unlock in case of stale locks
+ echo -e "''${YELLOW}Checking for stale locks...''${NC}"
+ ${pkgs.restic}/bin/restic unlock || true
+
+ # Prune old snapshots
+ echo -e "''${GREEN}Pruning old snapshots...''${NC}"
+ ${pkgs.restic}/bin/restic forget \
+ --prune \
+ --keep-daily=7 \
+ --keep-weekly=4 \
+ --keep-monthly=12 \
+ --compression max \
+ --verbose=1
+
+ # Check repository integrity (optional, can be slow)
+ echo -e "''${GREEN}Checking repository integrity...''${NC}"
+ ${pkgs.restic}/bin/restic check --read-data-subset=5%
+
+ echo -e "''${GREEN}Backup completed successfully!''${NC}"
+ '';
+ };
+
+ home.file.".local/bin/restic-status" = {
+ executable = true;
+ text = ''
+ #!/usr/bin/env bash
+ set -euo pipefail
+
+ echo "Repository: $RESTIC_REPOSITORY"
+ echo ""
+ echo "=== Latest snapshots ==="
+ ${pkgs.restic}/bin/restic snapshots --latest 5 --compact
+ echo ""
+ echo "=== Repository stats ==="
+ ${pkgs.restic}/bin/restic stats
+ '';
+ };
+
+ home.file.".local/bin/restic-mount" = {
+ executable = true;
+ text = ''
+ #!/usr/bin/env bash
+ set -euo pipefail
+
+ MOUNT_POINT="''${1:-$HOME/mnt/restic}"
+
+ if [ ! -d "$MOUNT_POINT" ]; then
+ echo "Creating mount point: $MOUNT_POINT"
+ mkdir -p "$MOUNT_POINT"
+ fi
+
+ echo "Mounting restic repository at $MOUNT_POINT"
+ echo "Press Ctrl+C to unmount"
+ ${pkgs.restic}/bin/restic mount "$MOUNT_POINT"
+ '';
+ };
+
+ home.file.".local/bin/restic-restore" = {
+ executable = true;
+ text = ''
+ #!/usr/bin/env bash
+ set -euo pipefail
+
+ if [ $# -lt 1 ]; then
+ echo "Usage: $0 <snapshot-id> [target-directory]"
+ echo ""
+ echo "Available snapshots:"
+ ${pkgs.restic}/bin/restic snapshots --compact
+ exit 1
+ fi
+
+ SNAPSHOT="$1"
+ TARGET="''${2:-$HOME/restic-restore}"
+
+ echo "Restoring snapshot $SNAPSHOT to $TARGET"
+ ${pkgs.restic}/bin/restic restore "$SNAPSHOT" --target "$TARGET"
+ '';
+ };
+}
diff --git a/home/programs/cli/bat.nix b/home/programs/cli/bat.nix
new file mode 100644
index 0000000..3627997
--- /dev/null
+++ b/home/programs/cli/bat.nix
@@ -0,0 +1,16 @@
+{ pkgs, ... }:
+{
+ programs.bat = {
+ enable = true;
+ extraPackages = with pkgs.bat-extras; [ batman ];
+ config = {
+ pager = "less -FR";
+ };
+ };
+
+ programs.fish.shellAliases = {
+ cat = "${pkgs.bat.outPath}/bin/bat --paging=never";
+ less = "${pkgs.bat.outPath}/bin/bat";
+ man = "${pkgs.bat-extras.batman}/bin/batman";
+ };
+}
diff --git a/home/programs/cli/core.nix b/home/programs/cli/core.nix
new file mode 100644
index 0000000..cbfd110
--- /dev/null
+++ b/home/programs/cli/core.nix
@@ -0,0 +1,43 @@
+{ config, pkgs, ... }:
+{
+ home.packages =
+ with pkgs;
+ [
+ bandwhich
+ bottom
+ coreutils
+ delve
+ dive # explore layers in docker images
+ docker
+ docker-credential-helpers
+ dust
+ dysk
+ jless
+ nil # nix lsp
+ nix-direnv # integration with direnv
+ nixfmt-rfc-style # new formatter
+ procs
+ shellcheck
+ tree
+ wget
+ wireshark
+ yq
+ ]
+ ++ lib.optionals pkgs.stdenv.isLinux [
+ pciutils
+ powertop
+ traceroute
+ ];
+
+ programs.ripgrep.enable = true;
+ programs.jq.enable = true;
+
+ programs.fish.shellAliases = {
+ grep = "${pkgs.ripgrep}/bin/rg";
+ ps = "${pkgs.procs}/bin/procs";
+ };
+
+ home.sessionPath = [
+ "${config.home.homeDirectory}/.local/bin"
+ ];
+}
diff --git a/home/programs/cli/eza.nix b/home/programs/cli/eza.nix
new file mode 100644
index 0000000..517ab2f
--- /dev/null
+++ b/home/programs/cli/eza.nix
@@ -0,0 +1,21 @@
+{ pkgs, ... }:
+{
+ programs.eza = {
+ enable = true;
+ icons = "always";
+ colors = "always";
+ git = true;
+ enableFishIntegration = false; # I setup my own aliases
+ extraOptions = [
+ "--group-directories-first"
+ "--no-quotes"
+ "--git-ignore"
+ ];
+ };
+
+ programs.fish.shellAliases = with pkgs; {
+ la = "${eza}/bin/eza -la";
+ ll = "${eza}/bin/eza -la -L=1";
+ lt = "${eza}/bin/eza -aT -L=2";
+ };
+}
diff --git a/home/programs/cli/fd.nix b/home/programs/cli/fd.nix
new file mode 100644
index 0000000..873eaed
--- /dev/null
+++ b/home/programs/cli/fd.nix
@@ -0,0 +1,16 @@
+{ pkgs, ... }:
+{
+ programs.fd = {
+ enable = true;
+ hidden = true;
+ ignores = [
+ ".git/"
+ ".direnv/"
+ "vendor/"
+ ];
+ };
+
+ programs.fish.shellAliases = {
+ find = "${pkgs.fd}/bin/fd";
+ };
+}
diff --git a/home/programs/cli/tmux.nix b/home/programs/cli/tmux.nix
new file mode 100644
index 0000000..776c443
--- /dev/null
+++ b/home/programs/cli/tmux.nix
@@ -0,0 +1,16 @@
+{ pkgs, ... }:
+{
+ programs.tmux = {
+ enable = true;
+ aggressiveResize = true;
+ baseIndex = 1;
+ clock24 = true;
+ escapeTime = 0;
+ historyLimit = 100000;
+ keyMode = "emacs";
+ mouse = true;
+ shell = "${pkgs.fish}/bin/fish";
+ shortcut = "z";
+ terminal = "tmux-256color";
+ };
+}
diff --git a/home/programs/dev/delta.nix b/home/programs/dev/delta.nix
new file mode 100644
index 0000000..726357f
--- /dev/null
+++ b/home/programs/dev/delta.nix
@@ -0,0 +1,7 @@
+{ ... }:
+{
+ programs.delta = {
+ enable = true;
+ options.features = "decorations side-by-side line-numbers";
+ };
+}
diff --git a/home/programs/dev/direnv.nix b/home/programs/dev/direnv.nix
new file mode 100644
index 0000000..bad971d
--- /dev/null
+++ b/home/programs/dev/direnv.nix
@@ -0,0 +1,13 @@
+{ ... }:
+{
+ programs.direnv = {
+ enable = true;
+ nix-direnv.enable = true;
+ config.global = {
+ disable_stdin = true;
+ strict_env = true;
+ hide_env_diff = true;
+ warn_timeout = 0;
+ };
+ };
+}
diff --git a/home/programs/dev/gh.nix b/home/programs/dev/gh.nix
new file mode 100644
index 0000000..b194b35
--- /dev/null
+++ b/home/programs/dev/gh.nix
@@ -0,0 +1,15 @@
+{ ... }:
+{
+ programs.gh = {
+ enable = true;
+ settings = {
+ version = 1;
+ git_protocol = "ssh";
+ prompt = "enabled";
+ aliases = {
+ co = "pr checkout";
+ vw = "pr view --web";
+ };
+ };
+ };
+}
diff --git a/home/programs/dev/git.nix b/home/programs/dev/git.nix
new file mode 100644
index 0000000..333f968
--- /dev/null
+++ b/home/programs/dev/git.nix
@@ -0,0 +1,86 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ inherit (config) userinfo;
+in
+{
+ home.packages = with pkgs; [
+ git-credential-manager
+ pre-commit
+ ];
+
+ programs.git = {
+ enable = true;
+ settings = {
+ user = {
+ name = lib.mkDefault userinfo.fullName;
+ email = lib.mkDefault userinfo.email;
+ };
+
+ core.whitespace = "trailing-space,space-before-tab";
+ color.ui = true;
+
+ # nicer output
+ column.ui = "auto";
+
+ # https://adamj.eu/tech/2024/01/18/git-improve-diff-histogram/
+ diff.algorithm = "histogram";
+
+ init.defaultBranch = "main";
+
+ # https://blog.gitbutler.com/how-git-core-devs-configure-git/
+ push = {
+ # abort if the remote branch does not match the local one
+ default = "simple";
+ autoSetupRemote = true;
+ followTags = true;
+ };
+
+ fetch = {
+ prune = true;
+ pruneTags = true;
+ all = true;
+ };
+
+ pull.rebase = true;
+
+ rebase = {
+ autosquash = true;
+ updateRefs = true;
+ # Automatically create a temporary stash entry before the
+ # operation begins, and apply it after the operation ends.
+ autoStash = true;
+ # Print a warning if some commits are removed
+ missingCommitsCheck = "warn";
+ };
+
+ branch = {
+ autosetuprebase = "remote";
+ sort = "authordate";
+ };
+
+ aliases = {
+ amend = "commit --amend";
+ a = "commit --amend --no-edit";
+ st = "status";
+ co = "checkout";
+ br = "branch";
+ rb = "pull --rebase";
+ hist = "log --pretty=format:\"%Cgreen%h %Creset%cd %Cblue[%cn] %Creset%s%C(yellow)%d%C(reset)\" --graph --date=relative --decorate --all";
+ llog = "log --graph --name-status --pretty=format:\"%C(red)%h %C(reset)(%cd) %C(green)%an %Creset%s %C(yellow)%d%Creset\" --date=relative";
+ logo = "log --pretty=format:\"%C(yellow)%h%Cred%d %Creset%s%Cblue (%cn)\" --decorate";
+ logf = "log --pretty=format:\"%C(yellow)%h%Cred%d %Creset%s%Cblue (%cn)\" --decorate --numstat";
+ };
+ };
+
+ ignores = [
+ ".DS_Store"
+ ".aider.*"
+ ".direnv"
+ ];
+ };
+}
diff --git a/home/programs/dev/go.nix b/home/programs/dev/go.nix
new file mode 100644
index 0000000..d6ea5f4
--- /dev/null
+++ b/home/programs/dev/go.nix
@@ -0,0 +1,19 @@
+{ config, pkgs, ... }:
+{
+ home.packages = with pkgs; [
+ go-tools # collection of tools, https://github.com/dominikh/go-tools
+ golangci-lint
+ gopls
+ ];
+
+ programs.go = {
+ enable = true;
+ env = {
+ GOPATH = "${config.xdg.dataHome}/pkg.go";
+ GOPRIVATE = [
+ "github.rbx.com/*"
+ "fcuny.net/*"
+ ];
+ };
+ };
+}
diff --git a/home/programs/dev/k8s.nix b/home/programs/dev/k8s.nix
new file mode 100644
index 0000000..1e6cd41
--- /dev/null
+++ b/home/programs/dev/k8s.nix
@@ -0,0 +1,43 @@
+{ pkgs, ... }:
+{
+ home.packages = with pkgs; [
+ kind # k8s in docker
+ kubebuilder # generate controller
+ kubectl
+ kubie # kubeconfig browser https://github.com/sbstp/kubie
+ kubernetes-helm # deploy applications
+ kubelogin-oidc # OIDC plugin
+ ];
+
+ programs.k9s = {
+ enable = true;
+ settings = {
+ k9s = {
+ refreshRate = 1;
+ };
+ };
+ };
+
+ home.file.kubie = {
+ target = ".kube/kubie.yaml";
+ text = ''
+ shell: fish
+ configs:
+ include:
+ - ~/.kube/rksconfig
+ prompt:
+ fish_use_rprompt: false
+ '';
+ };
+
+ programs.fish = {
+ shellAbbrs = {
+ k = "kubectl";
+ kctx = "kubie ctx";
+ klogs = "kubectl logs";
+ };
+ shellAliases = {
+ ukctx = "${pkgs.gh}/bin/gh api --hostname github.rbx.com repos/Roblox/cell-lifecycle/contents/rks/kubeconfig --jq '.content' | base64 -d > ~/.kube/rksconfig";
+ };
+ };
+}
diff --git a/home/programs/media/mpv.nix b/home/programs/media/mpv.nix
new file mode 100644
index 0000000..925d4fe
--- /dev/null
+++ b/home/programs/media/mpv.nix
@@ -0,0 +1,16 @@
+{ pkgs, ... }:
+{
+ programs.mpv = {
+ enable = true;
+ config = {
+ screenshot-directory = "~/Documents/screenshots";
+ ontop = true;
+ profile = "gpu-hq";
+ };
+ scripts = with pkgs.mpvScripts; [
+ sponsorblock
+ quality-menu # Switch video quality from YT on-the-go
+ vr-reversal # Script for mpv to play VR video with optional saving of head tracking data
+ ];
+ };
+}
diff --git a/home/programs/media/videos.nix b/home/programs/media/videos.nix
new file mode 100644
index 0000000..00d4f2a
--- /dev/null
+++ b/home/programs/media/videos.nix
@@ -0,0 +1,11 @@
+{ pkgs, ... }:
+{
+ home.packages =
+ with pkgs;
+ [
+ ffmpeg
+ ]
+ ++ lib.optionals pkgs.stdenv.isDarwin [
+ vlc-bin
+ ];
+}
diff --git a/home/programs/media/yt-dlp.nix b/home/programs/media/yt-dlp.nix
new file mode 100644
index 0000000..ae48c18
--- /dev/null
+++ b/home/programs/media/yt-dlp.nix
@@ -0,0 +1,17 @@
+{ ... }:
+{
+ programs.yt-dlp = {
+ enable = true;
+
+ settings = {
+ mtime = false;
+ merge-output-format = "mkv";
+ restrict-filenames = true;
+ embed-thumbnail = true;
+ embed-metadata = true;
+ embed-chapters = true;
+ sponsorblock-mark = "sponsor";
+ output = "~/Movies/%(uploader)s/%(upload_date>%Y-%m-%d)s-%(title)s-%(id)s.%(ext)s";
+ };
+ };
+}
diff --git a/home/programs/messengers/matrix.nix b/home/programs/messengers/matrix.nix
new file mode 100644
index 0000000..0bf6881
--- /dev/null
+++ b/home/programs/messengers/matrix.nix
@@ -0,0 +1,6 @@
+{ pkgs, ... }:
+{
+ home.packages = with pkgs; [
+ element-desktop
+ ];
+}
diff --git a/home/programs/security/age.nix b/home/programs/security/age.nix
new file mode 100644
index 0000000..e41d0d8
--- /dev/null
+++ b/home/programs/security/age.nix
@@ -0,0 +1,13 @@
+{ pkgs, config, ... }:
+{
+ home.packages = with pkgs; [
+ age
+ age-plugin-yubikey
+ passage
+ ];
+
+ home.sessionVariables = {
+ "PASSAGE_DIR" = "${config.xdg.dataHome}/passage";
+ "PASSAGE_IDENTITIES_FILE" = "${config.xdg.dataHome}/passage/identities";
+ };
+}
diff --git a/home/programs/security/hashi.nix b/home/programs/security/hashi.nix
new file mode 100644
index 0000000..c24845e
--- /dev/null
+++ b/home/programs/security/hashi.nix
@@ -0,0 +1,54 @@
+{ pkgs, ... }:
+let
+ nomad-prod = pkgs.writeShellScriptBin "nomad-prod" ''
+ set -e
+
+ if [ $# -ne 1 ]; then
+ echo "Usage: nomad-ui CELL_ID"
+ exit 1
+ fi
+
+ CELL_ID=$1
+
+ echo ">> Fetching cell definition for $CELL_ID from GitHub"
+ REGION_ID=$(${pkgs.gh}/bin/gh api --hostname github.rbx.com repos/Roblox/cell-lifecycle/contents/definitions/''${CELL_ID}.yaml --jq '.content' | base64 -d | yq -r '.regionId')
+
+ if [ -z "$REGION_ID" ] || [ "$REGION_ID" = "null" ]; then
+ echo "Error: Could not retrieve regionId for cell $CELL_ID"
+ exit 1
+ fi
+
+ echo ">> Found regionId: $REGION_ID"
+
+ case "$REGION_ID" in
+ r002)
+ VAULT_REGION="chi1"
+ ;;
+ r003)
+ VAULT_REGION="ash1"
+ ;;
+ *)
+ echo "Error: Unknown regionId $REGION_ID. Expected r002 or r003."
+ exit 1
+ ;;
+ esac
+
+ echo ">> Using vault region: $VAULT_REGION"
+
+ echo ">> Login to $VAULT_REGION vault using Okta"
+ export VAULT_ADDR="https://$VAULT_REGION-vault.simulprod.com:8200"
+ export VAULT_TOKEN=$(${pkgs.vault}/bin/vault login -field=token -method=oidc username=$USER)
+
+ echo ">> Accessing cell $CELL_ID"
+ export NOMAD_ADDR="https://$CELL_ID-nomad.simulprod.com"
+ export NOMAD_TOKEN=$(${pkgs.vault}/bin/vault read -field secret_id ''${CELL_ID}_nomad/creds/management)
+
+ ${pkgs.nomad}/bin/nomad ui --authenticate
+ '';
+in
+{
+ home.packages = with pkgs; [
+ nomad-prod
+ hashi
+ ];
+}
diff --git a/home/programs/security/onepassword.nix b/home/programs/security/onepassword.nix
new file mode 100644
index 0000000..f364a9e
--- /dev/null
+++ b/home/programs/security/onepassword.nix
@@ -0,0 +1,9 @@
+{ ... }:
+{
+ programs.onepassword = {
+ enable = true;
+ sshKeys = [
+ { account = "my.1password.com"; } # All keys from personal account
+ ];
+ };
+}
diff --git a/home/programs/security/sapi.nix b/home/programs/security/sapi.nix
new file mode 100644
index 0000000..1d90698
--- /dev/null
+++ b/home/programs/security/sapi.nix
@@ -0,0 +1,20 @@
+{ pkgs, ... }:
+{
+ home.packages = with pkgs; [
+ sapi
+ ];
+
+ # the configuration for sapi is generated when we run `sapi jump`,
+ # there's no need to manage it with nix.
+ programs.ssh.includes = [ "config_sapi" ];
+
+ programs.fish.shellAbbrs = {
+ "sjump-st1-snc2" = "${pkgs.sapi}/bin/sapi jump sitetest1-snc2";
+ "sjump-st1-snc3" = "${pkgs.sapi}/bin/sapi jump sitetest3-snc2";
+ "sjump-st2-snc2" = "${pkgs.sapi}/bin/sapi jump sitetest2-snc2";
+ "sjump-st3" = "${pkgs.sapi}/bin/sapi jump sitetest3";
+ "sjump" = "${pkgs.sapi}/bin/sapi jump";
+ "ssh-edge" =
+ "${pkgs.kitty}/bin/kitten ssh -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -J chi1-jumpcontainer-es -i (${pkgs._1password-cli}/bin/op read 'op://Infra-Compute-Edge-rks/ice_ssh-private-key/ice_rsa'|psub)";
+ };
+}
diff --git a/home/programs/security/ssh.nix b/home/programs/security/ssh.nix
new file mode 100644
index 0000000..004b082
--- /dev/null
+++ b/home/programs/security/ssh.nix
@@ -0,0 +1,48 @@
+{ config, ... }:
+{
+ programs.ssh = {
+ enable = true;
+ enableDefaultConfig = false;
+ matchBlocks = {
+ "*" = {
+ forwardAgent = true;
+ serverAliveInterval = 60;
+ controlPersist = "30m";
+ controlPath = "${config.home.homeDirectory}/.ssh/sockets/S.%r@%h:%p";
+ controlMaster = "auto";
+ };
+ "rivendell" = {
+ hostname = "192.168.1.114";
+ };
+ "riv-unlock" = {
+ hostname = "192.168.1.114";
+ user = "root";
+ port = 911;
+ };
+ "nas" = {
+ hostname = "192.168.1.68";
+ };
+ "bree" = {
+ hostname = "192.168.1.50";
+ };
+ "argonath" = {
+ hostname = "fcuny.net";
+ };
+ "github.com" = {
+ hostname = "github.com";
+ user = "git";
+ forwardAgent = false;
+ extraOptions = {
+ preferredAuthentications = "publickey";
+ controlMaster = "no";
+ controlPath = "none";
+ };
+ };
+ };
+ };
+
+ home.file = {
+ # we need this path to be created so that the control path can be used.
+ ".ssh/sockets/.keep".text = "# Managed by Home Manager";
+ };
+}
diff --git a/home/programs/security/yubikey.nix b/home/programs/security/yubikey.nix
new file mode 100644
index 0000000..8e5c598
--- /dev/null
+++ b/home/programs/security/yubikey.nix
@@ -0,0 +1,6 @@
+{ pkgs, ... }:
+{
+ home.packages = with pkgs; [
+ yubikey-manager
+ ];
+}
diff --git a/home/programs/shell/fish.nix b/home/programs/shell/fish.nix
new file mode 100644
index 0000000..1e1ef36
--- /dev/null
+++ b/home/programs/shell/fish.nix
@@ -0,0 +1,22 @@
+{ pkgs, ... }:
+{
+ programs.fish = {
+ enable = true;
+ interactiveShellInit = ''
+ set fish_greeting ""
+ '';
+ shellAbbrs = {
+ ncg = "nix-collect-garbage --delete-older-than 7d";
+ ndc = "nix develop --command";
+ nfc = "nix flake check";
+ ngcroot = "ls -al /nix/var/nix/gcroots/auto/";
+ nph = "nix profile history --profile /nix/var/nix/profiles/system";
+ nsn = "nix search nixpkgs";
+ nsv = "nix store verify --all";
+ };
+ };
+
+ home.sessionVariables = {
+ SHELL = "${pkgs.fish}/bin/fish";
+ };
+}
diff --git a/home/programs/term/kitty.nix b/home/programs/term/kitty.nix
new file mode 100644
index 0000000..b02702d
--- /dev/null
+++ b/home/programs/term/kitty.nix
@@ -0,0 +1,24 @@
+{ pkgs, ... }:
+{
+ programs.kitty = {
+ enable = true;
+ themeFile = "Modus_Operandi_Tinted";
+ settings = {
+ copy_on_select = "yes";
+ bold_font = "auto";
+ italic_font = "auto";
+ bold_italic_font = "auto";
+ window_padding_width = "3 10";
+ enable_audio_bell = "no";
+ tab_bar_edge = "bottom";
+ tab_title_template = "{title}{' :{}:'.format(num_windows) if num_windows > 1 else ''}";
+ tab_bar_style = "powerline";
+ font_family = "Source Code Pro";
+ font_size = "15.0";
+ };
+ };
+
+ programs.fish.shellAliases = {
+ s = "${pkgs.kitty}/bin/kitten ssh";
+ };
+}