create-entity-server 0.9.14 → 0.9.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/template/scripts/run.sh
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Entity Server - Run Script
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
# 심볼릭 링크 경로(/home/codeshop → /data/codeshop)로 실행돼도 systemd ExecStart 의 실경로와
|
|
5
|
+
# 매칭되도록 pwd -P 로 실경로로 정규화한다. (find_systemd_service 의 ExecStart 매칭에 필요)
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
5
7
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
6
8
|
|
|
7
9
|
cd "$PROJECT_ROOT"
|
|
@@ -45,6 +47,15 @@ find_systemd_service() {
|
|
|
45
47
|
[ -z "$namespace" ] && namespace="default"
|
|
46
48
|
|
|
47
49
|
local svc_name="${namespace}-entity-server.service"
|
|
50
|
+
|
|
51
|
+
# 유닛이 실제로 로드되어 있는지 먼저 확인한다.
|
|
52
|
+
# (등록되지 않은 유닛은 LoadState=not-found 이며, 이 경우 systemd 서비스로 취급하지 않는다.)
|
|
53
|
+
local load_state=""
|
|
54
|
+
load_state=$(systemctl show -p LoadState --value "$svc_name" 2>/dev/null || true)
|
|
55
|
+
if [ "$load_state" != "loaded" ]; then
|
|
56
|
+
return 1
|
|
57
|
+
fi
|
|
58
|
+
|
|
48
59
|
local exec_start=""
|
|
49
60
|
exec_start=$(systemctl show -p ExecStart --value "$svc_name" 2>/dev/null || true)
|
|
50
61
|
|
|
@@ -135,6 +146,12 @@ is_pid_running() {
|
|
|
135
146
|
return 1
|
|
136
147
|
fi
|
|
137
148
|
|
|
149
|
+
# 리눅스: /proc 로 먼저 확인한다. kill -0 은 다른 사용자(root) 프로세스에 대해
|
|
150
|
+
# EPERM 으로 실패해 "없음"으로 오판하므로, 존재 확인에 의존하면 안 된다.
|
|
151
|
+
if [ -d "/proc/$pid" ]; then
|
|
152
|
+
return 0
|
|
153
|
+
fi
|
|
154
|
+
|
|
138
155
|
if kill -0 "$pid" 2>/dev/null; then
|
|
139
156
|
return 0
|
|
140
157
|
fi
|
|
@@ -148,6 +165,18 @@ is_pid_running() {
|
|
|
148
165
|
return 1
|
|
149
166
|
}
|
|
150
167
|
|
|
168
|
+
# PID를 종료합니다. 권한이 부족하면(다른 사용자/root 소유) sudo 로 재시도합니다.
|
|
169
|
+
kill_pid_signal() {
|
|
170
|
+
local sig="$1"
|
|
171
|
+
local pid="$2"
|
|
172
|
+
|
|
173
|
+
if kill "$sig" "$pid" 2>/dev/null; then
|
|
174
|
+
return 0
|
|
175
|
+
fi
|
|
176
|
+
# 권한 부족 등으로 실패하면 sudo 로 한 번 더 시도한다.
|
|
177
|
+
sudo -n kill "$sig" "$pid" 2>/dev/null || true
|
|
178
|
+
}
|
|
179
|
+
|
|
151
180
|
# PID를 종료하고 남아 있으면 강제 종료까지 진행합니다.
|
|
152
181
|
force_stop_pid() {
|
|
153
182
|
local pid="$1"
|
|
@@ -156,7 +185,7 @@ force_stop_pid() {
|
|
|
156
185
|
return 1
|
|
157
186
|
fi
|
|
158
187
|
|
|
159
|
-
|
|
188
|
+
kill_pid_signal -TERM "$pid"
|
|
160
189
|
if is_pid_running "$pid" && has_command powershell.exe; then
|
|
161
190
|
powershell.exe -NoProfile -Command "Stop-Process -Id $pid -ErrorAction SilentlyContinue" >/dev/null 2>&1 || true
|
|
162
191
|
fi
|
|
@@ -168,7 +197,7 @@ force_stop_pid() {
|
|
|
168
197
|
sleep 0.1
|
|
169
198
|
done
|
|
170
199
|
|
|
171
|
-
|
|
200
|
+
kill_pid_signal -KILL "$pid"
|
|
172
201
|
if is_pid_running "$pid" && has_command powershell.exe; then
|
|
173
202
|
powershell.exe -NoProfile -Command "Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue" >/dev/null 2>&1 || true
|
|
174
203
|
fi
|
|
@@ -318,7 +347,37 @@ find_server_pids() {
|
|
|
318
347
|
port=$(get_server_value "port" "3400")
|
|
319
348
|
|
|
320
349
|
if has_command ss; then
|
|
321
|
-
|
|
350
|
+
local ss_pids
|
|
351
|
+
ss_pids="$(ss -ltnp 2>/dev/null | sed -n "s/.*:$port .*pid=\([0-9]\+\).*/\1/p" | sort -u)"
|
|
352
|
+
if [ -n "$ss_pids" ]; then
|
|
353
|
+
echo "$ss_pids"
|
|
354
|
+
return
|
|
355
|
+
fi
|
|
356
|
+
|
|
357
|
+
# ss 가 LISTEN 은 보이는데 PID 가 비어 있으면, 다른 사용자(root 등) 소유 소켓이라
|
|
358
|
+
# 일반 권한으로 PID 가 안 보이는 경우다. sudo 로 한 번 더, 그 다음 lsof/fuser 로 보강한다.
|
|
359
|
+
if ss -ltn 2>/dev/null | grep -q ":$port "; then
|
|
360
|
+
local sudo_pids
|
|
361
|
+
sudo_pids="$(sudo -n ss -ltnp 2>/dev/null | sed -n "s/.*:$port .*pid=\([0-9]\+\).*/\1/p" | sort -u)"
|
|
362
|
+
if [ -n "$sudo_pids" ]; then
|
|
363
|
+
echo "$sudo_pids"
|
|
364
|
+
return
|
|
365
|
+
fi
|
|
366
|
+
|
|
367
|
+
if has_command lsof; then
|
|
368
|
+
local lsof_pids
|
|
369
|
+
lsof_pids="$(sudo -n lsof -tiTCP:"$port" -sTCP:LISTEN 2>/dev/null | awk '/^[0-9]+$/' | sort -u)"
|
|
370
|
+
if [ -n "$lsof_pids" ]; then
|
|
371
|
+
echo "$lsof_pids"
|
|
372
|
+
return
|
|
373
|
+
fi
|
|
374
|
+
fi
|
|
375
|
+
|
|
376
|
+
if has_command fuser; then
|
|
377
|
+
sudo -n fuser "$port"/tcp 2>/dev/null | tr ' ' '\n' | awk '/^[0-9]+$/' | sort -u
|
|
378
|
+
return
|
|
379
|
+
fi
|
|
380
|
+
fi
|
|
322
381
|
return
|
|
323
382
|
fi
|
|
324
383
|
|
|
@@ -423,9 +482,11 @@ show_unmanaged_server_message() {
|
|
|
423
482
|
if [ "$LANGUAGE" = "en" ]; then
|
|
424
483
|
echo "ℹ️ A process is using port $port, but it was not started by this project's pid file."
|
|
425
484
|
echo " For safety, run.sh stop does not kill processes based on port match alone."
|
|
485
|
+
echo " To kill it anyway (by port, ignoring process name): ./run.sh stop --force"
|
|
426
486
|
else
|
|
427
487
|
echo "ℹ️ 포트 $port 를 사용하는 프로세스가 있지만, 현재 프로젝트의 pid 파일로 시작한 서버가 아닙니다."
|
|
428
488
|
echo " 안전을 위해 run.sh stop 은 포트 일치만으로 프로세스를 종료하지 않습니다."
|
|
489
|
+
echo " 그래도 종료하려면(포트 기준, 프로세스명 무시): ./run.sh stop --force"
|
|
429
490
|
fi
|
|
430
491
|
|
|
431
492
|
print_port_process_details
|
|
@@ -467,7 +528,94 @@ stop_pid_with_confirm() {
|
|
|
467
528
|
return 1
|
|
468
529
|
}
|
|
469
530
|
|
|
531
|
+
# 설정 포트를 점유한 모든 PID 를 프로세스명과 무관하게 강제 종료한다 (--force 전용).
|
|
532
|
+
# systemd 서비스가 등록돼 있으면 먼저 'systemctl stop' 으로 완전히 중지한다.
|
|
533
|
+
# - systemctl stop 은 명시적 중지라 Restart=always 정책을 트리거하지 않는다.
|
|
534
|
+
# - 반대로, 서비스를 stop 하지 않고 PID 만 kill 하면 systemd 가 비정상 종료로 보고 즉시 재기동한다.
|
|
535
|
+
# stop 이후에도 포트를 쥔 잔여(고아) 프로세스가 있으면 그때 kill 한다(이미 unit 이 멈춰 재기동 안 됨).
|
|
536
|
+
force_stop_by_port() {
|
|
537
|
+
local port
|
|
538
|
+
port=$(get_server_value "port" "3400")
|
|
539
|
+
|
|
540
|
+
local svc=""
|
|
541
|
+
svc=$(find_systemd_service || true)
|
|
542
|
+
if [ -n "$svc" ]; then
|
|
543
|
+
local svc_state=""
|
|
544
|
+
svc_state=$(systemctl is-active "$svc" 2>/dev/null || true)
|
|
545
|
+
if [ "$svc_state" = "active" ] || [ "$svc_state" = "activating" ] || [ "$svc_state" = "failed" ]; then
|
|
546
|
+
echo "ℹ️ systemd 서비스 완전 중지: $svc"
|
|
547
|
+
sudo systemctl stop "$svc"
|
|
548
|
+
# 포트가 풀릴 때까지 잠시 대기 (systemctl stop 은 재기동을 유발하지 않는다)
|
|
549
|
+
local i=0
|
|
550
|
+
while [ "$i" -lt 30 ]; do
|
|
551
|
+
if [ -z "$(find_server_pids | head -n 1)" ]; then
|
|
552
|
+
break
|
|
553
|
+
fi
|
|
554
|
+
sleep 0.1
|
|
555
|
+
i=$((i + 1))
|
|
556
|
+
done
|
|
557
|
+
fi
|
|
558
|
+
fi
|
|
559
|
+
|
|
560
|
+
rm -f "$PID_FILE"
|
|
561
|
+
|
|
562
|
+
local killed_any=0
|
|
563
|
+
local pid=""
|
|
564
|
+
while read -r pid; do
|
|
565
|
+
pid=$(echo "$pid" | tr -d '[:space:]')
|
|
566
|
+
[ -z "$pid" ] && continue
|
|
567
|
+
local name=""
|
|
568
|
+
name=$(get_pid_name "$pid")
|
|
569
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
570
|
+
echo "⚠️ --force: killing PID $pid (${name:-unknown}) on port $port"
|
|
571
|
+
else
|
|
572
|
+
echo "⚠️ --force: 포트 $port 점유 PID $pid (${name:-unknown}) 강제 종료"
|
|
573
|
+
fi
|
|
574
|
+
if force_stop_pid "$pid"; then
|
|
575
|
+
killed_any=1
|
|
576
|
+
else
|
|
577
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
578
|
+
echo "❌ failed to kill PID $pid"
|
|
579
|
+
else
|
|
580
|
+
echo "❌ PID $pid 종료 실패"
|
|
581
|
+
fi
|
|
582
|
+
return 1
|
|
583
|
+
fi
|
|
584
|
+
done < <(find_server_pids)
|
|
585
|
+
|
|
586
|
+
if [ "$killed_any" -eq 1 ]; then
|
|
587
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
588
|
+
echo "✅ ${SERVER_NAME} force-stopped (port $port)"
|
|
589
|
+
else
|
|
590
|
+
echo "✅ ${SERVER_NAME} 강제 종료 완료 (포트 $port)"
|
|
591
|
+
fi
|
|
592
|
+
return 0
|
|
593
|
+
fi
|
|
594
|
+
|
|
595
|
+
if [ -n "$svc" ]; then
|
|
596
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
597
|
+
echo "✅ ${SERVER_NAME} stopped via systemd (port $port released)"
|
|
598
|
+
else
|
|
599
|
+
echo "✅ ${SERVER_NAME} systemd 로 중지됨 (포트 $port 해제)"
|
|
600
|
+
fi
|
|
601
|
+
return 0
|
|
602
|
+
fi
|
|
603
|
+
|
|
604
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
605
|
+
echo "ℹ️ no process is occupying port $port."
|
|
606
|
+
else
|
|
607
|
+
echo "ℹ️ 포트 $port 를 점유한 프로세스가 없습니다."
|
|
608
|
+
fi
|
|
609
|
+
return 0
|
|
610
|
+
}
|
|
611
|
+
|
|
470
612
|
stop_server() {
|
|
613
|
+
# --force: 프로세스명을 따지지 않고 포트 점유 PID 를 무조건 종료한다.
|
|
614
|
+
if [ "${FORCE_STOP:-0}" -eq 1 ]; then
|
|
615
|
+
force_stop_by_port
|
|
616
|
+
return $?
|
|
617
|
+
fi
|
|
618
|
+
|
|
471
619
|
local svc=""
|
|
472
620
|
svc=$(find_systemd_service || true)
|
|
473
621
|
if [ -n "$svc" ]; then
|
|
@@ -584,14 +732,17 @@ if [ $# -eq 0 ]; then
|
|
|
584
732
|
echo "Modes:"
|
|
585
733
|
echo " dev environment=development, keep database.default, then run binary"
|
|
586
734
|
echo " start run current config in background without modifying configs"
|
|
587
|
-
echo " stop stop background server started by this script"
|
|
735
|
+
echo " stop stop background server started by this script (--force: kill by port)"
|
|
736
|
+
echo " restart restart server (--force: force-kill by port, then start)"
|
|
588
737
|
echo " status show server status"
|
|
589
738
|
echo ""
|
|
590
739
|
echo "Examples:"
|
|
591
|
-
echo " $0 dev
|
|
592
|
-
echo " $0 start
|
|
593
|
-
echo " $0 stop
|
|
594
|
-
echo " $0
|
|
740
|
+
echo " $0 dev # Start in development mode"
|
|
741
|
+
echo " $0 start # Start current config in background"
|
|
742
|
+
echo " $0 stop # Stop server"
|
|
743
|
+
echo " $0 stop --force # Kill whatever occupies the port (ignore process name)"
|
|
744
|
+
echo " $0 restart --force # Force-kill by port, then start"
|
|
745
|
+
echo " $0 status # Show status"
|
|
595
746
|
else
|
|
596
747
|
echo "Entity Server - 실행 스크립트"
|
|
597
748
|
echo "==========================="
|
|
@@ -603,38 +754,33 @@ if [ $# -eq 0 ]; then
|
|
|
603
754
|
echo "모드:"
|
|
604
755
|
echo " dev environment=development로 설정하고 database.default는 유지한 채 바이너리 실행"
|
|
605
756
|
echo " start 설정파일을 수정하지 않고 현재 설정 그대로 백그라운드 실행"
|
|
606
|
-
echo " stop run.sh로 백그라운드 실행한 서버 중지"
|
|
607
|
-
echo " restart 서버 재시작"
|
|
757
|
+
echo " stop run.sh로 백그라운드 실행한 서버 중지 (--force: 포트 기준 강제 종료)"
|
|
758
|
+
echo " restart 서버 재시작 (--force: 포트 기준 강제 종료 후 시작)"
|
|
608
759
|
echo " status 서버 상태 조회"
|
|
609
760
|
echo ""
|
|
610
761
|
echo "예제:"
|
|
611
|
-
echo " $0 dev
|
|
612
|
-
echo " $0 start
|
|
613
|
-
echo " $0 stop
|
|
614
|
-
echo " $0
|
|
615
|
-
echo " $0
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
echo ""
|
|
619
|
-
if [ -f "$SERVER_CONFIG" ] && [ -f "$DATABASE_CONFIG" ] && [ -f "$SERVER_BIN" ]; then
|
|
620
|
-
if [ "$LANGUAGE" = "en" ]; then
|
|
621
|
-
echo "Current status:"
|
|
622
|
-
else
|
|
623
|
-
echo "현재 상태:"
|
|
624
|
-
fi
|
|
625
|
-
show_status
|
|
626
|
-
else
|
|
627
|
-
if [ "$LANGUAGE" = "en" ]; then
|
|
628
|
-
echo "Current status: unavailable (missing config or server binary)"
|
|
629
|
-
else
|
|
630
|
-
echo "현재 상태: 확인 불가 (설정 파일 또는 서버 바이너리 없음)"
|
|
631
|
-
fi
|
|
762
|
+
echo " $0 dev # 개발 모드로 시작"
|
|
763
|
+
echo " $0 start # 현재 설정 그대로 시작(백그라운드)"
|
|
764
|
+
echo " $0 stop # 서버 중지"
|
|
765
|
+
echo " $0 stop --force # 포트 점유 프로세스를 이름 무관 강제 종료"
|
|
766
|
+
echo " $0 restart --force # 포트 기준 강제 종료 후 재시작"
|
|
767
|
+
echo " $0 status # 상태 조회"
|
|
632
768
|
fi
|
|
633
769
|
exit 0
|
|
634
770
|
fi
|
|
635
771
|
|
|
636
772
|
MODE="$1"
|
|
637
773
|
|
|
774
|
+
# --force: 프로세스명을 따지지 않고, 설정 포트를 점유한 PID 면 무조건 종료한다.
|
|
775
|
+
FORCE_STOP=0
|
|
776
|
+
for arg in "$@"; do
|
|
777
|
+
case "$arg" in
|
|
778
|
+
--force | -f)
|
|
779
|
+
FORCE_STOP=1
|
|
780
|
+
;;
|
|
781
|
+
esac
|
|
782
|
+
done
|
|
783
|
+
|
|
638
784
|
if [ ! -f "$SERVER_CONFIG" ]; then
|
|
639
785
|
if [ "$LANGUAGE" = "en" ]; then
|
|
640
786
|
echo "❌ configs/server.json not found"
|
|
@@ -666,6 +812,22 @@ fi
|
|
|
666
812
|
|
|
667
813
|
case "$MODE" in
|
|
668
814
|
dev|development)
|
|
815
|
+
# systemd 서비스로 등록된 환경에서는 dev 직접 실행을 막고 안내만 한다.
|
|
816
|
+
# (dev 는 설정을 development 로 바꾸고 포그라운드 실행하므로 systemd 운영과 충돌한다)
|
|
817
|
+
dev_svc=$(find_systemd_service || true)
|
|
818
|
+
if [ -n "$dev_svc" ]; then
|
|
819
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
820
|
+
echo "ℹ️ '$dev_svc' is registered as a systemd service; dev mode is disabled."
|
|
821
|
+
echo " Use: sudo systemctl start/stop/restart $dev_svc (or ./run.sh start|stop|restart)"
|
|
822
|
+
echo " To run dev mode, remove the service first: sudo ./scripts/service-remove.sh"
|
|
823
|
+
else
|
|
824
|
+
echo "ℹ️ '$dev_svc' 가 systemd 서비스로 등록되어 있어 dev 모드 실행을 막습니다."
|
|
825
|
+
echo " 사용: sudo systemctl start/stop/restart $dev_svc (또는 ./run.sh start|stop|restart)"
|
|
826
|
+
echo " dev 모드로 실행하려면 먼저 서비스를 제거하세요: sudo ./scripts/service-remove.sh"
|
|
827
|
+
fi
|
|
828
|
+
exit 0
|
|
829
|
+
fi
|
|
830
|
+
|
|
669
831
|
running_pid=$(find_active_server_pid || true)
|
|
670
832
|
if [ -n "$running_pid" ]; then
|
|
671
833
|
if [ "$LANGUAGE" = "en" ]; then
|
|
@@ -702,6 +864,11 @@ case "$MODE" in
|
|
|
702
864
|
echo " 재시작: sudo systemctl restart $svc"
|
|
703
865
|
exit 0
|
|
704
866
|
fi
|
|
867
|
+
# 부팅 시 자동 시작되도록 enable 까지 함께 켠다 (이미 enabled 면 멱등).
|
|
868
|
+
if [ "$(systemctl is-enabled "$svc" 2>/dev/null || true)" != "enabled" ]; then
|
|
869
|
+
echo "ℹ️ systemd 서비스 자동시작 등록(enable): $svc"
|
|
870
|
+
sudo systemctl enable "$svc" 2>/dev/null || true
|
|
871
|
+
fi
|
|
705
872
|
echo "ℹ️ systemd 서비스 시작: $svc"
|
|
706
873
|
sudo systemctl start "$svc"
|
|
707
874
|
echo "✅ ${SERVER_NAME} 시작 완료 (systemd)"
|
|
@@ -767,10 +934,23 @@ case "$MODE" in
|
|
|
767
934
|
;;
|
|
768
935
|
|
|
769
936
|
stop)
|
|
937
|
+
# 명시적 stop 은 부팅 자동시작도 끈다(disable). restart 는 이 경로를 타지 않으므로
|
|
938
|
+
# enable 상태가 유지된다. (start=enable 과 대칭)
|
|
939
|
+
stop_svc=$(find_systemd_service || true)
|
|
940
|
+
if [ -n "$stop_svc" ] && [ "$(systemctl is-enabled "$stop_svc" 2>/dev/null || true)" = "enabled" ]; then
|
|
941
|
+
echo "ℹ️ systemd 서비스 자동시작 해제(disable): $stop_svc"
|
|
942
|
+
sudo systemctl disable "$stop_svc" 2>/dev/null || true
|
|
943
|
+
fi
|
|
770
944
|
stop_server
|
|
771
945
|
;;
|
|
772
946
|
|
|
773
947
|
restart)
|
|
948
|
+
# --force restart: 포트 점유 프로세스를 이름 무관 강제 종료한 뒤 재기동한다.
|
|
949
|
+
if [ "$FORCE_STOP" -eq 1 ]; then
|
|
950
|
+
stop_server || exit $?
|
|
951
|
+
exec "$SCRIPT_DIR/run.sh" start
|
|
952
|
+
fi
|
|
953
|
+
|
|
774
954
|
svc=$(find_systemd_service || true)
|
|
775
955
|
if [ -n "$svc" ]; then
|
|
776
956
|
echo "ℹ️ systemd 서비스 재시작: $svc"
|
|
@@ -7,9 +7,17 @@ set -euo pipefail
|
|
|
7
7
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
8
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
9
9
|
|
|
10
|
-
# Load language from .env
|
|
10
|
+
# Load language and namespace from .env
|
|
11
|
+
# run.sh 와 동일한 서비스명을 산출하기 위해 SERVER_NAMESPACE/NAMESPACE 를 .env 에서 읽는다.
|
|
12
|
+
# (run.sh 는 .env 를 source 하므로, 여기서도 같은 값을 반영하지 않으면 서비스명이 어긋난다.)
|
|
11
13
|
if [ -f "$PROJECT_ROOT/.env" ]; then
|
|
12
14
|
LANGUAGE=$(sed -n 's/^LANGUAGE=//p' "$PROJECT_ROOT/.env" | tail -n 1)
|
|
15
|
+
if [ -z "${SERVER_NAMESPACE:-}" ]; then
|
|
16
|
+
SERVER_NAMESPACE=$(sed -n 's/^SERVER_NAMESPACE=//p' "$PROJECT_ROOT/.env" | tail -n 1)
|
|
17
|
+
fi
|
|
18
|
+
if [ -z "${NAMESPACE:-}" ]; then
|
|
19
|
+
NAMESPACE=$(sed -n 's/^NAMESPACE=//p' "$PROJECT_ROOT/.env" | tail -n 1)
|
|
20
|
+
fi
|
|
13
21
|
fi
|
|
14
22
|
LANGUAGE=${LANGUAGE:-ko}
|
|
15
23
|
|
|
@@ -65,6 +73,19 @@ if [ "$EUID" -ne 0 ]; then
|
|
|
65
73
|
exit 1
|
|
66
74
|
fi
|
|
67
75
|
|
|
76
|
+
# 이미 등록되어 있는지 먼저 확인한다. 등록돼 있으면 기존 ExecStart 와 함께 안내하고
|
|
77
|
+
# 재등록(덮어쓰기)으로 진행한다. (경로 변경 등으로 재설치가 필요한 경우가 있으므로 막지 않는다)
|
|
78
|
+
if systemctl list-unit-files 2>/dev/null | grep -q "^${SERVICE_NAME}\.service" || [ -f "$UNIT_PATH" ]; then
|
|
79
|
+
existing_exec=$(systemctl show -p ExecStart --value "${SERVICE_NAME}.service" 2>/dev/null || true)
|
|
80
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
81
|
+
echo "ℹ️ Service '$SERVICE_NAME' is already registered. Re-installing (overwrite)."
|
|
82
|
+
[ -n "$existing_exec" ] && echo " current ExecStart: $existing_exec"
|
|
83
|
+
else
|
|
84
|
+
echo "ℹ️ '$SERVICE_NAME' 서비스가 이미 등록되어 있습니다. 재등록(덮어쓰기)합니다."
|
|
85
|
+
[ -n "$existing_exec" ] && echo " 현재 ExecStart: $existing_exec"
|
|
86
|
+
fi
|
|
87
|
+
fi
|
|
88
|
+
|
|
68
89
|
cat > "$UNIT_PATH" <<EOF
|
|
69
90
|
[Unit]
|
|
70
91
|
Description=Entity Server
|
|
@@ -7,9 +7,17 @@ set -euo pipefail
|
|
|
7
7
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
8
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
9
9
|
|
|
10
|
-
# Load language from .env
|
|
10
|
+
# Load language and namespace from .env
|
|
11
|
+
# run.sh 와 동일한 서비스명을 산출하기 위해 SERVER_NAMESPACE/NAMESPACE 를 .env 에서 읽는다.
|
|
12
|
+
# (run.sh 는 .env 를 source 하므로, 여기서도 같은 값을 반영하지 않으면 서비스명이 어긋난다.)
|
|
11
13
|
if [ -f "$PROJECT_ROOT/.env" ]; then
|
|
12
14
|
LANGUAGE=$(sed -n 's/^LANGUAGE=//p' "$PROJECT_ROOT/.env" | tail -n 1)
|
|
15
|
+
if [ -z "${SERVER_NAMESPACE:-}" ]; then
|
|
16
|
+
SERVER_NAMESPACE=$(sed -n 's/^SERVER_NAMESPACE=//p' "$PROJECT_ROOT/.env" | tail -n 1)
|
|
17
|
+
fi
|
|
18
|
+
if [ -z "${NAMESPACE:-}" ]; then
|
|
19
|
+
NAMESPACE=$(sed -n 's/^NAMESPACE=//p' "$PROJECT_ROOT/.env" | tail -n 1)
|
|
20
|
+
fi
|
|
13
21
|
fi
|
|
14
22
|
LANGUAGE=${LANGUAGE:-ko}
|
|
15
23
|
|
|
@@ -54,6 +62,31 @@ for arg in "$@"; do
|
|
|
54
62
|
esac
|
|
55
63
|
done
|
|
56
64
|
|
|
65
|
+
UNIT_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
|
|
66
|
+
|
|
67
|
+
# 제거를 묻기 전에 서비스가 실제로 등록되어 있는지 먼저 확인한다.
|
|
68
|
+
# (등록되어 있지 않으면 묻지 않고 안내만 출력하고 종료한다.)
|
|
69
|
+
SERVICE_EXISTS=false
|
|
70
|
+
if systemctl list-unit-files 2>/dev/null | grep -q "^${SERVICE_NAME}\.service"; then
|
|
71
|
+
SERVICE_EXISTS=true
|
|
72
|
+
fi
|
|
73
|
+
if [ ! -f "$UNIT_PATH" ] && [ "$SERVICE_EXISTS" = false ]; then
|
|
74
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
75
|
+
echo "ℹ️ Service '$SERVICE_NAME' is not registered."
|
|
76
|
+
echo " Nothing to remove."
|
|
77
|
+
echo ""
|
|
78
|
+
echo " To register the service, run:"
|
|
79
|
+
echo " sudo $(dirname "$0")/service-install.sh"
|
|
80
|
+
else
|
|
81
|
+
echo "ℹ️ '$SERVICE_NAME' 서비스가 등록되어 있지 않습니다."
|
|
82
|
+
echo " 제거할 항목이 없습니다."
|
|
83
|
+
echo ""
|
|
84
|
+
echo " 서비스를 등록하려면:"
|
|
85
|
+
echo " sudo $(dirname "$0")/service-install.sh"
|
|
86
|
+
fi
|
|
87
|
+
exit 0
|
|
88
|
+
fi
|
|
89
|
+
|
|
57
90
|
if [ "$INTERACTIVE" = true ] && [ "$CONFIRMED" = false ]; then
|
|
58
91
|
if [ "$LANGUAGE" = "en" ]; then
|
|
59
92
|
echo "[interactive] systemd service removal"
|
|
@@ -79,8 +112,6 @@ if [ "$INTERACTIVE" = true ] && [ "$CONFIRMED" = false ]; then
|
|
|
79
112
|
fi
|
|
80
113
|
fi
|
|
81
114
|
|
|
82
|
-
UNIT_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
|
|
83
|
-
|
|
84
115
|
if [ "$EUID" -ne 0 ]; then
|
|
85
116
|
if command -v sudo >/dev/null 2>&1; then
|
|
86
117
|
exec sudo "$0" --yes
|
|
@@ -93,27 +124,6 @@ if [ "$EUID" -ne 0 ]; then
|
|
|
93
124
|
exit 1
|
|
94
125
|
fi
|
|
95
126
|
|
|
96
|
-
SERVICE_EXISTS=false
|
|
97
|
-
if systemctl list-unit-files | grep -q "^${SERVICE_NAME}\.service"; then
|
|
98
|
-
SERVICE_EXISTS=true
|
|
99
|
-
fi
|
|
100
|
-
if [ ! -f "$UNIT_PATH" ] && [ "$SERVICE_EXISTS" = false ]; then
|
|
101
|
-
if [ "$LANGUAGE" = "en" ]; then
|
|
102
|
-
echo "ℹ️ Service '$SERVICE_NAME' is not registered."
|
|
103
|
-
echo " Nothing to remove."
|
|
104
|
-
echo ""
|
|
105
|
-
echo " To register the service, run:"
|
|
106
|
-
echo " sudo $(dirname "$0")/service-install.sh"
|
|
107
|
-
else
|
|
108
|
-
echo "ℹ️ '$SERVICE_NAME' 서비스가 등록되어 있지 않습니다."
|
|
109
|
-
echo " 제거할 항목이 없습니다."
|
|
110
|
-
echo ""
|
|
111
|
-
echo " 서비스를 등록하려면:"
|
|
112
|
-
echo " sudo $(dirname "$0")/service-install.sh"
|
|
113
|
-
fi
|
|
114
|
-
exit 0
|
|
115
|
-
fi
|
|
116
|
-
|
|
117
127
|
if [ "$SERVICE_EXISTS" = true ]; then
|
|
118
128
|
systemctl stop "$SERVICE_NAME" 2>/dev/null || true
|
|
119
129
|
systemctl disable "$SERVICE_NAME" 2>/dev/null || true
|