diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 index 395a1b3..91dd7b5 --- a/build.sh +++ b/build.sh @@ -1,17 +1,19 @@ #!/bin/sh usage() { - echo "✏️ Использование: $0 -n <имя> -v <версия> [-a <адрес>] [-p <порт>] [-r]" + echo "✏️ Использование: $0 -n <имя> -v <версия> -d <версия_docker> -b <версия_базового_образа> [-r <адрес_registry>] [-p <порт>]" echo "🔧 Опции:" echo " -n, --name Имя образа (обязательно)" echo " -v, --version Версия образа в формате X.Y.Z (обязательно)" - echo " -a, --address Адрес registry (требуется с -r)" - echo " -p, --port Порт registry (опционально)" - echo " -r, --push-to-registry Создать теги и отправить образы в registry" + echo " -d, --docker-version Версия Docker для сборки (обязательно)" + echo " -b, --base-image-version Версия базового образа (обязательно)" + echo " -r, --push-to-registry Адрес registry для отправки образов (например, registry.example.com)" + echo " -p, --port Порт registry (по умолчанию 5000)" echo "" echo "📌 Примеры:" - echo " Только сборка: $0 -n myapp -v 2.5.7" - echo " Сборка и отправка: $0 -n myapp -v 2.5.7 -a registry.example.com -p 5000 -r" + echo " Только сборка: $0 -n myapp -v 2.5.7 -d 20.10 -b 3.8" + echo " Сборка и отправка: $0 -n myapp -v 2.5.7 -d 20.10 -b 3.8 -r registry.example.com" + echo " Сборка и отправка с другим портом: $0 -n myapp -v 2.5.7 -d 20.10 -b 3.8 -r registry.example.com -p 8080" exit 1 } @@ -24,9 +26,9 @@ validate_version() { validate_address() { if [ -z "$1" ]; then - echo "❌ Ошибка: Адрес не может быть пустым" + echo "❌ Ошибка: Адрес registry не может быть пустым" exit 1 - fi + } } validate_port() { @@ -38,53 +40,68 @@ validate_port() { fi } +check_dockerfile() { + if [ ! -f "Dockerfile.$1" ]; then + echo "❌ Ошибка: Файл Dockerfile.$1 не найден в директории docker" + exit 1 + fi +} + push_to_registry=false name="" version="" -address="" -port="" +docker_version="" +base_image_version="" +registry_address="" +port="5000" -while getopts ":n:v:a:p:r" opt; do +while getopts ":n:v:d:b:p:r:" opt; do case $opt in n) name="$OPTARG" ;; v) version="$OPTARG" ;; - a) address="$OPTARG" ;; + d) docker_version="$OPTARG" ;; + b) base_image_version="$OPTARG" ;; p) port="$OPTARG" ;; - r) push_to_registry=true ;; + r) push_to_registry=true; registry_address="$OPTARG" ;; \?) echo "❌ Неверный аргумент -$OPTARG" >&2; usage ;; :) echo "❌ Опция -$OPTARG требует аргумент" >&2; usage ;; esac done -if [ -z "$name" ] || [ -z "$version" ]; then - echo "❌ Ошибка: Не указаны обязательные аргументы (-n и -v)" +if [ -z "$name" ] || [ -z "$version" ] || [ -z "$docker_version" ] || [ -z "$base_image_version" ]; then + echo "❌ Ошибка: Не указаны обязательные аргументы (-n, -v, -d и -b)" usage fi validate_version "$version" if [ "$push_to_registry" = true ]; then - if [ -z "$address" ]; then - echo "❌ Ошибка: Для отправки в registry необходимо указать адрес (-a)" + if [ -z "$registry_address" ]; then + echo "❌ Ошибка: Для отправки в registry необходимо указать адрес с -r" usage fi - validate_address "$address" + validate_address "$registry_address" validate_port "$port" fi -echo "🐳 Сборка образа $name:$version..." -docker build . -t "${name}:${version}" || { +echo "📂 Переход в директорию docker..." +cd docker || { + echo "❌ Ошибка: Не удалось перейти в директорию docker" + exit 1 +} + +echo "🔍 Проверка наличия Dockerfile..." +check_dockerfile "$docker_version" + +echo "🐳 Сборка образа $name:$version с использованием Dockerfile.$docker_version и базового образа версии $base_image_version..." +docker build . -f "Dockerfile.$docker_version" -t "${name}:${version}" --build-arg BASE_IMAGE_VERSION="$base_image_version" || { echo "❌ Ошибка при сборке образа" exit 1 } if [ "$push_to_registry" = true ]; then - if [ -z "$port" ]; then - registry="$address" - else - registry="$address:$port" - fi + registry="$registry_address:$port" echo "🏷 Создание тегов для registry..." diff --git a/20.10.20/Dockerfile b/docker/Dockerfile.20.10.20 similarity index 90% rename from 20.10.20/Dockerfile rename to docker/Dockerfile.20.10.20 index 118e359..e6ce26e 100644 --- a/20.10.20/Dockerfile +++ b/docker/Dockerfile.20.10.20 @@ -1,4 +1,5 @@ -FROM alpine:3.16.9 +ARG BASE_IMAGE_VERSION=latest +FROM alpine:${BASE_IMAGE_VERSION} # Метаданные для CI/CD LABEL maintainer="Alexander Zhirov " @@ -16,7 +17,7 @@ ENV USER=builder \ NAME_KEY=builder # Копируем скрипт запуска в контейнер -COPY apk-build /usr/bin/apk-build +COPY build-apk /usr/bin/build-apk # Устанавливаем необходимые пакеты для сборки APK и NFS RUN echo "http://mirror.yandex.ru/mirrors/alpine/v3.16/main" > /etc/apk/repositories && \ @@ -27,7 +28,7 @@ RUN echo "http://mirror.yandex.ru/mirrors/alpine/v3.16/main" > /etc/apk/reposito adduser -D builder && \ addgroup builder abuild && \ echo "builder ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/builder && \ - chmod 0755 /usr/bin/apk-build && \ + chmod 0755 /usr/bin/build-apk && \ mkdir /home/builder/package && \ chown builder:builder /home/builder/package @@ -38,7 +39,7 @@ USER builder WORKDIR /home/builder/package # Указываем точку входа для CI/CD -ENTRYPOINT ["/usr/bin/apk-build"] +ENTRYPOINT ["/usr/bin/build-apk"] # Указываем команду по умолчанию с переменными окружения CMD ["-p", "/package"] diff --git a/27.3.1/Dockerfile b/docker/Dockerfile.27.3.1 similarity index 90% rename from 27.3.1/Dockerfile rename to docker/Dockerfile.27.3.1 index 885856d..b0ea592 100644 --- a/27.3.1/Dockerfile +++ b/docker/Dockerfile.27.3.1 @@ -1,4 +1,5 @@ -FROM alpine:3.16.9 +ARG BASE_IMAGE_VERSION=latest +FROM alpine:${BASE_IMAGE_VERSION} # Метаданные для CI/CD LABEL maintainer="Alexander Zhirov " @@ -16,7 +17,7 @@ ENV USER=builder \ NAME_KEY=builder # Копируем скрипт запуска в контейнер -COPY --chmod=0755 apk-build /usr/bin/apk-build +COPY --chmod=0755 build-apk /usr/bin/build-apk # Устанавливаем необходимые пакеты для сборки APK и NFS RUN < [-s -n ] [-r <приватный_ключ> -u <публичный_ключ>] [-d <путь_к_репозиторию>]" + echo "Использование: $0 -p <путь_к_APKBUILD> -k <наименование_ключа> [-s -n ] [-r <приватный_ключ> -u <публичный_ключ>] [-d <путь_к_репозиторию>]" echo "Параметры:" echo " -p <путь_к_APKBUILD> Путь к директории с APKBUILD (обязательный)" + echo " -k <наименование_ключа> Наименование файла ключа (обязательный)" echo " -s IP или имя NFS-сервера (опционально)" echo " -n Путь к NFS-ресурсу (опционально, требуется с -s)" echo " -r <приватный_ключ> Содержимое файла приватного ключа (опционально)" echo " -u <публичный_ключ> Содержимое файла публичного ключа (опционально)" echo " -d <путь_к_репозиторию> Путь к директории репозитория в ~/packages (опционально)" - echo " -k <наименование_ключа> Наименование файла ключа (опционально)" - echo "Пример: $0 -p /package -s 192.168.1.100 -n /nfs/share -r \"<содержимое_ключа.rsa>\" -u \"<содержимое_ключа.rsa.pub>\" -d /repo -k \"mykey\"" + echo "Пример: $0 -p /package -k mykey -s 192.168.1.100 -n /nfs/share -r \"<содержимое_ключа.rsa>\" -u \"<содержимое_ключа.rsa.pub>\" -d /repo" echo "Флаги -s и -n включают монтирование NFS, должны использоваться вместе." echo "Флаги -r и -u содержат текст приватного и публичного ключей для abuild." echo "Флаг -d задаёт директорию для сохранения пакетов." @@ -25,7 +25,7 @@ usage() { : "${PRIVATE_KEY:=}" : "${PUBLIC_KEY:=}" : "${REPODEST_DIR:=}" -: "${NAME_KEY:=builder}" +: "${NAME_KEY:=}" PACKAGES_DIR="/home/builder/packages" NFS_ENABLED=0 @@ -49,6 +49,18 @@ if [ -z "$PACKAGE_DIR" ]; then usage fi +# Проверка наличия обязательного аргумента -k +if [ -z "$NAME_KEY" ]; then + echo "🚫 Ошибка: Не указан обязательный параметр -k" + usage +fi + +# Проверка валидности имени ключа +if ! echo "$NAME_KEY" | grep -qE '^[a-zA-Z0-9_-]+$'; then + echo "🚫 Ошибка: Имя ключа должно содержать только буквы, цифры, символы '_' или '-'" + exit 1 +fi + # Проверка, что если указан один из -s или -n, то указан и другой if [ -n "$NFS_SERVER" ] && [ -z "$NFS_PATH" ] || [ -z "$NFS_SERVER" ] && [ -n "$NFS_PATH" ]; then echo "🚫 Ошибка: Флаги -s и -n должны быть указаны вместе" @@ -72,21 +84,35 @@ if [ ! -f "$PACKAGE_DIR/APKBUILD" ]; then exit 1 fi -if [ -z "$NAME_KEY" ]; then - echo "🚫 Ошибка: Необходимо указать наименование ключа подписи" +# Проверка прав доступа к директории +if [ ! -r "$PACKAGE_DIR" ] || [ ! -x "$PACKAGE_DIR" ]; then + echo "🚫 Ошибка: Недостаточно прав для доступа к директории $PACKAGE_DIR" exit 1 fi # Проверка и настройка ключей abuild if [ -n "$PRIVATE_KEY" ] || [ -n "$PUBLIC_KEY" ]; then echo "🔑 Настраиваю переданные ключи abuild..." - # Проверяем, что переданы все три компонента + # Проверяем, что переданы все компоненты if [ -z "$PRIVATE_KEY" ] || [ -z "$PUBLIC_KEY" ]; then - echo "🚫 Ошибка: Для использования ключей нужны все флаги: -r, -u" + echo "🚫 Ошибка: Для использования ключей нужны оба флага: -r, -u" + exit 1 + fi + # Проверка формата ключей + if ! echo "$PRIVATE_KEY" | grep -q "BEGIN RSA PRIVATE KEY"; then + echo "🚫 Ошибка: Приватный ключ имеет неверный формат" + exit 1 + fi + if ! echo "$PUBLIC_KEY" | grep -q "ssh-rsa"; then + echo "🚫 Ошибка: Публичный ключ имеет неверный формат" exit 1 fi # Создаем директорию .abuild mkdir -p /home/builder/.abuild + if [ $? -ne 0 ]; then + echo "🚫 Ошибка: Не удалось создать директорию /home/builder/.abuild" + exit 1 + fi # Записываем abuild.conf echo "PACKAGER_PRIVKEY=\"/home/builder/.abuild/$NAME_KEY.rsa\"" > /home/builder/.abuild/abuild.conf if [ $? -ne 0 ]; then @@ -110,6 +136,10 @@ if [ -n "$PRIVATE_KEY" ] || [ -n "$PUBLIC_KEY" ]; then chmod 644 /home/builder/.abuild/$NAME_KEY.rsa.pub /home/builder/.abuild/abuild.conf # Копирование ключа для apk менеджера sudo cp -v /home/builder/.abuild/$NAME_KEY.rsa.pub /etc/apk/keys/ + if [ $? -ne 0 ]; then + echo "🚫 Ошибка при копировании публичного ключа в /etc/apk/keys/" + exit 1 + fi echo "✅ Ключи abuild успешно настроены" else # Если ключи не переданы, проверяем существующие или генерируем новые @@ -122,7 +152,15 @@ else fi echo "✅ Ключи abuild сгенерированы" else - sudo cp -v /home/builder/.abuild/$NAME_KEY.rsa.pub /etc/apk/keys/ + if [ ! -f "/home/builder/.abuild/$NAME_KEY.rsa" ] || [ ! -f "/home/builder/.abuild/$NAME_KEY.rsa.pub" ]; then + echo "🚫 Ошибка: Указанное имя ключа $NAME_KEY не соответствует существующим ключам" + exit 1 + fi + sudo cp /home/builder/.abuild/$NAME_KEY.rsa.pub /etc/apk/keys/ + if [ $? -ne 0 ]; then + echo "🚫 Ошибка при копировании существующего публичного ключа" + exit 1 + fi echo "✅ Использую существующие ключи abuild" fi fi @@ -131,6 +169,10 @@ fi if [ "$NFS_ENABLED" -eq 1 ]; then echo "🔌 Монтирую NFS-ресурс $NFS_SERVER:$NFS_PATH в $PACKAGES_DIR..." sudo mkdir -p "$PACKAGES_DIR" + if [ $? -ne 0 ]; then + echo "🚫 Ошибка: Не удалось создать директорию $PACKAGES_DIR" + exit 1 + fi sudo mount -t nfs "$NFS_SERVER:$NFS_PATH" "$PACKAGES_DIR" if [ $? -ne 0 ]; then echo "🚫 Ошибка при монтировании NFS-ресурса" @@ -140,15 +182,20 @@ if [ "$NFS_ENABLED" -eq 1 ]; then else echo "ℹ️ NFS не указан, пакеты будут сохранены локально в $PACKAGES_DIR" mkdir -p "$PACKAGES_DIR" + if [ $? -ne 0 ]; then + echo "🚫 Ошибка: Не удалось создать директорию $PACKAGES_DIR" + exit 1 + fi fi # Копируем содержимое директории в рабочую директорию echo "📂 Копирую файлы проекта в рабочую директорию..." +mkdir -p /home/builder/package cp -r "$PACKAGE_DIR"/* /home/builder/package/ if [ $? -ne 0 ]; then echo "🚫 Ошибка при копировании файлов проекта" if [ "$NFS_ENABLED" -eq 1 ]; then - sudo umount "$PACKAGES_DIR" + sudo umount "$PACKAGES_DIR" || echo "🚫 Ошибка при размонтировании NFS" fi exit 1 fi @@ -158,7 +205,7 @@ echo "✅ Файлы успешно скопированы" cd /home/builder/package || { echo "🚫 Ошибка: Не удалось перейти в директорию /home/builder/package" if [ "$NFS_ENABLED" -eq 1 ]; then - sudo umount "$PACKAGES_DIR" + sudo umount "$PACKAGES_DIR" || echo "🚫 Ошибка при размонтировании NFS" fi exit 1 } @@ -167,17 +214,16 @@ echo "✅ Перешел в директорию проекта" # Проверяем зависимости и собираем пакет echo "🔨 Проверяю зависимости и собираю APK-пакет..." -# Устанавливаем флаг NFS_ENABLED, если указаны оба флага -s и -n +# Устанавливаем REPODEST_DIR if [ -n "$REPODEST_DIR" ]; then REPODEST_DIR=$(echo "${REPODEST_DIR}" | sed 's|^./||;s|^/||') fi REPODEST="$PACKAGES_DIR/${REPODEST_DIR:=v$(cat /etc/alpine-release | awk -F. '{print $1"."$2}')}" abuild -r - if [ $? -ne 0 ]; then echo "🚫 Ошибка при сборке APK-пакета" if [ "$NFS_ENABLED" -eq 1 ]; then - sudo umount "$PACKAGES_DIR" + sudo umount "$PACKAGES_DIR" || echo "🚫 Ошибка при размонтировании NFS" fi exit 1 fi diff --git a/edit b/edit new file mode 100644 index 0000000..e69de29