Squashed commit of the following:
commit 19ed08c375be6d6a0b344ab1b9d3f76f3c29514b Author: João Porta <jpedro.porta@gmail.com> Date: Fri Jul 17 23:12:12 2026 +0000 zsh commit 19df08188fa07b40b9b28a4665b015c4fa525dff Merge: 577d753 4e4cc38 Author: João Porta <jpedro.porta@gmail.com> Date: Thu Jul 16 22:29:29 2026 +0000 Merge remote-tracking branch 'refs/remotes/origin/tailscale' into tailscale commit 577d753475be867146ebcacc79330a1e227043a5 Author: João Porta <jpedro.porta@gmail.com> Date: Thu Jul 16 15:29:53 2026 +0000 tailscale commit 4e4cc381b9e333592184490ea9f749fe87ebbbb9 Author: João Porta <jpedro.porta@gmail.com> Date: Thu Jul 16 15:29:53 2026 +0000 tailscale
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
{
|
{ config
|
||||||
config,
|
, pkgs
|
||||||
pkgs,
|
, lib
|
||||||
lib,
|
, ...
|
||||||
...
|
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
@@ -47,6 +46,7 @@ in
|
|||||||
../../modules/home-manager/tmux
|
../../modules/home-manager/tmux
|
||||||
../../modules/home-manager/eza
|
../../modules/home-manager/eza
|
||||||
../../modules/home-manager/zoxide
|
../../modules/home-manager/zoxide
|
||||||
|
../../modules/home-manager/tailscale-daemon
|
||||||
];
|
];
|
||||||
|
|
||||||
home = {
|
home = {
|
||||||
@@ -86,6 +86,10 @@ in
|
|||||||
eza.enable = true;
|
eza.enable = true;
|
||||||
bat.enable = true;
|
bat.enable = true;
|
||||||
zoxide.enable = true;
|
zoxide.enable = true;
|
||||||
|
tailscale-daemon = {
|
||||||
|
enable = true;
|
||||||
|
acceptRoutes = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
@@ -97,11 +101,12 @@ in
|
|||||||
ripgrep
|
ripgrep
|
||||||
fd
|
fd
|
||||||
mosh
|
mosh
|
||||||
tailscale
|
|
||||||
fastfetch
|
fastfetch
|
||||||
|
lazygit
|
||||||
stow
|
stow
|
||||||
tmux
|
bluetuith
|
||||||
];
|
];
|
||||||
|
# `tailscale`/`ts` shell helpers come from the tailscale-daemon module.
|
||||||
|
|
||||||
# Non-NixOS host: fixes locales, ld paths, XDG desktop entries
|
# Non-NixOS host: fixes locales, ld paths, XDG desktop entries
|
||||||
targets.genericLinux.enable = true;
|
targets.genericLinux.enable = true;
|
||||||
@@ -214,7 +219,7 @@ in
|
|||||||
serverAliveInterval = 30;
|
serverAliveInterval = 30;
|
||||||
};
|
};
|
||||||
"pc-ts" = {
|
"pc-ts" = {
|
||||||
hostname = "jpporta-nixos";
|
hostname = "jpporta-nixos.taild23e4.ts.net";
|
||||||
user = "jpporta";
|
user = "jpporta";
|
||||||
serverAliveInterval = 30;
|
serverAliveInterval = 30;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.custom.tailscale-daemon;
|
||||||
|
|
||||||
|
# The writter-deck is a non-NixOS host that can't create a real tailscale0
|
||||||
|
# interface (missing TUN drivers). Userspace networking avoids that need.
|
||||||
|
#
|
||||||
|
# Layout:
|
||||||
|
# - Socket: %t/tailscaled/tailscaled.sock (per-session tmpfs)
|
||||||
|
# - State: $HOME/.local/state/tailscale/... (persistent)
|
||||||
|
#
|
||||||
|
# In systemd specifiers:
|
||||||
|
# %t → $XDG_RUNTIME_DIR (=/run/user/$UID) — works in systemd 249+
|
||||||
|
# %S → $XDG_CONFIG_HOME (! NOT $XDG_STATE_HOME) — works in systemd 249+
|
||||||
|
#
|
||||||
|
# Because %S points at the wrong place, we hard-code the persistent state
|
||||||
|
# path under $HOME/.local/state/, which is the XDG_STATE_HOME default.
|
||||||
|
homeDir = config.home.homeDirectory;
|
||||||
|
stateDir = "${homeDir}/.local/state/tailscale";
|
||||||
|
stateFile = "${stateDir}/tailscaled.state";
|
||||||
|
|
||||||
|
# Becomes "$XDG_RUNTIME_DIR/tailscaled/tailscaled.sock" at runtime.
|
||||||
|
socketFile = "%t/tailscaled/tailscaled.sock";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.custom.tailscale-daemon = {
|
||||||
|
enable = lib.mkEnableOption ''
|
||||||
|
Tailscale daemon (tailscaled) running as a systemd user service with
|
||||||
|
userspace networking. For non-NixOS hosts without TUN device drivers.
|
||||||
|
'';
|
||||||
|
|
||||||
|
acceptRoutes = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
If true, run `tailscale up --accept-routes` automatically on first
|
||||||
|
start. Otherwise you'll need to authenticate manually once.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
acceptDns = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to accept DNS settings from the coordination server.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# Create the persistent state dir up front so the systemd service can
|
||||||
|
# write to it immediately.
|
||||||
|
home.activation.createTailscaleDirs = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
run mkdir -p ${lib.escapeShellArg stateDir}
|
||||||
|
run chmod 0700 ${lib.escapeShellArg stateDir}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Export the socket path (systemd-249-expanded) so any tool (systray,
|
||||||
|
# scripts) picks the user-scope daemon automatically. Note: this
|
||||||
|
# contains a literal `%t` which systemd will expand when the daemon
|
||||||
|
# or its consumers run.
|
||||||
|
home.sessionVariables.TAILSCALED_SOCKET = "/run/user/$(id -u)/tailscaled/tailscaled.sock";
|
||||||
|
|
||||||
|
home.packages = [
|
||||||
|
pkgs.tailscale
|
||||||
|
|
||||||
|
# Wrapper so the CLI client can find the user-scope socket without flags.
|
||||||
|
(pkgs.writeShellApplication {
|
||||||
|
name = "ts";
|
||||||
|
runtimeInputs = [ pkgs.tailscale ];
|
||||||
|
text = ''
|
||||||
|
exec tailscale --socket="/run/user/$(id -u)/tailscaled/tailscaled.sock" "$@"
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.user.services.tailscaled = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Tailscale daemon (userspace networking, no TUN device)";
|
||||||
|
# No "After=default.target" — it would deadlock since default.target
|
||||||
|
# is what brings us up. Just wait for the runtime dir to exist.
|
||||||
|
RequiresMountsFor = [ "%t" ];
|
||||||
|
# Survive transient network blips / flap.
|
||||||
|
StartLimitIntervalSec = 60;
|
||||||
|
StartLimitBurst = 5;
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "notify";
|
||||||
|
ExecStart = lib.escapeShellArgs [
|
||||||
|
"${pkgs.tailscale}/bin/tailscaled"
|
||||||
|
"--tun=userspace-networking"
|
||||||
|
"--state=${stateFile}"
|
||||||
|
"--socket=${socketFile}"
|
||||||
|
];
|
||||||
|
# systemd-managed runtime dir:
|
||||||
|
# $XDG_RUNTIME_DIR/tailscaled (RuntimeDirectory, mode 0700)
|
||||||
|
# State is in $HOME/.local/state/tailscale and managed by us, not
|
||||||
|
# via StateDirectory, so we don't need to fight protectHome.
|
||||||
|
RuntimeDirectory = "tailscaled";
|
||||||
|
RuntimeDirectoryMode = "0700";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 5;
|
||||||
|
# Light sandboxing. systemd user services can't drop capabilities
|
||||||
|
# the way the system unit can, so we keep restrictions to a
|
||||||
|
# conservative subset that doesn't fight journald.
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
ReadWritePaths = [ "%t/tailscaled" "${stateDir}" ];
|
||||||
|
};
|
||||||
|
Install.WantedBy = [ "default.target" "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# One-shot: authenticate on first start if not already logged in.
|
||||||
|
# Idempotent: tailscale up is a no-op once you're logged in.
|
||||||
|
systemd.user.services.tailscale-up = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Tailscale: authenticate and connect";
|
||||||
|
After = [ "tailscaled.service" ];
|
||||||
|
Requires = [ "tailscaled.service" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = lib.escapeShellArgs ([
|
||||||
|
"${pkgs.tailscale}/bin/tailscale"
|
||||||
|
"--socket=${socketFile}"
|
||||||
|
"up"
|
||||||
|
(if cfg.acceptRoutes then "--accept-routes" else "--no-accept-routes")
|
||||||
|
(if cfg.acceptDns then "--accept-dns=true" else "--accept-dns=false")
|
||||||
|
]);
|
||||||
|
# Don't fail the whole stack if auth isn't completed yet.
|
||||||
|
SuccessExitStatus = [ 0 1 ];
|
||||||
|
};
|
||||||
|
Install.WantedBy = [ "default.target" "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -54,9 +54,22 @@
|
|||||||
rot0 = "wlr-randr --output HDMI-A-1 --transform normal";
|
rot0 = "wlr-randr --output HDMI-A-1 --transform normal";
|
||||||
rotl = "wlr-randr --output HDMI-A-1 --transform 270";
|
rotl = "wlr-randr --output HDMI-A-1 --transform 270";
|
||||||
rot180 = "wlr-randr --output HDMI-A-1 --transform 180";
|
rot180 = "wlr-randr --output HDMI-A-1 --transform 180";
|
||||||
|
# Tailscale shortcuts (writter-deck only really needs these, but
|
||||||
|
# they don't hurt anyone else either). `ts` is the wrapper that
|
||||||
|
# points the CLI at the user-scope socket from the tailscale-daemon
|
||||||
|
# module.
|
||||||
|
ts = "tailscale --socket=/tmp/ts-$UID/tailscaled.sock";
|
||||||
|
ts-status = "ts status";
|
||||||
|
ts-ping = "ts ping -c 3 jpporta-nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
initContent = ''
|
initContent = lib.mkMerge [
|
||||||
|
(lib.mkOrder 700 ''
|
||||||
|
# Home Manager normally defines ZSH in .zshenv. Keep it available
|
||||||
|
# when .zshrc is sourced directly as well.
|
||||||
|
export ZSH="${config.programs.zsh.oh-my-zsh.package}/share/oh-my-zsh"
|
||||||
|
'')
|
||||||
|
(lib.mkOrder 1000 ''
|
||||||
${lib.optionalString config.custom.zsh.fastfetch "fastfetch"}
|
${lib.optionalString config.custom.zsh.fastfetch "fastfetch"}
|
||||||
# Auto-rotate screen to portrait when running inside cage/foot
|
# Auto-rotate screen to portrait when running inside cage/foot
|
||||||
# on the writer-deck. Skipped over SSH and other non-Wayland sessions.
|
# on the writer-deck. Skipped over SSH and other non-Wayland sessions.
|
||||||
@@ -64,7 +77,8 @@
|
|||||||
export ROTATED=1
|
export ROTATED=1
|
||||||
wlr-randr --output HDMI-A-1 --transform 90 >/dev/null 2>&1
|
wlr-randr --output HDMI-A-1 --transform 90 >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
'';
|
'')
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
/nix/store/kldv63c3f6aqvk95rbwp7jf9ms7qjbb9-home-manager-generation
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
/nix/store/z1w7hmcjbxlj4zif3lwb8ifkn66rjy60-home-manager-generation
|
||||||
Reference in New Issue
Block a user