.
This commit is contained in:
parent
7529c0c5c4
commit
735aa76ea3
57 changed files with 3366 additions and 2482 deletions
539
flake.lock
generated
539
flake.lock
generated
|
|
@ -1,13 +1,35 @@
|
|||
{
|
||||
"nodes": {
|
||||
"arkenfox": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"pre-commit": "pre-commit"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1770200864,
|
||||
"narHash": "sha256-COdM5Lwfw07Q+YefYmcop1VPEX7e2goM9IiwfIrJt0g=",
|
||||
"owner": "dwarfmaster",
|
||||
"repo": "arkenfox-nixos",
|
||||
"rev": "94638bbfacfa250e5c88aaa7a8f2145926fb8e08",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "dwarfmaster",
|
||||
"repo": "arkenfox-nixos",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"cachyos-kernel": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1769435645,
|
||||
"narHash": "sha256-xxIqw5x8U+13ya2BUcwmAW6BdpCpMhrMTn6Pd0bzocE=",
|
||||
"lastModified": 1771517207,
|
||||
"narHash": "sha256-+zDtnmXNyMd3hMepErdPDZzqYS0PiZA0Anbbx9Pvs4g=",
|
||||
"owner": "CachyOS",
|
||||
"repo": "linux-cachyos",
|
||||
"rev": "e8675eeb9b48a23167b3e43f84e3be76e321935e",
|
||||
"rev": "39737576a25091a3c4ca00729b769a1f92ec98d5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -19,11 +41,11 @@
|
|||
"cachyos-kernel-patches": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1769587384,
|
||||
"narHash": "sha256-fPOlnH9arzQLmkbaZ6p+otwLuH9YEf/t8Q2o9/Yq/YA=",
|
||||
"lastModified": 1771516433,
|
||||
"narHash": "sha256-SuockPZgd2bfjWGmdT8AUBTnBZWvxdA+b8Ss98lNC6c=",
|
||||
"owner": "CachyOS",
|
||||
"repo": "kernel-patches",
|
||||
"rev": "5f061ab9733ad15eccf6b9995e9d56f572e67266",
|
||||
"rev": "505aef2086e584ba683a5ac1cb8ed8252fea2cfd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -37,11 +59,11 @@
|
|||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769432988,
|
||||
"narHash": "sha256-q4arZjXnLiuMnLzO972lrXIGdzyGb4DGaIt69CcCYdE=",
|
||||
"lastModified": 1771508520,
|
||||
"narHash": "sha256-srt94sUlkaGEJHQg7k6gVrBF1QZcHUY/VBESjCgZmKI=",
|
||||
"owner": "catppuccin",
|
||||
"repo": "nix",
|
||||
"rev": "d7a8632c0d8d144478aac1a8c8d5083b770cbb03",
|
||||
"rev": "ec35c21e843e4748e60822cd5543983eb61dc87a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -53,11 +75,11 @@
|
|||
"catppuccin-userstyles": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1769478525,
|
||||
"narHash": "sha256-V/5/yrwKJQldrzMW/lo42oOsceEcXFfsaFD1fHqeaGY=",
|
||||
"lastModified": 1771459037,
|
||||
"narHash": "sha256-QjS/R1ADaWMuRTOR+W8Ppx/HgGlUlXWjbt3iAkd5vSs=",
|
||||
"owner": "catppuccin",
|
||||
"repo": "userstyles",
|
||||
"rev": "72d08a0e24318741866741d38148aea50b4083e5",
|
||||
"rev": "9a0dd8c2d0dd87f2962be310ad882762e4ec7074",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -90,13 +112,40 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"cppnix": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_4",
|
||||
"flake-parts": "flake-parts_4",
|
||||
"git-hooks-nix": "git-hooks-nix",
|
||||
"nixpkgs": [
|
||||
"nixbsd",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-23-11": "nixpkgs-23-11",
|
||||
"nixpkgs-regression": "nixpkgs-regression"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1767672747,
|
||||
"narHash": "sha256-MqjbAkIYgJge5QSjx2b7hivVHkAVWuquN90HV789E1M=",
|
||||
"owner": "rhelmot",
|
||||
"repo": "nix",
|
||||
"rev": "595d3e984f91237a0ecef84567b461c26a9bf8a9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rhelmot",
|
||||
"ref": "freebsd",
|
||||
"repo": "nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1769287525,
|
||||
"narHash": "sha256-gABuYA6BzoRMLuPaeO5p7SLrpd4qExgkwEmYaYQY4bM=",
|
||||
"lastModified": 1771121070,
|
||||
"narHash": "sha256-aIlv7FRXF9q70DNJPI237dEDAznSKaXmL5lfK/Id/bI=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "0314e365877a85c9e5758f9ea77a9972afbb4c21",
|
||||
"rev": "a2812c19f1ed2e5ed5ce2ef7109798b575c180e1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -105,18 +154,38 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"firefox-addons": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771494902,
|
||||
"narHash": "sha256-G2yfLhPTuW4nSQCWdXzqknm9uop7OR+zQuoGll5rxLA=",
|
||||
"owner": "rycee",
|
||||
"repo": "nur-expressions",
|
||||
"rev": "07b71eb895d1f977c763899b985ee4980412dc57",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rycee",
|
||||
"repo": "nur-expressions",
|
||||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1767039857,
|
||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||
"owner": "NixOS",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
@ -137,6 +206,52 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_3": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1767039857,
|
||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||
"owner": "NixOS",
|
||||
"repo": "flake-compat",
|
||||
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_4": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1733328505,
|
||||
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_5": {
|
||||
"locked": {
|
||||
"lastModified": 1733328505,
|
||||
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
|
||||
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
|
||||
"revCount": 69,
|
||||
"type": "tarball",
|
||||
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.1.0/01948eb7-9cba-704f-bbf3-3fa956735b52/source.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
|
|
@ -181,11 +296,11 @@
|
|||
"nixpkgs-lib": "nixpkgs-lib_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1768135262,
|
||||
"narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=",
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -197,16 +312,17 @@
|
|||
"flake-parts_4": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixvim",
|
||||
"nixbsd",
|
||||
"cppnix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1768135262,
|
||||
"narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=",
|
||||
"lastModified": 1733312601,
|
||||
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac",
|
||||
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -216,6 +332,27 @@
|
|||
}
|
||||
},
|
||||
"flake-parts_5": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_6": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"steam-config-nix",
|
||||
|
|
@ -254,7 +391,64 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"git-hooks-nix": {
|
||||
"inputs": {
|
||||
"flake-compat": [
|
||||
"nixbsd",
|
||||
"cppnix"
|
||||
],
|
||||
"gitignore": [
|
||||
"nixbsd",
|
||||
"cppnix"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixbsd",
|
||||
"cppnix",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": [
|
||||
"nixbsd",
|
||||
"cppnix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734279981,
|
||||
"narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"arkenfox",
|
||||
"pre-commit",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"lanzaboote",
|
||||
|
|
@ -283,11 +477,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769638001,
|
||||
"narHash": "sha256-hGwdJ/+oo+IRo2TiWV/V8BWWptQihcdFV/olTONaHqg=",
|
||||
"lastModified": 1771531206,
|
||||
"narHash": "sha256-1R3Wx6KUkMb4x4E5UOhW9p6rqiexzSGGWxZqSHqW5n0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "bd9f031efc634be4b80c5090b9171cc3a9f8e49c",
|
||||
"rev": "91be7cce763fa4022c7cf025a71b0c366d1b6e77",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -372,15 +566,15 @@
|
|||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"pre-commit": "pre-commit",
|
||||
"pre-commit": "pre-commit_2",
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769417433,
|
||||
"narHash": "sha256-0WZ7I/N9InaBHL96/qdiJxg8mqFW3vRla8Z062JmQFE=",
|
||||
"lastModified": 1771492583,
|
||||
"narHash": "sha256-nQzvnU4BGu8dA6BsPPCqmVcab/3ebVmHtX3ZWbW3Hxc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "lanzaboote",
|
||||
"rev": "1902463415745b992dbaf301b2a35a1277be1584",
|
||||
"rev": "5e9380994665ef66c87ab8e22c913ff837174ce4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -413,11 +607,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769469790,
|
||||
"narHash": "sha256-VJI4KvK2AWtjPdNqanQ43MUydnU9qwN+HTDXrAtS2bI=",
|
||||
"lastModified": 1769804089,
|
||||
"narHash": "sha256-Wkot1j0cTx64xxjmLXzPubTckaZBSUJFhESEdOzPYas=",
|
||||
"owner": "utensils",
|
||||
"repo": "mcp-nixos",
|
||||
"rev": "af7b82497af2229893d0a5e4edaad4165f45eec7",
|
||||
"rev": "37a691ea4ea9c8bdcccfe174c6127847b8213fd3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -426,6 +620,27 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"mini-tmpfiles": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixbsd",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1742754557,
|
||||
"narHash": "sha256-nGxgiNhA94eSl8jcQwCboJ5Ed132z8yrFdOoT+rf8bE=",
|
||||
"owner": "nixos-bsd",
|
||||
"repo": "mini-tmpfiles",
|
||||
"rev": "534ee577692c7092fdcd035f89bc29b663c6f9ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos-bsd",
|
||||
"repo": "mini-tmpfiles",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"mkdocs-catppuccin": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
|
|
@ -450,11 +665,11 @@
|
|||
"rust-overlay": "rust-overlay_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769577126,
|
||||
"narHash": "sha256-v9vz9Rj4MGwPuhGELdvpRKl2HH+xvkgat6VwL0L86Fg=",
|
||||
"lastModified": 1771305475,
|
||||
"narHash": "sha256-lqweVTwHhYc+9T33cysp38gVwxaibGJHriOPZXWyhCY=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "f30db163b5748e8cf95c05aba77d0d3736f40543",
|
||||
"rev": "a2a52911757cb3b497db9407592f9b4c439571ea",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -472,11 +687,11 @@
|
|||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1766319780,
|
||||
"narHash": "sha256-Uh5180wjvBtSgtJ9zccZ7hu7bd7nvrnb6ff0nDwT2Rw=",
|
||||
"lastModified": 1770308099,
|
||||
"narHash": "sha256-VxuIePns4c+qpsHpLXW0CwovpKUx1xnvVIUuJwPO6fQ=",
|
||||
"owner": "Naxdy",
|
||||
"repo": "nix-bwrapper",
|
||||
"rev": "3b0d58d4d3e8da89147369d803926998798443e4",
|
||||
"rev": "1248b52f2bd4fe5690c1a36836a1798be21d953b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -489,16 +704,16 @@
|
|||
"inputs": {
|
||||
"cachyos-kernel": "cachyos-kernel",
|
||||
"cachyos-kernel-patches": "cachyos-kernel-patches",
|
||||
"flake-compat": "flake-compat_2",
|
||||
"flake-compat": "flake-compat_3",
|
||||
"flake-parts": "flake-parts_3",
|
||||
"nixpkgs": "nixpkgs_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769623217,
|
||||
"narHash": "sha256-GHpbWLiez3G54o9czW9zc4uy4h0/nMK3/ahMYmILqkY=",
|
||||
"lastModified": 1771525883,
|
||||
"narHash": "sha256-XqDuaRbxLGno5HcWRE5lQrgMBeXXs6ncGq+R6eCvsq8=",
|
||||
"owner": "xddxdd",
|
||||
"repo": "nix-cachyos-kernel",
|
||||
"rev": "03f574805ffe01b47e7fa93c7128d678b2037729",
|
||||
"rev": "15fb6039dd248d478a8f3f7f6c067b206da2bf54",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -507,19 +722,58 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixflix": {
|
||||
"nix-flatpak": {
|
||||
"locked": {
|
||||
"lastModified": 1768656715,
|
||||
"narHash": "sha256-Sbh037scxKFm7xL0ahgSCw+X2/5ZKeOwI2clqrYr9j4=",
|
||||
"owner": "gmodena",
|
||||
"repo": "nix-flatpak",
|
||||
"rev": "123fe29340a5b8671367055b75a6e7c320d6f89a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "gmodena",
|
||||
"repo": "nix-flatpak",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixbsd": {
|
||||
"inputs": {
|
||||
"mkdocs-catppuccin": "mkdocs-catppuccin",
|
||||
"cppnix": "cppnix",
|
||||
"flake-compat": "flake-compat_5",
|
||||
"mini-tmpfiles": "mini-tmpfiles",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769570521,
|
||||
"narHash": "sha256-o4crX1S+jsfytfy0liMr1NSnnVDdIOGoW3UTZXJG5PI=",
|
||||
"lastModified": 1768417153,
|
||||
"narHash": "sha256-2Vu3Yocs45HGVEYokRvN3DdBtaft37H4Z6rw4rAQ1gk=",
|
||||
"owner": "nixos-bsd",
|
||||
"repo": "nixbsd",
|
||||
"rev": "e393e147e3c30f6424c2a32c5362241c004b5156",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos-bsd",
|
||||
"repo": "nixbsd",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixflix": {
|
||||
"inputs": {
|
||||
"mkdocs-catppuccin": "mkdocs-catppuccin",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"treefmt-nix": "treefmt-nix_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771514873,
|
||||
"narHash": "sha256-sEAorIUS2IA1VG4mUVYWi+6LEnYmmn1f+3h6sNOqhso=",
|
||||
"owner": "kiriwalawren",
|
||||
"repo": "nixflix",
|
||||
"rev": "8037889b0be0275d1a96a4cc0a1d4aa878e2c82e",
|
||||
"rev": "078f61c04340c0365fd5a6772e08cd432d1123a3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -530,11 +784,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1769018530,
|
||||
"narHash": "sha256-MJ27Cy2NtBEV5tsK+YraYr2g851f3Fl1LpNHDzDX15c=",
|
||||
"lastModified": 1770197578,
|
||||
"narHash": "sha256-AYqlWrX09+HvGs8zM6ebZ1pwUqjkfpnv8mewYwAo+iM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "88d3861acdd3d2f0e361767018218e51810df8a1",
|
||||
"rev": "00c21e4c93d963c50d4c0c89bfa84ed6e0694df2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -544,6 +798,22 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-23-11": {
|
||||
"locked": {
|
||||
"lastModified": 1717159533,
|
||||
"narHash": "sha256-oamiKNfr2MS6yH64rUn99mIZjc45nGJlj9eGth/3Xuw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1765674936,
|
||||
|
|
@ -561,11 +831,11 @@
|
|||
},
|
||||
"nixpkgs-lib_2": {
|
||||
"locked": {
|
||||
"lastModified": 1765674936,
|
||||
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
|
||||
"lastModified": 1769909678,
|
||||
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
|
||||
"rev": "72716169fe93074c333e8d0173151350670b824c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -574,13 +844,29 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"nixpkgs-regression": {
|
||||
"locked": {
|
||||
"lastModified": 1758035966,
|
||||
"narHash": "sha256-qqIJ3yxPiB0ZQTT9//nFGQYn8X/PBoJbofA7hRKZnmE=",
|
||||
"lastModified": 1643052045,
|
||||
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8d4ddb19d03c65a36ad8d189d001dc32ffb0306b",
|
||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1767892417,
|
||||
"narHash": "sha256-dhhvQY67aboBk8b0/u0XB6vwHdgbROZT3fJAjyNh5Ww=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -592,11 +878,11 @@
|
|||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1754340878,
|
||||
"narHash": "sha256-lgmUyVQL9tSnvvIvBp7x1euhkkCho7n3TMzgjdvgPoU=",
|
||||
"lastModified": 1770107345,
|
||||
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cab778239e705082fe97bb4990e0d24c50924c04",
|
||||
"rev": "4533d9293756b63904b7238acb84ac8fe4c8c2c4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -608,11 +894,11 @@
|
|||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1769607364,
|
||||
"narHash": "sha256-bJIFB86xsMAJb0iEwb9p746T1XoslRAxbqMxBz7tjbo=",
|
||||
"lastModified": 1771482645,
|
||||
"narHash": "sha256-MpAKyXfJRDTgRU33Hja+G+3h9ywLAJJNRq4Pjbb4dQs=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "69459b3b3ea735e9933e1e367db3e68334cce3fe",
|
||||
"rev": "724cf38d99ba81fbb4a347081db93e2e3a9bc2ae",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -624,11 +910,11 @@
|
|||
},
|
||||
"nixpkgs_5": {
|
||||
"locked": {
|
||||
"lastModified": 1769461804,
|
||||
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
|
||||
"lastModified": 1771369470,
|
||||
"narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
|
||||
"rev": "0182a361324364ae3f436a63005877674cf45efb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -639,18 +925,18 @@
|
|||
},
|
||||
"nixvim": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts_4",
|
||||
"flake-parts": "flake-parts_5",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769644746,
|
||||
"narHash": "sha256-1X9o0GjCzku03magX4pM+1OZXA0aUTN7KvEReZ9t3OU=",
|
||||
"lastModified": 1771135771,
|
||||
"narHash": "sha256-wyvBIhDuyCRyjB3yPg77qoyxrlgQtBR1rVW3c9knV3E=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixvim",
|
||||
"rev": "3c27e1b35ca0fee6a89bfc20840654361ffe888d",
|
||||
"rev": "ed0424f0b08d303a7348f52f7850ad1b2704f9ba",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -666,11 +952,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769684048,
|
||||
"narHash": "sha256-KoMHkgsxan9c6JwTuuKSAQBg947zTs+GdjlH9hquccM=",
|
||||
"lastModified": 1771554771,
|
||||
"narHash": "sha256-atFYM8h8fgnXW/i/zM3yZnhsbVxlsIQ6eq/FcC6uZ6k=",
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia-shell",
|
||||
"rev": "7bf3dad98949c4895f15cdc4a7412b52e7d689ea",
|
||||
"rev": "8eef8ef71d64a7ad0144eb79221cdfcc568848cf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -686,11 +972,11 @@
|
|||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1758662783,
|
||||
"narHash": "sha256-igrxT+/MnmcftPOHEb+XDwAMq3Xg1Xy7kVYQaHhPlAg=",
|
||||
"lastModified": 1768249818,
|
||||
"narHash": "sha256-ANfn5OqIxq3HONPIXZ6zuI5sLzX1sS+2qcf/Pa0kQEc=",
|
||||
"owner": "NuschtOS",
|
||||
"repo": "search",
|
||||
"rev": "7d4c0fc4ffe3bd64e5630417162e9e04e64b27a4",
|
||||
"rev": "b6f77b88e9009bfde28e2130e218e5123dc66796",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -706,11 +992,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1766754166,
|
||||
"narHash": "sha256-anLh9N8KLqssOMd+xooagd/kLhoU4BChMfEToWmntCg=",
|
||||
"lastModified": 1771442093,
|
||||
"narHash": "sha256-DWRdWWS1luEuWgd0pYydmp97MdvfVGdsI8gnWfygNFg=",
|
||||
"owner": "AodhanHayter",
|
||||
"repo": "opencode-flake",
|
||||
"rev": "57574d4c2d550b24487cb810e2cfcb7c259b0357",
|
||||
"rev": "049b5b433ac88f05453d23a67a6d7ac8f62ea0b1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -721,19 +1007,45 @@
|
|||
},
|
||||
"pre-commit": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-compat": [
|
||||
"arkenfox",
|
||||
"flake-compat"
|
||||
],
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"arkenfox",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769939035,
|
||||
"narHash": "sha256-Fok2AmefgVA0+eprw2NDwqKkPGEI5wvR+twiZagBvrg=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "a8ca480175326551d6c4121498316261cbb5b260",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit_2": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_2",
|
||||
"gitignore": "gitignore_2",
|
||||
"nixpkgs": [
|
||||
"lanzaboote",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769069492,
|
||||
"narHash": "sha256-Efs3VUPelRduf3PpfPP2ovEB4CXT7vHf8W+xc49RL/U=",
|
||||
"lastModified": 1770726378,
|
||||
"narHash": "sha256-kck+vIbGOaM/dHea7aTBxdFYpeUl/jHOy5W3eyRvVx8=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "a1ef738813b15cf8ec759bdff5761b027e3e1d23",
|
||||
"rev": "5eaaedde414f6eb1aea8b8525c466dc37bba95ae",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -750,11 +1062,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769582933,
|
||||
"narHash": "sha256-MUzapTJuDJjfeOMlC9V1aesAX9WjFNUvjkyMCBHIA7E=",
|
||||
"lastModified": 1771507368,
|
||||
"narHash": "sha256-Q7cDybjd7GjYsN9SHd/fBSNdgieM5bX23gErJ9QE5xc=",
|
||||
"owner": "PrismLauncher",
|
||||
"repo": "PrismLauncher",
|
||||
"rev": "70cbbf5b07460524a14e661c1242cc51742e0937",
|
||||
"rev": "eac55d849c7ab44a3310a9c5c822a850331c3160",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -765,9 +1077,11 @@
|
|||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"arkenfox": "arkenfox",
|
||||
"catppuccin": "catppuccin",
|
||||
"catppuccin-userstyles": "catppuccin-userstyles",
|
||||
"cosmic-manager": "cosmic-manager",
|
||||
"firefox-addons": "firefox-addons",
|
||||
"home-manager": "home-manager",
|
||||
"impermanence": "impermanence",
|
||||
"lanzaboote": "lanzaboote",
|
||||
|
|
@ -775,6 +1089,8 @@
|
|||
"niri": "niri",
|
||||
"nix-bwrapper": "nix-bwrapper",
|
||||
"nix-cachyos-kernel": "nix-cachyos-kernel",
|
||||
"nix-flatpak": "nix-flatpak",
|
||||
"nixbsd": "nixbsd",
|
||||
"nixflix": "nixflix",
|
||||
"nixpkgs": "nixpkgs_5",
|
||||
"nixvim": "nixvim",
|
||||
|
|
@ -793,11 +1109,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769309768,
|
||||
"narHash": "sha256-AbOIlNO+JoqRJkK1VrnDXhxuX6CrdtIu2hSuy4pxi3g=",
|
||||
"lastModified": 1771125043,
|
||||
"narHash": "sha256-ldf/s49n6rOAxl7pYLJGGS1N/assoHkCOWdEdLyNZkc=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "140c9dc582cb73ada2d63a2180524fcaa744fad5",
|
||||
"rev": "4912f951a26dc8142b176be2c2ad834319dc06e8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -834,11 +1150,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769469829,
|
||||
"narHash": "sha256-wFcr32ZqspCxk4+FvIxIL0AZktRs6DuF8oOsLt59YBU=",
|
||||
"lastModified": 1771524872,
|
||||
"narHash": "sha256-eksVUcUsfS9mQx4D9DrYu88u9w70bAf+n6KmTDuIGEE=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "c5eebd4eb2e3372fe12a8d70a248a6ee9dd02eff",
|
||||
"rev": "e85540ffe97322dc1fea14dd11cdc2f59d540ac7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -849,18 +1165,18 @@
|
|||
},
|
||||
"steam-config-nix": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts_5",
|
||||
"flake-parts": "flake-parts_6",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1768615900,
|
||||
"narHash": "sha256-5Xfic5IZvg92mcW0sq+kFOh1PWgH7DO5WkxPYsDFDcY=",
|
||||
"lastModified": 1770296756,
|
||||
"narHash": "sha256-3jBIUXJu+Pc2MPu1KaHqhTS1z6KospVbDlBPvggATqs=",
|
||||
"owner": "different-name",
|
||||
"repo": "steam-config-nix",
|
||||
"rev": "083054c75cda3d5de25d6fc61aa3e779563c57f8",
|
||||
"rev": "e409b3bac9412513ff95fe293eb6ad42f985c60b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -919,11 +1235,32 @@
|
|||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1758728421,
|
||||
"narHash": "sha256-ySNJ008muQAds2JemiyrWYbwbG+V7S5wg3ZVKGHSFu8=",
|
||||
"lastModified": 1770228511,
|
||||
"narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "5eda4ee8121f97b218f7cc73f5172098d458f1d1",
|
||||
"rev": "337a4fe074be1042a35086f15481d763b8ddc0e7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixflix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1770228511,
|
||||
"narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "337a4fe074be1042a35086f15481d763b8ddc0e7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
54
flake.nix
54
flake.nix
|
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
description = "Modular NixOS Configuration with Hyprland";
|
||||
|
||||
nixConfig = {
|
||||
extra-substituters = [ "https://attic.mildlyfunctional.gay/nixbsd" ];
|
||||
extra-trusted-public-keys = [ "nixbsd:gwcQlsUONBLrrGCOdEboIAeFq9eLaDqfhfXmHZs1mgc=" ];
|
||||
};
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||
|
||||
|
|
@ -85,6 +90,23 @@
|
|||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.home-manager.follows = "home-manager";
|
||||
};
|
||||
|
||||
nix-flatpak.url = "github:gmodena/nix-flatpak";
|
||||
|
||||
arkenfox = {
|
||||
url = "github:dwarfmaster/arkenfox-nixos";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
firefox-addons = {
|
||||
url = "gitlab:rycee/nur-expressions";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
nixbsd = {
|
||||
url = "github:nixos-bsd/nixbsd";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
|
|
@ -97,6 +119,9 @@
|
|||
niri,
|
||||
cosmic-manager,
|
||||
nixflix,
|
||||
arkenfox,
|
||||
firefox-addons,
|
||||
nixbsd,
|
||||
...
|
||||
}@inputs:
|
||||
{
|
||||
|
|
@ -122,6 +147,24 @@
|
|||
default = import ./modules/home-manager;
|
||||
};
|
||||
|
||||
nixosConfigurations.nixbsd = nixbsd.lib.nixbsdSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
./hosts/nixbsd/configuration.nix
|
||||
];
|
||||
};
|
||||
|
||||
nixosConfigurations.nixbsd-vm = nixbsd.lib.nixbsdSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
./hosts/nixbsd/configuration.nix
|
||||
({ config, ... }: {
|
||||
# Enable VM variant
|
||||
# This is already in configuration.nix but we can make it explicit here if we want.
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
specialArgs = { inherit inputs; };
|
||||
|
|
@ -133,10 +176,14 @@
|
|||
home-manager.nixosModules.home-manager
|
||||
inputs.catppuccin.nixosModules.catppuccin
|
||||
inputs.nixvim.nixosModules.nixvim
|
||||
inputs.nix-flatpak.nixosModules.nix-flatpak
|
||||
{
|
||||
home-manager = {
|
||||
extraSpecialArgs = { inherit inputs; };
|
||||
sharedModules = [ inputs.cosmic-manager.homeManagerModules.cosmic-manager ];
|
||||
sharedModules = [
|
||||
inputs.cosmic-manager.homeManagerModules.cosmic-manager
|
||||
inputs.arkenfox.homeManagerModules.arkenfox
|
||||
];
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
backupFileExtension = "backup";
|
||||
|
|
@ -161,7 +208,10 @@
|
|||
{
|
||||
home-manager = {
|
||||
extraSpecialArgs = { inherit inputs; };
|
||||
sharedModules = [ inputs.cosmic-manager.homeManagerModules.cosmic-manager ];
|
||||
sharedModules = [
|
||||
inputs.cosmic-manager.homeManagerModules.cosmic-manager
|
||||
inputs.arkenfox.homeManagerModules.arkenfox
|
||||
];
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
backupFileExtension = "backup";
|
||||
|
|
|
|||
47
hosts/nixbsd/configuration.nix
Normal file
47
hosts/nixbsd/configuration.nix
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
nixpkgs.hostPlatform = "x86_64-freebsd";
|
||||
|
||||
# NixBSD doesn't have systemd, it uses FreeBSD's init or similar.
|
||||
# The NixBSD modules handle the specific FreeBSD configuration.
|
||||
|
||||
networking.hostName = "nixbsd";
|
||||
|
||||
# Default user configuration
|
||||
users.users.ashie = {
|
||||
isNormalUser = true;
|
||||
description = "Ashie";
|
||||
extraGroups = [ "wheel" ];
|
||||
initialPassword = "nixbsd";
|
||||
};
|
||||
|
||||
# SSH service for access
|
||||
services.sshd.enable = true;
|
||||
|
||||
# FreeBSD loader configuration
|
||||
boot.loader.stand-freebsd.enable = true;
|
||||
|
||||
# File system layout
|
||||
fileSystems."/" = {
|
||||
device = "/dev/gpt/nixos";
|
||||
fsType = "ufs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/msdosfs/ESP";
|
||||
fsType = "msdosfs";
|
||||
};
|
||||
|
||||
# VM variant for running in QEMU
|
||||
virtualisation.vmVariant = {
|
||||
virtualisation = {
|
||||
memorySize = 2048; # 2GB RAM
|
||||
cores = 2;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -6,36 +6,6 @@
|
|||
...
|
||||
}:
|
||||
{
|
||||
# Noctalia shell
|
||||
# Noctalia shell
|
||||
environment.systemPackages = with pkgs; [
|
||||
inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default
|
||||
ydotool
|
||||
];
|
||||
|
||||
environment.etc."glfw".source = "${pkgs.glfw}/lib";
|
||||
|
||||
boot.kernelModules = [
|
||||
"uinput"
|
||||
];
|
||||
users.groups.uinput = { };
|
||||
users.users.ashie.extraGroups = [ "uinput" ];
|
||||
|
||||
services.udev.extraRules = ''
|
||||
KERNEL=="uinput", GROUP="uinput", MODE="0660", OPTIONS+="static_node=uinput"
|
||||
'';
|
||||
|
||||
# FORCE Root Filesystem to satisfy assertions
|
||||
fileSystems."/" = lib.mkForce {
|
||||
device = "none";
|
||||
fsType = "tmpfs";
|
||||
options = [
|
||||
"defaults"
|
||||
"size=16G"
|
||||
"mode=755"
|
||||
];
|
||||
};
|
||||
|
||||
imports = [
|
||||
./default.nix # Host-specific configuration
|
||||
./hardware-configuration.nix
|
||||
|
|
@ -46,99 +16,43 @@
|
|||
./system/packages.nix # Package list
|
||||
./system/users.nix # User accounts
|
||||
./system/greetd.nix # Display manager
|
||||
../../modules/nixos/cosmic.nix # Cosmic Desktop
|
||||
./system/kernel.nix # CachyOS kernel
|
||||
./system/locate.nix # mlocate
|
||||
./system/secrets.nix # SOPS secrets
|
||||
./system/compatibility.nix # Compatibility layers (nix-ld)
|
||||
./system/game-drive.nix
|
||||
|
||||
#./system/authelia.nix # SSO/2FA
|
||||
../../modules/nixos/media.nix # Arr Stack
|
||||
../../modules/nixos/steam-gamemode.nix # Steam GameMode Session
|
||||
../../modules/nixos/redlib.nix # Redlib private frontend
|
||||
./system/authelia.nix # SSO/2FA
|
||||
|
||||
# Modularized configs
|
||||
./system/noctalia.nix
|
||||
./system/filesystems.nix
|
||||
./system/nix-settings.nix
|
||||
./system/locale.nix
|
||||
];
|
||||
|
||||
nixpkgs.config.allowUnfreePredicate =
|
||||
pkg:
|
||||
builtins.elem (lib.getName pkg) [
|
||||
"steam"
|
||||
"steam-original"
|
||||
"steam-run"
|
||||
"spotify"
|
||||
"antigravity"
|
||||
"vscode-extension-bmewburn-vscode-intelephense-client"
|
||||
"claude-code"
|
||||
"steam-unwrapped"
|
||||
];
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
|
||||
# Enable Fish shell
|
||||
programs.fish.enable = true;
|
||||
|
||||
# Enable Gamemode
|
||||
programs.gamemode.enable = true;
|
||||
|
||||
# Disable command-not-found to prevent info leaks
|
||||
programs.command-not-found.enable = false;
|
||||
|
||||
# Git security exception for flakes
|
||||
programs.git = {
|
||||
enable = true;
|
||||
config.safe.directory = "/home/ashie/nixos";
|
||||
};
|
||||
|
||||
# Automatic security updates
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
allowReboot = false;
|
||||
dates = "04:00";
|
||||
flake = "/home/ashie/nixos#nixos";
|
||||
};
|
||||
|
||||
time.timeZone = "Europe/Berlin";
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
i18n.supportedLocales = [
|
||||
"en_US.UTF-8/UTF-8"
|
||||
"de_DE.UTF-8/UTF-8"
|
||||
];
|
||||
|
||||
nix.settings.experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
nix.settings.allowed-users = [ "ashie" ];
|
||||
nix.settings.sandbox = true;
|
||||
|
||||
# Automatic Garbage Collection
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
|
||||
# Binary caches for CachyOS kernel
|
||||
nix.settings.substituters = [
|
||||
"https://hyprland.cachix.org"
|
||||
"https://nix-community.cachix.org"
|
||||
"https://attic.xuyh0120.win/lantian"
|
||||
"https://cache.garnix.io"
|
||||
];
|
||||
nix.settings.trusted-public-keys = [
|
||||
"cache.cachyos.org-1:j9qLlx+z0OYBtCqflh9v4I+5fsljqG5l2/C9t0yY18q="
|
||||
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||
"lantian:EeAUQ+W+6r7EtwnmYjeVwx5kOGEBpjlBfPlzGlTNvHc="
|
||||
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
|
||||
];
|
||||
|
||||
# Registry pinning for instant shell startups
|
||||
nix.registry.nixpkgs.flake = inputs.nixpkgs;
|
||||
nix.channel.enable = false; # We are using flakes
|
||||
|
||||
# Enable performance optimizations
|
||||
myModules.performance.enable = true;
|
||||
|
||||
# Enable modularized components
|
||||
myModules.desktop.cosmic.enable = true;
|
||||
myModules.media.enable = true;
|
||||
myModules.gaming.gamemode.enable = true;
|
||||
myModules.redlib.enable = true;
|
||||
|
||||
# Enable sandboxed applications
|
||||
myModules.steamSandboxed.enable = true;
|
||||
myModules.lutrisSandboxed.enable = true;
|
||||
myModules.firefoxSandboxed.enable = true;
|
||||
myModules.braveSandboxed.enable = true;
|
||||
myModules.azaharSandboxed.enable = true;
|
||||
myModules.faugusSandboxed.enable = true;
|
||||
myModules.citronSandboxed.enable = true;
|
||||
myModules.ryubingSandboxed.enable = true;
|
||||
myModules.spotifySandboxed.enable = true;
|
||||
myModules.vesktopSandboxed.enable = true;
|
||||
myModules.tutanotaSandboxed.enable = true;
|
||||
myModules.prismlauncherSandboxed.enable = true;
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,46 +29,36 @@
|
|||
zramAlgorithm = "zstd";
|
||||
};
|
||||
|
||||
# Hardened Malloc (Scudo)
|
||||
hardenedMalloc = {
|
||||
enable = false;
|
||||
};
|
||||
|
||||
# Secure Boot (Lanzaboote)
|
||||
# 1. sudo sbctl create-keys
|
||||
# 2. sudo sbctl enroll-keys -m
|
||||
# 3. Enable this option
|
||||
# 4. Reboot
|
||||
secureBoot = {
|
||||
enable = false; # Disabled for initial install (enable after running sbctl create-keys)
|
||||
enable = false; # switched to grub, needs update
|
||||
pkiBundle = "/var/lib/sbctl";
|
||||
};
|
||||
|
||||
# DNS-over-TLS with DNSSEC
|
||||
dnsOverTls = {
|
||||
enable = true;
|
||||
dnssec = true;
|
||||
};
|
||||
|
||||
# Cloudflare-only firewall rules
|
||||
cloudflareFirewall = {
|
||||
enable = true;
|
||||
allowLocalTraffic = true;
|
||||
enablePodmanWorkaround = true;
|
||||
publicPorts = [
|
||||
# Ports that are public
|
||||
443
|
||||
80
|
||||
];
|
||||
restrictedPorts = [ ];
|
||||
restrictedPorts = [ ]; # Ports that are Cloudflare only
|
||||
};
|
||||
|
||||
# Base Podman container runtime
|
||||
# Disabled here because system/podman.nix handles Podman + container definitions
|
||||
podman.enable = true;
|
||||
|
||||
# VPN-isolated browser containers
|
||||
browserVpn = {
|
||||
enable = true;
|
||||
enable = false;
|
||||
browsers = [
|
||||
"firefox"
|
||||
"tor-browser"
|
||||
|
|
@ -78,17 +68,14 @@
|
|||
];
|
||||
};
|
||||
|
||||
# Ollama System Service (Isolated)
|
||||
ollamaRocm = {
|
||||
enable = false; # Disabled temporarily to unblock install (namespace issues)
|
||||
};
|
||||
|
||||
# Open WebUI System Service (Isolated)
|
||||
openWebUI = {
|
||||
enable = true;
|
||||
enable = false;
|
||||
};
|
||||
|
||||
# SearXNG (Meta-Search Engine)
|
||||
searxng = {
|
||||
enable = true;
|
||||
port = 8888;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@
|
|||
./home/steam.nix
|
||||
./home/mangohud.nix
|
||||
./home/starship.nix
|
||||
./home/opencode.nix
|
||||
./home/fish.nix
|
||||
./home/git.nix
|
||||
./home/xdg.nix
|
||||
./home/fonts.nix
|
||||
];
|
||||
|
||||
home.packages = [
|
||||
|
|
@ -29,41 +34,6 @@
|
|||
pkgs.joplin-desktop
|
||||
pkgs.bemoji
|
||||
pkgs.wtype
|
||||
(pkgs.writeShellScriptBin "opencode" ''
|
||||
export OPENAI_BASE_URL="https://api.ashisgreat.xyz/v1"
|
||||
export OPENAI_API_KEY="$(cat ${config.sops.secrets.master_api_key.path})"
|
||||
export OPENCODE_DISABLE_DEFAULT_PLUGINS=true
|
||||
|
||||
# Ensure config directory exists
|
||||
mkdir -p $HOME/.config/opencode
|
||||
|
||||
# Force remove config.json if it is a symlink to ensure we can write to it
|
||||
if [ -L $HOME/.config/opencode/config.json ]; then
|
||||
rm -f $HOME/.config/opencode/config.json
|
||||
fi
|
||||
|
||||
# Validate permissions and force write correct config
|
||||
# We verify if we can write to it, if not (e.g. read-only file), we remove it
|
||||
if [ -f $HOME/.config/opencode/config.json ] && [ ! -w $HOME/.config/opencode/config.json ]; then
|
||||
rm -f $HOME/.config/opencode/config.json
|
||||
fi
|
||||
|
||||
# Always overwrite config.json to ensure correct settings
|
||||
cat > $HOME/.config/opencode/config.json <<EOF
|
||||
{
|
||||
"model": "openai/gpt-4o",
|
||||
"disabled_providers": ["opencode-anthropic-auth", "anthropic", "github"],
|
||||
"plugin": []
|
||||
}
|
||||
EOF
|
||||
|
||||
# Clear broken plugin from cache if it exists (one-time cleanup)
|
||||
if [ -d "$HOME/.cache/opencode/node_modules/opencode-anthropic-auth" ]; then
|
||||
rm -rf "$HOME/.cache/opencode"
|
||||
fi
|
||||
|
||||
exec ${inputs.opencode-flake.packages.${pkgs.stdenv.hostPlatform.system}.default}/bin/opencode "$@"
|
||||
'')
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = ../../secrets/secrets.yaml;
|
||||
|
|
@ -93,64 +63,10 @@
|
|||
};
|
||||
};
|
||||
|
||||
programs.fish = {
|
||||
enable = true;
|
||||
interactiveShellInit = ''
|
||||
set fish_greeting # Disable greeting
|
||||
hyfetch
|
||||
'';
|
||||
plugins = [
|
||||
{
|
||||
name = "grc";
|
||||
src = pkgs.fishPlugins.grc.src;
|
||||
}
|
||||
{
|
||||
name = "done";
|
||||
src = pkgs.fishPlugins.done.src;
|
||||
}
|
||||
{
|
||||
name = "sponge";
|
||||
src = pkgs.fishPlugins.sponge.src;
|
||||
}
|
||||
{
|
||||
name = "puffer";
|
||||
src = pkgs.fishPlugins.puffer.src;
|
||||
}
|
||||
{
|
||||
name = "fzf-fish";
|
||||
src = pkgs.fishPlugins.fzf-fish.src;
|
||||
}
|
||||
{
|
||||
name = "pisces";
|
||||
src = pkgs.fishPlugins.pisces.src;
|
||||
}
|
||||
];
|
||||
shellAliases = {
|
||||
btw = "echo i use hyprland btw";
|
||||
vi = "nvim";
|
||||
vim = "nvim";
|
||||
"67" = "nh os switch";
|
||||
};
|
||||
};
|
||||
|
||||
programs.bash = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
programs.git = {
|
||||
enable = true;
|
||||
settings.user.name = "ashisgreat22";
|
||||
settings.user.email = "dev@ashisgreat.xyz";
|
||||
};
|
||||
|
||||
programs.gh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
git_protocol = "ssh";
|
||||
editor = "nvim";
|
||||
};
|
||||
};
|
||||
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
nix-direnv.enable = true;
|
||||
|
|
@ -166,49 +82,65 @@
|
|||
};
|
||||
};
|
||||
|
||||
fonts.fontconfig = {
|
||||
programs.firefox = {
|
||||
enable = true;
|
||||
|
||||
defaultFonts = {
|
||||
serif = [ "ComicShannsMono Nerd Font" ];
|
||||
sansSerif = [ "ComicShannsMono Nerd Font" ];
|
||||
monospace = [ "ComicShannsMono Nerd Font Mono" ];
|
||||
emoji = [ "Noto Color Emoji" ];
|
||||
package = pkgs.firefox-esr; # Use standard package so HM can manage profiles/policies
|
||||
arkenfox = {
|
||||
enable = true;
|
||||
version = "140.0"; # Match ESR version
|
||||
};
|
||||
};
|
||||
|
||||
xdg.desktopEntries.youtube = {
|
||||
name = "YouTube";
|
||||
genericName = "Video Player";
|
||||
exec = "brave --profile-directory=YouTube --app=https://youtube.com";
|
||||
terminal = false;
|
||||
categories = [
|
||||
"Network"
|
||||
"Video"
|
||||
"AudioVideo"
|
||||
];
|
||||
icon = "youtube";
|
||||
};
|
||||
|
||||
xdg.mimeApps = {
|
||||
enable = true;
|
||||
defaultApplications = {
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" = [
|
||||
"onlyoffice-desktopeditors.desktop"
|
||||
profiles.ashie = {
|
||||
id = 0;
|
||||
extensions = with inputs.firefox-addons.legacyPackages.${pkgs.system}.firefox-addons; [
|
||||
ublock-origin
|
||||
bitwarden
|
||||
sponsorblock
|
||||
];
|
||||
"application/msword" = [ "onlyoffice-desktopeditors.desktop" ];
|
||||
"text/html" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"x-scheme-handler/http" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"x-scheme-handler/https" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"x-scheme-handler/about" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"x-scheme-handler/unknown" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/xhtml+xml" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-htm" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-html" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-shtml" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-xhtml" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-xht" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/pdf" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
search = {
|
||||
default = "AshisGreat";
|
||||
force = true;
|
||||
engines = {
|
||||
"AshisGreat" = {
|
||||
urls = [{
|
||||
template = "https://search.ashisgreat.xyz/search";
|
||||
params = [
|
||||
{ name = "q"; value = "{searchTerms}"; }
|
||||
];
|
||||
}];
|
||||
iconUpdateURL = "https://search.ashisgreat.xyz/favicon.ico";
|
||||
updateInterval = 24 * 60 * 60 * 1000; # every day
|
||||
definedAliases = [ "@ag" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
arkenfox = {
|
||||
enable = true;
|
||||
"0000".enable = true; # Top-level overrides
|
||||
"0100".enable = true; # Startup
|
||||
"0200".enable = true; # Geolocation
|
||||
"0300".enable = true; # Browser Features
|
||||
"0400".enable = true; # Safe Browsing
|
||||
"0600".enable = true; # Block Implicit Outbound
|
||||
"0700".enable = true; # DNS / DoH
|
||||
"0800".enable = true; # Search Bar / Forms / History
|
||||
"0900".enable = true; # Passwords
|
||||
"1000".enable = true; # Disk Cache / Antifingerprinting
|
||||
"1200".enable = true; # HTTPS
|
||||
"1600".enable = true; # Referers
|
||||
"1700".enable = true; # Containers
|
||||
"2000".enable = true; # Plugins / Media
|
||||
"2400".enable = true; # DOM
|
||||
"2600".enable = true; # Storage
|
||||
"2700".enable = true; # Enhanced Tracking Protection
|
||||
"2800".enable = true; # Shutdown & Sanitizing
|
||||
"4500".enable = true; # RFP (Resist Fingerprinting)
|
||||
"5000".enable = true; # Optional OPSEC
|
||||
"5500".enable = true; # Optional Hardening
|
||||
"6000".enable = true; # DON'T TOUCH
|
||||
"7000".enable = true; # DON'T TOUCH
|
||||
"8000".enable = true; # DON'T TOUCH
|
||||
"9000".enable = true; # DON'T TOUCH
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -224,4 +156,4 @@
|
|||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
42
hosts/nixos/home/fish.nix
Normal file
42
hosts/nixos/home/fish.nix
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
programs.fish = {
|
||||
enable = true;
|
||||
interactiveShellInit = ''
|
||||
set fish_greeting # Disable greeting
|
||||
hyfetch
|
||||
'';
|
||||
plugins = [
|
||||
{
|
||||
name = "grc";
|
||||
src = pkgs.fishPlugins.grc.src;
|
||||
}
|
||||
{
|
||||
name = "done";
|
||||
src = pkgs.fishPlugins.done.src;
|
||||
}
|
||||
{
|
||||
name = "sponge";
|
||||
src = pkgs.fishPlugins.sponge.src;
|
||||
}
|
||||
{
|
||||
name = "puffer";
|
||||
src = pkgs.fishPlugins.puffer.src;
|
||||
}
|
||||
{
|
||||
name = "fzf-fish";
|
||||
src = pkgs.fishPlugins.fzf-fish.src;
|
||||
}
|
||||
{
|
||||
name = "pisces";
|
||||
src = pkgs.fishPlugins.pisces.src;
|
||||
}
|
||||
];
|
||||
shellAliases = {
|
||||
btw = "echo i use hyprland btw";
|
||||
vi = "nvim";
|
||||
vim = "nvim";
|
||||
"67" = "nh os switch";
|
||||
};
|
||||
};
|
||||
}
|
||||
13
hosts/nixos/home/fonts.nix
Normal file
13
hosts/nixos/home/fonts.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ ... }:
|
||||
{
|
||||
fonts.fontconfig = {
|
||||
enable = true;
|
||||
|
||||
defaultFonts = {
|
||||
serif = [ "ComicShannsMono Nerd Font" ];
|
||||
sansSerif = [ "ComicShannsMono Nerd Font" ];
|
||||
monospace = [ "ComicShannsMono Nerd Font Mono" ];
|
||||
emoji = [ "Noto Color Emoji" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
16
hosts/nixos/home/git.nix
Normal file
16
hosts/nixos/home/git.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{ ... }:
|
||||
{
|
||||
programs.git = {
|
||||
enable = true;
|
||||
settings.user.name = "ashisgreat22";
|
||||
settings.user.email = "dev@ashisgreat.xyz";
|
||||
};
|
||||
|
||||
programs.gh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
git_protocol = "ssh";
|
||||
editor = "nvim";
|
||||
};
|
||||
};
|
||||
}
|
||||
45
hosts/nixos/home/opencode.nix
Normal file
45
hosts/nixos/home/opencode.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home.packages = [
|
||||
(pkgs.writeShellScriptBin "opencode" ''
|
||||
export OPENAI_BASE_URL="https://api.ashisgreat.xyz/v1"
|
||||
export OPENAI_API_KEY="$(cat ${config.sops.secrets.master_api_key.path})"
|
||||
export OPENCODE_DISABLE_DEFAULT_PLUGINS=true
|
||||
|
||||
# Ensure config directory exists
|
||||
mkdir -p $HOME/.config/opencode
|
||||
|
||||
# Force remove config.json if it is a symlink to ensure we can write to it
|
||||
if [ -L $HOME/.config/opencode/config.json ]; then
|
||||
rm -f $HOME/.config/opencode/config.json
|
||||
fi
|
||||
|
||||
# Validate permissions and force write correct config
|
||||
# We verify if we can write to it, if not (e.g. read-only file), we remove it
|
||||
if [ -f $HOME/.config/opencode/config.json ] && [ ! -w $HOME/.config/opencode/config.json ]; then
|
||||
rm -f $HOME/.config/opencode/config.json
|
||||
fi
|
||||
|
||||
# Always overwrite config.json to ensure correct settings
|
||||
cat > $HOME/.config/opencode/config.json <<EOF
|
||||
{
|
||||
"model": "openai/gpt-4o",
|
||||
"disabled_providers": ["opencode-anthropic-auth", "anthropic", "github"],
|
||||
"plugin": []
|
||||
}
|
||||
EOF
|
||||
|
||||
# Clear broken plugin from cache if it exists (one-time cleanup)
|
||||
if [ -d "$HOME/.cache/opencode/node_modules/opencode-anthropic-auth" ]; then
|
||||
rm -rf "$HOME/.cache/opencode"
|
||||
fi
|
||||
|
||||
exec ${inputs.opencode-flake.packages.${pkgs.stdenv.hostPlatform.system}.default}/bin/opencode "$@"
|
||||
'')
|
||||
];
|
||||
}
|
||||
50
hosts/nixos/home/xdg.nix
Normal file
50
hosts/nixos/home/xdg.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{ ... }:
|
||||
{
|
||||
xdg.desktopEntries.youtube = {
|
||||
name = "YouTube";
|
||||
genericName = "Video sharing platform";
|
||||
exec = "brave --profile-directory=YouTube --app=https://youtube.com";
|
||||
terminal = false;
|
||||
categories = [
|
||||
"Network"
|
||||
"Video"
|
||||
"AudioVideo"
|
||||
];
|
||||
icon = "youtube";
|
||||
};
|
||||
|
||||
xdg.desktopEntries.steam = {
|
||||
name = "Steam";
|
||||
genericName = "Game Store";
|
||||
exec = "steam %U";
|
||||
terminal = false;
|
||||
categories = [ "Game" ];
|
||||
icon = "steam";
|
||||
mimeType = [
|
||||
"x-scheme-handler/steam"
|
||||
"x-scheme-handler/steamlink"
|
||||
];
|
||||
};
|
||||
|
||||
xdg.mimeApps = {
|
||||
enable = true;
|
||||
defaultApplications = {
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" = [
|
||||
"onlyoffice-desktopeditors.desktop"
|
||||
];
|
||||
"application/msword" = [ "onlyoffice-desktopeditors.desktop" ];
|
||||
"text/html" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"x-scheme-handler/http" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"x-scheme-handler/https" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"x-scheme-handler/about" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"x-scheme-handler/unknown" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/xhtml+xml" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-htm" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-html" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-shtml" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-xhtml" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/x-extension-xht" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
"application/pdf" = [ "nix.bwrapper.firefox.desktop" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
{
|
||||
services.authelia.instances.main = {
|
||||
enable = false;
|
||||
enable = true;
|
||||
|
||||
# Secrets
|
||||
secrets = {
|
||||
jwtSecretFile = config.sops.secrets.authelia_jwt_secret.path;
|
||||
storageEncryptionKeyFile = config.sops.secrets.authelia_storage_encryption_key.path;
|
||||
|
|
@ -49,15 +48,19 @@
|
|||
domain = "auth.ashisgreat.xyz";
|
||||
policy = "bypass";
|
||||
}
|
||||
# Bypass for Jellyfin (handles its own auth)
|
||||
{
|
||||
domain = "jellyfin.ashisgreat.xyz";
|
||||
policy = "bypass";
|
||||
}
|
||||
# Protected services (2FA required)
|
||||
{
|
||||
domain = [
|
||||
"sonarr.ashisgreat.xyz"
|
||||
"radarr.ashisgreat.xyz"
|
||||
"prowlarr.ashisgreat.xyz"
|
||||
"jellyfin.ashisgreat.xyz" # Jellyfin can use its own auth, but wrapping it adds 2FA
|
||||
"torrent.ashisgreat.xyz"
|
||||
"jellyseer.ashisgreat.xyz" # Note: Typo in services.nix maintained here, check if corrected in Caddy
|
||||
"jellyseer.ashisgreat.xyz"
|
||||
];
|
||||
policy = "two_factor";
|
||||
}
|
||||
|
|
|
|||
13
hosts/nixos/system/filesystems.nix
Normal file
13
hosts/nixos/system/filesystems.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ lib, ... }:
|
||||
{
|
||||
# FORCE Root Filesystem to satisfy assertions
|
||||
fileSystems."/" = lib.mkForce {
|
||||
device = "none";
|
||||
fsType = "tmpfs";
|
||||
options = [
|
||||
"defaults"
|
||||
"size=16G"
|
||||
"mode=755"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
# Enable early KMS for the prompt
|
||||
boot.initrd.kernelModules = [ "amdgpu" ];
|
||||
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
|
||||
hardware.graphics = {
|
||||
enable = true;
|
||||
enable32Bit = true;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
"wireguard"
|
||||
"af_packet"
|
||||
"bridge"
|
||||
"xt_tcpudp"
|
||||
];
|
||||
|
||||
# =============================================================================
|
||||
|
|
|
|||
9
hosts/nixos/system/locale.nix
Normal file
9
hosts/nixos/system/locale.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{ ... }:
|
||||
{
|
||||
time.timeZone = "Europe/Berlin";
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
i18n.supportedLocales = [
|
||||
"en_US.UTF-8/UTF-8"
|
||||
"de_DE.UTF-8/UTF-8"
|
||||
];
|
||||
}
|
||||
|
|
@ -19,10 +19,13 @@
|
|||
Kind = "bridge";
|
||||
Name = "br0";
|
||||
};
|
||||
netdevs."br0".bridgeConfig = {
|
||||
STP = "no";
|
||||
};
|
||||
|
||||
links."10-eth" = {
|
||||
matchConfig.Name = "enp4s0";
|
||||
linkConfig.MACAddressPolicy = "random";
|
||||
linkConfig.MACAddressPolicy = "persistent";
|
||||
};
|
||||
|
||||
networks."10-eth" = {
|
||||
|
|
@ -34,24 +37,43 @@
|
|||
matchConfig.Name = "br0";
|
||||
networkConfig = {
|
||||
DHCP = "yes";
|
||||
# Ensure DNS/Gateway is accepted
|
||||
# Disable STP to prevent bridge topology re-calculations (fixes 15s delays)
|
||||
# STP = "no"; # Done in netdev
|
||||
IPv6PrivacyExtensions = "yes";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.enableIPv6 = false;
|
||||
|
||||
# Disable IPv6 via sysctl
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv6.conf.all.disable_ipv6" = 1;
|
||||
"net.ipv6.conf.default.disable_ipv6" = 1;
|
||||
"net.ipv6.conf.lo.disable_ipv6" = 1;
|
||||
};
|
||||
networking.enableIPv6 = true;
|
||||
|
||||
# Basic firewall settings
|
||||
networking.firewall.enable = true;
|
||||
networking.nftables.enable = true;
|
||||
networking.firewall.checkReversePath = false; # Required for container routing
|
||||
|
||||
# Container NAT (Restoring connectivity after removing VPN module)
|
||||
networking.nftables.tables."container-nat" = {
|
||||
family = "inet";
|
||||
content = ''
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority srcnat; policy accept;
|
||||
# Masquerade all container traffic going out via the bridge
|
||||
ip saddr 10.89.0.0/16 masquerade
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# Allow forwarding for containers (fixes DNS/Connectivity drops)
|
||||
networking.nftables.tables."container-filter" = {
|
||||
family = "inet";
|
||||
content = ''
|
||||
chain forward {
|
||||
type filter hook forward priority -100; policy accept;
|
||||
ip saddr 10.89.0.0/16 accept
|
||||
ip daddr 10.89.0.0/16 accept
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# Dynamic DNS for Cloudflare
|
||||
services.ddclient = {
|
||||
|
|
@ -80,4 +102,42 @@
|
|||
usev4 = "cmdv4";
|
||||
extraConfig = "cmdv4='${pkgs.curl}/bin/curl -s https://api.ipify.org'";
|
||||
};
|
||||
|
||||
# Make ddclient use a static user for UID-based routing
|
||||
users.users.ddclient = {
|
||||
isSystemUser = true;
|
||||
group = "ddclient";
|
||||
uid = 990;
|
||||
};
|
||||
users.groups.ddclient = {
|
||||
gid = 990;
|
||||
};
|
||||
|
||||
# Static Nginx User override removed - using dynamic detection in vpn-routing.nix
|
||||
|
||||
systemd.services.ddclient.serviceConfig = {
|
||||
DynamicUser = lib.mkForce false;
|
||||
User = "ddclient";
|
||||
Group = "ddclient";
|
||||
};
|
||||
|
||||
# Local Loopback for Hosted Services
|
||||
# Ensures the host can reach these domains even if VPN routing prevents public IP loopback
|
||||
networking.hosts = {
|
||||
"127.0.0.1" = [
|
||||
"api.ashisgreat.xyz"
|
||||
"search.ashisgreat.xyz"
|
||||
"chat.ashisgreat.xyz"
|
||||
"auth.ashisgreat.xyz"
|
||||
"stream.ashisgreat.xyz"
|
||||
"stream-api.ashisgreat.xyz"
|
||||
"sonarr.ashisgreat.xyz"
|
||||
"radarr.ashisgreat.xyz"
|
||||
"prowlarr.ashisgreat.xyz"
|
||||
"torrent.ashisgreat.xyz"
|
||||
"jellyfin.ashisgreat.xyz"
|
||||
"jellyseer.ashisgreat.xyz"
|
||||
"jellyseerr.ashisgreat.xyz"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
77
hosts/nixos/system/nix-settings.nix
Normal file
77
hosts/nixos/system/nix-settings.nix
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
antigravity = prev.antigravity.overrideAttrs (oldAttrs: rec {
|
||||
version = "1.18.3";
|
||||
src = prev.fetchurl {
|
||||
url = "https://edgedl.me.gvt1.com/edgedl/release2/j0qc3/antigravity/stable/1.18.3-4739469533380608/linux-x64/Antigravity.tar.gz";
|
||||
sha256 = "0f4n3i45gjr36hidpvibzn3p2jla2r7wg91ybmf2akafjn6f8zsc";
|
||||
};
|
||||
});
|
||||
})
|
||||
];
|
||||
|
||||
nixpkgs.config.allowUnfreePredicate =
|
||||
pkg:
|
||||
builtins.elem (lib.getName pkg) [
|
||||
"steam"
|
||||
"steam-original"
|
||||
"steam-run"
|
||||
"spotify"
|
||||
"antigravity"
|
||||
"vscode-extension-bmewburn-vscode-intelephense-client"
|
||||
"claude-code"
|
||||
"steam-unwrapped"
|
||||
];
|
||||
|
||||
# Disable command-not-found to prevent info leaks
|
||||
programs.command-not-found.enable = false;
|
||||
|
||||
# Git security exception for flakes
|
||||
programs.git = {
|
||||
enable = true;
|
||||
config.safe.directory = "/home/ashie/nixos";
|
||||
};
|
||||
|
||||
# Automatic Updates (System + Containers)
|
||||
myModules.autoUpdate.enable = true;
|
||||
|
||||
nix.settings.experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
nix.settings.allowed-users = [ "ashie" ];
|
||||
nix.settings.sandbox = true;
|
||||
|
||||
# Automatic Garbage Collection
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
|
||||
# Binary caches for CachyOS kernel
|
||||
nix.settings.substituters = [
|
||||
"https://hyprland.cachix.org"
|
||||
"https://nix-community.cachix.org"
|
||||
"https://attic.xuyh0120.win/lantian"
|
||||
"https://cache.garnix.io"
|
||||
];
|
||||
nix.settings.trusted-public-keys = [
|
||||
"cache.cachyos.org-1:j9qLlx+z0OYBtCqflh9v4I+5fsljqG5l2/C9t0yY18q="
|
||||
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||
"lantian:EeAUQ+W+6r7EtwnmYjeVwx5kOGEBpjlBfPlzGlTNvHc="
|
||||
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
|
||||
];
|
||||
|
||||
# Registry pinning for instant shell startups
|
||||
nix.registry.nixpkgs.flake = inputs.nixpkgs;
|
||||
nix.channel.enable = false; # We are using flakes
|
||||
}
|
||||
20
hosts/nixos/system/noctalia.nix
Normal file
20
hosts/nixos/system/noctalia.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{ pkgs, inputs, ... }:
|
||||
{
|
||||
# Noctalia shell
|
||||
environment.systemPackages = with pkgs; [
|
||||
inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default
|
||||
ydotool
|
||||
];
|
||||
|
||||
environment.etc."glfw".source = "${pkgs.glfw}/lib";
|
||||
|
||||
boot.kernelModules = [
|
||||
"uinput"
|
||||
];
|
||||
users.groups.uinput = { };
|
||||
users.users.ashie.extraGroups = [ "uinput" ];
|
||||
|
||||
services.udev.extraRules = ''
|
||||
KERNEL=="uinput", GROUP="uinput", MODE="0660", OPTIONS+="static_node=uinput"
|
||||
'';
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
git
|
||||
sbctl
|
||||
fuzzel
|
||||
# prismlauncher-sandboxed # Managed by Home Manager
|
||||
# prismlauncher-sandboxed # Managed by System Module
|
||||
polychromatic
|
||||
vscodium
|
||||
kdePackages.dolphin
|
||||
|
|
@ -58,22 +58,24 @@
|
|||
mangohud
|
||||
gamemode
|
||||
lact
|
||||
umu-launcher
|
||||
steam-run
|
||||
fastfetch
|
||||
hyfetch
|
||||
nautilus
|
||||
lutris-sandboxed
|
||||
steam-sandboxed
|
||||
azahar-sandboxed
|
||||
faugus-sandboxed
|
||||
citron-sandboxed
|
||||
ryubing-sandboxed
|
||||
# lutris-sandboxed # Added by module
|
||||
# steam-sandboxed # Added by module
|
||||
# azahar-sandboxed # Added by module
|
||||
# faugus-sandboxed # Added by module
|
||||
# citron-sandboxed # Added by module
|
||||
# ryubing-sandboxed # Added by module
|
||||
wireguard-tools
|
||||
jq
|
||||
grim
|
||||
vlc
|
||||
slurp
|
||||
wl-clipboard
|
||||
vesktop-sandboxed
|
||||
# vesktop-sandboxed # Added by module
|
||||
starship
|
||||
zip
|
||||
unzip
|
||||
|
|
@ -96,18 +98,18 @@
|
|||
stress-ng
|
||||
kdePackages.kleopatra
|
||||
kdePackages.ark
|
||||
easyeffects
|
||||
|
||||
dysk
|
||||
zstd
|
||||
podman
|
||||
spotify-sandboxed
|
||||
# spotify-sandboxed # Added by module
|
||||
jmtpfs
|
||||
glfw
|
||||
mlocate
|
||||
openssl
|
||||
nspr
|
||||
firefox-sandboxed
|
||||
tutanota-sandboxed
|
||||
# firefox-sandboxed # Added by module
|
||||
# tutanota-sandboxed # Added by module
|
||||
# brave-sandboxed # Imported via module, wrapper provided there
|
||||
eddie
|
||||
appimage-run
|
||||
|
|
@ -123,8 +125,14 @@
|
|||
protontricks
|
||||
file
|
||||
ffmpeg-full
|
||||
gsettings-desktop-schemas
|
||||
glib
|
||||
gtk3
|
||||
gtk4
|
||||
];
|
||||
|
||||
programs.dconf.enable = true;
|
||||
|
||||
environment.variables = {
|
||||
QT_QPA_PLATFORMTHEME = "qt6ct";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@
|
|||
sops.secrets.wireguard_dns = {
|
||||
owner = "ashie";
|
||||
};
|
||||
sops.secrets.wireguard6_dns = {
|
||||
owner = "ashie";
|
||||
};
|
||||
|
||||
sops.secrets.wireguard6_adresses = {
|
||||
owner = "ashie";
|
||||
};
|
||||
|
||||
sops.secrets.open_webui_env = {
|
||||
owner = "ashie";
|
||||
|
|
@ -46,7 +53,7 @@
|
|||
WIREGUARD_ENDPOINT_IP=${config.sops.placeholder.wireguard_endpoint_ip}
|
||||
WIREGUARD_ENDPOINT_PORT=${config.sops.placeholder.wireguard_endpoint_port}
|
||||
WIREGUARD_PRIVATE_KEY=${config.sops.placeholder.wireguard_private_key}
|
||||
WIREGUARD_ADDRESSES=${config.sops.placeholder.wireguard_addresses}
|
||||
WIREGUARD_ADDRESSES=${config.sops.placeholder.wireguard_addresses},${config.sops.placeholder.wireguard6_adresses}
|
||||
WIREGUARD_PRESHARED_KEY=${config.sops.placeholder.wireguard_preshared_key}
|
||||
DNS_ADDRESS=${config.sops.placeholder.wireguard_dns}
|
||||
WIREGUARD_MTU=1320
|
||||
|
|
@ -96,13 +103,13 @@
|
|||
sops.secrets.prowlarr_api_key = { };
|
||||
|
||||
# Authelia Secrets
|
||||
# sops.secrets.authelia_jwt_secret = {
|
||||
# owner = "authelia-main";
|
||||
# };
|
||||
# sops.secrets.authelia_session_secret = {
|
||||
# owner = "authelia-main";
|
||||
# };
|
||||
# sops.secrets.authelia_storage_encryption_key = {
|
||||
# owner = "authelia-main";
|
||||
# };
|
||||
sops.secrets.authelia_jwt_secret = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
sops.secrets.authelia_session_secret = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
sops.secrets.authelia_storage_encryption_key = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,38 @@
|
|||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
# Authelia internal location snippet
|
||||
autheliaLocation = {
|
||||
proxyPass = "http://127.0.0.1:9099/api/verify";
|
||||
extraConfig = ''
|
||||
internal;
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
'';
|
||||
};
|
||||
|
||||
# Config to enable Authelia protection
|
||||
autheliaProtect = ''
|
||||
auth_request /authelia;
|
||||
auth_request_set $target_url $scheme://$http_host$request_uri;
|
||||
auth_request_set $user $upstream_http_remote_user;
|
||||
auth_request_set $groups $upstream_http_remote_groups;
|
||||
proxy_set_header Remote-User $user;
|
||||
proxy_set_header Remote-Groups $groups;
|
||||
error_page 401 =302 https://auth.ashisgreat.xyz/?rd=$target_url;
|
||||
'';
|
||||
in
|
||||
{
|
||||
services.flatpak.enable = false;
|
||||
services.flatpak = {
|
||||
enable = true;
|
||||
packages = [
|
||||
"com.github.wwmm.easyeffects"
|
||||
];
|
||||
update.onActivation = true;
|
||||
};
|
||||
|
||||
services.snowflake-proxy = {
|
||||
enable = false;
|
||||
|
|
@ -169,6 +199,8 @@
|
|||
"sonarr.ashisgreat.xyz" = {
|
||||
useACMEHost = "ashisgreat.xyz";
|
||||
forceSSL = true;
|
||||
extraConfig = autheliaProtect;
|
||||
locations."/authelia" = autheliaLocation;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8989";
|
||||
proxyWebsockets = true;
|
||||
|
|
@ -178,6 +210,8 @@
|
|||
"radarr.ashisgreat.xyz" = {
|
||||
useACMEHost = "ashisgreat.xyz";
|
||||
forceSSL = true;
|
||||
extraConfig = autheliaProtect;
|
||||
locations."/authelia" = autheliaLocation;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:7878";
|
||||
proxyWebsockets = true;
|
||||
|
|
@ -187,6 +221,8 @@
|
|||
"prowlarr.ashisgreat.xyz" = {
|
||||
useACMEHost = "ashisgreat.xyz";
|
||||
forceSSL = true;
|
||||
extraConfig = autheliaProtect;
|
||||
locations."/authelia" = autheliaLocation;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:9696";
|
||||
proxyWebsockets = true;
|
||||
|
|
@ -196,6 +232,8 @@
|
|||
"torrent.ashisgreat.xyz" = {
|
||||
useACMEHost = "ashisgreat.xyz";
|
||||
forceSSL = true;
|
||||
extraConfig = autheliaProtect;
|
||||
locations."/authelia" = autheliaLocation;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8080";
|
||||
proxyWebsockets = true;
|
||||
|
|
@ -221,6 +259,8 @@
|
|||
"jellyseer.ashisgreat.xyz" = {
|
||||
useACMEHost = "ashisgreat.xyz";
|
||||
forceSSL = true;
|
||||
extraConfig = autheliaProtect;
|
||||
locations."/authelia" = autheliaLocation;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:5055";
|
||||
proxyWebsockets = true;
|
||||
|
|
@ -242,7 +282,9 @@
|
|||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
'';
|
||||
''
|
||||
+ autheliaProtect;
|
||||
locations."/authelia" = autheliaLocation;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8082";
|
||||
proxyWebsockets = true;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
...
|
||||
}:
|
||||
{
|
||||
programs.fish.enable = true;
|
||||
|
||||
users.mutableUsers = false;
|
||||
|
||||
users.users.ashie = {
|
||||
|
|
|
|||
|
|
@ -36,26 +36,38 @@ in
|
|||
systemd.user.services.antigravity2api = {
|
||||
Unit = {
|
||||
Description = "Antigravity API to OpenAI Proxy";
|
||||
After = [ "network.target" ];
|
||||
After = [ "network-online.target" ];
|
||||
Wants = [ "network-online.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
WorkingDirectory = workDir;
|
||||
ExecStartPre = pkgs.writeShellScript "antigravity2api-init" ''
|
||||
export PATH="${pkgs.coreutils}/bin:$PATH"
|
||||
export PATH="${pkgs.coreutils}/bin:${pkgs.iputils}/bin:$PATH"
|
||||
mkdir -p "${workDir}"
|
||||
|
||||
# Ensure network exists (Not needed for host network)
|
||||
# ${pkgs.podman}/bin/podman network create antigravity-net --ignore >/dev/null 2>&1 || true
|
||||
|
||||
# Wait for connectivity to 8.8.8.8 (Google DNS) used by the container
|
||||
echo "Waiting for internet connectivity..."
|
||||
until ping -c1 -W1 8.8.8.8 >/dev/null 2>&1; do
|
||||
sleep 2
|
||||
done
|
||||
echo "Connectivity check passed."
|
||||
|
||||
cat > "${workDir}/.env" <<EOF
|
||||
API_KEY=${cfg.credentials.apiKey}
|
||||
ADMIN_USERNAME=${cfg.credentials.username}
|
||||
ADMIN_PASSWORD=${cfg.credentials.password}
|
||||
SYSTEM_INSTRUCTION="你是聊天机器人,名字叫萌萌,如同名字这般,你的性格是软软糯糯萌萌哒的,专门为用户提供聊天和情绪价值,协助进行小说创作或者角色扮演"
|
||||
SYSTEM_INSTRUCTION=""
|
||||
OFFICIAL_SYSTEM_PROMPT="You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding.You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.**Proactiveness**"
|
||||
EOF
|
||||
'';
|
||||
|
||||
ExecStart = ''
|
||||
${pkgs.podman}/bin/podman run --replace --rm --name antigravity2api \
|
||||
-p 127.0.0.1:8045:8045 \
|
||||
--network=host \
|
||||
-v ${workDir}/data:/app/data \
|
||||
-v ${workDir}/public/images:/app/public/images \
|
||||
-v ${workDir}/.env:/app/.env \
|
||||
|
|
|
|||
|
|
@ -70,6 +70,33 @@ in
|
|||
pkgs.lxqt.lxqt-policykit
|
||||
pkgs.libnotify
|
||||
pkgs.swww
|
||||
(pkgs.writeShellScriptBin "freeze-shot" ''
|
||||
# Capture the screen to a temp file
|
||||
file=$(mktemp --suffix=.png)
|
||||
${pkgs.grim}/bin/grim "$file"
|
||||
|
||||
# Open imv in fullscreen to simulate freeze
|
||||
# We run it in the background
|
||||
${pkgs.imv}/bin/imv -f "$file" &
|
||||
pid=$!
|
||||
|
||||
# Give imv a moment to open
|
||||
sleep 0.2
|
||||
|
||||
# Run slurp to select region
|
||||
geometry=$(${pkgs.slurp}/bin/slurp)
|
||||
|
||||
# Close the "frozen" overlay
|
||||
kill "$pid"
|
||||
|
||||
# If we got a selection, crop and copy
|
||||
if [ -n "$geometry" ]; then
|
||||
${pkgs.imagemagick}/bin/magick "$file" -crop "$geometry" - | ${pkgs.wl-clipboard}/bin/wl-copy
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
rm "$file"
|
||||
'')
|
||||
];
|
||||
|
||||
xdg.portal = {
|
||||
|
|
@ -234,7 +261,7 @@ in
|
|||
|
||||
Mod+Shift+E { spawn "bemoji" "-t"; }
|
||||
|
||||
Print { spawn "sh" "-c" "grim -g \"$(slurp)\" - | wl-copy"; }
|
||||
Print { spawn "freeze-shot"; }
|
||||
|
||||
// Browsers
|
||||
Mod+W { spawn "firefox"; }
|
||||
|
|
|
|||
|
|
@ -61,6 +61,29 @@ in
|
|||
mShadow = mocha.crust;
|
||||
};
|
||||
|
||||
plugins = {
|
||||
sources = [
|
||||
{
|
||||
enabled = true;
|
||||
name = "Official Noctalia Plugins";
|
||||
url = "https://github.com/noctalia-dev/noctalia-plugins";
|
||||
branch = "main"; # Explicitly set branch just in case
|
||||
}
|
||||
];
|
||||
states = {
|
||||
"assistant-panel" = {
|
||||
enabled = true;
|
||||
sourceUrl = "https://github.com/noctalia-dev/noctalia-plugins";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pluginSettings = {
|
||||
"assistant-panel" = {
|
||||
service = "openai";
|
||||
};
|
||||
};
|
||||
|
||||
settings = {
|
||||
colorSchemes = {
|
||||
darkMode = true;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ let
|
|||
glfw
|
||||
];
|
||||
|
||||
defaultJvmArgs = "-XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+UseNUMA -XX:NmethodSweepActivity=1 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:-DontCompileHugeMethods -XX:MaxNodeLimit=240000 -XX:NodeLimitFudgeFactor=8000 -XX:+UseVectorCmov -XX:+PerfDisableSharedMem -XX:+UseFastUnorderedTimeStamps -XX:+UseCriticalJavaThreadPriority -XX:ThreadPriorityPolicy=1 -XX:AllocatePrefetchStyle=3 -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000 -XX:AllocatePrefetchStyle=1 -XX:ConcGCThreads=4";
|
||||
defaultJvmArgs = "-Djava.net.preferIPv4Stack=true -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+UseNUMA -XX:NmethodSweepActivity=1 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:-DontCompileHugeMethods -XX:MaxNodeLimit=240000 -XX:NodeLimitFudgeFactor=8000 -XX:+UseVectorCmov -XX:+PerfDisableSharedMem -XX:+UseFastUnorderedTimeStamps -XX:+UseCriticalJavaThreadPriority -XX:ThreadPriorityPolicy=1 -XX:AllocatePrefetchStyle=3 -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000 -XX:AllocatePrefetchStyle=1 -XX:ConcGCThreads=4";
|
||||
|
||||
in
|
||||
{
|
||||
|
|
@ -66,225 +66,230 @@ in
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [
|
||||
(bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
id = "org.prismlauncher.PrismLauncher";
|
||||
package = pkgs.prismlauncher.overrideAttrs (old: {
|
||||
pname = "prismlauncher";
|
||||
version = old.version or "9.1"; # Fallback or keep current if valid
|
||||
buildInputs = (old.buildInputs or [ ]) ++ [ pkgs.jemalloc ];
|
||||
(
|
||||
let
|
||||
sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
id = "org.prismlauncher.PrismLauncher";
|
||||
package = pkgs.prismlauncher.overrideAttrs (old: {
|
||||
pname = "prismlauncher";
|
||||
version = old.version or "9.1"; # Fallback or keep current if valid
|
||||
buildInputs = (old.buildInputs or [ ]) ++ [ pkgs.jemalloc ];
|
||||
|
||||
# Keep runtimeLibs in closure without injecting them into environment
|
||||
postInstall = (old.postInstall or "") + ''
|
||||
mkdir -p $out/share/prismlauncher-sandboxed
|
||||
echo "${lib.makeLibraryPath runtimeLibs}" > $out/share/prismlauncher-sandboxed/libs
|
||||
'';
|
||||
# Keep runtimeLibs in closure without injecting them into environment
|
||||
postInstall = (old.postInstall or "") + ''
|
||||
mkdir -p $out/share/prismlauncher-sandboxed
|
||||
echo "${lib.makeLibraryPath runtimeLibs}" > $out/share/prismlauncher-sandboxed/libs
|
||||
'';
|
||||
|
||||
qtWrapperArgs = (old.qtWrapperArgs or [ ]) ++ [
|
||||
"--set JEMALLOC_PATH ${pkgs.jemalloc}/lib/libjemalloc.so"
|
||||
"--prefix LD_PRELOAD : ${pkgs.jemalloc}/lib/libjemalloc.so"
|
||||
qtWrapperArgs = (old.qtWrapperArgs or [ ]) ++ [
|
||||
"--set JEMALLOC_PATH ${pkgs.jemalloc}/lib/libjemalloc.so"
|
||||
"--prefix LD_PRELOAD : ${pkgs.jemalloc}/lib/libjemalloc.so"
|
||||
];
|
||||
});
|
||||
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS so themes/icons can be found
|
||||
BROWSER = "firefox";
|
||||
QT_QPA_PLATFORM = "xcb";
|
||||
GDK_BACKEND = "x11";
|
||||
NO_AT_BRIDGE = "1";
|
||||
QT_QPA_PLATFORMTHEME = "";
|
||||
QT_STYLE_OVERRIDE = "fusion";
|
||||
|
||||
# Sanitize Desktop Environment to prevent loading conflicting platform themes
|
||||
XDG_CURRENT_DESKTOP = "X-Generic";
|
||||
XDG_SESSION_TYPE = "x11";
|
||||
GTK_USE_PORTAL = "0";
|
||||
GTK_THEME = "Adwaita"; # Force a safe theme or empty?
|
||||
|
||||
# Unset potential conflict variables
|
||||
GTK_MODULES = "";
|
||||
GTK3_MODULES = "";
|
||||
};
|
||||
};
|
||||
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString cfg.uid}"
|
||||
# Bind ro system paths commonly needed
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
"--ro-bind /run/dbus /run/dbus"
|
||||
];
|
||||
});
|
||||
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS so themes/icons can be found
|
||||
BROWSER = "firefox";
|
||||
QT_QPA_PLATFORM = "xcb";
|
||||
GDK_BACKEND = "x11";
|
||||
NO_AT_BRIDGE = "1";
|
||||
QT_QPA_PLATFORMTHEME = "";
|
||||
QT_STYLE_OVERRIDE = "fusion";
|
||||
|
||||
# Sanitize Desktop Environment to prevent loading conflicting platform themes
|
||||
XDG_CURRENT_DESKTOP = "X-Generic";
|
||||
XDG_SESSION_TYPE = "x11";
|
||||
GTK_USE_PORTAL = "0";
|
||||
GTK_THEME = "Adwaita"; # Force a safe theme or empty?
|
||||
|
||||
# Unset potential conflict variables
|
||||
GTK_MODULES = "";
|
||||
GTK3_MODULES = "";
|
||||
};
|
||||
};
|
||||
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString cfg.uid}"
|
||||
# Bind ro system paths commonly needed
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
"--ro-bind /run/dbus /run/dbus"
|
||||
];
|
||||
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/qt6ct"
|
||||
"$HOME/.config/Kvantum"
|
||||
"$HOME/.config/MangoHud"
|
||||
"$HOME/Downloads"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.local/share/PrismLauncher"
|
||||
"$HOME/.cache/PrismLauncher"
|
||||
];
|
||||
};
|
||||
|
||||
dbus.enable = false;
|
||||
|
||||
script.preCmds.stage2 =
|
||||
let
|
||||
glfwPath = "${cfg.glfwPackage}/lib/libglfw.so.3";
|
||||
|
||||
# We need to access the sandbox-utils.nix. Since it's in system modules,
|
||||
# we can't easily import it relative to here if it's not exported.
|
||||
# But the content was small, let's inline what we need or check if we can source it.
|
||||
# For now, I'll assume the dbus-proxy logic is needed.
|
||||
|
||||
# Reimplementing mkDbusProxyScript from sandbox-utils.nix inline to avoid path dependency
|
||||
mkDbusProxyScript =
|
||||
{ appId, proxyArgs }:
|
||||
let
|
||||
proxyArgsStr = lib.escapeShellArgs proxyArgs;
|
||||
appDir = "$XDG_RUNTIME_DIR/app/${appId}";
|
||||
proxySocket = "${appDir}/bus";
|
||||
in
|
||||
''
|
||||
mkdir -p "${appDir}"
|
||||
# Start xdg-dbus-proxy
|
||||
${pkgs.xdg-dbus-proxy}/bin/xdg-dbus-proxy \
|
||||
"$DBUS_SESSION_BUS_ADDRESS" "${proxySocket}" \
|
||||
${proxyArgsStr} &
|
||||
DBUS_PROXY_PID=$!
|
||||
|
||||
# Kill proxy on exit
|
||||
trap "kill $DBUS_PROXY_PID" EXIT
|
||||
|
||||
# Wait for socket to be created
|
||||
for i in {1..50}; do
|
||||
if [ -S "${proxySocket}" ]; then
|
||||
break
|
||||
fi
|
||||
if ! kill -0 $DBUS_PROXY_PID 2>/dev/null; then
|
||||
echo "xdg-dbus-proxy died unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
'';
|
||||
|
||||
dbusScript = mkDbusProxyScript {
|
||||
appId = "org.prismlauncher.PrismLauncher";
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
"--talk=org.freedesktop.portal.*"
|
||||
"--call=org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"
|
||||
"--talk=org.freedesktop.Notifications"
|
||||
"--own=org.prismlauncher.PrismLauncher"
|
||||
"--own=org.prismlauncher.PrismLauncher.*"
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/qt6ct"
|
||||
"$HOME/.config/Kvantum"
|
||||
"$HOME/.config/MangoHud"
|
||||
"$HOME/Downloads"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.local/share/PrismLauncher"
|
||||
"$HOME/.cache/PrismLauncher"
|
||||
];
|
||||
};
|
||||
in
|
||||
''
|
||||
${dbusScript}
|
||||
|
||||
# Sanitize Environment
|
||||
unset QT_QPA_PLATFORMTHEME
|
||||
unset GTK_THEME
|
||||
unset XDG_CURRENT_DESKTOP
|
||||
export QT_QPA_PLATFORM=xcb
|
||||
export GDK_BACKEND=x11
|
||||
export NO_AT_BRIDGE=1
|
||||
dbus.enable = false;
|
||||
|
||||
# Force Configs (JVM Args + GLFW)
|
||||
cfg="$HOME/.local/share/PrismLauncher/prismlauncher.cfg"
|
||||
if [ -f "$cfg" ]; then
|
||||
# JVM Args
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^JvmArgs=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^JvmArgs=.*|JvmArgs=${cfg.jvmArgs}|" "$cfg"
|
||||
else
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^\\[General\\]" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "/^\\[General\\]/a JvmArgs=${cfg.jvmArgs}" "$cfg"
|
||||
else
|
||||
echo "JvmArgs=${cfg.jvmArgs}" >> "$cfg"
|
||||
fi
|
||||
fi
|
||||
script.preCmds.stage2 =
|
||||
let
|
||||
glfwPath = "${cfg.glfwPackage}/lib/libglfw.so.3";
|
||||
|
||||
# GLFW Settings
|
||||
# 1. CustomGLFWPath
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^CustomGLFWPath=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^CustomGLFWPath=.*|CustomGLFWPath=${glfwPath}|" "$cfg"
|
||||
else
|
||||
echo "CustomGLFWPath=${glfwPath}" >> "$cfg"
|
||||
fi
|
||||
# We need to access the sandbox-utils.nix. Since it's in system modules,
|
||||
# we can't easily import it relative to here if it's not exported.
|
||||
# But the content was small, let's inline what we need or check if we can source it.
|
||||
# For now, I'll assume the dbus-proxy logic is needed.
|
||||
|
||||
# 2. UseNativeGLFW
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^UseNativeGLFW=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^UseNativeGLFW=.*|UseNativeGLFW=true|" "$cfg"
|
||||
else
|
||||
echo "UseNativeGLFW=true" >> "$cfg"
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
# Reimplementing mkDbusProxyScript from sandbox-utils.nix inline to avoid path dependency
|
||||
mkDbusProxyScript =
|
||||
{ appId, proxyArgs }:
|
||||
let
|
||||
proxyArgsStr = lib.escapeShellArgs proxyArgs;
|
||||
appDir = "$XDG_RUNTIME_DIR/app/${appId}";
|
||||
proxySocket = "${appDir}/bus";
|
||||
in
|
||||
''
|
||||
mkdir -p "${appDir}"
|
||||
# Start xdg-dbus-proxy
|
||||
${pkgs.xdg-dbus-proxy}/bin/xdg-dbus-proxy \
|
||||
"$DBUS_SESSION_BUS_ADDRESS" "${proxySocket}" \
|
||||
${proxyArgsStr} &
|
||||
DBUS_PROXY_PID=$!
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus proxy
|
||||
''--bind "$XDG_RUNTIME_DIR/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
# Note: The original code bound a specific path TO ./bus.
|
||||
# "''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''"
|
||||
# But mkDbusProxyScript (if standard) creates a socket.
|
||||
# The logic in prismlauncher-sandboxed.nix imported sandbox-utils.nix.
|
||||
# I'll try to match the original bind logic if possible.
|
||||
# Kill proxy on exit
|
||||
trap "kill $DBUS_PROXY_PID" EXIT
|
||||
|
||||
# The original code had:
|
||||
# ''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
# But my inline mkDbusProxyScript sets up "$XDG_RUNTIME_DIR/bus" as the listen socket *inside* the script execution?
|
||||
# Wait, xdg-dbus-proxy runs inside the outer unshared namespace or outside?
|
||||
# In mkBwrapper, preCmds run *inside* the bwrap?
|
||||
# No, typically preCmds run before the final exec?
|
||||
# Actually, looking at nix-bwrapper, `preCmds.stage2` runs *inside* the sandbox?
|
||||
# Wait for socket to be created
|
||||
for i in {1..50}; do
|
||||
if [ -S "${proxySocket}" ]; then
|
||||
break
|
||||
fi
|
||||
if ! kill -0 $DBUS_PROXY_PID 2>/dev/null; then
|
||||
echo "xdg-dbus-proxy died unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
'';
|
||||
|
||||
# Let's start with the binds exactly as they were, assuming `sandbox-utils` logic.
|
||||
# If I can't import sandbox-utils, I have to rely on what I can see.
|
||||
# The original `sandbox-utils.nix` likely set up the proxy.
|
||||
# I will copy the binds from the original file.
|
||||
dbusScript = mkDbusProxyScript {
|
||||
appId = "org.prismlauncher.PrismLauncher";
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
"--talk=org.freedesktop.portal.*"
|
||||
"--call=org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"
|
||||
"--talk=org.freedesktop.Notifications"
|
||||
"--own=org.prismlauncher.PrismLauncher"
|
||||
"--own=org.prismlauncher.PrismLauncher.*"
|
||||
];
|
||||
};
|
||||
in
|
||||
''
|
||||
${dbusScript}
|
||||
|
||||
''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
# Sanitize Environment
|
||||
unset QT_QPA_PLATFORMTHEME
|
||||
unset GTK_THEME
|
||||
unset XDG_CURRENT_DESKTOP
|
||||
export QT_QPA_PLATFORM=xcb
|
||||
export GDK_BACKEND=x11
|
||||
export NO_AT_BRIDGE=1
|
||||
|
||||
# Wayland socket
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
# Force Configs (JVM Args + GLFW)
|
||||
cfg="$HOME/.local/share/PrismLauncher/prismlauncher.cfg"
|
||||
if [ -f "$cfg" ]; then
|
||||
# JVM Args
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^JvmArgs=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^JvmArgs=.*|JvmArgs=${cfg.jvmArgs}|" "$cfg"
|
||||
else
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^\\[General\\]" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "/^\\[General\\]/a JvmArgs=${cfg.jvmArgs}" "$cfg"
|
||||
else
|
||||
echo "JvmArgs=${cfg.jvmArgs}" >> "$cfg"
|
||||
fi
|
||||
fi
|
||||
|
||||
# PipeWire + Pulse
|
||||
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
|
||||
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
|
||||
];
|
||||
})
|
||||
# GLFW Settings
|
||||
# 1. CustomGLFWPath
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^CustomGLFWPath=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^CustomGLFWPath=.*|CustomGLFWPath=${glfwPath}|" "$cfg"
|
||||
else
|
||||
echo "CustomGLFWPath=${glfwPath}" >> "$cfg"
|
||||
fi
|
||||
|
||||
# 2. UseNativeGLFW
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^UseNativeGLFW=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^UseNativeGLFW=.*|UseNativeGLFW=true|" "$cfg"
|
||||
else
|
||||
echo "UseNativeGLFW=true" >> "$cfg"
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus proxy
|
||||
''--bind "$XDG_RUNTIME_DIR/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
# Note: The original code bound a specific path TO ./bus.
|
||||
# "''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''"
|
||||
# But mkDbusProxyScript (if standard) creates a socket.
|
||||
# The logic in prismlauncher-sandboxed.nix imported sandbox-utils.nix.
|
||||
# I'll try to match the original bind logic if possible.
|
||||
|
||||
# The original code had:
|
||||
# ''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
# But my inline mkDbusProxyScript sets up "$XDG_RUNTIME_DIR/bus" as the listen socket *inside* the script execution?
|
||||
# Wait, xdg-dbus-proxy runs inside the outer unshared namespace or outside?
|
||||
# In mkBwrapper, preCmds run *inside* the bwrap?
|
||||
# No, typically preCmds run before the final exec?
|
||||
# Actually, looking at nix-bwrapper, `preCmds.stage2` runs *inside* the sandbox?
|
||||
|
||||
# Let's start with the binds exactly as they were, assuming `sandbox-utils` logic.
|
||||
# If I can't import sandbox-utils, I have to rely on what I can see.
|
||||
# The original `sandbox-utils.nix` likely set up the proxy.
|
||||
# I will copy the binds from the original file.
|
||||
|
||||
''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Wayland socket
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
|
||||
# PipeWire + Pulse
|
||||
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
|
||||
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
|
||||
];
|
||||
};
|
||||
in
|
||||
sandboxed
|
||||
)
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
81
modules/nixos/auto-update.nix
Normal file
81
modules/nixos/auto-update.nix
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# Automatic Updates Module
|
||||
# Provides:
|
||||
# 1. Weekly Nix flake updates for the system configuration
|
||||
# 2. Daily NixOS system upgrades via system.autoUpgrade
|
||||
# 3. Daily Podman container updates for services with 'io.containers.autoupdate' label
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.autoUpdate;
|
||||
repoPath = "/home/ashie/nixos";
|
||||
in
|
||||
{
|
||||
options.myModules.autoUpdate = {
|
||||
enable = lib.mkEnableOption "system-wide automatic updates";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# 1. NixOS System Upgrades
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
dates = "04:30";
|
||||
flake = "${repoPath}#nixos";
|
||||
allowReboot = false;
|
||||
flags = [
|
||||
"--refresh"
|
||||
];
|
||||
};
|
||||
|
||||
# 2. Flake Update Service (Runs before autoUpgrade)
|
||||
# This ensures the local flake.lock is updated so autoUpgrade has new versions to pull.
|
||||
systemd.services.nix-flake-update = {
|
||||
description = "Update Nix Flake Lockfile";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
};
|
||||
path = [ pkgs.nix pkgs.git pkgs.openssh ];
|
||||
script = ''
|
||||
cd ${repoPath}
|
||||
# Only update if it's a git repo and we have permissions
|
||||
if [ -d .git ]; then
|
||||
nix flake update --commit-lock-file
|
||||
else
|
||||
nix flake update
|
||||
fi
|
||||
'';
|
||||
startAt = "04:00"; # Run 30 mins before autoUpgrade
|
||||
};
|
||||
|
||||
# 3. Podman Container Auto-Updates
|
||||
# Runs 'podman auto-update' to refresh containers with the 'io.containers.autoupdate' label.
|
||||
systemd.services.podman-auto-update = {
|
||||
description = "Podman Container Auto-Update";
|
||||
after = [ "network-online.target" "nixos-upgrade.service" ];
|
||||
wants = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.podman}/bin/podman auto-update";
|
||||
ExecStartPost = "${pkgs.podman}/bin/podman image prune -f";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.timers.podman-auto-update = {
|
||||
description = "Podman Container Auto-Update Timer";
|
||||
timerConfig = {
|
||||
OnCalendar = "05:00";
|
||||
Persistent = true;
|
||||
};
|
||||
wantedBy = [ "timers.target" ];
|
||||
};
|
||||
|
||||
# Ensure the auto-upgrade service waits for the flake update
|
||||
systemd.services.nixos-upgrade.after = [ "nix-flake-update.service" ];
|
||||
};
|
||||
}
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
config,
|
||||
{ config,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
let
|
||||
cfg = config.myModules.azaharSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
|
||||
pname = "azahar";
|
||||
version = "2123.4";
|
||||
|
|
@ -35,58 +36,68 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
azahar-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = azahar;
|
||||
id = "org.azahar_emu.Azahar";
|
||||
env = {
|
||||
QT_QPA_PLATFORM = "wayland;xcb";
|
||||
XDG_CURRENT_DESKTOP = "KDE";
|
||||
options.myModules.azaharSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Azahar with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
azahar-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = azahar;
|
||||
id = "org.azahar_emu.Azahar";
|
||||
env = {
|
||||
QT_QPA_PLATFORM = "wayland;xcb";
|
||||
XDG_CURRENT_DESKTOP = "KDE";
|
||||
};
|
||||
};
|
||||
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { });
|
||||
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/org.azahar_emu.Azahar/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
];
|
||||
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read;
|
||||
readWrite = [
|
||||
"$HOME/Games/3DS"
|
||||
"$HOME/.config/azahar"
|
||||
"$HOME/.local/share/azahar"
|
||||
] ++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
dbus.enable = false;
|
||||
script.preCmds.stage2 = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "org.azahar_emu.Azahar";
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.Flatpak"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.freedesktop.portal.Desktop"''
|
||||
''--talk="org.freedesktop.portal.OpenURI"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
flatpak.enable = false;
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
''--bind "$XDG_RUNTIME_DIR/app/org.azahar_emu.Azahar/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
];
|
||||
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.config/MangoHud"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/Games/3DS"
|
||||
"$HOME/.config/azahar"
|
||||
"$HOME/.local/share/azahar"
|
||||
];
|
||||
};
|
||||
|
||||
dbus.enable = false;
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "org.azahar_emu.Azahar";
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.Flatpak"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.freedesktop.portal.Desktop"''
|
||||
''--talk="org.freedesktop.portal.OpenURI"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.azahar-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.braveSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
|
||||
# create a custom settings.ini to force dark mode
|
||||
darkSettingsIni = pkgs.writeText "settings.ini" ''
|
||||
|
|
@ -31,138 +33,150 @@ let
|
|||
);
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
brave-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = pkgs.symlinkJoin {
|
||||
name = "brave-single-desktop";
|
||||
paths = [ prev.brave ];
|
||||
inherit (prev.brave) pname version meta;
|
||||
postBuild = ''
|
||||
rm $out/share/applications/com.brave.Browser.desktop
|
||||
'';
|
||||
options.myModules.braveSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Brave with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
brave-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = pkgs.symlinkJoin {
|
||||
name = "brave-single-desktop";
|
||||
paths = [ prev.brave ];
|
||||
inherit (prev.brave) pname version meta;
|
||||
postBuild = ''
|
||||
rm $out/share/applications/com.brave.Browser.desktop
|
||||
'';
|
||||
};
|
||||
# id = "brave-browser"; # Omit app.id to avoid potential bind errors (like Firefox)
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS so GTK can find themes in user profile/system
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
GTK_THEME = "catppuccin-mocha-mauve-standard";
|
||||
HYPRCURSOR_THEME = "Future-Cyan-Hyprcursor_Theme";
|
||||
HYPRCURSOR_SIZE = "32";
|
||||
# Force ozone/wayland usage for Brave/Chromium
|
||||
NIXOS_OZONE_WL = "1";
|
||||
};
|
||||
};
|
||||
# id = "brave-browser"; # Omit app.id to avoid potential bind errors (like Firefox)
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS so GTK can find themes in user profile/system
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
GTK_THEME = "catppuccin-mocha-mauve-standard";
|
||||
HYPRCURSOR_THEME = "Future-Cyan-Hyprcursor_Theme";
|
||||
HYPRCURSOR_SIZE = "32";
|
||||
# Force ozone/wayland usage for Brave/Chromium
|
||||
NIXOS_OZONE_WL = "1";
|
||||
|
||||
flatpak.enable = false;
|
||||
sockets.x11 = false;
|
||||
sockets.wayland = true;
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
};
|
||||
|
||||
flatpak.enable = false;
|
||||
sockets.x11 = false;
|
||||
sockets.wayland = true;
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /mnt"
|
||||
"--tmpfs /run"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/booted-system /run/booted-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
# Brave flags
|
||||
"--setenv NIXOS_OZONE_WL \"1\""
|
||||
"--setenv NOTIFY_IGNORE_PORTAL 1"
|
||||
# Bind policies for Theme
|
||||
"--dir /etc/brave/policies/managed"
|
||||
"--ro-bind ${bravePolicies} /etc/brave/policies/managed/policies.json"
|
||||
# Fallback paths for Chromium/Chrome base
|
||||
"--dir /etc/chromium/policies/managed"
|
||||
"--ro-bind ${bravePolicies} /etc/chromium/policies/managed/policies.json"
|
||||
"--dir /etc/opt/chrome/policies/managed"
|
||||
"--ro-bind ${bravePolicies} /etc/opt/chrome/policies/managed/policies.json"
|
||||
];
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /mnt"
|
||||
"--tmpfs /run"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/booted-system /run/booted-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
# Brave flags
|
||||
"--setenv NIXOS_OZONE_WL \"1\""
|
||||
"--setenv NOTIFY_IGNORE_PORTAL 1"
|
||||
# Bind policies for Theme
|
||||
"--dir /etc/brave/policies/managed"
|
||||
"--ro-bind ${bravePolicies} /etc/brave/policies/managed/policies.json"
|
||||
# Fallback paths for Chromium/Chrome base
|
||||
"--dir /etc/chromium/policies/managed"
|
||||
"--ro-bind ${bravePolicies} /etc/chromium/policies/managed/policies.json"
|
||||
"--dir /etc/opt/chrome/policies/managed"
|
||||
"--ro-bind ${bravePolicies} /etc/opt/chrome/policies/managed/policies.json"
|
||||
# Filesystem: Limited to Brave directories and Downloads
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.config/user-dirs.dirs"
|
||||
"$HOME/.config/mimeapps.list"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/gtk-3.0"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.config/BraveSoftware"
|
||||
"$HOME/.cache/BraveSoftware"
|
||||
"$HOME/Downloads"
|
||||
] ++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
# Bind mount systemd-resolved socket for DNS and required system files
|
||||
# Disable built-in DBus module because it invokes bwrap without --unshare-user
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user
|
||||
script.preCmds.stage2 = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "nix.bwrapper.brave";
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.Desktop"''
|
||||
''--talk="org.freedesktop.portal.OpenURI"''
|
||||
''--talk="org.freedesktop.portal.FileChooser"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--own="org.chromium.LibCrosService"'' # Chromium/Brave specific
|
||||
''--own="org.mpris.MediaPlayer2.chromium.*"''
|
||||
''--own="org.mpris.MediaPlayer2.brave.*"''
|
||||
];
|
||||
enableSystemBus = true;
|
||||
systemProxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.NetworkManager"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
''--bind "$XDG_RUNTIME_DIR/app/nix.bwrapper.brave/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
''--bind "$XDG_RUNTIME_DIR/app/nix.bwrapper.brave/bus_system" /run/dbus/system_bus_socket''
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
"--bind-try /run/user/${toString config.users.users.${config.myModules.system.mainUser}.uid}/dconf /run/user/${toString config.users.users.${config.myModules.system.mainUser}.uid}/dconf"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellScriptBin "brave" ''
|
||||
exec ${config.myModules.system.repoPath}/scripts/launch-vpn-app.sh ${pkgs.brave-sandboxed}/bin/brave "$@"
|
||||
'')
|
||||
(pkgs.makeDesktopItem {
|
||||
name = "brave-vpn";
|
||||
desktopName = "Brave Web Browser";
|
||||
exec = "brave %U";
|
||||
icon = "brave-browser";
|
||||
categories = [
|
||||
"Network"
|
||||
"WebBrowser"
|
||||
];
|
||||
|
||||
# Filesystem: Limited to Brave directories and Downloads
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.config/user-dirs.dirs"
|
||||
"$HOME/.config/mimeapps.list"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/gtk-3.0"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.config/BraveSoftware"
|
||||
"$HOME/.cache/BraveSoftware"
|
||||
"$HOME/Downloads"
|
||||
];
|
||||
};
|
||||
|
||||
# Bind mount systemd-resolved socket for DNS and required system files
|
||||
# Disable built-in DBus module because it invokes bwrap without --unshare-user
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "nix.bwrapper.brave";
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.Desktop"''
|
||||
''--talk="org.freedesktop.portal.OpenURI"''
|
||||
''--talk="org.freedesktop.portal.FileChooser"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--own="org.chromium.LibCrosService"'' # Chromium/Brave specific
|
||||
''--own="org.mpris.MediaPlayer2.chromium.*"''
|
||||
''--own="org.mpris.MediaPlayer2.brave.*"''
|
||||
];
|
||||
enableSystemBus = true;
|
||||
systemProxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.NetworkManager"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
''--bind "$XDG_RUNTIME_DIR/app/nix.bwrapper.brave/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
''--bind "$XDG_RUNTIME_DIR/app/nix.bwrapper.brave/bus_system" /run/dbus/system_bus_socket''
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
"--bind-try /run/user/${toString config.users.users.ashie.uid}/dconf /run/user/${toString config.users.users.ashie.uid}/dconf"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellScriptBin "brave" ''
|
||||
exec /home/ashie/nixos/scripts/launch-vpn-app.sh ${pkgs.brave-sandboxed}/bin/brave "$@"
|
||||
'')
|
||||
(pkgs.makeDesktopItem {
|
||||
name = "brave-vpn";
|
||||
desktopName = "Brave Web Browser";
|
||||
exec = "brave %U";
|
||||
icon = "brave-browser";
|
||||
categories = [
|
||||
"Network"
|
||||
"WebBrowser"
|
||||
];
|
||||
})
|
||||
];
|
||||
}
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
64
modules/nixos/braveapi.py
Normal file
64
modules/nixos/braveapi.py
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
"""
|
||||
Search Engine: Brave Search API
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
from urllib.parse import quote
|
||||
|
||||
# About the engine
|
||||
about = {
|
||||
"website": "https://brave.com/search/api/",
|
||||
"use_official_api": True,
|
||||
"require_api_key": True,
|
||||
"results": "JSON",
|
||||
}
|
||||
|
||||
categories = ['general', 'web']
|
||||
paging = True
|
||||
max_page = 10
|
||||
page_size = 20
|
||||
|
||||
# API Endpoint
|
||||
base_url = "https://api.search.brave.com/res/v1/web/search"
|
||||
|
||||
def request(query, params):
|
||||
# Get key from environment
|
||||
api_key = os.getenv('BRAVE_API_KEY')
|
||||
|
||||
# Brave expects offset 0-9 for pages
|
||||
pageno = min(params.get('pageno', 1), 10)
|
||||
offset = pageno - 1
|
||||
|
||||
# Simple query string construction with proper quoting
|
||||
# Using 'x-subscription-token' (lowercase) which was verified to work
|
||||
params['url'] = f"{base_url}?q={quote(query)}&count=20&offset={offset}"
|
||||
|
||||
params['headers'] = {
|
||||
'x-subscription-token': api_key,
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
params['method'] = 'GET'
|
||||
|
||||
# Clean up SearXNG defaults to prevent interference
|
||||
if 'data' in params: del params['data']
|
||||
if 'params' in params: del params['params']
|
||||
|
||||
return params
|
||||
|
||||
def response(resp):
|
||||
results = []
|
||||
data = json.loads(resp.text)
|
||||
|
||||
# The Brave API returns 'web' results
|
||||
web_results = data.get('web', {}).get('results', [])
|
||||
|
||||
for item in web_results:
|
||||
results.append({
|
||||
'url': item.get('url'),
|
||||
'title': item.get('title'),
|
||||
'content': item.get('description'),
|
||||
})
|
||||
|
||||
return results
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
let
|
||||
cfg = config.myModules.browserVpn;
|
||||
mainUser = config.myModules.system.mainUser;
|
||||
|
||||
# Helper function for auto-recovery from podman namespace corruption
|
||||
# Detects "cannot re-exec process" errors and runs migrate to fix
|
||||
|
|
@ -78,7 +79,8 @@ let
|
|||
echo "Build complete."
|
||||
;;
|
||||
run)
|
||||
if ! podman_with_recovery image exists ${imageName}:latest 2>/dev/null; then
|
||||
if ! podman_with_recovery image exists ${imageName}:latest 2>/dev/null;
|
||||
then
|
||||
echo "Building ${name} container image..."
|
||||
podman_with_recovery build -t ${imageName}:latest "$REPO_DIR/containers/${name}-wayland/"
|
||||
fi
|
||||
|
|
@ -168,8 +170,8 @@ let
|
|||
Fingerprinting = true;
|
||||
};
|
||||
Preferences = {
|
||||
"network.dns.disableIPv6" = true;
|
||||
"network.ipv6" = false;
|
||||
"network.dns.disableIPv6" = false;
|
||||
"network.ipv6" = true;
|
||||
"network.http.fast-fallback-to-IPv4" = true;
|
||||
"network.trr.mode" = 5; # Disable DNS over HTTPS (use system/VPN DNS)
|
||||
"ui.systemUsesDarkTheme" = 1;
|
||||
|
|
@ -231,7 +233,8 @@ let
|
|||
echo "Build complete."
|
||||
;;
|
||||
run)
|
||||
if ! podman_with_recovery image exists localhost/thorium-wayland:latest 2>/dev/null; then
|
||||
if ! podman_with_recovery image exists localhost/thorium-wayland:latest 2>/dev/null;
|
||||
then
|
||||
echo "Building thorium-dev container image..."
|
||||
podman_with_recovery build -t localhost/thorium-wayland:latest "$REPO_DIR/containers/thorium-wayland/"
|
||||
fi
|
||||
|
|
@ -315,7 +318,8 @@ let
|
|||
echo "Build complete."
|
||||
;;
|
||||
run)
|
||||
if ! podman_with_recovery image exists localhost/arch-kitty:latest 2>/dev/null; then
|
||||
if ! podman_with_recovery image exists localhost/arch-kitty:latest 2>/dev/null;
|
||||
then
|
||||
echo "Building Arch Kitty container image..."
|
||||
podman_with_recovery build -t localhost/arch-kitty:latest "$REPO_DIR/containers/arch-kitty/"
|
||||
fi
|
||||
|
|
@ -450,13 +454,13 @@ in
|
|||
|
||||
kittyConfigDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/home/ashie/.config/kitty";
|
||||
default = "/home/${mainUser}/.config/kitty";
|
||||
description = "Path to kitty configuration directory";
|
||||
};
|
||||
|
||||
bashrcPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/home/ashie/.bashrc";
|
||||
default = "/home/${mainUser}/.bashrc";
|
||||
description = "Path to bashrc file for Kitty container";
|
||||
};
|
||||
};
|
||||
|
|
@ -464,4 +468,4 @@ in
|
|||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = enabledPackages ++ [ desktopEntriesPackage ];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,9 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.citronSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
|
||||
pname = "citron";
|
||||
version = "0.12.25";
|
||||
|
|
@ -74,123 +76,110 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
citron-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = citron;
|
||||
id = appId;
|
||||
env = {
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
QT_QPA_PLATFORM = "wayland;xcb";
|
||||
XDG_CURRENT_DESKTOP = "KDE";
|
||||
# Allow AppImage to extract and run
|
||||
APPIMAGE_EXTRACT_AND_RUN = "1";
|
||||
options.myModules.citronSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Citron with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
citron-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = citron;
|
||||
id = appId;
|
||||
env = {
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
QT_QPA_PLATFORM = "wayland;xcb";
|
||||
XDG_CURRENT_DESKTOP = "KDE";
|
||||
# Allow AppImage to extract and run
|
||||
APPIMAGE_EXTRACT_AND_RUN = "1";
|
||||
};
|
||||
};
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network for online features
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { } ++ [
|
||||
# Fix for amdgpu.ids missing - use tmpfs so mkdir can succeed
|
||||
"--tmpfs /usr/share"
|
||||
"--ro-bind ${pkgs.libdrm}/share/libdrm /usr/share/libdrm"
|
||||
"--ro-bind-try /nix/store /nix/store"
|
||||
]);
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
# Also create required directories before bwrap runs
|
||||
script.preCmds.stage2 = ''
|
||||
# Create directories that bwrap will bind
|
||||
mkdir -p "$HOME/.cache/citron-tmp"
|
||||
mkdir -p "$HOME/.config/citron"
|
||||
mkdir -p "$HOME/.config/Citron"
|
||||
mkdir -p "$HOME/.local/share/citron"
|
||||
mkdir -p "$HOME/.local/share/Citron"
|
||||
mkdir -p "$HOME/Games/Switch"
|
||||
''
|
||||
+ sandboxUtils.mkDbusProxyScript {
|
||||
inherit appId;
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--own="${appId}"''
|
||||
''--own="${appId}.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Read-write mounts
|
||||
"--bind $HOME/Games/Switch $HOME/Games/Switch"
|
||||
"--bind $HOME/.config/citron $HOME/.config/citron"
|
||||
"--bind $HOME/.config/Citron $HOME/.config/Citron"
|
||||
"--bind $HOME/.local/share/citron $HOME/.local/share/citron"
|
||||
"--bind $HOME/.local/share/Citron $HOME/.local/share/Citron"
|
||||
"--bind $HOME/.cache/citron-tmp $HOME/.cache/citron-tmp"
|
||||
];
|
||||
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read;
|
||||
readWrite = cfg.extraBindMounts;
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network for online features
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri" # GPU acceleration
|
||||
"--dev-bind /dev/shm /dev/shm" # Shared memory
|
||||
"--dev-bind-try /dev/uinput /dev/uinput" # Controller support
|
||||
"--dev-bind-try /dev/input /dev/input"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.ashie.uid}"
|
||||
# Fix for amdgpu.ids missing - use tmpfs so mkdir can succeed
|
||||
"--tmpfs /usr/share"
|
||||
"--ro-bind ${pkgs.libdrm}/share/libdrm /usr/share/libdrm"
|
||||
# System paths
|
||||
"--ro-bind /sys /sys"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--ro-bind-try /nix/store /nix/store"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
# udev for controller hotplug
|
||||
"--ro-bind-try /run/udev /run/udev"
|
||||
];
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
# Also create required directories before bwrap runs
|
||||
script.preCmds.stage2 = ''
|
||||
# Create directories that bwrap will bind
|
||||
mkdir -p "$HOME/.cache/citron-tmp"
|
||||
mkdir -p "$HOME/.config/citron"
|
||||
mkdir -p "$HOME/.config/Citron"
|
||||
mkdir -p "$HOME/.local/share/citron"
|
||||
mkdir -p "$HOME/.local/share/Citron"
|
||||
mkdir -p "$HOME/Games/Switch"
|
||||
''
|
||||
+ (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
inherit appId;
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--own="${appId}"''
|
||||
''--own="${appId}.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Manual mounts for data persistence
|
||||
"--ro-bind-try $HOME/.config/kdedefaults $HOME/.config/kdedefaults"
|
||||
"--ro-bind-try $HOME/.local/share/color-schemes $HOME/.local/share/color-schemes"
|
||||
"--ro-bind-try $HOME/.config/fontconfig $HOME/.config/fontconfig"
|
||||
"--ro-bind-try $HOME/.local/share/fonts $HOME/.local/share/fonts"
|
||||
"--ro-bind-try $HOME/.icons $HOME/.icons"
|
||||
"--ro-bind-try $HOME/.themes $HOME/.themes"
|
||||
"--ro-bind-try $HOME/.config/qt6ct $HOME/.config/qt6ct"
|
||||
"--ro-bind-try $HOME/.config/Kvantum $HOME/.config/Kvantum"
|
||||
"--ro-bind-try $HOME/.config/MangoHud $HOME/.config/MangoHud"
|
||||
# Read-write mounts
|
||||
"--bind $HOME/Games/Switch $HOME/Games/Switch"
|
||||
"--bind $HOME/.config/citron $HOME/.config/citron"
|
||||
"--bind $HOME/.config/Citron $HOME/.config/Citron"
|
||||
"--bind $HOME/.local/share/citron $HOME/.local/share/citron"
|
||||
"--bind $HOME/.local/share/Citron $HOME/.local/share/Citron"
|
||||
"--bind $HOME/.cache/citron-tmp $HOME/.cache/citron-tmp"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.citron-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,13 +118,16 @@ in
|
|||
# Allow all traffic from internal container interfaces (Podman/CNI)
|
||||
# This allows containers to reach the host (DNS, Gateway)
|
||||
iifname "podman*" accept
|
||||
|
||||
iifname "cni*" accept
|
||||
# Allow container subnet (fixes issues with non-podman* interface names)
|
||||
ip saddr 10.89.0.0/16 accept
|
||||
|
||||
# Allow RFC1918 Private Networks (LAN, Containers, Link-Local)
|
||||
${lib.optionalString cfg.allowLocalTraffic ''
|
||||
ip saddr 10.0.0.0/8 accept
|
||||
ip saddr 172.16.0.0/12 accept
|
||||
ip saddr 192.168.0.0/16 accept
|
||||
ip saddr 10.0.0.0/8 accept
|
||||
ip saddr 172.16.0.0/12 accept
|
||||
ip saddr 192.168.0.0/16 accept
|
||||
''}
|
||||
ip saddr 169.254.0.0/16 accept
|
||||
|
||||
|
|
@ -137,7 +140,7 @@ in
|
|||
${lib.optionalString (cfg.restrictedPorts != [ ]) ''
|
||||
ip saddr @cloudflare_ipv4 tcp dport { ${lib.concatStringsSep ", " (map toString cfg.restrictedPorts)} } accept
|
||||
ip6 saddr @cloudflare_ipv6 tcp dport { ${lib.concatStringsSep ", " (map toString cfg.restrictedPorts)} } accept
|
||||
|
||||
|
||||
# Drop all other traffic to restricted ports
|
||||
tcp dport { ${lib.concatStringsSep ", " (map toString cfg.restrictedPorts)} } drop
|
||||
''}
|
||||
|
|
@ -151,6 +154,9 @@ in
|
|||
oifname "podman*" accept
|
||||
iifname "cni*" accept
|
||||
oifname "cni*" accept
|
||||
# Allow container subnet forwarding
|
||||
ip saddr 10.89.0.0/16 accept
|
||||
ip daddr 10.89.0.0/16 accept
|
||||
|
||||
# Allow established/related forwarding
|
||||
ct state established,related accept
|
||||
|
|
|
|||
|
|
@ -10,5 +10,11 @@
|
|||
default = "/home/ashie/nixos";
|
||||
description = "Path to the main NixOS configuration repository";
|
||||
};
|
||||
|
||||
mainUser = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "ashie";
|
||||
description = "Username of the main user";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,25 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.myModules.desktop.cosmic;
|
||||
in
|
||||
{
|
||||
services.desktopManager.cosmic.enable = true;
|
||||
services.displayManager.cosmic-greeter.enable = false;
|
||||
options.myModules.desktop.cosmic = {
|
||||
enable = lib.mkEnableOption "Cosmic Desktop Environment";
|
||||
};
|
||||
|
||||
# Optimization
|
||||
services.system76-scheduler.enable = true;
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.desktopManager.cosmic.enable = true;
|
||||
services.displayManager.cosmic-greeter.enable = false;
|
||||
|
||||
# Clipboard support (unstable protocol)
|
||||
environment.sessionVariables.COSMIC_DATA_CONTROL_ENABLED = "1";
|
||||
}
|
||||
# Optimization
|
||||
services.system76-scheduler.enable = true;
|
||||
|
||||
# Clipboard support (unstable protocol)
|
||||
environment.sessionVariables.COSMIC_DATA_CONTROL_ENABLED = "1";
|
||||
};
|
||||
}
|
||||
|
|
@ -36,5 +36,10 @@
|
|||
./tutanota-sandboxed.nix
|
||||
./hardened-malloc.nix
|
||||
./searxng.nix
|
||||
./media.nix
|
||||
./cosmic.nix
|
||||
./steam-gamemode.nix
|
||||
./redlib.nix
|
||||
./auto-update.nix
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -10,138 +10,125 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.faugusSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
faugus-sandboxed =
|
||||
let
|
||||
singleDesktopPkg =
|
||||
pkgs.symlinkJoin {
|
||||
name = "faugus-launcher-single";
|
||||
paths = [ prev.faugus-launcher ];
|
||||
postBuild = ''
|
||||
rm -rf $out/share/applications
|
||||
mkdir -p $out/share/applications
|
||||
ln -s ${prev.faugus-launcher}/share/applications/faugus-launcher.desktop $out/share/applications/io.github.faugus.Launcher.desktop
|
||||
'';
|
||||
}
|
||||
// {
|
||||
inherit (prev.faugus-launcher) pname version meta;
|
||||
options.myModules.faugusSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Faugus Launcher with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
faugus-sandboxed =
|
||||
let
|
||||
singleDesktopPkg =
|
||||
pkgs.symlinkJoin {
|
||||
name = "faugus-launcher-single";
|
||||
paths = [ prev.faugus-launcher ];
|
||||
postBuild = ''
|
||||
rm -rf $out/share/applications
|
||||
mkdir -p $out/share/applications
|
||||
ln -s ${prev.faugus-launcher}/share/applications/faugus-launcher.desktop $out/share/applications/io.github.faugus.Launcher.desktop
|
||||
'';
|
||||
}
|
||||
// {
|
||||
inherit (prev.faugus-launcher) pname version meta;
|
||||
};
|
||||
in
|
||||
bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = singleDesktopPkg;
|
||||
id = "io.github.faugus.Launcher";
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS so themes/icons can be found
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
# Fix for file dialogs/theming
|
||||
XDG_CURRENT_DESKTOP = "KDE";
|
||||
# GTK theming
|
||||
GTK_THEME = "catppuccin-frappe-blue-standard";
|
||||
# Force GTK to use the portal for file dialogs
|
||||
GTK_USE_PORTAL = "1";
|
||||
# Force Wayland backend to ensure xdg-foreign protocol works
|
||||
GDK_BACKEND = "wayland";
|
||||
};
|
||||
};
|
||||
in
|
||||
bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = singleDesktopPkg;
|
||||
id = "io.github.faugus.Launcher";
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS so themes/icons can be found
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
# Fix for file dialogs/theming
|
||||
XDG_CURRENT_DESKTOP = "KDE";
|
||||
# GTK theming
|
||||
GTK_THEME = "catppuccin-frappe-blue-standard";
|
||||
# Force GTK to use the portal for file dialogs
|
||||
GTK_USE_PORTAL = "1";
|
||||
# Force Wayland backend to ensure xdg-foreign protocol works
|
||||
GDK_BACKEND = "wayland";
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network
|
||||
unshareIpc = false;
|
||||
};
|
||||
};
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { });
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read ++ [
|
||||
"$HOME/.gtkrc-2.0"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/Games"
|
||||
"$HOME/.config/faugus-launcher"
|
||||
"$HOME/.local/share/faugus-launcher"
|
||||
"$HOME/.cache/faugus-launcher"
|
||||
"$HOME/.config/qt6ct" # Allow theming
|
||||
] ++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network
|
||||
unshareIpc = false;
|
||||
};
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri" # GPU acceleration
|
||||
"--dev-bind /dev/shm /dev/shm" # Shared memory
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.ashie.uid}"
|
||||
# System paths
|
||||
"--ro-bind /sys /sys"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
];
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
script.preCmds.stage2 = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "io.github.faugus.Launcher";
|
||||
enableSystemBus = false; # No system bus access
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--talk="org.freedesktop.portal.FileChooser"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="org.freedesktop.portal.Settings"''
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--own="io.github.faugus.Launcher"''
|
||||
''--own="io.github.faugus.Launcher.*"''
|
||||
];
|
||||
};
|
||||
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.config/Kvantum"
|
||||
"$HOME/.config/gtk-3.0"
|
||||
"$HOME/.config/gtk-4.0"
|
||||
"$HOME/.gtkrc-2.0"
|
||||
"$HOME/.config/MangoHud"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/Games"
|
||||
"$HOME/.config/faugus-launcher"
|
||||
"$HOME/.local/share/faugus-launcher"
|
||||
"$HOME/.cache/faugus-launcher"
|
||||
"$HOME/.config/qt6ct" # Allow theming
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/io.github.faugus.Launcher/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# dconf for GTK settings
|
||||
"--bind-try /run/user/${toString config.users.users.${config.myModules.system.mainUser}.uid}/dconf /run/user/${toString config.users.users.${config.myModules.system.mainUser}.uid}/dconf"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "io.github.faugus.Launcher";
|
||||
enableSystemBus = false; # No system bus access
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--talk="org.freedesktop.portal.FileChooser"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="org.freedesktop.portal.Settings"''
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--own="io.github.faugus.Launcher"''
|
||||
''--own="io.github.faugus.Launcher.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/io.github.faugus.Launcher/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# dconf for GTK settings
|
||||
"--bind-try /run/user/${toString config.users.users.ashie.uid}/dconf /run/user/${toString config.users.users.ashie.uid}/dconf"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.faugus-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,38 +7,14 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.firefoxSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
|
||||
# create a custom settings.ini to force dark mode
|
||||
darkSettingsIni = pkgs.writeText "settings.ini" ''
|
||||
[Settings]
|
||||
gtk-theme-name=catppuccin-mocha-mauve-standard
|
||||
gtk-application-prefer-dark-theme=1
|
||||
gtk-cursor-theme-name=Future-Cyan-Hyprcursor_Theme
|
||||
gtk-xft-antialias=1
|
||||
gtk-xft-hinting=1
|
||||
gtk-xft-hintstyle=hintslight
|
||||
gtk-xft-rgba=rgb
|
||||
'';
|
||||
|
||||
# Define policies.json with Catppuccin Theme and P-Stream extension
|
||||
firefoxPolicies = pkgs.writeText "policies.json" (
|
||||
builtins.toJSON {
|
||||
policies = {
|
||||
ExtensionSettings = {
|
||||
# Catppuccin Mocha Mauve (Official)
|
||||
"catppuccin-mocha-mauve-official@catppuccin.com" = {
|
||||
install_url = "https://addons.mozilla.org/firefox/downloads/latest/catppuccin-mocha-mauve-official/latest.xpi";
|
||||
installation_mode = "force_installed";
|
||||
};
|
||||
# P-Stream extension
|
||||
"{de055456-589b-45fe-8342-c685a7ffb424}" = {
|
||||
install_url = "https://github.com/p-stream/extension/releases/download/1.3.5/firefox-mv3-prod.xpi";
|
||||
installation_mode = "force_installed";
|
||||
};
|
||||
};
|
||||
Preferences = {
|
||||
"extensions.activeThemeID" = "catppuccin-mocha-mauve-official@catppuccin.com";
|
||||
"xpinstall.signatures.required" = false;
|
||||
};
|
||||
};
|
||||
|
|
@ -46,112 +22,112 @@ let
|
|||
);
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
firefox-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = prev.firefox;
|
||||
# Omit app.id to avoid document portal bind that fails on FUSE
|
||||
env = {
|
||||
MOZ_ENABLE_WAYLAND = "1";
|
||||
LD_PRELOAD = "";
|
||||
# Propagate XDG_DATA_DIRS so GTK can find themes in user profile/system
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
GTK_THEME = "catppuccin-mocha-mauve-standard";
|
||||
HYPRCURSOR_THEME = "Future-Cyan-Hyprcursor_Theme";
|
||||
HYPRCURSOR_SIZE = "32";
|
||||
options.myModules.firefoxSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Firefox with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
firefox-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = prev.firefox-esr;
|
||||
# Omit app.id to avoid document portal bind that fails on FUSE
|
||||
env = {
|
||||
MOZ_ENABLE_WAYLAND = "1";
|
||||
LD_PRELOAD = "";
|
||||
# Propagate XDG_DATA_DIRS so GTK can find themes in user profile/system
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
GTK_THEME = "catppuccin-mocha-mauve-standard";
|
||||
HYPRCURSOR_THEME = "Future-Cyan-Hyprcursor_Theme";
|
||||
HYPRCURSOR_SIZE = "32";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
flatpak.enable = false;
|
||||
sockets.x11 = false;
|
||||
sockets.wayland = true;
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
flatpak.enable = false;
|
||||
sockets.x11 = false;
|
||||
sockets.wayland = true;
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /mnt"
|
||||
"--tmpfs /run"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/booted-system /run/booted-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
# Removed: --bind "$XDG_RUNTIME_DIR/doc/by-app/..." which causes FUSE errors
|
||||
"--unsetenv LD_PRELOAD"
|
||||
"--setenv MOZ_ENABLE_WAYLAND \"1\""
|
||||
"--setenv NOTIFY_IGNORE_PORTAL 1"
|
||||
"--dir /etc"
|
||||
"--dir /etc/firefox"
|
||||
"--dir /etc/firefox/policies"
|
||||
"--ro-bind ${firefoxPolicies} /etc/firefox/policies/policies.json"
|
||||
];
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (
|
||||
sandboxUtils.mkCommonBindArgs { inherit config lib; }
|
||||
++ sandboxUtils.mkGamingBindArgs { }
|
||||
++ [
|
||||
"--tmpfs /mnt"
|
||||
"--ro-bind-try /run/booted-system /run/booted-system"
|
||||
"--setenv MOZ_ENABLE_WAYLAND \"1\""
|
||||
"--setenv NOTIFY_IGNORE_PORTAL 1"
|
||||
"--dir /etc"
|
||||
"--dir /etc/firefox"
|
||||
"--dir /etc/firefox/policies"
|
||||
"--ro-bind ${firefoxPolicies} /etc/firefox/policies/policies.json"
|
||||
]
|
||||
);
|
||||
|
||||
# Filesystem: Limited to Mozilla directories and Downloads
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.config/user-dirs.dirs"
|
||||
"$HOME/.config/mimeapps.list"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/gtk-3.0"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.mozilla"
|
||||
"$HOME/.cache/mozilla"
|
||||
"$HOME/Downloads"
|
||||
# Filesystem: Limited to Mozilla directories and Downloads
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read ++ [
|
||||
"$HOME/.config/user-dirs.dirs"
|
||||
"$HOME/.config/mimeapps.list"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.mozilla"
|
||||
"$HOME/.cache/mozilla"
|
||||
"$HOME/Downloads"
|
||||
]
|
||||
++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
# Bind mount systemd-resolved socket for DNS and required system files
|
||||
# Disable built-in DBus module because it invokes bwrap without --unshare-user
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user
|
||||
script.preCmds.stage2 = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "nix.bwrapper.firefox";
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.Desktop"''
|
||||
''--talk="org.freedesktop.portal.OpenURI"''
|
||||
''--talk="org.freedesktop.portal.FileChooser"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--own="org.mozilla.firefox"''
|
||||
''--own="org.mozilla.firefox.*"''
|
||||
''--own="org.mpris.MediaPlayer2.firefox.*"''
|
||||
];
|
||||
enableSystemBus = true;
|
||||
systemProxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.NetworkManager"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
''--bind "$XDG_RUNTIME_DIR/app/nix.bwrapper.firefox/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
''--bind "$XDG_RUNTIME_DIR/app/nix.bwrapper.firefox/bus_system" /run/dbus/system_bus_socket''
|
||||
"--bind-try /run/user/${
|
||||
toString config.users.users.${config.myModules.system.mainUser}.uid
|
||||
}/dconf /run/user/${toString config.users.users.${config.myModules.system.mainUser}.uid}/dconf"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
# Bind mount systemd-resolved socket for DNS and required system files
|
||||
# Disable built-in DBus module because it invokes bwrap without --unshare-user
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "nix.bwrapper.firefox";
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.Desktop"''
|
||||
''--talk="org.freedesktop.portal.OpenURI"''
|
||||
''--talk="org.freedesktop.portal.FileChooser"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--own="org.mozilla.firefox"''
|
||||
''--own="org.mozilla.firefox.*"''
|
||||
''--own="org.mpris.MediaPlayer2.firefox.*"''
|
||||
];
|
||||
enableSystemBus = true;
|
||||
systemProxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.NetworkManager"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
''--bind "$XDG_RUNTIME_DIR/app/nix.bwrapper.firefox/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
''--bind "$XDG_RUNTIME_DIR/app/nix.bwrapper.firefox/bus_system" /run/dbus/system_bus_socket''
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
"--bind-try /run/user/${toString config.users.users.ashie.uid}/dconf /run/user/${toString config.users.users.ashie.uid}/dconf"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.firefox-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
"Music"
|
||||
"Pictures"
|
||||
"Videos"
|
||||
"src/aadniz-searxng"
|
||||
"Torrents"
|
||||
"nixos" # Config repo
|
||||
".local/share/PrismLauncher" # Minecraft
|
||||
|
|
@ -71,7 +72,8 @@
|
|||
".config/Antigravity" # Antigravity Config
|
||||
".config/modprobed-db" # Local modconfig database
|
||||
".config/VSCodium" # Codium Config
|
||||
".config/sops" # Sops Keys
|
||||
".config/sops" # Sops keys
|
||||
".config/easyeffects"
|
||||
".config/gh" # Github CLI Auth
|
||||
".local/share/keyrings" # Gnome Keyrings (Passwords)
|
||||
".local/share/nvim" # NeoVim data (LazyVim, Mason, etc.)
|
||||
|
|
@ -91,6 +93,8 @@
|
|||
".local/share/umu"
|
||||
".cache/mesa_shader_cache"
|
||||
# ".local/share/Steam" # Symlinked to /games/Steam (Already Persistent)
|
||||
".paradoxlauncher"
|
||||
".local/share/Paradox Interactive"
|
||||
".steam" # Steam Symlinks and logs
|
||||
".config/steamtinkerlaunch" # Example of extra tools
|
||||
".local/share/applications" # Desktop entries
|
||||
|
|
@ -99,6 +103,11 @@
|
|||
".local/share/qBittorrent"
|
||||
".local/share/jellyfin-desktop"
|
||||
".cache/jellyfin-desktop"
|
||||
".local/share/zoxide"
|
||||
".local/share/fish"
|
||||
"fabric-docs-mcp"
|
||||
];
|
||||
files = [
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ in
|
|||
"vsyscall=none"
|
||||
"oops=panic"
|
||||
"module.sig_enforce=1"
|
||||
"amd_iommu=on"
|
||||
"mitigations=auto"
|
||||
"lockdown=confidentiality"
|
||||
];
|
||||
|
||||
# Kernel sysctl hardening
|
||||
|
|
|
|||
|
|
@ -9,136 +9,141 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.lutrisSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
lutris-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = prev.lutris.override {
|
||||
extraPkgs = pkgs: [
|
||||
pkgs.curl
|
||||
pkgs.wget
|
||||
pkgs.gnutar
|
||||
pkgs.gzip
|
||||
pkgs.zstd
|
||||
pkgs.xz
|
||||
pkgs.p7zip
|
||||
pkgs.which
|
||||
pkgs.file
|
||||
pkgs.zenity
|
||||
pkgs.vulkan-loader
|
||||
pkgs.vulkan-tools
|
||||
pkgs.unzip
|
||||
pkgs.cabextract
|
||||
pkgs.pciutils
|
||||
pkgs.gamemode.lib
|
||||
pkgs.xdg-utils
|
||||
options.myModules.lutrisSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Lutris with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
lutris-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = prev.lutris.override {
|
||||
extraPkgs = pkgs: [
|
||||
pkgs.curl
|
||||
pkgs.wget
|
||||
pkgs.gnutar
|
||||
pkgs.gzip
|
||||
pkgs.zstd
|
||||
pkgs.xz
|
||||
pkgs.p7zip
|
||||
pkgs.which
|
||||
pkgs.file
|
||||
pkgs.zenity
|
||||
pkgs.vulkan-loader
|
||||
pkgs.vulkan-tools
|
||||
pkgs.unzip
|
||||
pkgs.cabextract
|
||||
pkgs.pciutils
|
||||
pkgs.gamemode.lib
|
||||
pkgs.xdg-utils
|
||||
pkgs.umu-launcher
|
||||
pkgs.sdl3
|
||||
];
|
||||
};
|
||||
isFhsenv = true;
|
||||
id = "net.lutris.Lutris";
|
||||
env = {
|
||||
WEBKIT_DISABLE_DMABUF_RENDERER = 1;
|
||||
APPIMAGE_EXTRACT_AND_RUN = 1;
|
||||
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION = "python";
|
||||
GTK_THEME = "catppuccin-mocha-blue-standard";
|
||||
BROWSER = "xdg-open";
|
||||
XDG_CURRENT_DESKTOP = "niri";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=$XDG_RUNTIME_DIR/bus";
|
||||
VK_ICD_FILENAMES = "/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json:/run/opengl-driver-32/share/vulkan/icd.d/radeon_icd.i686.json";
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
};
|
||||
};
|
||||
|
||||
fhsenv = {
|
||||
skipExtraInstallCmds = false;
|
||||
};
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
# Filesystem: Limited to Games directory
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read ++ [
|
||||
"$HOME/.local/share/Steam/compatibilitytools.d"
|
||||
"/data/Torrents/Games" # Repack installers
|
||||
];
|
||||
|
||||
readWrite = [
|
||||
"$HOME/Games/windows"
|
||||
"$HOME/Games/linux"
|
||||
"$HOME/.local/share/icons"
|
||||
"$HOME/.config/lutris"
|
||||
"$HOME/.local/share/lutris"
|
||||
"$HOME/.cache/lutris"
|
||||
"$HOME/.steam"
|
||||
"$HOME/.local/share/steam"
|
||||
"$HOME/.local/share/umu"
|
||||
"$HOME/.local/share/applications"
|
||||
"$HOME/.local/share/desktop-directories"
|
||||
]
|
||||
++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
# Bind mount systemd-resolved socket directory to fix DNS
|
||||
# The sandbox mounts a tmpfs on /run, so we need to validly expose this
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (
|
||||
sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { }
|
||||
);
|
||||
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus session proxy
|
||||
''--bind "$XDG_RUNTIME_DIR/app/net.lutris.Lutris/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
# D-Bus system proxy
|
||||
''--bind "$XDG_RUNTIME_DIR/app/net.lutris.Lutris/bus_system" /run/dbus/system_bus_socket''
|
||||
|
||||
# Bind system themes to /usr/share
|
||||
"--ro-bind /run/current-system/sw/share/themes /usr/share/themes"
|
||||
"--ro-bind /run/current-system/sw/share/icons /usr/share/icons"
|
||||
];
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user
|
||||
script.preCmds.stage2 = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "net.lutris.Lutris";
|
||||
enableSystemBus = true;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.Flatpak"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--own="net.lutris.Lutris"''
|
||||
];
|
||||
systemProxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.UDisks2"'' # Disk detection
|
||||
];
|
||||
};
|
||||
isFhsenv = true;
|
||||
id = "net.lutris.Lutris";
|
||||
env = {
|
||||
WEBKIT_DISABLE_DMABUF_RENDERER = 1;
|
||||
APPIMAGE_EXTRACT_AND_RUN = 1;
|
||||
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION = "python";
|
||||
GTK_THEME = "catppuccin-mocha-blue-standard";
|
||||
BROWSER = "xdg-open";
|
||||
XDG_CURRENT_DESKTOP = "niri";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=$XDG_RUNTIME_DIR/bus";
|
||||
VK_ICD_FILENAMES = "/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json:/run/opengl-driver-32/share/vulkan/icd.d/radeon_icd.i686.json";
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
fhsenv = {
|
||||
skipExtraInstallCmds = false;
|
||||
};
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
# Filesystem: Limited to Games directory
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
"$HOME/.local/share/Steam/compatibilitytools.d"
|
||||
"$HOME/.config/gtk-3.0"
|
||||
"$HOME/.config/gtk-4.0"
|
||||
"$HOME/.icons"
|
||||
"/data/Torrents/Games" # Repack installers
|
||||
];
|
||||
|
||||
readWrite = [
|
||||
"$HOME/Games/windows"
|
||||
"$HOME/.local/share/icons"
|
||||
"$HOME/.config/lutris"
|
||||
"$HOME/.local/share/lutris"
|
||||
"$HOME/.cache/lutris"
|
||||
"$HOME/.steam"
|
||||
"$HOME/.local/share/steam"
|
||||
"$HOME/.local/share/umu"
|
||||
"$HOME/.local/share/applications"
|
||||
"$HOME/.local/share/desktop-directories"
|
||||
];
|
||||
};
|
||||
|
||||
# Bind mount systemd-resolved socket directory to fix DNS
|
||||
# The sandbox mounts a tmpfs on /run, so we need to validly expose this
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
# D-Bus session proxy
|
||||
''--bind "$XDG_RUNTIME_DIR/app/net.lutris.Lutris/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
# D-Bus system proxy
|
||||
''--bind "$XDG_RUNTIME_DIR/app/net.lutris.Lutris/bus_system" /run/dbus/system_bus_socket''
|
||||
# Wayland socket
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
# PipeWire + Pulse
|
||||
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
|
||||
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
|
||||
|
||||
# Hardware access
|
||||
"--dev-bind /dev/dri /dev/dri"
|
||||
"--dev-bind /dev/shm /dev/shm"
|
||||
"--ro-bind /sys /sys"
|
||||
|
||||
# Bind system themes to /usr/share
|
||||
"--ro-bind /run/current-system/sw/share/themes /usr/share/themes"
|
||||
"--ro-bind /run/current-system/sw/share/icons /usr/share/icons"
|
||||
# OpenGL/Vulkan drivers
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
];
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "net.lutris.Lutris";
|
||||
enableSystemBus = true;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.Flatpak"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--own="net.lutris.Lutris"''
|
||||
];
|
||||
systemProxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.UDisks2"'' # Disk detection
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.lutris-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
}:
|
||||
|
||||
let
|
||||
# Define the user and group consistently
|
||||
user = "ashie";
|
||||
cfg = config.myModules.media;
|
||||
user = config.myModules.system.mainUser;
|
||||
group = "users";
|
||||
puid = "1000";
|
||||
pgid = "100";
|
||||
puid = toString config.users.users.${user}.uid;
|
||||
pgid = "100"; # GID for 'users' group
|
||||
|
||||
# Common env vars to avoid repetition
|
||||
commonEnv = {
|
||||
|
|
@ -20,183 +20,202 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
# 1. Enable Podman (required backend)
|
||||
virtualisation = {
|
||||
podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
};
|
||||
oci-containers.backend = "podman";
|
||||
options.myModules.media = {
|
||||
enable = lib.mkEnableOption "media server stack (Arr suite + Jellyfin)";
|
||||
};
|
||||
|
||||
# 2. Container Definitions
|
||||
virtualisation.oci-containers.containers = {
|
||||
config = lib.mkIf cfg.enable {
|
||||
# 1. Enable Podman (required backend)
|
||||
myModules.podman.enable = true;
|
||||
virtualisation.podman.autoPrune.enable = true;
|
||||
|
||||
# --- VPN Gateway ---
|
||||
vpn = {
|
||||
image = "docker.io/qmcgaw/gluetun";
|
||||
# The VPN manages the ports for the attached containers
|
||||
ports = [
|
||||
"8080:8080" # qBittorrent WebUI
|
||||
"36630:36630" # Torrent Port TCP
|
||||
"36630:36630/udp"
|
||||
"9696:9696" # Prowlarr
|
||||
"8191:8191" # Flaresolverr
|
||||
];
|
||||
environmentFiles = [ config.sops.templates."gluetun.env".path ];
|
||||
environment = {
|
||||
TZ = "Europe/Berlin";
|
||||
DOT = "off"; # DNS over TLS off (optional)
|
||||
FIREWALL_OUTBOUND_SUBNETS = "10.89.0.0/24"; # Allow access to local docker network
|
||||
FIREWALL_VPN_INPUT_PORTS = "36630"; # Allow incoming torrent traffic
|
||||
# 2. Container Definitions
|
||||
virtualisation.oci-containers.containers = {
|
||||
|
||||
# --- VPN Gateway ---
|
||||
vpn = {
|
||||
image = "docker.io/qmcgaw/gluetun";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
# The VPN manages the ports for the attached containers
|
||||
ports = [
|
||||
"127.0.0.1:8080:8080" # qBittorrent WebUI (Localhost only)
|
||||
"36630:36630" # Torrent Port TCP (Public)
|
||||
"36630:36630/udp" # Torrent Port UDP (Public)
|
||||
"127.0.0.1:8191:8191" # Flaresolverr (Localhost only)
|
||||
"127.0.0.1:9696:9696" # Prowlarr (Localhost only)
|
||||
];
|
||||
environmentFiles = [ config.sops.templates."gluetun.env".path ];
|
||||
environment = {
|
||||
TZ = "Europe/Berlin";
|
||||
DOT = "off"; # DNS over TLS off (optional)
|
||||
FIREWALL_OUTBOUND_SUBNETS = "10.89.0.0/24"; # Allow access to local docker network
|
||||
FIREWALL_VPN_INPUT_PORTS = "36630"; # Allow incoming torrent traffic
|
||||
};
|
||||
extraOptions = [
|
||||
"--cap-add=NET_ADMIN"
|
||||
"--cap-add=NET_RAW"
|
||||
"--device=/dev/net/tun:/dev/net/tun"
|
||||
"--network=media" # It joins the bridge so others can talk to it
|
||||
"--ip=10.89.0.5" # Static IP for VPN/Flaresolverr
|
||||
"--network-alias=flaresolverr" # Allow other containers to reach Flaresolverr via VPN
|
||||
"--add-host=sonarr:10.89.0.50" # Allow Prowlarr to reach Sonarr
|
||||
"--add-host=radarr:10.89.0.51" # Allow Prowlarr to reach Radarr
|
||||
"--add-host=prowlarr:127.0.0.1" # Prowlarr matches VPN IP for self-reference if needed
|
||||
];
|
||||
};
|
||||
extraOptions = [
|
||||
"--cap-add=NET_ADMIN"
|
||||
"--cap-add=NET_RAW"
|
||||
"--device=/dev/net/tun:/dev/net/tun"
|
||||
"--network=media" # It joins the bridge so others can talk to it
|
||||
"--network-alias=prowlarr" # Allow other containers to reach Prowlarr via VPN
|
||||
"--network-alias=flaresolverr" # Allow other containers to reach Flaresolverr via VPN
|
||||
"--add-host=sonarr:10.89.0.50" # Allow Prowlarr to reach Sonarr
|
||||
"--add-host=radarr:10.89.0.51" # Allow Prowlarr to reach Radarr
|
||||
];
|
||||
};
|
||||
|
||||
# --- Torrent Client (Routed via VPN) ---
|
||||
torrent = {
|
||||
image = "lscr.io/linuxserver/qbittorrent:latest";
|
||||
# VITAL: Reuse the VPN container's network stack
|
||||
extraOptions = [ "--network=container:vpn" ];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = commonEnv // {
|
||||
WEBUI_PORT = "8080";
|
||||
# --- Torrent Client (Routed via VPN) ---
|
||||
torrent = {
|
||||
image = "lscr.io/linuxserver/qbittorrent:latest";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
# VITAL: Reuse the VPN container's network stack
|
||||
extraOptions = [ "--network=container:vpn" ];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = commonEnv // {
|
||||
WEBUI_PORT = "8080";
|
||||
};
|
||||
volumes = [
|
||||
"/var/lib/qbittorrent:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
volumes = [
|
||||
"/var/lib/qbittorrent:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
|
||||
# --- The Arr Stack ---
|
||||
prowlarr = {
|
||||
image = "lscr.io/linuxserver/prowlarr:latest";
|
||||
extraOptions = [
|
||||
"--network=container:vpn"
|
||||
];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = commonEnv;
|
||||
volumes = [ "/var/lib/nixarr/prowlarr:/config" ];
|
||||
};
|
||||
# --- The Arr Stack ---
|
||||
prowlarr = {
|
||||
image = "lscr.io/linuxserver/prowlarr:latest";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
extraOptions = [
|
||||
"--network=container:vpn"
|
||||
];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = commonEnv;
|
||||
volumes = [ "/var/lib/nixarr/prowlarr:/config" ];
|
||||
};
|
||||
|
||||
sonarr = {
|
||||
image = "lscr.io/linuxserver/sonarr:latest";
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--ip=10.89.0.50"
|
||||
];
|
||||
ports = [ "8989:8989" ];
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/sonarr:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
sonarr = {
|
||||
image = "lscr.io/linuxserver/sonarr:latest";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--ip=10.89.0.50"
|
||||
"--dns=8.8.8.8"
|
||||
"--add-host=qbittorrent:10.89.0.5"
|
||||
"--add-host=prowlarr:10.89.0.5"
|
||||
];
|
||||
ports = [ "127.0.0.1:8989:8989" ];
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/sonarr:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
|
||||
radarr = {
|
||||
image = "lscr.io/linuxserver/radarr:latest";
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--ip=10.89.0.51"
|
||||
];
|
||||
ports = [ "7878:7878" ];
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/radarr:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
radarr = {
|
||||
image = "lscr.io/linuxserver/radarr:latest";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--ip=10.89.0.51"
|
||||
"--dns=8.8.8.8"
|
||||
"--add-host=qbittorrent:10.89.0.5"
|
||||
"--add-host=prowlarr:10.89.0.5"
|
||||
];
|
||||
ports = [ "127.0.0.1:7878:7878" ];
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/radarr:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
|
||||
# --- Media Server ---
|
||||
jellyfin = {
|
||||
image = "lscr.io/linuxserver/jellyfin:latest";
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--device=/dev/dri:/dev/dri"
|
||||
];
|
||||
ports = [ "8096:8096" ];
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/jellyfin:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
# --- Media Server ---
|
||||
jellyfin = {
|
||||
image = "lscr.io/linuxserver/jellyfin:latest";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--device=/dev/dri:/dev/dri"
|
||||
"--dns=8.8.8.8"
|
||||
"--ip=10.89.0.4"
|
||||
];
|
||||
ports = [ "127.0.0.1:8096:8096" ];
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/jellyfin:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
|
||||
jellyseerr = {
|
||||
image = "ghcr.io/fallenbagel/jellyseerr:latest";
|
||||
extraOptions = [ "--network=media" ];
|
||||
ports = [ "5055:5055" ];
|
||||
environment = commonEnv;
|
||||
volumes = [ "/var/lib/nixarr/jellyseerr:/app/config" ];
|
||||
};
|
||||
jellyseerr = {
|
||||
image = "ghcr.io/seerr-team/seerr:latest"; # Migrated from jellyseerr (stale) to seerr (v3+)
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
extraOptions = [
|
||||
"--init" # Required for Seerr
|
||||
"--network=media"
|
||||
"--dns=8.8.8.8"
|
||||
"--ip=10.89.0.3"
|
||||
"--add-host=sonarr:10.89.0.50"
|
||||
"--add-host=radarr:10.89.0.51"
|
||||
"--add-host=jellyfin:10.89.0.4"
|
||||
];
|
||||
ports = [ "127.0.0.1:5055:5055" ];
|
||||
environment = commonEnv;
|
||||
volumes = [ "/var/lib/nixarr/jellyseerr:/app/config" ];
|
||||
};
|
||||
|
||||
flaresolverr = {
|
||||
image = "ghcr.io/flaresolverr/flaresolverr:latest";
|
||||
extraOptions = [ "--network=container:vpn" ];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = {
|
||||
TZ = "Europe/Berlin";
|
||||
flaresolverr = {
|
||||
image = "ghcr.io/flaresolverr/flaresolverr:latest";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
extraOptions = [ "--network=container:vpn" ];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = {
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# 3. Network Setup (Fixed)
|
||||
# Ensure the network is created before ANY container starts
|
||||
systemd.services.create-media-network = {
|
||||
script = ''
|
||||
${pkgs.podman}/bin/podman network exists media || ${pkgs.podman}/bin/podman network create --subnet 10.89.0.0/24 media
|
||||
'';
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
# Removed 'User = ashie' -> Networks created by root are visible to root services
|
||||
};
|
||||
};
|
||||
|
||||
# Ensure containers wait for the network
|
||||
systemd.services."podman-vpn".requires = [ "create-media-network.service" ];
|
||||
systemd.services."podman-vpn".after = [ "create-media-network.service" ];
|
||||
# (Repeat for others if they don't depend on VPN, but usually unnecessary if they all join 'media')
|
||||
|
||||
# 4. Permissions
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /data 0775 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/prowlarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/sonarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/radarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/jellyfin 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/jellyseerr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/qbittorrent 0755 ${user} ${group} - -"
|
||||
];
|
||||
|
||||
users.users.${user}.extraGroups = [ "media" ];
|
||||
|
||||
# 5. Firewall
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
36630
|
||||
9696
|
||||
];
|
||||
networking.firewall.allowedUDPPorts = [
|
||||
36630
|
||||
443
|
||||
];
|
||||
};
|
||||
|
||||
# 3. Network Setup (Fixed)
|
||||
# Ensure the network is created before ANY container starts
|
||||
systemd.services.create-media-network = {
|
||||
script = ''
|
||||
${pkgs.podman}/bin/podman network exists media || ${pkgs.podman}/bin/podman network create media
|
||||
'';
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
# Removed 'User = ashie' -> Networks created by root are visible to root services
|
||||
};
|
||||
};
|
||||
|
||||
# Ensure containers wait for the network
|
||||
systemd.services."podman-vpn".requires = [ "create-media-network.service" ];
|
||||
systemd.services."podman-vpn".after = [ "create-media-network.service" ];
|
||||
# (Repeat for others if they don't depend on VPN, but usually unnecessary if they all join 'media')
|
||||
|
||||
# 4. Permissions
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /data 0775 ${user} media - -"
|
||||
"d /var/lib/nixarr/prowlarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/sonarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/radarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/jellyfin 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/jellyseerr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/qbittorrent 0755 ${user} ${group} - -"
|
||||
];
|
||||
|
||||
users.users.${user}.extraGroups = [ "media" ];
|
||||
|
||||
# 5. Firewall
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
9696
|
||||
8989
|
||||
7878
|
||||
8096
|
||||
5055
|
||||
8080
|
||||
36630
|
||||
8082
|
||||
8191
|
||||
];
|
||||
networking.firewall.allowedUDPPorts = [
|
||||
36630
|
||||
443
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ in
|
|||
];
|
||||
ExecStart = ''
|
||||
${pkgs.podman}/bin/podman run --rm --name ollama \
|
||||
--label "io.containers.autoupdate=registry" \
|
||||
--network=antigravity-net \
|
||||
--network-alias=ollama \
|
||||
--dns=8.8.8.8 \
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ in
|
|||
];
|
||||
ExecStart = ''
|
||||
${pkgs.podman}/bin/podman run --rm --name open-webui \
|
||||
--label "io.containers.autoupdate=registry" \
|
||||
--network=antigravity-net \
|
||||
--dns=8.8.8.8 \
|
||||
--userns=auto \
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.prismlauncherSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
|
||||
# Libraries required by Minecraft natives (LWJGL), various mods,
|
||||
# and the Microsoft authentication flow (NSS/NSPR).
|
||||
|
|
@ -48,153 +50,137 @@ let
|
|||
];
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
prismlauncher-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
id = "org.prismlauncher.PrismLauncher";
|
||||
package = pkgs.prismlauncher.overrideAttrs (old: {
|
||||
pname = "prismlauncher";
|
||||
version = old.version or "9.1";
|
||||
buildInputs = (old.buildInputs or [ ]) ++ [ pkgs.mimalloc ];
|
||||
options.myModules.prismlauncherSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed PrismLauncher with nix-bwrapper";
|
||||
|
||||
# Keep runtimeLibs in closure without injecting them into environment
|
||||
postInstall = (old.postInstall or "") + ''
|
||||
mkdir -p $out/share/prismlauncher-sandboxed
|
||||
echo "${lib.makeLibraryPath runtimeLibs}" > $out/share/prismlauncher-sandboxed/libs
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
prismlauncher-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
id = "org.prismlauncher.PrismLauncher";
|
||||
package = pkgs.prismlauncher.overrideAttrs (old: {
|
||||
pname = "prismlauncher";
|
||||
version = old.version or "9.1";
|
||||
buildInputs = (old.buildInputs or [ ]) ++ [ pkgs.mimalloc ];
|
||||
|
||||
# Keep runtimeLibs in closure without injecting them into environment
|
||||
postInstall = (old.postInstall or "") + ''
|
||||
mkdir -p $out/share/prismlauncher-sandboxed
|
||||
echo "${lib.makeLibraryPath runtimeLibs}" > $out/share/prismlauncher-sandboxed/libs
|
||||
'';
|
||||
|
||||
qtWrapperArgs = (old.qtWrapperArgs or [ ]) ++ [
|
||||
"--set MIMALLOC_PATH ${pkgs.mimalloc}/lib/libmimalloc.so"
|
||||
"--prefix LD_PRELOAD : ${pkgs.mimalloc}/lib/libmimalloc.so"
|
||||
];
|
||||
});
|
||||
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS so themes/icons can be found
|
||||
# XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
BROWSER = "firefox";
|
||||
QT_QPA_PLATFORMTHEME = "";
|
||||
QT_STYLE_OVERRIDE = "fusion";
|
||||
};
|
||||
};
|
||||
|
||||
sockets.x11 = true; # Old versions of minecraft require X11, and forge still doesnt care its breaking wayland.
|
||||
sockets.wayland = true;
|
||||
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { } ++ [
|
||||
"--ro-bind /run/dbus /run/dbus"
|
||||
]);
|
||||
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read ++ [
|
||||
"$HOME/Downloads"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.local/share/PrismLauncher"
|
||||
"$HOME/.cache/PrismLauncher"
|
||||
] ++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
dbus.enable = false;
|
||||
|
||||
script.preCmds.stage2 =
|
||||
let
|
||||
jvmArgs = "-XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+UseNUMA -XX:NmethodSweepActivity=1 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:-DontCompileHugeMethods -XX:MaxNodeLimit=240000 -XX:NodeLimitFudgeFactor=8000 -XX:+UseVectorCmov -XX:+PerfDisableSharedMem -XX:+UseFastUnorderedTimeStamps -XX:+UseCriticalJavaThreadPriority -XX:ThreadPriorityPolicy=1 -XX:AllocatePrefetchStyle=3 -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000 -XX:AllocatePrefetchStyle=1 -XX:ConcGCThreads=4";
|
||||
glfwPath = "${pkgs.glfw}/lib/libglfw.so.3";
|
||||
|
||||
dbusScript = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "org.prismlauncher.PrismLauncher";
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--own="org.prismlauncher.PrismLauncher"''
|
||||
''--own="org.prismlauncher.PrismLauncher.*"''
|
||||
];
|
||||
};
|
||||
in
|
||||
''
|
||||
${dbusScript}
|
||||
|
||||
# Force Configs (JVM Args + GLFW)
|
||||
cfg="$HOME/.local/share/PrismLauncher/prismlauncher.cfg"
|
||||
if [ -f "$cfg" ]; then
|
||||
# JVM Args
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^JvmArgs=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^JvmArgs=.*|JvmArgs=${jvmArgs}|" "$cfg"
|
||||
else
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^\[General\]" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "/^\[General\]/a JvmArgs=${jvmArgs}" "$cfg"
|
||||
else
|
||||
echo "JvmArgs=${jvmArgs}" >> "$cfg"
|
||||
fi
|
||||
fi
|
||||
|
||||
# GLFW Settings
|
||||
# 1. CustomGLFWPath
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^CustomGLFWPath=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^CustomGLFWPath=.*|CustomGLFWPath=${glfwPath}|" "$cfg"
|
||||
else
|
||||
echo "CustomGLFWPath=${glfwPath}" >> "$cfg"
|
||||
fi
|
||||
|
||||
# 2. UseNativeGLFW
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^UseNativeGLFW=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^UseNativeGLFW=.*|UseNativeGLFW=true|" "$cfg"
|
||||
else
|
||||
echo "UseNativeGLFW=true" >> "$cfg"
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
|
||||
qtWrapperArgs = (old.qtWrapperArgs or [ ]) ++ [
|
||||
"--set MIMALLOC_PATH ${pkgs.mimalloc}/lib/libmimalloc.so"
|
||||
"--prefix LD_PRELOAD : ${pkgs.mimalloc}/lib/libmimalloc.so"
|
||||
];
|
||||
});
|
||||
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS so themes/icons can be found
|
||||
# XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
BROWSER = "firefox";
|
||||
QT_QPA_PLATFORMTHEME = "";
|
||||
QT_STYLE_OVERRIDE = "fusion";
|
||||
};
|
||||
};
|
||||
|
||||
sockets.x11 = true; # Old versions of minecraft require X11, and forge still doesnt care its breaking wayland.
|
||||
sockets.wayland = true;
|
||||
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.ashie.uid}"
|
||||
# Bind ro system paths commonly needed
|
||||
# "--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
"--ro-bind /run/dbus /run/dbus"
|
||||
];
|
||||
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/qt6ct"
|
||||
"$HOME/.config/Kvantum"
|
||||
"$HOME/.config/MangoHud"
|
||||
"$HOME/Downloads"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.local/share/PrismLauncher"
|
||||
"$HOME/.cache/PrismLauncher"
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus proxy
|
||||
''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
dbus.enable = false;
|
||||
|
||||
script.preCmds.stage2 =
|
||||
let
|
||||
jvmArgs = "-XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+UseNUMA -XX:NmethodSweepActivity=1 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:-DontCompileHugeMethods -XX:MaxNodeLimit=240000 -XX:NodeLimitFudgeFactor=8000 -XX:+UseVectorCmov -XX:+PerfDisableSharedMem -XX:+UseFastUnorderedTimeStamps -XX:+UseCriticalJavaThreadPriority -XX:ThreadPriorityPolicy=1 -XX:AllocatePrefetchStyle=3 -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000 -XX:AllocatePrefetchStyle=1 -XX:ConcGCThreads=4";
|
||||
glfwPath = "${pkgs.glfw}/lib/libglfw.so.3";
|
||||
|
||||
dbusScript = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "org.prismlauncher.PrismLauncher";
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--own="org.prismlauncher.PrismLauncher"''
|
||||
''--own="org.prismlauncher.PrismLauncher.*"''
|
||||
];
|
||||
};
|
||||
in
|
||||
''
|
||||
${dbusScript}
|
||||
|
||||
# Force Configs (JVM Args + GLFW)
|
||||
cfg="$HOME/.local/share/PrismLauncher/prismlauncher.cfg"
|
||||
if [ -f "$cfg" ]; then
|
||||
# JVM Args
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^JvmArgs=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^JvmArgs=.*|JvmArgs=${jvmArgs}|" "$cfg"
|
||||
else
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^\[General\]" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "/^\[General\]/a JvmArgs=${jvmArgs}" "$cfg"
|
||||
else
|
||||
echo "JvmArgs=${jvmArgs}" >> "$cfg"
|
||||
fi
|
||||
fi
|
||||
|
||||
# GLFW Settings
|
||||
# 1. CustomGLFWPath
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^CustomGLFWPath=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^CustomGLFWPath=.*|CustomGLFWPath=${glfwPath}|" "$cfg"
|
||||
else
|
||||
echo "CustomGLFWPath=${glfwPath}" >> "$cfg"
|
||||
fi
|
||||
|
||||
# 2. UseNativeGLFW
|
||||
if ${pkgs.gnugrep}/bin/grep -q "^UseNativeGLFW=" "$cfg"; then
|
||||
${pkgs.gnused}/bin/sed -i "s|^UseNativeGLFW=.*|UseNativeGLFW=true|" "$cfg"
|
||||
else
|
||||
echo "UseNativeGLFW=true" >> "$cfg"
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus proxy
|
||||
''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Wayland socket
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
|
||||
# PipeWire + Pulse (PipeWire hosts both)
|
||||
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
|
||||
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.prismlauncher-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
let
|
||||
cfg = config.myModules.redlib;
|
||||
mainUser = config.myModules.system.mainUser;
|
||||
mainUserUid = toString config.users.users.${mainUser}.uid;
|
||||
in
|
||||
{
|
||||
options.myModules.redlib = {
|
||||
|
|
@ -34,6 +36,7 @@ in
|
|||
# Redlib Container
|
||||
virtualisation.oci-containers.containers."redlib" = {
|
||||
image = "quay.io/redlib/redlib:latest";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
# ports = [ "127.0.0.1:${toString cfg.port}:8080" ]; # Port exposed via VPN
|
||||
extraOptions = [
|
||||
"--pull=always"
|
||||
|
|
@ -44,20 +47,20 @@ in
|
|||
};
|
||||
|
||||
# Rootless Overrides
|
||||
systemd.services."podman-redlib".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-redlib".serviceConfig.User = lib.mkForce mainUser;
|
||||
systemd.services."podman-redlib".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
HOME = "/home/${mainUser}";
|
||||
XDG_RUNTIME_DIR = "/run/user/${mainUserUid}";
|
||||
};
|
||||
systemd.services."podman-redlib".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-redlib".serviceConfig.Delegate = true;
|
||||
systemd.services."podman-redlib".after = [
|
||||
"user-runtime-dir@1000.service"
|
||||
"user-runtime-dir@${mainUserUid}.service"
|
||||
"podman-vpn.service"
|
||||
];
|
||||
systemd.services."podman-redlib".requires = [
|
||||
"user-runtime-dir@1000.service"
|
||||
"user-runtime-dir@${mainUserUid}.service"
|
||||
"podman-vpn.service"
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -7,122 +7,114 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.ryubingSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
|
||||
appId = "org.ryubing.Ryubing";
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
ryubing-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = pkgs.ryubing;
|
||||
id = appId;
|
||||
env = {
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
# Ryubing uses Avalonia which works better with X11
|
||||
AVALONIA_SCREEN_SCALE_FACTOR = "1";
|
||||
options.myModules.ryubingSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Ryubing with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
ryubing-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = pkgs.ryubing;
|
||||
id = appId;
|
||||
env = {
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
# Ryubing uses Avalonia which works better with X11
|
||||
AVALONIA_SCREEN_SCALE_FACTOR = "1";
|
||||
};
|
||||
};
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network for online features
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { } ++ [
|
||||
# Fix for amdgpu.ids missing - use tmpfs so mkdir can succeed
|
||||
"--tmpfs /usr/share"
|
||||
"--ro-bind ${pkgs.libdrm}/share/libdrm /usr/share/libdrm"
|
||||
"--ro-bind-try /nix/store /nix/store"
|
||||
]);
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
# Also create required directories before bwrap runs
|
||||
script.preCmds.stage2 = ''
|
||||
# Create directories that bwrap will bind
|
||||
# Note: Ryubing still uses Ryujinx config paths
|
||||
mkdir -p "$HOME/.config/Ryujinx/system"
|
||||
mkdir -p "$HOME/.config/Ryujinx/bis/system/Contents/registered"
|
||||
mkdir -p "$HOME/.local/share/Ryujinx"
|
||||
mkdir -p "$HOME/Games/Switch"
|
||||
''
|
||||
+ sandboxUtils.mkDbusProxyScript {
|
||||
inherit appId;
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.Desktop"''
|
||||
''--talk="org.freedesktop.portal.OpenURI"''
|
||||
''--talk="org.freedesktop.portal.FileChooser"''
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--own="${appId}"''
|
||||
''--own="${appId}.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Read-write mounts
|
||||
"--bind $HOME/Games/Switch $HOME/Games/Switch"
|
||||
"--bind $HOME/.config/Ryujinx $HOME/.config/Ryujinx"
|
||||
"--bind $HOME/.local/share/Ryujinx $HOME/.local/share/Ryujinx"
|
||||
];
|
||||
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read;
|
||||
readWrite = cfg.extraBindMounts;
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network for online features
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri" # GPU acceleration
|
||||
"--dev-bind /dev/shm /dev/shm" # Shared memory
|
||||
"--dev-bind-try /dev/uinput /dev/uinput" # Controller support
|
||||
"--dev-bind-try /dev/input /dev/input"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.ashie.uid}"
|
||||
# Fix for amdgpu.ids missing - use tmpfs so mkdir can succeed
|
||||
"--tmpfs /usr/share"
|
||||
"--ro-bind ${pkgs.libdrm}/share/libdrm /usr/share/libdrm"
|
||||
# System paths
|
||||
"--ro-bind /sys /sys"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--ro-bind-try /nix/store /nix/store"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
# udev for controller hotplug
|
||||
"--ro-bind-try /run/udev /run/udev"
|
||||
];
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
# Also create required directories before bwrap runs
|
||||
script.preCmds.stage2 = ''
|
||||
# Create directories that bwrap will bind
|
||||
# Note: Ryubing still uses Ryujinx config paths
|
||||
mkdir -p "$HOME/.config/Ryujinx/system"
|
||||
mkdir -p "$HOME/.config/Ryujinx/bis/system/Contents/registered"
|
||||
mkdir -p "$HOME/.local/share/Ryujinx"
|
||||
mkdir -p "$HOME/Games/Switch"
|
||||
''
|
||||
+ (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
inherit appId;
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.Desktop"''
|
||||
''--talk="org.freedesktop.portal.OpenURI"''
|
||||
''--talk="org.freedesktop.portal.FileChooser"''
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--own="${appId}"''
|
||||
''--own="${appId}.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Manual mounts for data persistence
|
||||
"--ro-bind-try $HOME/.config/kdedefaults $HOME/.config/kdedefaults"
|
||||
"--ro-bind-try $HOME/.local/share/color-schemes $HOME/.local/share/color-schemes"
|
||||
"--ro-bind-try $HOME/.config/fontconfig $HOME/.config/fontconfig"
|
||||
"--ro-bind-try $HOME/.local/share/fonts $HOME/.local/share/fonts"
|
||||
"--ro-bind-try $HOME/.icons $HOME/.icons"
|
||||
"--ro-bind-try $HOME/.themes $HOME/.themes"
|
||||
"--ro-bind-try $HOME/.config/MangoHud $HOME/.config/MangoHud"
|
||||
# Read-write mounts
|
||||
"--bind $HOME/Games/Switch $HOME/Games/Switch"
|
||||
"--bind $HOME/.config/Ryujinx $HOME/.config/Ryujinx"
|
||||
"--bind $HOME/.local/share/Ryujinx $HOME/.local/share/Ryujinx"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.ryubing-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,91 +1,311 @@
|
|||
{ pkgs, lib }:
|
||||
{
|
||||
|
||||
let
|
||||
# Generates the shell script content to set up xdg-dbus-proxy inside a bwrap user namespace.
|
||||
# This is used for sandboxed apps that run with unshareUser = true.
|
||||
mkDbusProxyScript = {
|
||||
appId, # Unique ID for the app (e.g. "org.mozilla.firefox")
|
||||
proxyArgs, # Arguments for xdg-dbus-proxy (session bus). Can be string or list.
|
||||
socketPath ? "$XDG_RUNTIME_DIR/app/${appId}/bus",
|
||||
upstreamSocket ? "$XDG_RUNTIME_DIR/bus",
|
||||
enableSystemBus ? false,
|
||||
systemProxyArgs ? "", # Arguments for xdg-dbus-proxy (system bus). Can be string or list.
|
||||
systemSocketPath ? "$XDG_RUNTIME_DIR/app/${appId}/bus_system",
|
||||
systemUpstreamSocket ? "/run/dbus/system_bus_socket"
|
||||
}:
|
||||
let
|
||||
bwrap = "${pkgs.bubblewrap}/bin/bwrap";
|
||||
dbusProxy = "${pkgs.xdg-dbus-proxy}/bin/xdg-dbus-proxy";
|
||||
coreutils = "${pkgs.coreutils}/bin";
|
||||
|
||||
# Helper to normalize args (support list or string)
|
||||
normalizeArgs = args: if builtins.isList args then lib.concatStringsSep " " args else args;
|
||||
pArgs = normalizeArgs proxyArgs;
|
||||
sArgs = normalizeArgs systemProxyArgs;
|
||||
mkDbusProxyScript =
|
||||
{
|
||||
appId,
|
||||
# Unique ID for the app (e.g. "org.mozilla.firefox")
|
||||
proxyArgs, # Arguments for xdg-dbus-proxy (session bus). Can be string or list.
|
||||
socketPath ? "$XDG_RUNTIME_DIR/app/${appId}/bus",
|
||||
upstreamSocket ? "$XDG_RUNTIME_DIR/bus",
|
||||
enableSystemBus ? false,
|
||||
systemProxyArgs ? "", # Arguments for xdg-dbus-proxy (system bus). Can be string or list.
|
||||
systemSocketPath ? "$XDG_RUNTIME_DIR/app/${appId}/bus_system",
|
||||
systemUpstreamSocket ? "/run/dbus/system_bus_socket",
|
||||
}:
|
||||
let
|
||||
bwrap = "${pkgs.bubblewrap}/bin/bwrap";
|
||||
dbusProxy = "${pkgs.xdg-dbus-proxy}/bin/xdg-dbus-proxy";
|
||||
coreutils = "${pkgs.coreutils}/bin";
|
||||
|
||||
# Helper to generate the function definition
|
||||
# We bind XDG_RUNTIME_DIR to allow creating the socket.
|
||||
# We optionally bind /run/dbus for the system bus socket.
|
||||
mkProxyFunc = name: upstream: sock: args: bindSystem: ''
|
||||
${name}() {
|
||||
${coreutils}/mkdir -p "$(${coreutils}/dirname "${sock}")"
|
||||
${bwrap} \
|
||||
--unshare-user \
|
||||
--dev /dev \
|
||||
--proc /proc \
|
||||
--new-session \
|
||||
--ro-bind /nix/store /nix/store \
|
||||
--bind "$XDG_RUNTIME_DIR" "$XDG_RUNTIME_DIR" \
|
||||
${if bindSystem then "--ro-bind /run/dbus /run/dbus" else ""} \
|
||||
--die-with-parent \
|
||||
--clearenv \
|
||||
-- \
|
||||
${dbusProxy} "unix:path=${upstream}" "${sock}" ${args}
|
||||
# Helper to normalize args (support list or string)
|
||||
normalizeArgs = args: if builtins.isList args then lib.concatStringsSep " " args else args;
|
||||
pArgs = normalizeArgs proxyArgs;
|
||||
sArgs = normalizeArgs systemProxyArgs;
|
||||
|
||||
# Helper to generate the function definition
|
||||
# We bind XDG_RUNTIME_DIR to allow creating the socket.
|
||||
# We optionally bind /run/dbus for the system bus socket.
|
||||
mkProxyFunc = name: upstream: sock: args: bindSystem: ''
|
||||
${name}() {
|
||||
${coreutils}/mkdir -p "$(${coreutils}/dirname "${sock}")"
|
||||
${bwrap} \
|
||||
--unshare-user \
|
||||
--dev /dev \
|
||||
--proc /proc \
|
||||
--new-session \
|
||||
--ro-bind /nix/store /nix/store \
|
||||
--bind "$XDG_RUNTIME_DIR" "$XDG_RUNTIME_DIR" \
|
||||
${if bindSystem then "--ro-bind /run/dbus /run/dbus" else ""} \
|
||||
--die-with-parent \
|
||||
--clearenv \
|
||||
-- \
|
||||
${dbusProxy} "unix:path=${upstream}" "${sock}" ${args}
|
||||
}
|
||||
'';
|
||||
|
||||
sessionFunc = mkProxyFunc "set_up_dbus_proxy" upstreamSocket socketPath pArgs false;
|
||||
systemFunc =
|
||||
if enableSystemBus then
|
||||
mkProxyFunc "set_up_system_dbus_proxy" systemUpstreamSocket systemSocketPath sArgs true
|
||||
else
|
||||
"";
|
||||
|
||||
waitLoop = ''
|
||||
# Wait for socket(s) with fail-fast check
|
||||
for i in $(${coreutils}/seq 1 50);
|
||||
do
|
||||
# Check if processes are still running
|
||||
if ! kill -0 "$PID_SESSION" 2>/dev/null;
|
||||
then
|
||||
echo "Error: Session D-Bus proxy (PID $PID_SESSION) died unexpectedly." >&2
|
||||
exit 1
|
||||
fi
|
||||
${
|
||||
if enableSystemBus then
|
||||
''
|
||||
if ! kill -0 "$PID_SYSTEM" 2>/dev/null;
|
||||
then
|
||||
echo "Error: System D-Bus proxy (PID $PID_SYSTEM) died unexpectedly." >&2
|
||||
exit 1
|
||||
fi
|
||||
''
|
||||
else
|
||||
""
|
||||
}
|
||||
|
||||
# Check for sockets
|
||||
if [ -S "${socketPath}" ]${if enableSystemBus then " && [ -S \"${systemSocketPath}\" ]" else ""};
|
||||
then
|
||||
break
|
||||
fi
|
||||
${coreutils}/sleep 0.02
|
||||
done
|
||||
'';
|
||||
|
||||
in
|
||||
''
|
||||
${sessionFunc}
|
||||
${systemFunc}
|
||||
|
||||
set_up_dbus_proxy &
|
||||
PID_SESSION=$!
|
||||
${
|
||||
if enableSystemBus then
|
||||
''
|
||||
set_up_system_dbus_proxy &
|
||||
PID_SYSTEM=$!
|
||||
''
|
||||
else
|
||||
""
|
||||
}
|
||||
|
||||
${waitLoop}
|
||||
'';
|
||||
|
||||
sessionFunc = mkProxyFunc "set_up_dbus_proxy" upstreamSocket socketPath pArgs false;
|
||||
systemFunc = if enableSystemBus
|
||||
then mkProxyFunc "set_up_system_dbus_proxy" systemUpstreamSocket systemSocketPath sArgs true
|
||||
else "";
|
||||
|
||||
waitLoop = ''
|
||||
# Wait for socket(s) with fail-fast check
|
||||
for i in $(${coreutils}/seq 1 50);
|
||||
do
|
||||
# Check if processes are still running
|
||||
if ! kill -0 "$PID_SESSION" 2>/dev/null;
|
||||
then
|
||||
echo "Error: Session D-Bus proxy (PID $PID_SESSION) died unexpectedly." >&2
|
||||
exit 1
|
||||
fi
|
||||
${if enableSystemBus then ''
|
||||
if ! kill -0 "$PID_SYSTEM" 2>/dev/null;
|
||||
then
|
||||
echo "Error: System D-Bus proxy (PID $PID_SYSTEM) died unexpectedly." >&2
|
||||
exit 1
|
||||
fi
|
||||
'' else ""}
|
||||
# Standard Common Binds (System Essentials)
|
||||
mkCommonBindArgs =
|
||||
{ config, lib }:
|
||||
[
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind-try /dev/ntsync /dev/ntsync"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.${config.myModules.system.mainUser}.uid}"
|
||||
"--ro-bind /sys /sys"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
"--unsetenv LD_PRELOAD"
|
||||
];
|
||||
|
||||
# Check for sockets
|
||||
if [ -S "${socketPath}" ]${if enableSystemBus then " && [ -S \"${systemSocketPath}\" ]" else ""};
|
||||
then
|
||||
break
|
||||
fi
|
||||
${coreutils}/sleep 0.02
|
||||
done
|
||||
'';
|
||||
# GUI Application Binds (Fonts, Themes, Wayland/X11 sockets)
|
||||
mkGuiBindArgs =
|
||||
{ }:
|
||||
[
|
||||
# Wayland socket
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
# PipeWire + Pulse
|
||||
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
|
||||
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
|
||||
];
|
||||
|
||||
in ''
|
||||
${sessionFunc}
|
||||
${systemFunc}
|
||||
# GUI Mounts (Fonts, Configs)
|
||||
mkGuiMounts = {
|
||||
read = [
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/qt6ct"
|
||||
"$HOME/.config/Kvantum"
|
||||
"$HOME/.config/MangoHud"
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
"$HOME/.config/gtk-3.0"
|
||||
"$HOME/.config/gtk-4.0"
|
||||
];
|
||||
};
|
||||
|
||||
set_up_dbus_proxy &
|
||||
PID_SESSION=$!
|
||||
${if enableSystemBus then ''
|
||||
set_up_system_dbus_proxy &
|
||||
PID_SYSTEM=$!
|
||||
'' else ""}
|
||||
|
||||
${waitLoop}
|
||||
'';
|
||||
}
|
||||
# Gaming Binds (GPU, Controllers, Input)
|
||||
mkGamingBindArgs =
|
||||
{ }:
|
||||
[
|
||||
"--dev-bind /dev/dri /dev/dri" # GPU
|
||||
"--dev-bind /dev/shm /dev/shm" # Shared Mem
|
||||
"--dev-bind-try /dev/uinput /dev/uinput"
|
||||
"--dev-bind-try /dev/input /dev/input"
|
||||
"--dev-bind-try /dev/hidraw0 /dev/hidraw0"
|
||||
"--dev-bind-try /dev/hidraw1 /dev/hidraw1"
|
||||
"--dev-bind-try /dev/hidraw2 /dev/hidraw2"
|
||||
"--dev-bind-try /dev/hidraw3 /dev/hidraw3"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--ro-bind-try /run/udev /run/udev"
|
||||
];
|
||||
|
||||
# Helper to create a sandboxed application module
|
||||
mkSandboxedApp =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
optionName, # e.g. "steamSandboxed"
|
||||
packageName, # e.g. "steam-sandboxed"
|
||||
description,
|
||||
package, # e.g. pkgs.steam
|
||||
appId, # e.g. "com.valvesoftware.Steam"
|
||||
isFhsenv ? false,
|
||||
env ? { },
|
||||
sockets ? {
|
||||
x11 = true;
|
||||
wayland = true;
|
||||
},
|
||||
flatpak ? false,
|
||||
|
||||
# Mounts
|
||||
mounts ? {
|
||||
read = [ ];
|
||||
readWrite = [ ];
|
||||
},
|
||||
|
||||
# Bwrap/Fhsenv options
|
||||
fhsenvOpts ? {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
},
|
||||
fhsenvExtra ? { }, # merged into fhsenv
|
||||
|
||||
# Args
|
||||
baseArgs ? (mkCommonBindArgs { inherit config lib; }),
|
||||
additionalArgs ? [ ], # merged into fhsenv.bwrap.additionalArgs
|
||||
|
||||
# DBus
|
||||
dbusProxy ? null, # { rules ? [], systemRules ? [], enableSystemBus ? false }
|
||||
}:
|
||||
let
|
||||
cfg = config.myModules.${optionName};
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
|
||||
# Handle DBus Proxy Logic
|
||||
hasDbusProxy = dbusProxy != null;
|
||||
proxyScript =
|
||||
if hasDbusProxy then
|
||||
mkDbusProxyScript {
|
||||
inherit appId;
|
||||
enableSystemBus = dbusProxy.enableSystemBus or false;
|
||||
proxyArgs = dbusProxy.rules or [ ];
|
||||
systemProxyArgs = dbusProxy.systemRules or [ ];
|
||||
}
|
||||
else
|
||||
"";
|
||||
|
||||
dbusBindArgs =
|
||||
if hasDbusProxy then
|
||||
[
|
||||
''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
]
|
||||
++ (
|
||||
if (dbusProxy.enableSystemBus or false) then
|
||||
[
|
||||
''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus_system" /run/dbus/system_bus_socket''
|
||||
]
|
||||
else
|
||||
[ ]
|
||||
)
|
||||
else
|
||||
[ ];
|
||||
|
||||
in
|
||||
{
|
||||
options.myModules.${optionName} = {
|
||||
enable = lib.mkEnableOption description;
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
${packageName} = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = package;
|
||||
inherit isFhsenv;
|
||||
env = env;
|
||||
id = appId;
|
||||
};
|
||||
|
||||
inherit sockets;
|
||||
flatpak.enable = flatpak;
|
||||
|
||||
fhsenv = fhsenvExtra // {
|
||||
opts = fhsenvOpts;
|
||||
bwrap = {
|
||||
baseArgs = lib.mkForce baseArgs;
|
||||
additionalArgs = mkGuiBindArgs { } ++ additionalArgs ++ dbusBindArgs;
|
||||
};
|
||||
};
|
||||
|
||||
mounts = {
|
||||
read = mkGuiMounts.read ++ mounts.read;
|
||||
readWrite = mounts.readWrite ++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
dbus.enable = false;
|
||||
|
||||
script.preCmds.stage2 = proxyScript;
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
environment.systemPackages = [ pkgs.${packageName} ];
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
inherit
|
||||
mkDbusProxyScript
|
||||
mkCommonBindArgs
|
||||
mkGuiBindArgs
|
||||
mkGuiMounts
|
||||
mkGamingBindArgs
|
||||
mkSandboxedApp
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,189 +17,8 @@
|
|||
|
||||
let
|
||||
cfg = config.myModules.searxng;
|
||||
|
||||
catppuccinCss = pkgs.writeText "searxng-catppuccin.css" ''
|
||||
:root {
|
||||
/* Mocha (Dark) */
|
||||
--cat-rosewater: #f5e0dc;
|
||||
--cat-flamingo: #f2cdcd;
|
||||
--cat-pink: #f5c2e7;
|
||||
--cat-mauve: #cba6f7;
|
||||
--cat-red: #f38ba8;
|
||||
--cat-maroon: #eba0ac;
|
||||
--cat-peach: #fab387;
|
||||
--cat-yellow: #f9e2af;
|
||||
--cat-green: #a6e3a1;
|
||||
--cat-teal: #94e2d5;
|
||||
--cat-sky: #89dceb;
|
||||
--cat-sapphire: #74c7ec;
|
||||
--cat-blue: #89b4fa;
|
||||
--cat-lavender: #b4befe;
|
||||
--cat-text: #cdd6f4;
|
||||
--cat-subtext1: #bac2de;
|
||||
--cat-subtext0: #a6adc8;
|
||||
--cat-overlay2: #9399b2;
|
||||
--cat-overlay1: #7f849c;
|
||||
--cat-overlay0: #6c7086;
|
||||
--cat-surface2: #585b70;
|
||||
--cat-surface1: #45475a;
|
||||
--cat-surface0: #313244;
|
||||
--cat-base: #1e1e2e;
|
||||
--cat-mantle: #181825;
|
||||
--cat-crust: #11111b;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
/* Latte (Light) */
|
||||
--cat-rosewater: #dc8a78;
|
||||
--cat-flamingo: #dd7878;
|
||||
--cat-pink: #ea76cb;
|
||||
--cat-mauve: #8839ef;
|
||||
--cat-red: #d20f39;
|
||||
--cat-maroon: #e64553;
|
||||
--cat-peach: #fe640b;
|
||||
--cat-yellow: #df8e1d;
|
||||
--cat-green: #40a02b;
|
||||
--cat-teal: #179287;
|
||||
--cat-sky: #04a5e5;
|
||||
--cat-sapphire: #209fb5;
|
||||
--cat-blue: #1e66f5;
|
||||
--cat-lavender: #7287fd;
|
||||
--cat-text: #4c4f69;
|
||||
--cat-subtext1: #5c5f77;
|
||||
--cat-subtext0: #6c6f85;
|
||||
--cat-overlay2: #7c7f93;
|
||||
--cat-overlay1: #8c8fa1;
|
||||
--cat-overlay0: #9ca0b0;
|
||||
--cat-surface2: #acb0be;
|
||||
--cat-surface1: #bcc0cc;
|
||||
--cat-surface0: #ccd0da;
|
||||
--cat-base: #eff1f5;
|
||||
--cat-mantle: #e6e9ef;
|
||||
--cat-crust: #dce0e8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply variables */
|
||||
:root {
|
||||
--color-base-font: var(--cat-text);
|
||||
--color-base-background: var(--cat-base);
|
||||
--color-base-background-mobile: var(--cat-base);
|
||||
--color-url-font: var(--cat-mauve);
|
||||
--color-url-visited-font: var(--cat-mauve);
|
||||
--color-header-background: var(--cat-mantle);
|
||||
--color-header-border: var(--cat-mantle);
|
||||
--color-footer-background: var(--cat-mantle);
|
||||
--color-footer-border: var(--cat-mantle);
|
||||
--color-sidebar-border: var(--cat-base);
|
||||
--color-sidebar-font: var(--cat-text);
|
||||
--color-sidebar-background: var(--cat-base);
|
||||
--color-backtotop-font: var(--cat-subtext1);
|
||||
--color-backtotop-border: var(--cat-surface0);
|
||||
--color-backtotop-background: var(--cat-surface0);
|
||||
--color-btn-background: var(--cat-mauve);
|
||||
--color-btn-font: var(--cat-base);
|
||||
--color-show-btn-background: var(--cat-mauve);
|
||||
--color-show-btn-font: var(--cat-base);
|
||||
--color-search-border: var(--cat-surface0);
|
||||
--color-search-shadow: 0 2px 8px var(--cat-crust);
|
||||
--color-search-background: var(--cat-surface0);
|
||||
--color-search-font: var(--cat-text);
|
||||
--color-search-background-hover: var(--cat-mauve);
|
||||
--color-error: var(--cat-red);
|
||||
--color-error-background: var(--cat-surface0);
|
||||
--color-warning: var(--cat-yellow);
|
||||
--color-warning-background: var(--cat-surface0);
|
||||
--color-success: var(--cat-green);
|
||||
--color-success-background: var(--cat-surface0);
|
||||
--color-categories-item-selected-font: var(--cat-text);
|
||||
--color-categories-item-border-selected: var(--cat-mauve);
|
||||
--color-autocomplete-font: var(--cat-subtext1);
|
||||
--color-autocomplete-border: var(--cat-surface0);
|
||||
--color-autocomplete-shadow: 0 2px 8px var(--cat-crust);
|
||||
--color-autocomplete-background: var(--cat-surface0);
|
||||
--color-autocomplete-background-hover: var(--cat-surface1);
|
||||
--color-answer-font: var(--cat-text);
|
||||
--color-answer-background: var(--cat-mantle);
|
||||
--color-result-background: var(--cat-mantle);
|
||||
--color-result-border: var(--cat-base);
|
||||
--color-result-url-font: var(--cat-subtext1);
|
||||
--color-result-vim-selected: var(--cat-surface0);
|
||||
--color-result-vim-arrow: var(--cat-mauve);
|
||||
--color-result-description-highlight-font: var(--cat-text);
|
||||
--color-result-link-font: var(--cat-mauve);
|
||||
--color-result-link-font-highlight: var(--cat-mauve);
|
||||
--color-result-link-visited-font: var(--cat-mauve);
|
||||
--color-result-publishdate-font: var(--cat-surface2);
|
||||
--color-result-engines-font: var(--cat-surface2);
|
||||
--color-result-search-url-border: var(--cat-surface2);
|
||||
--color-result-search-url-font: var(--cat-text);
|
||||
--color-result-detail-font: var(--cat-text);
|
||||
--color-result-detail-label-font: var(--cat-subtext0);
|
||||
--color-result-detail-background: var(--cat-base);
|
||||
--color-result-detail-hr: var(--cat-base);
|
||||
--color-result-detail-link: var(--cat-mauve);
|
||||
--color-result-detail-loader-border: rgba(255, 255, 255, 0.2);
|
||||
--color-result-detail-loader-borderleft: var(--cat-crust);
|
||||
--color-result-image-span-font: var(--cat-text);
|
||||
--color-result-image-span-font-selected: var(--cat-base);
|
||||
--color-result-image-background: var(--cat-mantle);
|
||||
--color-settings-tr-hover: var(--cat-surface0);
|
||||
--color-settings-engine-description-font: var(--cat-text);
|
||||
--color-settings-engine-group-background: var(--cat-surface0);
|
||||
--color-toolkit-badge-font: var(--cat-text);
|
||||
--color-toolkit-badge-background: var(--cat-surface0);
|
||||
--color-toolkit-kbd-font: var(--cat-text);
|
||||
--color-toolkit-kbd-background: var(--cat-mantle);
|
||||
--color-toolkit-dialog-border: var(--cat-mantle);
|
||||
--color-toolkit-dialog-background: var(--cat-mantle);
|
||||
--color-toolkit-tabs-label-border: var(--cat-base);
|
||||
--color-toolkit-tabs-section-border: var(--cat-base);
|
||||
--color-toolkit-select-background: var(--cat-surface0);
|
||||
--color-toolkit-select-border: var(--cat-surface0);
|
||||
--color-toolkit-select-background-hover: var(--cat-surface1);
|
||||
--color-toolkit-input-text-font: var(--cat-text);
|
||||
--color-toolkit-checkbox-onoff-off-background: var(--cat-surface0);
|
||||
--color-toolkit-checkbox-onoff-on-background: var(--cat-surface0);
|
||||
--color-toolkit-checkbox-onoff-on-mark-background: var(--cat-green);
|
||||
--color-toolkit-checkbox-onoff-on-mark-color: var(--cat-mantle);
|
||||
--color-toolkit-checkbox-onoff-off-mark-background: var(--cat-red);
|
||||
--color-toolkit-checkbox-onoff-off-mark-color: var(--cat-mantle);
|
||||
--color-toolkit-checkbox-label-background: var(--cat-base);
|
||||
--color-toolkit-checkbox-label-border: var(--cat-mantle);
|
||||
--color-toolkit-checkbox-input-border: var(--cat-mauve);
|
||||
--color-toolkit-engine-tooltip-border: var(--cat-surface0);
|
||||
--color-toolkit-engine-tooltip-background: var(--cat-surface0);
|
||||
--color-toolkit-loader-border: rgba(255, 255, 255, 0.2);
|
||||
--color-toolkit-loader-borderleft: var(--cat-crust);
|
||||
--color-doc-code: var(--cat-rosewater);
|
||||
--color-doc-code-background: var(--cat-mantle);
|
||||
}
|
||||
|
||||
#search_logo svg :not([fill="none"]) {
|
||||
fill: var(--cat-mauve) !important;
|
||||
}
|
||||
#search_logo svg :not([stroke="none"]) {
|
||||
stroke: var(--cat-mauve) !important;
|
||||
}
|
||||
|
||||
/* Additional cute tweaks */
|
||||
article.result {
|
||||
background-color: var(--color-result-background);
|
||||
border-radius: 0.75em;
|
||||
padding: 0.75em;
|
||||
margin: 0.5em;
|
||||
border: 1px solid var(--cat-surface0);
|
||||
}
|
||||
article.category-images {
|
||||
padding-bottom: 4em;
|
||||
}
|
||||
input[type="text"] {
|
||||
border-radius: 2em !important;
|
||||
}
|
||||
'';
|
||||
|
||||
mainUser = config.myModules.system.mainUser;
|
||||
mainUserUid = toString config.users.users.${mainUser}.uid;
|
||||
anubisPolicy = pkgs.writeText "anubis-policy.yml" ''
|
||||
bots:
|
||||
- name: "Allow OpenSearch"
|
||||
|
|
@ -217,6 +36,10 @@ let
|
|||
[favicons.cache]
|
||||
db_url = "/var/cache/searxng/faviconcache.db"
|
||||
LIMIT_TOTAL_BYTES = 2147483648
|
||||
|
||||
[favicons.proxy.resolver_map]
|
||||
google = "searx.favicons.resolver.google_resolver"
|
||||
duckduckgo = "searx.favicons.resolver.duckduckgo_resolver"
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
|
@ -251,25 +74,32 @@ in
|
|||
# 1. Create Bridge Network
|
||||
systemd.services."create-searxng-network" = {
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.User = "ashie";
|
||||
serviceConfig.User = mainUser;
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
after = [ "user-runtime-dir@1000.service" ];
|
||||
requires = [ "user-runtime-dir@1000.service" ];
|
||||
after = [ "user-runtime-dir@${mainUserUid}.service" ];
|
||||
requires = [ "user-runtime-dir@${mainUserUid}.service" ];
|
||||
path = [
|
||||
pkgs.podman
|
||||
pkgs.shadow
|
||||
];
|
||||
script = ''
|
||||
export PATH=/run/wrappers/bin:$PATH
|
||||
export XDG_RUNTIME_DIR="/run/user/1000"
|
||||
export HOME="/home/ashie"
|
||||
podman network create searxng-net --subnet 10.89.2.0/24 --ignore
|
||||
export XDG_RUNTIME_DIR="/run/user/${mainUserUid}"
|
||||
export HOME="/home/${mainUser}"
|
||||
|
||||
if ! podman network exists searxng-net; then
|
||||
echo "Creating searxng-net..."
|
||||
podman network create searxng-net --subnet 10.89.2.0/24
|
||||
else
|
||||
echo "searxng-net already exists."
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# 2. Valkey Container (Cache/Limiter)
|
||||
virtualisation.oci-containers.containers."searxng-valkey" = {
|
||||
image = "docker.io/valkey/valkey:alpine";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
cmd = [
|
||||
"valkey-server"
|
||||
"--save"
|
||||
|
|
@ -286,12 +116,12 @@ in
|
|||
|
||||
# 3. SearXNG Container
|
||||
virtualisation.oci-containers.containers."searxng" = {
|
||||
image = "ghcr.io/privau/searxng:latest";
|
||||
# ports = [ "127.0.0.1:${toString cfg.port}:8080" ]; # Port moved to Anubis
|
||||
image = "localhost/aadniz/searxng:latest";
|
||||
environment = {
|
||||
"SEARXNG_BASE_URL" = "https://${cfg.domain}";
|
||||
"SEARXNG_REDIS_URL" = "valkey://valkey:6379"; # Talk to Valkey via alias
|
||||
"SEARXNG_URL_BASE" = "https://${cfg.domain}";
|
||||
"GRANIAN_HOST" = "0.0.0.0";
|
||||
};
|
||||
environmentFiles = [
|
||||
# Contains SEARXNG_SECRET_KEY
|
||||
|
|
@ -308,8 +138,9 @@ in
|
|||
];
|
||||
volumes = [
|
||||
"${config.sops.templates."searxng_settings.yml".path}:/etc/searxng/settings.yml:ro"
|
||||
"${catppuccinCss}:/etc/searxng/custom.css:ro"
|
||||
|
||||
"${faviconsConfig}:/etc/searxng/favicons.toml:ro"
|
||||
"${./braveapi.py}:/usr/local/searxng/searx/engines/braveapi.py:ro"
|
||||
"searxng-cache:/var/cache/searxng"
|
||||
];
|
||||
dependsOn = [ "searxng-valkey" ];
|
||||
|
|
@ -318,6 +149,7 @@ in
|
|||
# 4. Anubis Container (AI Firewall)
|
||||
virtualisation.oci-containers.containers."searxng-anubis" = {
|
||||
image = "ghcr.io/techarohq/anubis:latest";
|
||||
labels = { "io.containers.autoupdate" = "registry"; };
|
||||
ports = [ "127.0.0.1:${toString cfg.port}:8080" ];
|
||||
environment = {
|
||||
"TARGET" = "http://searxng:8080";
|
||||
|
|
@ -326,6 +158,7 @@ in
|
|||
};
|
||||
extraOptions = [
|
||||
"--network=searxng-net"
|
||||
"--network-alias=searxng-anubis"
|
||||
];
|
||||
volumes = [
|
||||
"${anubisPolicy}:/etc/anubis/policy.yml:ro"
|
||||
|
|
@ -333,32 +166,24 @@ in
|
|||
dependsOn = [ "searxng" ];
|
||||
};
|
||||
|
||||
# 5. Permanent NAT Fix for SearXNG Network
|
||||
networking.nftables.tables.searxng-nat = {
|
||||
family = "inet";
|
||||
content = ''
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority srcnat; policy accept;
|
||||
ip saddr 10.89.2.0/24 masquerade
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
sops.templates."searxng.env" = {
|
||||
owner = "ashie";
|
||||
owner = mainUser;
|
||||
content = ''
|
||||
SEARXNG_SECRET_KEY=${config.sops.placeholder.searxng_secret_key}
|
||||
BRAVE_API_KEY=${config.sops.placeholder.searxng_brave_api_key}
|
||||
'';
|
||||
};
|
||||
|
||||
sops.templates."searxng_settings.yml" = {
|
||||
owner = "ashie";
|
||||
owner = mainUser;
|
||||
content = ''
|
||||
use_default_settings: true
|
||||
|
||||
general:
|
||||
debug: false
|
||||
instance_name: "Ashie Search"
|
||||
contact_url: false
|
||||
issue_url: false
|
||||
donation_url: ${if cfg.donations ? "Monero" then "\"${cfg.donations.Monero}\"" else "false"}
|
||||
donations:
|
||||
${lib.concatStringsSep "\n " (
|
||||
|
|
@ -366,15 +191,20 @@ in
|
|||
)}
|
||||
|
||||
engines:
|
||||
- name: brave
|
||||
engine: brave
|
||||
api_key: "${config.sops.placeholder.searxng_brave_api_key}"
|
||||
- name: braveapi
|
||||
engine: braveapi
|
||||
shortcut: brapi
|
||||
categories: general
|
||||
# api_key: set via BRAVE_API_KEY env var
|
||||
tokens: ["${config.sops.placeholder.searxng_private_token}"]
|
||||
timeout: 2.0
|
||||
weight: 2
|
||||
disabled: false
|
||||
|
||||
|
||||
search:
|
||||
safe_search: 0
|
||||
favicon_resolver: "duckduckgo"
|
||||
favicon_resolver: "google"
|
||||
autocomplete: "google"
|
||||
default_lang: "en-US"
|
||||
formats:
|
||||
|
|
@ -387,17 +217,15 @@ in
|
|||
secret_key: "${config.sops.placeholder.searxng_secret_key}"
|
||||
limiter: true
|
||||
image_proxy: true
|
||||
public_instance: true
|
||||
|
||||
default_http_headers:
|
||||
Content-Security-Policy: "upgrade-insecure-requests; default-src 'none'; script-src 'self'; style-src 'self' 'sha256-/ldGxQqxNIMRftg3AGsPF+F281wiBPECUDcL2RJkxdU='; form-action 'self' https://github.com/searxng/searxng/issues/new; font-src 'self'; frame-ancestors 'self'; img-src 'self' data:; connect-src 'self' https://overpass-api.de; manifest-src 'self'"
|
||||
|
||||
ui:
|
||||
default_theme: simple
|
||||
default_theme_style: kagi
|
||||
default_theme: red-floof
|
||||
default_theme_style: dark
|
||||
static_use_hash: true
|
||||
# custom_css: custom.css
|
||||
# theme_args:
|
||||
# simple_style: kagi
|
||||
|
||||
hostname_replace:
|
||||
'(^|.*\.)reddit\.com$': 'reddit.ashisgreat.xyz'
|
||||
|
||||
redis:
|
||||
url: valkey://valkey:6379/0
|
||||
|
|
@ -410,58 +238,59 @@ in
|
|||
sops.secrets.searxng_private_token = { };
|
||||
|
||||
# Rootless Overrides
|
||||
systemd.services."podman-searxng".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-searxng".serviceConfig.User = lib.mkForce mainUser;
|
||||
systemd.services."podman-searxng".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
HOME = "/home/${mainUser}";
|
||||
XDG_RUNTIME_DIR = "/run/user/${mainUserUid}";
|
||||
};
|
||||
systemd.services."podman-searxng".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-searxng".serviceConfig.Delegate = true;
|
||||
systemd.services."podman-searxng".after = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
"user-runtime-dir@${mainUserUid}.service"
|
||||
"network-online.target"
|
||||
];
|
||||
systemd.services."podman-searxng".requires = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
"user-runtime-dir@${mainUserUid}.service"
|
||||
"network-online.target"
|
||||
];
|
||||
|
||||
systemd.services."podman-searxng-valkey".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-searxng-valkey".serviceConfig.User = lib.mkForce mainUser;
|
||||
systemd.services."podman-searxng-valkey".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
HOME = "/home/${mainUser}";
|
||||
XDG_RUNTIME_DIR = "/run/user/${mainUserUid}";
|
||||
};
|
||||
systemd.services."podman-searxng-valkey".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-searxng-valkey".serviceConfig.Delegate = true;
|
||||
systemd.services."podman-searxng-valkey".after = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
"user-runtime-dir@${mainUserUid}.service"
|
||||
"network-online.target"
|
||||
];
|
||||
systemd.services."podman-searxng-valkey".requires = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
"user-runtime-dir@${mainUserUid}.service"
|
||||
"network-online.target"
|
||||
];
|
||||
|
||||
systemd.services."podman-searxng-anubis".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-searxng-anubis".serviceConfig.User = lib.mkForce mainUser;
|
||||
systemd.services."podman-searxng-anubis".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
HOME = "/home/${mainUser}";
|
||||
XDG_RUNTIME_DIR = "/run/user/${mainUserUid}";
|
||||
};
|
||||
systemd.services."podman-searxng-anubis".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-searxng-anubis".serviceConfig.Delegate = true;
|
||||
systemd.services."podman-searxng-anubis".after = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
"user-runtime-dir@${mainUserUid}.service"
|
||||
"network-online.target"
|
||||
];
|
||||
systemd.services."podman-searxng-anubis".requires = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
"user-runtime-dir@${mainUserUid}.service"
|
||||
"network-online.target"
|
||||
];
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,111 +8,94 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.spotifySandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
spotify-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = prev.spotify;
|
||||
id = "com.spotify.Client";
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS for theming
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
# Force Wayland if preferred, or rely on auto-detection
|
||||
# DISPLAY variable is handled by sockets.x11/wayland
|
||||
options.myModules.spotifySandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Spotify with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
spotify-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = prev.spotify;
|
||||
id = "com.spotify.Client";
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS for theming
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
|
||||
# Spotify is not a flatpak ref, so disable flatpak emulation
|
||||
flatpak.enable = false;
|
||||
# Spotify is not a flatpak ref, so disable flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network for streaming
|
||||
unshareIpc = false;
|
||||
};
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network for streaming
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri" # GPU acceleration
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.ashie.uid}"
|
||||
# System paths
|
||||
"--ro-bind /sys /sys"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
# Audio
|
||||
"--ro-bind-try /etc/asound.conf /etc/asound.conf"
|
||||
];
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { } ++ [
|
||||
# Audio
|
||||
"--ro-bind-try /etc/asound.conf /etc/asound.conf"
|
||||
]);
|
||||
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.config/spotify"
|
||||
"$HOME/.cache/spotify"
|
||||
"$HOME/.local/share/spotify"
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read;
|
||||
readWrite = [
|
||||
"$HOME/.config/spotify"
|
||||
"$HOME/.cache/spotify"
|
||||
"$HOME/.local/share/spotify"
|
||||
] ++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
script.preCmds.stage2 = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "com.spotify.Client";
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.mpris.MediaPlayer2.Player"''
|
||||
''--own="org.mpris.MediaPlayer2.spotify"''
|
||||
''--own="com.spotify.Client"''
|
||||
''--own="com.spotify.Client.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/com.spotify.Client/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "com.spotify.Client";
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.mpris.MediaPlayer2.Player"''
|
||||
''--own="org.mpris.MediaPlayer2.spotify"''
|
||||
''--own="com.spotify.Client"''
|
||||
''--own="com.spotify.Client.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/com.spotify.Client/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Wayland socket
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
|
||||
# PipeWire + Pulse
|
||||
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
|
||||
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.spotify-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +1,63 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.myModules.gaming.gamemode;
|
||||
in
|
||||
{
|
||||
programs.gamescope = {
|
||||
enable = true;
|
||||
capSysNice = true;
|
||||
options.myModules.gaming.gamemode = {
|
||||
enable = lib.mkEnableOption "Steam GameMode Session";
|
||||
};
|
||||
|
||||
services.displayManager.sessionPackages = [
|
||||
(pkgs.writeTextFile {
|
||||
name = "steam-gamemode-session";
|
||||
destination = "/share/wayland-sessions/steam-gamemode.desktop";
|
||||
text = ''
|
||||
[Desktop Entry]
|
||||
Name=Steam GameMode
|
||||
Comment=Launch Steam in GameMode with Gamescope
|
||||
Exec=${pkgs.writeShellScript "steam-gamemode-start" ''
|
||||
# Load system environment
|
||||
. /etc/profile
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.gamemode.enable = true;
|
||||
|
||||
# Ensure we are in the user's home directory
|
||||
cd "$HOME" || exit 1
|
||||
programs.gamescope = {
|
||||
enable = true;
|
||||
capSysNice = true;
|
||||
};
|
||||
|
||||
exec >/tmp/steam-gamemode.log 2>&1
|
||||
echo "Starting Steam GameMode Session at $(date)"
|
||||
echo "User: $(whoami)"
|
||||
echo "PATH: $PATH"
|
||||
echo "Gamescope path: ${pkgs.gamescope}/bin/gamescope"
|
||||
services.displayManager.sessionPackages = [
|
||||
(pkgs.writeTextFile {
|
||||
name = "steam-gamemode-session";
|
||||
destination = "/share/wayland-sessions/steam-gamemode.desktop";
|
||||
text = ''
|
||||
[Desktop Entry]
|
||||
Name=Steam GameMode
|
||||
Comment=Launch Steam in GameMode with Gamescope
|
||||
Exec=${pkgs.writeShellScript "steam-gamemode-start" ''
|
||||
# Load system environment
|
||||
. /etc/profile
|
||||
|
||||
# Check for steam binary
|
||||
if ! command -v steam >/dev/null; then
|
||||
echo "ERROR: steam command not found in PATH"
|
||||
exit 1
|
||||
fi
|
||||
# Ensure we are in the user's home directory
|
||||
cd "$HOME" || exit 1
|
||||
|
||||
echo "Launching gamescope..."
|
||||
exec ${pkgs.gamescope}/bin/gamescope -f -e -- steam -gamepadui
|
||||
''}
|
||||
Type=Application
|
||||
'';
|
||||
derivationArgs = {
|
||||
passthru = {
|
||||
providedSessions = [ "steam-gamemode" ];
|
||||
exec >/tmp/steam-gamemode.log 2>&1
|
||||
echo "Starting Steam GameMode Session at $(date)"
|
||||
echo "User: $(whoami)"
|
||||
echo "PATH: $PATH"
|
||||
echo "Gamescope path: ${pkgs.gamescope}/bin/gamescope"
|
||||
|
||||
# Check for steam binary
|
||||
if ! command -v steam >/dev/null; then
|
||||
echo "ERROR: steam command not found in PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Launching gamescope..."
|
||||
exec ${pkgs.gamescope}/bin/gamescope -f -e -- steam -gamepadui
|
||||
''}
|
||||
Type=Application
|
||||
'';
|
||||
derivationArgs = {
|
||||
passthru = {
|
||||
providedSessions = [ "steam-gamemode" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -9,144 +9,81 @@
|
|||
}:
|
||||
|
||||
let
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
steam-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = prev.steam;
|
||||
isFhsenv = true; # Steam uses buildFHSEnv
|
||||
id = "com.valvesoftware.Steam";
|
||||
env = {
|
||||
# Unset LD_PRELOAD to avoid mimalloc crashes
|
||||
LD_PRELOAD = "";
|
||||
# Propagate XDG_DATA_DIRS for theming
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
# Proton/Wine optimizations
|
||||
PROTON_USE_NTSYNC = 1;
|
||||
XDG_CURRENT_DESKTOP = "niri";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=$XDG_RUNTIME_DIR/bus";
|
||||
};
|
||||
};
|
||||
sandboxUtils.mkSandboxedApp {
|
||||
inherit
|
||||
config
|
||||
lib
|
||||
pkgs
|
||||
inputs
|
||||
;
|
||||
optionName = "steamSandboxed";
|
||||
packageName = "steam-sandboxed";
|
||||
description = "sandboxed Steam with nix-bwrapper";
|
||||
package = pkgs.steam;
|
||||
appId = "com.valvesoftware.Steam";
|
||||
isFhsenv = true;
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
env = {
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
PROTON_USE_NTSYNC = 1;
|
||||
XDG_CURRENT_DESKTOP = "niri";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=$XDG_RUNTIME_DIR/bus";
|
||||
};
|
||||
|
||||
# Disable Flatpak emulation
|
||||
flatpak.enable = false;
|
||||
fhsenvExtra = {
|
||||
skipExtraInstallCmds = true;
|
||||
};
|
||||
|
||||
fhsenv = {
|
||||
skipExtraInstallCmds = true; # Steam package is special, don't try to modify it
|
||||
};
|
||||
fhsenvOpts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false;
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false; # Share PIDs for compatibility
|
||||
unshareNet = false; # Need network for Steam login/downloads
|
||||
unshareIpc = false;
|
||||
};
|
||||
baseArgs =
|
||||
sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { };
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri" # GPU acceleration
|
||||
"--dev-bind /dev/shm /dev/shm" # Shared memory (required for games)
|
||||
"--dev-bind-try /dev/uinput /dev/uinput" # Controller support
|
||||
"--dev-bind-try /dev/input /dev/input" # Controller/input devices
|
||||
"--dev-bind-try /dev/hidraw0 /dev/hidraw0" # HID devices (controllers)
|
||||
"--dev-bind-try /dev/hidraw1 /dev/hidraw1"
|
||||
"--dev-bind-try /dev/hidraw2 /dev/hidraw2"
|
||||
"--dev-bind-try /dev/hidraw3 /dev/hidraw3"
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.ashie.uid}"
|
||||
# System paths
|
||||
"--ro-bind /sys /sys"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
"--unsetenv LD_PRELOAD"
|
||||
# udev for controller hotplug
|
||||
"--ro-bind-try /run/udev /run/udev"
|
||||
];
|
||||
mounts = {
|
||||
read = [ ];
|
||||
readWrite = [
|
||||
"$HOME/.steam"
|
||||
"$HOME/.local/share/Steam"
|
||||
"$HOME/.local/share/umu"
|
||||
"$HOME/.local/share/applications"
|
||||
"$HOME/.local/share/desktop-directories"
|
||||
"$HOME/.local/share/icons"
|
||||
"$HOME/.local/share/Larian Studios"
|
||||
"$HOME/Desktop"
|
||||
"/games/steam"
|
||||
"/games/windows/Modlist"
|
||||
"/games/windows/Modlist_Downloads"
|
||||
];
|
||||
};
|
||||
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/qt6ct"
|
||||
"$HOME/.config/Kvantum"
|
||||
"$HOME/.config/MangoHud"
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.steam"
|
||||
"$HOME/.local/share/Steam"
|
||||
"$HOME/.local/share/umu"
|
||||
"$HOME/.local/share/applications"
|
||||
"$HOME/.local/share/desktop-directories"
|
||||
"$HOME/.local/share/icons"
|
||||
"$HOME/.local/share/Larian Studios"
|
||||
"$HOME/Desktop"
|
||||
"/games/steam"
|
||||
"/games/windows/Modlist"
|
||||
"/games/windows/Modlist_Downloads"
|
||||
"$HOME/Games/windows/Modlist/Nordic"
|
||||
];
|
||||
};
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "com.valvesoftware.Steam";
|
||||
enableSystemBus = false; # No system bus access
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--own="com.valvesoftware.Steam"''
|
||||
''--own="com.valvesoftware.Steam.*"''
|
||||
''--own="com.steampowered.PressureVessel.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/com.valvesoftware.Steam/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Wayland socket
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
|
||||
# PipeWire + Pulse
|
||||
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
|
||||
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
dbusProxy = {
|
||||
enable = true;
|
||||
enableSystemBus = false;
|
||||
rules = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.kde.KWin"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="com.feralinteractive.GameMode"''
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--own="com.valvesoftware.Steam"''
|
||||
''--own="com.valvesoftware.Steam.*"''
|
||||
''--own="com.steampowered.PressureVessel.*"''
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@
|
|||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
...}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.tutanotaSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
|
||||
pname = "tutanota-desktop";
|
||||
version = "319.260107.1";
|
||||
|
|
@ -34,86 +35,73 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
tutanota-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = tutanota;
|
||||
id = "com.tutanota.Tutanota";
|
||||
env = {
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
options.myModules.tutanotaSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Tutanota Desktop with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
tutanota-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = tutanota;
|
||||
id = "com.tutanota.Tutanota";
|
||||
env = {
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
flatpak.enable = false;
|
||||
flatpak.enable = false;
|
||||
|
||||
# Basic sandboxing
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = true;
|
||||
unshareCgroup = true;
|
||||
unsharePid = true;
|
||||
unshareNet = false; # Needs network
|
||||
unshareIpc = true;
|
||||
};
|
||||
# Basic sandboxing
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = true;
|
||||
unshareCgroup = true;
|
||||
unsharePid = true;
|
||||
unshareNet = false; # Needs network
|
||||
unshareIpc = true;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri" # GPU acceleration
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.ashie.uid}"
|
||||
# System paths
|
||||
"--ro-bind /sys /sys"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
];
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { });
|
||||
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.config/tutanota-desktop"
|
||||
"$HOME/Downloads"
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read;
|
||||
readWrite = [
|
||||
"$HOME/.config/tutanota-desktop"
|
||||
"$HOME/Downloads"
|
||||
] ++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
dbus.enable = false;
|
||||
script.preCmds.stage2 = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "com.tutanota.Tutanota";
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="org.gnome.keyring.SystemPrompter"'' # Often needed for secrets
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--own="com.tutanota.Tutanota"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/com.tutanota.Tutanota/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
dbus.enable = false;
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "com.tutanota.Tutanota";
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.secrets"''
|
||||
''--talk="org.gnome.keyring.SystemPrompter"'' # Often needed for secrets
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--own="com.tutanota.Tutanota"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/com.tutanota.Tutanota/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
# Wayland
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.tutanota-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.vesktopSandboxed;
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
sandboxUtils = import ./sandbox-utils.nix { inherit pkgs lib; };
|
||||
|
||||
# Define specific Vesktop version to avoid build errors from source
|
||||
vesktop-bin = pkgs.stdenv.mkDerivation rec {
|
||||
|
|
@ -40,106 +42,86 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
vesktop-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = vesktop-bin;
|
||||
id = "dev.vencord.Vesktop";
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS for theming
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
# Force Wayland
|
||||
NIXOS_OZONE_WL = "1";
|
||||
options.myModules.vesktopSandboxed = {
|
||||
enable = lib.mkEnableOption "sandboxed Vesktop with nix-bwrapper";
|
||||
|
||||
extraBindMounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Extra paths to bind mount (read-write) into the sandbox";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
vesktop-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
app = {
|
||||
package = vesktop-bin;
|
||||
id = "dev.vencord.Vesktop";
|
||||
env = {
|
||||
# Propagate XDG_DATA_DIRS for theming
|
||||
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
|
||||
# Force Wayland
|
||||
NIXOS_OZONE_WL = "1";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
# Enable X11 and Wayland
|
||||
sockets.x11 = true;
|
||||
sockets.wayland = true;
|
||||
|
||||
# Disable flatpak emulation
|
||||
flatpak.enable = false;
|
||||
# Disable flatpak emulation
|
||||
flatpak.enable = false;
|
||||
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network for Discord
|
||||
unshareIpc = false;
|
||||
};
|
||||
fhsenv.opts = {
|
||||
unshareUser = true;
|
||||
unshareUts = false;
|
||||
unshareCgroup = false;
|
||||
unsharePid = false;
|
||||
unshareNet = false; # Need network for Discord
|
||||
unshareIpc = false;
|
||||
};
|
||||
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce [
|
||||
"--new-session"
|
||||
"--proc /proc"
|
||||
"--dev /dev"
|
||||
"--dev-bind /dev/dri /dev/dri" # GPU acceleration
|
||||
"--tmpfs /home"
|
||||
"--tmpfs /tmp"
|
||||
"--tmpfs /run"
|
||||
"--dir /run/user"
|
||||
"--dir /run/user/${toString config.users.users.ashie.uid}"
|
||||
# System paths
|
||||
"--ro-bind /sys /sys"
|
||||
"--ro-bind-try /run/current-system /run/current-system"
|
||||
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
|
||||
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
|
||||
"--dir /run/systemd/resolve"
|
||||
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
|
||||
# Audio
|
||||
"--ro-bind-try /etc/asound.conf /etc/asound.conf"
|
||||
];
|
||||
fhsenv.bwrap.baseArgs = lib.mkForce (sandboxUtils.mkCommonBindArgs { inherit config lib; } ++ sandboxUtils.mkGamingBindArgs { });
|
||||
|
||||
mounts = {
|
||||
read = [
|
||||
"$HOME/.config/fontconfig"
|
||||
"$HOME/.local/share/fonts"
|
||||
"$HOME/.icons"
|
||||
"$HOME/.themes"
|
||||
"$HOME/.local/share/themes"
|
||||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
];
|
||||
readWrite = [
|
||||
"$HOME/.config/vesktop"
|
||||
"$HOME/Downloads"
|
||||
mounts = {
|
||||
read = sandboxUtils.mkGuiMounts.read;
|
||||
readWrite = [
|
||||
"$HOME/.config/vesktop"
|
||||
"$HOME/Downloads"
|
||||
] ++ cfg.extraBindMounts;
|
||||
};
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
script.preCmds.stage2 = sandboxUtils.mkDbusProxyScript {
|
||||
appId = "dev.vencord.Vesktop";
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="com.canonical.AppMenu.Registrar"''
|
||||
''--own="dev.vencord.Vesktop"''
|
||||
''--own="dev.vencord.Vesktop.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = sandboxUtils.mkGuiBindArgs { } ++ [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/dev.vencord.Vesktop/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
# Disable built-in DBus module (invokes bwrap without --unshare-user)
|
||||
dbus.enable = false;
|
||||
|
||||
# Manually set up DBus proxy with --unshare-user (session bus only)
|
||||
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
|
||||
appId = "dev.vencord.Vesktop";
|
||||
enableSystemBus = false;
|
||||
proxyArgs = [
|
||||
"--filter"
|
||||
''--talk="org.freedesktop.portal.*"''
|
||||
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
|
||||
''--talk="org.freedesktop.Notifications"''
|
||||
''--talk="org.freedesktop.ScreenSaver"''
|
||||
''--talk="org.kde.StatusNotifierWatcher"''
|
||||
''--talk="org.gnome.Mutter.DisplayConfig"''
|
||||
''--talk="com.canonical.AppMenu.Registrar"''
|
||||
''--own="dev.vencord.Vesktop"''
|
||||
''--own="dev.vencord.Vesktop.*"''
|
||||
];
|
||||
};
|
||||
|
||||
fhsenv.bwrap.additionalArgs = [
|
||||
# D-Bus session proxy only
|
||||
''--bind "$XDG_RUNTIME_DIR/app/dev.vencord.Vesktop/bus" "$XDG_RUNTIME_DIR/bus"''
|
||||
|
||||
# Wayland socket
|
||||
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
|
||||
|
||||
# PipeWire + Pulse
|
||||
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
|
||||
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
environment.systemPackages = [ pkgs.vesktop-sandboxed ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
10
scripts/run-nixbsd-vm.sh
Executable file
10
scripts/run-nixbsd-vm.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
# Script to build and run the NixBSD VM
|
||||
|
||||
set -e
|
||||
|
||||
echo "Building NixBSD VM..."
|
||||
VM_PATH=$(nix build .#nixosConfigurations.nixbsd.config.system.build.vm --no-link --print-out-paths --extra-experimental-features 'nix-command flakes')
|
||||
|
||||
echo "Starting NixBSD VM..."
|
||||
$VM_PATH/bin/run-nixbsd-vm
|
||||
|
|
@ -23,6 +23,11 @@ authelia_session_secret: ENC[AES256_GCM,data:jNB1QBocUNZSljjgIrtgTtmDQKthuGY8Gv8
|
|||
authelia_storage_encryption_key: ENC[AES256_GCM,data:2ELisYBEh7rY+Jcfy5c2mBOvFUi6uYnTHtkMviOffqkIkSUmgc+43Kt2tQA7P97y6Tn8/1w/3jJjx/1voz3ojQ==,iv:85k4x8bMoaJEGz4JgyrpmcTJktGypQjK/2GUxIFymOc=,tag:cJTW6YwZTtoUQDSXnYS32A==,type:str]
|
||||
searxng_brave_api_key: ENC[AES256_GCM,data:LgBCXW1jISajMWiZ7Miygv9TGjGImGP9TY7QLH4j1Q==,iv:r8E4dSjPofv+XFAsJFx3Z+y592tOOxWr0a/gGkJjPJw=,tag:1FHVfjvyvw7F5IOjQefySA==,type:str]
|
||||
searxng_private_token: ENC[AES256_GCM,data:Jw2yKNEkCZM7XHSrmz9wynSacT2XszjzDULo61Aodw==,iv:+0SA5IxRA7e/fd5Umw5wlWZj3YaTVEvYX7Jc1WZmPxk=,tag:rsg4N6GEl4yPmRsYzFAjOA==,type:str]
|
||||
cloudflare_warp_address_ipv4: ENC[AES256_GCM,data:kKmmnwVGkjNvbGAFYw==,iv:3FH6JA2KzwhHEYlMBmEl4ENTer78RMhk+g8KihO3t5Q=,tag:mVX6RmPH1JFCisJmxr7HbA==,type:str]
|
||||
cloudflare_warp_address_ipv6: ENC[AES256_GCM,data:YYbDxJKkyv8PM0eDMEf+LoTB0+a6MMOtSIox+PlWOuBTdPMhVQA7avg0,iv:/gR19idYvnAwDkIVW7gijKgQzZm0JsScbcYDJV6gBds=,tag:+hdPtRlZkDuJmj+tROA+iw==,type:str]
|
||||
cloudflare_warp_endpoint: ENC[AES256_GCM,data:gnjWcn9PABTaDPf+o/wsWyTPddkhg86g0aLbWg49hgM=,iv:jIHTtXz/crmQg+bABImMi3DVbUkUM3tfykBcwMeJD6c=,tag:bsU5hbQ+tc5mIDIN6nxnYg==,type:str]
|
||||
cloudflare_warp_private_key: ENC[AES256_GCM,data:KfpITQZ+VgTTiyoQdguazeLkUbK8RrAv927fLAWCe+VHVK9heGzwJS+S3sE=,iv:6rOGVFGdkPTXISTl9C2wU4GozI66p2BJDw65nKdHA+M=,tag:AabWup0iLEgmABhiNRhvmw==,type:str]
|
||||
cloudflare_warp_public_key: ENC[AES256_GCM,data:rN08TQCT3pNZokVl/ToKSy+7l5OkwH/BLURfhL+u5kZtOtN4fZmoPcKjcLU=,iv:4DN5rfmX2NnSYP51rgs3teYneWcnSD6G9BJQqa2RIO4=,tag:TPmoIEPcg5ey2BQrEi7pzA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1g76q4cec3qykmkzrd6f4fxxpafj5fsut4jk7pklweuff97scpuusnwdknu
|
||||
|
|
@ -43,7 +48,7 @@ sops:
|
|||
cVlpL1pxTFN3d1llbEhiNzlCcDV6NzAK6RlVB106woOkrmlINKB5hjoQs8CBfMAI
|
||||
nAjTYfHW0h4PznY0JpWfeNaVRD4EbDwbE2m8X6OzQEWJJB1WESw4Zg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-01-29T18:21:33Z"
|
||||
mac: ENC[AES256_GCM,data:k7C/t0INfl4bfUdrj81S2jbKjHGCP/W4+NeYXgzXrQ3mKD6myWNJW9j5Yh6WucFleV5uvk0IsH8zdUv/6F12fsCGRJ153Le8+LUZ400Co6toaLLIubLvC+mcUxqiXzSnGBUhjNH2jYNscBXtSSD+o2xUsyvs/vc5kqIv2tZzqHY=,iv:ef4nRzAaux9NEap87iphzOj3p1zPrvansBhq2v0w47o=,tag:HN0J/FlzWKg/ZoNvxYtRrg==,type:str]
|
||||
lastmodified: "2026-02-12T00:55:55Z"
|
||||
mac: ENC[AES256_GCM,data:KAXGETbqcDHyCtn0qiKg2PKPHrfzrwLFkx693j37pQTD1yKY/ziyencM0qQHl7oEtp4KI8u8pd7zwO6qJEts4wCCqG8MGJnKrwcD5AD8L+zn9szLKLPK31MSaRW799CcEGDE2PgaAtc7atqvs0OH8+KElN3vQeinJWFicqeICak=,iv:6E9uRXMadFt9mP0tPFOYNn2tt2KeyQb6DyS3NYykpy8=,tag:zdZ2CzCm6HIlX/W5m9es5A==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.11.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue