Используем rcm для деплоя конфигурации в любую папку

    И снова, здравствуйте. Неделю (эта статья о-очень долго мариновалась в бэклоге) Какое-то время назад я рассказал, как использовать 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

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое