2020-10 upd: we reached the first fundraising goal and rented a server in Hetzner for development! Thank you for donating !
О cbsd shell и SQLite3
99% кода CBSD написана на sh по следующим причинам:
- скрипты в основном повторяют ввод команд системного администратора в консоли, то есть работают с внешними утилитами, такими как: zfs, zpool, sudo, pkg, rsync, соответственно, необходимость применять языки программирования по большей части отсутствует. Часть узких мест, а также некоторый функционал (logtail, репликация, демон следящий за нодами и тп) написаны на C (в планах переписывать узкие места на Си и дальше).
- размер sh интерпретатора немногим больше 100 Кбайт, в отличие от bash или perl/python, что обеспечивает менее накладный bootstrap скрипта
- CBSD ориентирована в первую очередь на системных инженеров, которые могут не знать какой-либо язык из Perl, Python, Lua, C, Go и т.п, но shell-скриптинг является той базой знаний в среде Unix, которую знают все (или должны знать ;-)
- От языка не требуется выполнять много парсинга и математики, в основном он работает с внешними утилитами или API
Тем не менее, огромное количество ограничений sh (в основном при работе со строчками) делает написание сценариев делом непростым, ввиду этого, в cbsd идет форк /bin/sh в котором добавлен (и будет добавлятся) дополнительный функционал, который будет описываться в этом документе
Таким образом, если вы хотите изменить/дописать CBSD или ее модули, вам хватит привычных знаний по sh и нескольких расширяющих команд.
cbsdsh
cbsdsh - это модифицированная версия /bin/sh и в данный момент она имеет следующие отличия от /bin/sh:
- - Добавлена функция cbsd_pwait. Отличия от pwait(1) в том, что она позволяет указать таймаут на ожидание конца процесса. Используется, к примеру, для обеспечения параллельного запуска клеток, когда следующая клетка может начать запускаться или останавливаться параллельно не дожидаясь предыдущей клетки, которая, возможно - зависла (ошибка в rc-скрипте, неубиваемый процесс и тд)
- - Добавлена функция cbsd_fwatch для слежения за модификациями файлов. Например, используется для слежки за модификациями SQLite3 баз в taskd-демоне
- - Добавлена функция strlen для определения длины строки
- - Добавлена функция is_number для определения число ли это.
- - Добавлена функция strpos для откусывания произвльного количества символов из строчки
- - cbsdsh слинкован с SQLite3 для того, чтобы с базами SQL можно было работать inline в шелле и соотв, сценариях:
cbsd@home> pwd /tmp cbsd@home> uname -r 11.0-CURRENT cbsd@home> cbsdsql local SELECT dsk_controller,dsk_path,dsk_slot FROM bhyvedsk WHERE jname=\"debian1\" ahci-hd|dsk1.vhd|0 cbsd@home>
- - Добавлена функция cbsdsql как build-in функция шелла для запросов в SQL, в качестве второго аргумента идет база, все что дальше - сам SQL запрос. В качестве имени базы выступает непосредственно имя файла в $workdir/var/db/, при этом путь и расширение файла .sqlite писать не нужно. Например, если вы хотите получить список клеток с удаленной ноды node2, информация которой находится в SQLite файле /usr/jails/var/db/node2.sqlite и содержимое которой (в новых версиях CBSD) реплицируется с источника, в шелле вы можете написать так:
... cbsdsql node2 SELECT jname FROM jails
или назначить результат SQL команды shell-переменной, после чего разобрав его на выбранные переменные:
_res=$( cbsdsh local SELECT ip4_addr,jname,status FROM jails ) sqllist ${_res} ip4_addr jname status echo "Jail name: ${jname}; IPs: ${ip4_addr}; Jail status: ${status}
Если вы находитесь в cbsdsh, то перед CBSD командами не требуется вводить префикс cbsd:
CBSD в работе использует язык SQL и SQLite3 для работы с параметрами jail по следующим причинам:
- Хранить и тем более работать с таким количеством параметров в обычных ascii-файлах очень тяжело
- SQLite3 реплицируется не целым файлом, а лишь SQL инструкцией. Кроме этого, SQLite3 вместо MySQL/PgSQL/прочих позволяет добиться децентрализованности в данных, не завися от одной точки сбоя.
- SQLite3 не требует запущенного демона и крайне портабельна
- Многие утилиты ОС по независящим от нас причинам могут менять свой метод хранения. К примеру, до версии FreeBSD 10, jail конфигурировался через командную строчку, начиная с версии 10, оригинальные клетки обзавелись своими конфиг-файлами в формате YAML. Чтобы не страдать от таких изменений и переписывать все скрипты, работа с этими конфигами выведена в одну процедуру, остальные же подсистемы работают со своим "неизменчивым" API. Кроме этого, SQL базы является "универсальным" storage из которого легко можно формировать любые другие noSQL/xml/yaml данные
- Вместо SQLite3 можно легко слинковать с внешней базой данных MySQL, PgSQL, которая будет выступать центральным "реестром" для всей фермы, при этом скрипты переписывать не нужно. Также, репликация данных с нод на ноду не нужна, поскольку все ноды обновляют и читают центральный реестр.
- Каждая нода на запись работает только со своим собственным SQLite3 файлом (символический линк $workdir/var/db/local.sqlite), все файлы удаленных нод находятся в том же каталоге но под своими именами, поэтому локальная работа ноды не зависит от состояния информации с удаленной ноды.
Модули и команды, которые мало работают с внешними утилитами, но много со строчками и математикой (хелперы CBSD для некоторых сервисов в их числе), удобно писать на LUA (которая пока не встроена в cbsdsh ;-) )