Compare commits
69 Commits
shared-ste
...
boxy-app-l
| Author | SHA1 | Date | |
|---|---|---|---|
| f8ee011d27 | |||
| 4a4ea6316d | |||
| b75c43257b | |||
| 63d741e55e | |||
| 9ed3ad8fb8 | |||
| 330cd6f92b | |||
| 3b9d9ed60b | |||
| 2a017f584b | |||
| 47c4e0097e | |||
| 2b7cf66e69 | |||
| eed88a9ac0 | |||
| c02b74cce4 | |||
| 1132dda8a0 | |||
| 2696262ed3 | |||
| 40ac30c78f | |||
| ac986e37e7 | |||
| d3664fcf9d | |||
| 5591087be1 | |||
| 09a701989c | |||
| 62dbf84b4b | |||
| 81799cd6d2 | |||
| 35d965e432 | |||
| 2c4e6cc060 | |||
| 5c6dba77f0 | |||
| a6effa3944 | |||
| 0d53b86fcb | |||
| 6bf5c502d8 | |||
| 05592a9ec2 | |||
| 923aaf9e95 | |||
| 23b1c450a2 | |||
| a65a8e9af7 | |||
| 56b1111f54 | |||
| 6bf0a37533 | |||
| 396c8e0318 | |||
| b359acfcf0 | |||
| 455181365a | |||
| 06dd292524 | |||
| 8924fdbc6d | |||
| 671dc229de | |||
| 14cdee1468 | |||
| c6276c9758 | |||
| 31880e21e8 | |||
| 3d95995ebc | |||
| fb9dd66cf4 | |||
| a90b30eb1c | |||
| b22a4952e5 | |||
| 32f70d46b2 | |||
| d76e9e73f5 | |||
| 53504ffde3 | |||
| e5be1b5675 | |||
| 878962ad41 | |||
| 6d5eadcf6a | |||
| c323d1301b | |||
| 6cdbd2e300 | |||
| f0bf2f2d8c | |||
| 9d6abce8cc | |||
| 68f63db930 | |||
| 2e39984d14 | |||
| 9fed36e6ee | |||
| 38a8997448 | |||
| a3c8995422 | |||
| b9bb5d387f | |||
| e3aff80a97 | |||
| 574c8e6482 | |||
| 0f59a558cd | |||
| 14b7de30f6 | |||
| 8b676203e7 | |||
| beeb7acefd | |||
| a512d9bc06 |
77
CLAUDE.md
77
CLAUDE.md
@@ -10,7 +10,7 @@ This is a NixOS configuration repository using flakes, managing multiple machine
|
|||||||
|
|
||||||
### Flake Structure
|
### Flake Structure
|
||||||
- **flake.nix**: Main entry point defining inputs (nixpkgs, home-manager, plasma-manager, etc.) and outputs for multiple NixOS configurations
|
- **flake.nix**: Main entry point defining inputs (nixpkgs, home-manager, plasma-manager, etc.) and outputs for multiple NixOS configurations
|
||||||
- **Machines**: `nix-book`, `boxy`, `wixos` (WSL configuration)
|
- **Machines**: `nix-book`, `boxy`, `wixos` (WSL configuration), `zix790prors`, `live-usb`, `johno-macbookpro` (Darwin/macOS)
|
||||||
- **Home configurations**: Standalone home-manager configuration for user `johno`
|
- **Home configurations**: Standalone home-manager configuration for user `johno`
|
||||||
|
|
||||||
### Directory Structure
|
### Directory Structure
|
||||||
@@ -28,6 +28,12 @@ The repository uses a custom "roles" system where each role is a NixOS module wi
|
|||||||
- `roles.users`: User account management
|
- `roles.users`: User account management
|
||||||
- `roles.virtualisation`: Virtualization setup
|
- `roles.virtualisation`: Virtualization setup
|
||||||
- `roles.kodi`: Kodi media center
|
- `roles.kodi`: Kodi media center
|
||||||
|
- `roles.nvidia`: NVIDIA GPU configuration
|
||||||
|
- `roles.printing`: Printing support (CUPS)
|
||||||
|
- `roles.spotifyd`: Spotify daemon
|
||||||
|
- `roles.btrfs`: Btrfs filesystem configuration
|
||||||
|
- `roles.nfs-mounts`: NFS mount configuration
|
||||||
|
- `roles.darwin`: macOS-specific configurations
|
||||||
|
|
||||||
Example role usage in machine configuration:
|
Example role usage in machine configuration:
|
||||||
```nix
|
```nix
|
||||||
@@ -43,9 +49,40 @@ roles = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Home-Manager Role System
|
||||||
|
The repository also uses a modular home-manager role system for user-space configuration:
|
||||||
|
|
||||||
|
**Available Home Roles:**
|
||||||
|
- `home.roles.base`: Core CLI tools, git, ssh, bash, rbw (enabled everywhere)
|
||||||
|
- `home.roles.desktop`: GUI applications, Firefox, KDE services
|
||||||
|
- `home.roles.office`: LibreOffice, OpenSCAD (heavy packages)
|
||||||
|
- `home.roles.media`: VLC, Jellyfin, Moonlight (media consumption)
|
||||||
|
- `home.roles.development`: Custom packages, kubectl, development tools
|
||||||
|
- `home.roles.communication`: Element, Nextcloud Talk, Google cookie tools
|
||||||
|
- `home.roles.sync`: Syncthing service and tray (for file synchronization)
|
||||||
|
- `home.roles.kdeconnect`: KDE Connect for device integration
|
||||||
|
- `home.roles.gaming`: Gaming applications (future expansion)
|
||||||
|
|
||||||
|
**Role-Based Home Configurations:**
|
||||||
|
- `home-desktop.nix`: Full-featured desktop for development workstations
|
||||||
|
- `home-media-center.nix`: Living room media consumption and gaming setup (boxy)
|
||||||
|
- `home-laptop-compact.nix`: Essential tools only, excludes office/media for storage constraints (nix-book)
|
||||||
|
- `home-live-usb.nix`: Minimal setup for live environments, no persistent services
|
||||||
|
- `home-darwin-work.nix`: macOS work laptop configuration
|
||||||
|
|
||||||
|
**Machine-Specific Role Usage:**
|
||||||
|
- **nix-book**: Compact laptop → excludes office/media roles due to SSD space constraints
|
||||||
|
- **boxy**: Living room media center → optimized for media consumption, excludes sync/office (shared machine)
|
||||||
|
- **zix790prors**: All-purpose workstation → full desktop experience with all roles enabled
|
||||||
|
- **wixos**: WSL2 development → full desktop experience, inherits from zix790prors Windows host
|
||||||
|
- **live-usb**: Temporary environment → only base + desktop roles, no persistent services
|
||||||
|
- **johno-macbookpro**: macOS work laptop → Darwin-specific configuration with development tools
|
||||||
|
|
||||||
## Common Commands
|
## Common Commands
|
||||||
|
|
||||||
### Building and Switching Configurations
|
### Building and Switching Configurations
|
||||||
|
|
||||||
|
**NixOS (Linux):**
|
||||||
```bash
|
```bash
|
||||||
# Build and switch to a specific machine configuration
|
# Build and switch to a specific machine configuration
|
||||||
sudo nixos-rebuild switch --flake .#<hostname>
|
sudo nixos-rebuild switch --flake .#<hostname>
|
||||||
@@ -57,10 +94,22 @@ nixos-rebuild build --flake .#<hostname>
|
|||||||
home-manager switch --flake .#johno
|
home-manager switch --flake .#johno
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Darwin (macOS):**
|
||||||
|
```bash
|
||||||
|
# Build and switch to Darwin configuration
|
||||||
|
darwin-rebuild switch --flake .#johno-macbookpro
|
||||||
|
|
||||||
|
# Build without switching
|
||||||
|
darwin-rebuild build --flake .#johno-macbookpro
|
||||||
|
```
|
||||||
|
|
||||||
### Available Machine Configurations
|
### Available Machine Configurations
|
||||||
- `nix-book`: Uses `home/home-nix-book.nix`
|
- `nix-book`: Compact laptop with storage constraints, uses `home/home-laptop-compact.nix`
|
||||||
- `boxy`: Gaming desktop with AMD GPU, uses `home/home.nix`
|
- `boxy`: Shared living room media center/gaming desktop with AMD GPU, uses `home/home-media-center.nix`
|
||||||
- `wixos`: WSL configuration, uses `home/home.nix`
|
- `zix790prors`: Powerful all-purpose workstation (gaming, 3D modeling, development), dual-boots Windows 11 with shared btrfs /games partition, uses `home/home-desktop.nix`
|
||||||
|
- `wixos`: WSL2 development environment running in Windows partition of zix790prors, uses `home/home-desktop.nix`
|
||||||
|
- `live-usb`: Bootable ISO configuration, uses `home/home-live-usb.nix`
|
||||||
|
- `johno-macbookpro`: macOS work laptop, uses `home/home-darwin-work.nix`
|
||||||
|
|
||||||
### Flake Operations
|
### Flake Operations
|
||||||
```bash
|
```bash
|
||||||
@@ -81,14 +130,28 @@ sudo ./bootstrap.sh <hostname>
|
|||||||
```
|
```
|
||||||
This script pulls from the remote git repository and applies the configuration.
|
This script pulls from the remote git repository and applies the configuration.
|
||||||
|
|
||||||
|
### Build Live USB ISO
|
||||||
|
Use the provided script to build a bootable ISO:
|
||||||
|
```bash
|
||||||
|
./build-liveusb.sh
|
||||||
|
```
|
||||||
|
Creates an ISO suitable for Ventoy and other USB boot tools in `./result/iso/`.
|
||||||
|
|
||||||
## Development Workflow
|
## Development Workflow
|
||||||
|
|
||||||
### Adding New Machines
|
### Adding New Machines
|
||||||
|
|
||||||
|
**NixOS:**
|
||||||
1. Create new directory in `machines/<hostname>/`
|
1. Create new directory in `machines/<hostname>/`
|
||||||
2. Add `configuration.nix` with role assignments
|
2. Add `configuration.nix` with role assignments
|
||||||
3. Include hardware-configuration.nix (generated by nixos-generate-config)
|
3. Include hardware-configuration.nix (generated by nixos-generate-config)
|
||||||
4. Add nixosConfiguration to flake.nix outputs
|
4. Add nixosConfiguration to flake.nix outputs
|
||||||
|
|
||||||
|
**Darwin (macOS):**
|
||||||
|
1. Create new directory in `machines/<hostname>/`
|
||||||
|
2. Add `configuration.nix` with Darwin role assignments
|
||||||
|
3. Add darwinConfiguration to flake.nix outputs
|
||||||
|
|
||||||
### Adding New Roles
|
### Adding New Roles
|
||||||
1. Create directory in `roles/<role-name>/`
|
1. Create directory in `roles/<role-name>/`
|
||||||
2. Create `default.nix` with module definition using mkEnableOption
|
2. Create `default.nix` with module definition using mkEnableOption
|
||||||
@@ -107,4 +170,8 @@ This script pulls from the remote git repository and applies the configuration.
|
|||||||
- **Locale**: en_US.UTF-8, America/Los_Angeles timezone
|
- **Locale**: en_US.UTF-8, America/Los_Angeles timezone
|
||||||
- **SSH**: OpenSSH enabled on all configurations
|
- **SSH**: OpenSSH enabled on all configurations
|
||||||
- **Garbage collection**: Automatic, deletes older than 10 days
|
- **Garbage collection**: Automatic, deletes older than 10 days
|
||||||
- **Unfree packages**: Allowed globally
|
- **Unfree packages**: Allowed globally
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
- **Sudo access**: Claude Code does not have sudo access. Ask the user to run elevated commands like `sudo nixos-rebuild switch`
|
||||||
19
build-liveusb.sh
Executable file
19
build-liveusb.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Build Live USB ISO from flake configuration
|
||||||
|
# Creates an uncompressed ISO suitable for Ventoy and other USB boot tools
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Building Live USB ISO..."
|
||||||
|
nix build .#nixosConfigurations.live-usb.config.system.build.isoImage --show-trace
|
||||||
|
|
||||||
|
if [ -f "./result/iso/"*.iso ]; then
|
||||||
|
iso_file=$(ls ./result/iso/*.iso)
|
||||||
|
echo "✅ Build complete!"
|
||||||
|
echo "📁 ISO location: $iso_file"
|
||||||
|
echo "💾 Ready for Ventoy or dd to USB"
|
||||||
|
else
|
||||||
|
echo "❌ Build failed - no ISO file found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
51
flake.lock
generated
51
flake.lock
generated
@@ -43,11 +43,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1752402455,
|
"lastModified": 1759172751,
|
||||||
"narHash": "sha256-mCHfZhQKdTj2JhCFcqfOfa3uKZbwUkPQbd0/zPnhOE8=",
|
"narHash": "sha256-E8W8sRXfrvkFW26GuuiWq6QfReU7m5+cngwHuRo/3jc=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "bf893ad4cbf46610dd1b620c974f824e266cd1df",
|
"rev": "12fa8548feefa9a10266ba65152fd1a787cdde8f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -56,17 +56,37 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nix-darwin": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1758805352,
|
||||||
|
"narHash": "sha256-BHdc43Lkayd+72W/NXRKHzX5AZ+28F3xaUs3a88/Uew=",
|
||||||
|
"owner": "nix-darwin",
|
||||||
|
"repo": "nix-darwin",
|
||||||
|
"rev": "c48e963a5558eb1c3827d59d21c5193622a1477c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-darwin",
|
||||||
|
"repo": "nix-darwin",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixos-wsl": {
|
"nixos-wsl": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1752199438,
|
"lastModified": 1758785683,
|
||||||
"narHash": "sha256-xSBMmGtq8K4Qv80TMqREmESCAsRLJRHAbFH2T/2Bf1Y=",
|
"narHash": "sha256-mRn51IeEBXeNh5a6xNLylk4PKBX0s/QQxgkEbYoPq/w=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NixOS-WSL",
|
"repo": "NixOS-WSL",
|
||||||
"rev": "d34d9412556d3a896e294534ccd25f53b6822e80",
|
"rev": "1bfb978f2f6261b6086e04af17f9418e1fe36d70",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -78,11 +98,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1751792365,
|
"lastModified": 1758277210,
|
||||||
"narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=",
|
"narHash": "sha256-iCGWf/LTy+aY0zFu8q12lK8KuZp7yvdhStehhyX1v8w=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "1fd8bada0b6117e6c7eb54aad5813023eed37ccb",
|
"rev": "8eaee110344796db060382e15d3af0a9fc396e0e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -94,11 +114,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1751984180,
|
"lastModified": 1759036355,
|
||||||
"narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0",
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -118,11 +138,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1748196248,
|
"lastModified": 1759157415,
|
||||||
"narHash": "sha256-1iHjsH6/5UOerJEoZKE+Gx1BgAoge/YcnUsOA4wQ/BU=",
|
"narHash": "sha256-Fg8cOnVoIe0uQ38UpR6XZzRCwDsjjozVwfevW9yCLI0=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "plasma-manager",
|
"repo": "plasma-manager",
|
||||||
"rev": "b7697abe89967839b273a863a3805345ea54ab56",
|
"rev": "df5b3e6da631f732c26c6044c7cccb8706b4f479",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -135,6 +155,7 @@
|
|||||||
"inputs": {
|
"inputs": {
|
||||||
"google-cookie-retrieval": "google-cookie-retrieval",
|
"google-cookie-retrieval": "google-cookie-retrieval",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
|
"nix-darwin": "nix-darwin",
|
||||||
"nixos-wsl": "nixos-wsl",
|
"nixos-wsl": "nixos-wsl",
|
||||||
"nixpkgs": "nixpkgs_2",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"plasma-manager": "plasma-manager"
|
"plasma-manager": "plasma-manager"
|
||||||
|
|||||||
81
flake.nix
81
flake.nix
@@ -4,6 +4,11 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
nixos-wsl.url = "github:nix-community/NixOS-WSL/main";
|
nixos-wsl.url = "github:nix-community/NixOS-WSL/main";
|
||||||
|
|
||||||
|
nix-darwin = {
|
||||||
|
url = "github:nix-darwin/nix-darwin";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
home-manager = {
|
home-manager = {
|
||||||
url = "github:nix-community/home-manager";
|
url = "github:nix-community/home-manager";
|
||||||
@@ -23,8 +28,9 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, nixos-wsl, ... } @ inputs: let
|
outputs = { self, nixpkgs, nixos-wsl, ... } @ inputs: let
|
||||||
baseModules = [
|
nixosModules = [
|
||||||
./roles
|
./roles
|
||||||
|
] ++ [
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
{
|
{
|
||||||
home-manager.useGlobalPkgs = true;
|
home-manager.useGlobalPkgs = true;
|
||||||
@@ -37,13 +43,32 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
darwinModules = [
|
||||||
|
./roles/darwin.nix
|
||||||
|
] ++ [
|
||||||
|
inputs.home-manager.darwinModules.home-manager
|
||||||
|
{
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
home-manager.extraSpecialArgs = {
|
||||||
|
globalInputs = inputs;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
in {
|
in {
|
||||||
nixosConfigurations.nix-book = nixpkgs.lib.nixosSystem rec {
|
nixosConfigurations.nix-book = nixpkgs.lib.nixosSystem rec {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = baseModules ++ [
|
modules = nixosModules ++ [
|
||||||
./machines/nix-book/configuration.nix
|
./machines/nix-book/configuration.nix
|
||||||
{
|
{
|
||||||
home-manager.users.johno = import ./home/home-nix-book.nix;
|
home-manager.users.johno = {
|
||||||
|
imports = [ ./home/home-laptop-compact.nix ];
|
||||||
|
# Machine-specific overrides
|
||||||
|
home.i3_sway.extraSwayConfig = {
|
||||||
|
output.eDP-1.scale = "1.75";
|
||||||
|
};
|
||||||
|
};
|
||||||
home-manager.extraSpecialArgs = { inherit system; };
|
home-manager.extraSpecialArgs = { inherit system; };
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -51,11 +76,11 @@
|
|||||||
|
|
||||||
nixosConfigurations.boxy = nixpkgs.lib.nixosSystem rec {
|
nixosConfigurations.boxy = nixpkgs.lib.nixosSystem rec {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = baseModules ++ [
|
modules = nixosModules ++ [
|
||||||
./machines/boxy/configuration.nix
|
./machines/boxy/configuration.nix
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
{
|
{
|
||||||
home-manager.users.johno = import ./home/home.nix;
|
home-manager.users.johno = import ./home/home-media-center.nix;
|
||||||
home-manager.extraSpecialArgs = { inherit system; };
|
home-manager.extraSpecialArgs = { inherit system; };
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -63,27 +88,51 @@
|
|||||||
|
|
||||||
nixosConfigurations.wixos = nixpkgs.lib.nixosSystem rec {
|
nixosConfigurations.wixos = nixpkgs.lib.nixosSystem rec {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = baseModules ++ [
|
modules = nixosModules ++ [
|
||||||
nixos-wsl.nixosModules.default
|
nixos-wsl.nixosModules.default
|
||||||
./machines/wixos/configuration.nix
|
./machines/wixos/configuration.nix
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
{
|
{
|
||||||
home-manager.users.johno = import ./home/home.nix;
|
home-manager.users.johno = import ./home/home-desktop.nix;
|
||||||
home-manager.extraSpecialArgs = { inherit system; };
|
home-manager.extraSpecialArgs = { inherit system; };
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
homeConfigurations."johno" = inputs.home-manager.lib.homeManagerConfiguration {
|
nixosConfigurations.zix790prors = nixpkgs.lib.nixosSystem rec {
|
||||||
pkgs = inputs.nixpkgs.legacyPackages."x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = [
|
modules = nixosModules ++ [
|
||||||
inputs.plasma-manager.homeManagerModules.plasma-manager
|
./machines/zix790prors/configuration.nix
|
||||||
./home/home.nix
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
{
|
||||||
|
home-manager.users.johno = import ./home/home-desktop.nix;
|
||||||
|
home-manager.extraSpecialArgs = { inherit system; };
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Live USB ISO configuration
|
||||||
|
nixosConfigurations.live-usb = nixpkgs.lib.nixosSystem rec {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
modules = nixosModules ++ [
|
||||||
|
./machines/live-usb/configuration.nix
|
||||||
|
{
|
||||||
|
home-manager.users.nixos = import ./home/home-live-usb.nix;
|
||||||
|
home-manager.extraSpecialArgs = { inherit system; };
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Darwin/macOS configurations
|
||||||
|
darwinConfigurations."blkfv4yf49kt7" = inputs.nix-darwin.lib.darwinSystem rec {
|
||||||
|
system = "aarch64-darwin";
|
||||||
|
modules = darwinModules ++ [
|
||||||
|
./machines/johno-macbookpro/configuration.nix
|
||||||
|
{
|
||||||
|
home-manager.users.johno = import ./home/home-darwin-work.nix;
|
||||||
|
home-manager.extraSpecialArgs = { inherit system; };
|
||||||
|
}
|
||||||
];
|
];
|
||||||
extraSpecialArgs = {
|
|
||||||
system = "x86_64-linux";
|
|
||||||
globalInputs = inputs;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
56
home/home-darwin-work.nix
Normal file
56
home/home-darwin-work.nix
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{ config, lib, pkgs, globalInputs, system, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
customPkgs = pkgs.callPackage ../packages {};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Provide arguments to role modules
|
||||||
|
_module.args = { inherit customPkgs; };
|
||||||
|
# Home Manager configuration for Darwin work laptop
|
||||||
|
# Corporate-friendly setup with essential development tools
|
||||||
|
|
||||||
|
home.username = lib.mkForce "johno";
|
||||||
|
home.homeDirectory = lib.mkForce "/Users/johno";
|
||||||
|
home.stateVersion = "24.05";
|
||||||
|
|
||||||
|
# Override Darwin-incompatible settings from base role
|
||||||
|
programs.rbw.settings.pinentry = lib.mkForce pkgs.pinentry_mac;
|
||||||
|
|
||||||
|
programs.bash.initExtra = ''
|
||||||
|
export NODE_EXTRA_CA_CERTS=/opt/homebrew/etc/ca-certificates/cert.pem
|
||||||
|
export COREPACK_NPM_REGISTRY=https://global.block-artifacts.com/artifactory/api/npm/square-npm/
|
||||||
|
export COREPACK_INTEGRITY_KEYS=0
|
||||||
|
|
||||||
|
export NVM_DIR="$HOME/.nvm"
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||||
|
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.zsh.enable = true;
|
||||||
|
programs.zsh.initContent = ''
|
||||||
|
export NODE_EXTRA_CA_CERTS=/opt/homebrew/etc/ca-certificates/cert.pem
|
||||||
|
export COREPACK_NPM_REGISTRY=https://global.block-artifacts.com/artifactory/api/npm/square-npm/
|
||||||
|
export COREPACK_INTEGRITY_KEYS=0
|
||||||
|
export NVM_DIR="$HOME/.nvm"
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
|
||||||
|
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Keep SSH and Git disabled to avoid conflicts with work environment
|
||||||
|
programs.ssh.enable = lib.mkForce false;
|
||||||
|
programs.git.enable = lib.mkForce false;
|
||||||
|
programs.rbw.enable = lib.mkForce false;
|
||||||
|
|
||||||
|
home.shell.enableShellIntegration = true;
|
||||||
|
|
||||||
|
home.roles = {
|
||||||
|
base.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./roles
|
||||||
|
./modules/emacs
|
||||||
|
./modules/kubectl
|
||||||
|
./modules/tmux
|
||||||
|
];
|
||||||
|
}
|
||||||
38
home/home-desktop.nix
Normal file
38
home/home-desktop.nix
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{ pkgs, globalInputs, system, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
customPkgs = pkgs.callPackage ../packages {};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Provide arguments to role modules
|
||||||
|
_module.args = { inherit customPkgs; };
|
||||||
|
# Home Manager configuration for full desktop experience
|
||||||
|
home.username = "johno";
|
||||||
|
home.homeDirectory = "/home/johno";
|
||||||
|
home.stateVersion = "24.05";
|
||||||
|
|
||||||
|
# Enable all desktop roles for full-featured experience
|
||||||
|
home.roles = {
|
||||||
|
base.enable = true;
|
||||||
|
desktop.enable = true;
|
||||||
|
office.enable = true;
|
||||||
|
media.enable = true;
|
||||||
|
development.enable = true;
|
||||||
|
communication.enable = true;
|
||||||
|
sync.enable = true;
|
||||||
|
kdeconnect.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
targets.genericLinux.enable = true;
|
||||||
|
home.sessionVariables = {};
|
||||||
|
home.sessionPath = [];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./roles
|
||||||
|
./modules/emacs
|
||||||
|
./modules/i3+sway
|
||||||
|
./modules/kubectl
|
||||||
|
./modules/plasma-manager
|
||||||
|
./modules/tmux
|
||||||
|
];
|
||||||
|
}
|
||||||
41
home/home-laptop-compact.nix
Normal file
41
home/home-laptop-compact.nix
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{ config, lib, pkgs, globalInputs, system, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
customPkgs = pkgs.callPackage ../packages {};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Provide arguments to role modules
|
||||||
|
_module.args = { inherit customPkgs; };
|
||||||
|
# Home Manager configuration for compact laptop setups
|
||||||
|
# Optimized for space-constrained environments
|
||||||
|
|
||||||
|
home.username = "johno";
|
||||||
|
home.homeDirectory = "/home/johno";
|
||||||
|
home.stateVersion = "24.05";
|
||||||
|
|
||||||
|
# Enable essential roles only (exclude heavy office/media packages)
|
||||||
|
home.roles = {
|
||||||
|
base.enable = true;
|
||||||
|
desktop.enable = true;
|
||||||
|
development.enable = true;
|
||||||
|
communication.enable = true;
|
||||||
|
kdeconnect.enable = true;
|
||||||
|
media.enable = true;
|
||||||
|
sync.enable = true;
|
||||||
|
# office.enable = false; # Excluded for storage constraints
|
||||||
|
};
|
||||||
|
|
||||||
|
targets.genericLinux.enable = true;
|
||||||
|
home.sessionVariables = {};
|
||||||
|
home.sessionPath = [];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./roles
|
||||||
|
./modules/emacs
|
||||||
|
./modules/i3+sway
|
||||||
|
./modules/kubectl
|
||||||
|
./modules/plasma-manager
|
||||||
|
./modules/tmux
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
42
home/home-live-usb.nix
Normal file
42
home/home-live-usb.nix
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{ pkgs, globalInputs, system, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
customPkgs = pkgs.callPackage ../packages {};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Provide arguments to role modules
|
||||||
|
_module.args = { inherit customPkgs; };
|
||||||
|
# Home Manager configuration for live USB environments
|
||||||
|
# Minimal setup without persistent services
|
||||||
|
|
||||||
|
home.username = "nixos";
|
||||||
|
home.homeDirectory = "/home/nixos";
|
||||||
|
home.stateVersion = "24.05";
|
||||||
|
|
||||||
|
# Enable minimal roles only (no sync or kdeconnect for live environment)
|
||||||
|
home.roles = {
|
||||||
|
base.enable = true;
|
||||||
|
desktop.enable = true;
|
||||||
|
# development.enable = false; # Not needed for live USB
|
||||||
|
# communication.enable = false; # Not needed for live USB
|
||||||
|
# office.enable = false; # Not needed for live USB
|
||||||
|
# media.enable = false; # Not needed for live USB
|
||||||
|
# sync.enable = false; # No persistent sync on live USB
|
||||||
|
# kdeconnect.enable = false; # No device integration on live USB
|
||||||
|
};
|
||||||
|
|
||||||
|
targets.genericLinux.enable = true;
|
||||||
|
home.sessionVariables = {};
|
||||||
|
home.sessionPath = [];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./roles
|
||||||
|
./modules/emacs
|
||||||
|
./modules/i3+sway
|
||||||
|
./modules/kubectl
|
||||||
|
./modules/plasma-manager
|
||||||
|
./modules/tmux
|
||||||
|
];
|
||||||
|
|
||||||
|
# Live USB specific overrides can go here if needed
|
||||||
|
}
|
||||||
42
home/home-media-center.nix
Normal file
42
home/home-media-center.nix
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{ pkgs, globalInputs, system, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
customPkgs = pkgs.callPackage ../packages {};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Provide arguments to role modules
|
||||||
|
_module.args = { inherit customPkgs; };
|
||||||
|
# Home Manager configuration for media center setups
|
||||||
|
# Optimized for living room media consumption and gaming
|
||||||
|
|
||||||
|
home.username = "johno";
|
||||||
|
home.homeDirectory = "/home/johno";
|
||||||
|
home.stateVersion = "24.05";
|
||||||
|
|
||||||
|
# Enable media center focused roles
|
||||||
|
home.roles = {
|
||||||
|
base.enable = true;
|
||||||
|
desktop.enable = true;
|
||||||
|
media.enable = true;
|
||||||
|
communication.enable = true;
|
||||||
|
kdeconnect.enable = true;
|
||||||
|
development.enable = true;
|
||||||
|
# office.enable = false; # Not needed for media center
|
||||||
|
# sync.enable = false; # Shared machine, no personal file sync
|
||||||
|
};
|
||||||
|
|
||||||
|
targets.genericLinux.enable = true;
|
||||||
|
home.sessionVariables = {};
|
||||||
|
home.sessionPath = [];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./roles
|
||||||
|
./modules/emacs
|
||||||
|
./modules/i3+sway
|
||||||
|
./modules/kubectl
|
||||||
|
./modules/plasma-manager
|
||||||
|
./modules/tmux
|
||||||
|
];
|
||||||
|
|
||||||
|
# Media center specific overrides can go here if needed
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./home.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
home.i3_sway.extraSwayConfig = {
|
|
||||||
output.eDP-1.scale = "1.75";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
204
home/home.nix
204
home/home.nix
@@ -1,204 +0,0 @@
|
|||||||
{ pkgs, customPkgs, globalInputs, system, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
customPkgs = pkgs.callPackage ../packages {};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Home Manager needs a bit of information about you and the paths it should
|
|
||||||
# manage.
|
|
||||||
home.username = "johno";
|
|
||||||
home.homeDirectory = "/home/johno";
|
|
||||||
|
|
||||||
# This value determines the Home Manager release that your configuration is
|
|
||||||
# compatible with. This helps avoid breakage when a new Home Manager release
|
|
||||||
# introduces backwards incompatible changes.
|
|
||||||
#
|
|
||||||
# You should not change this value, even if you update Home Manager. If you do
|
|
||||||
# want to update the value, then make sure to first check the Home Manager
|
|
||||||
# release notes.
|
|
||||||
home.stateVersion = "24.05"; # Please read the comment before changing.
|
|
||||||
|
|
||||||
# The home.packages option allows you to install Nix packages into your
|
|
||||||
# environment.
|
|
||||||
home.packages = [
|
|
||||||
# # Adds the 'hello' command to your environment. It prints a friendly
|
|
||||||
# # "Hello, world!" when run.
|
|
||||||
# pkgs.hello
|
|
||||||
|
|
||||||
# # It is sometimes useful to fine-tune packages, for example, by applying
|
|
||||||
# # overrides. You can do that directly here, just don't forget the
|
|
||||||
# # parentheses. Maybe you want to install Nerd Fonts with a limited number of
|
|
||||||
# # fonts?
|
|
||||||
# (pkgs.nerdfonts.override { fonts = [ "FantasqueSansMono" ]; })
|
|
||||||
|
|
||||||
# # You can also create simple shell scripts directly inside your
|
|
||||||
# # configuration. For example, this adds a command 'my-hello' to your
|
|
||||||
# # environment:
|
|
||||||
# (pkgs.writeShellScriptBin "my-hello" ''
|
|
||||||
# echo "Hello, ${config.home.username}!"
|
|
||||||
# '')
|
|
||||||
|
|
||||||
pkgs.bitwarden
|
|
||||||
pkgs.claude-code
|
|
||||||
pkgs.codex
|
|
||||||
pkgs.dunst
|
|
||||||
pkgs.element-desktop
|
|
||||||
pkgs.fd
|
|
||||||
#pkgs.fluffychat # security vulnerability in current version
|
|
||||||
pkgs.goose-cli
|
|
||||||
pkgs.gzip
|
|
||||||
pkgs.htop
|
|
||||||
pkgs.jellyfin-media-player
|
|
||||||
pkgs.keepassxc
|
|
||||||
pkgs.killall
|
|
||||||
pkgs.kitty
|
|
||||||
pkgs.less
|
|
||||||
pkgs.moonlight-qt
|
|
||||||
pkgs.ncdu
|
|
||||||
pkgs.nextcloud-talk-desktop
|
|
||||||
pkgs.openscad-unstable
|
|
||||||
pkgs.pandoc
|
|
||||||
#pkgs.pinentry-qt
|
|
||||||
#pkgs.pytest
|
|
||||||
pkgs.shellcheck
|
|
||||||
pkgs.solaar # Logitech management software
|
|
||||||
(pkgs.snapcast.override { pulseaudioSupport = true; })
|
|
||||||
pkgs.tmux
|
|
||||||
pkgs.waybar
|
|
||||||
pkgs.wofi
|
|
||||||
pkgs.vlc
|
|
||||||
|
|
||||||
## Kubernetes cluster management
|
|
||||||
pkgs.kubectl
|
|
||||||
pkgs.kubernetes-helm
|
|
||||||
|
|
||||||
globalInputs.google-cookie-retrieval.packages.${system}.default
|
|
||||||
];
|
|
||||||
|
|
||||||
# Home Manager is pretty good at managing dotfiles. The primary way to manage
|
|
||||||
# plain files is through 'home.file'.
|
|
||||||
home.file = {
|
|
||||||
# # Building this configuration will create a copy of 'dotfiles/screenrc' in
|
|
||||||
# # the Nix store. Activating the configuration will then make '~/.screenrc' a
|
|
||||||
# # symlink to the Nix store copy.
|
|
||||||
# ".screenrc".source = dotfiles/screenrc;
|
|
||||||
|
|
||||||
# # You can also set the file content immediately.
|
|
||||||
# ".gradle/gradle.properties".text = ''
|
|
||||||
# org.gradle.console=verbose
|
|
||||||
# org.gradle.daemon.idletimeout=3600000
|
|
||||||
# '';
|
|
||||||
};
|
|
||||||
|
|
||||||
targets.genericLinux.enable = true;
|
|
||||||
|
|
||||||
# Home Manager can also manage your environment variables through
|
|
||||||
# 'home.sessionVariables'. These will be explicitly sourced when using a
|
|
||||||
# shell provided by Home Manager. If you don't want to manage your shell
|
|
||||||
# through Home Manager then you have to manually source 'hm-session-vars.sh'
|
|
||||||
# located at either
|
|
||||||
#
|
|
||||||
# ~/.nix-profile/etc/profile.d/hm-session-vars.sh
|
|
||||||
#
|
|
||||||
# or
|
|
||||||
#
|
|
||||||
# ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
|
|
||||||
#
|
|
||||||
# or
|
|
||||||
#
|
|
||||||
# /etc/profiles/per-user/johno/etc/profile.d/hm-session-vars.sh
|
|
||||||
#
|
|
||||||
home.sessionVariables = {
|
|
||||||
};
|
|
||||||
|
|
||||||
home.sessionPath = [
|
|
||||||
];
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
./modules/emacs
|
|
||||||
./modules/i3+sway
|
|
||||||
./modules/plasma-manager
|
|
||||||
./modules/tmux
|
|
||||||
];
|
|
||||||
|
|
||||||
programs.bash = {
|
|
||||||
enable = true;
|
|
||||||
initExtra = ''
|
|
||||||
codex() {
|
|
||||||
local key
|
|
||||||
key="$(rbw get openai-api-key-codex)"
|
|
||||||
OPENAI_API_KEY="$key" command codex "$@"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Let Home Manager install and manage itself.
|
|
||||||
programs.home-manager.enable = true;
|
|
||||||
|
|
||||||
programs.command-not-found.enable = true;
|
|
||||||
|
|
||||||
programs.firefox = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.git = {
|
|
||||||
enable = true;
|
|
||||||
userName = "John Ogle";
|
|
||||||
userEmail = "john@ogle.fyi";
|
|
||||||
extraConfig = {
|
|
||||||
safe.directory = "/etc/nixos";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.jq.enable = true;
|
|
||||||
|
|
||||||
programs.k9s.enable = true;
|
|
||||||
|
|
||||||
programs.neovim = {
|
|
||||||
enable = true;
|
|
||||||
viAlias = true;
|
|
||||||
vimAlias = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.rbw = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
email = "john@johnogle.info";
|
|
||||||
base_url = "https://bitwarden.johnogle.info";
|
|
||||||
pinentry = pkgs.pinentry-qt;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.spotify-player.enable = true;
|
|
||||||
|
|
||||||
programs.ssh = {
|
|
||||||
enable = true;
|
|
||||||
addKeysToAgent = "yes";
|
|
||||||
matchBlocks = {
|
|
||||||
"nucdeb1" = {
|
|
||||||
hostname = "nucdeb1.oglehome";
|
|
||||||
user = "root";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.kdeconnect = {
|
|
||||||
enable = true;
|
|
||||||
indicator = true;
|
|
||||||
package = pkgs.kdePackages.kdeconnect-kde;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.gnome-keyring = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.syncthing = {
|
|
||||||
enable = true;
|
|
||||||
tray = {
|
|
||||||
enable = true;
|
|
||||||
command = "syncthingtray --wait";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
xdg.enable = true;
|
|
||||||
}
|
|
||||||
@@ -6,20 +6,31 @@ let
|
|||||||
doomEmacs = pkgs.fetchFromGitHub {
|
doomEmacs = pkgs.fetchFromGitHub {
|
||||||
owner = "doomemacs";
|
owner = "doomemacs";
|
||||||
repo = "doomemacs";
|
repo = "doomemacs";
|
||||||
rev = "8406c1ff22b95bd0f816de4a0223fa3ce3c82568";
|
rev = "8f55404781edacf66fa330205533b002de3fb5ee";
|
||||||
sha256 = "sha256-rOkgOdmLESVAbOeEM9nJTzxyI+akdk48Ed2VlktOy3Q=";
|
sha256 = "sha256-vHwgENjip2+AFzs4oZfnKEAJKwf5Zid7fakImvxxQUw=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Shared emacs packages
|
||||||
|
emacsPackages = epkgs: [
|
||||||
|
epkgs.vterm
|
||||||
|
epkgs.treesit-grammars.with-all-grammars
|
||||||
|
];
|
||||||
|
|
||||||
|
# Default emacs configuration with vterm support
|
||||||
|
defaultEmacsPackage =
|
||||||
|
if pkgs.stdenv.isDarwin
|
||||||
|
then pkgs.emacs-macport.pkgs.withPackages emacsPackages
|
||||||
|
else pkgs.emacs.pkgs.withPackages emacsPackages;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
home.packages = [
|
home.packages = [
|
||||||
pkgs.emacs
|
|
||||||
|
|
||||||
pkgs.emacs-all-the-icons-fonts
|
pkgs.emacs-all-the-icons-fonts
|
||||||
pkgs.fira-code
|
pkgs.fira-code
|
||||||
pkgs.fontconfig
|
pkgs.fontconfig
|
||||||
pkgs.graphviz
|
pkgs.graphviz
|
||||||
pkgs.isort
|
pkgs.isort
|
||||||
|
#pkgs.libvterm # native vterm library
|
||||||
pkgs.nerd-fonts.fira-code
|
pkgs.nerd-fonts.fira-code
|
||||||
pkgs.nerd-fonts.droid-sans-mono
|
pkgs.nerd-fonts.droid-sans-mono
|
||||||
pkgs.nil # nix lsp language server
|
pkgs.nil # nix lsp language server
|
||||||
@@ -30,9 +41,18 @@ in
|
|||||||
pkgs.python3
|
pkgs.python3
|
||||||
];
|
];
|
||||||
|
|
||||||
|
programs.emacs = {
|
||||||
|
enable = true;
|
||||||
|
package = defaultEmacsPackage;
|
||||||
|
};
|
||||||
|
|
||||||
fonts.fontconfig.enable = true;
|
fonts.fontconfig.enable = true;
|
||||||
|
|
||||||
home.file."${config.xdg.configHome}/emacs".source = doomEmacs;
|
# Mount emacs and tree-sitter grammars from nix store
|
||||||
|
home.file = {
|
||||||
|
"${config.xdg.configHome}/emacs".source = doomEmacs;
|
||||||
|
};
|
||||||
|
|
||||||
home.sessionPath = [
|
home.sessionPath = [
|
||||||
"${config.xdg.configHome}/emacs/bin"
|
"${config.xdg.configHome}/emacs/bin"
|
||||||
];
|
];
|
||||||
@@ -42,6 +62,11 @@ in
|
|||||||
DOOMLOCALDIR = "${config.xdg.dataHome}/doom";
|
DOOMLOCALDIR = "${config.xdg.dataHome}/doom";
|
||||||
};
|
};
|
||||||
|
|
||||||
home.file."${config.xdg.configHome}/doom".source = ./doom;
|
# TODO: Use mkOutOfStoreSymlink instead?
|
||||||
|
home.activation.doomConfig = lib.hm.dag.entryAfter ["writeBoundary"] ''
|
||||||
|
# Always remove and recreate the symlink to ensure it points to the source directory
|
||||||
|
rm -rf "${config.xdg.configHome}/doom"
|
||||||
|
ln -sf "${config.home.homeDirectory}/nixos-configs/home/modules/emacs/doom" "${config.xdg.configHome}/doom"
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,20 @@
|
|||||||
;; wasn't installed correctly. Font issues are rarely Doom issues!
|
;; wasn't installed correctly. Font issues are rarely Doom issues!
|
||||||
(setq doom-font (font-spec :family "Fira Code"))
|
(setq doom-font (font-spec :family "Fira Code"))
|
||||||
|
|
||||||
|
;; Auto-install nerd-icons fonts if they're missing
|
||||||
|
(defun my/ensure-nerd-icons-fonts ()
|
||||||
|
"Check if nerd-icons fonts are installed and install them if missing."
|
||||||
|
(when (display-graphic-p)
|
||||||
|
(unless (find-font (font-spec :name "Symbols Nerd Font Mono"))
|
||||||
|
(when (fboundp 'nerd-icons-install-fonts)
|
||||||
|
(nerd-icons-install-fonts t)))))
|
||||||
|
|
||||||
|
(add-hook 'doom-init-ui-hook #'my/ensure-nerd-icons-fonts)
|
||||||
|
|
||||||
;; There are two ways to load a theme. Both assume the theme is installed and
|
;; There are two ways to load a theme. Both assume the theme is installed and
|
||||||
;; available. You can either set `doom-theme' or manually load a theme with the
|
;; available. You can either set `doom-theme' or manually load a theme with the
|
||||||
;; `load-theme' function. This is the default:
|
;; `load-theme' function. This is the default:
|
||||||
(setq doom-theme 'doom-one)
|
(setq doom-theme 'doom-tokyo-night)
|
||||||
|
|
||||||
;; This determines the style of line numbers in effect. If set to `nil', line
|
;; This determines the style of line numbers in effect. If set to `nil', line
|
||||||
;; numbers are disabled. For relative line numbers, set this to `relative'.
|
;; numbers are disabled. For relative line numbers, set this to `relative'.
|
||||||
@@ -44,6 +54,7 @@
|
|||||||
(setq org-directory "~/org/")
|
(setq org-directory "~/org/")
|
||||||
(after! org
|
(after! org
|
||||||
(setq org-agenda-span 'week
|
(setq org-agenda-span 'week
|
||||||
|
org-agenda-start-with-log-mode t
|
||||||
my-agenda-dirs '("projects" "roam")
|
my-agenda-dirs '("projects" "roam")
|
||||||
org-agenda-files (cons org-directory (mapcan (lambda (x) (directory-files-recursively
|
org-agenda-files (cons org-directory (mapcan (lambda (x) (directory-files-recursively
|
||||||
(expand-file-name x org-directory)
|
(expand-file-name x org-directory)
|
||||||
@@ -62,6 +73,13 @@
|
|||||||
'(("t" "Todo" entry (file+headline "~/org/todo.org" "Inbox")
|
'(("t" "Todo" entry (file+headline "~/org/todo.org" "Inbox")
|
||||||
"* TODO %? \n %i \n%a" :prepend t))))
|
"* TODO %? \n %i \n%a" :prepend t))))
|
||||||
|
|
||||||
|
(map! :after org-agenda
|
||||||
|
:map org-agenda-mode-map
|
||||||
|
:localleader
|
||||||
|
(:prefix ("v" . "view")
|
||||||
|
"d" #'org-agenda-day-view
|
||||||
|
"w" #'org-agenda-week-view))
|
||||||
|
|
||||||
;; (use-package! org-caldav
|
;; (use-package! org-caldav
|
||||||
;; :defer t
|
;; :defer t
|
||||||
;; :config
|
;; :config
|
||||||
@@ -78,10 +96,68 @@
|
|||||||
(output (shell-command-to-string cmd)))
|
(output (shell-command-to-string cmd)))
|
||||||
(string-trim output)))
|
(string-trim output)))
|
||||||
|
|
||||||
(use-package! gptel
|
(after! gptel
|
||||||
|
:config
|
||||||
|
(setq! gptel-api-key (my/get-rbw-password "openai-api-key-chatgpt-el")
|
||||||
|
gptel-default-mode 'org-mode
|
||||||
|
gptel-use-tools t
|
||||||
|
gptel-confirm-tool-calls 'always
|
||||||
|
gptel-include-reasoning 'ignore
|
||||||
|
gptel-model "qwen3:30b")
|
||||||
|
|
||||||
|
;; Set default backend to be Ollama-Local
|
||||||
|
(setq! gptel-backend
|
||||||
|
(gptel-make-ollama "Ollama-Local"
|
||||||
|
:host "localhost:11434"
|
||||||
|
:stream t
|
||||||
|
:models '(deepseek-r1 deepseek-r1-fullctx qwen3:30b qwen3:4b llama3.1 qwen2.5-coder mistral-nemo gpt-oss)))
|
||||||
|
|
||||||
|
;; Define custom tools
|
||||||
|
(gptel-make-tool
|
||||||
|
:name "run_shell_command"
|
||||||
|
:description "Execute shell commands and return output. Use this to run system commands, check file contents, or perform system operations."
|
||||||
|
:function (lambda (command)
|
||||||
|
(condition-case err
|
||||||
|
(shell-command-to-string command)
|
||||||
|
(error (format "Error running command: %s" (error-message-string err)))))
|
||||||
|
:args (list '(:name "command" :type "string" :description "Shell command to execute")))
|
||||||
|
|
||||||
|
(gptel-make-tool
|
||||||
|
:name "read_file"
|
||||||
|
:description "Read the contents of a file and return as text"
|
||||||
|
:function (lambda (filepath)
|
||||||
|
(condition-case err
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents (expand-file-name filepath))
|
||||||
|
(buffer-string))
|
||||||
|
(error (format "Error reading file %s: %s" filepath (error-message-string err)))))
|
||||||
|
:args (list '(:name "filepath" :type "string" :description "Path to the file to read")))
|
||||||
|
|
||||||
|
(gptel-make-tool
|
||||||
|
:name "list_directory"
|
||||||
|
:description "List contents of a directory"
|
||||||
|
:function (lambda (dirpath)
|
||||||
|
(condition-case err
|
||||||
|
(mapconcat 'identity
|
||||||
|
(directory-files (expand-file-name dirpath) nil "^[^.]")
|
||||||
|
"\n")
|
||||||
|
(error (format "Error listing directory %s: %s" dirpath (error-message-string err)))))
|
||||||
|
:args (list '(:name "dirpath" :type "string" :description "Directory path to list"))))
|
||||||
|
|
||||||
|
(use-package! claude-code-ide
|
||||||
:defer t
|
:defer t
|
||||||
:config
|
:config
|
||||||
(setq! gptel-api-key (my/get-rbw-password "openai-api-key-chatgpt-el")))
|
(claude-code-ide-emacs-tools-setup)
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("o" . "open")
|
||||||
|
:desc "Claude Code IDE" "c" #'claude-code-ide-menu)))
|
||||||
|
|
||||||
|
(after! gptel
|
||||||
|
(require 'gptel-tool-library)
|
||||||
|
(setq gptel-tool-library-use-maybe-safe t
|
||||||
|
gptel-tool-library-use-unsafe t)
|
||||||
|
(dolist (module '("bbdb" "buffer" "elisp" "emacs" "gnus" "os" "search-and-replace" "url"))
|
||||||
|
(gptel-tool-library-load-module module)))
|
||||||
|
|
||||||
;; Whenever you reconfigure a package, make sure to wrap your config in an
|
;; Whenever you reconfigure a package, make sure to wrap your config in an
|
||||||
;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
|
;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
doom ; what makes DOOM look the way it does
|
doom ; what makes DOOM look the way it does
|
||||||
doom-dashboard ; a nifty splash screen for Emacs
|
doom-dashboard ; a nifty splash screen for Emacs
|
||||||
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
|
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||||||
(emoji +unicode) ; 🙂
|
;;(emoji +unicode) ; 🙂
|
||||||
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
|
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
|
||||||
;;indent-guides ; highlighted indent columns
|
;;indent-guides ; highlighted indent columns
|
||||||
;;ligatures ; ligatures and symbols to make your code pretty again
|
;;ligatures ; ligatures and symbols to make your code pretty again
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
||||||
;;tabs ; a tab bar for Emacs
|
;;tabs ; a tab bar for Emacs
|
||||||
;;treemacs ; a project drawer, like neotree but cooler
|
;;treemacs ; a project drawer, like neotree but cooler
|
||||||
;;unicode ; extended unicode support for various languages
|
unicode ; extended unicode support for various languages
|
||||||
(vc-gutter +pretty) ; vcs diff in the fringe
|
(vc-gutter +pretty) ; vcs diff in the fringe
|
||||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||||
;;window-select ; visually switch windows
|
;;window-select ; visually switch windows
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
;;(format +onsave) ; automated prettiness
|
;;(format +onsave) ; automated prettiness
|
||||||
;;god ; run Emacs commands without modifier keys
|
;;god ; run Emacs commands without modifier keys
|
||||||
;;lispy ; vim for lisp, for people who don't like vim
|
;;lispy ; vim for lisp, for people who don't like vim
|
||||||
;;multiple-cursors ; editing in many places at once
|
multiple-cursors ; editing in many places at once
|
||||||
;;objed ; text object editing for the innocent
|
;;objed ; text object editing for the innocent
|
||||||
;;parinfer ; turn lisp into python, sort of
|
;;parinfer ; turn lisp into python, sort of
|
||||||
;;rotate-text ; cycle region at point between text candidates
|
;;rotate-text ; cycle region at point between text candidates
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
;;eshell ; the elisp shell that works everywhere
|
;;eshell ; the elisp shell that works everywhere
|
||||||
;;shell ; simple shell REPL for Emacs
|
;;shell ; simple shell REPL for Emacs
|
||||||
;;term ; basic terminal emulator for Emacs
|
;;term ; basic terminal emulator for Emacs
|
||||||
;;vterm ; the best terminal emulation in Emacs
|
vterm ; the best terminal emulation in Emacs
|
||||||
|
|
||||||
:checkers
|
:checkers
|
||||||
syntax ; tasing you for every semicolon you forget
|
syntax ; tasing you for every semicolon you forget
|
||||||
@@ -94,6 +94,7 @@
|
|||||||
;;editorconfig ; let someone else argue about tabs vs spaces
|
;;editorconfig ; let someone else argue about tabs vs spaces
|
||||||
;;ein ; tame Jupyter notebooks with emacs
|
;;ein ; tame Jupyter notebooks with emacs
|
||||||
(eval +overlay) ; run code, run (also, repls)
|
(eval +overlay) ; run code, run (also, repls)
|
||||||
|
llm ; When I said you needed friends, I didn't mean...
|
||||||
lookup ; navigate your code and its documentation
|
lookup ; navigate your code and its documentation
|
||||||
lsp ; M-x vscode
|
lsp ; M-x vscode
|
||||||
magit ; a git porcelain for Emacs
|
magit ; a git porcelain for Emacs
|
||||||
|
|||||||
@@ -52,3 +52,10 @@
|
|||||||
;; (package! org-caldav)
|
;; (package! org-caldav)
|
||||||
|
|
||||||
(package! gptel :recipe (:nonrecursive t))
|
(package! gptel :recipe (:nonrecursive t))
|
||||||
|
|
||||||
|
(package! claude-code-ide
|
||||||
|
:recipe (:host github :repo "manzaltu/claude-code-ide.el"))
|
||||||
|
|
||||||
|
(package! gptel-tool-library
|
||||||
|
:recipe (:host github :repo "aard-fi/gptel-tool-library"
|
||||||
|
:files ("*.el")))
|
||||||
|
|||||||
249
home/modules/kubectl/default.nix
Normal file
249
home/modules/kubectl/default.nix
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.kubectl-secure;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.programs.kubectl-secure = {
|
||||||
|
enable = mkEnableOption "secure kubectl configuration with Bitwarden integration";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
kubectl
|
||||||
|
kubernetes-helm
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.k9s.enable = true;
|
||||||
|
|
||||||
|
programs.bash.initExtra = mkAfter ''
|
||||||
|
# Kubectl secure session management
|
||||||
|
export KUBECTL_SESSION_DIR="/dev/shm/kubectl-$$"
|
||||||
|
|
||||||
|
kube-select() {
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
echo "Usage: kube-select <context-name>"
|
||||||
|
echo "Available contexts: $(kube-list)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local context="$1"
|
||||||
|
|
||||||
|
# Clean up any existing session first
|
||||||
|
kube-clear 2>/dev/null
|
||||||
|
|
||||||
|
# Create new session directory
|
||||||
|
mkdir -p "$KUBECTL_SESSION_DIR"
|
||||||
|
chmod 700 "$KUBECTL_SESSION_DIR"
|
||||||
|
|
||||||
|
# Set cleanup trap for this shell session
|
||||||
|
trap "rm -rf '$KUBECTL_SESSION_DIR' 2>/dev/null" EXIT
|
||||||
|
|
||||||
|
# Set KUBECONFIG for this session
|
||||||
|
export KUBECONFIG="$KUBECTL_SESSION_DIR/config"
|
||||||
|
|
||||||
|
# Load config from Bitwarden secure notes
|
||||||
|
if ! rbw get "kubectl-$context" > "$KUBECONFIG" 2>/dev/null; then
|
||||||
|
echo "Error: Could not retrieve kubectl-$context from Bitwarden"
|
||||||
|
echo "Make sure the entry exists with name: kubectl-$context"
|
||||||
|
kube-clear
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify the kubeconfig is valid
|
||||||
|
if ! kubectl config view >/dev/null 2>&1; then
|
||||||
|
echo "Error: Invalid kubeconfig retrieved from Bitwarden"
|
||||||
|
kube-clear
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Loaded kubectl context: $context (session: $$)"
|
||||||
|
echo " Config location: $KUBECONFIG"
|
||||||
|
}
|
||||||
|
|
||||||
|
kube-list() {
|
||||||
|
echo "Available kubectl contexts in Bitwarden:"
|
||||||
|
rbw search kubectl- 2>/dev/null | grep "^kubectl-" | sed 's/^kubectl-/ - /' || echo " (none found or rbw not accessible)"
|
||||||
|
}
|
||||||
|
|
||||||
|
kube-clear() {
|
||||||
|
if [[ -n "$KUBECTL_TIMEOUT_PID" ]]; then
|
||||||
|
kill "$KUBECTL_TIMEOUT_PID" 2>/dev/null
|
||||||
|
unset KUBECTL_TIMEOUT_PID
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d "$KUBECTL_SESSION_DIR" ]]; then
|
||||||
|
rm -rf "$KUBECTL_SESSION_DIR"
|
||||||
|
echo "Cleared kubectl session ($$)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset KUBECONFIG
|
||||||
|
}
|
||||||
|
|
||||||
|
kube-status() {
|
||||||
|
if [[ -f "$KUBECONFIG" ]]; then
|
||||||
|
local current_context
|
||||||
|
current_context=$(kubectl config current-context 2>/dev/null)
|
||||||
|
if [[ -n "$current_context" ]]; then
|
||||||
|
echo "Active kubectl context: $current_context"
|
||||||
|
echo "Session: $$ | Config: $KUBECONFIG"
|
||||||
|
|
||||||
|
# Show cluster info
|
||||||
|
local cluster_server
|
||||||
|
cluster_server=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' 2>/dev/null)
|
||||||
|
if [[ -n "$cluster_server" ]]; then
|
||||||
|
echo "Cluster: $cluster_server"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No active context in current session"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No kubectl session active in this shell"
|
||||||
|
echo "Use 'kube-select <context>' to start a session"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper function to show available commands
|
||||||
|
kube-help() {
|
||||||
|
echo "Secure kubectl session management commands:"
|
||||||
|
echo ""
|
||||||
|
echo "Session management:"
|
||||||
|
echo " kube-select <context> - Load kubeconfig from Bitwarden"
|
||||||
|
echo " kube-status - Show current session status"
|
||||||
|
echo " kube-clear - Clear current session"
|
||||||
|
echo ""
|
||||||
|
echo "Configuration management:"
|
||||||
|
echo " kube-list - List available contexts in Bitwarden"
|
||||||
|
echo ""
|
||||||
|
echo "Help:"
|
||||||
|
echo " kube-help - Show this help"
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " kube-select prod # Loads from secure note"
|
||||||
|
echo " kubectl get pods"
|
||||||
|
echo " kube-clear"
|
||||||
|
echo ""
|
||||||
|
echo "Note: Kubeconfigs are stored as secure notes in Bitwarden"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.zsh.initExtra = mkAfter ''
|
||||||
|
# Kubectl secure session management (zsh)
|
||||||
|
export KUBECTL_SESSION_DIR="/dev/shm/kubectl-$$"
|
||||||
|
|
||||||
|
kube-select() {
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
echo "Usage: kube-select <context-name>"
|
||||||
|
echo "Available contexts: $(kube-list)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local context="$1"
|
||||||
|
|
||||||
|
# Clean up any existing session first
|
||||||
|
kube-clear 2>/dev/null
|
||||||
|
|
||||||
|
# Create new session directory
|
||||||
|
mkdir -p "$KUBECTL_SESSION_DIR"
|
||||||
|
chmod 700 "$KUBECTL_SESSION_DIR"
|
||||||
|
|
||||||
|
# Set cleanup trap for this shell session
|
||||||
|
trap "rm -rf '$KUBECTL_SESSION_DIR' 2>/dev/null" EXIT
|
||||||
|
|
||||||
|
# Set KUBECONFIG for this session
|
||||||
|
export KUBECONFIG="$KUBECTL_SESSION_DIR/config"
|
||||||
|
|
||||||
|
# Load config from Bitwarden secure notes
|
||||||
|
if ! rbw get "kubectl-$context" > "$KUBECONFIG" 2>/dev/null; then
|
||||||
|
echo "Error: Could not retrieve kubectl-$context from Bitwarden"
|
||||||
|
echo "Make sure the entry exists with name: kubectl-$context"
|
||||||
|
kube-clear
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify the kubeconfig is valid
|
||||||
|
if ! kubectl config view >/dev/null 2>&1; then
|
||||||
|
echo "Error: Invalid kubeconfig retrieved from Bitwarden"
|
||||||
|
kube-clear
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Loaded kubectl context: $context (session: $$)"
|
||||||
|
echo " Config location: $KUBECONFIG"
|
||||||
|
|
||||||
|
# Optional: Set timeout cleanup
|
||||||
|
if [[ ${toString cfg.sessionTimeout} -gt 0 ]]; then
|
||||||
|
(sleep ${toString cfg.sessionTimeout}; kube-clear 2>/dev/null) &
|
||||||
|
export KUBECTL_TIMEOUT_PID=$!
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
kube-list() {
|
||||||
|
echo "Available kubectl contexts in Bitwarden:"
|
||||||
|
rbw search kubectl- 2>/dev/null | grep "^kubectl-" | sed 's/^kubectl-/ - /' || echo " (none found or rbw not accessible)"
|
||||||
|
}
|
||||||
|
|
||||||
|
kube-clear() {
|
||||||
|
if [[ -n "$KUBECTL_TIMEOUT_PID" ]]; then
|
||||||
|
kill "$KUBECTL_TIMEOUT_PID" 2>/dev/null
|
||||||
|
unset KUBECTL_TIMEOUT_PID
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d "$KUBECTL_SESSION_DIR" ]]; then
|
||||||
|
rm -rf "$KUBECTL_SESSION_DIR"
|
||||||
|
echo "Cleared kubectl session ($$)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset KUBECONFIG
|
||||||
|
}
|
||||||
|
|
||||||
|
kube-status() {
|
||||||
|
if [[ -f "$KUBECONFIG" ]]; then
|
||||||
|
local current_context
|
||||||
|
current_context=$(kubectl config current-context 2>/dev/null)
|
||||||
|
if [[ -n "$current_context" ]]; then
|
||||||
|
echo "Active kubectl context: $current_context"
|
||||||
|
echo "Session: $$ | Config: $KUBECONFIG"
|
||||||
|
|
||||||
|
# Show cluster info
|
||||||
|
local cluster_server
|
||||||
|
cluster_server=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' 2>/dev/null)
|
||||||
|
if [[ -n "$cluster_server" ]]; then
|
||||||
|
echo "Cluster: $cluster_server"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No active context in current session"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No kubectl session active in this shell"
|
||||||
|
echo "Use 'kube-select <context>' to start a session"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper function to show available commands
|
||||||
|
kube-help() {
|
||||||
|
echo "Secure kubectl session management commands:"
|
||||||
|
echo ""
|
||||||
|
echo "Session management:"
|
||||||
|
echo " kube-select <context> - Load kubeconfig from Bitwarden"
|
||||||
|
echo " kube-status - Show current session status"
|
||||||
|
echo " kube-clear - Clear current session"
|
||||||
|
echo ""
|
||||||
|
echo "Configuration management:"
|
||||||
|
echo " kube-list - List available contexts in Bitwarden"
|
||||||
|
echo ""
|
||||||
|
echo "Help:"
|
||||||
|
echo " kube-help - Show this help"
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " kube-select prod # Loads from secure note"
|
||||||
|
echo " kubectl get pods"
|
||||||
|
echo " kube-clear"
|
||||||
|
echo ""
|
||||||
|
echo "Note: Kubeconfigs are stored as secure notes in Bitwarden"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -52,26 +52,47 @@
|
|||||||
"Window Operations Menu" = "Alt+F3";
|
"Window Operations Menu" = "Alt+F3";
|
||||||
"Window Resize" = "Meta+R,,Resize Window";
|
"Window Resize" = "Meta+R,,Resize Window";
|
||||||
|
|
||||||
"Overview" = "Meta+W";
|
"Overview" = "Meta+Ctrl+W";
|
||||||
"Grid View" = "Meta+G";
|
"Grid View" = "Meta+G";
|
||||||
"Edit Tiles" = "Meta+T";
|
"Edit Tiles" = "Meta+T";
|
||||||
|
|
||||||
"Activate Window Demanding Attention" = "Meta+Ctrl+A";
|
"Activate Window Demanding Attention" = "Meta+Ctrl+A";
|
||||||
|
|
||||||
"Show Desktop" = "Meta+D";
|
"Show Desktop" = "Meta+Ctrl+D";
|
||||||
|
|
||||||
"Walk Through Windows" = "Alt+Tab";
|
"Walk Through Windows" = "Alt+Tab";
|
||||||
"Walk Through Windows (Reverse)" = "Alt+Shift+Tab";
|
"Walk Through Windows (Reverse)" = "Alt+Shift+Tab";
|
||||||
"Walk Through Windows of Current Application" = "Alt+`";
|
"Walk Through Windows of Current Application" = "Alt+`";
|
||||||
"Walk Through Windows of Current Application (Reverse)" = "Alt+~";
|
"Walk Through Windows of Current Application (Reverse)" = "Alt+~";
|
||||||
"Window Fullscreen" = "Meta+Shift+F,,Make Window Fullscreen";
|
|
||||||
|
|
||||||
"Window Quick Tile Bottom" = "Meta+Down";
|
"Window Quick Tile Bottom" = "Meta+Down";
|
||||||
"Window Quick Tile Left" = "Meta+Left";
|
"Window Quick Tile Left" = "Meta+Left";
|
||||||
"Window Quick Tile Right" = "Meta+Right";
|
"Window Quick Tile Right" = "Meta+Right";
|
||||||
"Window Quick Tile Top" = "Meta+Up";
|
"Window Quick Tile Top" = "Meta+Up";
|
||||||
|
|
||||||
"view_actual_size" = "Meta+0";
|
"Switch to Desktop 1" = "Meta+1";
|
||||||
|
"Switch to Desktop 2" = "Meta+2";
|
||||||
|
"Switch to Desktop 3" = "Meta+3";
|
||||||
|
"Switch to Desktop 4" = "Meta+4";
|
||||||
|
"Switch to Desktop 5" = "Meta+5";
|
||||||
|
"Switch to Desktop 6" = "Meta+6";
|
||||||
|
"Switch to Desktop 7" = "Meta+7";
|
||||||
|
"Switch to Desktop 8" = "Meta+8";
|
||||||
|
"Switch to Desktop 9" = "Meta+9";
|
||||||
|
"Switch to Desktop 10" = "Meta+0";
|
||||||
|
|
||||||
|
"Window to Desktop 1" = "Meta+!"; # Meta+Shift+1
|
||||||
|
"Window to Desktop 2" = "Meta+@"; # Meta+Shift+2
|
||||||
|
"Window to Desktop 3" = "Meta+#"; # Meta+Shift+3
|
||||||
|
"Window to Desktop 4" = "Meta+$"; # Meta+Shift+4
|
||||||
|
"Window to Desktop 5" = "Meta+%"; # Meta+Shift+5
|
||||||
|
"Window to Desktop 6" = "Meta+^"; # Meta+Shift+6
|
||||||
|
"Window to Desktop 7" = "Meta+&"; # Meta+Shift+7
|
||||||
|
"Window to Desktop 8" = "Meta+*"; # Meta+Shift+8
|
||||||
|
"Window to Desktop 9" = "Meta+("; # Meta+Shift+9
|
||||||
|
"Window to Desktop 10" = "Meta+)"; # Meta+Shift+0
|
||||||
|
|
||||||
|
"view_actual_size" = "Meta+Ctrl+=";
|
||||||
"view_zoom_in" = ["Meta++" "Meta+=,Meta++" "Meta+=,Zoom In"];
|
"view_zoom_in" = ["Meta++" "Meta+=,Meta++" "Meta+=,Zoom In"];
|
||||||
"view_zoom_out" = "Meta+-";
|
"view_zoom_out" = "Meta+-";
|
||||||
};
|
};
|
||||||
@@ -110,6 +131,22 @@
|
|||||||
value = 10;
|
value = 10;
|
||||||
immutable = true;
|
immutable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Enable KWin tiling features
|
||||||
|
kwinrc.Tiling = {
|
||||||
|
# Enable tiling functionality
|
||||||
|
"padding" = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable krohnkite plugin automatically
|
||||||
|
kwinrc.Plugins = {
|
||||||
|
krohnkiteEnabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
kwinrc.Effect-overview = {
|
||||||
|
# Configure overview effect for better tiling workflow
|
||||||
|
BorderActivate = 9; # Top-left corner activation
|
||||||
|
};
|
||||||
|
|
||||||
kcminputrc.Libinput = {
|
kcminputrc.Libinput = {
|
||||||
AccelerationProfile = "adaptive";
|
AccelerationProfile = "adaptive";
|
||||||
@@ -122,6 +159,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
kdeglobals.KDE.LookAndFeelPackage = "org.kde.breezedark.desktop";
|
kdeglobals.KDE.LookAndFeelPackage = "org.kde.breezedark.desktop";
|
||||||
|
|
||||||
|
# Focus follows mouse configuration
|
||||||
|
kwinrc.Windows = {
|
||||||
|
FocusPolicy = "FocusFollowsMouse";
|
||||||
|
AutoRaise = true; # Set to true if you want windows to auto-raise on focus
|
||||||
|
AutoRaiseInterval = 750; # Delay in ms before auto-raise (if enabled)
|
||||||
|
DelayFocusInterval = 0; # Delay in ms before focus follows mouse
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
81
home/roles/base/default.nix
Normal file
81
home/roles/base/default.nix
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.base;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.base = {
|
||||||
|
enable = mkEnableOption "Enable base CLI tools and essential programs";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
fd
|
||||||
|
glances
|
||||||
|
gzip
|
||||||
|
htop
|
||||||
|
killall
|
||||||
|
less
|
||||||
|
ncdu
|
||||||
|
shellcheck
|
||||||
|
tmux
|
||||||
|
tree
|
||||||
|
];
|
||||||
|
|
||||||
|
# Essential programs everyone needs
|
||||||
|
programs.bash = {
|
||||||
|
enable = true;
|
||||||
|
initExtra = ''
|
||||||
|
codex() {
|
||||||
|
local key
|
||||||
|
key="$(rbw get openai-api-key-codex)"
|
||||||
|
OPENAI_API_KEY="$key" command codex "$@"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.home-manager.enable = true;
|
||||||
|
programs.command-not-found.enable = true;
|
||||||
|
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
userName = "John Ogle";
|
||||||
|
userEmail = "john@ogle.fyi";
|
||||||
|
extraConfig = {
|
||||||
|
safe.directory = "/etc/nixos";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.jq.enable = true;
|
||||||
|
|
||||||
|
programs.neovim = {
|
||||||
|
enable = true;
|
||||||
|
viAlias = true;
|
||||||
|
vimAlias = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.ssh = {
|
||||||
|
enable = true;
|
||||||
|
matchBlocks = {
|
||||||
|
"nucdeb1" = {
|
||||||
|
hostname = "nucdeb1.oglehome";
|
||||||
|
user = "root";
|
||||||
|
addKeysToAgent = "yes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.rbw = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
email = "john@johnogle.info";
|
||||||
|
base_url = "https://bitwarden.johnogle.info";
|
||||||
|
pinentry = pkgs.pinentry-qt;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Note: modules must be imported at top-level home config
|
||||||
|
};
|
||||||
|
}
|
||||||
24
home/roles/communication/default.nix
Normal file
24
home/roles/communication/default.nix
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{ config, lib, pkgs, globalInputs, system, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.communication;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.communication = {
|
||||||
|
enable = mkEnableOption "Enable communication and messaging applications";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [
|
||||||
|
# Communication apps
|
||||||
|
pkgs.element-desktop
|
||||||
|
pkgs.fluffychat
|
||||||
|
pkgs.nextcloud-talk-desktop
|
||||||
|
|
||||||
|
# For logging back into google chat
|
||||||
|
globalInputs.google-cookie-retrieval.packages.${system}.default
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
13
home/roles/default.nix
Normal file
13
home/roles/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./base
|
||||||
|
./communication
|
||||||
|
./desktop
|
||||||
|
./development
|
||||||
|
./gaming
|
||||||
|
./kdeconnect
|
||||||
|
./media
|
||||||
|
./office
|
||||||
|
./sync
|
||||||
|
];
|
||||||
|
}
|
||||||
77
home/roles/desktop/default.nix
Normal file
77
home/roles/desktop/default.nix
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.desktop;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.desktop = {
|
||||||
|
enable = mkEnableOption "Enable desktop GUI applications and utilities";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
# Desktop applications
|
||||||
|
bitwarden
|
||||||
|
dunst
|
||||||
|
keepassxc
|
||||||
|
kitty
|
||||||
|
|
||||||
|
# Desktop utilities
|
||||||
|
solaar # Logitech management software
|
||||||
|
waybar
|
||||||
|
wofi
|
||||||
|
|
||||||
|
# System utilities with GUI components
|
||||||
|
(snapcast.override { pulseaudioSupport = true; })
|
||||||
|
|
||||||
|
# KDE tiling window management
|
||||||
|
kdePackages.krohnkite # Dynamic tiling extension for KWin 6
|
||||||
|
|
||||||
|
# KDE PIM applications for email, calendar, and contacts
|
||||||
|
kdePackages.kmail
|
||||||
|
kdePackages.kmail-account-wizard
|
||||||
|
kdePackages.kmailtransport
|
||||||
|
kdePackages.korganizer
|
||||||
|
kdePackages.kaddressbook
|
||||||
|
kdePackages.kontact
|
||||||
|
|
||||||
|
# KDE Online Accounts support
|
||||||
|
kdePackages.kaccounts-integration
|
||||||
|
kdePackages.kaccounts-providers
|
||||||
|
kdePackages.signond
|
||||||
|
|
||||||
|
# KDE Mapping
|
||||||
|
kdePackages.marble # Virtual globe and world atlas
|
||||||
|
|
||||||
|
# KDE Productivity
|
||||||
|
kdePackages.kate # Advanced text editor with syntax highlighting
|
||||||
|
kdePackages.okular # Universal document viewer (PDF, ePub, etc.)
|
||||||
|
kdePackages.spectacle # Screenshot capture utility
|
||||||
|
kdePackages.filelight # Visual disk usage analyzer
|
||||||
|
|
||||||
|
# KDE Multimedia
|
||||||
|
kdePackages.gwenview # Image viewer and basic editor
|
||||||
|
kdePackages.elisa # Music player
|
||||||
|
|
||||||
|
# KDE System Utilities
|
||||||
|
kdePackages.ark # Archive manager (zip, tar, 7z, etc.)
|
||||||
|
kdePackages.yakuake # Drop-down terminal emulator
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.firefox = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.spotify-player.enable = true;
|
||||||
|
|
||||||
|
services.gnome-keyring = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.enable = true;
|
||||||
|
|
||||||
|
# Note: modules must be imported at top-level home config
|
||||||
|
};
|
||||||
|
}
|
||||||
27
home/roles/development/default.nix
Normal file
27
home/roles/development/default.nix
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{ config, lib, pkgs, customPkgs, globalInputs, system, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.development;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.development = {
|
||||||
|
enable = mkEnableOption "Enable development tools and utilities";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [
|
||||||
|
pkgs.claude-code
|
||||||
|
pkgs.codex
|
||||||
|
pkgs.goose-cli
|
||||||
|
|
||||||
|
# Custom packages
|
||||||
|
customPkgs.tea-rbw
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.kubectl-secure.enable = true;
|
||||||
|
|
||||||
|
# Note: modules must be imported at top-level home config
|
||||||
|
};
|
||||||
|
}
|
||||||
20
home/roles/gaming/default.nix
Normal file
20
home/roles/gaming/default.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.gaming;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.gaming = {
|
||||||
|
enable = mkEnableOption "Enable gaming applications and tools";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
# Gaming applications would go here
|
||||||
|
# This role is created for future expansion
|
||||||
|
# moonlight-qt is currently in media role but could be moved here
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
20
home/roles/kdeconnect/default.nix
Normal file
20
home/roles/kdeconnect/default.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.kdeconnect;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.kdeconnect = {
|
||||||
|
enable = mkEnableOption "Enable KDE Connect for device integration";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.kdeconnect = {
|
||||||
|
enable = true;
|
||||||
|
indicator = true;
|
||||||
|
package = pkgs.kdePackages.kdeconnect-kde;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
23
home/roles/media/default.nix
Normal file
23
home/roles/media/default.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.media;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.media = {
|
||||||
|
enable = mkEnableOption "Enable media and multimedia applications";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
# Media players and streaming
|
||||||
|
# Using delfin instead of jellyfin-media-player to avoid qtwebengine security issues
|
||||||
|
# For full Jellyfin features, use web interface at http://jellyfin-server:8096
|
||||||
|
delfin
|
||||||
|
moonlight-qt
|
||||||
|
vlc
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
22
home/roles/office/default.nix
Normal file
22
home/roles/office/default.nix
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.office;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.office = {
|
||||||
|
enable = mkEnableOption "Enable office applications and document processing tools";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
# Office suite
|
||||||
|
libreoffice
|
||||||
|
|
||||||
|
# CAD/Design tools
|
||||||
|
openscad-unstable
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
22
home/roles/sync/default.nix
Normal file
22
home/roles/sync/default.nix
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home.roles.sync;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.home.roles.sync = {
|
||||||
|
enable = mkEnableOption "Enable file synchronization services";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
syncthingtray
|
||||||
|
];
|
||||||
|
|
||||||
|
services.syncthing = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ with lib;
|
|||||||
bluetooth.enable = true;
|
bluetooth.enable = true;
|
||||||
desktop = {
|
desktop = {
|
||||||
enable = true;
|
enable = true;
|
||||||
gaming = true;
|
gaming.enable = true;
|
||||||
kde = true;
|
kde = true;
|
||||||
sddm = true;
|
sddm = true;
|
||||||
wayland = true;
|
wayland = true;
|
||||||
|
|||||||
23
machines/johno-macbookpro/configuration.nix
Normal file
23
machines/johno-macbookpro/configuration.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Basic system configuration for macOS work laptop
|
||||||
|
system.stateVersion = 6;
|
||||||
|
|
||||||
|
# Set primary user for nix-darwin
|
||||||
|
system.primaryUser = "johno";
|
||||||
|
|
||||||
|
# System preferences (can be expanded later)
|
||||||
|
system.defaults = {
|
||||||
|
dock.autohide = true;
|
||||||
|
finder.AppleShowAllExtensions = true;
|
||||||
|
NSGlobalDomain.AppleShowAllExtensions = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: Find a way to not duplicate this
|
||||||
|
launchd.user.envVariables = {
|
||||||
|
# DOOM Emacs environment variables
|
||||||
|
DOOMDIR = "/Users/johno/.config/doom";
|
||||||
|
DOOMLOCALDIR = "/Users/johno/.local/doom";
|
||||||
|
};
|
||||||
|
}
|
||||||
89
machines/live-usb/configuration.nix
Normal file
89
machines/live-usb/configuration.nix
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Live USB ISO configuration for recovery and installation
|
||||||
|
{ pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# Use minimal installation CD as base
|
||||||
|
(modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
# Use roles structure for consistent configuration
|
||||||
|
roles = {
|
||||||
|
audio.enable = true;
|
||||||
|
bluetooth.enable = true;
|
||||||
|
desktop = {
|
||||||
|
enable = true;
|
||||||
|
kde = true;
|
||||||
|
x11 = true;
|
||||||
|
wayland = true;
|
||||||
|
sddm = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Allow unfree packages for broader hardware support
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
|
# Essential packages for system recovery and installation
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
# Text editors
|
||||||
|
neovim
|
||||||
|
nano
|
||||||
|
|
||||||
|
# System tools
|
||||||
|
git
|
||||||
|
curl
|
||||||
|
wget
|
||||||
|
htop
|
||||||
|
tree
|
||||||
|
lsof
|
||||||
|
strace
|
||||||
|
|
||||||
|
# Filesystem tools
|
||||||
|
btrfs-progs
|
||||||
|
e2fsprogs
|
||||||
|
xfsprogs
|
||||||
|
ntfs3g
|
||||||
|
dosfstools
|
||||||
|
|
||||||
|
# Network tools
|
||||||
|
networkmanager
|
||||||
|
wirelesstools
|
||||||
|
|
||||||
|
# Hardware tools
|
||||||
|
pciutils
|
||||||
|
usbutils
|
||||||
|
smartmontools
|
||||||
|
|
||||||
|
# Archive tools
|
||||||
|
unzip
|
||||||
|
p7zip
|
||||||
|
|
||||||
|
# Development tools (for quick fixes)
|
||||||
|
gcc
|
||||||
|
binutils
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable NetworkManager for easy wifi setup
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
|
||||||
|
# Enable SSH daemon for remote access
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PermitRootLogin = "yes";
|
||||||
|
PasswordAuthentication = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# ISO customization
|
||||||
|
isoImage = {
|
||||||
|
volumeID = "NIXOS-LIVE";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable some useful services
|
||||||
|
services.udisks2.enable = true; # For mounting USB drives
|
||||||
|
|
||||||
|
# Hardware support
|
||||||
|
hardware.enableAllFirmware = true;
|
||||||
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
desktop = {
|
desktop = {
|
||||||
enable = true;
|
enable = true;
|
||||||
wayland = true;
|
wayland = true;
|
||||||
gaming = false;
|
gaming.enable = false;
|
||||||
kde = true;
|
kde = true;
|
||||||
sddm = true;
|
sddm = true;
|
||||||
};
|
};
|
||||||
@@ -39,9 +39,17 @@
|
|||||||
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
|
||||||
|
|
||||||
# Enable networking
|
# Enable networking
|
||||||
networking.networkmanager.enable = true;
|
networking.networkmanager.enable = true;
|
||||||
|
|
||||||
|
# WireGuard setup
|
||||||
|
networking.wg-quick.interfaces = {
|
||||||
|
ogleNet = {
|
||||||
|
configFile = "/root/Oglehome-VPN-johno-nixbook.conf";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
hardware.graphics = {
|
hardware.graphics = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraPackages = with pkgs; [
|
extraPackages = with pkgs; [
|
||||||
|
|||||||
@@ -10,15 +10,27 @@
|
|||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "vmd" "nvme" "sdhci_pci" ];
|
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "vmd" "nvme" "sdhci_pci" ];
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.initrd.luks.devices."luks-4126fbd4-bd09-4ece-af0d-6fff414c21b3".device = "/dev/disk/by-uuid/4126fbd4-bd09-4ece-af0d-6fff414c21b3";
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
fileSystems."/" =
|
roles.btrfs = {
|
||||||
{ device = "/dev/disk/by-uuid/bd396529-e2c4-47cb-b844-8d6ed841f81a";
|
enable = true;
|
||||||
fsType = "ext4";
|
filesystems."/dev/disk/by-uuid/223a44e5-91e2-4272-830e-129166042a1d" = {
|
||||||
|
mountpoints = {
|
||||||
|
"/" = {
|
||||||
|
compression = "zstd";
|
||||||
|
extraOptions = [ "noatime" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
scrub.enable = true;
|
||||||
|
deduplication = {
|
||||||
|
enable = true;
|
||||||
|
hashTableSizeMB = 32;
|
||||||
|
verbosity = "err";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
boot.initrd.luks.devices."luks-4126fbd4-bd09-4ece-af0d-6fff414c21b3".device = "/dev/disk/by-uuid/4126fbd4-bd09-4ece-af0d-6fff414c21b3";
|
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-uuid/7A0B-CF88";
|
{ device = "/dev/disk/by-uuid/7A0B-CF88";
|
||||||
|
|||||||
223
machines/nix-book/nixbook-btrfs-migration.md
Normal file
223
machines/nix-book/nixbook-btrfs-migration.md
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
# NixBook ext4 to btrfs Migration Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This guide converts your nixbook machine from ext4 to btrfs with zstd compression and beesd deduplication while preserving your LUKS encryption and all data.
|
||||||
|
|
||||||
|
## Current System Info
|
||||||
|
- **Hostname**: nix-book
|
||||||
|
- **Root filesystem**: ext4 on `/dev/disk/by-uuid/bd396529-e2c4-47cb-b844-8d6ed841f81a`
|
||||||
|
- **Encryption**: LUKS with two devices configured
|
||||||
|
- **Current usage**: 138GB used / 225GB total (65% full)
|
||||||
|
- **Free space**: 76GB available (sufficient for conversion)
|
||||||
|
|
||||||
|
## Pre-Migration Checklist
|
||||||
|
|
||||||
|
### 1. Create Full System Backup (CRITICAL)
|
||||||
|
```bash
|
||||||
|
# Boot from NixOS live USB
|
||||||
|
# Mount encrypted filesystem
|
||||||
|
cryptsetup luksOpen /dev/disk/by-uuid/4126fbd4-bd09-4ece-af0d-6fff414c21b3 luks-nixbook
|
||||||
|
mount /dev/mapper/luks-nixbook /mnt
|
||||||
|
|
||||||
|
# Create backup to external drive (adjust target as needed)
|
||||||
|
rsync -avxHAX --progress /mnt/ /path/to/backup/nixbook-backup/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Verify Configuration Changes
|
||||||
|
The following files have been updated for btrfs:
|
||||||
|
- `machines/nix-book/configuration.nix` - Added beesd service
|
||||||
|
- `machines/nix-book/hardware-configuration.nix` - Changed fsType to btrfs with compression
|
||||||
|
|
||||||
|
## Migration Process
|
||||||
|
|
||||||
|
### Phase 1: Boot to Live Environment
|
||||||
|
1. **Create NixOS live USB**:
|
||||||
|
```bash
|
||||||
|
# Download latest NixOS ISO
|
||||||
|
# Flash to USB drive
|
||||||
|
dd if=nixos-minimal-xx.xx-x86_64-linux.iso of=/dev/sdX bs=4M status=progress
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Boot from live USB** and ensure you can access the encrypted drives
|
||||||
|
|
||||||
|
### Phase 2: Filesystem Conversion
|
||||||
|
3. **Unlock LUKS volumes**:
|
||||||
|
```bash
|
||||||
|
cryptsetup luksOpen /dev/disk/by-uuid/4126fbd4-bd09-4ece-af0d-6fff414c21b3 luks-nixbook
|
||||||
|
cryptsetup luksOpen /dev/disk/by-uuid/b614167b-9045-4234-a441-ac6f60a96d81 luks-nixbook2
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Check filesystem before conversion**:
|
||||||
|
```bash
|
||||||
|
fsck.ext4 -f /dev/mapper/luks-nixbook
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Convert ext4 to btrfs** (this preserves all data):
|
||||||
|
```bash
|
||||||
|
# Install btrfs-progs if not available
|
||||||
|
nix-shell -p btrfs-progs
|
||||||
|
|
||||||
|
# Convert the filesystem (takes 15-45 minutes depending on data)
|
||||||
|
btrfs-convert /dev/mapper/luks-nixbook
|
||||||
|
|
||||||
|
# Verify conversion succeeded
|
||||||
|
mount /dev/mapper/luks-nixbook /mnt
|
||||||
|
ls -la /mnt # Should show your normal filesystem
|
||||||
|
btrfs filesystem show /mnt
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Get new filesystem UUID** (may have changed):
|
||||||
|
```bash
|
||||||
|
blkid /dev/mapper/luks-nixbook
|
||||||
|
# Note the new UUID if it changed
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 3: Configuration Update
|
||||||
|
7. **Mount and chroot into system**:
|
||||||
|
```bash
|
||||||
|
mount -o compress=zstd,noatime /dev/mapper/luks-nixbook /mnt
|
||||||
|
mount /dev/disk/by-uuid/7A0B-CF88 /mnt/boot
|
||||||
|
nixos-enter --root /mnt
|
||||||
|
```
|
||||||
|
|
||||||
|
8. **Update hardware-configuration.nix** if UUID changed:
|
||||||
|
```bash
|
||||||
|
# Edit /etc/nixos/hardware-configuration.nix if needed
|
||||||
|
# Update the UUID in fileSystems."/" section
|
||||||
|
```
|
||||||
|
|
||||||
|
9. **Rebuild system with btrfs configuration**:
|
||||||
|
```bash
|
||||||
|
cd /home/johno/nixos-configs
|
||||||
|
nixos-rebuild switch --flake .#nix-book
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 4: Enable Compression and Deduplication
|
||||||
|
10. **Reboot into new btrfs system**:
|
||||||
|
```bash
|
||||||
|
exit # Exit chroot
|
||||||
|
umount -R /mnt
|
||||||
|
reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
11. **Verify btrfs is working**:
|
||||||
|
```bash
|
||||||
|
mount | grep btrfs
|
||||||
|
btrfs filesystem usage /
|
||||||
|
```
|
||||||
|
|
||||||
|
12. **Enable and start beesd**:
|
||||||
|
```bash
|
||||||
|
systemctl status beesd-root
|
||||||
|
systemctl start beesd-root
|
||||||
|
systemctl enable beesd-root
|
||||||
|
```
|
||||||
|
|
||||||
|
13. **Force compression on existing files** (optional but recommended):
|
||||||
|
```bash
|
||||||
|
# This will compress existing files with zstd
|
||||||
|
btrfs filesystem defragment -r -czstd /
|
||||||
|
```
|
||||||
|
|
||||||
|
## Post-Migration Verification
|
||||||
|
|
||||||
|
### Check System Health
|
||||||
|
```bash
|
||||||
|
# Verify btrfs health
|
||||||
|
btrfs scrub start /
|
||||||
|
btrfs scrub status /
|
||||||
|
|
||||||
|
# Check compression effectiveness
|
||||||
|
compsize /
|
||||||
|
|
||||||
|
# Monitor beesd deduplication
|
||||||
|
journalctl -u beesd-root -f
|
||||||
|
|
||||||
|
# Check filesystem usage
|
||||||
|
btrfs filesystem usage /
|
||||||
|
df -h /
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Monitoring
|
||||||
|
```bash
|
||||||
|
# Monitor beesd hash table
|
||||||
|
ls -lh /.beeshash
|
||||||
|
|
||||||
|
# Check compression ratio over time
|
||||||
|
compsize /home /nix /var
|
||||||
|
```
|
||||||
|
|
||||||
|
## Expected Benefits
|
||||||
|
|
||||||
|
### Space Savings
|
||||||
|
- **Compression**: 20-30% reduction in disk usage from zstd
|
||||||
|
- **Deduplication**: Additional 10-20% savings on duplicate files
|
||||||
|
- **Combined**: Potentially 30-40% total space savings
|
||||||
|
|
||||||
|
### Performance Impact
|
||||||
|
- **Compression**: Minimal CPU overhead, often improves I/O performance
|
||||||
|
- **Deduplication**: Background process, minimal impact during normal use
|
||||||
|
- **Overall**: Should be neutral to positive performance impact
|
||||||
|
|
||||||
|
## Rollback Plan (Emergency)
|
||||||
|
|
||||||
|
If something goes wrong:
|
||||||
|
|
||||||
|
1. **Boot from live USB**
|
||||||
|
2. **Restore from backup**:
|
||||||
|
```bash
|
||||||
|
cryptsetup luksOpen /dev/disk/by-uuid/4126fbd4-bd09-4ece-af0d-6fff414c21b3 luks-nixbook
|
||||||
|
mkfs.ext4 /dev/mapper/luks-nixbook
|
||||||
|
mount /dev/mapper/luks-nixbook /mnt
|
||||||
|
rsync -avxHAX --progress /path/to/backup/nixbook-backup/ /mnt/
|
||||||
|
```
|
||||||
|
3. **Restore original hardware-configuration.nix** with ext4 settings
|
||||||
|
4. **Rebuild and reboot**
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
**"Device busy" during conversion**:
|
||||||
|
- Ensure no processes are accessing the filesystem
|
||||||
|
- Check with `lsof` and `fuser`
|
||||||
|
|
||||||
|
**UUID changed after conversion**:
|
||||||
|
- Update hardware-configuration.nix with new UUID
|
||||||
|
- Regenerate initrd: `nixos-rebuild switch`
|
||||||
|
|
||||||
|
**Beesd service fails to start**:
|
||||||
|
- Check disk space for hash table
|
||||||
|
- Verify filesystem is btrfs: `mount | grep btrfs`
|
||||||
|
- Check logs: `journalctl -u beesd-root`
|
||||||
|
|
||||||
|
**Boot issues after conversion**:
|
||||||
|
- Boot from live USB
|
||||||
|
- Check /boot partition is mounted correctly
|
||||||
|
- Verify LUKS UUIDs match in configuration
|
||||||
|
- Rebuild bootloader: `nixos-rebuild switch --install-bootloader`
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
### Regular Tasks
|
||||||
|
```bash
|
||||||
|
# Monthly scrub (checks for corruption)
|
||||||
|
btrfs scrub start /
|
||||||
|
|
||||||
|
# Monitor compression effectiveness
|
||||||
|
compsize /
|
||||||
|
|
||||||
|
# Check beesd deduplication status
|
||||||
|
systemctl status beesd-root
|
||||||
|
```
|
||||||
|
|
||||||
|
### Space Management
|
||||||
|
```bash
|
||||||
|
# Balance filesystem (defragments and optimizes)
|
||||||
|
btrfs balance start -dusage=50 /
|
||||||
|
|
||||||
|
# Check for space issues
|
||||||
|
btrfs filesystem usage /
|
||||||
|
```
|
||||||
|
|
||||||
|
This migration preserves all your data while gaining the benefits of modern btrfs features including transparent compression and automatic deduplication.
|
||||||
31
machines/zix790prors/README.org
Normal file
31
machines/zix790prors/README.org
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
* zix790prors
|
||||||
|
|
||||||
|
The re-birthed NixOS install of my 2024/2025 gaming pc / workstation.
|
||||||
|
|
||||||
|
** Specs
|
||||||
|
- **CPU:** Intel Core i7-14700K (20 cores, 28 threads, up to 5.6 GHz)
|
||||||
|
- **Memory:** 64 GB RAM
|
||||||
|
- **Storage:**
|
||||||
|
- 4TB NVMe SSD (main drive with dual-boot partitions)
|
||||||
|
- Windows 11 partition (NTFS)
|
||||||
|
- NixOS /nix/store partition (btrfs)
|
||||||
|
- Shared /games partition (btrfs, accessible from both Windows and NixOS)
|
||||||
|
- **GPU:** NVIDIA GeForce RTX 4070 Ti
|
||||||
|
- **Boot:** UEFI with 100MB EFI System Partition
|
||||||
|
|
||||||
|
This is a powerful all-purpose workstation optimized for gaming, 3D modeling, and development. It dual-boots Windows 11 with a shared btrfs /games partition accessible from both operating systems.
|
||||||
|
*** Validation
|
||||||
|
Given the above specs, I want to run shell commands to validate them for accuracy. Use the run_shell_command tool to get the results required to complete this validation. Do not return to the user until you have exhausted your self-serve options for accomplishing your task.
|
||||||
|
|
||||||
|
** BIOS Settings
|
||||||
|
|
||||||
|
**2025-09-08**
|
||||||
|
|
||||||
|
I underclocked the CPU today. I set the cpu/cache voltage offset to -50mV and lowered the P-Core multiplier from 56x to 50x. I was able to run Intel XTU benchmarks and the CPU stayed around 80C without any throttling kicking in, whereas before it would bounce around various cores at 100C with lots of throttling taking place.
|
||||||
|
|
||||||
|
My goals for this change are:
|
||||||
|
- CPU longevity
|
||||||
|
- Fan noise
|
||||||
|
- Addressing various apps that say 100C is a "critical temperature" (though I believe the CPU is rated for up to 110C)
|
||||||
|
|
||||||
|
I'm leaving some performance on the table, but it almost feels like the default settings for this CPU were to effectively be overclocked.
|
||||||
99
machines/zix790prors/configuration.nix
Normal file
99
machines/zix790prors/configuration.nix
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# Edit this configuration file to define what should be installed on
|
||||||
|
# your system. Help is available in the configuration.nix(5) man page, on
|
||||||
|
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
||||||
|
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ # Include the results of the hardware scan.
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
roles = {
|
||||||
|
audio.enable = true;
|
||||||
|
bluetooth.enable = true;
|
||||||
|
desktop = {
|
||||||
|
enable = true;
|
||||||
|
gaming = {
|
||||||
|
enable = true;
|
||||||
|
emulation = true;
|
||||||
|
};
|
||||||
|
kde = true;
|
||||||
|
sddm = true;
|
||||||
|
wayland = true;
|
||||||
|
};
|
||||||
|
nfs-mounts.enable = true;
|
||||||
|
nvidia.enable = true;
|
||||||
|
printing.enable = true;
|
||||||
|
users.enable = true;
|
||||||
|
virtualisation.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Use the systemd-boot EFI boot loader.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.systemd-boot.configurationLimit = 20;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
boot.loader.timeout = 10;
|
||||||
|
|
||||||
|
networking.hostName = "zix790prors"; # Define your hostname.
|
||||||
|
|
||||||
|
# Enable networking
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
|
||||||
|
# Fix dual boot clock sync - tell Linux to use local time for hardware clock
|
||||||
|
time.hardwareClockInLocalTime = true;
|
||||||
|
|
||||||
|
# NVIDIA Graphics configuration
|
||||||
|
services.xserver.videoDrivers = [ "nvidia" ];
|
||||||
|
hardware.graphics.enable = true;
|
||||||
|
hardware.graphics.enable32Bit = true;
|
||||||
|
|
||||||
|
hardware.nvidia = {
|
||||||
|
# Modesetting is required.
|
||||||
|
modesetting.enable = true;
|
||||||
|
|
||||||
|
# Enable the Nvidia settings menu,
|
||||||
|
# accessible via `nvidia-settings`.
|
||||||
|
nvidiaSettings = true;
|
||||||
|
|
||||||
|
# Optionally, you may need to select the appropriate driver version for your specific GPU.
|
||||||
|
package = pkgs.linuxPackages.nvidiaPackages.stable;
|
||||||
|
|
||||||
|
# Use open source kernel modules (recommended for RTX/GTX 16xx and newer)
|
||||||
|
# Set to false if you have an older GPU
|
||||||
|
open = true;
|
||||||
|
|
||||||
|
# For gaming performance
|
||||||
|
powerManagement.enable = false;
|
||||||
|
powerManagement.finegrained = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.ollama = {
|
||||||
|
enable = true;
|
||||||
|
acceleration = "cuda";
|
||||||
|
loadModels = [ "gpt-oss" "deepseek-r1" "qwen3:30b" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# This option defines the first version of NixOS you have installed on this particular machine,
|
||||||
|
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
|
||||||
|
#
|
||||||
|
# Most users should NEVER change this value after the initial install, for any reason,
|
||||||
|
# even if you've upgraded your system to a new NixOS release.
|
||||||
|
#
|
||||||
|
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
|
||||||
|
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
|
||||||
|
# to actually do that.
|
||||||
|
#
|
||||||
|
# This value being lower than the current NixOS release does NOT mean your system is
|
||||||
|
# out of date, out of support, or vulnerable.
|
||||||
|
#
|
||||||
|
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
|
||||||
|
# and migrated your data accordingly.
|
||||||
|
#
|
||||||
|
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
||||||
|
system.stateVersion = "25.11"; # Did you read the comment?
|
||||||
|
|
||||||
|
}
|
||||||
57
machines/zix790prors/hardware-configuration.nix
Normal file
57
machines/zix790prors/hardware-configuration.nix
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/11C1-EB58";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0077" "dmask=0077" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
roles.btrfs = {
|
||||||
|
enable = true;
|
||||||
|
filesystems."/dev/disk/by-uuid/ec22734b-d1a3-4c99-8c6f-86f6a8d79007" = {
|
||||||
|
mountpoints = {
|
||||||
|
"/" = {
|
||||||
|
compression = "zstd";
|
||||||
|
extraOptions = [ "noatime" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
scrub.enable = true;
|
||||||
|
deduplication = {
|
||||||
|
enable = true;
|
||||||
|
hashTableSizeMB = 128;
|
||||||
|
verbosity = "err";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
filesystems."/dev/disk/by-uuid/4f9844ac-c1ad-4426-8eb3-21f2306345fb" = {
|
||||||
|
mountpoints = {
|
||||||
|
"/games" = {
|
||||||
|
extraOptions = [ "noatime" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
scrub.enable = true;
|
||||||
|
deduplication = {
|
||||||
|
enable = true;
|
||||||
|
hashTableSizeMB = 256;
|
||||||
|
verbosity = "err";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
||||||
@@ -1,333 +0,0 @@
|
|||||||
# NixOS Steam Dual Boot Implementation Plan (Btrfs + Beesd Edition)
|
|
||||||
|
|
||||||
## Goals & Motivations
|
|
||||||
|
|
||||||
### Primary Goals
|
|
||||||
1. **Eliminate storage waste**: Avoid duplicating terabytes of Steam games across Windows and NixOS
|
|
||||||
2. **Minimize maintenance overhead**: Create a solution that works reliably without constant tweaking
|
|
||||||
3. **Preserve Windows stability**: Ensure Windows Steam functionality remains unaffected by the dual-boot setup
|
|
||||||
4. **Maintain gaming performance**: No significant performance degradation on either OS
|
|
||||||
|
|
||||||
### Secondary Goals
|
|
||||||
- **Seamless game access**: Games should be available on both OSes without manual intervention
|
|
||||||
- **Update compatibility**: Game updates from either OS should be usable by both
|
|
||||||
- **Future-proof architecture**: Solution should be extensible and maintainable
|
|
||||||
- **Multi-user support**: Handle 3 Windows users sharing libraries, with 1 user also using Linux
|
|
||||||
|
|
||||||
## Architectural Overview
|
|
||||||
|
|
||||||
### The Problem with Previous Approaches
|
|
||||||
|
|
||||||
**Shared NTFS Library (Traditional)**:
|
|
||||||
- ❌ Proton creates files with colons, corrupting NTFS
|
|
||||||
- ❌ Requires fragile symlinks that Windows can break
|
|
||||||
- ❌ Permission issues plague the setup
|
|
||||||
- ❌ Valve officially discourages this approach
|
|
||||||
|
|
||||||
**Complex Symlink Management**:
|
|
||||||
- ❌ Requires custom scripts and maintenance
|
|
||||||
- ❌ Fragile edge cases with Steam updates
|
|
||||||
- ❌ Potential compatibility issues with Proton and anti-cheat
|
|
||||||
|
|
||||||
**Separate Libraries**:
|
|
||||||
- ❌ Wastes terabytes of storage
|
|
||||||
- ❌ Games must be installed twice
|
|
||||||
- ❌ No benefit from either OS's installations
|
|
||||||
|
|
||||||
### Our Solution: Btrfs + Beesd Automatic Deduplication
|
|
||||||
|
|
||||||
```
|
|
||||||
Windows Steam → /steam/windows/ (btrfs via WinBtrfs driver)
|
|
||||||
↓
|
|
||||||
Linux Steam → /steam/linux/ (native btrfs)
|
|
||||||
↓
|
|
||||||
[beesd automatically deduplicates identical files]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Key Insight**: Let each Steam installation work independently, rely on proven btrfs deduplication technology to eliminate duplicate storage automatically.
|
|
||||||
|
|
||||||
## Architecture Deep Dive
|
|
||||||
|
|
||||||
### Component 1: Shared Btrfs Filesystem
|
|
||||||
|
|
||||||
**Purpose**: Single high-performance filesystem for all game storage
|
|
||||||
- **Location**: `/steam` (dedicated btrfs partition)
|
|
||||||
- **Contents**:
|
|
||||||
- `/steam/windows/` - Windows Steam library
|
|
||||||
- `/steam/linux/` - Linux Steam library
|
|
||||||
- **Access**: Native on Linux, WinBtrfs driver on Windows
|
|
||||||
|
|
||||||
**Why this satisfies our goals**:
|
|
||||||
- ✅ **Automatic deduplication**: Beesd handles duplicate elimination transparently
|
|
||||||
- ✅ **No maintenance**: Zero custom scripts or symlink management
|
|
||||||
- ✅ **Independent operation**: Each Steam installation works normally
|
|
||||||
- ✅ **Performance**: Optimized mount options for gaming workloads
|
|
||||||
|
|
||||||
### Component 2: Beesd Deduplication Service
|
|
||||||
|
|
||||||
**Purpose**: Automatic background deduplication of game files
|
|
||||||
|
|
||||||
**Core Functionality**:
|
|
||||||
- Continuously scans `/steam` for duplicate blocks
|
|
||||||
- Automatically deduplicates identical files between `/steam/windows/` and `/steam/linux/`
|
|
||||||
- Operates transparently - games never know deduplication is happening
|
|
||||||
- Handles common duplicates: DirectX runtimes, Visual C++ redistributables, game engines, shared assets
|
|
||||||
|
|
||||||
**Expected Efficiency**:
|
|
||||||
- **40-70% storage savings** for typical game libraries
|
|
||||||
- **Common targets**: Unity/Unreal engine files, shared libraries, identical texture assets
|
|
||||||
- **Real-time operation**: New duplicates eliminated automatically
|
|
||||||
|
|
||||||
### Component 3: WinBtrfs Driver Integration
|
|
||||||
|
|
||||||
**Purpose**: Provide Windows with native btrfs read/write access
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# No special configuration needed - standard btrfs mount
|
|
||||||
fileSystems."/steam" = {
|
|
||||||
device = "/dev/disk/by-uuid/YOUR-BTRFS-UUID";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"noatime" # Don't update access times - major gaming performance boost
|
|
||||||
"ssd" # SSD optimizations
|
|
||||||
];
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
**Windows Requirements**:
|
|
||||||
- Install WinBtrfs driver (https://github.com/maharmstone/btrfs)
|
|
||||||
- Configure Steam library path to point to `/steam/windows/`
|
|
||||||
- No special configuration needed - works like any other drive
|
|
||||||
|
|
||||||
### Component 4: Beesd Configuration
|
|
||||||
|
|
||||||
**Purpose**: Optimized deduplication for gaming workloads
|
|
||||||
|
|
||||||
```nix
|
|
||||||
services.beesd.filesystems = {
|
|
||||||
steam = {
|
|
||||||
spec = "/steam";
|
|
||||||
hashTableSizeMB = 512; # Sized for ~4TB of game data (128MB per TB)
|
|
||||||
verbosity = "err"; # Only show actual problems
|
|
||||||
};
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
**Hash Table Storage**:
|
|
||||||
- Stored as file: `/steam/.beeshash`
|
|
||||||
- 512MB handles up to 4TB of game data efficiently (beesd recommends 128MB per TB)
|
|
||||||
- Loaded into RAM on-demand, not all resident simultaneously
|
|
||||||
- Smaller hash table = better performance and less disk usage
|
|
||||||
|
|
||||||
## Partition Strategy
|
|
||||||
|
|
||||||
### 4-Partition Architecture
|
|
||||||
|
|
||||||
1. **Windows Boot Partition** (NTFS) - *Existing*
|
|
||||||
- Standard Windows system drive
|
|
||||||
- Unchanged from current setup
|
|
||||||
|
|
||||||
2. **Linux Boot Partition** (btrfs/ext4) - *New*
|
|
||||||
- NixOS system installation
|
|
||||||
- Standard Linux root filesystem
|
|
||||||
|
|
||||||
3. **Shared Steam Library** (btrfs) - *New*
|
|
||||||
- `/steam/windows/` - Windows Steam library
|
|
||||||
- `/steam/linux/` - Linux Steam library
|
|
||||||
- Automatic beesd deduplication
|
|
||||||
|
|
||||||
4. **Legacy Windows Steam** (NTFS) - *Existing, Optional*
|
|
||||||
- Keep for anti-cheat games that may not work on btrfs
|
|
||||||
- Can be eliminated if all games work on btrfs
|
|
||||||
- Provides fallback option during testing
|
|
||||||
|
|
||||||
### Multi-User Considerations
|
|
||||||
|
|
||||||
**Current Setup**: 3 Windows users sharing Steam libraries
|
|
||||||
**Migration Strategy**:
|
|
||||||
- Other Windows users continue using existing NTFS library
|
|
||||||
- Primary user (johno) experiments with btrfs library
|
|
||||||
- Easy rollback: point Steam back to NTFS if issues arise
|
|
||||||
- Gradual migration as confidence builds
|
|
||||||
|
|
||||||
## Implementation Strategy
|
|
||||||
|
|
||||||
### Phase 1: Base Setup
|
|
||||||
|
|
||||||
1. **Partition Creation**:
|
|
||||||
- Create new btrfs partition for `/steam` (recommend 2TB+ for modern libraries)
|
|
||||||
- Install NixOS on separate Linux boot partition
|
|
||||||
- Keep existing Windows partitions untouched
|
|
||||||
|
|
||||||
2. **NixOS Configuration**:
|
|
||||||
```nix
|
|
||||||
fileSystems."/steam" = {
|
|
||||||
device = "/dev/disk/by-uuid/YOUR-BTRFS-UUID";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [ "noatime" "ssd" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.beesd.filesystems = {
|
|
||||||
steam = {
|
|
||||||
spec = "/steam";
|
|
||||||
hashTableSizeMB = 512; # 128MB per TB recommended
|
|
||||||
verbosity = "err";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Windows Setup**:
|
|
||||||
- Install WinBtrfs driver
|
|
||||||
- Add Steam library pointing to `/steam/windows/`
|
|
||||||
- Test with a few small games initially
|
|
||||||
|
|
||||||
### Phase 2: Gradual Migration
|
|
||||||
|
|
||||||
1. **Safe Game Testing**:
|
|
||||||
- Start with single-player games
|
|
||||||
- Test save game compatibility
|
|
||||||
- Verify performance matches NTFS installation
|
|
||||||
|
|
||||||
2. **Anti-Cheat Evaluation**:
|
|
||||||
- Test multiplayer games progressively
|
|
||||||
- Document which games work on btrfs vs require NTFS
|
|
||||||
- Keep problematic games on legacy NTFS partition
|
|
||||||
|
|
||||||
3. **Deduplication Verification**:
|
|
||||||
- Monitor beesd logs for successful deduplication
|
|
||||||
- Use `btrfs filesystem du /steam` to verify space savings
|
|
||||||
- Benchmark game loading times vs separate installations
|
|
||||||
|
|
||||||
### Phase 3: Optimization
|
|
||||||
|
|
||||||
1. **Performance Tuning**:
|
|
||||||
- Monitor btrfs performance under gaming workloads
|
|
||||||
- Adjust mount options if needed
|
|
||||||
- Optimize beesd parameters based on actual usage
|
|
||||||
|
|
||||||
2. **Monitoring Setup**:
|
|
||||||
- SystemD service monitoring for beesd
|
|
||||||
- Disk space alerts for `/steam` partition
|
|
||||||
- Basic health checks for WinBtrfs stability
|
|
||||||
|
|
||||||
## Trade-offs and Considerations
|
|
||||||
|
|
||||||
### Advantages
|
|
||||||
|
|
||||||
**Storage Efficiency**:
|
|
||||||
- ✅ 40-70% storage savings through automatic deduplication
|
|
||||||
- ✅ No manual intervention required
|
|
||||||
- ✅ Works with any game installation method
|
|
||||||
|
|
||||||
**Simplicity**:
|
|
||||||
- ✅ No custom scripts to maintain
|
|
||||||
- ✅ No symlink complexity
|
|
||||||
- ✅ Standard Steam library management on both OSes
|
|
||||||
|
|
||||||
**Reliability**:
|
|
||||||
- ✅ Each Steam installation completely independent
|
|
||||||
- ✅ Btrfs and beesd are mature, proven technologies
|
|
||||||
- ✅ Graceful degradation if deduplication fails
|
|
||||||
|
|
||||||
**Performance**:
|
|
||||||
- ✅ Optimized mount options for gaming
|
|
||||||
- ✅ No compression overhead
|
|
||||||
- ✅ Native filesystem performance on both OSes
|
|
||||||
|
|
||||||
### Limitations
|
|
||||||
|
|
||||||
**Windows Dependencies**:
|
|
||||||
- ⚠️ Requires WinBtrfs third-party driver
|
|
||||||
- ⚠️ Driver updates needed with major Windows releases
|
|
||||||
- ⚠️ Potential compatibility issues with some anti-cheat systems
|
|
||||||
|
|
||||||
**Complexity Trade-offs**:
|
|
||||||
- ⚠️ More partitions to manage than single-filesystem approach
|
|
||||||
- ⚠️ Beesd adds background CPU/disk usage (minimal but present)
|
|
||||||
- ⚠️ Hash table requires disk space (512MB for large libraries)
|
|
||||||
|
|
||||||
**Platform Compatibility**:
|
|
||||||
- ⚠️ Some games may prefer NTFS for maximum compatibility
|
|
||||||
- ⚠️ Anti-cheat systems may flag non-NTFS installations
|
|
||||||
- ⚠️ WinBtrfs stability depends on third-party development
|
|
||||||
|
|
||||||
### Risk Mitigation
|
|
||||||
|
|
||||||
**Backup Strategy**:
|
|
||||||
- Regular btrfs snapshots of `/steam` partition
|
|
||||||
- Keep legacy NTFS Steam library as fallback
|
|
||||||
- Steam's built-in backup/restore for critical games
|
|
||||||
|
|
||||||
**Fallback Options**:
|
|
||||||
- Easy to revert games to NTFS library if needed
|
|
||||||
- Linux can install games locally if `/steam` partition fails
|
|
||||||
- Independent operation means failure in one OS doesn't affect the other
|
|
||||||
|
|
||||||
**Monitoring**:
|
|
||||||
- SystemD service status for beesd
|
|
||||||
- Disk space monitoring for early warning
|
|
||||||
- Game launch testing after major updates
|
|
||||||
|
|
||||||
## Expected Outcomes
|
|
||||||
|
|
||||||
### Immediate Benefits
|
|
||||||
- **40-70% storage savings** for typical game libraries
|
|
||||||
- **Zero maintenance** after initial setup
|
|
||||||
- **Identical performance** to native installations
|
|
||||||
- **Future-proof** architecture using standard technologies
|
|
||||||
|
|
||||||
### Long-term Benefits
|
|
||||||
- **Automatic optimization**: New games deduplicated without intervention
|
|
||||||
- **Simplified management**: One shared library instead of separate installations
|
|
||||||
- **Technology leverage**: Benefits from ongoing btrfs and beesd improvements
|
|
||||||
|
|
||||||
### Success Metrics
|
|
||||||
- ✅ Games launch successfully from both OSes
|
|
||||||
- ✅ Save games work correctly on both platforms
|
|
||||||
- ✅ Updates from either OS don't break the other
|
|
||||||
- ✅ Storage usage 40-70% less than separate libraries
|
|
||||||
- ✅ No performance degradation vs native installations
|
|
||||||
- ✅ Anti-cheat compatibility acceptable for target games
|
|
||||||
|
|
||||||
### Monitoring and Maintenance
|
|
||||||
|
|
||||||
**Automated Monitoring**:
|
|
||||||
```nix
|
|
||||||
# Add to NixOS configuration for basic monitoring
|
|
||||||
systemd.services.steam-health-check = {
|
|
||||||
description = "Check Steam partition and beesd health";
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStart = pkgs.writeScript "steam-health" ''
|
|
||||||
#!/bin/bash
|
|
||||||
# Check beesd service status
|
|
||||||
systemctl is-active beesd-steam >/dev/null || echo "WARN: beesd not running"
|
|
||||||
|
|
||||||
# Check disk space
|
|
||||||
USAGE=$(df /steam | tail -1 | awk '{print $5}' | sed 's/%//')
|
|
||||||
[ "$USAGE" -gt 90 ] && echo "WARN: Steam partition >90% full"
|
|
||||||
|
|
||||||
# Verify both directories exist
|
|
||||||
[ ! -d "/steam/windows" ] && echo "ERROR: Windows Steam directory missing"
|
|
||||||
[ ! -d "/steam/linux" ] && echo "ERROR: Linux Steam directory missing"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.timers.steam-health-check = {
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig = {
|
|
||||||
OnCalendar = "daily";
|
|
||||||
Persistent = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Implementation Files Needed
|
|
||||||
|
|
||||||
1. **NixOS Configuration Addition** - Add to existing machine config
|
|
||||||
2. **WinBtrfs Installation Guide** - Windows setup instructions
|
|
||||||
3. **Migration Checklist** - Step-by-step game migration process
|
|
||||||
4. **Troubleshooting Guide** - Common issues and solutions
|
|
||||||
|
|
||||||
This architecture provides maximum storage efficiency with minimal complexity, leveraging proven technologies instead of custom solutions. The automatic nature of btrfs deduplication eliminates the maintenance overhead of complex symlink management while providing excellent storage savings.
|
|
||||||
104
packages/app-launcher-server/app-launcher-server.py
Normal file
104
packages/app-launcher-server/app-launcher-server.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||||
|
)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Allowlisted applications that can be launched
|
||||||
|
ALLOWED_APPS = {
|
||||||
|
'firefox': 'firefox',
|
||||||
|
'kodi': 'kodi'
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppLauncherHandler(BaseHTTPRequestHandler):
|
||||||
|
def log_message(self, format, *args):
|
||||||
|
logger.info(format % args)
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
if self.path == '/':
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-type', 'application/json')
|
||||||
|
self.end_headers()
|
||||||
|
response = {
|
||||||
|
'status': 'running',
|
||||||
|
'available_apps': list(ALLOWED_APPS.keys()),
|
||||||
|
'usage': 'POST /launch/<app_name> to launch an application'
|
||||||
|
}
|
||||||
|
self.wfile.write(json.dumps(response, indent=2).encode())
|
||||||
|
else:
|
||||||
|
self.send_error(404)
|
||||||
|
|
||||||
|
def do_POST(self):
|
||||||
|
parsed_path = urlparse(self.path)
|
||||||
|
path_parts = parsed_path.path.strip('/').split('/')
|
||||||
|
|
||||||
|
if len(path_parts) == 2 and path_parts[0] == 'launch':
|
||||||
|
app_name = path_parts[1]
|
||||||
|
self.launch_app(app_name)
|
||||||
|
else:
|
||||||
|
self.send_error(404, "Invalid endpoint. Use /launch/<app_name>")
|
||||||
|
|
||||||
|
def launch_app(self, app_name):
|
||||||
|
if app_name not in ALLOWED_APPS:
|
||||||
|
self.send_error(400, f"Application '{app_name}' not allowed. Available apps: {list(ALLOWED_APPS.keys())}")
|
||||||
|
return
|
||||||
|
|
||||||
|
command = ALLOWED_APPS[app_name]
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Launch the application in the background
|
||||||
|
# Ensure we have the proper environment for GUI apps
|
||||||
|
env = os.environ.copy()
|
||||||
|
|
||||||
|
logger.info(f"Launching application: {command}")
|
||||||
|
process = subprocess.Popen(
|
||||||
|
[command],
|
||||||
|
env=env,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
start_new_session=True
|
||||||
|
)
|
||||||
|
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-type', 'application/json')
|
||||||
|
self.end_headers()
|
||||||
|
response = {
|
||||||
|
'status': 'success',
|
||||||
|
'message': f'Successfully launched {app_name}',
|
||||||
|
'pid': process.pid
|
||||||
|
}
|
||||||
|
self.wfile.write(json.dumps(response).encode())
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
logger.error(f"Application not found: {command}")
|
||||||
|
self.send_error(500, f"Application '{app_name}' not found on system")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error launching {command}: {e}")
|
||||||
|
self.send_error(500, f"Failed to launch {app_name}: {str(e)}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8081
|
||||||
|
|
||||||
|
server = HTTPServer(('0.0.0.0', port), AppLauncherHandler)
|
||||||
|
logger.info(f"App launcher server starting on port {port}")
|
||||||
|
logger.info(f"Available applications: {list(ALLOWED_APPS.keys())}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
server.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
logger.info("Server shutting down...")
|
||||||
|
server.server_close()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
5
packages/app-launcher-server/default.nix
Normal file
5
packages/app-launcher-server/default.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{ pkgs }:
|
||||||
|
|
||||||
|
pkgs.writeShellScriptBin "app-launcher-server" ''
|
||||||
|
exec ${pkgs.python3}/bin/python3 ${./app-launcher-server.py} "$@"
|
||||||
|
''
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
vulkanHDRLayer = pkgs.callPackage ./vulkan-hdr-layer {};
|
vulkanHDRLayer = pkgs.callPackage ./vulkan-hdr-layer {};
|
||||||
|
tea-rbw = pkgs.callPackage ./tea-rbw {};
|
||||||
|
app-launcher-server = pkgs.callPackage ./app-launcher-server {};
|
||||||
}
|
}
|
||||||
|
|||||||
58
packages/tea-rbw/default.nix
Normal file
58
packages/tea-rbw/default.nix
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
pkgs.writeShellScriptBin "tea" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Check if tea config directory exists and has authentication
|
||||||
|
TEA_CONFIG_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/tea"
|
||||||
|
TEA_CONFIG_FILE="$TEA_CONFIG_DIR/config.yml"
|
||||||
|
|
||||||
|
# Function to setup tea authentication with rbw
|
||||||
|
setup_tea_auth() {
|
||||||
|
echo "Tea authentication not found. Setting up with rbw..."
|
||||||
|
|
||||||
|
# Check if rbw is available
|
||||||
|
if ! command -v rbw &> /dev/null; then
|
||||||
|
echo "Error: rbw is not available. Please ensure rbw is installed and configured."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Try to get the token from rbw
|
||||||
|
echo "Attempting to retrieve Gitea token from rbw..."
|
||||||
|
echo "Please enter the rbw entry name for your Gitea token:"
|
||||||
|
read -r rbw_entry
|
||||||
|
|
||||||
|
if ! token=$(rbw get "$rbw_entry" 2>/dev/null); then
|
||||||
|
echo "Error: Failed to retrieve token from rbw entry '$rbw_entry'"
|
||||||
|
echo "Available rbw entries:"
|
||||||
|
rbw list 2>/dev/null || echo "Failed to list rbw entries"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prompt for Gitea URL
|
||||||
|
echo "Please enter your Gitea URL (e.g., https://git.example.com):"
|
||||||
|
read -r gitea_url
|
||||||
|
|
||||||
|
# Create tea config directory if it doesn't exist
|
||||||
|
mkdir -p "$TEA_CONFIG_DIR"
|
||||||
|
|
||||||
|
# Setup tea login
|
||||||
|
if ! ${pkgs.tea}/bin/tea login add --name "default" --url "$gitea_url" --token "$token"; then
|
||||||
|
echo "Error: Failed to setup tea authentication"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Tea authentication setup complete!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if tea is already configured
|
||||||
|
if [[ ! -f "$TEA_CONFIG_FILE" ]]; then
|
||||||
|
setup_tea_auth
|
||||||
|
elif ! ${pkgs.tea}/bin/tea whoami &>/dev/null; then
|
||||||
|
echo "Tea config exists but authentication failed. Re-running setup..."
|
||||||
|
setup_tea_auth
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute tea with all provided arguments
|
||||||
|
exec ${pkgs.tea}/bin/tea "$@"
|
||||||
|
''
|
||||||
@@ -13,6 +13,7 @@ in
|
|||||||
config = mkIf cfg.enable
|
config = mkIf cfg.enable
|
||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
|
easyeffects
|
||||||
paprefs
|
paprefs
|
||||||
pavucontrol
|
pavucontrol
|
||||||
pulsemixer
|
pulsemixer
|
||||||
|
|||||||
173
roles/btrfs/default.nix
Normal file
173
roles/btrfs/default.nix
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.roles.btrfs;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.roles.btrfs = {
|
||||||
|
enable = mkEnableOption "Enable btrfs filesystem management";
|
||||||
|
|
||||||
|
filesystems = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule {
|
||||||
|
options = {
|
||||||
|
# Filesystem-level maintenance options
|
||||||
|
scrub = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Enable automatic scrubbing for this filesystem";
|
||||||
|
};
|
||||||
|
interval = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "weekly";
|
||||||
|
description = "Scrub interval (systemd timer format)";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
deduplication = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable beesd deduplication for this filesystem";
|
||||||
|
};
|
||||||
|
hashTableSizeMB = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 1024;
|
||||||
|
description = "Hash table size in MB (should be multiple of 16)";
|
||||||
|
};
|
||||||
|
verbosity = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "info";
|
||||||
|
description = "Logging verbosity level";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
balance = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable periodic balance operations";
|
||||||
|
};
|
||||||
|
interval = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "monthly";
|
||||||
|
description = "Balance interval (systemd timer format)";
|
||||||
|
};
|
||||||
|
dataUsage = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 50;
|
||||||
|
description = "Data usage threshold for balance";
|
||||||
|
};
|
||||||
|
metadataUsage = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 50;
|
||||||
|
description = "Metadata usage threshold for balance";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Mountpoint-based configuration
|
||||||
|
mountpoints = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule {
|
||||||
|
options = {
|
||||||
|
subvolume = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Subvolume name. If null, uses default subvolume.";
|
||||||
|
};
|
||||||
|
compression = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "zstd";
|
||||||
|
description = "Compression algorithm (zstd, lzo, lz4, none)";
|
||||||
|
};
|
||||||
|
autodefrag = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable automatic defragmentation";
|
||||||
|
};
|
||||||
|
extraOptions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "Additional mount options";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = {};
|
||||||
|
description = "Mountpoint configurations for this filesystem";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = {};
|
||||||
|
description = "Btrfs filesystems configuration";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
btrfs-progs
|
||||||
|
compsize
|
||||||
|
];
|
||||||
|
|
||||||
|
# Generate fileSystems configuration from mountpoints
|
||||||
|
fileSystems = mkMerge (flatten (mapAttrsToList (device: fsCfg:
|
||||||
|
mapAttrsToList (mountpoint: mountCfg:
|
||||||
|
{
|
||||||
|
${mountpoint} = {
|
||||||
|
device = device;
|
||||||
|
fsType = "btrfs";
|
||||||
|
options =
|
||||||
|
(optional (mountCfg.subvolume != null) "subvol=${mountCfg.subvolume}") ++
|
||||||
|
[ "compress=${mountCfg.compression}" ] ++
|
||||||
|
(optional mountCfg.autodefrag "autodefrag") ++
|
||||||
|
mountCfg.extraOptions;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) fsCfg.mountpoints
|
||||||
|
) cfg.filesystems));
|
||||||
|
|
||||||
|
# Configure scrub service using NixOS built-in
|
||||||
|
services.btrfs.autoScrub = mkIf (any (fs: fs.scrub.enable) (attrValues cfg.filesystems)) {
|
||||||
|
enable = true;
|
||||||
|
interval = "weekly"; # TODO: Make this configurable per filesystem
|
||||||
|
fileSystems = attrNames (filterAttrs (_: fs: fs.scrub.enable) cfg.filesystems);
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure beesd for filesystems with deduplication enabled
|
||||||
|
services.beesd.filesystems = mapAttrs' (device: fsCfg:
|
||||||
|
nameValuePair (replaceStrings ["/"] ["_"] (replaceStrings ["-"] ["_"] device)) {
|
||||||
|
spec = device;
|
||||||
|
hashTableSizeMB = fsCfg.deduplication.hashTableSizeMB;
|
||||||
|
verbosity = fsCfg.deduplication.verbosity;
|
||||||
|
}
|
||||||
|
) (filterAttrs (_: fs: fs.deduplication.enable) cfg.filesystems);
|
||||||
|
|
||||||
|
# Custom balance services for filesystems with balance enabled
|
||||||
|
systemd.services = mkMerge (mapAttrsToList (device: fsCfg: mkIf fsCfg.balance.enable {
|
||||||
|
"btrfs-balance-${replaceStrings ["/"] ["-"] (replaceStrings ["-"] ["_"] device)}" = {
|
||||||
|
description = "Balance btrfs filesystem ${device}";
|
||||||
|
script = ''
|
||||||
|
${pkgs.btrfs-progs}/bin/btrfs balance start \
|
||||||
|
-dusage=${toString fsCfg.balance.dataUsage} \
|
||||||
|
-musage=${toString fsCfg.balance.metadataUsage} \
|
||||||
|
${device}
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
Nice = 19;
|
||||||
|
IOSchedulingClass = "idle";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}) cfg.filesystems);
|
||||||
|
|
||||||
|
# Balance timers
|
||||||
|
systemd.timers = mkMerge (mapAttrsToList (device: fsCfg: mkIf fsCfg.balance.enable {
|
||||||
|
"btrfs-balance-${replaceStrings ["/"] ["-"] (replaceStrings ["-"] ["_"] device)}" = {
|
||||||
|
description = "Periodic balance for ${device}";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = fsCfg.balance.interval;
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}) cfg.filesystems);
|
||||||
|
};
|
||||||
|
}
|
||||||
84
roles/darwin.nix
Normal file
84
roles/darwin.nix
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
# Extract the set-environment path that nix-darwin generates
|
||||||
|
setEnvironmentPath = "${config.system.build.setEnvironment}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
# Salt manages /etc/bashrc, /etc/zshrc, /etc/zshenv
|
||||||
|
# nix-darwin writes to .local variants for nix-specific configuration
|
||||||
|
|
||||||
|
# Disable nix-darwin from managing the main shell files
|
||||||
|
environment.etc."bashrc".enable = false;
|
||||||
|
environment.etc."zshrc".enable = false;
|
||||||
|
environment.etc."zshenv".enable = false;
|
||||||
|
|
||||||
|
# Create .local files with nix environment setup
|
||||||
|
environment.etc."bash.local".text = ''
|
||||||
|
# Nix environment setup
|
||||||
|
if [ -z "$__NIX_DARWIN_SET_ENVIRONMENT_DONE" ]; then
|
||||||
|
. ${setEnvironmentPath}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.etc."zshrc.local".text = ''
|
||||||
|
# Nix environment setup (already done in zshenv.local)
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.etc."zshenv.local".text = ''
|
||||||
|
# Nix environment setup
|
||||||
|
if [[ -o rcs ]]; then
|
||||||
|
if [ -z "''${__NIX_DARWIN_SET_ENVIRONMENT_DONE-}" ]; then
|
||||||
|
. ${setEnvironmentPath}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tell zsh how to find installed completions
|
||||||
|
for p in ''${(z)NIX_PROFILES}; do
|
||||||
|
fpath=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions $p/share/zsh/vendor-completions $fpath)
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
time.timeZone = "America/Los_Angeles";
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
git
|
||||||
|
glances
|
||||||
|
pciutils
|
||||||
|
tree
|
||||||
|
usbutils
|
||||||
|
vim
|
||||||
|
];
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
package = pkgs.nix;
|
||||||
|
# distributedBuilds = true;
|
||||||
|
# buildMachines = [{
|
||||||
|
# hostName = "z790prors.oglehome";
|
||||||
|
# system = "x86_64-linux";
|
||||||
|
# protocol = "ssh-ng";
|
||||||
|
# sshUser = "johno";
|
||||||
|
# sshKey = "/root/.ssh/id_ed25519";
|
||||||
|
# maxJobs = 3;
|
||||||
|
# speedFactor = 2;
|
||||||
|
# }];
|
||||||
|
settings = {
|
||||||
|
experimental-features = [ "nix-command" "flakes" ];
|
||||||
|
max-jobs = "auto";
|
||||||
|
trusted-users = [ "johno" ];
|
||||||
|
substituters = [
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
gc = {
|
||||||
|
automatic = true;
|
||||||
|
options = "--delete-older-than 10d";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -6,9 +6,11 @@ with lib;
|
|||||||
imports = [
|
imports = [
|
||||||
./audio
|
./audio
|
||||||
./bluetooth
|
./bluetooth
|
||||||
|
./btrfs
|
||||||
./desktop
|
./desktop
|
||||||
./kodi
|
./kodi
|
||||||
./nfs-mounts
|
./nfs-mounts
|
||||||
|
./nvidia
|
||||||
./printing
|
./printing
|
||||||
./spotifyd
|
./spotifyd
|
||||||
./users
|
./users
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ with lib;
|
|||||||
x11 = mkOption { type = types.bool; default = false; description = "Enable X11 support."; };
|
x11 = mkOption { type = types.bool; default = false; description = "Enable X11 support."; };
|
||||||
wayland = mkOption { type = types.bool; default = false; description = "Enable Wayland support."; };
|
wayland = mkOption { type = types.bool; default = false; description = "Enable Wayland support."; };
|
||||||
kde = mkOption { type = types.bool; default = false; description = "Enable KDE."; };
|
kde = mkOption { type = types.bool; default = false; description = "Enable KDE."; };
|
||||||
gaming = mkOption { type = types.bool; default = false; description = "Enable gaming support."; };
|
gaming = {
|
||||||
|
enable = mkOption { type = types.bool; default = false; description = "Enable gaming support."; };
|
||||||
|
emulation = mkOption { type = types.bool; default = false; description = "Enable emulation support."; };
|
||||||
|
};
|
||||||
sddm = mkOption { type = types.bool; default = false; description = "Enable SDDM greeter."; };
|
sddm = mkOption { type = types.bool; default = false; description = "Enable SDDM greeter."; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,22 @@ let
|
|||||||
cfg = config.roles.desktop;
|
cfg = config.roles.desktop;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = mkIf (cfg.enable && cfg.gaming) {
|
config = mkMerge [
|
||||||
environment.systemPackages = with pkgs; [
|
(mkIf (cfg.enable && cfg.gaming.enable) {
|
||||||
steam
|
environment.systemPackages = with pkgs; [
|
||||||
lutris
|
steam
|
||||||
moonlight
|
lutris
|
||||||
];
|
moonlight
|
||||||
|
];
|
||||||
|
|
||||||
# Possibly other gaming specific services or settings
|
# Possibly other gaming specific services or settings
|
||||||
};
|
})
|
||||||
|
|
||||||
|
(mkIf (cfg.enable && cfg.gaming.emulation) {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
ryubing
|
||||||
|
dolphin-emu
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ with lib;
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.roles.kodi;
|
cfg = config.roles.kodi;
|
||||||
|
customPkgs = pkgs.callPackage ../../packages {};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.roles.kodi = {
|
options.roles.kodi = {
|
||||||
@@ -14,6 +15,18 @@ in
|
|||||||
wayland = mkOption {
|
wayland = mkOption {
|
||||||
default = true;
|
default = true;
|
||||||
};
|
};
|
||||||
|
appLauncherServer = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Enable HTTP app launcher server for remote control";
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 8081;
|
||||||
|
description = "Port for the app launcher HTTP server";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -33,17 +46,35 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
allowedTCPPorts = [ 8080 ];
|
allowedTCPPorts = [ 8080 ] ++ optional cfg.appLauncherServer.enable cfg.appLauncherServer.port;
|
||||||
allowedUDPPorts = [ 8080 ];
|
allowedUDPPorts = [ 8080 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
kodiPkg
|
kodiPkg
|
||||||
wget
|
wget
|
||||||
];
|
firefox
|
||||||
|
] ++ optional cfg.appLauncherServer.enable customPkgs.app-launcher-server;
|
||||||
|
|
||||||
programs.kdeconnect.enable = true;
|
programs.kdeconnect.enable = true;
|
||||||
|
|
||||||
|
systemd.user.services = mkIf cfg.appLauncherServer.enable {
|
||||||
|
app-launcher-server = {
|
||||||
|
description = "HTTP App Launcher Server";
|
||||||
|
wantedBy = [ "graphical-session.target" ];
|
||||||
|
after = [ "graphical-session.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${customPkgs.app-launcher-server}/bin/app-launcher-server ${toString cfg.appLauncherServer.port}";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "5s";
|
||||||
|
Environment = [
|
||||||
|
"PATH=${pkgs.firefox}/bin:${kodiPkg}/bin:/run/current-system/sw/bin"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services = if cfg.autologin then {
|
services = if cfg.autologin then {
|
||||||
displayManager = {
|
displayManager = {
|
||||||
autoLogin.enable = true;
|
autoLogin.enable = true;
|
||||||
|
|||||||
20
roles/nvidia/default.nix
Normal file
20
roles/nvidia/default.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.roles.nvidia;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.roles.nvidia = {
|
||||||
|
enable = mkEnableOption "Enable the nvidia role";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
libva-utils
|
||||||
|
nvidia-vaapi-driver
|
||||||
|
nvtopPackages.nvidia
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ in
|
|||||||
|
|
||||||
hardware.printers.ensurePrinters = [{
|
hardware.printers.ensurePrinters = [{
|
||||||
name = "MFC-L8900CDW_series";
|
name = "MFC-L8900CDW_series";
|
||||||
deviceUri = "dnssd://Brother%20MFC-L8900CDW%20series._ipp._tcp.local/?uuid=e3248000-80ce-11db-8000-b422006699d8";
|
deviceUri = "ipp://brother.oglehome/ipp/print";
|
||||||
model = "everywhere";
|
model = "everywhere";
|
||||||
}];
|
}];
|
||||||
hardware.printers.ensureDefaultPrinter = "MFC-L8900CDW_series";
|
hardware.printers.ensureDefaultPrinter = "MFC-L8900CDW_series";
|
||||||
|
|||||||
Reference in New Issue
Block a user