chore: сохранение текущих изменений (deploy local-bundle/local-jar, request-service, slots UI markedObjectIds)
Безопасный коммит незакоммиченной работы перед реализацией бронирования слотов. Вне коммита оставлены: package-lock.json (пустой, мусор), requests.json (scratch-данные).
This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
COMPOSE_PROJECT_NAME=pcp-local
|
||||
|
||||
USE_EXTERNAL_INFRA=false
|
||||
PCP_DOCKER_NETWORK=pcp-local_default
|
||||
PCP_DOCKER_NETWORK_EXTERNAL=false
|
||||
|
||||
# Existing allinone infra example:
|
||||
# USE_EXTERNAL_INFRA=true
|
||||
# PCP_DOCKER_NETWORK=allinone_camunda
|
||||
# PCP_DOCKER_NETWORK_EXTERNAL=true
|
||||
# EXTERNAL_POSTGRES_CONTAINER=allinone-postgres-1
|
||||
# EXTERNAL_KAFKA_CONTAINER=allinone-kafka-1
|
||||
# CAMUNDA_CLIENT_ENABLED=true
|
||||
# CAMUNDA_GRPC_ADDRESS=http://orchestration:26500
|
||||
|
||||
PCP_IMAGE_TAG=local
|
||||
|
||||
POSTGRES_IMAGE=postgis/postgis:16-3.4
|
||||
@@ -8,14 +21,24 @@ KAFKA_IMAGE=apache/kafka:3.7.2
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=password
|
||||
POSTGRES_PORT=5432
|
||||
PCP_POSTGRES_HOST=postgres
|
||||
PCP_POSTGRES_PORT=5432
|
||||
EXTERNAL_POSTGRES_CONTAINER=
|
||||
|
||||
KAFKA_PORT=29092
|
||||
PCP_KAFKA_HOST=kafka
|
||||
PCP_KAFKA_PORT=9092
|
||||
EXTERNAL_KAFKA_CONTAINER=
|
||||
|
||||
CAMUNDA_CLIENT_ENABLED=false
|
||||
CAMUNDA_GRPC_ADDRESS=http://host.docker.internal:26500
|
||||
|
||||
CONFIG_SERVER_PORT=38888
|
||||
|
||||
PCP_ADMIN_PORT=7000
|
||||
PCP_TLE_MONITORING_PORT=7001
|
||||
PCP_COMPLEX_MISSION_PORT=7002
|
||||
PCP_BALLISTICS_PORT=7003
|
||||
PCP_ROUTE_PROCESSING_PORT=7004
|
||||
PCP_REQUEST_PORT=7005
|
||||
PCP_SLOTS_PORT=7006
|
||||
PCP_UI_PORT=7008
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
Локальный bundle предназначен для запуска PCP на машине с Docker без GitLab Config Repo, Kubernetes и Helm.
|
||||
|
||||
В bundle входят backend-сервисы PCP, кроме `tle-monitoring-service`; отдельный frontend
|
||||
`pcp-tgu-ops-ui` также не включается.
|
||||
|
||||
## Состав
|
||||
|
||||
- `docker-compose.yml` - локальная схема запуска.
|
||||
@@ -15,6 +18,72 @@
|
||||
- `scripts/stop.sh` - остановка compose stack.
|
||||
- `scripts/status.sh` - статус контейнеров.
|
||||
|
||||
## Локальный запуск без архива
|
||||
|
||||
Для запуска на той же машине, где собираются images, архив и `docker save` не нужны.
|
||||
Используйте один скрипт:
|
||||
|
||||
```bash
|
||||
./deploy/local-bundle/run-local.sh start
|
||||
```
|
||||
|
||||
Скрипт:
|
||||
|
||||
- создаёт `.env` из `.env.example`, если его ещё нет;
|
||||
- собирает `bootJar` в Gradle offline mode;
|
||||
- собирает локальные Docker images `pcp/<service>:<PCP_IMAGE_TAG>`;
|
||||
- запускает `docker compose`.
|
||||
|
||||
Для вашего allinone Postgres/Kafka/Camunda перед первым запуском настройте
|
||||
`deploy/local-bundle/.env`:
|
||||
|
||||
```env
|
||||
USE_EXTERNAL_INFRA=true
|
||||
PCP_DOCKER_NETWORK=allinone_camunda
|
||||
PCP_DOCKER_NETWORK_EXTERNAL=true
|
||||
PCP_POSTGRES_HOST=postgres
|
||||
PCP_POSTGRES_PORT=5432
|
||||
PCP_KAFKA_HOST=kafka
|
||||
PCP_KAFKA_PORT=9092
|
||||
EXTERNAL_POSTGRES_CONTAINER=allinone-postgres-1
|
||||
EXTERNAL_KAFKA_CONTAINER=allinone-kafka-1
|
||||
CAMUNDA_CLIENT_ENABLED=true
|
||||
CAMUNDA_GRPC_ADDRESS=http://orchestration:26500
|
||||
```
|
||||
|
||||
Команды:
|
||||
|
||||
```bash
|
||||
./deploy/local-bundle/run-local.sh start
|
||||
./deploy/local-bundle/run-local.sh status
|
||||
./deploy/local-bundle/run-local.sh logs
|
||||
./deploy/local-bundle/run-local.sh stop
|
||||
```
|
||||
|
||||
## Пересборка одного сервиса
|
||||
|
||||
После первого запуска всего стека можно пересобирать и перезапускать только один сервис:
|
||||
|
||||
```bash
|
||||
./deploy/local-bundle/services/pcp-request-service.sh
|
||||
```
|
||||
|
||||
Это выполнит:
|
||||
|
||||
- `bootJar` только для `pcp-request-service`;
|
||||
- `docker build` только для `pcp/pcp-request-service:<PCP_IMAGE_TAG>`;
|
||||
- `docker compose up -d --no-deps --force-recreate pcp-request-service`.
|
||||
|
||||
Доступны wrapper-скрипты в `deploy/local-bundle/services/` для каждого сервиса.
|
||||
То же самое можно вызвать через общий скрипт:
|
||||
|
||||
```bash
|
||||
./deploy/local-bundle/run-service.sh pcp-request-service
|
||||
./deploy/local-bundle/run-service.sh pcp-request-service build
|
||||
./deploy/local-bundle/run-service.sh pcp-request-service logs
|
||||
./deploy/local-bundle/run-service.sh pcp-request-service stop
|
||||
```
|
||||
|
||||
## Сборка архива
|
||||
|
||||
Из корня репозитория:
|
||||
@@ -38,6 +107,7 @@ deploy/local-bundle/build/pcp-local-bundle-<version>.tar.gz
|
||||
Скрипт сборки:
|
||||
|
||||
- собирает `bootJar` для разворачиваемых сервисов;
|
||||
- запускает Gradle в offline mode по умолчанию;
|
||||
- собирает Docker images сервисов;
|
||||
- сохраняет PCP service images в один `images/pcp-services.tar`;
|
||||
- по умолчанию не сохраняет публичные infra images, чтобы не раздувать архив;
|
||||
@@ -61,6 +131,41 @@ KOTLIN_DAEMON_JVMARGS="-Xmx3g -XX:MaxMetaspaceSize=768m" \
|
||||
./deploy/local-bundle/build-local-bundle.sh
|
||||
```
|
||||
|
||||
Gradle offline mode включён по умолчанию:
|
||||
|
||||
```bash
|
||||
GRADLE_OFFLINE=true ./deploy/local-bundle/build-local-bundle.sh
|
||||
```
|
||||
|
||||
Если нужно один раз прогреть локальный Gradle cache, временно отключите offline mode:
|
||||
|
||||
```bash
|
||||
GRADLE_OFFLINE=false ./deploy/local-bundle/build-local-bundle.sh
|
||||
```
|
||||
|
||||
Важно: `GRADLE_OFFLINE=true` отключает сетевой резолв зависимостей Gradle, но Docker всё равно
|
||||
должен иметь локально доступный base image. Для local bundle сервисные Dockerfile собираются с
|
||||
локальным override:
|
||||
|
||||
```text
|
||||
LOCAL_BUNDLE_RUNTIME_IMAGE=bellsoft/liberica-openjre-alpine:21.0.5
|
||||
```
|
||||
|
||||
Поэтому перед полностью offline Docker-сборкой подтяните или импортируйте:
|
||||
|
||||
```bash
|
||||
docker pull bellsoft/liberica-openjre-alpine:21.0.5
|
||||
```
|
||||
|
||||
Для полностью переносимого архива с infra images заранее подтяните Postgres/Kafka и включите их
|
||||
сохранение:
|
||||
|
||||
```bash
|
||||
docker pull postgis/postgis:16-3.4
|
||||
docker pull apache/kafka:3.7.2
|
||||
INCLUDE_INFRA_IMAGES=true ./deploy/local-bundle/build-local-bundle.sh
|
||||
```
|
||||
|
||||
## Запуск на локальной машине
|
||||
|
||||
Распаковать архив:
|
||||
@@ -72,6 +177,26 @@ cd pcp-local-bundle-<version>
|
||||
|
||||
Проверить `.env` и при необходимости изменить порты.
|
||||
|
||||
Если Postgres/Kafka/Camunda уже подняты внешним allinone compose, например в сети
|
||||
`allinone_camunda`, включите external infra mode в `.env`:
|
||||
|
||||
```env
|
||||
USE_EXTERNAL_INFRA=true
|
||||
PCP_DOCKER_NETWORK=allinone_camunda
|
||||
PCP_DOCKER_NETWORK_EXTERNAL=true
|
||||
PCP_POSTGRES_HOST=postgres
|
||||
PCP_POSTGRES_PORT=5432
|
||||
PCP_KAFKA_HOST=kafka
|
||||
PCP_KAFKA_PORT=9092
|
||||
EXTERNAL_POSTGRES_CONTAINER=allinone-postgres-1
|
||||
EXTERNAL_KAFKA_CONTAINER=allinone-kafka-1
|
||||
CAMUNDA_CLIENT_ENABLED=true
|
||||
CAMUNDA_GRPC_ADDRESS=http://orchestration:26500
|
||||
```
|
||||
|
||||
В этом режиме `scripts/start.sh` не поднимает свои `postgres` и `kafka`, а сервисы PCP
|
||||
подключаются к уже существующим контейнерам через общую Docker network.
|
||||
|
||||
Импортировать images:
|
||||
|
||||
```bash
|
||||
@@ -109,9 +234,9 @@ cd pcp-local-bundle-<version>
|
||||
|
||||
- Config Server: `http://localhost:38888`
|
||||
- Spring Boot Admin: `http://localhost:7000`
|
||||
- TLE Monitoring: `http://localhost:7001`
|
||||
- Complex Mission: `http://localhost:7002`
|
||||
- Ballistics: `http://localhost:7003`
|
||||
- Route Processing: `http://localhost:7004`
|
||||
- Request Service: `http://localhost:7005`
|
||||
- Slots Service: `http://localhost:7006`
|
||||
- UI: `http://localhost:7008`
|
||||
@@ -178,13 +303,13 @@ SPRING_CLOUD_CONFIG_LABEL=
|
||||
|
||||
- `pcp_ballistics`
|
||||
- `pcp_requests`
|
||||
- `pcp_route_processing`
|
||||
- `pcp_missions`
|
||||
- `pcp_slots`
|
||||
- `pcp_complex_plan`
|
||||
- `pcp_satellite_catalog`
|
||||
- `pcp_stations`
|
||||
- `pcp_tgu`
|
||||
- `pcp_tle`
|
||||
- `pcp_satellites`
|
||||
|
||||
Таблицы, схемы и seed data вручную не создаются. Схемы создаются существующими Flyway migrations внутри сервисов при старте приложений.
|
||||
|
||||
@@ -26,6 +26,7 @@ service_names=(
|
||||
pcp-satellite-catalog-service
|
||||
pcp-ballistics-service
|
||||
pcp-request-service
|
||||
pcp-route-processing-service
|
||||
slots-service
|
||||
pcp-complex-mission-service
|
||||
pcp-mission-planing-service
|
||||
@@ -33,13 +34,14 @@ service_names=(
|
||||
pcp-dynamic-plan-service
|
||||
pcp-stations-service
|
||||
pcp-ui-service
|
||||
tle-monitoring-service
|
||||
pcp-tgu-service
|
||||
)
|
||||
|
||||
gradle_max_workers="${GRADLE_MAX_WORKERS:-1}"
|
||||
gradle_jvmargs="${GRADLE_JVMARGS:--Xmx2g -Dfile.encoding=UTF-8}"
|
||||
kotlin_daemon_jvmargs="${KOTLIN_DAEMON_JVMARGS:--Xmx3g -XX:MaxMetaspaceSize=768m}"
|
||||
gradle_offline="${GRADLE_OFFLINE:-true}"
|
||||
runtime_image="${LOCAL_BUNDLE_RUNTIME_IMAGE:-bellsoft/liberica-openjre-alpine:21.0.5}"
|
||||
include_infra_images="${INCLUDE_INFRA_IMAGES:-false}"
|
||||
|
||||
gradle_common_args=(
|
||||
@@ -49,6 +51,10 @@ gradle_common_args=(
|
||||
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
|
||||
)
|
||||
|
||||
if [[ "$gradle_offline" == "true" ]]; then
|
||||
gradle_common_args+=("--offline")
|
||||
fi
|
||||
|
||||
infra_images=(
|
||||
"${POSTGRES_IMAGE:-postgis/postgis:16-3.4}"
|
||||
"${KAFKA_IMAGE:-apache/kafka:3.7.2}"
|
||||
@@ -117,9 +123,11 @@ echo "Building bootJar artifacts..."
|
||||
echo "Gradle max workers: $gradle_max_workers"
|
||||
echo "Gradle JVM args: $gradle_jvmargs"
|
||||
echo "Kotlin daemon JVM args: $kotlin_daemon_jvmargs"
|
||||
echo "Gradle offline mode: $gradle_offline"
|
||||
echo "Local bundle runtime image: $runtime_image"
|
||||
for service_name in "${service_names[@]}"; do
|
||||
echo "Building bootJar for $service_name..."
|
||||
"$repo_root/gradlew" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
|
||||
"$repo_root/gradlew" --project-dir "$repo_root" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
|
||||
done
|
||||
|
||||
rm -rf "$dist_dir" "$docker_contexts_dir" "$archive_path"
|
||||
@@ -132,7 +140,11 @@ for service_name in "${service_names[@]}"; do
|
||||
context_dir="$docker_contexts_dir/$service_name"
|
||||
|
||||
copy_single_boot_jar "$service_name" "$context_dir"
|
||||
docker build --file "$context_dir/Dockerfile" --tag "$image_name" "$context_dir"
|
||||
docker build \
|
||||
--build-arg "RUNTIME_IMAGE=$runtime_image" \
|
||||
--file "$context_dir/Dockerfile" \
|
||||
--tag "$image_name" \
|
||||
"$context_dir"
|
||||
service_images+=("$image_name")
|
||||
done
|
||||
|
||||
|
||||
@@ -8,9 +8,17 @@ x-pcp-service-env: &pcp-service-env
|
||||
SPRING_CLOUD_CONFIG_LABEL: ""
|
||||
SPRING_KAFKA_ADMIN_AUTO_CREATE: "true"
|
||||
SPRING_KAFKA_LISTENER_AUTO_STARTUP: "true"
|
||||
PCP_POSTGRES_HOST: ${PCP_POSTGRES_HOST:-postgres}
|
||||
PCP_POSTGRES_PORT: ${PCP_POSTGRES_PORT:-5432}
|
||||
PCP_KAFKA_HOST: ${PCP_KAFKA_HOST:-kafka}
|
||||
PCP_KAFKA_PORT: ${PCP_KAFKA_PORT:-9092}
|
||||
CAMUNDA_CLIENT_ENABLED: ${CAMUNDA_CLIENT_ENABLED:-false}
|
||||
CAMUNDA_GRPC_ADDRESS: ${CAMUNDA_GRPC_ADDRESS:-http://host.docker.internal:26500}
|
||||
|
||||
x-pcp-service-common: &pcp-service-common
|
||||
restart: unless-stopped
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
depends_on:
|
||||
spring-cloud-config-server:
|
||||
condition: service_started
|
||||
@@ -64,11 +72,8 @@ services:
|
||||
spring-cloud-config-server:
|
||||
image: pcp/spring-cloud-config-server:${PCP_IMAGE_TAG:-local}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: local
|
||||
CONFIG_NATIVE_SEARCH_LOCATIONS: file:/config-repo
|
||||
@@ -86,14 +91,6 @@ services:
|
||||
ports:
|
||||
- "${PCP_ADMIN_PORT:-7000}:7000"
|
||||
|
||||
tle-monitoring-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/tle-monitoring-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_TLE_MONITORING_PORT:-7001}:7001"
|
||||
|
||||
pcp-complex-mission-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-complex-mission-service:${PCP_IMAGE_TAG:-local}
|
||||
@@ -118,6 +115,14 @@ services:
|
||||
ports:
|
||||
- "${PCP_REQUEST_PORT:-7005}:7005"
|
||||
|
||||
pcp-route-processing-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-route-processing-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_ROUTE_PROCESSING_PORT:-7004}:7004"
|
||||
|
||||
slots-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/slots-service:${PCP_IMAGE_TAG:-local}
|
||||
@@ -193,3 +198,8 @@ services:
|
||||
volumes:
|
||||
postgres-data:
|
||||
kafka-data:
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: ${PCP_DOCKER_NETWORK:-pcp-local_default}
|
||||
external: ${PCP_DOCKER_NETWORK_EXTERNAL:-false}
|
||||
|
||||
Executable
+199
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "$script_dir/../.." && pwd)"
|
||||
env_file="$script_dir/.env"
|
||||
env_example_file="$script_dir/.env.example"
|
||||
docker_contexts_dir="$script_dir/build/local-docker-contexts"
|
||||
|
||||
service_names=(
|
||||
spring-cloud-config-server
|
||||
pcp-srpring-boot-admin-server
|
||||
pcp-satellite-catalog-service
|
||||
pcp-ballistics-service
|
||||
pcp-request-service
|
||||
pcp-route-processing-service
|
||||
slots-service
|
||||
pcp-complex-mission-service
|
||||
pcp-mission-planing-service
|
||||
pcp-coverage-scheme-service
|
||||
pcp-dynamic-plan-service
|
||||
pcp-stations-service
|
||||
pcp-ui-service
|
||||
pcp-tgu-service
|
||||
)
|
||||
|
||||
ensure_env_file() {
|
||||
if [[ ! -f "$env_file" && -f "$env_example_file" ]]; then
|
||||
cp "$env_example_file" "$env_file"
|
||||
echo "Created $env_file from .env.example"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_source_config_repo_dir() {
|
||||
if grep -q '^CONFIG_REPO_DIR=' "$env_file"; then
|
||||
sed -i "s#^CONFIG_REPO_DIR=.*#CONFIG_REPO_DIR=$repo_root/config-repo#" "$env_file"
|
||||
else
|
||||
printf '\nCONFIG_REPO_DIR=%s/config-repo\n' "$repo_root" >> "$env_file"
|
||||
fi
|
||||
}
|
||||
|
||||
load_env() {
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$env_file"
|
||||
set +a
|
||||
}
|
||||
|
||||
require_command() {
|
||||
local command_name="$1"
|
||||
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||
echo "$command_name is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose --project-directory "$script_dir" -f "$script_dir/docker-compose.yml" "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose --project-directory "$script_dir" -f "$script_dir/docker-compose.yml" "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
copy_single_boot_jar() {
|
||||
local service_name="$1"
|
||||
local context_dir="$2"
|
||||
local jar_count
|
||||
local jar_file
|
||||
|
||||
jar_count="$(
|
||||
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | wc -l
|
||||
)"
|
||||
|
||||
if [[ "$jar_count" != "1" ]]; then
|
||||
echo "Expected exactly one bootJar for $service_name, found $jar_count:" >&2
|
||||
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' -print >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jar_file="$(
|
||||
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | head -n 1
|
||||
)"
|
||||
|
||||
mkdir -p "$context_dir/build/libs"
|
||||
cp "$repo_root/services/$service_name/Dockerfile" "$context_dir/Dockerfile"
|
||||
cp "$jar_file" "$context_dir/build/libs/app.jar"
|
||||
}
|
||||
|
||||
build_images() {
|
||||
local gradle_max_workers="${GRADLE_MAX_WORKERS:-1}"
|
||||
local gradle_jvmargs="${GRADLE_JVMARGS:--Xmx2g -Dfile.encoding=UTF-8}"
|
||||
local kotlin_daemon_jvmargs="${KOTLIN_DAEMON_JVMARGS:--Xmx3g -XX:MaxMetaspaceSize=768m}"
|
||||
local gradle_offline="${GRADLE_OFFLINE:-true}"
|
||||
local runtime_image="${LOCAL_BUNDLE_RUNTIME_IMAGE:-bellsoft/liberica-openjre-alpine:21.0.5}"
|
||||
local image_tag="${PCP_IMAGE_TAG:-local}"
|
||||
local service_name
|
||||
local image_name
|
||||
local context_dir
|
||||
local gradle_common_args=(
|
||||
"--no-parallel"
|
||||
"--max-workers=$gradle_max_workers"
|
||||
"-Dorg.gradle.jvmargs=$gradle_jvmargs"
|
||||
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
|
||||
)
|
||||
|
||||
if [[ "$gradle_offline" == "true" ]]; then
|
||||
gradle_common_args+=("--offline")
|
||||
fi
|
||||
|
||||
echo "Building local Docker images..."
|
||||
echo "Gradle offline mode: $gradle_offline"
|
||||
echo "Local image tag: $image_tag"
|
||||
echo "Runtime image: $runtime_image"
|
||||
|
||||
for service_name in "${service_names[@]}"; do
|
||||
echo "Building bootJar for $service_name..."
|
||||
"$repo_root/gradlew" --project-dir "$repo_root" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
|
||||
done
|
||||
|
||||
rm -rf "$docker_contexts_dir"
|
||||
mkdir -p "$docker_contexts_dir"
|
||||
|
||||
for service_name in "${service_names[@]}"; do
|
||||
image_name="pcp/$service_name:$image_tag"
|
||||
context_dir="$docker_contexts_dir/$service_name"
|
||||
|
||||
copy_single_boot_jar "$service_name" "$context_dir"
|
||||
echo "Building Docker image $image_name..."
|
||||
docker build \
|
||||
--build-arg "RUNTIME_IMAGE=$runtime_image" \
|
||||
--file "$context_dir/Dockerfile" \
|
||||
--tag "$image_name" \
|
||||
"$context_dir"
|
||||
done
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./deploy/local-bundle/run-local.sh [command]
|
||||
|
||||
Commands:
|
||||
start Build service images locally and start docker compose.
|
||||
restart Stop compose stack, then build and start.
|
||||
build Build service images locally, without starting compose.
|
||||
stop Stop compose stack.
|
||||
status Show compose status.
|
||||
logs Follow compose logs.
|
||||
EOF
|
||||
}
|
||||
|
||||
start_local() {
|
||||
build_images
|
||||
"$script_dir/scripts/start.sh"
|
||||
}
|
||||
|
||||
command="${1:-start}"
|
||||
case "$command" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
ensure_env_file
|
||||
ensure_source_config_repo_dir
|
||||
load_env
|
||||
require_command docker
|
||||
|
||||
case "$command" in
|
||||
start)
|
||||
start_local
|
||||
;;
|
||||
restart)
|
||||
"$script_dir/scripts/stop.sh"
|
||||
start_local
|
||||
;;
|
||||
build)
|
||||
build_images
|
||||
;;
|
||||
stop)
|
||||
"$script_dir/scripts/stop.sh"
|
||||
;;
|
||||
status)
|
||||
"$script_dir/scripts/status.sh"
|
||||
;;
|
||||
logs)
|
||||
compose logs -f
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Executable
+242
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "$script_dir/../.." && pwd)"
|
||||
env_file="$script_dir/.env"
|
||||
env_example_file="$script_dir/.env.example"
|
||||
docker_contexts_dir="$script_dir/build/local-docker-contexts"
|
||||
|
||||
service_names=(
|
||||
spring-cloud-config-server
|
||||
pcp-srpring-boot-admin-server
|
||||
pcp-satellite-catalog-service
|
||||
pcp-ballistics-service
|
||||
pcp-request-service
|
||||
pcp-route-processing-service
|
||||
slots-service
|
||||
pcp-complex-mission-service
|
||||
pcp-mission-planing-service
|
||||
pcp-coverage-scheme-service
|
||||
pcp-dynamic-plan-service
|
||||
pcp-stations-service
|
||||
pcp-ui-service
|
||||
pcp-tgu-service
|
||||
)
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./deploy/local-bundle/run-service.sh SERVICE [command]
|
||||
|
||||
Commands:
|
||||
restart Build SERVICE bootJar, rebuild its Docker image and recreate only this compose service.
|
||||
build Build SERVICE bootJar and Docker image, without restarting container.
|
||||
stop Stop SERVICE container.
|
||||
logs Follow SERVICE logs.
|
||||
|
||||
Examples:
|
||||
./deploy/local-bundle/run-service.sh pcp-request-service
|
||||
./deploy/local-bundle/run-service.sh pcp-request-service build
|
||||
EOF
|
||||
}
|
||||
|
||||
ensure_env_file() {
|
||||
if [[ ! -f "$env_file" && -f "$env_example_file" ]]; then
|
||||
cp "$env_example_file" "$env_file"
|
||||
echo "Created $env_file from .env.example"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_source_config_repo_dir() {
|
||||
if grep -q '^CONFIG_REPO_DIR=' "$env_file"; then
|
||||
sed -i "s#^CONFIG_REPO_DIR=.*#CONFIG_REPO_DIR=$repo_root/config-repo#" "$env_file"
|
||||
else
|
||||
printf '\nCONFIG_REPO_DIR=%s/config-repo\n' "$repo_root" >> "$env_file"
|
||||
fi
|
||||
}
|
||||
|
||||
load_env() {
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$env_file"
|
||||
set +a
|
||||
}
|
||||
|
||||
require_command() {
|
||||
local command_name="$1"
|
||||
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||
echo "$command_name is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose --project-directory "$script_dir" -f "$script_dir/docker-compose.yml" "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose --project-directory "$script_dir" -f "$script_dir/docker-compose.yml" "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_known_service() {
|
||||
local service_name="$1"
|
||||
local known_service_name
|
||||
|
||||
for known_service_name in "${service_names[@]}"; do
|
||||
if [[ "$known_service_name" == "$service_name" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
copy_single_boot_jar() {
|
||||
local service_name="$1"
|
||||
local context_dir="$2"
|
||||
local jar_count
|
||||
local jar_file
|
||||
|
||||
jar_count="$(
|
||||
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | wc -l
|
||||
)"
|
||||
|
||||
if [[ "$jar_count" != "1" ]]; then
|
||||
echo "Expected exactly one bootJar for $service_name, found $jar_count:" >&2
|
||||
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' -print >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jar_file="$(
|
||||
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | head -n 1
|
||||
)"
|
||||
|
||||
mkdir -p "$context_dir/build/libs"
|
||||
cp "$repo_root/services/$service_name/Dockerfile" "$context_dir/Dockerfile"
|
||||
cp "$jar_file" "$context_dir/build/libs/app.jar"
|
||||
}
|
||||
|
||||
build_service_image() {
|
||||
local service_name="$1"
|
||||
local gradle_max_workers="${GRADLE_MAX_WORKERS:-1}"
|
||||
local gradle_jvmargs="${GRADLE_JVMARGS:--Xmx2g -Dfile.encoding=UTF-8}"
|
||||
local kotlin_daemon_jvmargs="${KOTLIN_DAEMON_JVMARGS:--Xmx3g -XX:MaxMetaspaceSize=768m}"
|
||||
local gradle_offline="${GRADLE_OFFLINE:-true}"
|
||||
local runtime_image="${LOCAL_BUNDLE_RUNTIME_IMAGE:-bellsoft/liberica-openjre-alpine:21.0.5}"
|
||||
local image_tag="${PCP_IMAGE_TAG:-local}"
|
||||
local image_name="pcp/$service_name:$image_tag"
|
||||
local context_dir="$docker_contexts_dir/$service_name"
|
||||
local gradle_common_args=(
|
||||
"--no-parallel"
|
||||
"--max-workers=$gradle_max_workers"
|
||||
"-Dorg.gradle.jvmargs=$gradle_jvmargs"
|
||||
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
|
||||
)
|
||||
|
||||
if [[ "$gradle_offline" == "true" ]]; then
|
||||
gradle_common_args+=("--offline")
|
||||
fi
|
||||
|
||||
echo "Building bootJar for $service_name..."
|
||||
"$repo_root/gradlew" --project-dir "$repo_root" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
|
||||
|
||||
rm -rf "$context_dir"
|
||||
copy_single_boot_jar "$service_name" "$context_dir"
|
||||
|
||||
echo "Building Docker image $image_name..."
|
||||
docker build \
|
||||
--build-arg "RUNTIME_IMAGE=$runtime_image" \
|
||||
--file "$context_dir/Dockerfile" \
|
||||
--tag "$image_name" \
|
||||
"$context_dir"
|
||||
}
|
||||
|
||||
http_get() {
|
||||
local url="$1"
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsS "$url" >/dev/null
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -q -O /dev/null "$url"
|
||||
else
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_config_server() {
|
||||
local attempt
|
||||
local url="http://localhost:${CONFIG_SERVER_PORT:-38888}/actuator/health"
|
||||
|
||||
for attempt in {1..90}; do
|
||||
if http_get "$url"; then
|
||||
echo "spring-cloud-config-server is ready: $url"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "spring-cloud-config-server is not ready after 180 seconds: $url" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
restart_service() {
|
||||
local service_name="$1"
|
||||
|
||||
build_service_image "$service_name"
|
||||
|
||||
if [[ "$service_name" == "spring-cloud-config-server" ]]; then
|
||||
compose up -d --no-deps --force-recreate "$service_name"
|
||||
wait_for_config_server
|
||||
return 0
|
||||
fi
|
||||
|
||||
compose up -d spring-cloud-config-server
|
||||
wait_for_config_server
|
||||
compose up -d --no-deps --force-recreate "$service_name"
|
||||
}
|
||||
|
||||
service_name="${1:-}"
|
||||
command="${2:-restart}"
|
||||
|
||||
if [[ -z "$service_name" || "$service_name" == "help" || "$service_name" == "-h" || "$service_name" == "--help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! is_known_service "$service_name"; then
|
||||
echo "Unknown service: $service_name" >&2
|
||||
echo "Known services:" >&2
|
||||
printf ' %s\n' "${service_names[@]}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ensure_env_file
|
||||
ensure_source_config_repo_dir
|
||||
load_env
|
||||
require_command docker
|
||||
|
||||
case "$command" in
|
||||
restart)
|
||||
restart_service "$service_name"
|
||||
;;
|
||||
build)
|
||||
build_service_image "$service_name"
|
||||
;;
|
||||
stop)
|
||||
compose stop "$service_name"
|
||||
;;
|
||||
logs)
|
||||
compose logs -f "$service_name"
|
||||
;;
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -25,6 +25,10 @@ ensure_env_file() {
|
||||
}
|
||||
|
||||
ensure_env_file
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source "$bundle_dir/.env"
|
||||
set +a
|
||||
|
||||
if [[ ! -d "$images_dir" ]]; then
|
||||
echo "Images directory not found: $images_dir" >&2
|
||||
@@ -49,7 +53,12 @@ if [[ -f "$images_dir/public-images.txt" ]]; then
|
||||
fi
|
||||
|
||||
cd "$bundle_dir"
|
||||
echo "Starting postgres, kafka and spring-cloud-config-server..."
|
||||
compose up -d postgres kafka spring-cloud-config-server
|
||||
if [[ "${USE_EXTERNAL_INFRA:-false}" == "true" ]]; then
|
||||
echo "Using external infrastructure. Starting spring-cloud-config-server only."
|
||||
compose up -d spring-cloud-config-server
|
||||
else
|
||||
echo "Starting postgres, kafka and spring-cloud-config-server..."
|
||||
compose up -d postgres kafka spring-cloud-config-server
|
||||
fi
|
||||
|
||||
echo "Images imported and base services requested."
|
||||
|
||||
@@ -43,6 +43,26 @@ wait_for_postgres() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for_external_postgres() {
|
||||
local container_name="${EXTERNAL_POSTGRES_CONTAINER:-}"
|
||||
local attempt
|
||||
|
||||
if [[ -z "$container_name" ]]; then
|
||||
echo "EXTERNAL_POSTGRES_CONTAINER is required when USE_EXTERNAL_INFRA=true and SKIP_DB_INIT is not true." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for attempt in {1..60}; do
|
||||
if docker exec "$container_name" pg_isready -U "${POSTGRES_USER:-postgres}" -d postgres >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "External Postgres is not ready after 120 seconds: $container_name" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
create_database_if_missing() {
|
||||
local db_name="$1"
|
||||
local exists
|
||||
@@ -61,16 +81,35 @@ create_database_if_missing() {
|
||||
compose exec -T postgres createdb -U "${POSTGRES_USER:-postgres}" "$db_name"
|
||||
}
|
||||
|
||||
create_external_database_if_missing() {
|
||||
local db_name="$1"
|
||||
local container_name="${EXTERNAL_POSTGRES_CONTAINER:-}"
|
||||
local exists
|
||||
|
||||
exists="$(
|
||||
docker exec "$container_name" psql -U "${POSTGRES_USER:-postgres}" -d postgres -tAc \
|
||||
"SELECT 1 FROM pg_database WHERE datname = '$db_name'" | tr -d '[:space:]'
|
||||
)"
|
||||
|
||||
if [[ "$exists" == "1" ]]; then
|
||||
echo "Database already exists: $db_name"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Creating database: $db_name"
|
||||
docker exec "$container_name" createdb -U "${POSTGRES_USER:-postgres}" "$db_name"
|
||||
}
|
||||
|
||||
databases=(
|
||||
pcp_ballistics
|
||||
pcp_requests
|
||||
pcp_route_processing
|
||||
pcp_missions
|
||||
pcp_slots
|
||||
pcp_complex_plan
|
||||
pcp_satellite_catalog
|
||||
pcp_stations
|
||||
pcp_tgu
|
||||
pcp_tle
|
||||
pcp_satellites
|
||||
)
|
||||
|
||||
@@ -78,12 +117,20 @@ ensure_env_file
|
||||
load_env
|
||||
|
||||
cd "$bundle_dir"
|
||||
compose up -d postgres
|
||||
wait_for_postgres
|
||||
if [[ "${USE_EXTERNAL_INFRA:-false}" == "true" ]]; then
|
||||
wait_for_external_postgres
|
||||
|
||||
for db_name in "${databases[@]}"; do
|
||||
create_database_if_missing "$db_name"
|
||||
done
|
||||
for db_name in "${databases[@]}"; do
|
||||
create_external_database_if_missing "$db_name"
|
||||
done
|
||||
else
|
||||
compose up -d postgres
|
||||
wait_for_postgres
|
||||
|
||||
for db_name in "${databases[@]}"; do
|
||||
create_database_if_missing "$db_name"
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Database initialization completed. Tables are left to service Flyway migrations."
|
||||
echo "No schema objects or seed data were created by this script."
|
||||
|
||||
@@ -72,11 +72,34 @@ wait_for_kafka() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for_external_kafka() {
|
||||
local container_name="${EXTERNAL_KAFKA_CONTAINER:-}"
|
||||
local attempt
|
||||
|
||||
if [[ -z "$container_name" ]]; then
|
||||
echo "External Kafka container is not configured; skipping Kafka readiness check."
|
||||
return 0
|
||||
fi
|
||||
|
||||
for attempt in {1..60}; do
|
||||
if docker exec "$container_name" kafka-topics --bootstrap-server "${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}" --list >/dev/null 2>&1 ||
|
||||
docker exec "$container_name" kafka-topics.sh --bootstrap-server "${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}" --list >/dev/null 2>&1; then
|
||||
echo "External Kafka is ready in container $container_name."
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "External Kafka is not ready after 120 seconds: $container_name" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
app_services=(
|
||||
pcp-srpring-boot-admin-server
|
||||
pcp-satellite-catalog-service
|
||||
pcp-ballistics-service
|
||||
pcp-request-service
|
||||
pcp-route-processing-service
|
||||
slots-service
|
||||
pcp-complex-mission-service
|
||||
pcp-mission-planing-service
|
||||
@@ -84,7 +107,6 @@ app_services=(
|
||||
pcp-dynamic-plan-service
|
||||
pcp-stations-service
|
||||
pcp-ui-service
|
||||
tle-monitoring-service
|
||||
pcp-tgu-service
|
||||
)
|
||||
|
||||
@@ -93,9 +115,16 @@ load_env
|
||||
|
||||
cd "$bundle_dir"
|
||||
|
||||
echo "Starting infrastructure..."
|
||||
compose up -d postgres kafka
|
||||
wait_for_kafka
|
||||
if [[ "${USE_EXTERNAL_INFRA:-false}" == "true" ]]; then
|
||||
echo "Using external infrastructure. Skipping local postgres/kafka startup."
|
||||
echo "Postgres endpoint for services: ${PCP_POSTGRES_HOST:-postgres}:${PCP_POSTGRES_PORT:-5432}"
|
||||
echo "Kafka endpoint for services: ${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}"
|
||||
wait_for_external_kafka
|
||||
else
|
||||
echo "Starting infrastructure..."
|
||||
compose up -d postgres kafka
|
||||
wait_for_kafka
|
||||
fi
|
||||
|
||||
if [[ "${SKIP_DB_INIT:-false}" != "true" ]]; then
|
||||
"$script_dir/init-db.sh"
|
||||
@@ -106,7 +135,10 @@ compose up -d spring-cloud-config-server
|
||||
wait_for_http "spring-cloud-config-server" "http://localhost:${CONFIG_SERVER_PORT:-38888}/actuator/health"
|
||||
|
||||
echo "Starting application services..."
|
||||
compose up -d "${app_services[@]}"
|
||||
for service_name in "${app_services[@]}"; do
|
||||
echo "Starting $service_name..."
|
||||
compose up -d "$service_name"
|
||||
done
|
||||
|
||||
echo "Application startup requested."
|
||||
compose ps
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-ballistics-service "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-complex-mission-service "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-coverage-scheme-service "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-dynamic-plan-service "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-mission-planing-service "$@"
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-request-service "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-route-processing-service "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-satellite-catalog-service "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-srpring-boot-admin-server "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-stations-service "$@"
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-tgu-service "$@"
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" pcp-ui-service "$@"
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" slots-service "$@"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
exec "$script_dir/run-service.sh" spring-cloud-config-server "$@"
|
||||
@@ -0,0 +1,79 @@
|
||||
# Local jar runner
|
||||
|
||||
Скрипт запускает backend-сервисы как Spring Boot jar'ы на локальной машине.
|
||||
Spring Cloud Config Server стартует первым и читает конфигурацию из локального
|
||||
`config-repo`.
|
||||
|
||||
## Запуск
|
||||
|
||||
Из корня репозитория:
|
||||
|
||||
```bash
|
||||
./deploy/local-jar/run-services.sh start
|
||||
```
|
||||
|
||||
Что делает `start`:
|
||||
|
||||
- собирает `bootJar` для `spring-cloud-config-server` и всех Spring Boot сервисов;
|
||||
- поднимает локальные `postgres` и `kafka` через `deploy/local-bundle/docker-compose.yml`;
|
||||
- создаёт сервисные базы данных, если их ещё нет;
|
||||
- запускает `spring-cloud-config-server` на `http://localhost:38888`;
|
||||
- проверяет lookup конфигурации из `config-repo`;
|
||||
- запускает остальные jar'ы в заданной последовательности.
|
||||
|
||||
Runtime-файлы создаются в `build/local-jar-runtime`:
|
||||
|
||||
- `pids/` - PID процессов;
|
||||
- `logs/` - stdout/stderr каждого сервиса.
|
||||
|
||||
## Команды
|
||||
|
||||
```bash
|
||||
./deploy/local-jar/run-services.sh status
|
||||
./deploy/local-jar/run-services.sh logs pcp-request-service
|
||||
./deploy/local-jar/run-services.sh stop
|
||||
./deploy/local-jar/run-services.sh restart
|
||||
```
|
||||
|
||||
Только сборка:
|
||||
|
||||
```bash
|
||||
./deploy/local-jar/run-services.sh build
|
||||
```
|
||||
|
||||
Только инфраструктура:
|
||||
|
||||
```bash
|
||||
./deploy/local-jar/run-services.sh infra-up
|
||||
./deploy/local-jar/run-services.sh infra-down
|
||||
```
|
||||
|
||||
## Настройки
|
||||
|
||||
По умолчанию config-server использует:
|
||||
|
||||
```text
|
||||
SPRING_PROFILES_ACTIVE=local
|
||||
CONFIG_NATIVE_SEARCH_LOCATIONS=file:<repo>/config-repo
|
||||
SERVER_PORT=38888
|
||||
```
|
||||
|
||||
Сервисы используют:
|
||||
|
||||
```text
|
||||
SPRING_PROFILES_ACTIVE=local
|
||||
SPRING_CLOUD_CONFIG_PROFILE=local
|
||||
SPRING_CLOUD_CONFIG_LABEL=
|
||||
CONFIG_SERVER_URI=http://localhost:38888
|
||||
```
|
||||
|
||||
Полезные override'ы:
|
||||
|
||||
```bash
|
||||
START_INFRA=false ./deploy/local-jar/run-services.sh start
|
||||
INIT_DB=false ./deploy/local-jar/run-services.sh start
|
||||
WAIT_FOR_APPS=false ./deploy/local-jar/run-services.sh start
|
||||
JAVA_OPTS="-Xmx1g" ./deploy/local-jar/run-services.sh start
|
||||
CONFIG_REPO_DIR=/path/to/config-repo ./deploy/local-jar/run-services.sh start
|
||||
LOCAL_SERVICE_PROFILES=local,foo ./deploy/local-jar/run-services.sh start
|
||||
```
|
||||
Executable
+538
@@ -0,0 +1,538 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "$script_dir/../.." && pwd)"
|
||||
local_bundle_dir="$repo_root/deploy/local-bundle"
|
||||
compose_file="$local_bundle_dir/docker-compose.yml"
|
||||
local_bundle_env_file="$local_bundle_dir/.env"
|
||||
|
||||
if [[ -f "$local_bundle_env_file" ]]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$local_bundle_env_file"
|
||||
set +a
|
||||
fi
|
||||
|
||||
config_repo_dir="${CONFIG_REPO_DIR:-$repo_root/config-repo}"
|
||||
runtime_dir="${LOCAL_JAR_RUNTIME_DIR:-$repo_root/build/local-jar-runtime}"
|
||||
pid_dir="$runtime_dir/pids"
|
||||
log_dir="$runtime_dir/logs"
|
||||
|
||||
if [[ "$config_repo_dir" != /* ]]; then
|
||||
config_repo_dir="$repo_root/$config_repo_dir"
|
||||
fi
|
||||
|
||||
if [[ "$runtime_dir" != /* ]]; then
|
||||
runtime_dir="$repo_root/$runtime_dir"
|
||||
pid_dir="$runtime_dir/pids"
|
||||
log_dir="$runtime_dir/logs"
|
||||
fi
|
||||
|
||||
config_service="spring-cloud-config-server"
|
||||
app_services=(
|
||||
pcp-srpring-boot-admin-server
|
||||
pcp-stations-service
|
||||
pcp-satellite-catalog-service
|
||||
pcp-request-service
|
||||
pcp-route-processing-service
|
||||
pcp-ballistics-service
|
||||
slots-service
|
||||
pcp-complex-mission-service
|
||||
pcp-mission-planing-service
|
||||
pcp-coverage-scheme-service
|
||||
pcp-dynamic-plan-service
|
||||
tle-monitoring-service
|
||||
pcp-tgu-service
|
||||
pcp-ui-service
|
||||
)
|
||||
all_services=("$config_service" "${app_services[@]}")
|
||||
|
||||
databases=(
|
||||
pcp_ballistics
|
||||
pcp_requests
|
||||
pcp_route_processing
|
||||
pcp_missions
|
||||
pcp_slots
|
||||
pcp_complex_plan
|
||||
pcp_satellite_catalog
|
||||
pcp_stations
|
||||
pcp_tgu
|
||||
pcp_tle
|
||||
pcp_satellites
|
||||
)
|
||||
|
||||
declare -A service_ports=(
|
||||
[spring-cloud-config-server]="${CONFIG_SERVER_PORT:-38888}"
|
||||
[pcp-srpring-boot-admin-server]="${PCP_ADMIN_PORT:-7000}"
|
||||
[tle-monitoring-service]="${PCP_TLE_MONITORING_PORT:-7001}"
|
||||
[pcp-complex-mission-service]="${PCP_COMPLEX_MISSION_PORT:-7002}"
|
||||
[pcp-ballistics-service]="${PCP_BALLISTICS_PORT:-7003}"
|
||||
[pcp-route-processing-service]="${PCP_ROUTE_PROCESSING_PORT:-7004}"
|
||||
[pcp-request-service]="${PCP_REQUEST_PORT:-7005}"
|
||||
[slots-service]="${PCP_SLOTS_PORT:-7006}"
|
||||
[pcp-ui-service]="${PCP_UI_PORT:-7008}"
|
||||
[pcp-stations-service]="${PCP_STATIONS_PORT:-7009}"
|
||||
[pcp-mission-planing-service]="${PCP_MISSION_PORT:-7010}"
|
||||
[pcp-tgu-service]="${PCP_TGU_PORT:-7011}"
|
||||
[pcp-coverage-scheme-service]="${PCP_COVERAGE_SCHEME_PORT:-7012}"
|
||||
[pcp-satellite-catalog-service]="${PCP_SATELLITE_CATALOG_PORT:-7013}"
|
||||
[pcp-dynamic-plan-service]="${PCP_DYNAMIC_PLAN_PORT:-7014}"
|
||||
)
|
||||
|
||||
gradle_max_workers="${GRADLE_MAX_WORKERS:-1}"
|
||||
gradle_jvmargs="${GRADLE_JVMARGS:--Xmx2g -Dfile.encoding=UTF-8}"
|
||||
kotlin_daemon_jvmargs="${KOTLIN_DAEMON_JVMARGS:--Xmx3g -XX:MaxMetaspaceSize=768m}"
|
||||
config_server_port="${service_ports[$config_service]}"
|
||||
config_server_uri="${LOCAL_CONFIG_SERVER_URI:-http://localhost:$config_server_port}"
|
||||
service_profiles="${LOCAL_SERVICE_PROFILES:-local}"
|
||||
config_profiles="${LOCAL_CONFIG_PROFILES:-$service_profiles}"
|
||||
postgres_host="${PCP_POSTGRES_HOST:-localhost}"
|
||||
postgres_port="${PCP_POSTGRES_PORT:-5432}"
|
||||
kafka_host="${PCP_KAFKA_HOST:-localhost}"
|
||||
kafka_port="${PCP_KAFKA_PORT:-29092}"
|
||||
|
||||
gradle_common_args=(
|
||||
"--no-parallel"
|
||||
"--max-workers=$gradle_max_workers"
|
||||
"-Dorg.gradle.jvmargs=$gradle_jvmargs"
|
||||
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
|
||||
)
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./deploy/local-jar/run-services.sh [command]
|
||||
|
||||
Commands:
|
||||
start Build bootJar artifacts and start local infra, config-server and services.
|
||||
restart Stop local jar processes, then run start.
|
||||
stop Stop jar processes started by this script.
|
||||
status Show pid and log status for local jar processes.
|
||||
build Build bootJar artifacts only.
|
||||
infra-up Start local Postgres/Kafka via deploy/local-bundle/docker-compose.yml.
|
||||
infra-down Stop local Postgres/Kafka containers.
|
||||
logs NAME Tail log for a service.
|
||||
|
||||
Useful environment:
|
||||
START_INFRA=false Do not start Postgres/Kafka containers during start.
|
||||
INIT_DB=false Do not create local Postgres databases during start.
|
||||
WAIT_FOR_APPS=false Do not wait for each app /actuator/health.
|
||||
CONFIG_REPO_DIR=... Config repository used by spring-cloud-config-server.
|
||||
JAVA_OPTS="-Xmx1g" Extra JVM options for every jar process.
|
||||
LOCAL_SERVICE_PROFILES=local,foo
|
||||
EOF
|
||||
}
|
||||
|
||||
require_command() {
|
||||
local command_name="$1"
|
||||
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||
echo "$command_name is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose --project-directory "$local_bundle_dir" -f "$compose_file" "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose --project-directory "$local_bundle_dir" -f "$compose_file" "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
http_get() {
|
||||
local url="$1"
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsS "$url" >/dev/null
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -q -O /dev/null "$url"
|
||||
else
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_http() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
local attempts="${3:-90}"
|
||||
local attempt
|
||||
|
||||
for ((attempt = 1; attempt <= attempts; attempt++)); do
|
||||
if http_get "$url"; then
|
||||
echo "$name is ready: $url"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "$name is not ready after $((attempts * 2)) seconds: $url" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for_postgres() {
|
||||
local attempt
|
||||
local postgres_user="${POSTGRES_USER:-postgres}"
|
||||
|
||||
for attempt in {1..60}; do
|
||||
if compose exec -T postgres pg_isready -U "$postgres_user" -d postgres >/dev/null 2>&1; then
|
||||
echo "Postgres is ready."
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Postgres is not ready after 120 seconds." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for_kafka() {
|
||||
local attempt
|
||||
for attempt in {1..60}; do
|
||||
if compose exec -T kafka kafka-topics.sh --bootstrap-server kafka:9092 --list >/dev/null 2>&1; then
|
||||
echo "Kafka is ready."
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Kafka is not ready after 120 seconds." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
create_database_if_missing() {
|
||||
local db_name="$1"
|
||||
local postgres_user="${POSTGRES_USER:-postgres}"
|
||||
local exists
|
||||
|
||||
exists="$(
|
||||
compose exec -T postgres psql -U "$postgres_user" -d postgres -tAc \
|
||||
"SELECT 1 FROM pg_database WHERE datname = '$db_name'" | tr -d '[:space:]'
|
||||
)"
|
||||
|
||||
if [[ "$exists" == "1" ]]; then
|
||||
echo "Database already exists: $db_name"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Creating database: $db_name"
|
||||
compose exec -T postgres createdb -U "$postgres_user" "$db_name"
|
||||
}
|
||||
|
||||
start_infra() {
|
||||
require_command docker
|
||||
echo "Starting local Postgres and Kafka..."
|
||||
compose up -d postgres kafka
|
||||
wait_for_postgres
|
||||
wait_for_kafka
|
||||
}
|
||||
|
||||
init_databases() {
|
||||
echo "Initializing local service databases..."
|
||||
for db_name in "${databases[@]}"; do
|
||||
create_database_if_missing "$db_name"
|
||||
done
|
||||
}
|
||||
|
||||
build_services() {
|
||||
echo "Building bootJar artifacts..."
|
||||
echo "Gradle max workers: $gradle_max_workers"
|
||||
echo "Gradle JVM args: $gradle_jvmargs"
|
||||
echo "Kotlin daemon JVM args: $kotlin_daemon_jvmargs"
|
||||
|
||||
for service_name in "${all_services[@]}"; do
|
||||
echo "Building bootJar for $service_name..."
|
||||
"$repo_root/gradlew" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
|
||||
done
|
||||
}
|
||||
|
||||
service_pid_file() {
|
||||
local service_name="$1"
|
||||
printf '%s/%s.pid' "$pid_dir" "$service_name"
|
||||
}
|
||||
|
||||
service_log_file() {
|
||||
local service_name="$1"
|
||||
printf '%s/%s.log' "$log_dir" "$service_name"
|
||||
}
|
||||
|
||||
is_pid_running() {
|
||||
local pid="$1"
|
||||
[[ -n "$pid" ]] && kill -0 "$pid" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
read_service_pid() {
|
||||
local service_name="$1"
|
||||
local pid_file
|
||||
|
||||
pid_file="$(service_pid_file "$service_name")"
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
tr -d '[:space:]' < "$pid_file"
|
||||
fi
|
||||
}
|
||||
|
||||
find_boot_jar() {
|
||||
local service_name="$1"
|
||||
local jar_dir="$repo_root/services/$service_name/build/libs"
|
||||
local jar_count
|
||||
local jar_file
|
||||
|
||||
if [[ ! -d "$jar_dir" ]]; then
|
||||
echo "Missing build/libs for $service_name. Run build first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jar_count="$(find "$jar_dir" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | wc -l)"
|
||||
if [[ "$jar_count" != "1" ]]; then
|
||||
echo "Expected exactly one bootJar for $service_name, found $jar_count:" >&2
|
||||
find "$jar_dir" -maxdepth 1 -type f -name '*.jar' -print >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jar_file="$(find "$jar_dir" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | head -n 1)"
|
||||
printf '%s' "$jar_file"
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local service_name="$1"
|
||||
local jar_file
|
||||
local pid_file
|
||||
local log_file
|
||||
local existing_pid
|
||||
local port="${service_ports[$service_name]}"
|
||||
local java_cmd=(java)
|
||||
local parsed_java_opts=()
|
||||
|
||||
pid_file="$(service_pid_file "$service_name")"
|
||||
log_file="$(service_log_file "$service_name")"
|
||||
existing_pid="$(read_service_pid "$service_name" || true)"
|
||||
|
||||
if is_pid_running "$existing_pid"; then
|
||||
echo "$service_name is already running with pid $existing_pid"
|
||||
return 0
|
||||
fi
|
||||
|
||||
mkdir -p "$pid_dir" "$log_dir"
|
||||
jar_file="$(find_boot_jar "$service_name")"
|
||||
if [[ -n "${JAVA_OPTS:-}" ]]; then
|
||||
read -r -a parsed_java_opts <<< "$JAVA_OPTS"
|
||||
java_cmd+=("${parsed_java_opts[@]}")
|
||||
fi
|
||||
java_cmd+=(-jar "$jar_file")
|
||||
|
||||
echo "Starting $service_name on port $port..."
|
||||
if [[ "$service_name" == "$config_service" ]]; then
|
||||
(
|
||||
cd "$repo_root"
|
||||
env \
|
||||
SPRING_PROFILES_ACTIVE=local \
|
||||
CONFIG_NATIVE_SEARCH_LOCATIONS="file:$config_repo_dir" \
|
||||
SERVER_PORT="$config_server_port" \
|
||||
"${java_cmd[@]}" > "$log_file" 2>&1 &
|
||||
echo "$!" > "$pid_file"
|
||||
)
|
||||
else
|
||||
(
|
||||
cd "$repo_root"
|
||||
env \
|
||||
CONFIG_SERVER_URI="$config_server_uri" \
|
||||
CONFIG_SERVER_FAIL_FAST=true \
|
||||
SPRING_PROFILES_ACTIVE="$service_profiles" \
|
||||
SPRING_CLOUD_CONFIG_PROFILE="$config_profiles" \
|
||||
SPRING_CLOUD_CONFIG_LABEL= \
|
||||
SPRING_KAFKA_ADMIN_AUTO_CREATE=true \
|
||||
SPRING_KAFKA_LISTENER_MISSING_TOPICS_FATAL=false \
|
||||
CAMUNDA_CLIENT_ENABLED=false \
|
||||
PLANNING_EXTERNAL_UPDATE_ENABLED=false \
|
||||
TLE_POLLING_ENABLED=false \
|
||||
PCP_POSTGRES_HOST="$postgres_host" \
|
||||
PCP_POSTGRES_PORT="$postgres_port" \
|
||||
PCP_KAFKA_HOST="$kafka_host" \
|
||||
PCP_KAFKA_PORT="$kafka_port" \
|
||||
PCP_PORTS_CONFIG="$config_server_port" \
|
||||
PCP_PORTS_ADMIN="${service_ports[pcp-srpring-boot-admin-server]}" \
|
||||
PCP_PORTS_TLE_MONITORING="${service_ports[tle-monitoring-service]}" \
|
||||
PCP_PORTS_COMPLEX_MISSION_SERVICE="${service_ports[pcp-complex-mission-service]}" \
|
||||
PCP_PORTS_BALLISTICS="${service_ports[pcp-ballistics-service]}" \
|
||||
PCP_PORTS_ROUTE_PROCESSING="${service_ports[pcp-route-processing-service]}" \
|
||||
PCP_PORTS_REQUEST="${service_ports[pcp-request-service]}" \
|
||||
PCP_PORTS_SLOTS="${service_ports[slots-service]}" \
|
||||
PCP_PORTS_UI="${service_ports[pcp-ui-service]}" \
|
||||
PCP_PORTS_STATIONS="${service_ports[pcp-stations-service]}" \
|
||||
PCP_PORTS_MISSION="${service_ports[pcp-mission-planing-service]}" \
|
||||
PCP_PORTS_TGU="${service_ports[pcp-tgu-service]}" \
|
||||
PCP_PORTS_COVERAGE_SCHEME="${service_ports[pcp-coverage-scheme-service]}" \
|
||||
PCP_PORTS_SATELLITE_CATALOG="${service_ports[pcp-satellite-catalog-service]}" \
|
||||
PCP_PORTS_DYNAMIC_PLAN="${service_ports[pcp-dynamic-plan-service]}" \
|
||||
"${java_cmd[@]}" > "$log_file" 2>&1 &
|
||||
echo "$!" > "$pid_file"
|
||||
)
|
||||
fi
|
||||
|
||||
echo "$service_name log: $log_file"
|
||||
}
|
||||
|
||||
start_config_server() {
|
||||
if [[ ! -d "$config_repo_dir" ]]; then
|
||||
echo "Config repo directory does not exist: $config_repo_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
start_service "$config_service"
|
||||
wait_for_http "$config_service" "$config_server_uri/actuator/health"
|
||||
wait_for_http "$config_service config-repo lookup" "$config_server_uri/pcp-request-service/local"
|
||||
}
|
||||
|
||||
wait_for_service_health() {
|
||||
local service_name="$1"
|
||||
local port="${service_ports[$service_name]}"
|
||||
wait_for_http "$service_name" "http://localhost:$port/actuator/health" "${APP_HEALTH_ATTEMPTS:-90}"
|
||||
}
|
||||
|
||||
start_app_services() {
|
||||
for service_name in "${app_services[@]}"; do
|
||||
start_service "$service_name"
|
||||
if [[ "${WAIT_FOR_APPS:-true}" == "true" ]]; then
|
||||
wait_for_service_health "$service_name"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
local service_name="$1"
|
||||
local pid_file
|
||||
local pid
|
||||
local attempt
|
||||
|
||||
pid_file="$(service_pid_file "$service_name")"
|
||||
pid="$(read_service_pid "$service_name" || true)"
|
||||
if ! is_pid_running "$pid"; then
|
||||
rm -f "$pid_file"
|
||||
echo "$service_name is not running."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Stopping $service_name with pid $pid..."
|
||||
kill "$pid" >/dev/null 2>&1 || true
|
||||
for attempt in {1..30}; do
|
||||
if ! is_pid_running "$pid"; then
|
||||
rm -f "$pid_file"
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Force stopping $service_name with pid $pid..."
|
||||
kill -9 "$pid" >/dev/null 2>&1 || true
|
||||
rm -f "$pid_file"
|
||||
}
|
||||
|
||||
stop_services() {
|
||||
local service_name
|
||||
local idx
|
||||
|
||||
for ((idx = ${#app_services[@]} - 1; idx >= 0; idx--)); do
|
||||
service_name="${app_services[$idx]}"
|
||||
stop_service "$service_name"
|
||||
done
|
||||
stop_service "$config_service"
|
||||
}
|
||||
|
||||
status_services() {
|
||||
local service_name
|
||||
local pid
|
||||
local log_file
|
||||
|
||||
printf '%-36s %-10s %s\n' "service" "pid" "log"
|
||||
for service_name in "${all_services[@]}"; do
|
||||
pid="$(read_service_pid "$service_name" || true)"
|
||||
log_file="$(service_log_file "$service_name")"
|
||||
if is_pid_running "$pid"; then
|
||||
printf '%-36s %-10s %s\n' "$service_name" "$pid" "$log_file"
|
||||
else
|
||||
printf '%-36s %-10s %s\n' "$service_name" "-" "$log_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
tail_logs() {
|
||||
local service_name="${1:-}"
|
||||
local log_file
|
||||
|
||||
if [[ -z "$service_name" ]]; then
|
||||
echo "Service name is required for logs command." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_file="$(service_log_file "$service_name")"
|
||||
if [[ ! -f "$log_file" ]]; then
|
||||
echo "Log file does not exist: $log_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tail -f "$log_file"
|
||||
}
|
||||
|
||||
start_all() {
|
||||
require_command java
|
||||
|
||||
build_services
|
||||
|
||||
if [[ "${START_INFRA:-true}" == "true" ]]; then
|
||||
start_infra
|
||||
if [[ "${INIT_DB:-true}" == "true" ]]; then
|
||||
init_databases
|
||||
fi
|
||||
else
|
||||
echo "Skipping local infra startup. Expecting Postgres at $postgres_host:$postgres_port and Kafka at $kafka_host:$kafka_port."
|
||||
fi
|
||||
|
||||
start_config_server
|
||||
start_app_services
|
||||
|
||||
echo "Local jar startup requested."
|
||||
status_services
|
||||
}
|
||||
|
||||
command="${1:-start}"
|
||||
case "$command" in
|
||||
start)
|
||||
start_all
|
||||
;;
|
||||
restart)
|
||||
stop_services
|
||||
start_all
|
||||
;;
|
||||
stop)
|
||||
stop_services
|
||||
;;
|
||||
status)
|
||||
status_services
|
||||
;;
|
||||
build)
|
||||
build_services
|
||||
;;
|
||||
infra-up)
|
||||
start_infra
|
||||
if [[ "${INIT_DB:-true}" == "true" ]]; then
|
||||
init_databases
|
||||
fi
|
||||
;;
|
||||
infra-down)
|
||||
require_command docker
|
||||
compose stop kafka postgres
|
||||
;;
|
||||
logs)
|
||||
tail_logs "${2:-}"
|
||||
;;
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user