[О блоге]
[наверх]
[пред]
[2025-08-13 23:37:32+03:00]
[9b00c0724455d355f89bbee14ead8a0525b8b173]
Темы: [tcl]
Damn small configuration
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
[оставить комментарий]