{ lib, config, pkgs, inputs, ... }: let serverIP = "10.0.174.12"; buildNodeYggIP = "200:ccc6:1361:5c84:aba0:1244:35f5:c903"; hasBootPartition = config.fileSystems ? "/boot"; isNvidia = (builtins.readFile ( pkgs.runCommandLocal "isNvidia" { } '' ${pkgs.pciutils}/bin/lspci | ${pkgs.busybox}/bin/grep NVIDIA | ${pkgs.busybox}/bin/grep VGA > $out || true '' )) != ""; isAdata = # ADATA is a famous cheap troubleful NVMe controllers (builtins.readFile ( pkgs.runCommandLocal "isAdata" { } '' ${pkgs.pciutils}/bin/lspci | ${pkgs.busybox}/bin/grep ADATA | ${pkgs.busybox}/bin/grep -i NVMe > $out || true '' )) != ""; in { nixpkgs.overlays = [ (final: prev: { staruml = prev.staruml.overrideAttrs (old: { src = final.fetchurl { url = "http://${serverIP}/StarUML_6.2.2_amd64.deb"; hash = "sha256-1zxrT7phXeQYNbWHWMyPuHiUglrPSMPP0bfAcfvt8dM="; }; }); }) ]; users.users.student = { isNormalUser = true; initialPassword = "student"; # вход беспарольный, но пароль student extraGroups = [ "video" "sound" "input" "storage" "dialout" ]; packages = let # определение как скачивать плагины jetbrains (скачивать с нашего сервера копию) customJBPlugin = nam: ver: sha: pkgs.stdenv.mkDerivation { name = nam; version = ver; src = pkgs.fetchurl { url = "http://${serverIP}/custom-jetbrains-plugins/${nam}-${ver}.zip"; sha256 = sha; }; nativeBuildInputs = with pkgs; [ unzip ]; dontUnpack = true; installPhase = "unzip $src; mkdir -p $out; mv ./${nam}/* $out"; }; in with pkgs; [ (pkgs.jetbrains.plugins.addPlugins pkgs.jetbrains.idea-community ( # набор плагинов, я бы сказал, богат до избыточности, но главное есть Python # и Database Nagivator. Остальное - любителям и любознательным. (with inputs.nix-jetbrains-plugins.plugins."${system}"; [ idea-community."2024.1"."mobi.hsz.idea.gitignore" #idea-community."2024.1"."org.jetbrains.erlang" idea-community."2024.1"."JProfiler" idea-community."2024.1"."DBN" idea-community."2024.1"."MatlabSupport" idea-community."2024.1"."PlantUML integration" idea-community."2024.1"."org.intellij.scala" idea-community."2024.1"."PythonCore" #idea-community."2024.1"."net.sjrx.intellij.plugins.systemdunitfiles" idea-community."2024.1"."com.intellij.jsonpath" idea-community."2024.1"."Lombook Plugin" idea-community."2024.1"."org.mapstruct.intellij" idea-community."2024.1"."ski.chrzanow.foldableprojectview" idea-community."2024.1"."String Manipulation" #idea-community."2024.1"."quokka.js" idea-community."2024.1"."org.asciidoctor.intellij.asciidoc" idea-community."2024.1"."R4Intellij" idea-community."2024.1"."com.redhat.devtools.lsp4ij" ]) ++ [ # поддежка языка C/C++ на уровне подсветки синтаксиса и автодополнения (customJBPlugin "clsp" "1.0.1" "sha256-AU/Q61YYsGn2BAYykCGm4XGNyeSwd5K/txGNzP2dJg0=") # поддежка фреймворка Spring через opensource-плагин Explyt. пусть будет (customJBPlugin "spring-tool" "241-b3085-signed" "sha256-u9Hqy4BN1johA7e8proMekyERXkE6gXRnqGRNR7FouE=" ) ] )) chromium # браузер pinta # графический редактор sakura # терминал unzipNLS # поддержка zip unrar # поддержка rar mate.engrampa gtk3 whitesur-icon-theme # необходимо для иконок (pkgs.writeShellScriptBin "powermenu" ( builtins.readFile inputs.mireadesktop.packages.x86_64-linux.powermenu )) (pkgs.writeShellScriptBin "resethome" ( builtins.readFile inputs.mireadesktop.packages.x86_64-linux.resethome )) inputs.kompas3d.packages.${pkgs.system}.default # KOMPAS-3D freecad elmerfem gmsh # FEM calculation inputs.stm32cubemx.packages.x86_64-linux.stm32cubemx pandoc #onlyoffice-desktopeditors # к сожалению, пока у OnlyOffice баг со шрифтами. Ждём фикс libreoffice # поэтому пока что у нас Libreoffice... # Напоминаю что у нас есть СЕТЕВОЙ ДИСК по адресу 10.0.174.12 # и для студентов пока есть единая учётка student@mirea.ru, # рассматривается вариант авторизации через sso.mirea.ru. # Преподаватели могут зарегистрироваться ОТДЕЛЬНО seafile-client # утилиты разработчика git cmakeWithGui gnumake ###### ЯЗЫКИ ПРОГРАММИРОВАНИЯ ##### # поставка Python, полный список возможностей # см. на github.com/gregorybednov/mireapython inputs.mireapython.packages.x86_64-linux.mireapython # базовая поддержка C/C++ и дебага clang clang-tools lldb valgrind cpplint cppcheck gcc-arm-embedded # компиляция С/C++ под STM32 и прочие arm octaveFull # GNU Octave shellcheck # проверка шелл-кода (bash, POSIX sh, ...) # Другие возможные языки и инструменты, например: # rustc # - Rust # go gopls delve golint go-tools # - Go jdk kotlin # - Java, Kotlin (идут вместе с IJ IDEA) # ghc haskell-language-server # - Haskell # nodePackages.intelephense # - PHP # dotnet-sdk # - C# ####### Проектирование и разработка баз данных, ИУС, ... ####### # Workbench для управления и ER-моделирования БД на mysql # у КАЖДОГО nixos есть свой локальный сервер mysql, см. ниже по файлу mysql-workbench # аналог Bizagi Modeler, расширенный вариант bpmn.io camunda-modeler # графическое моделирование UML-диаграмм # также доступно моделирование BPMN и ER (staruml.overrideAttrs (oldAttrs: { nativeBuildInputs = (oldAttrs.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ]; postFixup = (oldAttrs.postFixup or "") + '' # Rename the original binary mv $out/bin/staruml $out/bin/.staruml-org # Create the wrapper script makeWrapper ${pkgs.bash}/bin/bash $out/bin/staruml \ --add-flags "-c 'rm -rf \$HOME/.config/StarUML && exec $out/bin/.staruml-org \"\$@\"'" ''; })) # Язык текстового описания UML-диаграмм # актуально для разработчиков ПО (встраивание диаграмм в код) # поддерживается нашей поставкой IJ IDEA CE plantuml archi # поддержка archimate ##### Утилиты и программы для STM32 ##### # 1) STM32CubeIDE упаковать не удалось # 2) есть основания полагать, что её функциональность лучше встроить # в IJ IDEA CE, как это сделано в настоящем Clion; stlink stlink-gui stm32loader ##### СЕТЕВЫЕ УТИЛИТЫ ###### # установлен Cisco Packet Tracer, обернут в firejail чтобы не стучался на Netacad.com nodePackages.node-red # - лоукод-платформа программирования устройств, в частности интернета вещей httpie httpie-desktop # - передовой клиент HTTP-запросов netcat socat # - низкоуровневые простейшие утилиты установления TCP или UDP между компьютерами или с ПЛК opcua-client-gui # - простой графический клиент OPC UA ###### Другой софт ####### logisim-evolution unityhub # UnityHub - 3D-моделирование, визуализация, геймдев, AR/VR (pkgs.stdenv.mkDerivation rec { pname = "dwsim"; version = "9.0.5"; src = pkgs.fetchurl { url = "http://${serverIP}/dwsim_9.0.5-amd64.deb"; sha256 = "sha256:0352mxz9czfh52z4lf7njlyqvikvbh2bgs2h4zi2dsjrssql3h2j"; }; nativeBuildInputs = [ pkgs.dpkg pkgs.makeWrapper pkgs.bubblewrap ]; buildInputs = ( with pkgs; [ dotnet-runtime gtk3 glib pango cairo gdk-pixbuf atk fontconfig freetype ] ++ (with pkgs.xorg; [ libX11 libXcursor libXrandr libXinerama libXi ]) ); unpackPhase = '' dpkg-deb -x $src . ''; installPhase = '' mkdir -p $out/lib/dwsim mkdir -p $out/bin cp -r usr/local/lib/dwsim/* $out/lib/dwsim/ mkdir -p $out/share/icons/hicolor/256x256/apps cp $out/lib/dwsim/bitmaps/DWSIM_ico.png \ $out/share/icons/hicolor/256x256/apps/dwsim.png mkdir -p "$out/lib/dwsim/DWSIM Application Data" cat > $out/bin/dwsim << 'EOF' #!/bin/sh set -e APPDIR="@out@/lib/dwsim" APPDATA="$HOME/.local/share/dwsim-appdata" mkdir -p "$APPDATA" # LD_LIBRARY_PATH для GtkSharp export LD_LIBRARY_PATH="@gtk3@/lib:@glib@/lib:@pango@/lib:@cairo@/lib:@gdk-pixbuf@/lib:@atk@/lib:@fontconfig@/lib:@freetype@/lib:$LD_LIBRARY_PATH" export DISPLAY="$DISPLAY" exec @bwrap@ \ --bind "@out@" "@out@" \ --bind "$APPDATA" "$APPDIR/DWSIM Application Data" \ --ro-bind /nix /nix \ --ro-bind "$XAUTHORITY" "$HOME/.Xauthority" \ --setenv XAUTHORITY "$HOME/.Xauthority" \ --dev /dev \ --proc /proc \ --bind /tmp/.X11-unix /tmp/.X11-unix \ --setenv DISPLAY $DISPLAY \ --chdir "$APPDIR" \ @dotnet@ "$APPDIR/DWSIM.UI.Desktop.exe" "$@" EOF substituteInPlace $out/bin/dwsim \ --subst-var out \ --subst-var-by bwrap ${pkgs.bubblewrap}/bin/bwrap \ --subst-var-by dotnet ${pkgs.dotnet-runtime}/bin/dotnet \ --subst-var-by gtk3 ${pkgs.gtk3} \ --subst-var-by glib ${pkgs.glib} \ --subst-var-by pango ${pkgs.pango} \ --subst-var-by cairo ${pkgs.cairo} \ --subst-var-by gdk-pixbuf ${pkgs.gdk-pixbuf} \ --subst-var-by atk ${pkgs.atk} \ --subst-var-by fontconfig ${pkgs.fontconfig} \ --subst-var-by freetype ${pkgs.freetype} chmod +x $out/bin/dwsim mkdir -p $out/share/applications cat > $out/share/applications/dwsim.desktop << EOF [Desktop Entry] Type=Application Name=DWSIM GenericName=Process Simulator Comment=Chemical Process Simulation Environment Exec=dwsim Icon=dwsim Terminal=false Categories=Development StartupWMClass=DWSIM EOF ''; }) (pkgs.stdenv.mkDerivation rec { pname = "cnc_vmc_sim"; version = "1.0.0-share"; src = builtins.fetchTarball { url = "http://${serverIP}/linux_cnc_vmc_share.tar.xz"; sha256 = "sha256:1hjkm2wq6dfmddb2van1q8hdvf41bp4snslcbkj0b1myi3zpi1md"; }; installPhase = '' runHook preInstall mkdir -p $out/bin mkdir -p $out/share/applications mkdir -p $out/share/icons cp ${src}/icon.png $out/share/icons/${pname}.png cp ${fhsEnv}/bin/${pname}-fhs $out/bin/${pname} cp ${desktopItem}/share/applications/*.desktop $out/share/applications ''; fhsEnv = pkgs.buildFHSEnv { name = "${pname}-fhs"; targetPkgs = p: with p; [ eudev.out libGL.out openal.out xorg.libX11.out ]; runScript = "${src}/${pname}"; }; desktopItem = pkgs.makeDesktopItem { name = "CNC VMC (free)"; exec = "${pname}"; desktopName = "CNC VMC (free)"; categories = [ "Development" ]; icon = "${pname}"; terminal = false; startupNotify = false; }; }) (pkgs.stdenv.mkDerivation rec { pname = "ramus"; version = "0.1.3"; src = builtins.fetchTarball { url = "http://${serverIP}/ramus.tar.xz"; sha256 = "sha256:1a9fha7zwyyag0q4glk58pzigqdczshxpnax7cdzg1bry4aw6f9d"; }; installPhase = '' sed -e "s~ramus.ico~$out/share/icons/ramus.ico~; s~Other~Database~" -i share/applications/ramus.desktop mkdir $out cp -r share bin lib $out echo "JDK_JAVA_OPTIONS='-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel' ${pkgs.jre8}/bin/java -jar $out/bin/ramus-startup.jar" > $out/bin/ramus chmod +x $out/bin/ramus ''; }) # поставка SimInTech. Кодогенерация библиотек для ПК работает, # но несовместима с .dll из windows! #simintech.packages.x86_64-linux.simintech (pkgs.stdenv.mkDerivation rec { pname = "simintech"; version = "2.23.13"; src = builtins.fetchTarball { url = "http://${serverIP}/simintech_rus_linux.tgz"; sha256 = "sha256:1i9plx6vx6jm38bx4kbh4piak5jwrpc4hxxjd3b89zyng1g4abvs"; }; dontFixLibtool = true; fhsEnv = pkgs.buildFHSEnv { name = "${pname}-fhs-env"; targetPkgs = p: with p; [ at-spi2-atk.out gdk-pixbuf.out glamoroustoolkit.out glib.out gtk2.out libGL.out libGLU.out pango.out xorg.libX11.out zlib.out xorg.libX11.out zlib.out (pkgs.writeShellScriptBin "firefox" "exec ${pkgs.chromium}/bin/chromium \"$@\"") # похоже, что SimInTech захардкодил Firefox, но не все так юзают Firefox ]; runScript = "${src}/bin/mmain"; }; desktopItem = pkgs.makeDesktopItem { name = "SimInTech"; exec = "simintech"; desktopName = "SimInTech"; categories = [ "Development" ]; icon = "simintech"; terminal = false; startupNotify = false; mimeTypes = [ "x-scheme-handler/prt" ]; }; installPhase = '' runHook preInstall mkdir -p $out/bin mkdir -p $out/share/applications mkdir -p $out/share/icons #cp ${src}/share/icon.svg $out/share/icons/simintech.svg cp ${fhsEnv}/bin/${pname}-fhs-env $out/bin/simintech cp ${desktopItem}/share/applications/*.desktop $out/share/applications runHook postInstall ''; }) (stdenv.mkDerivation { pname = "erlu-idef0-editor"; version = "1.0.1"; src = builtins.fetchGit { url = "http://forgejo.gregorbednov.ru/gregorbednov/erlu.git"; ref = "master"; rev = "58198c6ecd8572f1c7db42b90c8189954c9a32fc"; }; nativeBuildInputs = with pkgs; [ cmake pkg-config qt6.wrapQtAppsHook qt6.qttools ]; buildInputs = with pkgs; [ qt6.qtbase qt6.qtsvg ]; configurePhase = '' cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=$out \ -DBUILD_COLORS_PLUGIN=ON ''; buildPhase = '' cmake --build build find . -path "*/translations/*.ts" -print0 | while IFS= read -r -d "" f; do out_path=$(printf '%s\n' "$f" | sed 's/\.ts$/.qm/') lrelease "$f" -qm "$out_path" done ''; installPhase = '' runHook preInstall cmake --install build --prefix $out # app translations if [ -d translations ]; then mkdir -p $out/share/idef0/translations find translations -maxdepth 1 -type f -name '*.qm' -print0 | xargs -0 -r cp -t $out/share/idef0/translations fi # plugin translations find src/plugins -path "*/translations/*.qm" -print0 | while IFS= read -r -d "" f; do rel="''${f#src/plugins/}" # e.g., color/translations/colors_en.qm plugdir="''${rel%%/translations/*}" # e.g., color dest="$out/plugins/$plugdir/translations" mkdir -p "$dest" cp "$f" "$dest/" done runHook postInstall ''; qtWrapperArgs = [ "--set" "QT_LOGGING_RULES" "qt.qpa.wayland.textinput=false" ]; meta = with lib; { description = "IDEF0 diagram editor built with Qt 6 Widgets"; license = licenses.lgpl3Plus; mainProgram = "erlu_idef0_editor"; platforms = platforms.linux; }; }) (pkgs.writeShellScriptBin "gcc" ''${pkgs.clang}/bin/clang "$@"'') (pkgs.writeShellScriptBin "g++" ''${pkgs.clang}/bin/clang++ "$@"'') (vscode-with-extensions.override { vscodeExtensions = with vscode-extensions; [ ms-vscode.cpptools-extension-pack zainchen.json ms-dotnettools.csharp formulahendry.code-runner tomoki1207.pdf ms-vscode.hexeditor ms-vscode.makefile-tools ms-ceintl.vscode-language-pack-ru ms-python.python ms-python.pylint ms-python.isort ms-python.black-formatter jebbs.plantuml ms-toolsai.jupyter ms-toolsai.vscode-jupyter-slideshow ms-toolsai.vscode-jupyter-cell-tags ms-vscode-remote.remote-ssh timonwong.shellcheck ] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [ { name = "better-cpp-syntax"; publisher = "jeff-hykin"; version = "1.27.1"; sha256 = "sha256-GO/ooq50KLFsiEuimqTbD/mauQYcD/p2keHYo/6L9gw="; } { name = "vscode-cppcheck"; publisher = "brobeson"; version = "0.1.0"; sha256 = "sha256-RDgO8/XenttOcYQSGEu4N2FKg9+FZaQe6HYkVjztH5o="; } { name = "cortex-debug"; publisher = "marus25"; version = "1.12.1"; sha256 = "sha256-ioK6gwtkaAcfxn11lqpwhrpILSfft/byeEqoEtJIfM0="; } { name = "vscode-serial-monitor"; publisher = "ms-vscode"; version = "0.13.251128001"; sha256 = "sha256-eTQcLyF6DMvzDByKLw2KR8PrjVwejsOU60Hew7IOmY8="; } { name = "linux-arm-none-eabi"; publisher = "metalcode-eu"; version = "0.1.2"; sha256 = "sha256-MCpBsd491pCO1K9tgL5KBJQbtr4IuVEuTPQzQHeQSWQ="; } { name = "arm-assembly-syntax"; publisher = "ciprianelies"; version = "1.7.6"; sha256 = "sha256-4vWw0ogtZ3mOw0lT95k/5I/7GMvU5kfaaztwc+eI/do="; } { name = "stm32-for-vscode"; publisher = "bmd"; version = "3.2.13"; sha256 = "sha256-Dzj++F0xTDOaL9VA3X/bVtAhkxd8kPPl3Oz8LWrXpAA="; } { name = "qt-cpp-pack"; publisher = "TheQtCompany"; version = "1.0.2"; sha256 = "sha256-Kd2/kk3qJUOahz71Uh3mUI1wDuwS8/t84tgdWorRPG4"; } { name = "debug-tracker-vscode"; publisher = "mcu-debug"; version = "0.0.15"; sha256 = "sha256-2u4Moixrf94vDLBQzz57dToLbqzz7OenQL6G9BMCn3I="; } { name = "memory-view"; publisher = "mcu-debug"; version = "0.0.28"; sha256 = "sha256-mQr/uLulKoPVXz0GaMMEHZ/ZSmSAEfO9UpFzy4MfcW4="; } { name = "rtos-views"; publisher = "mcu-debug"; version = "0.0.13"; sha256 = "sha256-eTEdZkHbAGSDXP9A06YL6jDBfO8rU1kC9RysxOUxI1U="; } { name = "peripheral-viewer"; publisher = "mcu-debug"; version = "1.6.0"; sha256 = "sha256-nKK8HRzeqDixpdKmgacjhNzanJaTsAnYLC6nCbmWXuU="; } ]; }) qtcreator qt6.full qt6.qtbase gdb isort black # POSIX утилиты для совместимости om4 pax mailutils sharutils flex bison universal-ctags inetutils uucp util-linux cflow ncompress ]; }; # вставленные флешки автоматически монтируются services.devmon.enable = true; # необходимо для совместимости с POSIX по команде at, при отсутствии необходимости можно удалить services.atd = { enable = true; allowEveryone = true; }; # на каждой машине свой сервер mysql и postgresql services.mysql = { enable = true; package = pkgs.mysql80; }; services.postgresql = { enable = true; authentication = pkgs.lib.mkOverride 10 '' #type database DBuser auth-method local all all trust ''; }; # и оба поддерживают вход без пароля в "руты" system.userActivationScripts.mycnf = { text = '' printf "[client]\nport=3306\nuser=root" > /home/student/.my.cnf echo "\set user postgres" > /home/student/.psqlrc ''; deps = [ ]; }; environment = { etc."gtk-3.0/settings.ini" = { text = '' [Settings] gtk-icon-theme-name = WhiteSur ''; mode = "0644"; }; variables = { PGUSER = "postgres"; }; }; services.grdcontrol.enable = true; imports = [ inputs.guardant.nixosModules.grdcontrol ./hardware-configuration.nix ]; programs.tmux = { enable = true; withUtempter = true; historyLimit = 5000; clock24 = true; }; programs.chromium = { enable = true; extraOpts = { "BrowserSignin" = 0; "SyncDisabled" = true; "PasswordManagerEnabled" = false; "SpellcheckEnabled" = true; "SpellcheckLanguage" = [ "ru" "en-US" "fr" ]; }; }; # если машина установлена на диск с Windows, # то она позволяет "увидеть" и выбрать Windows в течение 30 с # иначе - 5 c таймаута (для виртуалок) boot.loader = if hasBootPartition then { efi.canTouchEfiVariables = true; timeout = 30; grub = { enable = true; efiSupport = true; device = "nodev"; useOSProber = true; theme = "${pkgs.sleek-grub-theme.override { withStyle = "orange"; withBanner = "Выберите ОС"; }}"; }; } else { timeout = 5; grub = { enable = true; device = "/dev/sda"; theme = "${pkgs.sleek-grub-theme.override { withStyle = "orange"; withBanner = "Загрузчик Linux"; }}"; }; }; time.hardwareClockInLocalTime = hasBootPartition; # настройки Nix nixpkgs.config = { allowUnfree = true; nvidia.acceptLicense = true; }; nix.settings = { # Локальный кэш идёт первым — большинство пакетов уже собраны на build-ноде substituters = [ "http://nixos.builds.node" "https://cache.nixos.org" ]; trusted-public-keys = [ "nixos.builds.node:E/XNkcdzB0EyTyEJuOTXJH8qynxgCfQ87JHkbD88uF8=" "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ]; trusted-substituters = [ "http://nixos.builds.node" ]; auto-optimise-store = true; # Если build-нода временно недоступна — переходим к cache.nixos.org, не зависаем connect-timeout = 5; experimental-features = [ "nix-command" "flakes" ]; # На дисках 50 GiB автоматически запускать GC при нехватке места min-free = 2147483648; # 2 GiB — порог запуска GC max-free = 5368709120; # 5 GiB — цель освобождения }; nix.gc = { automatic = true; dates = "weekly"; randomizedDelaySec = "45min"; # машины не запускают GC одновременно options = "--delete-older-than 14d"; }; # Хранить не более 5 поколений в меню GRUB boot.loader.grub.configurationLimit = 5; # Периодический TRIM для SSD (безопасен и на HDD — просто no-op) services.fstrim.enable = true; # nix-daemon стартует только после Yggdrasil, иначе nixos.builds.node недостижим systemd.services.nix-daemon = { after = [ "yggdrasil.service" ]; wants = [ "yggdrasil.service" ]; }; # Уникальный hostname на основе последних 6 цифр MAC-адреса основного интерфейса. # networking.hostName = "nixos" остаётся fallback-значением в /etc/hostname; # сервис перекрывает его transient-именем при каждой загрузке. systemd.services.hostname-from-mac = { description = "Set unique hostname from primary NIC MAC address"; wantedBy = [ "network-pre.target" ]; before = [ "network-pre.target" ]; after = [ "systemd-udev-settle.service" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; script = '' mac=$(${pkgs.iproute2}/bin/ip link show \ | grep -v LOOPBACK \ | grep -oE '([0-9a-f]{2}:){5}[0-9a-f]{2}' \ | head -1 \ | tr -d ':') if [ -n "$mac" ]; then ${pkgs.systemd}/bin/hostnamectl set-hostname --transient "nixos-''${mac: -6}" fi ''; }; # Директория для хранения данных о физическом расположении компьютера systemd.tmpfiles.rules = [ "d /var/lib/place 0755 student users -" ]; ##### НАСТРОЙКИ ГРАФИКИ И РАБОЧЕГО СТОЛА ###### hardware.graphics = { enable = true; #enable32Bit = true; extraPackages = if isNvidia then with pkgs; [ nvidia-vaapi-driver vaapiVdpau libvdpau-va-gl ] else [ ]; }; services.xserver = { enable = true; videoDrivers = if isNvidia then [ "nvidia" ] else [ "modesetting" "fbdev" ]; xkb.layout = "us,ru"; xkb.options = "grp:alt_shift_toggle"; }; hardware.enableAllFirmware = true; hardware.nvidia = { package = config.boot.kernelPackages.nvidiaPackages.stable; modesetting.enable = true; powerManagement.enable = true; open = false; nvidiaSettings = false; }; services.udev.extraRules = if isAdata then '' ACTION=="add|change",KERNEL=="nvme[0-9]", ATTR{queue/scheduler}="none" '' else ""; boot.kernelParams = lib.optionals isNvidia [ "nvidia-drm.modeset=1" ] ++ lib.optionals isAdata [ "nvme_core.default_ps_max_latency_us=0" "nvme_core.io_timeout=4294967295" ]; boot.blacklistedKernelModules = lib.optionals isNvidia [ "nouveau" ]; boot.extraModprobeConfig = if isNvidia then "options nvidia " + lib.concatStringsSep " " [ "NVreg_UsePageAttributeTable=1" "NVreg_EnablePCIeGen3=1" "NVreg_RegistryDwords=RMUseSwI2c=0x01;RMI2cSpeed=100" ] else ""; services.displayManager.autoLogin.user = "student"; services.getty.autologinUser = "student"; services.xserver.displayManager.lightdm.enable = true; services.xserver.displayManager.startx.enable = true; services.displayManager.defaultSession = "MIREA-WindowsLike+Metacity"; services.xserver.displayManager.session = [ { manage = "desktop"; name = "MIREA-WindowsLike"; # подробности настроек рабочего стола см. на github.com/gregorybednov/mireadesktop start = '' ${inputs.mireadesktop.packages.x86_64-linux.tint2} & ${inputs.mireadesktop.packages.x86_64-linux.pcmanfm} & ${inputs.mireadesktop.packages.x86_64-linux.sxhkd} & #${inputs.mireadesktop.packages.x86_64-linux.xcape} & waitPID=$! ''; } { manage = "window"; name = "Metacity"; start = '' ${pkgs.metacity}/bin/metacity & waitPID=$! ''; } ]; ##### СЕТЕВЫЕ НАСТРОЙКИ ####### services.yggdrasil = { enable = true; persistentKeys = true; settings = { Peers = [ "tcp://${serverIP}:12345" ]; }; }; # каждый компьютер имеет выход в интернет networking.networkmanager.enable = true; networking.hostName = "nixos"; networking.firewall.allowedTCPPorts = [ 22 ] ++ lib.optionals config.services.harmonia.enable [ 80 ]; # каждый компьютер знает, что kafpi.local - это адрес нашего сервера networking.hosts."${serverIP}" = [ "kafpi.local" ]; networking.hosts."${buildNodeYggIP}" = [ "nixos.builds.node" ]; #### ЛОКАЛИЗАЦИЯ ##### time.timeZone = "Europe/Moscow"; i18n.defaultLocale = "ru_RU.UTF-8"; console = { font = "cyr-sun16"; useXkbConfig = true; }; # установлены шрифты Microsoft (corefonts), # установлен ГОСТ Тип А (задел на будущее), # установлены базовые свободные шрифты, # установлен шрифт Jetbrains Mono fonts.packages = with pkgs; [ jetbrains-mono inputs.gostfont.packages.x86_64-linux.gostfont corefonts liberation_ttf ]; ####### ПРОЧИЕ НАСТРОЙКИ ####### environment.systemPackages = with pkgs; [ vim tree wget git yad # Утилита фиксации физического расположения компьютера в аудитории. # Использование: place [АУДИТОРИЯ] (например: place А-101) # Запись: /var/lib/place/location (JSON, доступен root по SSH) # При запуске от root через SSH автоматически подключается к X-сессии student на :0 (pkgs.writeShellApplication { name = "place"; runtimeInputs = [ yad coreutils util-linux ]; text = '' ROOM_ARG="''${1:-}" PLACE_FILE="/var/lib/place/location" # Когда запускается от root по SSH — показать диалог на локальном X :0 if [ -z "''${DISPLAY:-}" ]; then export DISPLAY=":0" export XAUTHORITY="/home/student/.Xauthority" fi if ! result=$(yad \ --title="Место компьютера" \ --text="Зафиксируйте расположение этого компьютера в аудитории.\nДанные сохраняются в /var/lib/place/location." \ --form \ --field="Аудитория" \ --field="Ряд:NUM" \ --field="Место:NUM" \ --button="Сохранить:0" \ --button="Отмена:1" \ --width=340 \ -- "''${ROOM_ARG}" 1 1 \ 2>/dev/null); then exit 0 # Нажата «Отмена» — без ошибки fi room=$(printf '%s' "''${result}" | cut -d'|' -f1) row=$(printf '%s' "''${result}" | cut -d'|' -f2 | cut -d'.' -f1) seat=$(printf '%s' "''${result}" | cut -d'|' -f3 | cut -d'.' -f1) if [ -z "''${room}" ]; then echo "Ошибка: поле «Аудитория» не заполнено" >&2 exit 1 fi mkdir -p "$(dirname "''${PLACE_FILE}")" printf '{"room":"%s","row":%s,"seat":%s,"host":"%s","at":"%s"}\n' \ "''${room}" "''${row}" "''${seat}" "$(hostname)" "$(date -Iseconds)" \ > "''${PLACE_FILE}" echo "Сохранено: аудитория ''${room}, ряд ''${row}, место ''${seat}" echo "Файл: ''${PLACE_FILE}" ''; }) ]; # удаленный доступ в пределах нашей сети services.openssh = { enable = true; settings.PermitRootLogin = "yes"; }; users.users.root.openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCyBYo/E/FkFZVABzMixLS2TWaipfN5T24y8f+E6Px1t+IG8PLnQ38dLJiCR8k971DOycLuJUfKWsC06BK3XLWTO0+PmpfGKNT4NI6dwP2REl/umaignP/QQSs2w9Ff49WqPjIYTSmATTsCNZSVB0VtM0eJ+Y9Ff4CXb1frtt4GYztk6XB3jc3TxV72qzB0g6DqrHkf6pT5YAq2UeuFGZYSZCqBvVXCGcvKHkO1KBubuo95itVA5XbzK3INQTZpQowbtK4ULhUYlaGBcX5tYq1bdiTCDlTcLt6MfxYfFHSFiHbJOzdGPd+mXM7urOQhq49uQOf07dHt9qAzQHajItQb+X3FOgyFt4n6Y9Q37gn/6KC3PH1zClldq9DtgttuG/Xk15q+uvCldji9YIgb80aRHBIp6DY8PlYodmGGesBLiBMGQ7hgKupfkqszjfMkxnMYIkZodUCQVgaqsxsEQ7lD84JJMgBY8HkNLxKhy+6dP6kTc4vTtrpjezq/Ph95PFE= bednov@kafpi-108-1-mainserver2" ]; services.gnome.gnome-keyring.enable = true; programs = { firejail = { enable = true; wrappedBinaries = { packettracer7 = { executable = "${inputs.packettracer7.packages.x86_64-linux.default}/bin/packettracer7"; extraArgs = [ "--net=none" "--noprofile" ]; }; }; }; java.enable = true; gnupg.agent = { enable = true; enableSSHSupport = true; }; udevil.enable = true; # тоже нужно для флешек }; # НЕ МЕНЯТЬ, иначе придётся все компы переустанавливать, а не обновлять system.stateVersion = "24.05"; }