Compare commits

...

22 Commits

Author SHA1 Message Date
2928c14adb Generate static mac-portable config 2026-05-14 16:40:54 +02:00
35e92af403 Create static build of mac-portable config 2026-05-14 14:36:47 +00:00
6e1631d77b Describe layout 2026-05-14 15:38:40 +02:00
ac28afc5eb Update signing key 2026-05-14 15:22:08 +02:00
ac3712aec5 Correct path to test legacy presence 2026-05-14 15:20:23 +02:00
a453390013 Clarify "migrated" .zshrc 2026-05-14 15:19:41 +02:00
00049f5255 Make homeDirectory setting a default
Some hosts may have different home path
2026-05-14 15:17:23 +02:00
6f260619a7 Add git signingkey and name/email to personal file 2026-05-14 14:38:06 +02:00
031eab1b27 Clarify FIDO2 key limitations 2026-05-14 14:04:34 +02:00
231a769de5 Update fw_nix to pick up new cache paths 2026-05-13 20:53:04 +00:00
6df6976cd2 nix flake update 2026-05-11 19:14:38 +00:00
9f5e9b00e8 Enable mosh on linux-headless 2026-05-11 19:10:04 +00:00
7b85d3b585 Give gemini esphome 2026-05-11 19:09:52 +00:00
ce75ee4024 Show timezone next to timestamp in tmux 2026-05-08 15:41:02 +00:00
94800586f6 Add MIT license 2026-05-04 09:27:04 +00:00
efbcd546f9 TODO for better integration between zsh and iTerm2 2026-05-03 16:20:53 +02:00
f75a9f1ccb Finish migrating to tmux
fix environment variable being reset to most recent value in new panels
2026-05-01 19:49:21 +00:00
e38f96eedb Move linux-lxc away from linux-headless
Not every linux-headless is LXC; e.g. venus
2026-04-30 13:12:34 +02:00
d7be1664ae nix flake update 2026-04-29 20:48:39 +00:00
24055ddfe7 Extract linux bits into a new module 2026-04-29 22:44:15 +02:00
7bde25ebec Avoid affinity warnings for ag 2026-04-29 19:57:14 +00:00
930d951625 Migrate from GNU screen to tmux 2026-04-29 19:56:58 +00:00
26 changed files with 1020 additions and 222 deletions

7
LICENSE.txt Normal file
View File

@@ -0,0 +1,7 @@
Copyright (c) 2026 dotdoom
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -10,11 +10,11 @@ git clone git@github.com:dotdoom/dotfiles.git
cd dotfiles
```
Step 2 - stow.
Step 2 - if Nix is not an option.
```
stow migrated
stow legacy
stow exported/{machine}
```
Step 2 - Nix.
@@ -28,6 +28,15 @@ nix run \
--flake .#artem@deimos
```
## Layout
- `assets`: files which are assets for home-manager
- `legacy`: files to be placed under `$HOME` which are still under stow
- `hosts/*/{darwin,nixos,home}.nix`: personal machine nix configs
- `modules/{darwin,nixos,home}/*.nix`: exported nix configs
- `exported`: for those poor souls who can not run nix, a pre-built collection
of files for `$HOME`, best effort
## Security
Risks taken (disclaimer):
@@ -68,7 +77,9 @@ Risks taken (disclaimer):
Instead of PIV, we use FIDO2 slots on Yubikey to generate resident (i.e.
stored solely on Yubikey itself) SSH keys using modern OpenSSH client built-in
FIDO2 support. This doesn't need an agent or a background daemon.
FIDO2 support. This doesn't need an agent or a background daemon. The lack of
agent however means that these keys can not be forwarded to remote host for
further SSH, Git signing or push.
To generate a new key:
@@ -103,8 +114,9 @@ Host deimos
### Commit signing
Use SSH keys (from Apple SE and Yubikey) to sign commits. Make sure to generate
a different set of keys for signing than the one you use for authentication. Add
`-O application=ssh:git-signature` to mark the key for signing (personal
a different set of keys for signing than the one you use for authentication, to
decouple authentication from authorization and reduce key leakage blast radius.
Add `-O application=ssh:git-signature` to mark the key for signing (personal
convention).
### AGE encryption

View File

@@ -8,9 +8,9 @@ export PATH="${HOME}/bin:${PATH}"
# Since we exec right afterwards, there's no point in setting this shell up.
if [[ -o login ]]; then
[ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] && \
[ -z "$STY" ] && \
which screen 2>/dev/null && \
exec screen -URR
[ -z "$TMUX" ] && \
command -v tmux >/dev/null && \
exec tmux new -A -D -s main
fi
HISTFILE=~/.zsh_history
@@ -62,7 +62,7 @@ alias grep='grep --line-buffered --color=auto'
alias ipt='iptables -nvL --line-numbers'
alias ip6t='ip6tables -nvL --line-numbers'
alias tcpdump='tcpdump -l'
alias ag='ag -C 2 --pager="$PAGER" --smart-case'
alias ag='ag -C 2 --noaffinity --pager="$PAGER" --smart-case'
alias mysql='mysql --select_limit=1000'
alias logcat='adb logcat -v "color printable usec year zone" -T 10'
alias readelf='readelf -W'

7
bin/export-home-config Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
CONFIG=$1
OUT_DIR="exported/$CONFIG"
STORE_PATH=$(nix build .#homeConfigurations."$CONFIG".activationPackage --extra-experimental-features 'nix-command flakes' --no-link --print-out-paths)
mkdir -p "$OUT_DIR"
cp -rL "$STORE_PATH/home-files/." "$OUT_DIR/"

View File

View File

@@ -0,0 +1,3 @@
[global]
hide_env_diff = true
warn_timeout = "30s"

View File

@@ -0,0 +1,603 @@
# -*- mode: sh -*-
# shellcheck shell=bash
# begin prologue inserted by resholve
NIX_DIRENV_FALLBACK_NIX=${NIX_DIRENV_FALLBACK_NIX:-/nix/store/bym3ycma17qshv526xjbdn2iayn6q7kr-nix-2.34.7/bin/nix}
# end prologue inserted by resholve
NIX_DIRENV_VERSION=3.1.1
# min required versions
BASH_MIN_VERSION=4.4
DIRENV_MIN_VERSION=2.21.3
_NIX_DIRENV_LOG_PREFIX="nix-direnv: "
_nix_direnv_info() {
log_status "${_NIX_DIRENV_LOG_PREFIX}$*"
}
_nix_direnv_warning() {
local msg=$*
local color_normal=""
local color_warning=""
if [[ -t 2 ]]; then
color_normal="\e[m"
color_warning="\e[33m"
fi
printf "%b" "$color_warning"
log_status "${_NIX_DIRENV_LOG_PREFIX}${msg}"
printf "%b" "$color_normal"
}
_nix_direnv_error() { log_error "${_NIX_DIRENV_LOG_PREFIX}$*"; }
_nix_direnv_nix=""
_nix() {
${_nix_direnv_nix} --no-warn-dirty --extra-experimental-features "nix-command flakes" "$@"
}
_require_version() {
local cmd=$1 raw_version=$2 version=${2%%[^0-9.]*} required=$3
if ! printf "%s\n" "$required" "$version" | LC_ALL=C /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/sort -c -V 2>/dev/null; then
_nix_direnv_error \
"minimum required $(/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/basename "$cmd") version is $required (installed: $raw_version)"
return 1
fi
}
_require_cmd_version() {
local cmd=$1 required=$2 version
if ! has "$cmd"; then
_nix_direnv_error "command not found: $cmd"
return 1
fi
version=$($cmd --version)
[[ $version =~ ([0-9]+\.[0-9]+(\.[0-9]+)?) ]]
_require_version "$cmd" "${BASH_REMATCH[1]}" "$required"
}
_nix_direnv_preflight() {
if [[ -z $direnv ]]; then
# shellcheck disable=2016
_nix_direnv_error '$direnv environment variable was not defined. Was this script run inside direnv?'
return 1
fi
# check command min versions
if [[ -z ${NIX_DIRENV_SKIP_VERSION_CHECK:-} ]]; then
# bash check uses $BASH_VERSION with _require_version instead of
# _require_cmd_version because _require_cmd_version uses =~ operator which would be
# a syntax error on bash < 3
if ! _require_version bash "$BASH_VERSION" "$BASH_MIN_VERSION" ||
# direnv stdlib defines $direnv
! _require_cmd_version "$direnv" "$DIRENV_MIN_VERSION"; then
return 1
fi
fi
if command -v nix >/dev/null 2>&1; then
_nix_direnv_nix=$(command -v nix)
elif [[ -n ${NIX_DIRENV_FALLBACK_NIX:-} ]]; then
_nix_direnv_nix="${NIX_DIRENV_FALLBACK_NIX}"
else
_nix_direnv_error "Could not find Nix binary, please add Nix to PATH or set NIX_DIRENV_FALLBACK_NIX"
return 1
fi
local layout_dir
layout_dir=$(direnv_layout_dir)
if [[ ! -d "$layout_dir/bin" ]]; then
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/mkdir -p "$layout_dir/bin"
fi
# N.B. This script relies on variable expansion in *this* shell.
# (i.e. The written out file will have the variables expanded)
# If the source path changes, the script becomes broken.
# Because direnv_layout_dir is user controlled,
# we can't assume to be able to reverse it to get the source dir
# So there's little to be done about this.
# Remove first to handle case where file is owned by a different user
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -f "${layout_dir}/bin/nix-direnv-reload"
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/cat >"${layout_dir}/bin/nix-direnv-reload" <<-EOF
#!/usr/bin/env bash
set -e
if [[ ! -d "$PWD" ]]; then
echo "Cannot find source directory; Did you move it?"
echo "(Looking for "$PWD")"
echo 'Cannot force reload with this script - use "direnv reload" manually and then try again'
exit 1
fi
# rebuild the cache forcefully
_nix_direnv_force_reload=1 direnv exec "$PWD" true
# Update the mtime for .envrc.
# This will cause direnv to reload again - but without re-building.
touch "$PWD/.envrc"
# Also update the timestamp of whatever profile_rc we have.
# This makes sure that we know we are up to date.
touch -r "$PWD/.envrc" "${layout_dir}"/*.rc
EOF
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/chmod +x "${layout_dir}/bin/nix-direnv-reload"
PATH_add "${layout_dir}/bin"
}
# Usage: nix_direnv_version <version_at_least>
#
# Checks that the nix-direnv version is at least as old as <version_at_least>.
nix_direnv_version() {
_require_version nix-direnv $NIX_DIRENV_VERSION "$1"
}
_nix_export_or_unset() {
local key=$1 value=$2
if [[ $value == __UNSET__ ]]; then
unset "$key"
else
export "$key=$value"
fi
}
_nix_import_env() {
local profile_rc=$1
local -A values_to_restore=(
["NIX_BUILD_TOP"]=${NIX_BUILD_TOP:-__UNSET__}
["TMP"]=${TMP:-__UNSET__}
["TMPDIR"]=${TMPDIR:-__UNSET__}
["TEMP"]=${TEMP:-__UNSET__}
["TEMPDIR"]=${TEMPDIR:-__UNSET__}
["terminfo"]=${terminfo:-__UNSET__}
)
local old_xdg_data_dirs=${XDG_DATA_DIRS:-}
# On the first run in manual mode, the profile_rc does not exist.
if [[ ! -e $profile_rc ]]; then
return
fi
eval "$(<"$profile_rc")"
# `nix print-dev-env` will create a temporary directory and use it as TMPDIR
# We cannot rely on this directory being available at all times,
# as it may be garbage collected.
# Instead - just remove it immediately.
# Use recursive & force as it may not be empty.
if [[ -n ${NIX_BUILD_TOP+x} && $NIX_BUILD_TOP == */nix-shell.* && -d $NIX_BUILD_TOP ]]; then
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -rf "$NIX_BUILD_TOP"
fi
for key in "${!values_to_restore[@]}"; do
_nix_export_or_unset "$key" "${values_to_restore[${key}]}"
done
local new_xdg_data_dirs=${XDG_DATA_DIRS:-}
export XDG_DATA_DIRS=
local IFS=:
for dir in $new_xdg_data_dirs${old_xdg_data_dirs:+:}$old_xdg_data_dirs; do
dir="${dir%/}" # remove trailing slashes
if [[ :$XDG_DATA_DIRS: == *:$dir:* ]]; then
continue # already present, skip
fi
XDG_DATA_DIRS="$XDG_DATA_DIRS${XDG_DATA_DIRS:+:}$dir"
done
}
_nix_add_gcroot() {
local storepath=$1
local symlink=$2
_nix build --out-link "$symlink" "$storepath"
}
_nix_refresh_gcroots() {
# Use touch to update all symlinks' timestamps to prevent nh
# from garbage collecting the frequently used direnv environment.
local layout_dir
layout_dir=$(direnv_layout_dir)
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/touch -h "${layout_dir}"/flake-profile-* "${layout_dir}"/flake-inputs/* "${layout_dir}"/nix-profile-*
}
_nix_clean_old_gcroots() {
local layout_dir=$1
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -rf "$layout_dir/flake-inputs/"
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -f "$layout_dir"/{nix,flake}-profile*
}
_nix_argsum_suffix() {
local out checksum
if [ -n "$1" ]; then
if has sha1sum; then
out=$(/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/sha1sum <<<"$1")
elif has shasum; then
out=$(shasum <<<"$1")
else
# degrade gracefully both tools are not present
return
fi
read -r checksum _ <<<"$out"
echo "-$checksum"
fi
}
nix_direnv_watch_file() {
# shellcheck disable=2016
log_error '`nix_direnv_watch_file` is deprecated - use `watch_file`'
watch_file "$@"
}
_nix_direnv_watches() {
local -n _watches=$1
if [[ -z ${DIRENV_WATCHES-} ]]; then
return
fi
while IFS= read -r line; do
local regex='"[Pp]ath": "(.+)"$'
if [[ $line =~ $regex ]]; then
local path="${BASH_REMATCH[1]}"
if [[ $path == "${XDG_DATA_HOME:-${HOME:-/var/empty}/.local/share}/direnv/allow/"* ]]; then
continue
fi
# expand new lines and other json escapes
# shellcheck disable=2059
path=$(printf "$path")
_watches+=("$path")
fi
done < <($direnv show_dump "${DIRENV_WATCHES}")
}
: "${_nix_direnv_manual_reload:=0}"
nix_direnv_manual_reload() {
_nix_direnv_manual_reload=1
}
: "${_nix_direnv_allow_fallback:=1}"
nix_direnv_disallow_fallback() {
_nix_direnv_info "Fallback disallowed"
_nix_direnv_allow_fallback=0
}
_nix_direnv_warn_manual_reload() {
if [[ -e $1 ]]; then
_nix_direnv_warning 'cache is out of date. use "nix-direnv-reload" to reload'
else
_nix_direnv_warning 'cache does not exist. use "nix-direnv-reload" to create it'
fi
}
use_flake() {
if ! _nix_direnv_preflight; then
return 1
fi
flake_expr="${1:-.}"
flake_uri="${flake_expr%#*}"
flake_dir=${flake_uri#"path:"}
if [[ $flake_expr == -* ]]; then
local message="the first argument must be a flake expression"
if [[ -n ${2:-} ]]; then
_nix_direnv_error "$message"
return 1
else
_nix_direnv_error "$message. did you mean 'use flake . $1'?"
return 1
fi
fi
local files_to_watch
files_to_watch=("$HOME/.direnvrc" "$HOME/.config/direnv/direnvrc")
if [[ -d $flake_dir ]]; then
files_to_watch+=("$flake_dir/flake.nix" "$flake_dir/flake.lock" "$flake_dir/devshell.toml")
fi
watch_file "${files_to_watch[@]}"
local layout_dir profile
layout_dir=$(direnv_layout_dir)
profile="${layout_dir}/flake-profile$(_nix_argsum_suffix "$flake_expr")"
local profile_rc="${profile}.rc"
local flake_inputs="${layout_dir}/flake-inputs/"
local watches
_nix_direnv_watches watches
local profile_missing=0
if [[ ! -e $profile ]]; then
_nix_direnv_info "cache invalidated: profile ($profile) does not exist"
profile_missing=1
fi
local profile_rc_missing=0
if [[ ! -e $profile_rc ]]; then
_nix_direnv_info "cache invalidated: profile_rc ($profile_rc) does not exist"
profile_rc_missing=1
fi
local file_nt_profilerc=0
local file=
local newer_files
for file in "${watches[@]}"; do
if [[ $file -nt $profile_rc ]]; then
newer_files+=("$file")
file_nt_profilerc=1
fi
done
if [[ $file_nt_profilerc -eq 1 ]]; then
_nix_direnv_info "cache invalidated: files newer than cache:"
echo -n "$_NIX_DIRENV_LOG_PREFIX" >/dev/stderr
printf "%s\n" "${newer_files[@]}" >/dev/stderr
fi
if [[ $profile_missing -eq 1 || $profile_rc_missing -eq 1 || $file_nt_profilerc -eq 1 ]]; then
if [[ $_nix_direnv_manual_reload -eq 1 && -z ${_nix_direnv_force_reload-} ]]; then
_nix_direnv_warn_manual_reload "$profile_rc"
else
local tmp_profile_rc
local tmp_profile="${layout_dir}/flake-tmp-profile.$$"
if tmp_profile_rc=$(_nix print-dev-env --profile "$tmp_profile" "$@"); then
# If we've gotten here, the user's current devShell is valid and we should cache it
_nix_clean_old_gcroots "$layout_dir"
# We need to update our cache
echo "$tmp_profile_rc" >"$profile_rc"
_nix_add_gcroot "$tmp_profile" "$profile"
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -f "$tmp_profile" "$tmp_profile"*
# also add garbage collection root for source
local flake_input_paths
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/mkdir -p "$flake_inputs"
flake_input_paths=$(_nix flake archive \
--json --no-write-lock-file \
-- "$flake_uri")
while [[ $flake_input_paths =~ /nix/store/[^\"]+ ]]; do
local store_path="${BASH_REMATCH[0]}"
_nix_add_gcroot "${store_path}" "${flake_inputs}/${store_path##*/}"
flake_input_paths="${flake_input_paths/${store_path}/}"
done
_nix_direnv_info "Renewed cache"
else
# The user's current flake failed to evaluate,
# but there is already a prior profile_rc,
# which is probably more useful than nothing.
# Fallback to use that (which means just leaving profile_rc alone!)
if [[ $_nix_direnv_allow_fallback -eq 1 ]]; then
_nix_direnv_warning "Evaluating current devShell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
else
return 1
fi
fi
fi
else
if [[ -e ${profile_rc} ]]; then
# Our cache is valid, use that
_nix_direnv_info "Using cached dev shell"
_nix_refresh_gcroots
else
# We don't have a profile_rc to use!
_nix_direnv_error "use_flake failed - Is your flake's devShell working?"
return 1
fi
fi
_nix_import_env "$profile_rc"
}
use_nix() {
if ! _nix_direnv_preflight; then
return 1
fi
local layout_dir path version
layout_dir=$(direnv_layout_dir)
if path=$(/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/realpath -e "$(_nix eval --impure --expr "<nixpkgs>" 2>/dev/null)"); then
if [[ -f "${path}/.version-suffix" ]]; then
version=$(<"${path}/.version-suffix")
elif [[ -f "${path}/.git/HEAD" ]]; then
local head
read -r head <"${path}/.git/HEAD"
local regex="ref: (.*)"
if [[ $head =~ $regex ]]; then
read -r version <"${path}/.git/${BASH_REMATCH[1]}"
else
version="$head"
fi
elif [[ -f "${path}/.version" && ${path} == "/nix/store/"* ]]; then
# borrow some bits from the store path
local version_prefix
read -r version_prefix < <(
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/cat "${path}/.version"
echo
)
version="${version_prefix}-${path:11:16}"
fi
fi
local profile
profile="${layout_dir}/nix-profile-${version:-unknown}$(_nix_argsum_suffix "$*")"
local profile_rc="${profile}.rc"
local in_packages=0
local attribute=
local packages=""
local extra_args=()
local nixfile=
if [[ -e "shell.nix" ]]; then
nixfile="./shell.nix"
elif [[ -e "default.nix" ]]; then
nixfile="./default.nix"
fi
while [[ $# -gt 0 ]]; do
i="$1"
shift
case $i in
-p | --packages)
in_packages=1
;;
--command | --run | --exclude)
# These commands are unsupported
# ignore them
shift
;;
--pure | -i | --keep)
# These commands are unsupported (but take no argument)
# ignore them
;;
--include | -I)
extra_args+=("$i" "${1:-}")
shift
;;
--attr | -A)
attribute="${1:-}"
shift
;;
--option | -o | --arg | --argstr)
extra_args+=("$i" "${1:-}" "${2:-}")
shift
shift
;;
-*)
# Other arguments are assumed to be of a single arg form
# (--foo=bar or -j4)
extra_args+=("$i")
;;
*)
if [[ $in_packages -eq 1 ]]; then
packages+=" $i"
else
nixfile=$i
fi
;;
esac
done
watch_file "$HOME/.direnvrc" "$HOME/.config/direnv/direnvrc" "shell.nix" "default.nix"
local watches
_nix_direnv_watches watches
local profile_missing=0
if [[ ! -e $profile ]]; then
_nix_direnv_info "cache invalidated: profile ($profile) does not exist"
profile_missing=1
fi
local profile_rc_missing=0
if [[ ! -e $profile_rc ]]; then
_nix_direnv_info "cache invalidated: profile_rc ($profile_rc) does not exist"
profile_rc_missing=1
fi
local file_nt_profilerc=0
local file=
local newer_files
for file in "${watches[@]}"; do
if [[ $file -nt $profile_rc ]]; then
newer_files+=("$file")
file_nt_profilerc=1
fi
done
if [[ $file_nt_profilerc -eq 1 ]]; then
_nix_direnv_info "cache invalidated: files newer than cache:"
echo -n "$_NIX_DIRENV_LOG_PREFIX" >/dev/stderr
printf "%s\n" "${newer_files[@]}" >/dev/stderr
fi
if [[ $profile_missing -eq 1 || $profile_rc_missing -eq 1 || $file_nt_profilerc -eq 1 ]]; then
if [[ $_nix_direnv_manual_reload -eq 1 && -z ${_nix_direnv_force_reload-} ]]; then
_nix_direnv_warn_manual_reload "$profile_rc"
else
local tmp_profile="${layout_dir}/nix-tmp-profile.$$"
local tmp_profile_rc
if [[ -n $packages ]]; then
extra_args+=("--expr" "with import <nixpkgs> {}; mkShell { buildInputs = [ $packages ]; }")
else
extra_args+=("--file" "$nixfile" --arg inNixShell true)
if [[ -n $attribute ]]; then
extra_args+=("$attribute")
fi
fi
# Some builtin nix tooling depends on this variable being set BEFORE their invocation to change their behavior
# (notably haskellPackages.developPackage returns an env if this is set)
# This allows us to more closely mimic nix-shell.
export IN_NIX_SHELL="impure"
if tmp_profile_rc=$(_nix \
print-dev-env \
--profile "$tmp_profile" \
--impure \
"${extra_args[@]}"); then
_nix_clean_old_gcroots "$layout_dir"
echo "$tmp_profile_rc" >"$profile_rc"
_nix_add_gcroot "$tmp_profile" "$profile"
/nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm -f "$tmp_profile" "$tmp_profile"*
_nix_direnv_info "Renewed cache"
else
if [[ $_nix_direnv_allow_fallback -eq 1 ]]; then
_nix_direnv_warning "Evaluating current nix shell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
else
unset IN_NIX_SHELL
return 1
fi
fi
fi
else
if [[ -e ${profile_rc} ]]; then
_nix_direnv_info "Using cached dev shell"
_nix_refresh_gcroots
else
_nix_direnv_error "use_nix failed - Is your nix shell working?"
unset IN_NIX_SHELL
return 1
fi
fi
_nix_import_env "$profile_rc"
}
### resholve directives (auto-generated) ## format_version: 3
# resholve: fake builtin:PATH_add
# resholve: fake builtin:direnv_layout_dir
# resholve: fake builtin:has
# resholve: fake builtin:log_error
# resholve: fake builtin:log_status
# resholve: fake builtin:watch_file
# resholve: fake external:nix
# resholve: fake function:shasum
# resholve: keep $NIX_DIRENV_FALLBACK_NIX
# resholve: keep $_nix_direnv_nix
# resholve: keep $ambient_nix
# resholve: keep $cmd
# resholve: keep $direnv
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/basename
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/cat
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/chmod
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/mkdir
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/realpath
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/rm
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/sha1sum
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/sort
# resholve: keep /nix/store/imxdgy6dqqmhb3mzzxg14zkfxx9vc1w0-coreutils-9.10/bin/touch

View File

@@ -0,0 +1,83 @@
set -g default-terminal "screen"
set -g base-index 0
setw -g pane-base-index 0
set -g status-keys vi
set -g mode-keys vi
bind -N "Select pane to the left of the active pane" h select-pane -L
bind -N "Select pane below the active pane" j select-pane -D
bind -N "Select pane above the active pane" k select-pane -U
bind -N "Select pane to the right of the active pane" l select-pane -R
bind -r -N "Resize the pane left by 5" \
H resize-pane -L 5
bind -r -N "Resize the pane down by 5" \
J resize-pane -D 5
bind -r -N "Resize the pane up by 5" \
K resize-pane -U 5
bind -r -N "Resize the pane right by 5" \
L resize-pane -R 5
# rebind main key: C-a
unbind C-b
set -g prefix C-a
bind -N "Send the prefix key through to the application" \
C-a send-prefix
set -g mouse on
set -g focus-events off
setw -g aggressive-resize off
setw -g clock-mode-style 12
set -s escape-time 0
set -g history-limit 10240
set-environment -g SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
set-option -g update-environment "DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION"
# Instead of flashing or beeping, blink the window in status.
set -g visual-bell off
set -g monitor-activity on
set -g bell-action none
set -g window-status-activity-style "fg=yellow,blink"
# Requires support from terminal (e.g. iTerm2).
set -s set-clipboard on
# For scrolling through logs.
bind y set-window-option synchronize-panes
# Panel configuration.
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind Enter resize-pane -Z
# Navigation.
bind -n M-Up new-window -c "#{pane_current_path}"
bind -n M-Down confirm-before -p "kill-window #W? (y/n)" kill-window
bind -n M-Left previous-window
bind -n M-Right next-window
# Status bar.
set -g status-interval 5
set -g status-position bottom
set -g status-style "bg=default,fg=white"
set -g status-left-length 20
set -g status-left "#[fg=green,bold]#H #[fg=white]| "
set -g status-right-length 60
set -g status-right "#[fg=cyan]%H:%M%Z %d.%m.%Y #[fg=white]| #[fg=yellow]Load: #(cut -d ' ' -f 1-3 /proc/loadavg)"
set -g status-justify left
set -g window-status-format "#[fg=white,dim]#I:#W#F"
set -g window-status-current-format "#[fg=white,bold,bg=blue] #I:#W#F "

View File

View File

@@ -0,0 +1,27 @@
# Environment variables
. "/nix/store/qvbn8gycz1r5r2n7ffx60258jwhsf9qs-hm-session-vars.sh/etc/profile.d/hm-session-vars.sh"
# Only source this once
if [[ -z "$__HM_ZSH_SESS_VARS_SOURCED" ]]; then
export __HM_ZSH_SESS_VARS_SOURCED=1
fi
[ -r ~/.zshenv_local ] && source ~/.zshenv_local || true
# Can't use ssh-agent-mux to mux Secretive and yubikey-agent:
# https://github.com/overhacked/ssh-agent-mux/issues/56
# export SSH_AUTH_SOCK=~/.ssh/ssh-agent-mux.sock
# Can't use Secretive to SSH using PIV from Yubikey:
# https://github.com/maxgoedjen/secretive/issues/330
#
# If PIV entry was generated by yubikey-agent, Secretive may not see it at
# all. Running 'ykman piv objects generate chuid' should fix that.
# https://github.com/maxgoedjen/secretive/issues/333
# See README.md "Security" section to learn how we create keys.
# Setting IdentityAgent in SSH config achieves a similar result, but doesn't
# work with commit signing.
export SSH_AUTH_SOCK=~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh

View File

@@ -0,0 +1,41 @@
typeset -U path cdpath fpath manpath
for profile in ${(z)NIX_PROFILES}; do
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
done
HELPDIR="/nix/store/0vkfqzpklvs9nmx6439vqwvlzwryd60j-zsh-5.9/share/zsh/$ZSH_VERSION/help"
autoload -U compinit && compinit
# History options should be set in .zshrc and after oh-my-zsh sourcing.
# See https://github.com/nix-community/home-manager/issues/177.
HISTSIZE="10000"
SAVEHIST="10000"
HISTFILE="/Users/empty/.zsh_history"
mkdir -p "$(dirname "$HISTFILE")"
# Set shell options
set_opts=(
HIST_FCNTL_LOCK HIST_IGNORE_DUPS HIST_IGNORE_SPACE SHARE_HISTORY
NO_APPEND_HISTORY NO_EXTENDED_HISTORY NO_HIST_EXPIRE_DUPS_FIRST
NO_HIST_FIND_NO_DUPS NO_HIST_IGNORE_ALL_DUPS NO_HIST_SAVE_NO_DUPS
)
for opt in "${set_opts[@]}"; do
setopt "$opt"
done
unset opt set_opts
# Outside NixOS, we need to load this manually. Same on MacOS, if
# /etc/zshrc is reset to its default content (post-upgrade).
if [ -r /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]; then
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
fi
if [ -r ~/dotfiles/assets/.zshrc ]; then
# Hack for faster iterations
. ~/dotfiles/assets/.zshrc
else
. /nix/store/036d8d9k0wqwsg88azvzb8lb02hd22n2-.zshrc
fi
eval "$(/nix/store/wjg69ndjcayriaav4rqrfq93rqn8hsq4-direnv-2.37.1/bin/direnv hook zsh)"

View File

@@ -0,0 +1 @@
{"Profiles":[{"Columns":160,"Guid":"17DF2CCB-C7CD-4BCC-AC28-666DD6C8AF4A","Mouse Reporting":true,"Name":"Nix-Managed","Normal Font":"Menlo-Regular 13","Rows":45}]}

View File

@@ -0,0 +1 @@
/nix/store/f1p62r5lq4ilsj6kla8mmzfqj4q57x45-home-manager-fonts

69
flake.lock generated
View File

@@ -3,16 +3,16 @@
"brew-src": {
"flake": false,
"locked": {
"lastModified": 1774235677,
"narHash": "sha256-0ryNYmzDAeRlrzPTAgmzGH/Cgc8iv/LBN6jWGUANvIk=",
"lastModified": 1778146321,
"narHash": "sha256-HeBwuJmuBioZHyZqDOcf7W/xsMFupSD583v6I5Cl7a8=",
"owner": "Homebrew",
"repo": "brew",
"rev": "894a3d23ac0c8aaf561b9874b528b9cb2e839201",
"rev": "af835384ac574f76025adb38b292b04cecee1f1f",
"type": "github"
},
"original": {
"owner": "Homebrew",
"ref": "5.1.1",
"ref": "5.1.10",
"repo": "brew",
"type": "github"
}
@@ -24,11 +24,11 @@
]
},
"locked": {
"lastModified": 1775037210,
"narHash": "sha256-KM2WYj6EA7M/FVZVCl3rqWY+TFV5QzSyyGE2gQxeODU=",
"lastModified": 1777780666,
"narHash": "sha256-8wURyQMdDkGUarSTKOGdCuFfYiwa3HbzwscUfn3STDE=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "06648f4902343228ce2de79f291dd5a58ee12146",
"rev": "8c62fba0854ba15c8917aed18894dbccb48a3777",
"type": "github"
},
"original": {
@@ -96,11 +96,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1776096920,
"narHash": "sha256-8ZyTKMgyms+4Gcp1Zy3qMDXLxvO3FUDJUukxUYnlbLU=",
"lastModified": 1778705491,
"narHash": "sha256-LOZbixhLsv2QbUbqH+I06eRMAI7FBDDkGoMWH523OkE=",
"ref": "refs/heads/main",
"rev": "caafea45ba50ab9cdaefaf049ecd862b690124bb",
"revCount": 19,
"rev": "b6fb4221bd5f54bc427de84230e0c95952399c21",
"revCount": 25,
"type": "git",
"url": "https://github.com/futureware-tech/nix.git"
},
@@ -119,11 +119,11 @@
]
},
"locked": {
"lastModified": 1774104215,
"narHash": "sha256-EAtviqz0sEAxdHS4crqu7JGR5oI3BwaqG0mw7CmXkO8=",
"lastModified": 1778507602,
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "f799ae951fde0627157f40aec28dec27b22076d0",
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"type": "github"
},
"original": {
@@ -141,11 +141,11 @@
]
},
"locked": {
"lastModified": 1775585728,
"narHash": "sha256-8Psjt+TWvE4thRKktJsXfR6PA/fWWsZ04DVaY6PUhr4=",
"lastModified": 1778507602,
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "580633fa3fe5fc0379905986543fd7495481913d",
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"type": "github"
},
"original": {
@@ -204,11 +204,11 @@
]
},
"locked": {
"lastModified": 1776046499,
"narHash": "sha256-Wzc4nn07/0RL21ypPHRzNDQZcjhIC8LaYo7QJQjM5T4=",
"lastModified": 1778503501,
"narHash": "sha256-08L/X4/do7nET4rzidJ76eV/1r+mB7DchVpdPypsghc=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "287f84846c1eb3b72c986f5f6bebcff0bd67440d",
"rev": "85ba629c79449badf4338117c27f0ee92b4b9f1a",
"type": "github"
},
"original": {
@@ -237,11 +237,11 @@
"brew-src": "brew-src"
},
"locked": {
"lastModified": 1774720267,
"narHash": "sha256-YYftFe8jyfpQI649yfr0E+dqEXE2jznZNcYvy/lKV1U=",
"lastModified": 1778332591,
"narHash": "sha256-ctJ3ADtugrnbMfMBobA645gCqXVIyHnsCNMkVaIuSiM=",
"owner": "zhaofengli",
"repo": "nix-homebrew",
"rev": "a7760a3a83f7609f742861afb5732210fdc437ed",
"rev": "7d0038b5bb60568ec41f5f4ef5067cd221ca7c0d",
"type": "github"
},
"original": {
@@ -252,11 +252,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1775710090,
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
"lastModified": 1777954456,
"narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
"rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1",
"type": "github"
},
"original": {
@@ -266,22 +266,6 @@
"type": "github"
}
},
"nixpkgs-screen": {
"locked": {
"lastModified": 1737753705,
"narHash": "sha256-fQeXAeNQrsEUH3fd6RTjN/W+8flJiAFHo7Eya2RT87M=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e518d4ad2bcad74f98fec028cf21ce5b1e5020dd",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e518d4ad2bcad74f98fec028cf21ce5b1e5020dd",
"type": "github"
}
},
"root": {
"inputs": {
"darwin": "darwin",
@@ -291,7 +275,6 @@
"jail-nix": "jail-nix",
"nix-homebrew": "nix-homebrew",
"nixpkgs": "nixpkgs",
"nixpkgs-screen": "nixpkgs-screen",
"systems": "systems_2",
"vscode-server": "vscode-server"
}

View File

@@ -3,11 +3,6 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
# too many issues with screen 5.0
# - load average in status broken
# - background colors in programs (eg less) not showing
# - caption and hardstatus color lacks intensity
nixpkgs-screen.url = "github:NixOS/nixpkgs/e518d4ad2bcad74f98fec028cf21ce5b1e5020dd";
systems.url = "github:nix-systems/default";
home-manager = {
url = "github:nix-community/home-manager";
@@ -58,6 +53,13 @@
pre-commit-check = inputs.git-hooks.lib.${system}.run (
{
src = ./.;
excludes = [ "^exported/" ];
hooks.export-mac-portable = {
enable = nixpkgs.lib.hasInfix "darwin" system;
name = "Build static mac-portable home directory files";
entry = "bin/export-home-config mac-portable && git add exported/mac-portable";
pass_filenames = false;
};
}
// inputs.fw_nix.lib.pre-commit
);
@@ -70,6 +72,10 @@
darwinModules = {
mac-portable = import ./modules/darwin/mac-portable.nix;
};
nixosModules = {
linux-headless = import ./modules/nixos/linux-headless.nix;
linux-lxc = import ./modules/nixos/linux-lxc.nix;
};
homeConfigurations."artem@deimos" = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
@@ -93,6 +99,12 @@
];
};
homeConfigurations.mac-portable = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-darwin;
extraSpecialArgs.primaryUser = "empty";
modules = [ self.homeModules.mac-portable ];
};
darwinConfigurations.mars = darwin.lib.darwinSystem {
system = "x86_64-darwin";
specialArgs.primaryUser = "artem";
@@ -115,11 +127,10 @@
specialArgs = {
inherit trustedSSHKeys;
inherit (inputs) jail-nix;
pkgs-screen = import inputs.nixpkgs-screen {
inherit system;
};
};
modules = [
self.nixosModules.linux-headless
self.nixosModules.linux-lxc
inputs.fw_nix.nixosModules.nix-gc
inputs.fw_nix.nixosModules.nix-settings
inputs.fw_nix.nixosModules.tools

View File

@@ -1,7 +1,5 @@
{
modulesPath,
pkgs,
pkgs-screen,
trustedSSHKeys,
jail-nix,
...
@@ -10,67 +8,6 @@ let
jail = jail-nix.lib.init pkgs;
in
{
imports = [
"${modulesPath}/virtualisation/lxc-container.nix"
];
# Disable legacy channel behavior that lxc-container brings in via installer/cd-dvd/channel.nix.
system.installer.channel.enable = false;
# Impermanence setup:
# 1. There's no initrd/stage 1 in LXC container; /sbin/init is invoked after
# LXC finishes setting up special and user-configured filesystems. Any
# options in boot.initrd, as well as neededForBoot fileSystems won't be
# respected.
# 2. Non-boot fileSystems (aka systemd) mount too late for systemd or nixos
# persistence to be instantiated, so we have to create this script below.
# 3. The expectation from host is to mount /home and /nix. Root filesystem
# will also be a disk, as that's Incus requirement; the host should clean
# it up periodically using: "incus rebuild --empty <vm>".
# 4. Since rootfs will be empty after rebuild, you have to point LXC at the
# current init (instead of /sbin/init), by adding to the "config:" section
# in "incus config edit <vm>":
# raw.lxc: lxc.init.cmd = /nix/var/nix/profiles/system/init
system.activationScripts.persistence = {
deps = [ "specialfs" ];
text = ''
persist() {
local item="$1"
local constructor="''${item%%:*}"
local target="''${item#*:}"
mkdir -p "$(dirname "$target")"
$constructor "$target"
if ! mountpoint -q "$target"; then
local source="/home/persistent/$target"
mkdir -p "$(dirname "$source")"
$constructor "$source"
mount --bind "$source" "$target"
fi
}
for item in \
"mkdir -p:/var/lib/nixos" \
"mkdir -p:/var/lib/systemd" \
"touch:/etc/machine-id" \
"touch:/etc/ssh/ssh_host_ed25519_key" \
; do
persist "$item"
done
chmod 0600 /etc/ssh/ssh_host_ed25519_key
# lxc-container.nix installBootloader/installInitScript will attempt to
# symlink /sbin/init, so we have to create the parent directory.
mkdir -p /sbin
'';
};
system.activationScripts.users.deps = [ "persistence" ];
# This is supposed to persist machine-id, but fails.
systemd.services.systemd-machine-id-commit.enable = false;
users.users.artem = {
uid = 1000;
isNormalUser = true;
@@ -82,51 +19,16 @@ in
shell = pkgs.zsh;
linger = true; # Keep sshfs mounted even on logout.
};
# Create /etc/zshrc that loads the nix-darwin environment.
programs.zsh.enable = true;
security.sudo.wheelNeedsPassword = false;
virtualisation.docker.enable = true;
documentation.man.enable = true;
environment.systemPackages = with pkgs; [
# TODO: clean this up against artem@deimos
git
pkgs-screen.screen
# TODO: move below into hosts/deimos/home.nix
sshfs
# https://unix.stackexchange.com/questions/651165/using-systemd-to-mount-remote-filesystems-in-user-bus
# Have to run the wrapper due to SUID.
(pkgs.writeShellScriptBin "umount.fuse.sshfs" ''
exec /run/wrappers/bin/fusermount -u "$1"
'')
file
nixfmt
nixd
home-assistant-cli
yt-dlp
# From hosts/common/tools.nix:
# Software debug
iotop
dool # dool --time --disk -D /dev/sde,/dev/sdf --top-bio --top-cpu --zfs-arc
strace
ltrace
smem # smem -tkP nginx
# Hardware info and tunables
parted
hdparm
efivar
efibootmgr
sg3_utils # sg_unmap
lm_sensors # sensors
nvme-cli
dmidecode
ethtool
# jailed-gemini --yolo
(jail "jailed-gemini" pkgs.gemini-cli (
with jail.combinators;
@@ -163,6 +65,7 @@ in
procps
python3
esphome
nix
]
@@ -171,14 +74,6 @@ in
))
];
# unprivileged LXCs can't set net.ipv4.ping_group_range
security.wrappers.ping = {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = "${pkgs.iputils.out}/bin/ping";
};
# For building RPi configs. Extra steps are handled by the host (nas).
# https://discuss.linuxcontainers.org/t/systemd-binfmt-service-is-masked/21566/4
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
@@ -187,6 +82,4 @@ in
hostName = "deimos";
domain = "home.arpa";
};
system.stateVersion = "25.11"; # Never change this.
}

View File

@@ -1,7 +1,6 @@
{
pkgs,
lib,
config,
trustedSSHKeys,
...
}:
@@ -20,7 +19,7 @@
home.activation.setupAuthorizedKeys = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
run install -m 0600 -D \
${pkgs.writeText "keys" (builtins.concatStringsSep "\n" trustedSSHKeys)} \
${config.home.homeDirectory}/.ssh/ephemeral_sshd/authorized_keys
''${HOME?}/.ssh/ephemeral_sshd/authorized_keys
'';
# TODO: consider

View File

@@ -33,12 +33,13 @@
autoSetupMerge = false
# Set up new branches in a way that "git pull" does a rebase by default.
autoSetupRebase = always
# Commit signing, currently using ssh@mars -- to be switched to sign@mars after 2026-05-15
[gpg]
format = ssh
[commit]
gpgsign = true
# Must always go last, to be able to override the settings above.
[include]
path = ~/.config/gitconfig_local
[user]
signingkey = key::ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNwSX/Ib6kNzgRKqWfcb3HsAQQo++Gt9KeXSvP6NDk6YQPjDsi+//IiBovgLjQ34El+x8l8y3aYhfIGlCyX7aOM= sign@mars
name = Artem Sheremet
email = dot.doom@gmail.com

View File

@@ -1,34 +0,0 @@
# http://aperiodic.net/screen/commands:start
# see accompanying file ~/.ssh/rc
setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
# no screen blinking on bell
vbell off
startup_message off
# disable "New screen..." message
msgwait 0
defscrollback 10240
# hostname, timestamp, LA in status bar
caption always "%{+b}%H | %c %d.%m.%Y | Load: %l"
# colored window list
hardstatus alwayslastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<"
# Launch login shells
shell -${SHELL}
# 256color support
#termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
term screen-256color
#defbce "on"
# beep on activity monitor alert (C-a M)
# ex.: 12:37 activity -> 7$ zsh
activity "%c activity -> %n%f %t^G"
# Alt Left/Right = switch windows
bindkey "^[[1;3D" prev
bindkey "^[[1;3C" next
bindkey "^[b" prev
bindkey "^[f" next
# Alt N = new window
bindkey "^[n" screen
shelltitle '% |zsh'

View File

@@ -14,7 +14,7 @@
yubikey-manager
];
home.activation.stowLegacy = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
if [ -d "$HOME/dotfiles" ]; then
if [ -d "$HOME/dotfiles/legacy" ]; then
run ${pkgs.stow}/bin/stow -d $HOME/dotfiles -t $HOME legacy
fi
'';
@@ -28,11 +28,11 @@
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
fi
if [ -r ~/dotfiles/migrated/.zshrc ]; then
. ~/dotfiles/migrated/.zshrc
if [ -r ~/dotfiles/assets/.zshrc ]; then
# Hack for faster iterations
. ~/dotfiles/assets/.zshrc
else
# If no custom override is available, use the one bundled with flake.
. ${../../migrated/.zshrc}
. ${../../assets/.zshrc}
fi
'';
@@ -61,10 +61,11 @@
vim-startify
];
extraConfig = ''
if filereadable(expand("~/dotfiles/migrated/.vimrc"))
source ~/dotfiles/migrated/.vimrc
if filereadable(expand("~/dotfiles/assets/.vimrc"))
# Hack for faster iterations
source ~/dotfiles/assets/.vimrc
else
source ${../../migrated/.vimrc}
source ${../../assets/.vimrc}
endif
'';
};
@@ -82,5 +83,60 @@
};
};
programs.tmux = {
enable = true;
shortcut = "a"; # ^a
escapeTime = 0;
historyLimit = 10240;
# hjkl HJKL and mouse to switch between and resize panels.
mouse = true;
keyMode = "vi";
customPaneNavigationAndResize = true;
extraConfig = ''
set-environment -g SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
set-option -g update-environment "DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION"
# Instead of flashing or beeping, blink the window in status.
set -g visual-bell off
set -g monitor-activity on
set -g bell-action none
set -g window-status-activity-style "fg=yellow,blink"
# Requires support from terminal (e.g. iTerm2).
set -s set-clipboard on
# For scrolling through logs.
bind y set-window-option synchronize-panes
# Panel configuration.
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind Enter resize-pane -Z
# Navigation.
bind -n M-Up new-window -c "#{pane_current_path}"
bind -n M-Down confirm-before -p "kill-window #W? (y/n)" kill-window
bind -n M-Left previous-window
bind -n M-Right next-window
# Status bar.
set -g status-interval 5
set -g status-position bottom
set -g status-style "bg=default,fg=white"
set -g status-left-length 20
set -g status-left "#[fg=green,bold]#H #[fg=white]| "
set -g status-right-length 60
set -g status-right "#[fg=cyan]%H:%M%Z %d.%m.%Y #[fg=white]| #[fg=yellow]Load: #(cut -d ' ' -f 1-3 /proc/loadavg)"
set -g status-justify left
set -g window-status-format "#[fg=white,dim]#I:#W#F"
set -g window-status-current-format "#[fg=white,bold,bg=blue] #I:#W#F "
'';
};
home.stateVersion = "25.11"; # never modify
}

View File

@@ -1,8 +1,8 @@
{ primaryUser, ... }:
{ lib, primaryUser, ... }:
{
imports = [
./common.nix
];
home.homeDirectory = "/home/${primaryUser}";
home.homeDirectory = lib.mkDefault "/home/${primaryUser}";
}

View File

@@ -1,16 +1,22 @@
{ pkgs, primaryUser, ... }:
{
pkgs,
lib,
primaryUser,
...
}:
{
imports = [
./common.nix
];
home.homeDirectory = "/Users/${primaryUser}";
home.homeDirectory = lib.mkDefault "/Users/${primaryUser}";
home.packages = with pkgs; [
secretive
vlc-bin
# Faster and more feature-rich than Terminal.
# TODO: https://iterm2.com/shell_integration/zsh
iterm2
# Newer OpenSSH client to support FIDO2 keys.

View File

@@ -0,0 +1,23 @@
{
pkgs,
...
}:
{
# Create /etc/zshrc that loads the nix-darwin environment.
programs.zsh.enable = true;
security.sudo.wheelNeedsPassword = false;
programs.mosh.enable = true;
documentation.man.enable = true;
environment.systemPackages = with pkgs; [
# https://unix.stackexchange.com/questions/651165/using-systemd-to-mount-remote-filesystems-in-user-bus
# Have to run the wrapper due to SUID.
(pkgs.writeShellScriptBin "umount.fuse.sshfs" ''
exec /run/wrappers/bin/fusermount -u "$1"
'')
];
system.stateVersion = "25.11"; # Never change this.
}

View File

@@ -0,0 +1,75 @@
{
modulesPath,
pkgs,
...
}:
{
imports = [
"${modulesPath}/virtualisation/lxc-container.nix"
];
# Disable legacy channel behavior that lxc-container brings in via installer/cd-dvd/channel.nix.
system.installer.channel.enable = false;
# Impermanence setup:
# 1. There's no initrd/stage 1 in LXC container; /sbin/init is invoked after
# LXC finishes setting up special and user-configured filesystems. Any
# options in boot.initrd, as well as neededForBoot fileSystems won't be
# respected.
# 2. Non-boot fileSystems (aka systemd) mount too late for systemd or nixos
# persistence to be instantiated, so we have to create this script below.
# 3. The expectation from host is to mount /home and /nix. Root filesystem
# will also be a disk, as that's Incus requirement; the host should clean
# it up periodically using: "incus rebuild --empty <vm>".
# 4. Since rootfs will be empty after rebuild, you have to point LXC at the
# current init (instead of /sbin/init), by adding to the "config:" section
# in "incus config edit <vm>":
# raw.lxc: lxc.init.cmd = /nix/var/nix/profiles/system/init
system.activationScripts.persistence = {
deps = [ "specialfs" ];
text = ''
persist() {
local item="$1"
local constructor="''${item%%:*}"
local target="''${item#*:}"
mkdir -p "$(dirname "$target")"
$constructor "$target"
if ! mountpoint -q "$target"; then
local source="/home/persistent/$target"
mkdir -p "$(dirname "$source")"
$constructor "$source"
mount --bind "$source" "$target"
fi
}
for item in \
"mkdir -p:/var/lib/nixos" \
"mkdir -p:/var/lib/systemd" \
"touch:/etc/machine-id" \
"touch:/etc/ssh/ssh_host_ed25519_key" \
; do
persist "$item"
done
chmod 0600 /etc/ssh/ssh_host_ed25519_key
# lxc-container.nix installBootloader/installInitScript will attempt to
# symlink /sbin/init, so we have to create the parent directory.
mkdir -p /sbin
'';
};
system.activationScripts.users.deps = [ "persistence" ];
# This is supposed to persist machine-id, but fails.
systemd.services.systemd-machine-id-commit.enable = false;
# unprivileged LXCs can't set net.ipv4.ping_group_range
security.wrappers.ping = {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = "${pkgs.iputils.out}/bin/ping";
};
}