feat: seperate applicatoins
This commit is contained in:
parent
515f422f03
commit
5bc30053d1
9 changed files with 220 additions and 130 deletions
|
|
@ -35,70 +35,6 @@
|
|||
services.resolved.enable = true;
|
||||
|
||||
networking.firewall.enable = true;
|
||||
# Required for Tailscale
|
||||
networking.firewall.checkReversePath = "loose";
|
||||
networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ 4096 ];
|
||||
|
||||
services.tailscale = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
systemd.services.tailscale-set-operator = {
|
||||
description = "Set Tailscale local preferences";
|
||||
after = [ "tailscaled.service" ];
|
||||
requires = [ "tailscaled.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
path = [ pkgs.tailscale ];
|
||||
script = ''
|
||||
tailscale set --operator=jet
|
||||
tailscale set --exit-node-allow-lan-access=true
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.opencode-tailnet = {
|
||||
description = "Expose OpenCode on the tailnet";
|
||||
after = [
|
||||
"network-online.target"
|
||||
"tailscaled.service"
|
||||
"tailscale-set-operator.service"
|
||||
];
|
||||
wants = [ "network-online.target" ];
|
||||
requires = [
|
||||
"tailscaled.service"
|
||||
"tailscale-set-operator.service"
|
||||
];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [
|
||||
pkgs.tailscale
|
||||
pkgs.coreutils
|
||||
pkgs.gnugrep
|
||||
];
|
||||
preStart = ''
|
||||
for attempt in {1..60}; do
|
||||
if tailscale status --json --peers=false | grep -q '"BackendState": *"Running"'; then
|
||||
tailscale serve --bg 4096
|
||||
exit 0
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Timed out waiting for Tailscale to reach Running state"
|
||||
exit 1
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "jet";
|
||||
Environment = [ "OPENCODE_DB=opencode.db" ];
|
||||
Restart = "always";
|
||||
RestartSec = 5;
|
||||
TimeoutStartSec = 75;
|
||||
ExecStart = "/etc/profiles/per-user/jet/bin/o serve --hostname 127.0.0.1 --port 4096";
|
||||
WorkingDirectory = config.users.users.jet.home;
|
||||
};
|
||||
};
|
||||
|
||||
time.timeZone = "America/Los_Angeles";
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
|
|
@ -389,12 +325,9 @@
|
|||
# Enable base suspend/resume hooks.
|
||||
powerManagement.enable = true;
|
||||
|
||||
# v4l2loopback for OBS Virtual Camera
|
||||
boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
|
||||
boot.kernelModules = [ "v4l2loopback" ];
|
||||
# Framework AMD laptops perform best with the US regulatory domain set explicitly.
|
||||
boot.extraModprobeConfig = ''
|
||||
options cfg80211 ieee80211_regdom=US
|
||||
options v4l2loopback devices=1 video_nr=1 card_label="OBS Virtual Camera" exclusive_caps=1
|
||||
'';
|
||||
|
||||
# RAM optimizations for 96GB system
|
||||
|
|
@ -420,7 +353,6 @@
|
|||
wget
|
||||
];
|
||||
|
||||
programs.steam.enable = true;
|
||||
programs.nix-index-database.comma.enable = true;
|
||||
|
||||
programs._1password.enable = true;
|
||||
|
|
@ -435,14 +367,8 @@
|
|||
binfmt = true;
|
||||
};
|
||||
|
||||
# GameCube adapter udev rules for Slippi/Dolphin
|
||||
# Disable USB autosuspend for Framework's problematic devices (fingerprint reader, USB-C hub)
|
||||
services.udev.extraRules = ''
|
||||
# GameCube adapter USB device (vendor ID 057e, product ID 0337)
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="0666"
|
||||
# GameCube adapter HID device (needed for Dolphin to access controllers)
|
||||
KERNEL=="hidraw*", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="0666", GROUP="input"
|
||||
# Disable autosuspend for Framework devices that have shown resume issues.
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="27c6", ATTR{idProduct}=="609c", ATTR{power/control}="on", ATTR{power/autosuspend}="-1"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{power/control}="on", ATTR{power/autosuspend}="-1"
|
||||
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1022", ATTR{class}=="0x0c0330", ATTR{power/control}="on"
|
||||
|
|
|
|||
|
|
@ -105,11 +105,16 @@
|
|||
sudo -v || exit $?
|
||||
nh os switch --hostname "$(${pkgs.hostname}/bin/hostname)" path:. "$@"
|
||||
'';
|
||||
nhb = pkgs.writeShellScriptBin "nhb" ''
|
||||
sudo -v || exit $?
|
||||
nh os boot --hostname "$(${pkgs.hostname}/bin/hostname)" path:. "$@"
|
||||
'';
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
pkgs.nh
|
||||
inputs.agenix.packages.x86_64-linux.default
|
||||
nhb
|
||||
nhs
|
||||
];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ lib, pkgs, ... }:
|
||||
{
|
||||
hostname,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
firefoxApplicationId = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
|
||||
|
|
@ -63,7 +68,7 @@ let
|
|||
});
|
||||
in
|
||||
{
|
||||
home.packages = [ torBrowser ];
|
||||
home.packages = lib.optionals (hostname == "framework") [ torBrowser ];
|
||||
|
||||
programs.zen-browser = {
|
||||
enable = true;
|
||||
|
|
@ -179,13 +184,21 @@ in
|
|||
force = true;
|
||||
engines = {
|
||||
"Google Web" = {
|
||||
urls = [ { template = "https://www.google.com/search?q={searchTerms}&udm=14&pws=0&filter=0&nfpr=1&hl=en&gl=US&safe=active"; } ];
|
||||
urls = [
|
||||
{
|
||||
template = "https://www.google.com/search?q={searchTerms}&udm=14&pws=0&filter=0&nfpr=1&hl=en&gl=US&safe=active";
|
||||
}
|
||||
];
|
||||
definedAliases = [
|
||||
"@g"
|
||||
];
|
||||
};
|
||||
"Google Basic" = {
|
||||
urls = [ { template = "https://www.google.com/search?gbv=1&q={searchTerms}&udm=14&pws=0&filter=0&nfpr=1&hl=en&gl=US&safe=active"; } ];
|
||||
urls = [
|
||||
{
|
||||
template = "https://www.google.com/search?gbv=1&q={searchTerms}&udm=14&pws=0&filter=0&nfpr=1&hl=en&gl=US&safe=active";
|
||||
}
|
||||
];
|
||||
definedAliases = [
|
||||
"@gb"
|
||||
"@gnj"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ let
|
|||
"-${osConfig.age.secrets."nasa-api-env".path}"
|
||||
else
|
||||
"-%h/.config/nasa-api.env";
|
||||
chatDesktopId = if hostname == "framework-work" then "slack.desktop" else "vesktop.desktop";
|
||||
isWork = hostname == "framework-work";
|
||||
isPersonal = hostname == "framework";
|
||||
chatDesktopId = if isWork then "slack.desktop" else "vesktop.desktop";
|
||||
favoriteApps = [
|
||||
"zen-beta.desktop"
|
||||
"com.mitchellh.ghostty.desktop"
|
||||
|
|
@ -26,13 +28,13 @@ let
|
|||
"betterbird.desktop"
|
||||
]
|
||||
++ (
|
||||
if hostname == "framework-work" then
|
||||
[ ]
|
||||
else
|
||||
if isPersonal then
|
||||
[
|
||||
"signal.desktop"
|
||||
"zulip.desktop"
|
||||
]
|
||||
else
|
||||
[ ]
|
||||
);
|
||||
autoMoveApplications = [
|
||||
"zen-beta.desktop:1"
|
||||
|
|
@ -41,32 +43,38 @@ let
|
|||
"betterbird.desktop:4"
|
||||
]
|
||||
++ (
|
||||
if hostname == "framework-work" then
|
||||
[ ]
|
||||
else
|
||||
if isPersonal then
|
||||
[
|
||||
"signal.desktop:5"
|
||||
"zulip.desktop:6"
|
||||
]
|
||||
else
|
||||
[ ]
|
||||
);
|
||||
autostartEntries = [
|
||||
"${homeLib.zenStartup}/share/applications/zen-startup.desktop"
|
||||
"${homeLib.ghosttyZellijStartup}/share/applications/ghostty-zellij-startup.desktop"
|
||||
]
|
||||
++ (
|
||||
if hostname == "framework-work" then
|
||||
if isWork then
|
||||
[
|
||||
"${pkgs.slack}/share/applications/slack.desktop"
|
||||
"${homeLib.betterbirdStartup}/share/applications/betterbird-startup.desktop"
|
||||
]
|
||||
else
|
||||
else if isPersonal then
|
||||
[
|
||||
"${homeLib.vesktopStartup}/share/applications/vesktop-startup.desktop"
|
||||
"${homeLib.betterbirdStartup}/share/applications/betterbird-startup.desktop"
|
||||
"${homeLib.signalStartup}/share/applications/signal-startup.desktop"
|
||||
"${homeLib.zulipStartup}/share/applications/zulip-startup.desktop"
|
||||
]
|
||||
else
|
||||
[ ]
|
||||
);
|
||||
personalEnabledExtensions = pkgs.lib.optionals isPersonal [
|
||||
"tailscale-gnome-qs@tailscale-qs.github.io"
|
||||
"evil-bit-toggle@jetpham.github.com"
|
||||
];
|
||||
vlcDesktop = "vlc.desktop";
|
||||
vlcVideoMimeTypes = [
|
||||
"application/mxf"
|
||||
|
|
@ -121,6 +129,18 @@ let
|
|||
"x-content/video-svcd"
|
||||
"x-content/video-vcd"
|
||||
];
|
||||
personalMimeDefaults =
|
||||
pkgs.lib.optionalAttrs isPersonal {
|
||||
"x-content/image-dcf" = "net.damonlynch.RapidPhotoDownloader.desktop";
|
||||
}
|
||||
// pkgs.lib.optionalAttrs isPersonal (
|
||||
builtins.listToAttrs (
|
||||
map (mimeType: {
|
||||
name = mimeType;
|
||||
value = vlcDesktop;
|
||||
}) vlcVideoMimeTypes
|
||||
)
|
||||
);
|
||||
in
|
||||
|
||||
{
|
||||
|
|
@ -146,7 +166,7 @@ in
|
|||
autorun-never = false;
|
||||
autorun-x-content-ignore = [ ];
|
||||
autorun-x-content-open-folder = [ ];
|
||||
autorun-x-content-start-app = [ "x-content/image-dcf" ];
|
||||
autorun-x-content-start-app = pkgs.lib.optionals isPersonal [ "x-content/image-dcf" ];
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/power" = {
|
||||
sleep-inactive-ac-type = "nothing";
|
||||
|
|
@ -183,14 +203,13 @@ in
|
|||
"wifiqrcode@glerro.pm.me"
|
||||
"system-monitor-next@paradoxxx.zero.gmail.com"
|
||||
"clipboard-indicator@tudmotu.com"
|
||||
"tailscale-gnome-qs@tailscale-qs.github.io"
|
||||
"auto-move-windows@gnome-shell-extensions.gcampax.github.com"
|
||||
"gnome-shell-extension-maximized-by-default@stiggimy.github.com"
|
||||
"no-titlebar-when-maximized@alec.ninja"
|
||||
"opencode-token-usage@jetpham.github.com"
|
||||
"evil-bit-toggle@jetpham.github.com"
|
||||
"reduced-motion-toggle@jetpham.github.com"
|
||||
];
|
||||
]
|
||||
++ personalEnabledExtensions;
|
||||
favorite-apps = favoriteApps;
|
||||
};
|
||||
"org/gnome/shell/extensions/auto-move-windows" = {
|
||||
|
|
@ -305,7 +324,7 @@ in
|
|||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
|
||||
xdg.desktopEntries."net.damonlynch.RapidPhotoDownloader" = {
|
||||
xdg.desktopEntries."net.damonlynch.RapidPhotoDownloader" = pkgs.lib.mkIf isPersonal {
|
||||
name = "Rapid Photo Downloader";
|
||||
genericName = "Photo Downloader";
|
||||
comment = "Download, rename, and back up photos and videos from cameras and cards";
|
||||
|
|
@ -333,7 +352,6 @@ in
|
|||
"x-scheme-handler/unknown" = "zen-beta.desktop";
|
||||
"x-scheme-handler/mailto" = "betterbird.desktop";
|
||||
"inode/directory" = "org.gnome.Nautilus.desktop";
|
||||
"x-content/image-dcf" = "net.damonlynch.RapidPhotoDownloader.desktop";
|
||||
"image/x-canon-cr2" = "gimp.desktop";
|
||||
"application/zip" = "org.gnome.FileRoller.desktop";
|
||||
"application/x-tar" = "org.gnome.FileRoller.desktop";
|
||||
|
|
@ -346,11 +364,6 @@ in
|
|||
"application/x-rar" = "org.gnome.FileRoller.desktop";
|
||||
"application/x-rar-compressed" = "org.gnome.FileRoller.desktop";
|
||||
}
|
||||
// builtins.listToAttrs (
|
||||
map (mimeType: {
|
||||
name = mimeType;
|
||||
value = vlcDesktop;
|
||||
}) vlcVideoMimeTypes
|
||||
);
|
||||
// personalMimeDefaults;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ homeLib, pkgs, ... }:
|
||||
{
|
||||
homeLib,
|
||||
hostname,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
chromeDevtoolsMcpShell = pkgs.runCommand "chrome-devtools-mcp-shell-path" { } ''
|
||||
|
|
@ -41,12 +46,12 @@ in
|
|||
mcp.linear = {
|
||||
type = "remote";
|
||||
url = "https://mcp.linear.app/mcp";
|
||||
enabled = true;
|
||||
enabled = hostname == "framework-work";
|
||||
};
|
||||
mcp.heytea = {
|
||||
type = "remote";
|
||||
url = "https://mcp.heytea.dev/mcp";
|
||||
enabled = true;
|
||||
enabled = hostname == "framework";
|
||||
};
|
||||
mcp.cloudflare-api = {
|
||||
type = "remote";
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@
|
|||
inputs,
|
||||
pkgs,
|
||||
homeLib,
|
||||
hostname,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
isWork = hostname == "framework-work";
|
||||
isPersonal = hostname == "framework";
|
||||
|
||||
evilBitCtl = pkgs.writeShellApplication {
|
||||
name = "evil-bitctl";
|
||||
runtimeInputs = [
|
||||
|
|
@ -118,10 +122,8 @@ let
|
|||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
in
|
||||
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
sharedPackages = with pkgs; [
|
||||
bat
|
||||
bun
|
||||
claude-code
|
||||
|
|
@ -153,10 +155,8 @@ in
|
|||
typescript-language-server
|
||||
nil
|
||||
|
||||
element-desktop
|
||||
file-roller
|
||||
font-manager
|
||||
foliate
|
||||
(gimp-with-plugins.override {
|
||||
plugins = with gimpPlugins; [
|
||||
gmic
|
||||
|
|
@ -166,26 +166,11 @@ in
|
|||
google-chrome
|
||||
handbrake
|
||||
inkscape
|
||||
kdePackages.kdenlive
|
||||
libreoffice
|
||||
logseq
|
||||
nufraw-thumbnailer
|
||||
obs-studio
|
||||
pavucontrol
|
||||
prismlauncher
|
||||
qpwgraph
|
||||
signal-desktop
|
||||
slack
|
||||
vesktop
|
||||
vlc
|
||||
zulip
|
||||
linphone
|
||||
lmstudio
|
||||
homeLib.betterbird
|
||||
darktable
|
||||
digikam
|
||||
exiftool
|
||||
rapid-photo-downloader
|
||||
brightnessctl
|
||||
nautilus
|
||||
playerctl
|
||||
|
|
@ -200,12 +185,43 @@ in
|
|||
gnomeExtensions.maximized-by-default-actually-reborn
|
||||
gnomeExtensions.no-titlebar-when-maximized
|
||||
gnomeExtensions.system-monitor-next
|
||||
gnomeExtensions.tailscale-qs
|
||||
gnomeExtensions.wifi-qrcode
|
||||
evilBitToggleExtension
|
||||
opencodeTokenUsageExtension
|
||||
reducedMotionToggleExtension
|
||||
|
||||
nerd-fonts.commit-mono
|
||||
];
|
||||
|
||||
workPackages = with pkgs; [
|
||||
slack
|
||||
];
|
||||
|
||||
personalPackages = with pkgs; [
|
||||
element-desktop
|
||||
foliate
|
||||
kdePackages.kdenlive
|
||||
logseq
|
||||
nufraw-thumbnailer
|
||||
obs-studio
|
||||
prismlauncher
|
||||
signal-desktop
|
||||
vesktop
|
||||
vlc
|
||||
zulip
|
||||
linphone
|
||||
darktable
|
||||
digikam
|
||||
exiftool
|
||||
rapid-photo-downloader
|
||||
|
||||
gnomeExtensions.tailscale-qs
|
||||
evilBitToggleExtension
|
||||
];
|
||||
in
|
||||
|
||||
{
|
||||
home.packages =
|
||||
sharedPackages
|
||||
++ pkgs.lib.optionals isWork workPackages
|
||||
++ pkgs.lib.optionals isPersonal personalPackages;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
{ config, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
hostname,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
isPersonal = hostname == "framework";
|
||||
|
||||
configureQbittorrentTailscale = pkgs.writeShellApplication {
|
||||
name = "configure-qbittorrent-tailscale";
|
||||
runtimeInputs = [
|
||||
|
|
@ -24,6 +32,7 @@ let
|
|||
postBuild = ''
|
||||
rm -f "$out/bin/qbittorrent"
|
||||
# Enforce qBittorrent's bind settings, then add a systemd interface allowlist.
|
||||
# RestrictNetworkInterfaces works for transient services, not transient scopes.
|
||||
cat > "$out/bin/qbittorrent" <<'EOF'
|
||||
#!${pkgs.runtimeShell}
|
||||
set -eu
|
||||
|
|
@ -37,7 +46,6 @@ let
|
|||
|
||||
exec ${pkgs.systemd}/bin/systemd-run \
|
||||
--user \
|
||||
--scope \
|
||||
--quiet \
|
||||
--collect \
|
||||
--property='RestrictNetworkInterfaces=lo tailscale0' \
|
||||
|
|
@ -57,10 +65,27 @@ let
|
|||
};
|
||||
in
|
||||
|
||||
{
|
||||
lib.mkIf isPersonal {
|
||||
home.activation.configureQbittorrentTailscale = config.lib.dag.entryAfter [ "writeBoundary" ] ''
|
||||
${configureQbittorrentTailscale}/bin/configure-qbittorrent-tailscale
|
||||
'';
|
||||
|
||||
home.file.".local/share/applications/org.qbittorrent.qBittorrent.desktop".text = ''
|
||||
[Desktop Entry]
|
||||
Categories=Network;FileTransfer;P2P;Qt;
|
||||
Exec=${qbittorrentTailscale}/bin/qbittorrent %U
|
||||
GenericName=BitTorrent client
|
||||
Comment=Download and share files over BitTorrent
|
||||
Icon=qbittorrent
|
||||
MimeType=application/x-bittorrent;x-scheme-handler/magnet;
|
||||
Name=qBittorrent
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=false
|
||||
StartupWMClass=qbittorrent
|
||||
Keywords=bittorrent;torrent;magnet;download;p2p;
|
||||
SingleMainWindow=true
|
||||
'';
|
||||
|
||||
home.packages = [ qbittorrentTailscale ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ let
|
|||
"${pkgs.wl-clipboard}/bin/wl-paste --type image --watch ${pkgs.cliphist}/bin/cliphist store"
|
||||
"${pkgs.swayidle}/bin/swayidle -w timeout 300 '${lockCommand}' before-sleep '${lockCommand}'"
|
||||
];
|
||||
isWork = hostname == "framework-work";
|
||||
isPersonal = hostname == "framework";
|
||||
workStartup = [
|
||||
"${config.programs.zen-browser.package}/bin/zen-beta"
|
||||
"${pkgs.ghostty}/bin/ghostty --fullscreen=true -e ${homeLib.zellijPersistentSession}/bin/zellij-persistent-session"
|
||||
|
|
@ -71,7 +73,13 @@ let
|
|||
"${pkgs.signal-desktop}/bin/signal-desktop --start-fullscreen"
|
||||
"${pkgs.zulip}/bin/zulip --start-fullscreen"
|
||||
];
|
||||
appStartup = if hostname == "framework-work" then workStartup else personalStartup;
|
||||
appStartup =
|
||||
if isWork then
|
||||
workStartup
|
||||
else if isPersonal then
|
||||
personalStartup
|
||||
else
|
||||
[ ];
|
||||
in
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ ... }:
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
|
|
@ -8,6 +8,85 @@
|
|||
|
||||
networking.hostName = "framework";
|
||||
|
||||
# Tailscale and tailnet exposure are personal-laptop only.
|
||||
networking.firewall.checkReversePath = "loose";
|
||||
networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ 4096 ];
|
||||
|
||||
services.tailscale.enable = true;
|
||||
|
||||
systemd.services.tailscale-set-operator = {
|
||||
description = "Set Tailscale local preferences";
|
||||
after = [ "tailscaled.service" ];
|
||||
requires = [ "tailscaled.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
path = [ pkgs.tailscale ];
|
||||
script = ''
|
||||
tailscale set --operator=jet
|
||||
tailscale set --exit-node-allow-lan-access=true
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.opencode-tailnet = {
|
||||
description = "Expose OpenCode on the tailnet";
|
||||
after = [
|
||||
"network-online.target"
|
||||
"tailscaled.service"
|
||||
"tailscale-set-operator.service"
|
||||
];
|
||||
wants = [ "network-online.target" ];
|
||||
requires = [
|
||||
"tailscaled.service"
|
||||
"tailscale-set-operator.service"
|
||||
];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [
|
||||
pkgs.tailscale
|
||||
pkgs.coreutils
|
||||
pkgs.gnugrep
|
||||
];
|
||||
preStart = ''
|
||||
for attempt in {1..60}; do
|
||||
if tailscale status --json --peers=false | grep -q '"BackendState": *"Running"'; then
|
||||
tailscale serve --bg 4096
|
||||
exit 0
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Timed out waiting for Tailscale to reach Running state"
|
||||
exit 1
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "jet";
|
||||
Environment = [ "OPENCODE_DB=opencode.db" ];
|
||||
Restart = "always";
|
||||
RestartSec = 5;
|
||||
TimeoutStartSec = 75;
|
||||
ExecStart = "/etc/profiles/per-user/jet/bin/o serve --hostname 127.0.0.1 --port 4096";
|
||||
WorkingDirectory = config.users.users.jet.home;
|
||||
};
|
||||
};
|
||||
|
||||
programs.steam.enable = true;
|
||||
|
||||
# Personal media/gaming hardware support.
|
||||
boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
|
||||
boot.kernelModules = [ "v4l2loopback" ];
|
||||
boot.extraModprobeConfig = ''
|
||||
options v4l2loopback devices=1 video_nr=1 card_label="OBS Virtual Camera" exclusive_caps=1
|
||||
'';
|
||||
|
||||
services.udev.extraRules = ''
|
||||
# GameCube adapter USB device (vendor ID 057e, product ID 0337)
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="0666"
|
||||
# GameCube adapter HID device (needed for Dolphin to access controllers)
|
||||
KERNEL=="hidraw*", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="0666", GROUP="input"
|
||||
'';
|
||||
|
||||
fileSystems."/tmp" = {
|
||||
device = "tmpfs";
|
||||
fsType = "tmpfs";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue