mirror of
https://github.com/Direct-Dev-Ru/go-lcg.git
synced 2025-11-16 01:29:55 +00:00
Исправления в ветке auth-feature
This commit is contained in:
29
deploy/.goreleaser.yaml
Normal file
29
deploy/.goreleaser.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
# Goreleaser configuration version 2
|
||||
version: 2
|
||||
|
||||
builds:
|
||||
- id: lcg
|
||||
binary: "lcg_{{ .Version }}"
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w
|
||||
- -X main.version={{.Version}}
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
main: .
|
||||
dir: .
|
||||
|
||||
archives:
|
||||
- id: lcg
|
||||
builds:
|
||||
- lcg
|
||||
format: binary
|
||||
name_template: "{{ .Binary }}_{{ .Os }}_{{ .Arch }}"
|
||||
files:
|
||||
- "lcg_{{ .Version }}"
|
||||
21
deploy/0.create_sealed_secrets.example.sh
Normal file
21
deploy/0.create_sealed_secrets.example.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# https://dev.to/ashokan/sealed-secrets-the-secret-sauce-for-managing-secrets-2hg6
|
||||
# head -c 64 /dev/urandom | base64 -w 0
|
||||
export KUBECONFIG=/home/su/.kube/config_hlab
|
||||
|
||||
kubectl create secret generic lcg-secrets -n lcg \
|
||||
--from-literal=LCG_SERVER_PASSWORDL= \
|
||||
--from-literal=LCG_CSRF_SECRET=\
|
||||
--from-literal=LCG_JWT_SECRET=\
|
||||
--from-literal=LCG_JWT_TOKEN=\
|
||||
--dry-run=client -o yaml | tee secret-cfg.yaml
|
||||
|
||||
kubeseal --controller-name=sealed-secrets-controller --controller-namespace=kube-system -o yaml <secret-cfg.yaml | tee sealed-cfg.yaml
|
||||
|
||||
rm -f secret-cfg.yaml
|
||||
|
||||
kubectl apply -f sealed-cfg.yaml
|
||||
cp sealed-cfg.yaml ../kustomize/secret.yaml
|
||||
|
||||
kubectl get secret lcg-secrets -n lcg -o json | jq ".data | map_values(@base64d)"
|
||||
7
deploy/0.namespace.yaml
Normal file
7
deploy/0.namespace.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: lcg
|
||||
labels:
|
||||
name: lcg
|
||||
app: linux-command-gpt
|
||||
46
deploy/1.configmap.yaml
Normal file
46
deploy/1.configmap.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: lcg-config
|
||||
namespace: lcg
|
||||
data:
|
||||
# Основные настройки
|
||||
LCG_VERSION: "${VERSION}"
|
||||
LCG_BASE_PATH: "/lcg"
|
||||
LCG_SERVER_HOST: "0.0.0.0"
|
||||
LCG_SERVER_PORT: "8080"
|
||||
LCG_SERVER_ALLOW_HTTP: "true"
|
||||
LCG_APP_NAME: "Linux Command GPT"
|
||||
LCG_RESULT_FOLDER: "/app/data/results"
|
||||
LCG_PROMPT_FOLDER: "/app/data/prompts"
|
||||
LCG_CONFIG_FOLDER: "/app/data/config"
|
||||
LCG_NO_HISTORY: "false"
|
||||
LCG_ALLOW_EXECUTION: "false"
|
||||
LCG_DEBUG: "false"
|
||||
|
||||
# Настройки аутентификации
|
||||
LCG_SERVER_REQUIRE_AUTH: "true"
|
||||
|
||||
LCG_COOKIE_SECURE: "true"
|
||||
LCG_COOKIE_TTL_HOURS: "168"
|
||||
LCG_DOMAIN: "direct-dev.ru"
|
||||
LCG_COOKIE_PATH: "/lcg"
|
||||
|
||||
# Настройки провайдера (по умолчанию)
|
||||
LCG_PROVIDER_TYPE: "proxy"
|
||||
LCG_HOST: "https://direct-dev.ru"
|
||||
LCG_HEALTH_URL: "/api/v1/protected/sberchat/health"
|
||||
LCG_PROXY_URL: "/api/v1/protected/sberchat/chat"
|
||||
LCG_MODEL: "GigaChat-2-Max"
|
||||
|
||||
# Настройки валидации
|
||||
LCG_MAX_SYSTEM_PROMPT_LENGTH: "2000"
|
||||
LCG_MAX_USER_MESSAGE_LENGTH: "4000"
|
||||
LCG_MAX_PROMPT_NAME_LENGTH: "2000"
|
||||
LCG_MAX_PROMPT_DESC_LENGTH: "50000"
|
||||
|
||||
# Настройки таймаутов
|
||||
LCG_TIMEOUT: "300"
|
||||
|
||||
# Настройки отладки
|
||||
LCG_DEBUG: "false"
|
||||
12
deploy/2.gitrepository.yaml
Normal file
12
deploy/2.gitrepository.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: linux-command-gpt
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 3m
|
||||
url: https://direct-dev.ru/gitea/GiteaAdmin/go-lcg.git
|
||||
ref:
|
||||
branch: release
|
||||
secretRef:
|
||||
name: gitea-token
|
||||
19
deploy/3.lcg-kustomization.yaml
Normal file
19
deploy/3.lcg-kustomization.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: lcg
|
||||
namespace: flux-system
|
||||
spec:
|
||||
healthChecks:
|
||||
- kind: Deployment
|
||||
name: lcg
|
||||
namespace: lcg
|
||||
interval: 3m15s
|
||||
path: ./kustomize
|
||||
prune: true
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: linux-command-gpt
|
||||
targetNamespace: lcg
|
||||
timeout: 2m0s
|
||||
114
deploy/4.build-binaries.sh
Executable file
114
deploy/4.build-binaries.sh
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🚀 LCG Binary Build Script
|
||||
# Скрипт для сборки бинарных файлов с помощью goreleaser на хосте
|
||||
|
||||
set -e
|
||||
|
||||
# Цвета для вывода
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Функция для вывода сообщений
|
||||
log() {
|
||||
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
# Параметры
|
||||
VERSION=${1:-"dev"}
|
||||
# CLEAN=${2:-"true"}
|
||||
|
||||
# Записываем версию в файл VERSION.txt (в корневой директории проекта)
|
||||
echo "$VERSION" > VERSION.txt
|
||||
log "📝 Версия записана в VERSION.txt: $VERSION"
|
||||
|
||||
log "🚀 Сборка бинарных файлов LCG с goreleaser..."
|
||||
|
||||
# Проверяем наличие goreleaser
|
||||
if ! command -v goreleaser &> /dev/null; then
|
||||
error "goreleaser не найден. Установите goreleaser:"
|
||||
echo " curl -sL https://github.com/goreleaser/goreleaser/releases/latest/download/goreleaser_Linux_x86_64.tar.gz | tar -xz -C /usr/local/bin goreleaser"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Проверяем наличие Go
|
||||
if ! command -v go &> /dev/null; then
|
||||
error "Go не найден. Установите Go для сборки."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Переходим в корневую директорию проекта
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
log "📁 Рабочая директория: $(pwd)"
|
||||
log "📁 Папка dist будет создана в: $(pwd)/dist"
|
||||
|
||||
# Очищаем предыдущие сборки если нужно
|
||||
# if [ "$CLEAN" = "true" ]; then
|
||||
# log "🧹 Очистка предыдущих сборок..."
|
||||
# rm -rf dist/
|
||||
# goreleaser clean
|
||||
# fi
|
||||
|
||||
# Проверяем наличие .goreleaser.yaml
|
||||
if [ ! -f "deploy/.goreleaser.yaml" ]; then
|
||||
error "Файл .goreleaser.yaml не найден в папке deploy/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Копируем конфигурацию goreleaser в корень проекта
|
||||
log "📋 Копирование конфигурации goreleaser..."
|
||||
cp deploy/.goreleaser.yaml .goreleaser.yaml
|
||||
|
||||
# Устанавливаем переменные окружения для версии
|
||||
export GORELEASER_CURRENT_TAG="$VERSION"
|
||||
|
||||
# Собираем бинарные файлы
|
||||
log "🏗️ Сборка бинарных файлов для всех платформ..."
|
||||
goreleaser build --snapshot --clean
|
||||
|
||||
# Проверяем результат
|
||||
if [ -d "dist" ]; then
|
||||
log "📊 Собранные бинарные файлы:"
|
||||
find dist -name "lcg_*" -type f | while read -r binary; do
|
||||
echo " $binary ($(stat -c%s "$binary") bytes, $(file "$binary" | cut -d: -f2))"
|
||||
done
|
||||
|
||||
success "🎉 Бинарные файлы успешно собраны!"
|
||||
|
||||
# Показываем структуру dist/
|
||||
log "📁 Структура папки dist/:"
|
||||
tree -h dist/ 2>/dev/null || find dist -type f | sort
|
||||
|
||||
else
|
||||
error "Папка dist/ не создана. Проверьте конфигурацию goreleaser."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Очищаем временный файл конфигурации
|
||||
rm -f .goreleaser.yaml
|
||||
|
||||
success "🎉 Сборка бинарных файлов завершена!"
|
||||
|
||||
# Показываем команды для Docker сборки
|
||||
echo ""
|
||||
log "📝 Следующие шаги:"
|
||||
echo " cd deploy"
|
||||
echo " docker buildx build --platform linux/amd64,linux/arm64 --tag your-registry.com/lcg:$VERSION --push ."
|
||||
echo " # или используйте скрипт:"
|
||||
echo " ./5.build-docker.sh your-registry.com/lcg $VERSION"
|
||||
12
deploy/4.pvc.yaml
Normal file
12
deploy/4.pvc.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: lcg-data
|
||||
namespace: lcg
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
storageClassName: nfs
|
||||
183
deploy/5.build-docker.sh
Executable file
183
deploy/5.build-docker.sh
Executable file
@@ -0,0 +1,183 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🐳 LCG Docker Build Script
|
||||
# Скрипт для сборки Docker образа с предварительно собранными бинарными файлами
|
||||
|
||||
set -e
|
||||
|
||||
# Цвета для вывода
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Функция для вывода сообщений
|
||||
log() {
|
||||
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
# Параметры
|
||||
REPOSITORY=${1:-"your-registry.com/lcg"}
|
||||
VERSION=${2:-""}
|
||||
PLATFORMS=${3:-"linux/amd64,linux/arm64"}
|
||||
|
||||
if [ -z "$VERSION" ]; then
|
||||
error "Версия не указана! Использование: $0 <repository> <version>"
|
||||
echo "Пример: $0 your-registry.com/lcg v1.0.0 <platforms>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "🐳 Сборка Docker образа LCG..."
|
||||
|
||||
# Проверяем наличие docker
|
||||
if ! command -v docker &> /dev/null; then
|
||||
error "Docker не найден. Установите Docker для сборки образов."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Проверяем наличие docker buildx
|
||||
if ! docker buildx version &> /dev/null; then
|
||||
error "Docker Buildx не найден. Установите Docker Buildx для мультиплатформенной сборки."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Проверяем наличие бинарных файлов в текущей директории (если запускаем из корня)
|
||||
if [ ! -d "dist" ]; then
|
||||
error "Папка dist/ не найдена. Сначала соберите бинарные файлы:"
|
||||
echo " ./deploy/4.build-binaries.sh $VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Проверяем наличие бинарных файлов для всех платформ
|
||||
MISSING_BINARIES=()
|
||||
|
||||
# Ищем бинарные файлы с версией в имени
|
||||
AMD64_BINARY=$(find dist -name "*linux_amd64*" -type d | head -1)
|
||||
echo "AMD64_BINARY: $AMD64_BINARY"
|
||||
ARM64_BINARY=$(find dist -name "*linux_arm64*" -type d | head -1)
|
||||
echo "ARM64_BINARY: $ARM64_BINARY"
|
||||
|
||||
# Проверяем наличие бинарных файлов в найденных папках и соответствие версии
|
||||
if [ -n "$AMD64_BINARY" ]; then
|
||||
AMD64_FILE=$(find "$AMD64_BINARY" -name "lcg_*" -type f | head -1)
|
||||
if [ -z "$AMD64_FILE" ]; then
|
||||
AMD64_BINARY=""
|
||||
else
|
||||
# Извлекаем версию из имени файла
|
||||
FILE_VERSION=$(basename "$AMD64_FILE" | sed 's/lcg_//' | sed 's/-SNAPSHOT.*//')
|
||||
# Нормализуем версии для сравнения (убираем префикс 'v' если есть)
|
||||
NORMALIZED_FILE_VERSION=$(echo "$FILE_VERSION" | sed 's/^v//')
|
||||
NORMALIZED_VERSION=$(echo "$VERSION" | sed 's/^v//')
|
||||
if [ "$NORMALIZED_FILE_VERSION" != "$NORMALIZED_VERSION" ]; then
|
||||
error "Версия в имени бинарного файла ($FILE_VERSION) не совпадает с переданной версией ($VERSION)"
|
||||
echo "Файл: $AMD64_FILE"
|
||||
echo "Ожидаемая версия: $VERSION"
|
||||
echo "Версия в файле: $FILE_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$ARM64_BINARY" ]; then
|
||||
ARM64_FILE=$(find "$ARM64_BINARY" -name "lcg_*" -type f | head -1)
|
||||
if [ -z "$ARM64_FILE" ]; then
|
||||
ARM64_BINARY=""
|
||||
else
|
||||
# Извлекаем версию из имени файла
|
||||
FILE_VERSION=$(basename "$ARM64_FILE" | sed 's/lcg_//' | sed 's/-SNAPSHOT.*//')
|
||||
# Нормализуем версии для сравнения (убираем префикс 'v' если есть)
|
||||
NORMALIZED_FILE_VERSION=$(echo "$FILE_VERSION" | sed 's/^v//')
|
||||
NORMALIZED_VERSION=$(echo "$VERSION" | sed 's/^v//')
|
||||
if [ "$NORMALIZED_FILE_VERSION" != "$NORMALIZED_VERSION" ]; then
|
||||
error "Версия в имени бинарного файла ($FILE_VERSION) не совпадает с переданной версией ($VERSION)"
|
||||
echo "Файл: $ARM64_FILE"
|
||||
echo "Ожидаемая версия: $VERSION"
|
||||
echo "Версия в файле: $FILE_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$AMD64_BINARY" ]; then
|
||||
MISSING_BINARIES+=("linux/amd64")
|
||||
fi
|
||||
if [ -z "$ARM64_BINARY" ]; then
|
||||
MISSING_BINARIES+=("linux/arm64")
|
||||
fi
|
||||
|
||||
if [ ${#MISSING_BINARIES[@]} -gt 0 ]; then
|
||||
error "Отсутствуют бинарные файлы для платформ: ${MISSING_BINARIES[*]}"
|
||||
echo "Сначала соберите бинарные файлы:"
|
||||
echo " ./4.build-binaries.sh $VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Показываем найденные файлы и их версии
|
||||
log "📊 Найденные бинарные файлы:"
|
||||
if [ -n "$AMD64_FILE" ]; then
|
||||
echo " AMD64: $AMD64_FILE"
|
||||
fi
|
||||
if [ -n "$ARM64_FILE" ]; then
|
||||
echo " ARM64: $ARM64_FILE"
|
||||
fi
|
||||
|
||||
# Создаем builder если не существует
|
||||
log "🔧 Настройка Docker Buildx..."
|
||||
docker buildx create --name lcg-builder --use 2>/dev/null || docker buildx use lcg-builder
|
||||
|
||||
# Копируем бинарные файлы и файл версии в папку deploy
|
||||
log "📋 Копирование бинарных файлов и файла версии..."
|
||||
cp -r dist ./deploy/dist
|
||||
cp VERSION.txt ./deploy/VERSION.txt 2>/dev/null || echo "dev" > ./deploy/VERSION.txt
|
||||
|
||||
# Сборка для всех платформ
|
||||
log "🏗️ Сборка образа для платформ: $PLATFORMS"
|
||||
log "📦 Репозиторий: $REPOSITORY"
|
||||
log "🏷️ Версия: $VERSION"
|
||||
|
||||
# Сборка и push
|
||||
docker buildx build \
|
||||
--platform "$PLATFORMS" \
|
||||
--tag "$REPOSITORY:$VERSION" \
|
||||
--tag "$REPOSITORY:latest" \
|
||||
--push \
|
||||
--file deploy/Dockerfile \
|
||||
deploy/
|
||||
|
||||
# Очищаем скопированные файлы
|
||||
rm -rf ./deploy/dist
|
||||
|
||||
success "🎉 Образ успешно собран и отправлен в репозиторий!"
|
||||
|
||||
# Показываем информацию о собранном образе
|
||||
log "📊 Информация о собранном образе:"
|
||||
echo " Репозиторий: $REPOSITORY"
|
||||
echo " Версия: $VERSION"
|
||||
echo " Платформы: $PLATFORMS"
|
||||
echo " Теги: $REPOSITORY:$VERSION, $REPOSITORY:latest"
|
||||
|
||||
# Проверяем образы в репозитории
|
||||
log "🔍 Проверка образов в репозитории..."
|
||||
docker buildx imagetools inspect "$REPOSITORY:$VERSION" || warning "Не удалось проверить образ в репозитории"
|
||||
|
||||
success "🎉 Сборка завершена успешно!"
|
||||
|
||||
# Показываем команды для использования
|
||||
echo ""
|
||||
log "📝 Полезные команды:"
|
||||
echo " docker pull $REPOSITORY:$VERSION"
|
||||
echo " docker run -p 8080:8080 $REPOSITORY:$VERSION"
|
||||
echo " docker buildx imagetools inspect $REPOSITORY:$VERSION"
|
||||
202
deploy/6.full-build.sh
Executable file
202
deploy/6.full-build.sh
Executable file
@@ -0,0 +1,202 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🚀 LCG Full Build Script
|
||||
# Полный скрипт сборки: бинарные файлы + Docker образ
|
||||
|
||||
set -e
|
||||
|
||||
# Цвета для вывода
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Функция для вывода сообщений
|
||||
log() {
|
||||
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
# Параметры
|
||||
|
||||
REPOSITORY=${1:-"kuznetcovay/lcg"}
|
||||
VERSION=${2:-""}
|
||||
PLATFORMS=${3:-"linux/amd64,linux/arm64"}
|
||||
|
||||
if [ -z "$VERSION" ]; then
|
||||
error "Версия не указана! Использование: $0 <repository> <version> <platforms>"
|
||||
echo "Пример: $0 kuznetcovay/lcg v1.0.0 linux/amd64,linux/arm64"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Записываем версию в файл VERSION.txt (в корневой директории проекта)
|
||||
cd "$(dirname "$0")/.."
|
||||
echo "$VERSION" > VERSION.txt
|
||||
log "📝 Версия записана в VERSION.txt: $VERSION"
|
||||
|
||||
log "🚀 Полная сборка LCG (бинарные файлы + Docker образ)..."
|
||||
|
||||
# Этап 1: Сборка бинарных файлов
|
||||
log "📦 Этап 1: Сборка бинарных файлов с goreleaser..."
|
||||
./deploy/4.build-binaries.sh "$VERSION"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
error "Ошибка при сборке бинарных файлов"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
success "✅ Бинарные файлы собраны успешно"
|
||||
|
||||
# Этап 2: Сборка Docker образа
|
||||
log "🐳 Этап 2: Сборка Docker образа..."
|
||||
./deploy/5.build-docker.sh "$REPOSITORY" "$VERSION" "$PLATFORMS"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
error "Ошибка при сборке Docker образа"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
success "✅ Docker образы собраны успешно"
|
||||
|
||||
# Этап 3: Генерация deployment.yaml
|
||||
log "📝 Этап 3: Генерация deployment.yaml..."
|
||||
# Generate deployment.yaml with env substitution
|
||||
export REPOSITORY=$REPOSITORY
|
||||
export VERSION=$VERSION
|
||||
export PLATFORMS=$PLATFORMS
|
||||
export KUBECONFIG="${HOME}/.kube/config_hlab" && kubectx default
|
||||
|
||||
if ! envsubst < deploy/1.configmap.yaml > kustomize/configmap.yaml; then
|
||||
error "Ошибка при генерации deploy/1.configmap.yaml"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
success "✅ kustomize/configmap.yaml сгенерирован успешно"
|
||||
|
||||
if ! envsubst < deploy/deployment.tmpl.yaml > kustomize/deployment.yaml; then
|
||||
error "Ошибка при генерации kustomize/deployment.yaml"
|
||||
exit 1
|
||||
fi
|
||||
success "✅ kustomize/deployment.yaml сгенерирован успешно"
|
||||
|
||||
if ! envsubst < deploy/ingress-route.tmpl.yaml > kustomize/ingress-route.yaml; then
|
||||
error "Ошибка при генерации kustomize/ingress-route.yaml"
|
||||
exit 1
|
||||
fi
|
||||
success "✅ kustomize/ingress-route.yaml сгенерирован успешно"
|
||||
|
||||
if ! envsubst < deploy/service.tmpl.yaml > kustomize/service.yaml; then
|
||||
error "Ошибка при генерации kustomize/service.yaml"
|
||||
exit 1
|
||||
fi
|
||||
success "✅ kustomize/service.yaml сгенерирован успешно"
|
||||
|
||||
if ! envsubst < deploy/kustomization.tmpl.yaml > kustomize/kustomization.yaml; then
|
||||
error "Ошибка при генерации kustomize/kustomization.yaml"
|
||||
exit 1
|
||||
fi
|
||||
success "✅ kustomize/kustomization.yaml сгенерирован успешно"
|
||||
|
||||
# отключить reconciliation flux
|
||||
if kubectl get kustomization lcg -n flux-system > /dev/null 2>&1; then
|
||||
kubectl patch kustomization lcg -n flux-system --type=merge -p '{"spec":{"suspend":true}}'
|
||||
else
|
||||
echo "ℹ️ Kustomization 'lcg' does not exist in 'flux-system' namespace. Skipping suspend."
|
||||
fi
|
||||
sleep 5
|
||||
|
||||
|
||||
# зафиксировать изменения в текущей ветке, если она не main
|
||||
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [ "$current_branch" != "main" ]; then
|
||||
log "🔧 Исправления в текущей ветке: $current_branch"
|
||||
# считать, что изменения уже сделаны
|
||||
git add .
|
||||
git commit -m "Исправления в ветке $current_branch"
|
||||
fi
|
||||
|
||||
# переключиться на ветку main и слить с текущей веткой, если не находимся на main
|
||||
if [ "$current_branch" != "main" ]; then
|
||||
git checkout main
|
||||
git merge --no-ff -m "Merged branch '$current_branch' into main while building $VERSION" "$current_branch"
|
||||
fi
|
||||
|
||||
# переключиться на ветку release и слить с веткой main
|
||||
git checkout -b release
|
||||
git merge --no-ff -m "Merged main into release while building $VERSION" main
|
||||
|
||||
# если тег $VERSION существует, удалить его и принудительно запушить
|
||||
tag_exists=$(git tag -l "$VERSION")
|
||||
if [ "$tag_exists" ]; then
|
||||
log "🗑️ Удаление существующего тега $VERSION"
|
||||
git tag -d "$VERSION"
|
||||
git push origin ":refs/tags/$VERSION"
|
||||
fi
|
||||
|
||||
# Create tag $VERSION and push to remote release branch and all tags
|
||||
git tag "$VERSION"
|
||||
git push origin release
|
||||
git push origin --tags
|
||||
|
||||
# Push main branch
|
||||
git checkout main
|
||||
git push origin main
|
||||
|
||||
|
||||
# Включить reconciliation flux
|
||||
if kubectl get kustomization lcg -n flux-system > /dev/null 2>&1; then
|
||||
kubectl patch kustomization lcg -n flux-system --type=merge -p '{"spec":{"suspend":false}}'
|
||||
else
|
||||
echo "ℹ️ Kustomization 'lcg' does not exist in 'flux-system' namespace. Skipping suspend."
|
||||
fi
|
||||
echo "🔄 Flux will automatically deploy $VERSION version in ~4-6 minutes..."
|
||||
|
||||
# Итоговая информация
|
||||
echo ""
|
||||
log "🎉 Полная сборка завершена успешно!"
|
||||
echo ""
|
||||
log "📊 Результат:"
|
||||
echo " Репозиторий: $REPOSITORY"
|
||||
echo " Версия: $VERSION"
|
||||
echo " Платформы: $PLATFORMS"
|
||||
echo " Теги: $REPOSITORY:$VERSION, $REPOSITORY:latest"
|
||||
echo ""
|
||||
echo ""
|
||||
log "🔍 Информация о git коммитах:"
|
||||
git_log=$(git log release -1 --pretty=format:"%H - %s")
|
||||
echo "$git_log"
|
||||
echo ""
|
||||
|
||||
|
||||
log "📝 Команды для использования:"
|
||||
echo " docker pull $REPOSITORY:$VERSION"
|
||||
echo " docker run -p 8080:8080 $REPOSITORY:$VERSION"
|
||||
echo " docker buildx imagetools inspect $REPOSITORY:$VERSION"
|
||||
echo ""
|
||||
log "🔍 Проверка образа:"
|
||||
echo " docker run --rm $REPOSITORY:$VERSION /app/lcg --version"
|
||||
echo ""
|
||||
log "📝 Команды для использования:"
|
||||
echo " kubectl apply -k kustomize"
|
||||
echo " kubectl get pods"
|
||||
echo " kubectl get services"
|
||||
echo " kubectl get ingress"
|
||||
echo " kubectl get hpa"
|
||||
echo " kubectl get servicemonitor"
|
||||
echo " kubectl get pods"
|
||||
echo " kubectl get services"
|
||||
echo " kubectl get ingress"
|
||||
echo " kubectl get hpa"
|
||||
echo " kubectl get servicemonitor"
|
||||
39
deploy/Dockerfile
Normal file
39
deploy/Dockerfile
Normal file
@@ -0,0 +1,39 @@
|
||||
# Однофазный build для LCG с предварительно собранным бинарным файлом
|
||||
FROM alpine:3.22.2
|
||||
|
||||
# Устанавливаем зависимости
|
||||
RUN apk --no-cache add ca-certificates tzdata
|
||||
|
||||
# Создаем пользователя
|
||||
RUN adduser -D -s /bin/sh lcg
|
||||
|
||||
# Создаем директории и файлы
|
||||
RUN mkdir -p /app/data /app/config /home/lcg/.config/lcg/gpt_results /home/lcg/.config/lcg/gpt_sys_prompts && \
|
||||
echo '[]' > /home/lcg/.config/lcg/gpt_results/lcg_history.json && \
|
||||
chown -R lcg:lcg /app /home/lcg/.config
|
||||
|
||||
# Копируем файл версии
|
||||
COPY VERSION.txt /app/VERSION.txt
|
||||
|
||||
# Копируем предварительно собранный бинарный файл
|
||||
# Ищем папку с бинарным файлом для текущей архитектуры
|
||||
COPY dist/lcg_linux_${TARGETARCH}*/lcg_* /app/lcg
|
||||
|
||||
# Устанавливаем права
|
||||
RUN chmod +x /app/lcg
|
||||
|
||||
# Переключаемся на пользователя lcg
|
||||
USER lcg
|
||||
|
||||
# Устанавливаем рабочую директорию
|
||||
WORKDIR /app
|
||||
|
||||
# Открываем порт
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/login || exit 1
|
||||
|
||||
# Запускаем приложение
|
||||
CMD ["./lcg", "serve", "-H", "0.0.0.0", "-p", "8080"]
|
||||
1
deploy/VERSION.txt
Normal file
1
deploy/VERSION.txt
Normal file
@@ -0,0 +1 @@
|
||||
v2.0.2
|
||||
95
deploy/deployment.tmpl.yaml
Normal file
95
deploy/deployment.tmpl.yaml
Normal file
@@ -0,0 +1,95 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: lcg
|
||||
namespace: lcg
|
||||
labels:
|
||||
app: lcg
|
||||
version: ${VERSION}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: lcg
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: lcg
|
||||
version: ${VERSION}
|
||||
spec:
|
||||
containers:
|
||||
- name: lcg
|
||||
image: ${REPOSITORY}:${VERSION}
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
protocol: TCP
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: lcg-config
|
||||
- secretRef:
|
||||
name: lcg-secret
|
||||
env:
|
||||
# Pod information
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
volumeMounts:
|
||||
- name: lcg-data
|
||||
mountPath: /app/data
|
||||
- name: lcg-config
|
||||
mountPath: /app/config
|
||||
readOnly: true
|
||||
# Health checks
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /login
|
||||
port: 8080
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
failureThreshold: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /login
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /login
|
||||
port: 8080
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 60
|
||||
volumes:
|
||||
- name: lcg-data
|
||||
persistentVolumeClaim:
|
||||
claimName: lcg-data
|
||||
- name: lcg-config
|
||||
configMap:
|
||||
name: lcg-config
|
||||
# Security context
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
readOnlyRootFilesystem: false
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
restartPolicy: Always
|
||||
42
deploy/hpa.yaml
Normal file
42
deploy/hpa.yaml
Normal file
@@ -0,0 +1,42 @@
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: lcg-hpa
|
||||
namespace: lcg
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: lcg
|
||||
minReplicas: 2
|
||||
maxReplicas: 10
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 80
|
||||
behavior:
|
||||
scaleDown:
|
||||
stabilizationWindowSeconds: 300
|
||||
policies:
|
||||
- type: Percent
|
||||
value: 10
|
||||
periodSeconds: 60
|
||||
scaleUp:
|
||||
stabilizationWindowSeconds: 60
|
||||
policies:
|
||||
- type: Percent
|
||||
value: 50
|
||||
periodSeconds: 60
|
||||
- type: Pods
|
||||
value: 2
|
||||
periodSeconds: 60
|
||||
selectPolicy: Max
|
||||
64
deploy/ingress-route.tmpl.yaml
Normal file
64
deploy/ingress-route.tmpl.yaml
Normal file
@@ -0,0 +1,64 @@
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lcg-route
|
||||
namespace: lcg
|
||||
labels:
|
||||
app: lcg
|
||||
version: ${VERSION}
|
||||
spec:
|
||||
entryPoints:
|
||||
- websecure
|
||||
routes:
|
||||
- kind: Rule
|
||||
match: Host(`direct-dev.ru`) && PathPrefix(`/lcg`)
|
||||
services:
|
||||
- name: lcg
|
||||
port: 8080
|
||||
tls:
|
||||
secretName: le-root-direct-dev-ru
|
||||
---
|
||||
|
||||
# apiVersion: traefik.io/v1alpha1
|
||||
# kind: IngressRoute
|
||||
# metadata:
|
||||
# name: lcg-route
|
||||
# namespace: lcg
|
||||
# spec:
|
||||
# entryPoints:
|
||||
# - websecure
|
||||
# routes:
|
||||
# - kind: Rule
|
||||
# match: Host(`direct-dev.ru`) && PathPrefix(`/lcg`)
|
||||
# services:
|
||||
# - name: lcg
|
||||
# port: 8080
|
||||
# middlewares:
|
||||
# - name: lcg-strip-prefix
|
||||
# tls:
|
||||
# secretName: le-root-direct-dev-ru
|
||||
# ---
|
||||
# apiVersion: traefik.io/v1alpha1
|
||||
# kind: Middleware
|
||||
# metadata:
|
||||
# name: lcg-strip-prefix
|
||||
# namespace: lcg
|
||||
# spec:
|
||||
# stripPrefix:
|
||||
# prefixes:
|
||||
# - /lcg
|
||||
# ---
|
||||
# apiVersion: traefik.io/v1alpha1
|
||||
# kind: Middleware
|
||||
# metadata:
|
||||
# name: lcg-headers
|
||||
# namespace: lcg
|
||||
# spec:
|
||||
# headers:
|
||||
# customRequestHeaders:
|
||||
# X-Forwarded-Proto: "https"
|
||||
# X-Forwarded-Port: "443"
|
||||
# customResponseHeaders:
|
||||
# X-Frame-Options: "DENY"
|
||||
# X-Content-Type-Options: "nosniff"
|
||||
# X-XSS-Protection: "1; mode=block"
|
||||
25
deploy/kustomization.tmpl.yaml
Normal file
25
deploy/kustomization.tmpl.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
# Namespace
|
||||
namespace: lcg
|
||||
|
||||
# Resources
|
||||
resources:
|
||||
- configmap.yaml
|
||||
- secret.yaml
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
- ingress-route.yaml
|
||||
|
||||
# Common labels
|
||||
commonLabels:
|
||||
app: lcg
|
||||
version: ${VERSION}
|
||||
managed-by: kustomize
|
||||
|
||||
# Images
|
||||
images:
|
||||
- name: lcg
|
||||
newName: ${REPOSITORY}
|
||||
newTag: ${VERSION}
|
||||
18
deploy/service.tmpl.yaml
Normal file
18
deploy/service.tmpl.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: lcg
|
||||
namespace: lcg
|
||||
labels:
|
||||
app: lcg
|
||||
version: ${VERSION}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: lcg
|
||||
version: ${VERSION}
|
||||
Reference in New Issue
Block a user