From 9b00c0724455d355f89bbee14ead8a0525b8b173 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Wed, 13 Aug 2025 23:37:32 +0300 Subject: [PATCH] Damn small configuration MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit http://www.git.cypherpunks.su/?p=dsc.git;a=blob;f=dsc Не нашёл решений типа OpenWrt-шного UCI. Его самого брать не очень охота: CMake, зависимость от их DBus-like библиотеки. Бе. А вот централизованный конфиг не прочь иметь. Менее чем в 300 строк Tcl написал свой аналог. Пока не покрыто тестами, возможно перед коммитом что-то поломал, но вроде базовый желаемый функционал обеспечивает. Вместо текстового файла, всё хранится в иерархии директорий и файлов. Значение переменной конфигурации: один текстовый файл. Всякие подобия списков, где динамические элементы: директории внутри других директорий. Иерархией директорией описываются и доступные настройки, а в отдельных файлах и их названия и описаниями. Рядом же лежат и валидаторы введённых данных, которые и значения по умолчанию могут показать. Некоторые примеры: -- net/*/title -- Network interface name -- net/*/addr/*/descr -- No CIDR notation, just a pure address. Set prefix length through net/*/addr/*/prefixlen. -- net/*/addr/*/check -- #!/usr/bin/env tclsh8.6 set addr [read -nonewline stdin] package require ip set version [::ip::version $addr] if {$version == -1} { puts "invalid format" exit 1 } if {[::ip::mask $addr] != ""} { puts "prefixlen must be empty" exit 1 } if {$version == 4} { set addr [::ip::normalize $addr] } else { set addr [::ip::contract $addr] } puts $addr -- net/*/mtu/title -- Maximum transmission unit -- net/*/mtu/descr -- If not set, then defaults to 1500. -- net/*/mtu/check -- #!/usr/bin/env tclsh8.6 set i [read -nonewline stdin] if {$i == ""} { set i 1500 } if {! [string is integer -strict $i]} { puts "invalid integer" exit 1 } if {$i <= 0 || $i > 65535} { puts "not in (0..65536) range" exit 1 } puts $i -- sys/hostname/check -- #!/usr/bin/env tclsh8.6 set n [read -nonewline stdin] if {$n == ""} { set n unknown } if {! [regexp {^[a-z0-9]+$} $n]} { puts {does not match ^[a-z0-9]+$} exit 1 } puts $n Ну и интерактивное использование предполагается аналогично UCI. Возможно экспортировать всю конфигурацию в виде txtar архива (337b234db58b3893f11deac7b140240b16ba1d5d). С особым .dirs файлом, в котором список директорий содержится (ведь в них могут отсутствовать файлы). Список изменений: просто вызов diff. Откат изменений: просто удаление части директорий/файлов и копирование из предыдущей версии. % ./dsc list net/* Network interface name net/*/addr/* Network address net/*/addr/*/prefixlen Prefix length net/*/mtu Maximum transmission unit sys/hostname Hostname sys/note Arbitrary note ui/password WebUI's admin password % ./dsc list -v net/* Network interface name net/*/addr/* Network address No CIDR notation, just a pure address. Set prefix length through net/*/addr/*/prefixlen. net/*/addr/*/prefixlen Prefix length If not set, then defaults to /64 (or /24 for IPv4). net/*/mtu Maximum transmission unit If not set, then defaults to 1500. sys/hostname Hostname sys/note Arbitrary note ui/password WebUI's admin password Password for the admin user accessing WebUI. % ./dsc set sys/hostname "что-то невалидное" does not match ^[a-z0-9]+$ % ./dsc set sys/hostname validhostname % ./dsc get sys/hostname validhostname % ./dsc get ui/password admin # это значение по умолчанию % ./dsc set ui/password secure-pass % ./dsc add net/eth0 net/eth0 % ./dsc get net/eth0/mtu 1500 # это значение по умолчанию % ./dsc add net/eth0/addr/2001:db8::невалидный invalid format % ./dsc add net/eth0/addr/2001:db8::1234 net/eth0/addr/2001:db8::1234 % ./dsc add net/eth0/addr/2001:db8::2345 net/eth0/addr/2001:db8::2345 % ./dsc get net/eth0/addr/* 2001:db8::1234 2001:db8::2345 % ./dsc get net/eth0/addr/2001:db8::1234/prefixlen 64 % ./dsc set net/eth0/addr/2001:db8::1234/prefixlen 48 % ./dsc set sys/note "длинная заметка" % ./dsc diff --- dirs +++ /tmp//tcl_bdyKPA 2025-08-12 18:37:44.875730000 +0300 @@ -0,0 +1,7 @@ +net +net/eth0 +net/eth0/addr +net/eth0/addr/2001:db8::1234 +net/eth0/addr/2001:db8::2345 +sys +ui diff -urN committed/net/eth0/addr/2001:db8::1234/prefixlen current/net/eth0/addr/2001:db8::1234/prefixlen --- committed/net/eth0/addr/2001:db8::1234/prefixlen 1970-01-01 03:00:00.000000000 +0300 +++ current/net/eth0/addr/2001:db8::1234/prefixlen 2025-08-12 18:36:43.439407000 +0300 @@ -0,0 +1 @@ +48 diff -urN committed/sys/hostname current/sys/hostname --- committed/sys/hostname 1970-01-01 03:00:00.000000000 +0300 +++ current/sys/hostname 2025-08-12 18:36:25.889303000 +0300 @@ -0,0 +1 @@ +validhostname diff -urN committed/sys/note current/sys/note --- committed/sys/note 1970-01-01 03:00:00.000000000 +0300 +++ current/sys/note 2025-08-12 18:37:24.284574000 +0300 @@ -0,0 +1,2 @@ +длинная +заметка diff -urN committed/ui/password current/ui/password --- committed/ui/password 1970-01-01 03:00:00.000000000 +0300 +++ current/ui/password 2025-08-12 18:35:57.006567000 +0300 @@ -0,0 +1 @@ +secure-pass % ./dsc commit % ./dsc export -- .dirs -- net net/eth0 net/eth0/addr net/eth0/addr/2001:db8::1234 net/eth0/addr/2001:db8::2345 sys ui -- net/eth0/addr/2001:db8::1234/prefixlen -- 48 -- sys/hostname -- validhostname -- sys/note -- длинная заметка -- ui/password -- secure-pass % ./dsc set net/eth0/addr/2001:db8::1234/prefixlen "" # сбросить значение % ./dsc diff diff -urN committed/net/eth0/addr/2001:db8::1234/prefixlen current/net/eth0/addr/2001:db8::1234/prefixlen --- committed/net/eth0/addr/2001:db8::1234/prefixlen 2025-08-12 18:36:43.000000000 +0300 +++ current/net/eth0/addr/2001:db8::1234/prefixlen 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -48 % % ./dsc revert net/eth0/addr/2001:db8::1234/prefixlen % ./dsc del net/eth0/addr/2001:db8::2345 % ./dsc del sys/note % ./dsc commit % ./dsc export -- .dirs -- net net/eth0 net/eth0/addr net/eth0/addr/2001:db8::1234 sys ui -- net/eth0/addr/2001:db8::1234/prefixlen -- 48 -- sys/hostname -- validhostname -- ui/password -- secure-pass -- 2.51.0