Автоматизация сборки MXNet с использованием сценариев Bash

Создание двоичных файлов для выпуска программного обеспечения - дело кропотливое. Но автоматизация с использованием сценариев Bash оказалась стоящей хлопот!

В рамках тестирования Apache MXNet мне было поручено создать двоичные файлы для внутренней вилки Apache MXNet.

При создании и тестировании двоичного файла MXNet мне пришлось выполнить множество шагов. Кроме того, этот конвейер нужно было воспроизвести 8 раз, чтобы соответствовать различным вариантам, поддерживаемым Apache MXNet, таким как CPU / GPU, +/- MKL и +/- Большой тензор (2³ = 8).

Это упражнение было критичным по времени и одновременно повторяющимся. Определенный набор шагов нужно было выполнить последовательно. Более того, его нужно было воспроизвести на нескольких машинах с небольшими изменениями. Все это требует автоматизации.

Все, что написано более двух раз, можно и нужно автоматизировать.

Bash (сценарий оболочки) - идеальный кандидат для этой задачи. Имея небольшой предыдущий опыт, я очень хотел применить его в режиме реального времени. Вот попытка уловить концепции, связанные с написанием сценариев оболочки, с которыми я столкнулся в процессе.

# (хеш) +! (взрыв) = #! (shebang)

Вызов другого сценария оболочки из существующего сценария оболочки
Очень распространенный вариант использования - иметь несколько сценариев оболочки для выполнения определенных задач (думайте, что это модульный, но на уровне файла, а не функция уровень). Я быстро понял, зачем нам shebang благодаря необходимости вызова другого скрипта.

При большом количестве альтернатив bash (zsh, ksh, sh) добавление shebang вверху сообщает операционной системе (да! OS ftw!) Использовать указанную библиотеку. Программа вместе с абсолютным путем (/usr/bin/env). Если он не указан, ОС принимает значение по умолчанию.

Печать / ведение журнала

Первый шаг в изучении любого языка, тестировании любого кода, отладке чего-либо начинается с операторов печати: ведение журнала консоли. Печать в стандартный вывод (стандартный вывод).

echo

Передача аргументов в сценарий оболочки

./pip_build_test.sh mkl

Учитывая эту команду, mkl - это аргумент, который нам нужно обработать.
Доступ к аргументам осуществляется внутри сценария bash с использованием переменных $ 1, $ 2 и т. Д.
$ 1 является первым аргументом (после команды, конечно): мкл

Другой метод передачи аргументов, называемый методом флагов, хорошо объясняется в этой статье livewire.

Обеспокоены раскрытием учетных данных?

Одна из команд git (для репозитория, размещенного на AWS Code Commit) требовала имени пользователя и пароля.

git clone https://username:password@server

Хотя вышеупомянутый метод, упомянутый в топе поиска Google, существует, это определенно не лучший способ.

Предоставление учетных данных git (или любых других) - плохая идея.

Быстрый и грязный обходной путь? Не указывайте имя пользователя и пароль, и пусть пользователь сам настраивает их на своем компьютере. По иронии судьбы, это единственный ручной аспект автоматизированного процесса.

Лучшие решения?

  1. Мерзавцы-секреты
  2. AWS Secrets Manager / SSH-ключи
  3. Переменные среды!

Сохранение вывода команды в переменной

Иногда нам нужно сохранить результат команды в переменной для использования в будущем. Этого можно добиться с помощью: var=$(command)

Условные выражения

Это возвращает нас к Алголу! За if, else следует fi
Использование зеркальных слов, благодаря Стивену Борну, было перенесено с Алгола на языки сценариев оболочки Unix.

if [[ condition ]]
then
    echo "yes"
else
    echo "no"

Условие может использовать различные флаги. Например, несколько условных выражений -
-d: поиск каталога
-f: поиск файла
-z: возвращает True, если длина строки равна нулю

Для получения дополнительной информации команда man bash.

Боковое примечание: споры между тестом и расширенным тестом.
[] vs [[]]: используйте двойной [[. Есть улучшения. Почему? "Читать".

Считывание данных, введенных пользователем, в переменную

Кроме того, гибкости можно достичь, позволив пользователю вводить значение, которое может быть сохранено в переменной (опять же для использования в будущем).
read -p “Enter the name of the AWS S3 bucket: ” bucketname

Повышая удобство использования на ступеньку выше, мы можем позволить пользователю подтвердить, используя:
read -p “Continue? (Y/N): “ confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1

Безопасность превыше всего. Наконец-то.

Благодарим Педро Ларроя за указание на две полезные детали.
Перво-наперво. Чтобы сделать сценарий bash безопасным, важно использовать set -euxo pipefail. Без этого ошибки сценария bash останутся незамеченными, поскольку сценарий всегда будет возвращать значение true. Во-вторых, по возможности используйте Python поверх Bash.

Почему вы спросите? Прочтите эту статью Написание сценариев безопасной оболочки.

Превратите скрипт в исполняемый файл

После того, как все сказано и сделано, остается последнее: превратить .sh файл в исполняемый .sh скрипт.

chmod u+x <name of the file>.sh

Теперь вместо u вы можете выбрать другие разрешения

  • u означает "пользователь".
  • g обозначает группу.
  • o означает другие.
  • a означает все.

Окончательный сценарий оболочки

Примечание: aws-cli обычно можно установить с помощью
sudo apt install awscli

Вышеупомянутый процесс использования пакета awscli требовался для более старой версии Ubuntu 14.04. (Можете ли вы поверить, что люди до сих пор используют 14.04? Старое - золото!)

Это всего лишь пример моего обычного рабочего дня. Участие в Apache MXNet научило меня большему, чем я когда-либо узнал в школе. Мы приветствуем больше таких вкладов в нашем репозитории Github: https://github.com/apache/incubator-mxnet/

Ресурсы











В целях конфиденциальности и безопасности содержимое скрипта было изменено.