i20n and universalization for config
Some checks failed
/ build-installer (push) Failing after 2s

This commit is contained in:
Gregory Bednov 2026-09-14 14:21:08 +03:00
commit 4aae45f13b
10 changed files with 588 additions and 180 deletions

View file

@ -11,7 +11,8 @@ jobs:
SERVER: ${{ forgejo.server_url }}
REPO: ${{ forgejo.repository }}
run: |
ISO="result/iso/mirea-nixos-installer.iso"
ISO_NAME=$(nix eval --raw ./installer#nixosConfigurations.installer.config.isoImage.isoName)
ISO="result/iso/$ISO_NAME"
NEW_SHA=$(sha256sum "$ISO" | awk '{print $1}')
LATEST_BODY=$(curl -sf \
@ -37,7 +38,7 @@ jobs:
curl -sf -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/octet-stream" \
"$SERVER/api/v1/repos/$REPO/releases/$RELEASE_ID/assets?name=mirea-nixos-installer.iso" \
"$SERVER/api/v1/repos/$REPO/releases/$RELEASE_ID/assets?name=$ISO_NAME" \
--data-binary "@$ISO"
echo "Published release $TAG (sha256: $NEW_SHA)"

View file

@ -7,7 +7,12 @@
}:
let
serverIP = "10.0.174.12";
serverAddress = "kafpi.local";
buildNodeYggIP = "200:ccc6:1361:5c84:aba0:1244:35f5:c903";
sshKeys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCyBYo/E/FkFZVABzMixLS2TWaipfN5T24y8f+E6Px1t+IG8PLnQ38dLJiCR8k971DOycLuJUfKWsC06BK3XLWTO0+PmpfGKNT4NI6dwP2REl/umaignP/QQSs2w9Ff49WqPjIYTSmATTsCNZSVB0VtM0eJ+Y9Ff4CXb1frtt4GYztk6XB3jc3TxV72qzB0g6DqrHkf6pT5YAq2UeuFGZYSZCqBvVXCGcvKHkO1KBubuo95itVA5XbzK3INQTZpQowbtK4ULhUYlaGBcX5tYq1bdiTCDlTcLt6MfxYfFHSFiHbJOzdGPd+mXM7urOQhq49uQOf07dHt9qAzQHajItQb+X3FOgyFt4n6Y9Q37gn/6KC3PH1zClldq9DtgttuG/Xk15q+uvCldji9YIgb80aRHBIp6DY8PlYodmGGesBLiBMGQ7hgKupfkqszjfMkxnMYIkZodUCQVgaqsxsEQ7lD84JJMgBY8HkNLxKhy+6dP6kTc4vTtrpjezq/Ph95PFE= bednov@kafpi-108-1-mainserver2"
];
hasBootPartition = config.fileSystems ? "/boot";
isNvidia =
(builtins.readFile (
@ -21,8 +26,23 @@ let
${pkgs.pciutils}/bin/lspci | ${pkgs.busybox}/bin/grep ADATA | ${pkgs.busybox}/bin/grep -i NVMe > $out || true
''
)) != "";
# any MIREA Uuniversity specifics (apps, wallpapers) are located in ./mirea-specific
# other uuniversities can use their own files there
#
# всё, что специфично именно для МИРЭА (брендирование, герб, номер учебной недели),
# вынесено в mirea-specific/ — другой вуз может подставить свои значения/файлы.
university = import ./mirea-specific/university.nix;
mireaweek = pkgs.callPackage ./mirea-specific/mireaweek.nix { };
desktop = inputs.mireadesktop.lib.mkDesktop {
wallpaper = university.wallpaper;
extraTint2Widgets = import ./mirea-specific/tint2-widget.nix { inherit mireaweek; };
};
in
{
# local versions for stm32cubemx and staruml installers
# локальные версии stm32cubemx и staruml
nixpkgs.overlays = [
(final: prev: {
staruml = prev.staruml.overrideAttrs (old: {
@ -32,19 +52,32 @@ in
};
});
stm32cubemx = prev.stm32cubemx.override {
fetchzip = args: prev.fetchzip (args // {
fetchzip =
args:
prev.fetchzip (
args
// {
url = "http://${serverIP}/stm32cube_mx_v6111-lin.zip";
hash = "sha256-By9T43GLM1J63TkRi3kl05h1RflBorU1QHgYOrXQ9N0=";
});
buildFHSEnv = args: prev.buildFHSEnv ( args // {
}
);
buildFHSEnv =
args:
prev.buildFHSEnv (
args
// {
unshareNet = true;
});
}
);
};
})
];
users.users.student = {
isNormalUser = true;
initialPassword = "student"; # вход беспарольный, но пароль student
# login is passwordless, however password is 'student' too
# вход беспарольный, но пароль student
initialPassword = "student";
extraGroups = [
"video"
"sound"
@ -54,7 +87,8 @@ in
];
packages =
let
# определение как скачивать плагины jetbrains (скачивать с нашего сервера копию)
# local copies of plugins
# скачивать с нашего сервера копии плагинов jetbrains
customJBPlugin =
nam: ver: sha:
pkgs.stdenv.mkDerivation {
@ -73,8 +107,8 @@ in
[
(pkgs.jetbrains.plugins.addPlugins pkgs.jetbrains.idea-community (
# набор плагинов, я бы сказал, богат до избыточности, но главное есть Python
# и Database Nagivator. Остальное - любителям и любознательным.
# wide plugin set. PythonCore and Database Navigator is a key difference to stock IDEA CE
# богатый набор плагинов, главное есть 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"
@ -96,53 +130,86 @@ in
idea-community."2024.1"."com.redhat.devtools.lsp4ij"
])
++ [
# поддежка фреймворка Spring через opensource-плагин Explyt. пусть будет
# russian opensource Explyt Spring plugin out of Jetbrains Marketplace
# поддежка фреймворка 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
))
# browser
# браузер
chromium
inputs.kompas3d.packages.${pkgs.system}.default # KOMPAS-3D
freecad elmerfem gmsh # FEM calculation
# graphics editor
# графический редактор
pinta
# terminal emulator
# терминал
sakura
# GUI archive/unarchive tool with zip and rar support
# Архиватор с поддержкой zip и rar
mate.engrampa
unzipNLS
unrar
gtk3
# icon theme
# тема иконок
whitesur-icon-theme
# powermenu GUI util for poweroff or reboot
# графическое меню выключения или перезагрузки компьютера
(pkgs.writeShellScriptBin "powermenu" (builtins.readFile desktop.powermenu))
# resethome reset student home, deleting most of files, user caches and configs, leaving only default options
# useful for resetting vandal settings
#
# resethome позволяет удалить содержимое домашней директории пользователя student,
# сбрасывая нефунциональные настройки, установленные студентами в том числе из хулиганских побуждений
(pkgs.writeShellScriptBin "resethome" (builtins.readFile desktop.resethome))
inputs.kompas3d.packages.${pkgs.system}.default # KOMPAS-3D CAD
freecad
elmerfem
gmsh # FEM calculation
inputs.nix-wine-experiments.packages.x86_64-linux.nbdesigner
pandoc
onlyoffice-desktopeditors
# -----
# Seafile client for department cloud drive
# Напоминаю что у нас есть СЕТЕВОЙ ДИСК по адресу 10.0.174.12
# и для студентов пока есть единая учётка student@mirea.ru,
# рассматривается вариант авторизации через sso.mirea.ru.
# и для студентов пока есть единая учётка (домен и SSO — см. mirea-specific/university.nix),
# рассматривается вариант авторизации через SSO вуза.
# Преподаватели могут зарегистрироваться ОТДЕЛЬНО
seafile-client
# ------
# developer utils
# утилиты разработчика
git
cmakeWithGui
gnumake
###### PROGRAMMING LANGUAGES #####
###### ЯЗЫКИ ПРОГРАММИРОВАНИЯ #####
# Python enviroment, for full abilites list see
# https://forgejo.gregorbednov.ru/gregorbednov/mireapython
# поставка Python, полный список возможностей
# см. на github.com/gregorybednov/mireapython
# см. на https://forgejo.gregorbednov.ru/gregorbednov/mireapython
inputs.mireapython.packages.x86_64-linux.mireapython
# basic C/C++ support and debug
# базовая поддержка C/C++ и дебага
clang
clang-tools
@ -150,55 +217,82 @@ in
valgrind
cpplint
cppcheck
gcc-arm-embedded # компиляция С/C++ под STM32 и прочие arm
# C/C++ toolchain for STM32 and other ARM chips
# компиляция С/C++ под STM32 и прочие arm
gcc-arm-embedded
octaveFull # GNU Octave
shellcheck # проверка шелл-кода (bash, POSIX sh, ...)
# static shell code analyzer (bash, POSIX sh, ...)
# проверка шелл-кода (bash, POSIX sh, ...)
shellcheck
# Other possible languages and tools, e.g.:
# Другие возможные языки и инструменты, например:
# rustc # - Rust
# go gopls delve golint go-tools # - Go
jdk
kotlin # - Java, Kotlin (идут вместе с IJ IDEA)
kotlin # - Java, Kotlin (needed for IJ IDEA)
# ghc haskell-language-server # - Haskell
# nodePackages.intelephense # - PHP
# dotnet-sdk # - C#
####### DB modeling and development ##########
####### Проектирование и разработка баз данных, ИУС, ... #######
# EACH nixos has its own local mysql and postgres servers
# with root access by students, see below for details
#
# у КАЖДОГО nixos есть свой локальный сервер mysql и postgres,
# у студентов есть root-доступ, см. ниже по файлу
# Workbench for ER modeling and wrigin MySQL code
# Workbench для управления и ER-моделирования БД на mysql
# у КАЖДОГО nixos есть свой локальный сервер mysql, см. ниже по файлу
mysql-workbench
# BPMN Modeler, just like Bizagi Modeler we used before, but cross-platform
# btw has web-version on https://bpmn.io
#
# аналог Bizagi Modeler, расширенный вариант bpmn.io
camunda-modeler
# GUI UML, BPMN, ER, etc. modeling
#
# графическое моделирование UML-диаграмм
# также доступно моделирование BPMN и ER
(staruml.overrideAttrs (oldAttrs: {
nativeBuildInputs = (oldAttrs.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
postFixup =
(oldAttrs.postFixup or "")
+ ''
# Rename the original binary
# бесконечный триал
postFixup = (oldAttrs.postFixup or "") + ''
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 \"\$@\"'"
'';
}))
# declarative text to UML diagrams visualizer
# very useful for software developers (bc inserting diagrams into code)
# has VSCode and IJ IDEA CE support
#
# Язык текстового описания UML-диаграмм
# актуально для разработчиков ПО (встраивание диаграмм в код)
# поддерживается нашей поставкой IJ IDEA CE
plantuml
# graph visualizer
# it is necessary for plantuml
#
# визуализатор графов общего назначения
# обязателен для plantuml
graphviz
archi # поддержка archimate
# archimate diagrams support
# поддержка archimate
archi
##### Utils and apps for STM32 #####
##### Утилиты и программы для STM32 #####
stm32cubemx
stlink
@ -206,19 +300,41 @@ in
stm32loader
openocd
##### NETWORK APPS AND UTILS ######
##### СЕТЕВЫЕ УТИЛИТЫ ######
# установлен Cisco Packet Tracer, обернут в firejail чтобы не стучался на Netacad.com
nodePackages.node-red # - лоукод-платформа программирования устройств, в частности интернета вещей
httpie
httpie-desktop # - передовой клиент HTTP-запросов
netcat
socat # - низкоуровневые простейшие утилиты установления TCP или UDP между компьютерами или с ПЛК
opcua-client-gui # - простой графический клиент OPC UA
# Cisco Packet Tracer 7 was installed but it was firejailed to work without Netacad.com accounts
# установлен Cisco Packet Tracer 7, обернут в firejail чтобы не стучался на Netacad.com
# lowcode for IoT programming used in IIoT and IoT practices in uuniversity
# лоукод-платформа программирования устройств, в частности интернета вещей
nodePackages.node-red
# probably best http request client
# передовой клиент HTTP-запросов
httpie
httpie-desktop
# simple network and socket level utils for practicing simple TCP and UDP between PCs, IoT devices and PLCs
# низкоуровневые простейшие утилиты установления TCP или UDP между компьютерами или с ПЛК
netcat
socat
# simple OPC UA GUI client
# простой графический клиент OPC UA
opcua-client-gui
###### OTHER SOFTWARE ####
###### Другой софт #######
logisim-evolution
unityhub # UnityHub - 3D-моделирование, визуализация, геймдев, AR/VR
# UnityHub - 3D modeling, visualisation, gamedev, AR/VR
# UnityHub - 3D моделирование, визуализация, геймдев, AR/VR
unityhub
# DWSim for chemical techology simulation and modeling
# DWSIM - симулятор химических технологических процессов
(pkgs.stdenv.mkDerivation rec {
pname = "dwsim";
version = "9.0.5";
@ -332,6 +448,8 @@ in
'';
})
# shareware CNC VMC 3D-graphical simulator
(pkgs.stdenv.mkDerivation rec {
pname = "cnc_vmc_sim";
version = "1.0.0-share";
@ -372,6 +490,9 @@ in
startupNotify = false;
};
})
# ramus educational for IDEF0 and DFD modeling
# ramus educational для моделирования в нотациях IDEF0, DFD
(pkgs.stdenv.mkDerivation rec {
pname = "ramus";
version = "0.1.3";
@ -388,6 +509,10 @@ in
'';
})
# SimInTech (russian matlab simulink alternative)
# C code generation works, but dynamic libraries are NOT
# compatible with Windows DLL!
#
# поставка SimInTech. Кодогенерация библиотек для ПК работает,
# но несовместима с .dll из windows!
(pkgs.stdenv.mkDerivation rec {
@ -441,6 +566,8 @@ in
'';
})
# ErLu is a modern Qt-based opensource alternative to Ramus and Erwin Process Modeler
# ErLu - современная альтернатива с октрытым исходным кодом для Ramus и Erwin Process Modeler
(stdenv.mkDerivation {
pname = "erlu-idef0-editor";
version = "1.0.1";
@ -495,7 +622,11 @@ in
runHook postInstall
'';
qtWrapperArgs = [ "--set" "QT_LOGGING_RULES" "qt.qpa.wayland.textinput=false" ];
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;
@ -504,15 +635,19 @@ in
};
})
# student & teacher's userspace alias gcc = clang, g++ = clang++
# i know it looks crazy but sometimes we have to match someone's wrong expectations.
# Of course you can delete this shit if you want to
(pkgs.writeShellScriptBin "gcc" ''${pkgs.clang}/bin/clang "$@"'')
(pkgs.writeShellScriptBin "g++" ''${pkgs.clang}/bin/clang++ "$@"'')
# VS Code
(vscode-with-extensions.override {
vscodeExtensions =
with vscode-extensions;
[
ms-vscode.cpptools-extension-pack
ms-dotnettools.csharp
#ms-dotnettools.csharp
formulahendry.code-runner
tomoki1207.pdf
ms-vscode.hexeditor
@ -529,6 +664,7 @@ in
ms-vscode-remote.remote-ssh
timonwong.shellcheck
]
# QT, STM32, ARM, debug
++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
name = "vscode-cppcheck";
@ -560,12 +696,6 @@ in
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";
@ -590,19 +720,31 @@ in
version = "1.6.0";
sha256 = "sha256-nKK8HRzeqDixpdKmgacjhNzanJaTsAnYLC6nCbmWXuU=";
}
{
name = "qt-cpp-pack";
publisher = "TheQtCompany";
version = "1.0.2";
sha256 = "sha256-Kd2/kk3qJUOahz71Uh3mUI1wDuwS8/t84tgdWorRPG4";
}
];
})
# QT
qtcreator
qt6.full
qt6.qtbase
# debugging
gdb
isort black
# Python-related things
# доп.утилиты для Python
isort
black
# POSIX утилиты для совместимости
# POSIX утилиты для совместимости с предметами про POSIX
# POSIX utils to align POSIX-related university courses and subjects
om4
pax
mailutils
@ -618,15 +760,18 @@ in
];
};
# inserted USB sticks mounts automatically
# вставленные флешки автоматически монтируются
services.devmon.enable = true;
# POSIX at
# необходимо для совместимости с POSIX по команде at, при отсутствии необходимости можно удалить
services.atd = {
enable = true;
allowEveryone = true;
};
# each PC has its own mysql and postgresql
# на каждой машине свой сервер mysql и postgresql
services.mysql = {
enable = true;
@ -640,6 +785,7 @@ in
'';
};
# each mysql and psql support root without password for student
# и оба поддерживают вход без пароля в "руты"
system.userActivationScripts.mycnf = {
text = ''
@ -648,26 +794,29 @@ in
'';
deps = [ ];
};
environment = {
etc."gtk-3.0/settings.ini" = {
environment.variables = {
PGUSER = "postgres";
};
# whitesur icons
environment.etc."gtk-3.0/settings.ini" = {
text = ''
[Settings]
gtk-icon-theme-name = WhiteSur
'';
mode = "0644";
};
variables = {
PGUSER = "postgres";
};
};
# STM32CubeMX STM32F107VCT6 automatic on-login firmware setup
systemd.user.services.stm32cubemx-repo =
let
stm32f1-v180 = builtins.fetchTarball { url = "http://${serverIP}/STM32Cube.tar.gz"; sha256 = "sha256:1zlcp82xq16anx02ghiv9xa5bi2fsz78h945miqmi26bwcjxdagn"; };
stm32f1-v180 = builtins.fetchTarball {
url = "http://${serverIP}/STM32Cube.tar.gz";
sha256 = "sha256:1zlcp82xq16anx02ghiv9xa5bi2fsz78h945miqmi26bwcjxdagn";
};
in {
in
{
description = "STM32CubeMX firmware repository setup";
wantedBy = [ "default.target" ];
serviceConfig = {
@ -679,6 +828,8 @@ in
'';
};
};
# russian licensing service for Kompas-3D CAD
services.grdcontrol.enable = true;
imports = [
@ -706,8 +857,14 @@ in
};
};
# if it also has Windows partition, then it should allow
# choose OS for 30 sec
#
# otherwise, it should boot in 5 sec
# ----------
# если машина установлена на диск с Windows,
# то она позволяет "увидеть" и выбрать Windows в течение 30 с
#
# иначе - 5 c таймаута (для виртуалок)
boot.loader =
if hasBootPartition then
@ -741,12 +898,13 @@ in
};
time.hardwareClockInLocalTime = hasBootPartition;
# настройки Nix
# Nix settings
nixpkgs.config = {
allowUnfree = true;
nvidia.acceptLicense = true;
};
nix.settings = {
# Local cache is asked before global because most of packages are already built
# Локальный кэш идёт первым — большинство пакетов уже собраны на build-ноде
substituters = [
"http://nixos.builds.node"
@ -758,9 +916,15 @@ in
];
trusted-substituters = [ "http://nixos.builds.node" ];
auto-optimise-store = true;
# If build node is unavailiable then go to cache.nixos.org with no hanging
# Если build-нода временно недоступна — переходим к cache.nixos.org, не зависаем
connect-timeout = 5;
experimental-features = [ "nix-command" "flakes" ];
experimental-features = [
"nix-command"
"flakes"
];
# For 50 GiB partition use auto-GC if no space left
# На дисках 50 GiB автоматически запускать GC при нехватке места
min-free = 2147483648; # 2 GiB — порог запуска GC
max-free = 5368709120; # 5 GiB — цель освобождения
@ -768,17 +932,24 @@ in
nix.gc = {
automatic = true;
dates = "weekly";
randomizedDelaySec = "45min"; # машины не запускают GC одновременно
randomizedDelaySec = "45min"; # PCs don't launch GC at the same time
options = "--delete-older-than 14d";
};
# Периодический TRIM для SSD (безопасен и на HDD — просто no-op)
# periodic TRIM for SSD (safe for HDD)
# Периодический TRIM для SSD (безопасен на HDD)
services.fstrim.enable = true;
# nix-daemon starts after Yggdrasil does, otherwise nixos.builds.node will be unavailiable
# nix-daemon стартует только после Yggdrasil, иначе nixos.builds.node недостижим
systemd.services.nix-daemon = {
after = [ "yggdrasil.service" ];
wants = [ "yggdrasil.service" ];
};
# unique hostname based on 6 last MAC address digits
# networking.hostName = "nixos" leaves back as default fallback
#
# Уникальный hostname на основе последних 6 цифр MAC-адреса основного интерфейса.
# networking.hostName = "nixos" остаётся fallback-значением в /etc/hostname;
# сервис перекрывает его transient-именем при каждой загрузке.
@ -802,11 +973,14 @@ in
fi
'';
};
# Place location service
# Директория для хранения данных о физическом расположении компьютера
systemd.tmpfiles.rules = [
"d /var/lib/place 0755 student users -"
];
##### GRAPHICS & DE & DM SETTINGS ######
##### НАСТРОЙКИ ГРАФИКИ И РАБОЧЕГО СТОЛА ######
hardware.graphics = {
enable = true;
@ -844,12 +1018,23 @@ in
nvidiaSettings = false;
};
services.udev.packages = [ pkgs.stlink pkgs.openocd ];
services.udev.extraRules = if isAdata then ''
services.udev.packages = [
pkgs.stlink
pkgs.openocd
];
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" ];
''
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
@ -866,17 +1051,16 @@ in
services.getty.autologinUser = "student";
services.xserver.displayManager.lightdm.enable = true;
services.xserver.displayManager.startx.enable = true;
services.displayManager.defaultSession = "MIREA-WindowsLike+Metacity";
services.displayManager.defaultSession = "${university.shortName}-WindowsLike+Metacity";
services.xserver.displayManager.session = [
{
manage = "desktop";
name = "MIREA-WindowsLike";
# подробности настроек рабочего стола см. на github.com/gregorybednov/mireadesktop
name = "${university.shortName}-WindowsLike";
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} &
${desktop.tint2} &
${desktop.pcmanfm} &
${desktop.sxhkd} &
#${desktop.xcape} &
waitPID=$!
'';
}
@ -890,7 +1074,17 @@ in
}
];
##### NETWORKING SETTINGS #####
##### СЕТЕВЫЕ НАСТРОЙКИ #######
# Yggdrasil-маршрутизация позволяет целевым ПК автоматически получать статический IPv6 даже в сетях DHCP,
# что также запускается на установщике для максимальной гибкости.
# Благодаря Yggdrasil может быть доступно удаленнное управление и локальный кэш сборок
# Yggdrasil routing above network allows any target PC to get automatically static IPv6 even on DHCP,
# so installer is recommended to use Yggdrasil too for maximum scalability
# With Yggdrasil routing it's easy to connect remotely, and you can use
# nix build cache nodes with DHCP-addresses (e.g. other PCs)
services.yggdrasil = {
enable = true;
persistentKeys = true;
@ -899,16 +1093,31 @@ in
};
};
# each computer has internet connection
# каждый компьютер имеет выход в интернет
# our buildnode caught a bug on launching with networkmanager,
# so I had to disable it
#
# наша build-нода не работала с networkmanager, отключалась от сети,
# так что пришлось ее отключить
networking.networkmanager.enable = !config.services.harmonia.enable;
networking.hostName = "nixos";
networking.firewall.allowedTCPPorts = [ 22 ] ++ lib.optionals config.services.harmonia.enable [ 80 ];
networking.firewall.allowedTCPPorts = [
22
]
++ lib.optionals config.services.harmonia.enable [ 80 ];
# каждый компьютер знает, что kafpi.local - это адрес нашего сервера
networking.hosts."${serverIP}" = [ "kafpi.local" ];
# each computer knows where is ${serverAddress} (at ${serverIP}) - useful for self-signed HTTPS
# and where is nixos.builds.node (at ${buildNodeYggIP}) - userful for nix caching via harmonia server
#
# каждый компьютер знает, что ${serverAddress} - это адрес нашего сервера
# полезно для self-signed HTTPS
networking.hosts."${serverIP}" = [ serverAddress ];
networking.hosts."${buildNodeYggIP}" = [ "nixos.builds.node" ];
#### LOCALIZATION ####
# (if you're foreign you probably would like to change it)
#### ЛОКАЛИЗАЦИЯ #####
time.timeZone = "Europe/Moscow";
@ -918,6 +1127,12 @@ in
useXkbConfig = true;
};
# installed:
# - Microsoft corefonts
# - GOST Type A (for learning CADs and manufacturing documents)
# - basic freetype fonts
# - JetBrains Mono
#
# установлены шрифты Microsoft (corefonts),
# установлен ГОСТ Тип А (задел на будущее),
# установлены базовые свободные шрифты,
@ -929,6 +1144,7 @@ in
liberation_ttf
];
####### OTHER SETTINGS #######
####### ПРОЧИЕ НАСТРОЙКИ #######
environment.systemPackages = with pkgs; [
vim
@ -942,7 +1158,11 @@ in
# При запуске от root через SSH автоматически подключается к X-сессии student на :0
(pkgs.writeShellApplication {
name = "place";
runtimeInputs = [ yad coreutils util-linux ];
runtimeInputs = [
yad
coreutils
util-linux
];
text = ''
ROOM_ARG="''${1:-}"
PLACE_FILE="/var/lib/place/location"
@ -988,12 +1208,14 @@ in
})
];
# remote-control inside our local networking
# удаленный доступ в пределах нашей сети
services.openssh = {
enable = true;
settings.PermitRootLogin = "yes";
settings.PermitRootLogin = "yes"; # TODO
};
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" ];
users.users.root.openssh.authorizedKeys.keys = sshKeys; # TODO root
services.gnome.gnome-keyring.enable = true;
programs = {
@ -1014,9 +1236,13 @@ in
enable = true;
enableSSHSupport = true;
};
udevil.enable = true; # тоже нужно для флешек
# required for flash stick support
# требуется для поддержки флеш-накопителей
udevil.enable = true;
};
# DO NOT CHANGE THIS IF YOU'RE UPDATING OLD COMPUTERS
# НЕ МЕНЯТЬ, иначе придётся все компы переустанавливать, а не обновлять
system.stateVersion = "24.05";
}

View file

@ -1,5 +1,7 @@
{
description = "MIREA NixOS USB Installer";
description =
let university = import ../mirea-specific/university.nix;
in "${university.shortName} NixOS USB Installer";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";

View file

@ -1,11 +1,63 @@
{ pkgs, lib, config, ... }:
{
pkgs,
lib,
config,
...
}:
let
# static server IP address, it must be always online and serve as Yggdrasil peer
# (see config.services.ygggdrasil.settings.peers for details)
# WARN: the peer should NOT connect Yggdrasil worldwide network
# if your PC fleet shouldn't be globally accessible around the world
#
# статический IP адрес сервера, который должен быть всегда онлайн и служить пиром Yggdrasil
# (см. подробности config.services.ygggdrasil.settings.peers)
# ПРЕДУПРЕЖДЕНИЕ: этот пир не должен быть подключен к мировой сети Yggdrasil,
# если конечно вы не хотите чтобы весь компьютерный парк был доступен из любой точки мира
serverIP = "10.0.174.12";
# -------
# Yggdrasil address cache build node. It should use the same NixOS config as others
# It's NOT required to be the same server as ${serverIP} but it also should be always online
# It CAN be a NixOS VM installed on the same server ${serverIP} autostarted
#
# Yggdrasil-адрес кэширующего сервера. На нем должна быть установлена NixOS с той
# же конфигурацией, что и у остальных машин. Не обязательно, чтобы эта машина была той же,
# что сервер ${serverIP}, но она также должна быть онлайн.
# Это может быть виртуальная NixOS-машина, установленная на сервере ${serverIP} в режим автозапуска
buildNodeYggIP = "200:ccc6:1361:5c84:aba0:1244:35f5:c903";
# -------
# here is your configuration repo URL. fork it and change it on your own if you want
#
# здесь требуется указать ваш URL-адрес репозитория с конфигурацией. fork-аете, и меняете на свой
configRepoUrl = "https://forgejo.gregorbednov.ru/gregorbednov/configuration.nix.git";
# -------
# here is some university specifics, apps and resources
# e.g. for MIREA it's wallpaper, university logo, utils to show uuniversity schedule week number and so on
#
# LEGALS: I am NOT a creator on wallpaper.svg,
# I do NOT own wallpaper.svg, this doesn't represent any of my ideas or views,
# that's just a logo (a coat of arms to be precise) of a university,
# and it is in the public domain.
#
# здесь могут быть специфические вузовские данные и ресурсы,
# например, обои, логотип университета, утилита для показа номера недели по расписанию, и так далее
#
# ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ:
# Я не являюсь владельцем файла wallpaper.svg, его добавление не репрезентует моих идей или взглядов,
# это просто логотип (точнее герб) университета, и он является общественным достоянием.
university = import ../mirea-specific/university.nix;
in
{
isoImage.isoName = lib.mkForce "mirea-nixos-installer.iso";
isoImage.isoName = lib.mkForce university.isoName;
isoImage.squashfsCompression = "zstd -Xcompression-level 6";
services.getty.autologinUser = lib.mkForce "root";
@ -19,15 +71,22 @@ in
git
pv
curl
(writeShellScriptBin "mirea-install" (
(writeShellScriptBin university.installerBin (
builtins.replaceStrings
[ "@CONFIG_REPO_URL@" ]
[ configRepoUrl ]
[ "@CONFIG_REPO_URL@" "@DISTRO_TITLE@" ]
[ configRepoUrl university.shortName ]
(builtins.readFile ./mirea-install.sh)
))
];
# Yggdrasil запускается на установщике — благодаря ему доступен локальный кэш сборок
# Yggdrasil-маршрутизация позволяет целевым ПК автоматически получать статический IPv6 даже в сетях DHCP,
# что также запускается на установщике для максимальной гибкости.
# Благодаря Yggdrasil может быть доступно удаленнное управление и локальный кэш сборок
# Yggdrasil routing above network allows any target PC to get automatically static IPv6 even on DHCP,
# so installer is recommended to use Yggdrasil too for maximum scalability
# With Yggdrasil routing it's easy to connect remotely, and you can use
# nix build cache nodes with DHCP-addresses (e.g. other PCs)
services.yggdrasil = {
enable = true;
persistentKeys = false;
@ -49,7 +108,10 @@ in
];
trusted-substituters = [ "http://nixos.builds.node" ];
connect-timeout = 5;
experimental-features = [ "nix-command" "flakes" ];
experimental-features = [
"nix-command"
"flakes"
];
};
systemd.services.nix-daemon = {
@ -64,10 +126,13 @@ in
environment.etc."issue".text = ''
┌─────────────────────────────────────────┐
│ Установщик NixOS MIREA │
│ Запустите: mirea-install │
│ Установщик NixOS ${university.shortName}
│ Запустите: ${university.installerBin}
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ NixOS Installer ${university.shortName}
│ Run: ${university.installerBin}
└─────────────────────────────────────────┘
'';
system.stateVersion = "24.11";

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash
# MIREA NixOS Installer
# @DISTRO_TITLE@ NixOS Installer
# Устанавливает NixOS рядом с Windows или на чистый диск.
# NixOS root: 50 GiB, EFI (при чистой установке): 512 MiB.
# Идемпотентен: если установка прервалась, просто запустите повторно.
@ -331,9 +331,9 @@ else
info "noatime добавлен к ext4 разделам"
fi
step "Загрузка конфигурации MIREA"
step "Загрузка конфигурации @DISTRO_TITLE@"
if [[ -f "$MNT/etc/nixos/flake.nix" ]]; then
skip "конфигурация MIREA уже загружена"
skip "конфигурация @DISTRO_TITLE@ уже загружена"
else
tmpconf=$(mktemp -d)
git clone --depth=1 "$CONFIG_REPO_URL" "$tmpconf/config" \
@ -342,7 +342,7 @@ else
cp "$tmpconf/config/flake.lock" "$MNT/etc/nixos/"
cp "$tmpconf/config/configuration.nix" "$MNT/etc/nixos/"
rm -rf "$tmpconf"
info "Конфигурация MIREA установлена"
info "Конфигурация @DISTRO_TITLE@ установлена"
fi
# ── Установка ─────────────────────────────────────────────────────────────────

View file

@ -0,0 +1,19 @@
# Утилита расчёта номера учебной недели.
# Даты отсечки семестров (9 февраля / 1 сентября) специфичны для МИРЭА,
# поэтому пакет живёт здесь, а не в общем mireadesktop.
{ pkgs }:
pkgs.stdenv.mkDerivation rec {
pname = "mireaweek";
version = "0.1.0";
src = ./weekday.kt;
dontInstall = true;
dontUnpack = true;
nativeBuildInputs = [ pkgs.kotlin ];
buildPhase = ''
mkdir -p $out/{bin,lib}
kotlinc $src -include-runtime -d mireaweek.jar
mv mireaweek.jar $out/lib
printf "${pkgs.jre}/bin/java -jar $out/lib/mireaweek.jar" > $out/bin/mireaweek
chmod +x $out/bin/mireaweek
'';
}

View file

@ -0,0 +1,15 @@
# Виджет панели tint2, показывающий номер учебной недели МИРЭА.
# Подставляется в mireadesktop через параметр extraTint2Widgets.
{ mireaweek }:
''
#-------------------------------------
execp = new
execp_name = mireaweek
execp_command = ${mireaweek}/bin/mireaweek
execp_interval = 0
execp_font = mono 10
execp_font_color = #dddddd 100
execp_centered = 1
execp_has_icon = 0
execp_padding = 5 5
''

View file

@ -0,0 +1,27 @@
{
# University names
# May be written any language
#
# Название университета
# Может быть на любом языке
name = "МИРЭА — Российский технологический университет";
# short name should be in english
# короткое название должно быть на английском
shortName = "MIREA";
# NixOS installer branding
# Брендирование установщика NixOS
isoName = "mirea-nixos-installer.iso";
installerBin = "mirea-install";
# LEGALS: I am NOT a creator on wallpaper.svg,
# I do NOT own wallpaper.svg, this doesn't represent any of my ideas or views,
# that's just a logo (a coat of arms to be precise) of a university,
# and it is in the public domain.
#
# ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ:
# Я не являюсь владельцем файла wallpaper.svg, его добавление не репрезентует моих идей или взглядов,
# это просто логотип (точнее герб) университета, и он является общественным достоянием.
wallpaper = ./wallpaper.svg;
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 689 KiB

52
mirea-specific/weekday.kt Normal file
View file

@ -0,0 +1,52 @@
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.Month
enum class Period {
Autumn,
Winter,
Spring
}
fun determinePeriod(today: LocalDate): Period {
val februaryCutoff = LocalDate.of(today.year, Month.FEBRUARY, 9)
val septemberCutoff = LocalDate.of(today.year, Month.SEPTEMBER, 1)
return when {
today.isBefore(februaryCutoff) -> Period.Winter
today.isAfter(septemberCutoff.minusDays(1)) -> Period.Autumn
else -> Period.Spring
}
}
fun calculateWeek(period: Period, date: LocalDate): String {
return when {
period == Period.Winter -> "Хороших праздников, удачной сессии!"
date.dayOfWeek == DayOfWeek.SUNDAY -> "Сегодня воскресенье, лучше иди домой"
else -> {
val currentWeek = date.getWeekOfYear()
val periodLimit = when (period) {
Period.Spring -> LocalDate.of(date.year, Month.FEBRUARY, 9)
Period.Autumn -> LocalDate.of(date.year, Month.SEPTEMBER, 1)
else -> throw IllegalStateException("Unexpected period")
}
val limitWeek = periodLimit.getWeekOfYear()
val isLimitSunday = periodLimit.dayOfWeek == DayOfWeek.SUNDAY
val weekOffset = if (isLimitSunday) 1 else 0
val weekNumber = 1 + currentWeek - limitWeek - weekOffset
"$weekNumber неделя"
}
}
}
fun LocalDate.getWeekOfYear(): Int {
return this.get(java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR)
}
fun main() {
val today = LocalDate.now()
val period = determinePeriod(today)
val weekInfo = calculateWeek(period, today)
println(weekInfo)
}