refactor: centralise all modules
This commit is contained in:
parent
1989535535
commit
6c60cd8e8b
70 changed files with 151 additions and 188 deletions
18
configs/boot.nix
Normal file
18
configs/boot.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
boot = {
|
||||
loader = {
|
||||
timeout = 5;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
kernelPackages = pkgs.linuxPackages_latest;
|
||||
initrd.availableKernelModules = [
|
||||
"nvme"
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"usbhid"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
};
|
||||
}
|
6
configs/bootloaders/systemd-boot.nix
Normal file
6
configs/bootloaders/systemd-boot.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
boot.loader = {
|
||||
systemd-boot.enable = true;
|
||||
systemd-boot.configurationLimit = 5;
|
||||
};
|
||||
}
|
37
configs/default.nix
Normal file
37
configs/default.nix
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
lib,
|
||||
hostname,
|
||||
type,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = builtins.concatLists [
|
||||
# Common options for all machines.
|
||||
[
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
./boot.nix
|
||||
./networking.nix
|
||||
./nix-config.nix
|
||||
./programs/zsh.nix
|
||||
./security.nix
|
||||
./users.nix
|
||||
]
|
||||
# Options for graphical systems.
|
||||
(lib.optionals (type == "desktop") [
|
||||
./hardware/audio.nix
|
||||
./hardware/bluetooth.nix
|
||||
./programs/getty.nix
|
||||
./programs/hyprland.nix
|
||||
./programs/hyprlock.nix
|
||||
./stylix.nix
|
||||
])
|
||||
# Options for specific hostnames.
|
||||
(lib.optionals (hostname == "nemesis") [
|
||||
./hw-nemesis.nix
|
||||
./bootloaders/systemd-boot.nix
|
||||
./hardware/cpu_amd.nix
|
||||
./hardware/nvidia.nix
|
||||
])
|
||||
];
|
||||
}
|
13
configs/hardware/audio.nix
Normal file
13
configs/hardware/audio.nix
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
security.rtkit.enable = true;
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
extraConfig = { };
|
||||
jack.enable = true;
|
||||
pulse.enable = true;
|
||||
alsa = {
|
||||
enable = true;
|
||||
support32Bit = true;
|
||||
};
|
||||
};
|
||||
}
|
6
configs/hardware/bluetooth.nix
Normal file
6
configs/hardware/bluetooth.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
hardware.bluetooth = {
|
||||
enable = true;
|
||||
powerOnBoot = true;
|
||||
};
|
||||
}
|
6
configs/hardware/cpu_amd.nix
Normal file
6
configs/hardware/cpu_amd.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
{ lib, config, ... }:
|
||||
{
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
46
configs/hardware/nvidia.nix
Normal file
46
configs/hardware/nvidia.nix
Normal file
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# Accept the license by default; needed for some packages.
|
||||
nixpkgs.config.nvidia.acceptLicense = true;
|
||||
nix.settings = {
|
||||
substituters = [ "https://cuda-maintainers.cachix.org" ];
|
||||
trusted-public-keys = [
|
||||
"cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E="
|
||||
];
|
||||
};
|
||||
services.xserver.videoDrivers = [ "nvidia" ];
|
||||
environment.variables = {
|
||||
GBM_BACKEND = "nvidia-drm";
|
||||
LIBVA_DRIVER_NAME = "nvidia";
|
||||
__GLX_VENDOR_LIBRARY_NAME = "nvidia";
|
||||
};
|
||||
hardware = {
|
||||
enableRedistributableFirmware = true;
|
||||
nvidia-container-toolkit.enable = true;
|
||||
graphics = {
|
||||
enable = true;
|
||||
package = inputs.hyprland.inputs.nixpkgs.legacyPackages.${pkgs.stdenv.hostPlatform.system}.mesa;
|
||||
extraPackages = with pkgs; [
|
||||
nvidia-vaapi-driver # hardware acceleration
|
||||
];
|
||||
};
|
||||
nvidia = {
|
||||
modesetting.enable = true;
|
||||
open = false;
|
||||
nvidiaSettings = true;
|
||||
nvidiaPersistenced = true;
|
||||
package = config.boot.kernelPackages.nvidiaPackages.latest;
|
||||
};
|
||||
};
|
||||
boot.initrd.availableKernelModules = [
|
||||
"nvidia"
|
||||
"nvidia_modeset"
|
||||
"nvidia_uvm"
|
||||
"nvidia_drm"
|
||||
];
|
||||
}
|
15
configs/hw-nemesis.nix
Normal file
15
configs/hw-nemesis.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/e5005ea6-6c5a-4ab3-9767-ce7772582024";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/6BBE-0E70";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
}
|
110
configs/impermanence.nix
Normal file
110
configs/impermanence.nix
Normal file
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
inputs,
|
||||
lib,
|
||||
device ? throw "Set this to your disk device",
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
inputs.disko.nixosModules.disko
|
||||
inputs.impermanence.nixosModules.impermanence
|
||||
];
|
||||
# Disk Partitioning
|
||||
disko.devices.disk.main = {
|
||||
# device = "/dev/disk/by-id/nvme-eui.01000000000000008ce38e04019a68ab";
|
||||
inherit device;
|
||||
type = "disk";
|
||||
content.type = "gpt";
|
||||
content.partitions = {
|
||||
boot = {
|
||||
name = "boot";
|
||||
type = "EF02";
|
||||
size = "1M";
|
||||
priority = 1;
|
||||
};
|
||||
esp = {
|
||||
name = "ESP";
|
||||
type = "EF00";
|
||||
size = "500M";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "umask=0077" ];
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = "4G";
|
||||
content = {
|
||||
type = "swap";
|
||||
resumeDevice = true;
|
||||
};
|
||||
};
|
||||
root = {
|
||||
name = "root";
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "lvm_pv";
|
||||
vg = "root_vg";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Logical Volume Set up
|
||||
disko.devices.lvm_vg.root_vg = {
|
||||
type = "lvm_vg";
|
||||
lvs.root = {
|
||||
size = "100%FREE";
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = [ "-f" ];
|
||||
subvolumes = {
|
||||
"/root".mountpoint = "/";
|
||||
"/persist".mountpoint = "/persist";
|
||||
"/persist".mountOptions = [
|
||||
"subvol=persist"
|
||||
"noatime"
|
||||
];
|
||||
"/nix".mountpoint = "/nix";
|
||||
"/nix".mountOptions = [
|
||||
"subvol=nix"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Back up old roots and delete older ones
|
||||
boot.initrd.postDeviceCommands = lib.mkAfter ''
|
||||
mkdir /btrfs_tmp
|
||||
mount /dev/root_vg/root /btrfs_tmp
|
||||
if [[ -e /btrfs_tmp/root ]]; then
|
||||
mkdir -p /btrfs_tmp/old_roots
|
||||
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%M-%D_%H:%M:%S")
|
||||
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
|
||||
fi
|
||||
|
||||
delete_subvolume_recursively() {
|
||||
IFS=$'\n'
|
||||
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
|
||||
delete_subvolume_recursively "/btrfs_tmp/$i"
|
||||
done
|
||||
btrfs subvolume delete "$1"
|
||||
}
|
||||
|
||||
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
|
||||
delete_subvolume_recursively "$i"
|
||||
done
|
||||
|
||||
btrfs subvolume create /btrfs_tmp/root
|
||||
umount /btrfs_tmp
|
||||
'';
|
||||
|
||||
# Directories to persist between boots
|
||||
fileSystems."/persist".neededForBoot = true;
|
||||
environment.persistence."/persist" = {
|
||||
hideMounts = true;
|
||||
};
|
||||
}
|
BIN
configs/media/wallpaper.jpg
Normal file
BIN
configs/media/wallpaper.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 MiB |
32
configs/networking.nix
Normal file
32
configs/networking.nix
Normal file
|
@ -0,0 +1,32 @@
|
|||
{ hostname, lib, ... }:
|
||||
{
|
||||
networking = {
|
||||
hostName = hostname;
|
||||
useDHCP = lib.mkDefault true;
|
||||
networkmanager.enable = true;
|
||||
networkmanager.wifi.backend = "iwd";
|
||||
|
||||
# Configures a simple stateful firewall.
|
||||
# By default, it doesn't allow any incoming connections.
|
||||
firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [
|
||||
22 # SSH
|
||||
];
|
||||
allowedUDPPorts = [ ];
|
||||
};
|
||||
|
||||
interfaces.enp12s0.wakeOnLan.policy = [
|
||||
"phy"
|
||||
"unicast"
|
||||
"multicast"
|
||||
"broadcast"
|
||||
"arp"
|
||||
"magic"
|
||||
"secureon"
|
||||
];
|
||||
interfaces.enp12s0.wakeOnLan.enable = true;
|
||||
};
|
||||
services.openssh.enable = true;
|
||||
services.tailscale.enable = true;
|
||||
}
|
28
configs/nix-config.nix
Normal file
28
configs/nix-config.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
system.stateVersion = "24.11";
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
nix = {
|
||||
settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
"pipe-operators"
|
||||
];
|
||||
|
||||
# Add binary caches to avoid having to compile them
|
||||
substituters = [
|
||||
"https://hyprland.cachix.org"
|
||||
"https://nix-community.cachix.org"
|
||||
"https://nvf.cachix.org"
|
||||
"https://yazi.cachix.org"
|
||||
];
|
||||
trusted-public-keys = [
|
||||
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||
"nvf.cachix.org-1:GMQWiUhZ6ux9D5CvFFMwnc2nFrUHTeGaXRlVBXo+naI="
|
||||
"yazi.cachix.org-1:Dcdz63NZKfvUCbDGngQDAZq6kOroIrFoyO064uvLh8k="
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
5
configs/programs/getty.nix
Normal file
5
configs/programs/getty.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
services.getty = {
|
||||
autologinUser = "rafiq";
|
||||
};
|
||||
}
|
11
configs/programs/hyprland.nix
Normal file
11
configs/programs/hyprland.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
programs.hyprland = {
|
||||
enable = true;
|
||||
package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland;
|
||||
portalPackage = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland;
|
||||
};
|
||||
}
|
62
configs/programs/hyprlock.nix
Normal file
62
configs/programs/hyprlock.nix
Normal file
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
inputs,
|
||||
hostname,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg =
|
||||
if hostname == "nemesis" then
|
||||
{
|
||||
mainMonitor = "HDMI-A-1";
|
||||
}
|
||||
else
|
||||
{
|
||||
mainMonitor = "";
|
||||
};
|
||||
in
|
||||
{
|
||||
security.pam.services.hyprlock = { };
|
||||
home-manager.users.rafiq = {
|
||||
programs.hyprlock = {
|
||||
enable = true;
|
||||
package = inputs.hyprlock.packages.${pkgs.stdenv.hostPlatform.system}.hyprlock;
|
||||
|
||||
settings = {
|
||||
general = {
|
||||
hide_cursor = true;
|
||||
ignore_empty_input = true;
|
||||
};
|
||||
|
||||
background = {
|
||||
blur_passes = 5;
|
||||
blur_size = 5;
|
||||
};
|
||||
|
||||
label = {
|
||||
monitor = cfg.mainMonitor;
|
||||
text = ''hi, $USER.'';
|
||||
font_size = 32;
|
||||
halign = "center";
|
||||
valign = "center";
|
||||
position = "0, 0";
|
||||
zindex = 1;
|
||||
shadow_passes = 5;
|
||||
shadow_size = 5;
|
||||
};
|
||||
|
||||
input-field = {
|
||||
fade_on_empty = true;
|
||||
size = "200, 45";
|
||||
halign = "center";
|
||||
valign = "center";
|
||||
position = "0, -5%";
|
||||
placeholder_text = "";
|
||||
zindex = 1;
|
||||
shadow_passes = 5;
|
||||
shadow_size = 5;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
7
configs/programs/zsh.nix
Normal file
7
configs/programs/zsh.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{pkgs, ...}: {
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
};
|
||||
users.defaultUserShell = pkgs.zsh;
|
||||
environment.pathsToLink = ["/share/zsh"]; # enables completion
|
||||
}
|
40
configs/scripts/byebye.sh
Normal file
40
configs/scripts/byebye.sh
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Set up the terminal to read input immediately, without waiting for Enter.
|
||||
# This is done using the `stty` command.
|
||||
# `stty` controls terminal settings.
|
||||
# `-icanon` disables canonical mode. In canonical mode, the terminal buffers input until a newline is received. Disabling it makes input available immediately.
|
||||
# `min 1` specifies that at least 1 character should be read.
|
||||
# `time 0` specifies that the read should return immediately if a character is available.
|
||||
stty -icanon min 1 time 0
|
||||
|
||||
# Prompt the user to enter 'y' or 'n' to confirm or cancel the poweroff.
|
||||
# `echo -n` prints the prompt without a trailing newline, so the input will appear on the same line.
|
||||
echo -n "Poweroff system? (y/n) [n]: "
|
||||
|
||||
# Read a single character from the input and store it in the 'answer' variable.
|
||||
# `read -n 1 answer` reads only 1 character.
|
||||
read -n 1 answer
|
||||
|
||||
# Print a newline character after the input has been read.
|
||||
# This makes the output more readable, as the subsequent messages will appear on a new line.
|
||||
echo
|
||||
|
||||
# Restore the terminal settings to their default values.
|
||||
# This is important, as leaving the terminal in non-canonical mode can cause unexpected behavior.
|
||||
# `stty icanon` re-enables canonical mode.
|
||||
stty icanon
|
||||
|
||||
# Check the value of the 'answer' variable.
|
||||
# `[[ ... ]]` is a more robust and feature-rich way to perform conditional tests than `[ ... ]`.
|
||||
# `"y"` matches only the lowercase "y". If you want case-insensitive matching, consider using `[[ ${answer,,} == "y" ]]` (converts answer to lowercase).
|
||||
if [[ "$answer" == "y" ]]; then
|
||||
# If the user entered 'y', proceed with the poweroff.
|
||||
echo "Powering off..."
|
||||
|
||||
# Execute the systemctl poweroff command with root privileges using sudo.
|
||||
# `sudo` allows you to run commands as the superuser (root).
|
||||
# `systemctl poweroff` sends the command to the systemd init system to shut down the machine.
|
||||
sudo systemctl poweroff
|
||||
else
|
||||
# If the user entered anything other than 'y', cancel the poweroff.
|
||||
echo "Poweroff cancelled."
|
||||
fi
|
14
configs/scripts/default.nix
Normal file
14
configs/scripts/default.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [
|
||||
(pkgs.writers.writePython3Bin "git-extract" {
|
||||
libraries = with pkgs.python3Packages; [
|
||||
magic
|
||||
chardet
|
||||
];
|
||||
} (builtins.readFile ./git-extract.py))
|
||||
|
||||
(pkgs.writeShellScriptBin "rebuild" (builtins.readFile ./rebuild.sh))
|
||||
(pkgs.writeShellScriptBin "byebye" (builtins.readFile ./byebye.sh))
|
||||
];
|
||||
}
|
317
configs/scripts/git-extract.py
Normal file
317
configs/scripts/git-extract.py
Normal file
|
@ -0,0 +1,317 @@
|
|||
# flake8: noqa: E501
|
||||
import subprocess
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
import argparse
|
||||
import magic
|
||||
import chardet
|
||||
import math
|
||||
|
||||
|
||||
def is_ascii(file_path):
|
||||
"""
|
||||
Checks if a file contains only ASCII characters.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file.
|
||||
|
||||
Returns:
|
||||
bool: True if the file contains only ASCII characters, False otherwise.
|
||||
None: If the file does not exist.
|
||||
"""
|
||||
if not os.path.exists(file_path):
|
||||
return None # Indicate file not found.
|
||||
|
||||
try:
|
||||
with open(file_path, "r", encoding="ascii") as f:
|
||||
f.read() # Attempt to read the entire file as ASCII
|
||||
return True
|
||||
except UnicodeDecodeError:
|
||||
return False
|
||||
|
||||
|
||||
def has_high_entropy(file_path, threshold=0.7):
|
||||
"""
|
||||
Checks if a file has high entropy, which might indicate it's not text.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file.
|
||||
threshold (float): Entropy threshold above which it's considered high entropy.
|
||||
|
||||
Returns:
|
||||
bool: True if entropy is above the threshold, False otherwise.
|
||||
None: If the file does not exist.
|
||||
"""
|
||||
if not os.path.exists(file_path):
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(file_path, "rb") as f: # Important: Read as binary
|
||||
data = f.read()
|
||||
except IOError:
|
||||
return True # Treat as non-text if there is an I/O error
|
||||
|
||||
if not data:
|
||||
return False # empty files considered text
|
||||
|
||||
entropy = calculate_entropy(data)
|
||||
return entropy > threshold
|
||||
|
||||
|
||||
def calculate_entropy(data):
|
||||
"""
|
||||
Calculates the entropy of a byte string.
|
||||
|
||||
Args:
|
||||
data (bytes): The byte string.
|
||||
|
||||
Returns:
|
||||
float: The entropy.
|
||||
"""
|
||||
if not data:
|
||||
return 0.0 # Avoid log(0)
|
||||
|
||||
entropy = 0
|
||||
data_length = len(data)
|
||||
seen_bytes = bytearray(range(256)) # All possible byte values
|
||||
counts = [0] * 256
|
||||
|
||||
for byte in data:
|
||||
counts[byte] += 1
|
||||
|
||||
for byte in seen_bytes:
|
||||
probability = float(counts[byte]) / data_length
|
||||
if probability > 0:
|
||||
entropy -= probability * math.log(probability, 2)
|
||||
|
||||
return entropy
|
||||
|
||||
|
||||
def check_chardet_encoding(file_path, confidence_threshold=0.8):
|
||||
"""
|
||||
Checks the file encoding using chardet library.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file.
|
||||
confidence_threshold (float): The minimum confidence level for encoding detection.
|
||||
|
||||
Returns:
|
||||
bool: True if the encoding is detected with high confidence and is a text encoding, False otherwise.
|
||||
None: If the file does not exist.
|
||||
"""
|
||||
if not os.path.exists(file_path):
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(file_path, "rb") as f: # Important: Read as binary
|
||||
data = f.read()
|
||||
except IOError:
|
||||
return False # If file can't be opened, assume it's not a simple text file.
|
||||
|
||||
if not data:
|
||||
return True # Empty files are usually considered text
|
||||
|
||||
result = chardet.detect(data)
|
||||
encoding = result["encoding"]
|
||||
confidence = result["confidence"]
|
||||
|
||||
if encoding and confidence > confidence_threshold:
|
||||
# Check if it's a recognized text encoding (not binary or None)
|
||||
if encoding != "binary" and encoding is not None:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_text_file(file_path, aggressive=False):
|
||||
"""
|
||||
Wrapper function to check if a file is a text file using multiple methods.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file.
|
||||
aggressive (bool, optional): If True, combines all checks for stricter verification.
|
||||
If False, returns True if any check passes. Defaults to False.
|
||||
|
||||
Returns:
|
||||
bool: True if the file is a text file, False otherwise.
|
||||
None: If the file does not exist.
|
||||
"""
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
return None
|
||||
|
||||
# Basic checks
|
||||
ascii_check = is_ascii(file_path)
|
||||
if ascii_check is None:
|
||||
return None # File not found
|
||||
|
||||
if aggressive:
|
||||
# Run all checks and require them all to pass
|
||||
high_entropy_check = not has_high_entropy(
|
||||
file_path
|
||||
) # Invert because we want to know if it DOESN'T have high entropy
|
||||
chardet_check = check_chardet_encoding(file_path)
|
||||
|
||||
return ascii_check and high_entropy_check and chardet_check
|
||||
else:
|
||||
# Run checks and return True if any of them pass
|
||||
high_entropy_check = not has_high_entropy(file_path)
|
||||
chardet_check = check_chardet_encoding(file_path)
|
||||
return ascii_check or high_entropy_check or chardet_check
|
||||
|
||||
|
||||
def get_latest_text_files_to_stdout(remote_repo_url=None, ignored_files=None):
|
||||
"""
|
||||
Checks out the latest commit from a remote Git repository or the current
|
||||
working directory (if no URL is provided) to a temporary folder,
|
||||
and then prints the contents of all files identified as text files to stdout,
|
||||
prepended by their relative paths from the repository root, excluding specified
|
||||
ignored files. Supports "!" to specify includes only.
|
||||
|
||||
Args:
|
||||
remote_repo_url: The URL of the remote Git repository (optional). If None,
|
||||
the current working directory is assumed to be a Git repo.
|
||||
ignored_files: A list of files or directories to ignore (relative to the repo root).
|
||||
If a list contains a value starting with "!", it means "include only".
|
||||
"""
|
||||
|
||||
temp_dir = None
|
||||
if ignored_files is None:
|
||||
ignored_files = []
|
||||
|
||||
# Ensure .git and .gitignore are always ignored (unless include only is specified)
|
||||
include_only = any(item.startswith("!") for item in ignored_files)
|
||||
if not include_only:
|
||||
ignored_files.extend([".git", ".gitignore"])
|
||||
ignored_files = list(set(ignored_files)) # remove duplicates
|
||||
|
||||
# Determine if "include only" is active and extract the include paths
|
||||
include_only = any(item.startswith("!") for item in ignored_files)
|
||||
include_paths = [item[1:] for item in ignored_files if item.startswith("!")]
|
||||
ignore_paths = [item for item in ignored_files if not item.startswith("!")]
|
||||
|
||||
|
||||
try:
|
||||
# Create a temporary directory
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
|
||||
# Clone the repository, but only the latest commit (shallow clone)
|
||||
clone_command = ["git", "clone", "--depth", "1"]
|
||||
if remote_repo_url:
|
||||
clone_command.extend([remote_repo_url, temp_dir])
|
||||
else:
|
||||
# Check if the current directory is a Git repository.
|
||||
try:
|
||||
subprocess.run(
|
||||
["git", "rev-parse", "--is-inside-work-tree"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=os.getcwd(),
|
||||
) # run in current directory
|
||||
except subprocess.CalledProcessError:
|
||||
raise ValueError(
|
||||
"No Git repository URL provided and current directory is not a Git repository."
|
||||
)
|
||||
clone_command.extend([os.getcwd(), temp_dir]) # clone current dir to temp
|
||||
|
||||
subprocess.run(clone_command, check=True, capture_output=True, text=True)
|
||||
|
||||
# Find all files and filter for text files
|
||||
text_files = []
|
||||
for root, _, files in os.walk(temp_dir):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
relative_path = os.path.relpath(file_path, temp_dir)
|
||||
|
||||
if include_only:
|
||||
# Include only logic
|
||||
include = False
|
||||
for include_path in include_paths:
|
||||
if relative_path.startswith(include_path):
|
||||
include = True
|
||||
break
|
||||
if not include:
|
||||
continue # Skip if not in include paths
|
||||
else:
|
||||
# Ignore logic (standard ignore)
|
||||
ignore = False
|
||||
path_components = relative_path.split(
|
||||
os.sep
|
||||
) # split based on OS-specific path separator
|
||||
current_path = ""
|
||||
for component in path_components:
|
||||
current_path = (
|
||||
os.path.join(current_path, component)
|
||||
if current_path
|
||||
else component
|
||||
) # prevent empty first join
|
||||
if current_path in ignore_paths:
|
||||
ignore = True
|
||||
break
|
||||
if ignore:
|
||||
continue
|
||||
|
||||
if is_text_file(file_path): # Use the is_text_file function
|
||||
text_files.append(file_path)
|
||||
|
||||
# Print the contents of each text file, prepended by its relative path
|
||||
for file_path in text_files:
|
||||
relative_path = os.path.relpath(file_path, temp_dir)
|
||||
print(f"--- {relative_path} ---")
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as f: # Use UTF-8 encoding
|
||||
print(f.read())
|
||||
except UnicodeDecodeError:
|
||||
print(
|
||||
f"Error: Could not decode file {relative_path} using UTF-8. Skipping file contents."
|
||||
) # handle binary or other non-UTF-8 encodings
|
||||
print() # Add a blank line between files
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error executing Git command: {e.stderr}")
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
finally:
|
||||
# Clean up the temporary directory
|
||||
if temp_dir:
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Checkout and print text files from a remote Git repository."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--repo",
|
||||
required=False,
|
||||
help="The URL of the remote Git repository. If not provided, the current directory is used if it's a Git repository.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--ignored-files",
|
||||
nargs="+",
|
||||
default=[],
|
||||
help="Files or directories to ignore (space-separated). Use !<path> to specify include only.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
remote_repository_url = args.repo
|
||||
ignored_files = args.ignored_files
|
||||
|
||||
# Verify the URL only if it's provided
|
||||
if remote_repository_url:
|
||||
if (
|
||||
"github.com" not in remote_repository_url
|
||||
and "gitlab.com" not in remote_repository_url
|
||||
and "bitbucket.org" not in remote_repository_url
|
||||
):
|
||||
print(
|
||||
"Warning: This script is designed for common public repository hosting providers. Ensure the Git URL is correct."
|
||||
)
|
||||
|
||||
get_latest_text_files_to_stdout(remote_repository_url, ignored_files)
|
3
configs/scripts/rebuild.sh
Executable file
3
configs/scripts/rebuild.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
git add .
|
||||
# nh clean all
|
||||
nh os switch .
|
9
configs/secrets/.sops.yaml
Normal file
9
configs/secrets/.sops.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
keys:
|
||||
- &admin age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6
|
||||
- &nemesis age1sq4n2ywk6h94a0r5rye6vzkqy5x6ae736faqregz8u2ku8ttepeqqh5crh
|
||||
creation_rules:
|
||||
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *admin
|
||||
- *nemesis
|
30
configs/secrets/secrets.yaml
Normal file
30
configs/secrets/secrets.yaml
Normal file
|
@ -0,0 +1,30 @@
|
|||
password: ENC[AES256_GCM,data:pbNp9qB92UiLv8S18L1Wr+wbiGahxyNbAsvhrJtZTJfQ9H2yyTH6QgfJNUN/hr/wTJFyEKg7E6c7XXh/a0hU4BhJ8QKIUPbHDw==,iv:0bEUOsXQ1tRPa9wfLGNEF4MeCBzvCMaRCbYWRRab6SY=,tag:EiWFVzxxHcQWtBkCL8cSYw==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVaU5aQjB5aWlsSXBNOElh
|
||||
QTZqRnkxSVFibWRReFExTngrck5ZR2JRSHc0CmlFVUpMcXZUYitncFNqU016eU8r
|
||||
UUhIQVR1OHNNajh1WGpaTG1aUFdzakEKLS0tIEk2MUhBVkUxNXRjbnVrb3pPdjlU
|
||||
K1l0QlZ6RDBQZlY0VUtXZXRpekNTelUKoDd6bqX2RNYUNKYBaferXO/FIRSTVXpn
|
||||
JrTPgC+e/f0XMIMcQCiSDmoiuGzEwChboyFAX0JQ7oBSfcGCDd6BEw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1sq4n2ywk6h94a0r5rye6vzkqy5x6ae736faqregz8u2ku8ttepeqqh5crh
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHSGxoM3pPbEU5Ym1mSG1u
|
||||
Wi9laFlnUHNqVnFWOUt1cmUrbHNqQ1ZqMGlJCkNLcXUrTXBKbVlmL1NxbWNiR3Z2
|
||||
ejBGOERrYWZvNi9kUlloTlRkY1dyL3MKLS0tIHVWcmxmN2grMjhkMmZVM3ZQTW9z
|
||||
WEhyYk45Tkw4UGtvVjBtNUxBelAvTDAKS4vDgFOagPMcL9n7nuzyuRuMxRSM6zZ7
|
||||
v7ktd9UmHo/UledQNXrJVi8UWNGX0h7xV163CUNKDqJcwVYrVnQCyA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-03-26T13:53:07Z"
|
||||
mac: ENC[AES256_GCM,data:kO8aTBApujS8ew7vPJlnfMEs6g73liZJ0OCjIVT+dalaAEIS6VM/uLiuVvMi2fL0gWZtsW46UbXrOoiUrMNXrC7Z5RZOhyLwpqE8B3PU5u1BLkBnLub+/391V+PSUjV0YohRGdvKt2Gmpy/c7bG13ltYk9FBP1yXuXwb3pDO4aw=,iv:cldmB2N/u90JVnyXoOW3zAdx+t9eLAdDqPqvxIycQD4=,tag:aXQ+FF2cg435nxPNvkb+7g==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.9.4
|
9
configs/security.nix
Normal file
9
configs/security.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
sops = {
|
||||
defaultSopsFile = ./secrets/secrets.yaml;
|
||||
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
secrets.password.neededForUsers = true;
|
||||
};
|
||||
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
}
|
36
configs/stylix.nix
Normal file
36
configs/stylix.nix
Normal file
|
@ -0,0 +1,36 @@
|
|||
{ inputs, ... }:
|
||||
let
|
||||
opacity = 0.8;
|
||||
toImport = [
|
||||
./themes/cursors/banana-cursor.nix
|
||||
./themes/colourschemes/darkviolet.nix
|
||||
./themes/fonts/sauce-code-pro.nix
|
||||
{
|
||||
# Put options that exist in both NixOS and home-manager modules here.
|
||||
stylix = {
|
||||
enable = true;
|
||||
image = ./media/wallpaper.jpg;
|
||||
opacity = {
|
||||
applications = opacity;
|
||||
desktop = opacity;
|
||||
popups = opacity;
|
||||
terminal = opacity;
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
in
|
||||
{
|
||||
# Enable basic fonts for reasonable Unicode coverage
|
||||
fonts.enableDefaultPackages = true;
|
||||
|
||||
imports = [ inputs.stylix.nixosModules.stylix ] ++ toImport;
|
||||
home-manager.users.rafiq.imports = [ inputs.stylix.homeManagerModules.stylix ] ++ toImport;
|
||||
|
||||
# Put options that only exist in the NixOS module here.
|
||||
stylix.homeManagerIntegration.autoImport = false;
|
||||
stylix.homeManagerIntegration.followSystem = false;
|
||||
|
||||
# Put options that only exist in the home-manager module here.
|
||||
# home-manager.users.rafiq.stylix = {};
|
||||
}
|
4
configs/themes/colourschemes/3024.nix
Normal file
4
configs/themes/colourschemes/3024.nix
Normal file
|
@ -0,0 +1,4 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/3024.yaml";
|
||||
}
|
4
configs/themes/colourschemes/black-metal.nix
Normal file
4
configs/themes/colourschemes/black-metal.nix
Normal file
|
@ -0,0 +1,4 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/black-metal.yaml";
|
||||
}
|
4
configs/themes/colourschemes/bright.nix
Normal file
4
configs/themes/colourschemes/bright.nix
Normal file
|
@ -0,0 +1,4 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/bright.yaml";
|
||||
}
|
4
configs/themes/colourschemes/catppuccin-mocha.nix
Normal file
4
configs/themes/colourschemes/catppuccin-mocha.nix
Normal file
|
@ -0,0 +1,4 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-mocha.yaml";
|
||||
}
|
4
configs/themes/colourschemes/darkviolet.nix
Normal file
4
configs/themes/colourschemes/darkviolet.nix
Normal file
|
@ -0,0 +1,4 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/darkviolet.yaml";
|
||||
}
|
8
configs/themes/cursors/banana-cursor.nix
Normal file
8
configs/themes/cursors/banana-cursor.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
stylix.cursor = {
|
||||
name = "Banana";
|
||||
package = pkgs.banana-cursor;
|
||||
size = 22;
|
||||
};
|
||||
}
|
9
configs/themes/cursors/wii-cursor.nix
Normal file
9
configs/themes/cursors/wii-cursor.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
stylix.cursor = {
|
||||
name = "wii-cursor";
|
||||
# package = inputs.wii-cursor.packages.${pkgs.stdenv.hostPlatform.system}.wii-cursor;
|
||||
package = builtins.trace (inputs.wii-cursor.packages.${pkgs.stdenv.hostPlatform.system}.wii-cursor
|
||||
) (inputs.wii-cursor.packages.${pkgs.stdenv.hostPlatform.system}.wii-cursor);
|
||||
size = 20;
|
||||
};
|
||||
}
|
29
configs/themes/fonts/0xProto.nix
Normal file
29
configs/themes/fonts/0xProto.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{pkgs, ...}: {
|
||||
fonts.packages = with pkgs; [
|
||||
nerd-fonts._0xproto
|
||||
];
|
||||
stylix.fonts = {
|
||||
serif = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "0xProto Nerd Font";
|
||||
};
|
||||
sansSerif = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "0xProto Nerd Font";
|
||||
};
|
||||
emoji = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "0xProto Nerd Font";
|
||||
};
|
||||
monospace = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "0xProto Nerd Font Mono";
|
||||
};
|
||||
sizes = {
|
||||
applications = 16;
|
||||
desktop = 12;
|
||||
popups = 12;
|
||||
terminal = 16;
|
||||
};
|
||||
};
|
||||
}
|
29
configs/themes/fonts/3270.nix
Normal file
29
configs/themes/fonts/3270.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{pkgs, ...}: {
|
||||
fonts.packages = with pkgs; [
|
||||
nerd-fonts._3270
|
||||
];
|
||||
stylix.fonts = {
|
||||
serif = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "3270 Nerd Font";
|
||||
};
|
||||
sansSerif = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "3270 Nerd Font";
|
||||
};
|
||||
emoji = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "3270 Nerd Font";
|
||||
};
|
||||
monospace = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "3270 Nerd Font Mono";
|
||||
};
|
||||
sizes = {
|
||||
applications = 16;
|
||||
desktop = 12;
|
||||
popups = 12;
|
||||
terminal = 16;
|
||||
};
|
||||
};
|
||||
}
|
21
configs/themes/fonts/sauce-code-pro.nix
Normal file
21
configs/themes/fonts/sauce-code-pro.nix
Normal file
|
@ -0,0 +1,21 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
stylix.fonts = {
|
||||
# packages = [ pkgs.nerd-fonts.sauce-code-pro ];
|
||||
emoji.name = "SauceCodePro Nerd Font";
|
||||
emoji.package = pkgs.nerd-fonts.sauce-code-pro;
|
||||
monospace.name = "SauceCodePro Nerd Font Mono";
|
||||
monospace.package = pkgs.nerd-fonts.sauce-code-pro;
|
||||
sansSerif.name = "SauceCodePro Nerd Font";
|
||||
sansSerif.package = pkgs.nerd-fonts.sauce-code-pro;
|
||||
serif.name = "SauceCodePro Nerd Font";
|
||||
serif.package = pkgs.nerd-fonts.sauce-code-pro;
|
||||
|
||||
sizes = {
|
||||
applications = 16;
|
||||
desktop = 12;
|
||||
popups = 12;
|
||||
terminal = 16;
|
||||
};
|
||||
};
|
||||
}
|
29
configs/themes/fonts/terminess.nix
Normal file
29
configs/themes/fonts/terminess.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{pkgs, ...}: {
|
||||
fonts.packages = with pkgs; [
|
||||
nerd-fonts.terminess-ttf
|
||||
];
|
||||
stylix.fonts = {
|
||||
serif = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "Terminess Nerd Font";
|
||||
};
|
||||
sansSerif = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "Terminess Nerd Font";
|
||||
};
|
||||
emoji = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "Terminess Nerd Font";
|
||||
};
|
||||
monospace = {
|
||||
package = pkgs.nerd-fonts.terminess-ttf;
|
||||
name = "Terminess Nerd Font Mono";
|
||||
};
|
||||
sizes = {
|
||||
applications = 16;
|
||||
desktop = 12;
|
||||
popups = 12;
|
||||
terminal = 16;
|
||||
};
|
||||
};
|
||||
}
|
111
configs/users.nix
Normal file
111
configs/users.nix
Normal file
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
specialArgs,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home-manager = {
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
extraSpecialArgs = specialArgs;
|
||||
};
|
||||
|
||||
users.mutableUsers = false; # Always reset users on system activation
|
||||
|
||||
time.timeZone = "Asia/Singapore";
|
||||
i18n.defaultLocale = "en_SG.UTF-8";
|
||||
|
||||
home-manager.users.rafiq.imports = [
|
||||
../programs_temp/ags.nix
|
||||
../programs_temp/btop.nix
|
||||
../programs_temp/clipse.nix
|
||||
../programs_temp/comma.nix
|
||||
../programs_temp/direnv.nix
|
||||
../programs_temp/dunst.nix
|
||||
../programs_temp/firefox.nix
|
||||
../programs_temp/fuzzel.nix
|
||||
../programs_temp/fzf.nix
|
||||
../programs_temp/git.nix
|
||||
../programs_temp/hyprland.nix
|
||||
../programs_temp/hyprshade.nix
|
||||
../programs_temp/kitty.nix
|
||||
../programs_temp/nh.nix
|
||||
../programs_temp/nvf.nix
|
||||
../programs_temp/spicetify.nix
|
||||
../programs_temp/starship.nix
|
||||
../programs_temp/tealdeer.nix
|
||||
../programs_temp/yazi.nix
|
||||
../programs_temp/zellij.nix
|
||||
../programs_temp/zoxide.nix
|
||||
../programs_temp/zsh.nix
|
||||
./scripts
|
||||
{
|
||||
# This enables using home-manager from the command line.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
editorconfig = {
|
||||
enable = true;
|
||||
settings = {
|
||||
"*" = {
|
||||
end_of_line = "lf";
|
||||
insert_final_newline = true;
|
||||
trim_trailing_whitespace = true;
|
||||
charset = "utf-8";
|
||||
indent_style = "space";
|
||||
indent_size = 2;
|
||||
};
|
||||
"package.json" = {
|
||||
indent_style = "unset";
|
||||
};
|
||||
"*.lock" = {
|
||||
indent_size = "unset";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
home = {
|
||||
username = "rafiq";
|
||||
homeDirectory = "/home/rafiq";
|
||||
|
||||
# This defines the version home-manager
|
||||
# was originally bulit against on this system.
|
||||
# Do not change it.
|
||||
stateVersion = "25.05";
|
||||
|
||||
shell.enableShellIntegration = true;
|
||||
shellAliases = {
|
||||
gs = "git status";
|
||||
ai = "aichat -r %shell% -e";
|
||||
cd = "z";
|
||||
list-all-packages = "nix-store --query --requisites /run/current-system | cut -d- -f2- | sort | uniq";
|
||||
};
|
||||
|
||||
packages = with pkgs; [
|
||||
fastfetch # system info
|
||||
wl-clipboard # provides cli copy and paste commands
|
||||
aichat # duh
|
||||
ripgrep
|
||||
devenv
|
||||
bat
|
||||
ttyper
|
||||
hyprpicker
|
||||
inputs.hyprcloser.packages.${pkgs.stdenv.hostPlatform.system}.default
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
users.users.rafiq = {
|
||||
isNormalUser = true;
|
||||
description = "rafiq";
|
||||
hashedPasswordFile = config.sops.secrets.password.path;
|
||||
extraGroups = [
|
||||
"networkmanager"
|
||||
"wheel"
|
||||
];
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILdsZyY3gu8IGB8MzMnLdh+ClDxQQ2RYG9rkeetIKq8n"
|
||||
];
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue