[О блоге] [наверх] [пред] [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

    [оставить комментарий]