refactoring

This commit is contained in:
암냥 2026-07-05 13:36:31 +09:00
commit 3adc5e9f73
No known key found for this signature in database
40 changed files with 73 additions and 73 deletions

View file

@ -0,0 +1,9 @@
{ ... }:
{
imports = [
./nix.nix
./user.nix
./i18n.nix
./packages.nix
];
}

View file

@ -0,0 +1,62 @@
{ pkgs, ... }:
{
# 시간대 설정
time.timeZone = "Asia/Seoul";
# 로케일 설정 (영어 기본 + 한국 로케일)
i18n = {
defaultLocale = "en_US.UTF-8";
extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
LC_IDENTIFICATION = "en_US.UTF-8";
LC_MEASUREMENT = "en_US.UTF-8";
LC_MONETARY = "en_US.UTF-8";
LC_NAME = "en_US.UTF-8";
LC_NUMERIC = "en_US.UTF-8";
LC_PAPER = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
};
i18n.inputMethod = {
enable = true;
type = "fcitx5";
fcitx5 = {
settings.globalOptions = {
"Hotkey/TriggerKeys" = {
"0" = "Hangul";
};
"Hotkey/ActivateKeys" = {
"0" = "Hangul_Hanja";
};
"Hotkey/DeactivateKeys" = {
"0" = "Hangul_Romaja";
};
"Hotkey/EnumerateGroupForwardKeys" = {
"0" = "Super+space";
};
"Hotkey/PrevPage" = {
"0" = "Up";
};
"Hotkey/NextPage" = {
"0" = "Down";
};
"Hotkey" = {
"AltTriggerKeys" = "";
"EnumerateForwardKeys" = "";
"EnumerateBackwardKeys" = "";
};
};
};
fcitx5.addons = with pkgs; [
fcitx5-hangul
];
};
environment.sessionVariables = {
GTK_IM_MODULE = "fcitx";
QT_IM_MODULE = "fcitx";
XMODIFIERS = "@im=fcitx";
};
}

View file

@ -0,0 +1,47 @@
{ overlays, ... }:
{
# Apply overlays
nixpkgs.overlays = overlays;
nixpkgs.config.allowUnfree = true;
# Nix 설정
nix.settings = {
sandbox = false;
experimental-features = [
"nix-command"
"flakes"
];
auto-optimise-store = true;
};
nix.settings.trusted-users = [
"root"
"imnyang"
];
nix.settings = {
substituters = [
"https://cache.mizuki.guru/public"
"https://cache.mizuki.guru/imnyang"
"https://nix.mizuki.my/public"
"https://vicinae.cachix.org"
];
trusted-public-keys = [
"public:IgipakDD/clr0XbuaIejPYMT5UkTVGKVTxtWXcsbiAg="
"imnyang:x8Oex2DLzZUBxS/3VvkVptT3DiugjsCbQ23VjsxMT5c="
"public:SnHrtrxbCPcZujbJdgsKFeObTfRKQl5KhrI+LljtZUE="
"vicinae.cachix.org-1:1kDrfienkGHPYbkpNj1mWTr7Fm1+zcenzgTizIcI3oc="
];
};
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};
nixpkgs.config.permittedInsecurePackages = [
"openssl-1.1.1w"
"pnpm-10.29.2"
];
}

View file

@ -0,0 +1,31 @@
{ pkgs, ... }:
{
programs.nix-ld.enable = true;
programs.nix-ld.libraries = with pkgs; [
glib
stdenv.cc.cc
zlib
];
# Unfree 패키지 허용
nixpkgs.config.allowUnfree = true;
programs.direnv.enable = true;
# 기본 시스템 패키지
environment.systemPackages = with pkgs; [
eza
btop
vim
wget
curl
git
tree
unzip
zip
file
attic-client
direnv
devenv
];
}

View file

@ -0,0 +1,34 @@
{ pkgs, inputs, ... }:
{
users.users.imnyang = {
isNormalUser = true;
linger = true;
description = "@imnya.ng";
extraGroups = [
"imnyang"
"networkmanager"
"wheel"
"docker"
"libvirtd"
"podman"
];
shell = pkgs.fish;
};
security.sudo.extraRules = [
{
users = [ "imnyang" ];
commands = [
{
command = "ALL";
options = [ "NOPASSWD" ];
}
];
}
];
system.activationScripts.createIcon = "ln -sfn ${inputs.self}/assets/avatar.webp /var/lib/AccountsService/icons/imnyang";
programs.fish.enable = true;
}

View file

@ -0,0 +1,18 @@
{ pkgs, ... }:
{
catppuccin.enable = true;
catppuccin.flavor = "latte";
catppuccin.autoEnable = false;
catppuccin = {
cache.enable = true;
cursors.enable = false;
fcitx5.enable = true;
forgejo.enable = false;
limine.enable = false;
gitea.enable = false;
grub.enable = true;
plymouth.enable = false;
sddm.enable = false;
tty.enable = true;
};
}

View file

@ -0,0 +1,19 @@
{ pkgs, ... }: {
systemd.user.services.figma-agent = {
description = "Figma Agent for local font access";
wantedBy = [ "default.target" ];
serviceConfig = {
ExecStart = "${pkgs.figma-agent}/bin/figma-agent";
Restart = "on-failure";
};
};
systemd.user.sockets.figma-agent = {
description = "Figma Agent socket";
wantedBy = [ "default.target" ];
socketConfig = {
ListenStream = "127.0.0.1:44950";
NoDelay = true;
};
};
}

View file

@ -0,0 +1,70 @@
{ pkgs, ... }:
let
wantedSans = pkgs.stdenvNoCC.mkDerivation {
pname = "wanted-sans";
version = "1.0.3";
src = pkgs.fetchzip {
url = "https://github.com/wanteddev/wanted-sans/releases/download/v1.0.3/WantedSans-1.0.3.zip";
hash = "sha256-uksJ7Qmwv0kQw/mXyI179XaFHGMI8fuumcitD/XpA/w=";
stripRoot = false;
};
installPhase = ''
runHook preInstall
install -Dm644 variable/*.ttf -t $out/share/fonts/truetype
install -Dm644 otf/*.otf -t $out/share/fonts/opentype
runHook postInstall
'';
};
suit-font = pkgs.stdenvNoCC.mkDerivation {
pname = "suit-font";
version = "v2.0.5";
# name을 다르게 지정하여 unpack 시 충돌을 방지합니다.
srcs = [
(pkgs.fetchzip {
name = "suit-variable";
url = "https://github.com/sun-typeface/SUIT/releases/download/v2.0.5/SUIT-Variable-ttf.zip";
hash = "sha256-oRZGxT/v6jBa5cOsYWG8qHfdPIRBqPAyt6hjfBTD1jo=";
stripRoot = false;
})
(pkgs.fetchzip {
name = "suit-static";
url = "https://github.com/sun-typeface/SUIT/releases/download/v2.0.5/SUIT-otf.zip";
hash = "sha256-YDyBKU5P+tlMsK4L2dEn6ibOo6UxDK2B507rm/zy2FA=";
stripRoot = false;
})
];
sourceRoot = ".";
installPhase = ''
runHook preInstall
mkdir -p $out/share/fonts/truetype $out/share/fonts/opentype
# 각 소스가 suit-variable, suit-static 디렉토리에 풀려 있으므로 전체 탐색하여 복사
find . -name "__MACOSX" -prune -o -name "*.ttf" -exec cp {} $out/share/fonts/truetype/ \;
find . -name "__MACOSX" -prune -o -name "*.otf" -exec cp {} $out/share/fonts/opentype/ \;
runHook postInstall
'';
};
in
{
fonts = {
packages = with pkgs; [
liberation_ttf
fira-code
fira-code-symbols
dejavu_fonts
pretendard
pretendard-jp
nanum-gothic-coding
nerd-fonts.jetbrains-mono
wantedSans
suit-font
];
};
}

View file

@ -0,0 +1,26 @@
{ pkgs, ... }:
{
virtualisation.libvirtd = {
enable = true;
dbus.enable = true;
};
users.groups.libvirtd.members = [ "imnyang" ];
services.cockpit = {
enable = true;
plugins = with pkgs; [
cockpit-machines
cockpit-files
cockpit-podman
];
openFirewall = true;
allowed-origins = [ "*" ];
};
environment.systemPackages = with pkgs; [
libvirt-dbus
virt-manager
virt-viewer
];
}

View file

@ -0,0 +1,4 @@
{ ... }:
{
virtualisation.docker.enable = true;
}

View file

@ -0,0 +1,29 @@
{
config,
lib,
pkgs,
...
}:
{
virtualisation = {
containers.enable = true;
podman = {
enable = true;
dockerCompat = true;
defaultNetwork.settings.dns_enabled = true; # Required for containers under podman-compose to be able to talk to each other.
};
};
environment.systemPackages = with pkgs; [
podman-compose
podman
podman-tui
];
users.users.imnyang = {
extraGroups = [
"podman"
];
};
}

View file

@ -0,0 +1,77 @@
{
pkgs,
inputs,
...
}:
let
nr = import ./packages/nr.nix { inherit pkgs; };
nrr = import ./packages/nrr.nix { inherit pkgs; };
in
{
programs._1password.enable = true;
programs._1password-gui = {
enable = true;
polkitPolicyOwners = [ "imnyang" ];
};
environment.etc = {
"1password/custom_allowed_browsers" = {
text = ''
microsoft-edge
firefox-devedition
'';
mode = "0755";
};
};
# 시스템 전역 패키지 (데스크탑/개발용)
environment.systemPackages = with pkgs; [
nr
nrr
# 네트워크 도구
networkmanager
networkmanager-ssh
# 개발 도구
gcc
gnumake
nil
nixd
cockpit
libvirt
virt-manager
mono
msbuild
docker
docker-buildx
docker-compose
docker-client
uv
python3
openssl
pkg-config
mtr
glibc
gtk3
pango
librsvg
penelope
ntfs3g
_1password-cli
_1password-gui
inputs.muvel.packages.${pkgs.stdenv.hostPlatform.system}.muvel
sbctl
];
}

View file

@ -0,0 +1,44 @@
{ pkgs }:
pkgs.writeShellApplication {
name = "dr";
runtimeInputs = with pkgs; [
nix-output-monitor
coreutils
nix
attic-client
];
text = ''
set -e
TARGET_NAME="''${1:-$(hostname -s)}"
FLAKE_PATH="."
UPLOAD_CACHE=true
while [[ $# -gt 0 ]]; do
case "$1" in
--no-upload) UPLOAD_CACHE=false ;;
*) TARGET_NAME="$1" ;;
esac
shift
done
echo "macOS ... ($TARGET_NAME)"
BUILD_PATH=$(nom build "$FLAKE_PATH#darwinConfigurations.$TARGET_NAME.system" --print-out-paths --no-link)
echo " ..."
sudo nix-env --profile /nix/var/nix/profiles/system --set "$BUILD_PATH"
sudo "$BUILD_PATH/activate"
if [ "$UPLOAD_CACHE" = true ]; then
echo " ..."
attic push imnyang "$BUILD_PATH" || echo " "
fi
echo "nix-darwin !"
'';
}

View file

@ -0,0 +1,50 @@
{ pkgs }:
pkgs.writeShellApplication {
name = "nr";
runtimeInputs = with pkgs; [
nix-output-monitor
openssh
coreutils
nix
attic-client
];
text = ''
set -e
TARGET_NAME="''${1:-$(hostname)}"
FLAKE_PATH="."
UPLOAD_CACHE=true
while [[ $# -gt 0 ]]; do
case "$1" in
--no-upload) UPLOAD_CACHE=false ;;
*) TARGET_NAME="$1" ;;
esac
shift
done
EXTRA_BUILD_FLAGS=()
if [ "$TARGET_NAME" = "kazusa" ]; then
EXTRA_BUILD_FLAGS+=("--max-substituter-jobs" "2")
fi
echo " ... $TARGET_NAME"
# shellcheck disable=SC2086
BUILD_PATH=$(nom build "$FLAKE_PATH#nixosConfigurations.$TARGET_NAME.config.system.build.toplevel" \
"''${EXTRA_BUILD_FLAGS[@]}" \
--print-out-paths --no-link)
echo " ..."
sudo nix-env --profile /nix/var/nix/profiles/system --set "$BUILD_PATH"
sudo "$BUILD_PATH/bin/switch-to-configuration" switch
if [ "$UPLOAD_CACHE" = true ]; then
echo " ..."
attic push imnyang "$BUILD_PATH" || echo " "
fi
echo " !"
'';
}

View file

@ -0,0 +1,59 @@
{ pkgs }:
pkgs.writeShellApplication {
name = "nrr";
runtimeInputs = with pkgs; [
nix-output-monitor
openssh
coreutils
];
text = ''
set -e
TARGET_NAME=""
if [ $# -gt 0 ]; then
TARGET_NAME="$1"
fi
FLAKE_PATH="."
declare -A HOST_MAP
HOST_MAP["hikari"]="10.11.8.100"
HOST_MAP["hako"]="10.11.8.102"
HOST_MAP["kazusa"]="82.21.82.30"
HOST_MAP["natsu"]="natsu.icn.mizuki.guru"
HOST_MAP["mafuyu"]="10.20.30.101"
HOST_MAP["mizuki"]="10.20.30.103"
HOST_MAP["ena"]="10.20.30.104"
if [ -z "$TARGET_NAME" ]; then
echo "nrr - NixOS "
echo ": nrr <hostname>"
exit 1
fi
if [[ -v "HOST_MAP[$TARGET_NAME]" ]]; then
TARGET_IP=''${HOST_MAP[$TARGET_NAME]}
echo " : $TARGET_NAME -> $TARGET_IP"
else
echo " ."
exit 1
fi
echo " ..."
BUILD_PATH=$(nom build "$FLAKE_PATH#nixosConfigurations.$TARGET_NAME.config.system.build.toplevel" --print-out-paths --no-link --eval-cache --accept-flake-config)
echo " ... ($BUILD_PATH -> $TARGET_IP)"
nix copy --to "ssh://imnyang@$TARGET_IP" "$BUILD_PATH"
echo " ..."
# shellcheck disable=SC2029
ssh "imnyang@$TARGET_IP" "sudo nix-env --profile /nix/var/nix/profiles/system --set \"$BUILD_PATH\" && sudo $BUILD_PATH/bin/switch-to-configuration switch"
echo " ..."
attic push imnyang "$BUILD_PATH" || echo " "
echo " !"
'';
}

View file

@ -0,0 +1,22 @@
{ pkgs, ... }:
{
services.xserver = {
enable = true;
xkb = {
layout = "us";
variant = "";
};
};
services.displayManager.sddm.enable = true;
services.desktopManager.plasma6.enable = true;
xdg.portal = {
enable = true;
extraPortals = with pkgs; [ kdePackages.xdg-desktop-portal-kde ];
config.common.default = "kde";
};
system.nixos.variant_id = "mizuki";
system.nixos.variantName = "Mizuki";
}

View file

@ -0,0 +1,9 @@
{ ... }:
{
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "prohibit-password";
};
};
}

View file

@ -0,0 +1,16 @@
{
...
}:
{
services.sunshine = {
enable = true;
autoStart = true;
capSysAdmin = true; # only needed for Wayland -- omit this when using with Xorg
openFirewall = true;
};
users.users.imnyang = {
extraGroups = [ "uinput" ];
};
hardware.uinput.enable = true;
}

View file

@ -0,0 +1,23 @@
{ pkgs, ... }:
{
programs.steam = {
enable = true;
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
localNetworkGameTransfers.openFirewall = true;
gamescopeSession.enable = true;
package = pkgs.millennium-steam;
extraCompatPackages = with pkgs; [
proton-ge-bin
];
};
hardware.steam-hardware.enable = true;
environment.systemPackages = with pkgs; [
steam-run
sgdboop
mangohud
protontricks
];
}

View file

@ -0,0 +1,16 @@
{ ... }:
{
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
Experimental = true;
FastConnectable = true;
};
Policy = {
AutoEnable = true;
};
};
};
}

View file

@ -0,0 +1,32 @@
{ pkgs, ... }:
{
# boot.plymouth.enable = true;
boot.loader = {
grub = {
enable = true;
efiSupport = true;
useOSProber = true;
efiInstallAsRemovable = true;
device = "nodev";
enableCryptodisk = true;
# extraInstallCommands = ''
# mkdir -p /boot/EFI/BOOT
# cp -f /boot/EFI/NixOS-boot/grubx64.efi /boot/EFI/BOOT/BOOTX64.EFI
# '';
default = "saved";
extraConfig = ''
GRUB_SAVEDEFAULT=true
'';
};
# efi.canTouchEfiVariables = true;
efi.efiSysMountPoint = "/boot";
};
boot.initrd.systemd.enable = true;
boot.initrd.systemd.emergencyAccess = true;
boot.kernelPackages = pkgs.linuxPackages_latest;
}

View file

@ -0,0 +1,7 @@
{ ... }:
{
hardware.graphics = {
enable = true;
enable32Bit = true;
};
}

View file

@ -0,0 +1,74 @@
{ pkgs, config, ... }:
{
environment.systemPackages = with pkgs; [
grub2_efi
];
system.activationScripts = {
# This, has to be the LAST GRUB script to run.
# The reason is that a standalone GRUB image takes with it
# the configuration too, apparently.
# "90-generate-standalone-grub" = {
# text = ''
# if [ "$NIXOS_ACTION" = "switch" ] || [ "$NIXOS_ACTION" = "boot" ]; then
# echo "Generating standalone GRUB EFI entry..."
# ESP="${config.boot.loader.efi.efiSysMountPoint}"
# OUT_DIR="$ESP/EFI/NixOS-boot"
# FALLBACK_DIR="$ESP/EFI/BOOT"
# mkdir -p "$OUT_DIR" "$FALLBACK_DIR"
# OUT="$OUT_DIR/grubx64.efi"
# FALLBACK="$FALLBACK_DIR/BOOTX64.EFI"
# # GPT-5 told me to add all those modules, idk.
# ${pkgs.grub2_efi}/bin/grub-mkstandalone -O x86_64-efi -o "$OUT" \
# "boot/grub/grub.cfg=${pkgs.writeText "grub-standalone-template.cfg" ''
# search --file --no-floppy --set=esp /EFI/NixOS-boot/grubx64.efi
# set prefix=($esp)/grub
# if [ -f ($esp)/grub/grubenv ]; then
# load_env ($esp)/grub/grubenv
# fi
# if [ -f ($esp)/grub/grub.cfg ]; then
# configfile ($esp)/grub/grub.cfg
# else
# echo "Error: ($esp)/grub/grub.cfg not found."
# sleep 5
# fi
# ''}" \
# --modules="part_gpt part_msdos fat normal search search_fs_uuid search_label configfile linux gzio efi_gop efi_uga all_video gfxterm gfxmenu png jpeg tga font" \
# --disable-shim-lock
# # It's so stupid but otherwise it won't boot:
# # https://wejn.org/2021/09/fixing-grub-verification-requested-nobody-cares/
# ${pkgs.gnused}/bin/sed -i 's/SecureBoot/SecureB00t/' "$OUT"
# cp -f "$OUT" "$FALLBACK"
# fi
# '';
# };
"99-sign-all" = {
text = ''
if [ "$NIXOS_ACTION" = "switch" ] || [ "$NIXOS_ACTION" = "boot" ]; then
echo "Signing all EFI binaries with sbctl..."
# 1. 파일이 존재하는지 먼저 확인하고,
# 2. 이미 등록되어 있다면 sign-all로 한 번에 처리하거나,
# 3. 개별 파일에 대해 에러가 나도 스크립트가 중단되지 않도록 || true를 붙입니다.
# 주요 바이너리들을 DB에 등록 (이미 등록되어 있으면 sbctl이 알아서 스킵하거나 에러를 낼 텐데, 그걸 무시합니다)
${pkgs.sbctl}/bin/sbctl sign -s /boot/EFI/NixOS-boot/grubx64.efi || true
${pkgs.sbctl}/bin/sbctl sign -s /boot/EFI/BOOT/BOOTX64.EFI || true
# Windows 부트로더 등 다른 파일들도 필요한 경우 추가
if [ -f /boot/EFI/Microsoft/Boot/bootmgfw.efi ]; then
${pkgs.sbctl}/bin/sbctl sign -s /boot/EFI/Microsoft/Boot/bootmgfw.efi || true
fi
# 4. 마지막으로 전체 서명 수행
${pkgs.sbctl}/bin/sbctl sign-all || echo "Some files failed to sign, but continuing..."
fi
'';
};
};
}

View file

@ -0,0 +1,37 @@
{ pkgs, config, ... }:
{
environment.systemPackages = with pkgs; [
sbctl
];
# The 99 here ensures that this runs AFTER the grub activation scripts.
system.activationScripts."99-sign-all" = {
text = ''
if [ "$NIXOS_ACTION" = "switch" ] || [ "$NIXOS_ACTION" = "boot" ]; then
# `sbctl verify --json` returns "null" if there is an error,
# empty string if there are no files in the database.
if [ "$(${pkgs.sbctl}/bin/sbctl verify --json)" != "null" ]; then
echo "Signing all EFI binaries with sbctl..."
ESP="${config.boot.loader.efi.efiSysMountPoint}"
readarray -t files < <(find "$ESP" -type f -iname "*.efi" -o -iname "*bzImage")
# Removing all the files first.
for file in "${"$"}{files[@]}"; do
echo "Removing from sbctl: $file"
# The `|| true` part is because otherwise some files might not exist and
# the script would return an error.
${pkgs.sbctl}/bin/sbctl remove-file "$file" >/dev/null 2>&1 || true
done
for file in "${"$"}{files[@]}"; do
echo "Signing with sbctl: $file"
${pkgs.sbctl}/bin/sbctl sign -s "$file" >/dev/null 2>&1
done
fi
fi
'';
};
}

View file

@ -0,0 +1,12 @@
{ ... }:
{
# 사운드
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
}

View file

@ -0,0 +1,23 @@
{ pkgs, ... }:
{
virtualisation.docker = {
enable = true;
};
virtualisation.libvirtd = {
enable = true;
qemu = {
package = pkgs.qemu_kvm;
runAsRoot = true;
swtpm.enable = true;
};
};
# Override the virt-secret-init-encryption service to use correct shell path
systemd.services.virt-secret-init-encryption = {
serviceConfig.ExecStart = [
""
"${pkgs.bash}/bin/bash -c 'umask 0077 && (${pkgs.coreutils}/bin/dd if=/dev/urandom status=none bs=32 count=1 | ${pkgs.systemd}/bin/systemd-creds encrypt --name=secrets-encryption-key - /var/lib/libvirt/secrets/secrets-encryption-key)'"
];
};
}