
Как известно, большинство программ в мире Linux и частично в MacOS используют текстовые файлы для конфигурации.
Иногда случается необходимость в переносе своих настроек на новую систему. Также очень важно иметь одинаковое окружение дома и на работе.
Особенно важно это тем людям, которые как и я любят перенастраивать свое рабочее окружение.
Очень долгое время у меня был git репозиторий, синхронизированный с Github, Gitlab и Bitbucket.
Для некоторых конфигов я вручную делал симлинки, для других использовал vimdiff/meld для визуального сравнения файлов и переноса общих настроек.
Например я добавил настройку в свой .vimrc на домашнем компьютере. Запустил meld ~/.vimrc <git path>/.vimrc, просмотрел изменения, синхронизировал их и запушил в репозиторий.
Потом на работе уже нужно было скачать изменения и запустить такую же команду, чтобы синхронизировать изменения на рабочем компе.
Сценарий далек от идеального и на это уходит много времени. А еще так не синхронизируешь какие-то секретные данные, типа ssh ключей.
Я знаю, что можно шифровать данные в репозитории, но так как они публичные, я предпочитаю использовать флешку, на которой так же хранится моя keepassxc база паролей.
Совсем недавно в ютубе я наткнулся на видео про использование GNU Stow для синхронизации дотфайлов и понял, что не только меня беспокоит эта ситуация и кто-то уже инвестировал свое время в ее решение. Как только вопрос сформулировался, как сразу нашелся на него ответ в виде отличной статьи на Archwiki. Так как у меня много файлов, которые немного отличаются на разных машинах, то все программы, не умеющие в шаблоны сразу отпали. Мой выбор пал на chezmoi, так как он написан на go и можно напрямую скачать один бинарник с Github курлом, если нужно перенести свои настройки на новую машину. Так же решается проблема синхронизации секретных данных интеграцией с разными менеджерами паролей(1Password, Bitwarden, gopass, KeePassXC, LastPass, pass, Vault, Keychain, Keyring) или шифрованием данных с помощью GnuPG/age.
Я не буду прямо переводить документацию, кто захочет прочитает сам, она хорошо структурирована.
Просто приведу пару собственных примеров, чтобы оценить всю мощь данной программы.
Собственный конфиг
chezmoi как и любая другая программа в мире Linux имеет собственный конфиг, который должен быть по пути $XDG_CONFIG_HOME/chezmoi/config.toml.
Сам конфиг может быть 3 форматов — Toml, Yaml или Json. Для себя я выбрал Toml.
Можно хранить конфиг на каждой машине отдельно, но я предпочитаю синхронизировать его вместе с другими файлами. Поэтому я использую специальный файл .chezmoi.toml.tmpl в корне репозитория. Все файлы с расширением *.tmpl интерпретируются как шаблоны на языке go(также доступны все дополнительные функции шаблонизатора sprig). Вот мой шаблон конфига
{{- $type := "personal" -}} {{- $kps_key := "" -}} {{- $personal_ip := "" -}} {{- if ne .chezmoi.hostname "personal" -}} {{- $type = "work" -}} {{- end -}} {{- if (hasKey . "kps_key") -}} {{- $kps_key = .kps_key -}} {{- else -}} {{- $kps_key = promptString "kps_key" -}} {{- end -}} {{- if (hasKey . "personal_ip") -}} {{- $personal_ip = .personal_ip -}} {{- else -}} {{- $personal_ip = promptString "personal_ip" -}} {{- end -}} [data] type = {{ $type | quote }} kps_key = {{ $kps_key | quote }} personal_ip = {{ $personal_ip | quote }} {{ if eq .chezmoi.hostname "personal" -}} bluetooth_mac = "<mac>" cpu_format = "{utilization} {frequency}" eth_id = "<personal eth>" wifi_id = "<personal wifi>" {{- else }} cpu_format = "{barchart} {utilization} {frequency}" eth_id = "<work eth>" wifi_id = "<work wifi>" {{- end }} color = "on" format = "toml" mode = "file" pager = "bat" [diff] command = "meld" [git] autoAdd = true [keepassxc] database = "<path to db>.kdbx" args = ["-k", "{{ .kps_key }}" ]
В конфиге есть общие настройки, типа color или format, а есть секция data.
В данной секции объявляется список ключей=значений, которые потом можно использовать в шаблонах. Пример использования — {{ .kps_key }}
Для общих данных есть файл .chezmoidata.<format>.
Создание конфига происходит командой chezmoi init
После этого можно добавлять файлы, которые будут синхронизироваться командой chezmoi add <path>
Чтобы посмотреть разницу между репозиторием и текущим состоянием системы есть команда chezmoi diff
Если вы вручную отредактировали файл, можно смержить командой chezmoi merge <path> или chezmoi merge-all.
Чтобы применить изменения — chezmoi apply.
Отдельно стоит выделить создание шаблонов.
Можно просто руками переименовать файл, добавив в конце суффикс .tmpl, но для этого лучше использовать специальные флаги при добавлении файлов.
При использовании флага --template файл сразу добавится с нужным расширением.
А если файл уже содержит значение, которое есть в конфиге в секции data — chezmoi add --autotemplate <path> автоматически подставит нужный ключ, как переменную в созданный шаблон.
Кстати, все файлы, которые добавляются в репозиторий, вместо точки в начале имени файла используют префикс dot_.
Например команда chezmoi add ~/.bashrc создаст файл с именем dot_bashrc.
Скрипты
Шаблоны — это хорошо, но они не могут заменить все возможные сценарии, поэтому данная программа может запускать любые скрипты, если их правильно оформить.
Например вам надо создать какую-то директорию, на которую потом будет ссылка в .bashrc
Надо создать скрипт с префиксом before_dot_basrc, например before_dot_bashrc_run.sh
#!/usr/bin/env bash mkdir -p $HOME/.local/share/bash/functions
Не забываем про шебанг и соответствующие исполнительные привилегии. Скрипт может быть любой, на баш, на питоне, бинарник на го/раст и тд.
Есть разные другие полезные префиксы и для скриптов и для файлов
Например, вот как я создаю ssh ключ для github на новой машине
Файл private_dot_ssh/private_dot_ssh/create_private_github.tmpl с контентом
{{ keepassxcAttribute "/dotfiles/ssh/github" "private" }}
Префикс create_ создает файл, если его нету, private_ добавляет маску чтения файла владельцем.
Еще примеры
Я использую шаблоны чтобы создавать уникальные конфиги для каждой системы.
Например в моем .zshrc раньше были такие проверки
if [ -f $ZDOTDIR/aliases.local.zsh ]; then . $ZDOTDIR/aliases.local.zsh fi
Сейчас я их заменил таким шаблоном
{{ if stat (expandenv "$ZDOTDIR/aliases.local.zsh") }} . $ZDOTDIR/aliases.local.zsh {{ end }}
Также можно проверять на наличие исполнительного файла в $PATH
{{- if (or (lookPath "cargo") (stat (expandenv "$HOME/.rustup"))) }} alias crn='cargo run' alias cup='cargo update' alias cbd='cargo build' alias cbr='cargo build --release' setup_cargo () { rustup completions zsh cargo > $LOCAL_ZSH_COMP_DIR/_cargo rustup completions zsh rustup > $LOCAL_ZSH_COMP_DIR/_rustup } setup_cargo_tools() { if ! command_exists cargo-expand; then cargo install cargo-expand fi if ! command_exists cargo-audit; then cargo install cargo-audit fi if ! command_exists cargo-outdated; then cargo install cargo-outdated fi } {{- end }}
Заключение
Мой сценарий синхронизации конфиг-файлов сильно упростился. Также надеюсь, что эта статья кому-то поможет упростить их сценарии.
P.S. Так же посматриваю на различные системы установки необходимых пакетов, при переустановке системы. Пока в планах затестить Comtrya, как ориентированную на локалхост альтернативу Ansible.
ссылка на оригинал статьи https://habr.com/ru/articles/585578/
Добавить комментарий