Skip to content

Instantly share code, notes, and snippets.

@anutator
Last active January 24, 2023 21:41
Show Gist options
  • Select an option

  • Save anutator/4713dae85885f5d20fa5e700eb2d2d42 to your computer and use it in GitHub Desktop.

Select an option

Save anutator/4713dae85885f5d20fa5e700eb2d2d42 to your computer and use it in GitHub Desktop.
Создание Makefile для удобства повседневной работы
# Пример Makefile
SHELL:=/bin/bash
.DEFAULT_GOAL := help
dt := $$(date +"%Y-%m-%d")
logs := logs
.PHONY: ps status up down restart images logs help
ps: ## список всех контейнеров (распределены по подам)
podman ps --pod
status: ## статус сервиса podman-compose@dataserver
systemctl --user status podman-compose@dataserver
up: ## запустить контейнеры Dataserver
#podman-compose -f dataserver.yml up -d
systemctl --user start podman-compose@dataserver
down: ## остановить контейнеры Dataserver
#podman-compose -f dataserver.yml down
systemctl --user stop podman-compose@dataserver
restart: ## перезапустить контейнеры Dataserver
#podman-compose -f dataserver.yml down
#podman-compose -f dataserver.yml up -d
systemctl --user restart podman-compose@dataserver
images: ## загрузить новые образы (далее ввести podman auto-update или make update)
podman load -i dataserver.tar.gz
podman load -i shuttle.tar.gz
podman image prune -f
update: ## автообновление образов через systemctl (podman auto-update), требует registry
podman auto-update
logs: ## собрать логи всех контейнеров в каталог 'logs' и заархивировать в файл 'logs-dts01.tgz'
@echo -e "====Сбор логов всех контейнеров в архив logs-dts01.tgz====\n"
@echo -e "Пересоздаем каталог $(logs)"
rm -rf $(logs); \
mkdir $(logs)
@echo -e "\nСбор логов контейнера dataserver"
id=$$(podman ps -aqf "name=^dataserver$$") && \
podman cp $$id:/app/Logs/. $(logs)/dataserver; \
podman logs $$id &> ./$(logs)/$(dt)_dataserver.log
@echo -e "\nСбор логов контейнера shuttle"
id=$$(podman ps -aqf "name=^shuttle$$") && \
podman cp $$id:/app/Logs/. $(logs)/shuttle; \
podman logs $$id &> ./$(logs)/$(dt)_shuttle.log
@echo -e "\nСбор логов контейнера mysql-history"
podman logs $$(podman ps -aqf "name=^mysql-history$$") &> ./$(logs)/$(dt)_mysql-history.log
@echo -e "\nАрхивируем все архивы из каталога $(logs) в logs-dts01.tgz"
tar czvf logs-dts01.tgz $(logs)
j: ## journalctl
#journalctl --user -xeu podman-compose@dataserver
journalctl -xe
stats: ## статистика по поду pod_dataserver (пока не работает, требует cgroups v2)
podman pod stats pod_dataserver
tail: ## последние сообщения лога pod_dataserver в реальном времени
podman pod logs --tail=10 -f pod_dataserver
help: ## отобразить подсказки
@awk -F ':|##' '/^[^\t].+?:.*?##/ { printf "\033[36m%-30s\033[0m %s\n", $$1, $$NF }' $(MAKEFILE_LIST) | sort

Надо помнить, что Makefile — это не совсем bash. Он изначально не предназначен для скриптов. Его можно использовать для упрощения ввода команд, хотя основное назначение Makefile — для сборки программ из исходников. Но в иностранных видеокурсах Makefile используют разработчики для удобства: вот некоторые примеры https://chriswiegman.com/tag/make/ Что ещё не докрутила: хитрости, чтобы make воспринимал команду как make target аргумент аргумент. Вообще make не работает как стандартные скрипты, и по умолчанию всё что вводится после make считается target-ом. А аргумент можно ввести например перед командой типа ПЕРЕМЕННАЯ=значение make ... Однако я хочу докрутить Makefile для удобного использования команд Ansible. Пока что я упростила добавление сотрудников через ansible использую функцию bash. Но для меня коллег желательно бы создать Makefile. Есть некоторые примеры для Ansible на Github, я их тоже учту.

Несколько нюансов:

  1. файлах Makefile ввод отступа через Tab должен быть именно Tab-ом. Если у вас Tab заменяется на двойной пробел, как например в файлах .yaml для Ansible или Kubernetes, будет ошибка. Как это сделать например в редакторе vim? Надо в .vimrc добавить настройки:
" Сокращения: sw - shiftwidth, sts - softtabstop, ts - tabstop,
" et - expandtab, noet - noexpandtab, setl - setlocal, au - autocmd
" По умолчанию Tab делаем отступ 2 пробела
set ts=2 sts=2 sw=2 ai et
" в Makefile (makefile, and *.mk) нужен именно Tab, а не пробелы
au FileType make setl noet

По умолчанию при нажатии Tab у меня вставляется 2 пробела. А когда я создаю Makefile вставляется именно символ табуляции. Это важно, т.к. если не отобразить специально в vim невидимые символы, визуально вы никак не отличите пробелы от Tab.

  1. Изначально Makefile предназначен для компиляции кода, например сборки проектов на C, C++ и т.д. Т.е. подразумевается, что в результате выполнения target-а будет создан каталог или файл с именем target-а. Из моего примера. У меня в каталоге есть подкаталог logs. Поэтому если просто так создать таргет logs и выполнить в Linux команду make logs, ничего не произойдет, и будет сообщение, что каталог уже есть. Для таких случаев есть директива .PHONY, где мы перечисляем то, что не должно быть файлами.

  2. Знак $ является спецсимволом в Makefile, поэтому если задача получить переменную, выполнив команду оболочки Linux, или использовать $ как спецсимвол в bash, обозначающий конец слова, надо добавить дополнительный знак доллара. Это будет видно в примере. Т.е. например мы хотим найти слово php, т.е. только три этих буквы. В bash мы пишем ^php$, а вот в Makefile надо писать ^php$$.

  3. Для удобства добавим дополнительный target с именем help, чтобы по команде make help выводились подсказки по всем target-ам. Как мы получаем подскахки? С помощью команды awk разбираем строку так, что подсказкой является текст после двух решеток. Также результат сортируется по алфавиту (по именам target-ов).

  4. По умолчанию, если просто ввести make, будет выполнен первый target из файла. Но я использую директиву .DEFAULT_GOAL := help, чтобы по умолчанию при выполнении команды make без аргументов выполнялась make help (отображение подсказок).

  5. Если надо добавить пустые строки, используем echo -e "\nтекст \n"

  6. Спецсимвол @ перед строкой позволяет не выводить саму команду, которая указана в строке, а выводить сразу её результат. Например, я отображаю все команды, чтобы видеть, что именно выполняется, но саму команду @echo я не отображаю, т.к. хочу, чтобы появится только итоговый текст.

  7. Команды внутри target -а выполняются в разных оболочках, поэтому если надо их выполнить в одной или объединить, используем обратный слеш \.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment