Compare commits
54 Commits
4261c3e605
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| ce9475e001 | |||
| a37e25329a | |||
| 3975092d67 | |||
| a2c2b2a2e5 | |||
| 0c0c94e4bf | |||
| a659a07637 | |||
| 60531ed270 | |||
| e6e62a375c | |||
| 58ade9d886 | |||
| eb2bdc2d33 | |||
| c4fb365814 | |||
| b4383e0d19 | |||
| e57b3e6937 | |||
| 0938c76f1b | |||
| 2e02f82ae2 | |||
| 2c380eaf10 | |||
| 76061f4919 | |||
| 159daf0630 | |||
| 82419c57ad | |||
| 6df89b4b06 | |||
| 3fabad4344 | |||
| 616a81d29d | |||
| 5a1da34702 | |||
| 8b813e6345 | |||
| 080cd5b1cc | |||
| 28a2a91d93 | |||
| f878110e49 | |||
| a57b0f2fef | |||
| 0160a8aa80 | |||
| 3b688fd5a2 | |||
| 0ee7266b3d | |||
| ecb0dc092e | |||
| 97248c0da3 | |||
| 7819928be2 | |||
| 6e1631d77b | |||
| ac28afc5eb | |||
|
ac3712aec5
|
|||
|
a453390013
|
|||
|
00049f5255
|
|||
|
6f260619a7
|
|||
|
031eab1b27
|
|||
|
231a769de5
|
|||
|
6df6976cd2
|
|||
|
9f5e9b00e8
|
|||
|
7b85d3b585
|
|||
|
ce75ee4024
|
|||
|
94800586f6
|
|||
|
efbcd546f9
|
|||
|
f75a9f1ccb
|
|||
|
e38f96eedb
|
|||
|
d7be1664ae
|
|||
|
24055ddfe7
|
|||
|
7bde25ebec
|
|||
|
930d951625
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,3 +6,6 @@ result
|
||||
|
||||
# nix pre-commit autogenerated by devShell
|
||||
/.pre-commit-config.yaml
|
||||
|
||||
# agy sessions
|
||||
.antigravitycli
|
||||
|
||||
7
LICENSE.txt
Normal file
7
LICENSE.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright (c) 2026 dotdoom
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
21
README.md
21
README.md
@@ -28,6 +28,18 @@ nix run \
|
||||
--flake .#artem@deimos
|
||||
```
|
||||
|
||||
## Layout
|
||||
|
||||
- `migrated`: files which are assets for home-manager, but can still be used to
|
||||
stow
|
||||
- `legacy`: files to be placed under `$HOME` which are still under stow
|
||||
- `hosts/*/{darwin,nixos,home}.nix`: personal machine nix configs
|
||||
- `modules/{darwin,nixos,home}/*.nix`: exported nix configs
|
||||
|
||||
TODO: rename `migrated` to `assets` and create `exported` which would be the
|
||||
exact mirror of nix-built configuration, but without nix (for machines where nix
|
||||
can not be installed). That `exported` will then be used by stow.
|
||||
|
||||
## Security
|
||||
|
||||
Risks taken (disclaimer):
|
||||
@@ -68,7 +80,9 @@ Risks taken (disclaimer):
|
||||
|
||||
Instead of PIV, we use FIDO2 slots on Yubikey to generate resident (i.e.
|
||||
stored solely on Yubikey itself) SSH keys using modern OpenSSH client built-in
|
||||
FIDO2 support. This doesn't need an agent or a background daemon.
|
||||
FIDO2 support. This doesn't need an agent or a background daemon. The lack of
|
||||
agent however means that these keys can not be forwarded to remote host for
|
||||
further SSH, Git signing or push.
|
||||
|
||||
To generate a new key:
|
||||
|
||||
@@ -103,8 +117,9 @@ Host deimos
|
||||
### Commit signing
|
||||
|
||||
Use SSH keys (from Apple SE and Yubikey) to sign commits. Make sure to generate
|
||||
a different set of keys for signing than the one you use for authentication. Add
|
||||
`-O application=ssh:git-signature` to mark the key for signing (personal
|
||||
a different set of keys for signing than the one you use for authentication, to
|
||||
decouple authentication from authorization and reduce key leakage blast radius.
|
||||
Add `-O application=ssh:git-signature` to mark the key for signing (personal
|
||||
convention).
|
||||
|
||||
### AGE encryption
|
||||
|
||||
75
flake.lock
generated
75
flake.lock
generated
@@ -3,16 +3,16 @@
|
||||
"brew-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1774235677,
|
||||
"narHash": "sha256-0ryNYmzDAeRlrzPTAgmzGH/Cgc8iv/LBN6jWGUANvIk=",
|
||||
"lastModified": 1781226006,
|
||||
"narHash": "sha256-w4ZTuOnhYiDxjaynrMTASzp802QblBWmo3wpB8wVN4Y=",
|
||||
"owner": "Homebrew",
|
||||
"repo": "brew",
|
||||
"rev": "894a3d23ac0c8aaf561b9874b528b9cb2e839201",
|
||||
"rev": "109191be4988470b51a60a5ef1998520aa24c01b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Homebrew",
|
||||
"ref": "5.1.1",
|
||||
"ref": "6.0.1",
|
||||
"repo": "brew",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -24,11 +24,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775037210,
|
||||
"narHash": "sha256-KM2WYj6EA7M/FVZVCl3rqWY+TFV5QzSyyGE2gQxeODU=",
|
||||
"lastModified": 1781761792,
|
||||
"narHash": "sha256-rCPytmKNjctLloB6UgK5CRrHSwV4b0ygxtJLPPp8R14=",
|
||||
"owner": "nix-darwin",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "06648f4902343228ce2de79f291dd5a58ee12146",
|
||||
"rev": "a1fa429e945becaf60468600daf649be4ba0350c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -96,11 +96,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776096920,
|
||||
"narHash": "sha256-8ZyTKMgyms+4Gcp1Zy3qMDXLxvO3FUDJUukxUYnlbLU=",
|
||||
"lastModified": 1781866110,
|
||||
"narHash": "sha256-eysWGLqD/9ZshEAg1bj1O8QpJZ6UoDEpjWzBJaR6ono=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "caafea45ba50ab9cdaefaf049ecd862b690124bb",
|
||||
"revCount": 19,
|
||||
"rev": "7fdd373d58137cdcddd8ba6f00ee06186affe5a5",
|
||||
"revCount": 36,
|
||||
"type": "git",
|
||||
"url": "https://github.com/futureware-tech/nix.git"
|
||||
},
|
||||
@@ -119,11 +119,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1774104215,
|
||||
"narHash": "sha256-EAtviqz0sEAxdHS4crqu7JGR5oI3BwaqG0mw7CmXkO8=",
|
||||
"lastModified": 1778507602,
|
||||
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "f799ae951fde0627157f40aec28dec27b22076d0",
|
||||
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -141,11 +141,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775585728,
|
||||
"narHash": "sha256-8Psjt+TWvE4thRKktJsXfR6PA/fWWsZ04DVaY6PUhr4=",
|
||||
"lastModified": 1781733627,
|
||||
"narHash": "sha256-U3yTuGBnmXvXoQI3qkpfEDsn9RovQPAjN7ndRco+3u0=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "580633fa3fe5fc0379905986543fd7495481913d",
|
||||
"rev": "3bbec39bc90eadfa031e6f3b77272f3f60803e39",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -204,11 +204,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776046499,
|
||||
"narHash": "sha256-Wzc4nn07/0RL21ypPHRzNDQZcjhIC8LaYo7QJQjM5T4=",
|
||||
"lastModified": 1781844424,
|
||||
"narHash": "sha256-sWBr0D6eu6UhmtM87NOd4oOYilIclFXGDd/s7tVvO10=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "287f84846c1eb3b72c986f5f6bebcff0bd67440d",
|
||||
"rev": "c804fab681f03ec772390af4421bcc9bce80c1d9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -219,11 +219,11 @@
|
||||
},
|
||||
"jail-nix": {
|
||||
"locked": {
|
||||
"lastModified": 1772137954,
|
||||
"narHash": "sha256-h4MGNbOo7L3RHi4uNFmsg5g17/DHXEfnv/xiG6BrNFQ=",
|
||||
"lastModified": 1776230864,
|
||||
"narHash": "sha256-YsEjjdOsGEzTeD+iT7ONh071BqWAOQWpzYVei3okAXE=",
|
||||
"owner": "~alexdavid",
|
||||
"repo": "jail.nix",
|
||||
"rev": "42b355c38ca63dab4904acc5c0d95f17954a8c9b",
|
||||
"rev": "404e7da9da5ab9aa643666682b2ba1312fa5fbe8",
|
||||
"type": "sourcehut"
|
||||
},
|
||||
"original": {
|
||||
@@ -237,11 +237,11 @@
|
||||
"brew-src": "brew-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1774720267,
|
||||
"narHash": "sha256-YYftFe8jyfpQI649yfr0E+dqEXE2jznZNcYvy/lKV1U=",
|
||||
"lastModified": 1781389246,
|
||||
"narHash": "sha256-ORqLAo/hoJdsZC7UPAuEHev6S0+XIqKEC7vjo5prz1k=",
|
||||
"owner": "zhaofengli",
|
||||
"repo": "nix-homebrew",
|
||||
"rev": "a7760a3a83f7609f742861afb5732210fdc437ed",
|
||||
"rev": "de7953a08ed4bb9245be043e468561c17b89130d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -252,11 +252,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1775710090,
|
||||
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
|
||||
"lastModified": 1781577229,
|
||||
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
|
||||
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -266,22 +266,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-screen": {
|
||||
"locked": {
|
||||
"lastModified": 1737753705,
|
||||
"narHash": "sha256-fQeXAeNQrsEUH3fd6RTjN/W+8flJiAFHo7Eya2RT87M=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e518d4ad2bcad74f98fec028cf21ce5b1e5020dd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e518d4ad2bcad74f98fec028cf21ce5b1e5020dd",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"darwin": "darwin",
|
||||
@@ -291,7 +275,6 @@
|
||||
"jail-nix": "jail-nix",
|
||||
"nix-homebrew": "nix-homebrew",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-screen": "nixpkgs-screen",
|
||||
"systems": "systems_2",
|
||||
"vscode-server": "vscode-server"
|
||||
}
|
||||
|
||||
86
flake.nix
86
flake.nix
@@ -3,11 +3,6 @@
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
# too many issues with screen 5.0
|
||||
# - load average in status broken
|
||||
# - background colors in programs (eg less) not showing
|
||||
# - caption and hardstatus color lacks intensity
|
||||
nixpkgs-screen.url = "github:NixOS/nixpkgs/e518d4ad2bcad74f98fec028cf21ce5b1e5020dd";
|
||||
systems.url = "github:nix-systems/default";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
@@ -44,13 +39,7 @@
|
||||
...
|
||||
}@inputs:
|
||||
let
|
||||
trustedSSHKeys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBxRBsFGa8OFbviYDGSAKLgfm/K2XUxvCo+31FW37yab artem"
|
||||
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIPAtIXXHm58julnr7S0xzBTM1jN5JkKxOL4JpuWDOa2jAAAABHNzaDo= office-dock-usb-a"
|
||||
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIHY1xx0huqV6Mcc2WngYDabITeNUbGamJ8//206MxxVTAAAABHNzaDo= keychain-usb-c"
|
||||
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIHzY2eOz+JdaKOpIgZbF5FsZzQy0l8vPJjAQdTpBFGsoAAAABHNzaDo= safe"
|
||||
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJg7zQ4H0LQeQcILZBwCzQ+MYKtCgKm7HPe9oFeoyprKZXAvpm+HDHtaYdU39JF9f+nvRztzXuMhgETAQMAQCkc= fingerprint@macbook"
|
||||
];
|
||||
homeManagerUser = "artem";
|
||||
eachSystem = nixpkgs.lib.genAttrs (import systems);
|
||||
in
|
||||
{
|
||||
@@ -70,24 +59,35 @@
|
||||
darwinModules = {
|
||||
mac-portable = import ./modules/darwin/mac-portable.nix;
|
||||
};
|
||||
nixosModules = {
|
||||
linux-headless = import ./modules/nixos/linux-headless.nix;
|
||||
linux-lxc = import ./modules/nixos/linux-lxc.nix;
|
||||
jailed-agy = import ./modules/nixos/jailed-agy.nix;
|
||||
};
|
||||
|
||||
homeConfigurations."artem@deimos" = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
extraSpecialArgs.primaryUser = "artem";
|
||||
homeConfigurations."${homeManagerUser}@deimos" = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = import nixpkgs {
|
||||
system = "x86_64-linux";
|
||||
};
|
||||
extraSpecialArgs.primaryUser = homeManagerUser;
|
||||
modules = [
|
||||
inputs.fw_nix.nixosModules.identities
|
||||
vscode-server.homeModules.default
|
||||
self.homeModules.linux-headless
|
||||
./hosts/deimos/home.nix
|
||||
];
|
||||
};
|
||||
|
||||
homeConfigurations."artem@mars" = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-darwin;
|
||||
homeConfigurations."${homeManagerUser}@mars" = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = import nixpkgs {
|
||||
system = "x86_64-darwin";
|
||||
config.allowDeprecatedx86_64Darwin = true;
|
||||
};
|
||||
extraSpecialArgs = {
|
||||
primaryUser = "artem";
|
||||
inherit trustedSSHKeys;
|
||||
primaryUser = homeManagerUser;
|
||||
};
|
||||
modules = [
|
||||
inputs.fw_nix.nixosModules.identities
|
||||
self.homeModules.mac-portable
|
||||
./hosts/mars/home.nix
|
||||
];
|
||||
@@ -95,39 +95,41 @@
|
||||
|
||||
darwinConfigurations.mars = darwin.lib.darwinSystem {
|
||||
system = "x86_64-darwin";
|
||||
specialArgs.primaryUser = "artem";
|
||||
specialArgs.primaryUser = homeManagerUser;
|
||||
modules = [
|
||||
inputs.fw_nix.nixosModules.identities
|
||||
self.darwinModules.mac-portable
|
||||
inputs.fw_nix.nixosModules.tools
|
||||
inputs.fw_nix.nixosModules.nix-gc
|
||||
inputs.fw_nix.nixosModules.nix-settings
|
||||
inputs.fw_nix.nixosModules.tools
|
||||
inputs.fw_nix.nixosModules.futureware
|
||||
inputs.nix-homebrew.darwinModules.nix-homebrew
|
||||
./hosts/mars/darwin.nix
|
||||
{
|
||||
nixpkgs.config.allowDeprecatedx86_64Darwin = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
nixosConfigurations.deimos =
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
in
|
||||
nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
specialArgs = {
|
||||
inherit trustedSSHKeys;
|
||||
inherit (inputs) jail-nix;
|
||||
pkgs-screen = import inputs.nixpkgs-screen {
|
||||
inherit system;
|
||||
};
|
||||
};
|
||||
modules = [
|
||||
inputs.fw_nix.nixosModules.nix-gc
|
||||
inputs.fw_nix.nixosModules.nix-settings
|
||||
inputs.fw_nix.nixosModules.tools
|
||||
inputs.fw_nix.nixosModules.sshd
|
||||
inputs.fw_nix.nixosModules.futureware
|
||||
./hosts/deimos/nixos.nix
|
||||
];
|
||||
nixosConfigurations.deimos = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
specialArgs = {
|
||||
primaryUser = homeManagerUser;
|
||||
inherit (inputs) jail-nix;
|
||||
};
|
||||
modules = [
|
||||
inputs.fw_nix.nixosModules.identities
|
||||
self.nixosModules.linux-headless
|
||||
self.nixosModules.linux-lxc
|
||||
self.nixosModules.jailed-agy
|
||||
inputs.fw_nix.nixosModules.nix-gc
|
||||
inputs.fw_nix.nixosModules.nix-settings
|
||||
inputs.fw_nix.nixosModules.tools
|
||||
inputs.fw_nix.nixosModules.sshd
|
||||
inputs.fw_nix.nixosModules.futureware
|
||||
./hosts/deimos/nixos.nix
|
||||
];
|
||||
};
|
||||
|
||||
devShells = eachSystem (
|
||||
system:
|
||||
|
||||
22
hosts/common/home.nix
Normal file
22
hosts/common/home.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
identities,
|
||||
primaryUser,
|
||||
...
|
||||
}:
|
||||
let
|
||||
user = identities.users.${primaryUser};
|
||||
in
|
||||
{
|
||||
programs.git = {
|
||||
signing = {
|
||||
# Will be available on remote machines via SSH agent (Secretive).
|
||||
key = "key::" + user.sign."sign@mars".publicKey;
|
||||
signByDefault = true;
|
||||
};
|
||||
|
||||
settings.user = {
|
||||
name = "Artem Sheremet";
|
||||
inherit (user) email;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,18 @@
|
||||
_: {
|
||||
home.homeDirectory = "/home/artem";
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
utils = import "${pkgs.path}/nixos/lib/utils.nix" { inherit lib pkgs config; };
|
||||
haremote-path = "${config.home.homeDirectory}/src/haremote";
|
||||
haremote-unit = utils.escapeSystemdPath haremote-path;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
../common/home.nix
|
||||
];
|
||||
|
||||
services.vscode-server.enable = true;
|
||||
services.vscode-server.installPath = [
|
||||
@@ -7,17 +20,17 @@ _: {
|
||||
"$HOME/.antigravity-server"
|
||||
];
|
||||
|
||||
systemd.user.mounts.home-artem-src-haremote = {
|
||||
systemd.user.mounts."${haremote-unit}" = {
|
||||
Unit = {
|
||||
Description = "Mount ~/src/haremote";
|
||||
Description = "Mount ${haremote-path}";
|
||||
After = [ "network-online.target" ];
|
||||
Wants = [ "network-online.target" ];
|
||||
};
|
||||
Mount = {
|
||||
What = "root@homeassistant.home.arpa:/homeassistant";
|
||||
Where = "/home/artem/src/haremote";
|
||||
Where = haremote-path;
|
||||
Type = "fuse.sshfs";
|
||||
Options = "reconnect,ServerAliveInterval=15,uid=1000,gid=1000,IdentityAgent=/home/artem/.ssh/ssh_auth_sock";
|
||||
Options = "reconnect,ServerAliveInterval=15,uid=1000,gid=1000,IdentityAgent=${config.home.homeDirectory}/.ssh/ssh_auth_sock";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
@@ -26,8 +39,8 @@ _: {
|
||||
|
||||
programs.zsh.loginExtra = ''
|
||||
if [ -n "$SSH_AUTH_SOCK" ]; then
|
||||
mkdir -p ~/src/haremote
|
||||
[ -z "$(ls -A ~/src/haremote 2>/dev/null)" ] && systemctl --user restart home-artem-src-haremote.mount
|
||||
mkdir -p ${haremote-path}
|
||||
[ -z "$(ls -A ${haremote-path} 2>/dev/null)" ] && systemctl --user restart ${haremote-unit}.mount
|
||||
fi
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,184 +1,35 @@
|
||||
{
|
||||
modulesPath,
|
||||
pkgs,
|
||||
pkgs-screen,
|
||||
trustedSSHKeys,
|
||||
jail-nix,
|
||||
identities,
|
||||
primaryUser,
|
||||
...
|
||||
}:
|
||||
let
|
||||
jail = jail-nix.lib.init pkgs;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
"${modulesPath}/virtualisation/lxc-container.nix"
|
||||
];
|
||||
# Disable legacy channel behavior that lxc-container brings in via installer/cd-dvd/channel.nix.
|
||||
system.installer.channel.enable = false;
|
||||
|
||||
# Impermanence setup:
|
||||
# 1. There's no initrd/stage 1 in LXC container; /sbin/init is invoked after
|
||||
# LXC finishes setting up special and user-configured filesystems. Any
|
||||
# options in boot.initrd, as well as neededForBoot fileSystems won't be
|
||||
# respected.
|
||||
# 2. Non-boot fileSystems (aka systemd) mount too late for systemd or nixos
|
||||
# persistence to be instantiated, so we have to create this script below.
|
||||
# 3. The expectation from host is to mount /home and /nix. Root filesystem
|
||||
# will also be a disk, as that's Incus requirement; the host should clean
|
||||
# it up periodically using: "incus rebuild --empty <vm>".
|
||||
# 4. Since rootfs will be empty after rebuild, you have to point LXC at the
|
||||
# current init (instead of /sbin/init), by adding to the "config:" section
|
||||
# in "incus config edit <vm>":
|
||||
# raw.lxc: lxc.init.cmd = /nix/var/nix/profiles/system/init
|
||||
system.activationScripts.persistence = {
|
||||
deps = [ "specialfs" ];
|
||||
text = ''
|
||||
persist() {
|
||||
local item="$1"
|
||||
local constructor="''${item%%:*}"
|
||||
local target="''${item#*:}"
|
||||
|
||||
mkdir -p "$(dirname "$target")"
|
||||
$constructor "$target"
|
||||
|
||||
if ! mountpoint -q "$target"; then
|
||||
local source="/home/persistent/$target"
|
||||
|
||||
mkdir -p "$(dirname "$source")"
|
||||
$constructor "$source"
|
||||
|
||||
mount --bind "$source" "$target"
|
||||
fi
|
||||
}
|
||||
|
||||
for item in \
|
||||
"mkdir -p:/var/lib/nixos" \
|
||||
"mkdir -p:/var/lib/systemd" \
|
||||
"touch:/etc/machine-id" \
|
||||
"touch:/etc/ssh/ssh_host_ed25519_key" \
|
||||
; do
|
||||
persist "$item"
|
||||
done
|
||||
|
||||
chmod 0600 /etc/ssh/ssh_host_ed25519_key
|
||||
|
||||
# lxc-container.nix installBootloader/installInitScript will attempt to
|
||||
# symlink /sbin/init, so we have to create the parent directory.
|
||||
mkdir -p /sbin
|
||||
'';
|
||||
};
|
||||
system.activationScripts.users.deps = [ "persistence" ];
|
||||
# This is supposed to persist machine-id, but fails.
|
||||
systemd.services.systemd-machine-id-commit.enable = false;
|
||||
|
||||
users.users.artem = {
|
||||
users.users.${primaryUser} = {
|
||||
uid = 1000;
|
||||
isNormalUser = true;
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"docker"
|
||||
"kvm"
|
||||
];
|
||||
openssh.authorizedKeys.keys = trustedSSHKeys;
|
||||
openssh.authorizedKeys.keys = identities.getAccessKeys { user = primaryUser; };
|
||||
shell = pkgs.zsh;
|
||||
linger = true; # Keep sshfs mounted even on logout.
|
||||
};
|
||||
# Create /etc/zshrc that loads the nix-darwin environment.
|
||||
programs.zsh.enable = true;
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
||||
virtualisation.docker.enable = true;
|
||||
|
||||
documentation.man.enable = true;
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
# TODO: clean this up against artem@deimos
|
||||
git
|
||||
pkgs-screen.screen
|
||||
# TODO: move below into hosts/deimos/home.nix
|
||||
sshfs
|
||||
|
||||
# https://unix.stackexchange.com/questions/651165/using-systemd-to-mount-remote-filesystems-in-user-bus
|
||||
# Have to run the wrapper due to SUID.
|
||||
(pkgs.writeShellScriptBin "umount.fuse.sshfs" ''
|
||||
exec /run/wrappers/bin/fusermount -u "$1"
|
||||
'')
|
||||
|
||||
file
|
||||
nixfmt
|
||||
nixd
|
||||
home-assistant-cli
|
||||
yt-dlp
|
||||
|
||||
# From hosts/common/tools.nix:
|
||||
# Software debug
|
||||
iotop
|
||||
dool # dool --time --disk -D /dev/sde,/dev/sdf --top-bio --top-cpu --zfs-arc
|
||||
strace
|
||||
ltrace
|
||||
smem # smem -tkP nginx
|
||||
|
||||
# Hardware info and tunables
|
||||
parted
|
||||
hdparm
|
||||
efivar
|
||||
efibootmgr
|
||||
sg3_utils # sg_unmap
|
||||
lm_sensors # sensors
|
||||
nvme-cli
|
||||
dmidecode
|
||||
ethtool
|
||||
|
||||
# jailed-gemini --yolo
|
||||
(jail "jailed-gemini" pkgs.gemini-cli (
|
||||
with jail.combinators;
|
||||
[
|
||||
network
|
||||
time-zone
|
||||
no-new-session
|
||||
mount-cwd
|
||||
|
||||
(readwrite (noescape "~/.gemini"))
|
||||
# The above is a stow-controlled symlink to the following.
|
||||
(readwrite (noescape "~/dotfiles/legacy/.gemini"))
|
||||
|
||||
(add-pkg-deps (
|
||||
with pkgs;
|
||||
[
|
||||
bashInteractive
|
||||
curl
|
||||
wget
|
||||
jq
|
||||
git
|
||||
which
|
||||
ripgrep
|
||||
gnugrep
|
||||
gnused
|
||||
gawkInteractive
|
||||
ps
|
||||
findutils
|
||||
gzip
|
||||
unzip
|
||||
gnutar
|
||||
diffutils
|
||||
coreutils
|
||||
procps
|
||||
|
||||
python3
|
||||
|
||||
nix
|
||||
]
|
||||
))
|
||||
]
|
||||
))
|
||||
];
|
||||
|
||||
# unprivileged LXCs can't set net.ipv4.ping_group_range
|
||||
security.wrappers.ping = {
|
||||
owner = "root";
|
||||
group = "root";
|
||||
capabilities = "cap_net_raw+p";
|
||||
source = "${pkgs.iputils.out}/bin/ping";
|
||||
};
|
||||
|
||||
# For building RPi configs. Extra steps are handled by the host (nas).
|
||||
# https://discuss.linuxcontainers.org/t/systemd-binfmt-service-is-masked/21566/4
|
||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||
@@ -187,6 +38,4 @@ in
|
||||
hostName = "deimos";
|
||||
domain = "home.arpa";
|
||||
};
|
||||
|
||||
system.stateVersion = "25.11"; # Never change this.
|
||||
}
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
trustedSSHKeys,
|
||||
identities,
|
||||
primaryUser,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
../common/home.nix
|
||||
];
|
||||
|
||||
home.packages = with pkgs; [
|
||||
dosbox-staging # dosbox appears broken on darwin
|
||||
|
||||
@@ -19,7 +24,11 @@
|
||||
|
||||
home.activation.setupAuthorizedKeys = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
run install -m 0600 -D \
|
||||
${pkgs.writeText "keys" (builtins.concatStringsSep "\n" trustedSSHKeys)} \
|
||||
${
|
||||
pkgs.writeText "keys" (
|
||||
builtins.concatStringsSep "\n" (identities.getAccessKeys { user = primaryUser; })
|
||||
)
|
||||
} \
|
||||
${config.home.homeDirectory}/.ssh/ephemeral_sshd/authorized_keys
|
||||
'';
|
||||
|
||||
|
||||
29
legacy/.gemini/config/mcp_config.json
Normal file
29
legacy/.gemini/config/mcp_config.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"nix": {
|
||||
"command": "nix",
|
||||
"args": [
|
||||
"run",
|
||||
"github:utensils/mcp-nixos",
|
||||
"--"
|
||||
]
|
||||
},
|
||||
"ha": {
|
||||
"command": "nix",
|
||||
"args": [
|
||||
"shell",
|
||||
"nixpkgs#uv",
|
||||
"nixpkgs#python3",
|
||||
"--command",
|
||||
"uv",
|
||||
"tool",
|
||||
"run",
|
||||
"ha-mcp"
|
||||
],
|
||||
"env": {
|
||||
"UV_PYTHON_DOWNLOADS": "never",
|
||||
"UV_PYTHON_PREFERENCE": "system"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"nix": {
|
||||
"command": "nix",
|
||||
"args": [
|
||||
"run",
|
||||
"github:utensils/mcp-nixos",
|
||||
"--"
|
||||
]
|
||||
},
|
||||
"ha": {
|
||||
"url": "${HASS_SERVER}/mcp_server/sse",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ${HASS_TOKEN}"
|
||||
},
|
||||
"timeout": 5000
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"auth": {
|
||||
"selectedType": "oauth-personal"
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
"sessionRetention": {
|
||||
"warningAcknowledged": true,
|
||||
"enabled": true,
|
||||
"maxAge": "30d"
|
||||
},
|
||||
"preferredEditor": "vim"
|
||||
},
|
||||
"model": {
|
||||
"name": "auto-gemini-3"
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
[color]
|
||||
ui = auto
|
||||
[alias]
|
||||
co = checkout
|
||||
st = status
|
||||
di = diff -w --no-prefix
|
||||
df = diff
|
||||
dc = diff --cached
|
||||
ci = commit
|
||||
br = branch
|
||||
lg = log -p --decorate=full --show-signature
|
||||
lol = log --graph --decorate=full --pretty=oneline --abbrev-commit
|
||||
lola = log --graph --decorate=full --pretty=oneline --abbrev-commit --all
|
||||
ls = ls-files
|
||||
# Show files ignored by git:
|
||||
ign = ls-files -o -i --exclude-standard
|
||||
[apply]
|
||||
whitespace = nowarn
|
||||
[push]
|
||||
default = tracking
|
||||
[rebase]
|
||||
stat = yes
|
||||
[format]
|
||||
pretty = fuller
|
||||
[fetch]
|
||||
prune = yes
|
||||
[credential "https://source.developers.google.com"]
|
||||
helper = gcloud.sh
|
||||
[core]
|
||||
autocrlf = input
|
||||
[branch]
|
||||
# 0 times I wanted this when doing "git checkout".
|
||||
autoSetupMerge = false
|
||||
# Set up new branches in a way that "git pull" does a rebase by default.
|
||||
autoSetupRebase = always
|
||||
[gpg]
|
||||
format = ssh
|
||||
[commit]
|
||||
gpgsign = true
|
||||
|
||||
|
||||
# Must always go last, to be able to override the settings above.
|
||||
[include]
|
||||
path = ~/.config/gitconfig_local
|
||||
@@ -1,34 +0,0 @@
|
||||
# http://aperiodic.net/screen/commands:start
|
||||
|
||||
# see accompanying file ~/.ssh/rc
|
||||
setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
|
||||
|
||||
# no screen blinking on bell
|
||||
vbell off
|
||||
startup_message off
|
||||
# disable "New screen..." message
|
||||
msgwait 0
|
||||
defscrollback 10240
|
||||
# hostname, timestamp, LA in status bar
|
||||
caption always "%{+b}%H | %c %d.%m.%Y | Load: %l"
|
||||
# colored window list
|
||||
hardstatus alwayslastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<"
|
||||
# Launch login shells
|
||||
shell -${SHELL}
|
||||
# 256color support
|
||||
#termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
|
||||
term screen-256color
|
||||
#defbce "on"
|
||||
# beep on activity monitor alert (C-a M)
|
||||
# ex.: 12:37 activity -> 7$ zsh
|
||||
activity "%c activity -> %n%f %t^G"
|
||||
|
||||
# Alt Left/Right = switch windows
|
||||
bindkey "^[[1;3D" prev
|
||||
bindkey "^[[1;3C" next
|
||||
bindkey "^[b" prev
|
||||
bindkey "^[f" next
|
||||
# Alt N = new window
|
||||
bindkey "^[n" screen
|
||||
|
||||
shelltitle '% |zsh'
|
||||
@@ -1,25 +0,0 @@
|
||||
Host *
|
||||
# Share SSH connection.
|
||||
# If disabling, consider impact on ssh agent forwarding in screen
|
||||
# sessions (see .ssh/rc file).
|
||||
ControlMaster auto
|
||||
ControlPath ~/.ssh/ctl/%r@%h:%p
|
||||
ControlPersist 10m
|
||||
# When a shared connection is broken (remote reboot), detect it faster.
|
||||
ServerAliveInterval 11
|
||||
ServerAliveCountMax 2
|
||||
|
||||
ConnectTimeout 10
|
||||
AddKeysToAgent yes
|
||||
|
||||
#Host custom-host-with-xorg
|
||||
# HostName custom-hostname
|
||||
# User crate
|
||||
# ForwardX11 yes
|
||||
# ForwardX11Trusted yes
|
||||
|
||||
#Host always-changing-keys-dont-care
|
||||
# StrictHostKeyChecking no
|
||||
# UserKnownHostsFile=/dev/null
|
||||
|
||||
Include config.d/*
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# When SSH-ing with agent forwarding enabled, this variable is set by sshd
|
||||
# itself. However, an existing screen session that we attach to will not have
|
||||
# its SSH_AUTH_SOCK environment variable updated, so we hardcode this path in
|
||||
# .screenrc and create a symlink to keep it alive.
|
||||
#
|
||||
# It WILL break if two sessions are opened to a machine, and a newer one is
|
||||
# terminated. ControlMaster in .ssh/config solves this problem by sharing the
|
||||
# connection (and as a result, sharing SSH agent socket).
|
||||
[ -n "$SSH_AUTH_SOCK" ] && ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
|
||||
@@ -35,6 +35,9 @@ if exists("+undofile")
|
||||
" Enable the persistent undo file(s)
|
||||
set undodir=~/.vim/undo
|
||||
set undofile
|
||||
if !isdirectory(expand(&undodir))
|
||||
call mkdir(expand(&undodir), "p")
|
||||
endif
|
||||
endif
|
||||
|
||||
set switchbuf+=usetab " Switch to existing tab; open a new tab for the new buf
|
||||
|
||||
@@ -8,9 +8,9 @@ export PATH="${HOME}/bin:${PATH}"
|
||||
# Since we exec right afterwards, there's no point in setting this shell up.
|
||||
if [[ -o login ]]; then
|
||||
[ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] && \
|
||||
[ -z "$STY" ] && \
|
||||
which screen 2>/dev/null && \
|
||||
exec screen -URR
|
||||
[ -z "$TMUX" ] && \
|
||||
command -v tmux >/dev/null && \
|
||||
exec tmux new -A -D -s main
|
||||
fi
|
||||
|
||||
HISTFILE=~/.zsh_history
|
||||
@@ -62,7 +62,6 @@ alias grep='grep --line-buffered --color=auto'
|
||||
alias ipt='iptables -nvL --line-numbers'
|
||||
alias ip6t='ip6tables -nvL --line-numbers'
|
||||
alias tcpdump='tcpdump -l'
|
||||
alias ag='ag -C 2 --pager="$PAGER" --smart-case'
|
||||
alias mysql='mysql --select_limit=1000'
|
||||
alias logcat='adb logcat -v "color printable usec year zone" -T 10'
|
||||
alias readelf='readelf -W'
|
||||
@@ -81,6 +80,10 @@ starttransfer: %{time_starttransfer} | \
|
||||
total: %{time_total} | \
|
||||
size: %{size_download}\n"'
|
||||
|
||||
rg() {
|
||||
command rg -C 2 --smart-case --pretty "$@" | pager
|
||||
}
|
||||
|
||||
# nix-deploy # current host
|
||||
# nix-deploy nas # deploy nas
|
||||
# nix-deploy test secondary # deploy secondary but do not add to boot
|
||||
@@ -125,7 +128,22 @@ nix-deploy() {
|
||||
cmd=(nixos-rebuild)
|
||||
command -v nixos-rebuild >/dev/null 2>&1 || cmd=(nix run "nixpkgs#nixos-rebuild" --)
|
||||
|
||||
"${cmd[@]}" "$action" --flake ".#$config" --target-host "$target" --sudo "$@" |& nom
|
||||
nix build ".#nixosConfigurations.$config.config.system.build.toplevel" \
|
||||
--out-link "result.$config" |& nom
|
||||
local build_status=$pipestatus[1]
|
||||
if (( build_status != 0 )); then
|
||||
return $build_status
|
||||
fi
|
||||
|
||||
if [[ "$action" != "build" ]]; then
|
||||
# Bypass nixos-rebuild self-update check which errors in
|
||||
# flake-only setups when --store-path is used.
|
||||
_NIXOS_REBUILD_REEXEC=1 "${cmd[@]}" "$action" \
|
||||
--store-path "$(readlink -f "result.$config")" \
|
||||
--target-host "$target" \
|
||||
--sudo \
|
||||
"$@"
|
||||
fi
|
||||
}
|
||||
|
||||
myip() {
|
||||
|
||||
@@ -1,24 +1,75 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
identities,
|
||||
primaryUser,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home.username = primaryUser;
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
home.packages = with pkgs; [
|
||||
stow
|
||||
wget
|
||||
gemini-cli
|
||||
silver-searcher
|
||||
antigravity-cli
|
||||
yubikey-manager
|
||||
];
|
||||
|
||||
home.activation.stowLegacy = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
if [ -d "$HOME/dotfiles" ]; then
|
||||
if [ -d "$HOME/dotfiles/legacy" ]; then
|
||||
run ${pkgs.stow}/bin/stow -d $HOME/dotfiles -t $HOME legacy
|
||||
fi
|
||||
'';
|
||||
|
||||
home.activation.report-changes = lib.hm.dag.entryAnywhere ''
|
||||
# oldGenPath can be undefined with home-manager used as part of NixOS config
|
||||
if [ -n "''${oldGenPath+x}" ]; then
|
||||
${pkgs.nvd}/bin/nvd diff $oldGenPath $newGenPath
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.git = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
alias = {
|
||||
co = "checkout";
|
||||
st = "status";
|
||||
di = "diff -w --no-prefix";
|
||||
df = "diff";
|
||||
dc = "diff --cached";
|
||||
ci = "commit";
|
||||
br = "branch";
|
||||
lg = "log -p --decorate=full --show-signature";
|
||||
lol = "log --graph --decorate=full --pretty=oneline --abbrev-commit";
|
||||
lola = "log --graph --decorate=full --pretty=oneline --abbrev-commit --all";
|
||||
ls = "ls-files";
|
||||
# Show files ignored by git:
|
||||
ign = "ls-files -o -i --exclude-standard";
|
||||
};
|
||||
|
||||
color.ui = "auto";
|
||||
apply.whitespace = "nowarn";
|
||||
push.default = "tracking";
|
||||
rebase.stat = "yes";
|
||||
format.pretty = "fuller";
|
||||
fetch.prune = "yes";
|
||||
core.autocrlf = "input";
|
||||
branch = {
|
||||
# 0 times I wanted this when doing "git checkout".
|
||||
autoSetupMerge = false;
|
||||
# Set up new branches in a way that "git pull" does a rebase by default.
|
||||
autoSetupRebase = "always";
|
||||
};
|
||||
gpg.format = "ssh";
|
||||
gpg.ssh.allowedSignersFile = "${pkgs.writeText "allowed_signers" (
|
||||
lib.concatStringsSep "\n" (identities.getSigningEntries { })
|
||||
)}";
|
||||
credential."https://source.developers.google.com".helper = "gcloud.sh";
|
||||
};
|
||||
};
|
||||
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
initContent = ''
|
||||
@@ -29,9 +80,9 @@
|
||||
fi
|
||||
|
||||
if [ -r ~/dotfiles/migrated/.zshrc ]; then
|
||||
# Hack for faster iterations
|
||||
. ~/dotfiles/migrated/.zshrc
|
||||
else
|
||||
# If no custom override is available, use the one bundled with flake.
|
||||
. ${../../migrated/.zshrc}
|
||||
fi
|
||||
'';
|
||||
@@ -82,5 +133,104 @@
|
||||
};
|
||||
};
|
||||
|
||||
programs.tmux = {
|
||||
enable = true;
|
||||
shortcut = "a"; # ^a
|
||||
escapeTime = 0;
|
||||
historyLimit = 10240;
|
||||
|
||||
# hjkl HJKL and mouse to switch between and resize panels.
|
||||
mouse = true;
|
||||
keyMode = "vi";
|
||||
customPaneNavigationAndResize = true;
|
||||
|
||||
extraConfig = ''
|
||||
set-environment -g SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
|
||||
set-option -g update-environment "DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION"
|
||||
|
||||
# Instead of flashing or beeping, blink the window in status.
|
||||
set -g visual-bell off
|
||||
set -g monitor-activity on
|
||||
set -g bell-action none
|
||||
set -g window-status-activity-style "fg=yellow,blink"
|
||||
|
||||
# Requires support from terminal (e.g. iTerm2).
|
||||
set -s set-clipboard on
|
||||
|
||||
# For scrolling through logs.
|
||||
bind y set-window-option synchronize-panes
|
||||
|
||||
# Panel configuration.
|
||||
bind | split-window -h -c "#{pane_current_path}"
|
||||
bind - split-window -v -c "#{pane_current_path}"
|
||||
bind Enter resize-pane -Z
|
||||
|
||||
# Navigation.
|
||||
bind -n M-Up new-window -c "#{pane_current_path}"
|
||||
bind -n M-Down confirm-before -p "kill-window #W? (y/n)" kill-window
|
||||
bind -n M-Left previous-window
|
||||
bind -n M-Right next-window
|
||||
|
||||
# Status bar.
|
||||
set -g status-interval 5
|
||||
set -g status-position bottom
|
||||
set -g status-style "bg=default,fg=white"
|
||||
|
||||
set -g status-left-length 20
|
||||
set -g status-left "#[fg=green,bold]#H #[fg=white]| "
|
||||
|
||||
set -g status-right-length 60
|
||||
set -g status-right "#[fg=cyan]%H:%M%Z %d.%m.%Y #[fg=white]| #[fg=yellow]Load: #(cut -d ' ' -f 1-3 /proc/loadavg)"
|
||||
|
||||
set -g status-justify left
|
||||
set -g window-status-format "#[fg=white,dim]#I:#W#F"
|
||||
set -g window-status-current-format "#[fg=white,bold,bg=blue] #I:#W#F "
|
||||
'';
|
||||
};
|
||||
|
||||
programs.ssh = {
|
||||
enable = true;
|
||||
enableDefaultConfig = false;
|
||||
includes = [ "config.d/*" ];
|
||||
|
||||
settings = {
|
||||
"*" = {
|
||||
# Share SSH connection.
|
||||
# If disabling, consider impact on ssh agent forwarding in screen
|
||||
# sessions (see .ssh/rc file).
|
||||
ControlMaster = "auto";
|
||||
ControlPath = "~/.ssh/ctl/%r@%h:%p";
|
||||
ControlPersist = "10m";
|
||||
|
||||
# When a shared connection is broken (remote reboot), detect it faster.
|
||||
ServerAliveInterval = 11;
|
||||
ServerAliveCountMax = 2;
|
||||
|
||||
ConnectTimeout = 10;
|
||||
AddKeysToAgent = "yes";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
home.file = {
|
||||
".ssh/rc" = {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/bin/sh
|
||||
|
||||
# When SSH-ing with agent forwarding enabled, this variable is set by sshd
|
||||
# itself. However, an existing screen session that we attach to will not have
|
||||
# its SSH_AUTH_SOCK environment variable updated, so we hardcode this path in
|
||||
# .screenrc and create a symlink to keep it alive.
|
||||
#
|
||||
# It WILL break if two sessions are opened to a machine, and a newer one is
|
||||
# terminated. ControlMaster in .ssh/config solves this problem by sharing the
|
||||
# connection (and as a result, sharing SSH agent socket).
|
||||
[ -n "$SSH_AUTH_SOCK" ] && ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
|
||||
'';
|
||||
};
|
||||
".ssh/ctl/.keep".text = "";
|
||||
};
|
||||
|
||||
home.stateVersion = "25.11"; # never modify
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{ primaryUser, ... }:
|
||||
{ lib, primaryUser, ... }:
|
||||
{
|
||||
imports = [
|
||||
./common.nix
|
||||
];
|
||||
|
||||
home.homeDirectory = "/home/${primaryUser}";
|
||||
home.homeDirectory = lib.mkDefault "/home/${primaryUser}";
|
||||
}
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
{ pkgs, primaryUser, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
primaryUser,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./common.nix
|
||||
];
|
||||
|
||||
home.homeDirectory = "/Users/${primaryUser}";
|
||||
home.homeDirectory = lib.mkDefault "/Users/${primaryUser}";
|
||||
|
||||
home.packages = with pkgs; [
|
||||
secretive
|
||||
vlc-bin
|
||||
|
||||
# Faster and more feature-rich than Terminal.
|
||||
# TODO: https://iterm2.com/shell_integration/zsh
|
||||
iterm2
|
||||
|
||||
# Newer OpenSSH client to support FIDO2 keys.
|
||||
@@ -29,6 +35,10 @@
|
||||
TripleClickSelectsFullWrappedLines = true;
|
||||
WordChars = "/-._~";
|
||||
PromptOnQuit = false;
|
||||
|
||||
# Use system browser to open links.
|
||||
NoSyncBrowserUpsell = 1;
|
||||
NoSyncBrowserUpsell_selection = 1;
|
||||
};
|
||||
home.file."Library/Application Support/iTerm2/DynamicProfiles/nix-profile.json".text =
|
||||
builtins.toJSON
|
||||
@@ -41,6 +51,7 @@
|
||||
|
||||
Columns = 160;
|
||||
Rows = 45;
|
||||
"Scrollback Lines" = 1000000;
|
||||
|
||||
# For tmux selection and moving borders.
|
||||
"Mouse Reporting" = true;
|
||||
@@ -67,6 +78,10 @@
|
||||
export SSH_AUTH_SOCK=~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh
|
||||
'';
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
# TODO: defaults read NSGlobalDomain
|
||||
# https://nix-darwin.github.io/nix-darwin/manual/index.html
|
||||
# -> set system.defaults.NSGlobalDomain
|
||||
# or system.defaults.CustomSystemPreferences
|
||||
|
||||
programs.vscode.enable = true;
|
||||
}
|
||||
|
||||
148
modules/nixos/jailed-agy.nix
Normal file
148
modules/nixos/jailed-agy.nix
Normal file
@@ -0,0 +1,148 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
jail-nix,
|
||||
primaryUser,
|
||||
...
|
||||
}:
|
||||
let
|
||||
jail = jail-nix.lib.init pkgs;
|
||||
allPackages =
|
||||
with pkgs;
|
||||
[
|
||||
bashInteractive
|
||||
curl
|
||||
wget
|
||||
jq
|
||||
git
|
||||
which
|
||||
ripgrep
|
||||
gnugrep
|
||||
gnused
|
||||
gawkInteractive
|
||||
ps
|
||||
findutils
|
||||
gzip
|
||||
unzip
|
||||
gnutar
|
||||
diffutils
|
||||
coreutils
|
||||
procps
|
||||
|
||||
python3
|
||||
python3Packages.pip
|
||||
esphome
|
||||
|
||||
ruby
|
||||
go
|
||||
gcc
|
||||
gnumake
|
||||
pkg-config
|
||||
|
||||
nix
|
||||
]
|
||||
++ config.programs.jailed-agy.extraPackages;
|
||||
in
|
||||
{
|
||||
options.programs.jailed-agy = {
|
||||
extraPackages = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.package;
|
||||
default = [ ];
|
||||
description = "Extra packages to append to the jailed-agy environment.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
environment.systemPackages = [
|
||||
(jail "jailed-agy" pkgs.antigravity-cli (
|
||||
with jail.combinators;
|
||||
[
|
||||
network
|
||||
time-zone
|
||||
no-new-session
|
||||
mount-cwd
|
||||
|
||||
# Enforce that the wrapper is not run as root/privileged user
|
||||
(add-runtime ''
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
echo "Error: jailed-agy must not be run as root/privileged user!" >&2
|
||||
exit 1
|
||||
fi
|
||||
'')
|
||||
|
||||
# Automatically append --dangerously-skip-permissions to agy invocation
|
||||
(set-argv [
|
||||
"--dangerously-skip-permissions"
|
||||
(noescape "\"$@\"")
|
||||
])
|
||||
|
||||
(readwrite (noescape "~/.gemini"))
|
||||
# The above is a stow-controlled symlink to the following.
|
||||
(readwrite (noescape "~/dotfiles/legacy/.gemini"))
|
||||
|
||||
# Enable easy installation of pip packages in the current directory.
|
||||
(set-env "PYTHONPATH" (noescape "\"$PWD/.pip-packages\""))
|
||||
(set-env "PIP_TARGET" (noescape "\"$PWD/.pip-packages\""))
|
||||
(set-env "PIP_CACHE_DIR" (noescape "\"$PWD/.pip-cache\""))
|
||||
(set-env "PIP_BREAK_SYSTEM_PACKAGES" "1")
|
||||
|
||||
# Enable easy installation and persistence of RubyGems in the current directory.
|
||||
(set-env "GEM_HOME" (noescape "\"$PWD/.gem\""))
|
||||
|
||||
# Enable easy installation and persistence of Go modules and caches in the current directory.
|
||||
(set-env "GOPATH" (noescape "\"$PWD/.go\""))
|
||||
(set-env "GOCACHE" (noescape "\"$PWD/.go-cache\""))
|
||||
|
||||
# Preconfigure compiler and linker flags dynamically for all jail packages.
|
||||
# This allows compiling Ruby gems (e.g. ffi, which requires libffi) and Go packages
|
||||
# (e.g. YubiKey plugins, which require pcsclite) out-of-the-box.
|
||||
(set-env "PKG_CONFIG_PATH" (
|
||||
lib.concatStringsSep ":" (map (pkg: "${pkg.dev or pkg}/lib/pkgconfig") allPackages)
|
||||
))
|
||||
(set-env "NIX_CFLAGS_COMPILE" (
|
||||
lib.concatStringsSep " " (map (pkg: "-isystem ${pkg.dev or pkg}/include") allPackages)
|
||||
))
|
||||
(set-env "NIX_LDFLAGS" (
|
||||
lib.concatStringsSep " " (map (pkg: "-L${pkg.out or pkg}/lib") allPackages)
|
||||
))
|
||||
|
||||
# Mount system and user profiles so their packages are automatically available at runtime
|
||||
(try-ro-bind "/run/current-system/sw" "/run/current-system/sw")
|
||||
(try-ro-bind "/etc/profiles/per-user/${primaryUser}" "/etc/profiles/per-user/${primaryUser}")
|
||||
|
||||
# Mount Nix files and directories to support nix-shell and Nix operations in jail
|
||||
(try-ro-bind "/nix/store" "/nix/store")
|
||||
(try-ro-bind "/nix/var/nix/daemon-socket" "/nix/var/nix/daemon-socket")
|
||||
(try-ro-bind "/nix/var/nix/profiles" "/nix/var/nix/profiles")
|
||||
(try-ro-bind "/etc/nix" "/etc/nix")
|
||||
(try-ro-bind "/etc/static" "/etc/static")
|
||||
|
||||
# Forward Nix environment variables
|
||||
(try-fwd-env "NIX_REMOTE")
|
||||
(try-fwd-env "NIX_PATH")
|
||||
(try-fwd-env "NIX_SSL_CERT_FILE")
|
||||
|
||||
(add-pkg-deps allPackages)
|
||||
|
||||
# Prepend local project binary directories, system, and user bin paths to the jail's PATH.
|
||||
# Note: We place this after `add-pkg-deps` so that local paths take highest precedence.
|
||||
# We use explicit double quotes to allow bash to expand $PWD at runtime and handle spaces.
|
||||
(
|
||||
state:
|
||||
state
|
||||
// {
|
||||
env = state.env // {
|
||||
PATH =
|
||||
if state.env ? PATH && state.env.PATH != "" then
|
||||
"\"\$PWD/.gem/bin:\$PWD/.go/bin:\$PWD/.pip-packages/bin:/run/current-system/sw/bin:/etc/profiles/per-user/${primaryUser}/bin:${state.env.PATH}\""
|
||||
else
|
||||
"\"\$PWD/.gem/bin:\$PWD/.go/bin:\$PWD/.pip-packages/bin:/run/current-system/sw/bin:/etc/profiles/per-user/${primaryUser}/bin\"";
|
||||
};
|
||||
}
|
||||
)
|
||||
]
|
||||
))
|
||||
];
|
||||
};
|
||||
}
|
||||
23
modules/nixos/linux-headless.nix
Normal file
23
modules/nixos/linux-headless.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# Create /etc/zshrc that loads the nix-darwin environment.
|
||||
programs.zsh.enable = true;
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
||||
programs.mosh.enable = true;
|
||||
|
||||
documentation.man.enable = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
# https://unix.stackexchange.com/questions/651165/using-systemd-to-mount-remote-filesystems-in-user-bus
|
||||
# Have to run the wrapper due to SUID.
|
||||
(pkgs.writeShellScriptBin "umount.fuse.sshfs" ''
|
||||
exec /run/wrappers/bin/fusermount -u "$1"
|
||||
'')
|
||||
];
|
||||
|
||||
system.stateVersion = "25.11"; # Never change this.
|
||||
}
|
||||
76
modules/nixos/linux-lxc.nix
Normal file
76
modules/nixos/linux-lxc.nix
Normal file
@@ -0,0 +1,76 @@
|
||||
{
|
||||
modulesPath,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
"${modulesPath}/virtualisation/lxc-container.nix"
|
||||
];
|
||||
# Disable legacy channel behavior that lxc-container brings in via installer/cd-dvd/channel.nix.
|
||||
system.installer.channel.enable = false;
|
||||
|
||||
# Impermanence setup:
|
||||
# 1. There's no initrd/stage 1 in LXC container; /sbin/init is invoked after
|
||||
# LXC finishes setting up special and user-configured filesystems. Any
|
||||
# options in boot.initrd, as well as neededForBoot fileSystems won't be
|
||||
# respected.
|
||||
# 2. Non-boot fileSystems (aka systemd) mount too late for systemd or nixos
|
||||
# persistence to be instantiated, so we have to create this script below.
|
||||
# 3. The expectation from host is to mount /home and /nix. Root filesystem
|
||||
# will also be a disk, as that's Incus requirement; the host should clean
|
||||
# it up periodically using: "incus rebuild --empty <vm>".
|
||||
# 4. Since rootfs will be empty after rebuild, you have to point LXC at the
|
||||
# current init (instead of /sbin/init), by adding to the "config:" section
|
||||
# in "incus config edit <vm>":
|
||||
# raw.lxc: lxc.init.cmd = /nix/var/nix/profiles/system/init
|
||||
system.activationScripts.persistence = {
|
||||
deps = [ "specialfs" ];
|
||||
text = ''
|
||||
persist() {
|
||||
local item="$1"
|
||||
local constructor="''${item%%:*}"
|
||||
local target="''${item#*:}"
|
||||
|
||||
mkdir -p "$(dirname "$target")"
|
||||
$constructor "$target"
|
||||
|
||||
if ! mountpoint -q "$target"; then
|
||||
local source="/home/persistent/$target"
|
||||
|
||||
mkdir -p "$(dirname "$source")"
|
||||
$constructor "$source"
|
||||
|
||||
mount --bind "$source" "$target"
|
||||
fi
|
||||
}
|
||||
|
||||
for item in \
|
||||
"mkdir -p:/var/lib/nixos" \
|
||||
"mkdir -p:/var/lib/systemd" \
|
||||
"mkdir -p:/var/lib/docker" \
|
||||
"touch:/etc/machine-id" \
|
||||
"touch:/etc/ssh/ssh_host_ed25519_key" \
|
||||
; do
|
||||
persist "$item"
|
||||
done
|
||||
|
||||
chmod 0600 /etc/ssh/ssh_host_ed25519_key
|
||||
|
||||
# lxc-container.nix installBootloader/installInitScript will attempt to
|
||||
# symlink /sbin/init, so we have to create the parent directory.
|
||||
mkdir -p /sbin
|
||||
'';
|
||||
};
|
||||
system.activationScripts.users.deps = [ "persistence" ];
|
||||
# This is supposed to persist machine-id, but fails.
|
||||
systemd.services.systemd-machine-id-commit.enable = false;
|
||||
|
||||
# unprivileged LXCs can't set net.ipv4.ping_group_range
|
||||
security.wrappers.ping = {
|
||||
owner = "root";
|
||||
group = "root";
|
||||
capabilities = "cap_net_raw+p";
|
||||
source = "${pkgs.iputils.out}/bin/ping";
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user