Автоматизируем настройку macOS с помощью Ansible
В какой-то момент мой мак "зарос" всяким мусором и я решил - пришло время чистой установки ОС с наведением порядка. Сделать я это задумал с помощью инструментов автоматизации - Ansible плейбуков и вспомогательных скриптов. Вдохновила меня на это коллекция из Ansible Galaxy от Джефа Гирлинга. Правда её использование мне показалось избыточной затеей, поэтому я решил сделать свой вариант (Да-да, разбираться в чужих огромных плейбуках никому не хочется).
Что будем делать
Мне хочется затронуть основные вопросы конфигурации macOS, поэтому попробуем решить следующие задачи:
- Установим пару приложений
- Раскатаем дотфайлы
- Поменяем системные параметры и параметры пользовательского окружения
Думаю этого хватит, чтобы понять суть и потом допилить решение под себя. Погнали.
Подготовительный этап
Если мак не только что достали из коробки, а уже давно используют в качестве рабочей лошади, конечно же сначала надо сделать бэкап данных и только потом заниматься экспериментами, поэтому:
- Делаем бэкап системы, файлов, фотографий, документов, паролей, ключей и т.п.
- Убеждаемся, что есть доступ к своей учётной записи Apple ID
- Убеждаемся, что есть доступ к бэкапу и всем учётным записям, которые потребуются для его восстановления (если бэкап делался в облако или на файловый сервер)
- Начисто переустанавливаем macOS.
И теперь, когда в руках оказался чистый мак со свежей ОС, можно начинать развлекаться.
Волшебный репозиторий
Сперва - вот мой репозиторий для настройки своего Мака. Можно скачать его к себе и посмотреть содержимое.
Если коротко, то скрипт run.sh
сначала устанавливает Xcode Command Line tools и Ansible, а потом запускает плейбук с дальнейшей конфигурацией системы.
Установка приложений
К счастью в моём арсенале практически все приложения можно установить с помощью HomeBrew (пакетного менеджера, которого так не хватало в macOS), поэтому особых танцев с бубном тут нет.
- name: Check if Homebrew is Installed ansible.builtin.command: brew -v register: homebrew - name: Download HomeBrew Installation Script ansible.builtin.get_url: url: https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh dest: /tmp/brew-install.sh mode: '0755' when: homebrew.rc != 0 - name: Install HomeBrew ansible.builtin.script: /tmp/brew-install.sh when: homebrew.rc != 0 - name: Delete HomeBrew Installation Script ansible.builtin.file: path: /tmp/brew-install.sh state: absent when: homebrew.rc != 0
Теперь можно установить какое-нибудь приложение. Я поставлю сразу несколько:
- name: Install Formulas community.general.homebrew: name: - ranger - tmux state: present - name: Install Casks community.general.homebrew_cask: name: - iterm2 - visual-studio-code state: present
Следует заметить, что для homebrew написано несколько модулей ansible. Для консольных приложений (formula) используется модуль homebrew, для графических (cask) - homebrew_cask.
Однако несколько пакетов придётся установить и из Mac App Store. Для этого придётся воспользоваться утилитой mas. С её помощью мы можем найти интересующий нас пакет и узнать его ID, после чего установить.
Раскатка дотфайлов
После установки приложений можно заняться деплоем их конфигураций. Для примера я включу превью изображений в ranger, установлю Oh My Zsh и подключу к нему тему powerlevel10k.
ranger
С дотфайлами есть несколько подходов - можно подготовить файл и просто скопировать его, а можно менять или добавлять строки в исходной конфигурации. Поскольку для включения изображений нужно включить всего две опции, можно воспользоваться вторым способом
- name: Ranger - enable image preview ansible.builtin.lineinfile: path: ~/.config/ranger/rc.conf regexp: "{{ item.regexp }}" line: "{{ item.line }}" loop: - { regexp: '^set\ preview_images', line: 'set preview_images true' } - { regexp: '^set\ preview_images_method', line: 'set preview_images_method iterm2' }
Теперь можно запустить Ranger и проверить работоспособность
zsh
С установкой Oh My Zsh проблем быть не должно - Фреймворк ставится так же, как и homebrew - скачивается установочный скрипт, запускается и удаляется. А вот с применением темы Powerlevel10k уже интереснее. Если файла конфига нет, то придётся выполнить первые два шага, после чего запустить терминал, ответить на вопросы визарда Powerlevel10k - он всё сделает сам, останется лишь забрать себе сгенерированный конфиг.
- name: Powerlevel10k - get source code ansible.builtin.git: repo: https://github.com/romkatv/powerlevel10k.git dest: ~/.powerlevel10k update: yes - name: Powerlevel10k - update .zshrc ansible.builtin.lineinfile: path: ~/.zshrc regexp: '^source ~\/.powerlevel10k' line: source ~/.powerlevel10k/powerlevel10k.zsh-theme - name: Powerlevel10k - copy config ansible.builtin.copy: src: zsh/.p10k.zsh dest: ~/.p10k.zsh mode: '0644' - name: Powerlevel10k - Update .zshrc ansible.builtin.blockinfile: path: ~/.zshrc block: | if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" fi insertbefore: BOF marker_begin: "BEGIN Enable Powerlevel10k instant prompt" marker_end: "END Powerlevel10k instant prompt" backup: yes create: yes - name: Powerlevel10k - Update .zshrc ansible.builtin.blockinfile: path: ~/.zshrc_test block: | [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh insertafter: EOF marker_begin: "BEGIN Powerlevel10k config" marker_end: "END Powerlevel10k config" backup: yes
Изменение параметров системы
Основной инструмент для управления системой из командной строки - утилита defaults
. С её помощью можно прочитать или установить параметры практически для всего, что можно щёлкнуть мышью в графическом интерфейсе. Это могут быть как настройки ОС, так и установленных приложений.
Например, я хочу использовать клавишу Caps Lock для переключения раскладки клавиатуры. За это отвечает параметр TISRomanSwitchState
и я могу его поменять следующей командой:
defaults write -g TISRomanSwitchState 1
К счастью в Ansible есть готовый модуль osx_defaults, позволяющий описывать конфигурацию привычным образом:
- name: Use CapsLock to switch keyboard layout community.general.osx_defaults: key: TISRomanSwitchState type: int value: 1
Кстати, чтобы определить тип значения, можно воспользоваться командой:
defaults read-type -g TISRomanSwitchState Type is integer
А сейчас я хочу настроить Finder на отображение текущего пути стиле Unix. Для этого включу скрытую опцию _FXShowPosixPathInTitle
, а заодно включу интерактивную панель пути - ShowPathbar
:
- name: Set Option - Show Current Path community.general.osx_defaults: domain: com.apple.finder key: "{{ item.key }}" type: "{{ item.type }}" value: "{{ item.value }}" loop: - { key: ShowPathbar, type: boolean, value: 1 } - { key: _FXShowPosixPathInTitle, type: boolean, value: 1 } register: finder - name: Finder - kill ansible.builtin.command: killall Finder when: finder is changed
Готово, теперь Finder перезапустился и стал выглядеть крутым.
Итоги
Я постарался показать базовые возможности Ansible для хранения конфигурации своего мака в виде кода. Теперь остаётся только сделать над собой усилие и не трогать ничего руками. Да, это будет сложно, потому что искать нужные параметры через defaults
тот ещё квест. Да, не все приложения могут работать с defaults
, например, тот же iTerm2, использующий собственный API. Но всё равно этот опыт будет полезным. Как минимум, это просто способ получить академические знания об устройстве MacOS, как максимум - облегчить боль обслуживания яблочного парка из десятков и сотен машин.