FreeBSD virtual environment management and repository

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 ;-) )