Промежуточный стабильный вариант
This commit is contained in:
parent
ab7a65969e
commit
92ff34dbf3
5 changed files with 111 additions and 46 deletions
67
build.sh
Normal file → Executable file
67
build.sh
Normal file → Executable file
|
@ -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..."
|
||||
|
||||
|
|
|
@ -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 <alexander@zhirov.kz>"
|
||||
|
@ -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"]
|
|
@ -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 <alexander@zhirov.kz>"
|
||||
|
@ -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 <<EOF
|
||||
|
@ -37,7 +38,7 @@ USER builder
|
|||
WORKDIR /home/builder/package
|
||||
|
||||
# Указываем точку входа для CI/CD
|
||||
ENTRYPOINT ["/usr/bin/apk-build"]
|
||||
ENTRYPOINT ["/usr/bin/build-apk"]
|
||||
|
||||
# Указываем команду по умолчанию с переменными окружения
|
||||
CMD ["-p", "/package"]
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
# Функция для вывода справки
|
||||
usage() {
|
||||
echo "Использование: $0 -p <путь_к_APKBUILD> [-s <NFS_сервер> -n <NFS_путь>] [-r <приватный_ключ> -u <публичный_ключ>] [-d <путь_к_репозиторию>]"
|
||||
echo "Использование: $0 -p <путь_к_APKBUILD> -k <наименование_ключа> [-s <NFS_сервер> -n <NFS_путь>] [-r <приватный_ключ> -u <публичный_ключ>] [-d <путь_к_репозиторию>]"
|
||||
echo "Параметры:"
|
||||
echo " -p <путь_к_APKBUILD> Путь к директории с APKBUILD (обязательный)"
|
||||
echo " -k <наименование_ключа> Наименование файла ключа (обязательный)"
|
||||
echo " -s <NFS_сервер> IP или имя NFS-сервера (опционально)"
|
||||
echo " -n <NFS_путь> Путь к 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
|
0
edit
Normal file
0
edit
Normal file
Loading…
Add table
Add a link
Reference in a new issue