И снова, здравствуйте. Неделю (эта статья о-очень долго мариновалась в бэклоге) Какое-то время назад я рассказал, как использовать rcm для обычного управления конфигурацией. У нас в компании есть модуль puppet, распространяющий персональные настройки пользователя по всем хостам, на которые у него есть доступ. Соответственно, хочется следующего:
- Иметь собственные настройки для всего, чем я пользуюсь (vim, zsh, git, etc..)
- Обновлять их по мере обновления в репозитории dotfiles
- Всё это — без лишних телодвижений
Инструменты
Всё, что нужно, уже используется мною, а именно:
Формат, используемый для деплоя файлов на хосты
Здесь ничего хитрого нету: мы деплоим tar-ball'ы, распаковывая их содержимое на хостах. Управляются только файлы и директории из конкретного списка, полностью перетираясь при каждом деплое по крону. Соответственно, если изменился тарболл, то перетирается всё в $HOME
по списку. Если нет — содержимое $HOME остаётся без изменений. За (пере)упаковку папки с исходниками персональных файлов отвечает отдельный скрипт, он выглядит достаточно тривиально:
#!/bin/bash -e
# Repack each personal directory into a tarball, use gtar on mac/*BSD and tar on linux
TAR=$(command -v gtar tar | head -1)
cd "$(dirname "$0")"
for file in *; do
if [ -d "${file}" ]; then
printf '\033[0;32mArchiving of \033[1;33m%s\033[0m\n' "$file"
# to avoid differences in an archive because of different mtime
# hard coded 2003-01-01 CET
XZ_OPT=-e9 $TAR --mtime="@1041375600" -cJf "${file}.tar.xz" "${file}"
fi
done
Как создать новый tar-ball по коммиту
Деплоим dotfiles не в $HOME
Раз уж у меня уже есть инструмент, которым я деплою конфиги на различные хосты, то, очевидно, использовать я буду его же. Надо просто кое-что подправить и заставить rcm
копировать файлы туда, куда мне надо. Однако rcm всегда устанавливает дот-файлы в $HOME, аргументов командной строки для изменения этого поведения нет.
После некоторых экспериментов и ковыряния в исходниках, я понял, что можно изменить непосредственно $HOME, тогда поведение утилит всех команд rcm поменяется следующим образом: каждая из утилит lsrc, mkrc, rcdn, rsup
будет считывать ${HOME}/.rcrc
и использовать ${HOME}/.dotfiles
по умолчанию. Соответственно, достаточно создать тот самый ${HOME}/.rcrc
со всеми необходимыми параметрами.
Проще всего сделать "болванку" домашней папки и заполнять её с нуля при каждом коммите. Пример того, как она выглядит можно увидеть в репозитории. Эта папка игнорируется на всех хостах без тега personal, соответственно, не помешает основной конфигурации. Один единственный файл .rcrc содержит все параметры для логики копирования файлов, сделаю только некоторые ремарки:
- Без
$SYMLINK_DIRS
rcup
отрабатывает безнадёжно долго, создавая полный список файлов, которые надо копировать. При наличии данного параметра совместно с$COPY_ALWAYS
утилита просто копирует всю папку какcp -r
без лишней мороки - Очевидно, что многое не нужно на удалённых серверах, всё это перечислено в
$EXCLUDES
(за исключением плагинов vim, их приходится удалять в хуке, потому что используется$SYMLINK_DIRS
) - Так как
${HOME}/.dotfiles
перестаёт работать по очевидным причинам, необходимо также переопределить$DOTFILES_DIRS
Вот и всё. Теперь можно скопировать папку tag-personal куда угодно, переопределить на время ${HOME}
и выполнить rcup
WORK_DIR="${HOME}/.dotfiles/tag-personal"
_OLD_HOME=$HOME
HOME="${HOME}/some/long/custom/path"
cp -r "${WORK_DIR}" "${HOME}"
rcup -v
HOME=$_OLD_HOME
Здорово! Но хочется чего-то ещё…
Автоматизируем "деплоймент" конфигов в кастомный $HOME
Сделать это "что-то" просто, git в этом месте поможет своими хуками. Имеется исполняемый файл .git/hooks/post-commit
следующего содержания:
#!/bin/sh
set -e
WORK_DIR="tag-personal"
HOME="${HOME}/some/long/custom/path/final_directory/USERNAME"
# Some unnecessary and very heavy plugins
EXCLUDED_VIM_PLUGINS='YouCompleteMe vimtex'
rm -rf "${HOME}"
cp -r "${WORK_DIR}" "${HOME}"
rcdn -v
rcup -v
for plugin in ${EXCLUDED_VIM_PLUGINS}; do
rm -rf "${HOME}/.vim/plugged/${plugin}"
done
# cleanup for .git dirs, compiled py and pictures
find "${HOME}" \( \
\( -type d -iname '.git' \) -o \
\( -type f \
\( -iname '*.pyc' -o -iname '*.gif' -o -iname '*.png' \) \
\) \
\) -exec rm -rf {} +
# final repack for files
"${HOME}/../repack.sh"
Теперь после каждого коммита в репозиторий с дот-файлами будет запускаться этот скрипт.
Всё, после этого остаётся сделать коммит+пуш в репозитории с персональными данными и дождаться, пока магия автоматизации довезёт мои конфиги до рабочих хостов.
Зачем всё так усложнять?
Дело в том, что пока в компании не было инструментов для деплоя персональной конфигурации на хосты, не было необходимости и в подобном обвесе. Но как только появлется возможность, аппетит растёт моментально. Кое кто из моих коллег остался доволен и тем, что привёз на хосты три файлика, допустим, .vimrc .bashrc .gitconfig
. Однако у меня уже довольно долго любовно точился, подправлялся и подвергался полировке целый набор различных инструментов. Одна только папка ~/.vim
после установки всех плагинов весит 427MB (да, 218 из них это YCM, и его я на серверы не тащу, а после чистки и упаковки это всё худеет до 3MB).
Наверное, кому-то покажется, что это уж как-то слишком и можно было бы и руками. Пожалуй, не все с этим согласятся.
Надеюсь, что у кого-то ещё есть почти физическая потребность чувствовать себя на рабочих станциях комфортно, почти как дома, и ему позволяет это инструментарий. Пользуйтесь на здоровье и да пребудет с нами автоматизация!