И снова, здравствуйте. Неделю (эта статья о-очень долго мариновалась в бэклоге) Какое-то время назад я рассказал, как использовать rcm для обычного управления конфигурацией. У нас в компании есть модуль puppet, распространяющий персональные настройки пользователя по всем хостам, на которые у него есть доступ. Соответственно, хочется следующего:


  • Иметь собственные настройки для всего, чем я пользуюсь (vim, zsh, git, etc..)
  • Обновлять их по мере обновления в репозитории dotfiles
  • Всё это — без лишних телодвижений

Инструменты


Всё, что нужно, уже используется мною, а именно:


  • rcm
  • git
  • tar

Формат, используемый для деплоя файлов на хосты


Здесь ничего хитрого нету: мы деплоим 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).


Наверное, кому-то покажется, что это уж как-то слишком и можно было бы и руками. Пожалуй, не все с этим согласятся.


Надеюсь, что у кого-то ещё есть почти физическая потребность чувствовать себя на рабочих станциях комфортно, почти как дома, и ему позволяет это инструментарий. Пользуйтесь на здоровье и да пребудет с нами автоматизация!

Комментарии (0)