Pull to refresh

Синхронизация системных настроек

Reading time5 min
Views5.2K

image
Как известно, большинство программ в мире 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 файл сразу добавится с нужным расширением.
А если файл уже содержит значение, которое есть в конфиге в секции datachezmoi 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.

Only registered users can participate in poll. Log in, please.
Как вы синхронизируете свои конфиги?
16.22% Использую один из dotfiles менеджеров6
18.92% Использую git репозиторий и синхронизирую вручную7
64.86% Не использую синхронизацию вообще24
37 users voted. 14 users abstained.
Tags:
Hubs:
+1
Comments15

Articles

Change theme settings