|
|
|
|
@ -75,37 +75,92 @@ public class WarSyncScheduler {
|
|
|
|
|
log.info("[배포] SFTP 업테이트 서버 연결 성공");
|
|
|
|
|
|
|
|
|
|
// 리모트 파일 속성
|
|
|
|
|
// todo : 데브환경 분기처리
|
|
|
|
|
SftpATTRS attrs = null;
|
|
|
|
|
if(activeProfile.equals("prod")){
|
|
|
|
|
String ftpDir;
|
|
|
|
|
SftpATTRS attrs;
|
|
|
|
|
if (activeProfile.equals("prod")) {
|
|
|
|
|
attrs = sftp.lstat(REMOTE_CC_WAR_PATH);
|
|
|
|
|
ftpDir = REMOTE_CC_WAR_PATH;
|
|
|
|
|
} else {
|
|
|
|
|
attrs = sftp.lstat(REMOTE_CC_WAR_DEV_PATH);
|
|
|
|
|
ftpDir = REMOTE_CC_WAR_DEV_PATH;
|
|
|
|
|
}
|
|
|
|
|
log.info("--- " + activeProfile + " ---");
|
|
|
|
|
|
|
|
|
|
long remoteSize = attrs.getSize();
|
|
|
|
|
int remoteMtime = attrs.getMTime();
|
|
|
|
|
|
|
|
|
|
// 메타파일 비교
|
|
|
|
|
boolean isUpdated = isWarUpdated(remoteSize, remoteMtime);
|
|
|
|
|
log.info("[배포] 변경감지");
|
|
|
|
|
log.info("[배포] 변경감지: " + isUpdated);
|
|
|
|
|
|
|
|
|
|
// 변경 없을 때도 실행 상태 확인
|
|
|
|
|
if (!isUpdated) {
|
|
|
|
|
log.info("[배포] 변경 없음. 스킵");
|
|
|
|
|
log.info("[배포] 변경 없음. 실행 상태 확인");
|
|
|
|
|
|
|
|
|
|
boolean needRun = true;
|
|
|
|
|
|
|
|
|
|
if (Files.exists(PID_FILE_PATH)) {
|
|
|
|
|
long pid = Long.parseLong(Files.readString(PID_FILE_PATH).trim());
|
|
|
|
|
boolean isAlive = ProcessHandle.of(pid).map(ProcessHandle::isAlive).orElse(false);
|
|
|
|
|
|
|
|
|
|
if (isAlive) {
|
|
|
|
|
String cmdline = "";
|
|
|
|
|
try {
|
|
|
|
|
cmdline = Files.readString(Path.of("/proc/" + pid + "/cmdline"));
|
|
|
|
|
} catch (IOException ignored) {}
|
|
|
|
|
|
|
|
|
|
if (cmdline.contains("cc-server")) { // ← 실제 WAR 명칭으로 변경
|
|
|
|
|
log.info("[배포] 프로세스는 살아 있고 동일 앱입니다. 스킵");
|
|
|
|
|
needRun = false;
|
|
|
|
|
} else {
|
|
|
|
|
log.warn("[배포] PID 살아있지만 다른 앱입니다. PID 제거");
|
|
|
|
|
Files.deleteIfExists(PID_FILE_PATH);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
log.warn("[배포] PID 살아있지 않음. 제거 후 재실행");
|
|
|
|
|
Files.deleteIfExists(PID_FILE_PATH);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (needRun) {
|
|
|
|
|
log.info("[배포] 앱 실행 중 아님. 기존 WAR로 재실행");
|
|
|
|
|
runWar();
|
|
|
|
|
log.info("[배포] 재실행 완료 (변경 없음)");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 변경 있음 → 배포 절차 실행
|
|
|
|
|
|
|
|
|
|
// 다운로드
|
|
|
|
|
try (InputStream in = sftp.get(REMOTE_CC_WAR_PATH)) {
|
|
|
|
|
try (InputStream in = sftp.get(ftpDir)) {
|
|
|
|
|
Files.copy(in, LOCAL_TMP_PATH, StandardCopyOption.REPLACE_EXISTING);
|
|
|
|
|
log.info("[배포] SFTP 다운로드 완료");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 실행 중이면 종료
|
|
|
|
|
killPreviousWar();
|
|
|
|
|
log.info("[배포] 프로세스 kill");
|
|
|
|
|
|
|
|
|
|
// 킬하고 기존에 war를 백업으로 이동해야함
|
|
|
|
|
// 롤백을 위함.
|
|
|
|
|
if (Files.exists(PID_FILE_PATH)) {
|
|
|
|
|
long pid = Long.parseLong(Files.readString(PID_FILE_PATH).trim());
|
|
|
|
|
boolean isAlive = ProcessHandle.of(pid).map(ProcessHandle::isAlive).orElse(false);
|
|
|
|
|
|
|
|
|
|
if (isAlive) {
|
|
|
|
|
String cmdline = "";
|
|
|
|
|
try {
|
|
|
|
|
cmdline = Files.readString(Path.of("/proc/" + pid + "/cmdline"));
|
|
|
|
|
} catch (IOException ignored) {}
|
|
|
|
|
|
|
|
|
|
if (cmdline.contains("cc-server")) {
|
|
|
|
|
killPreviousWar();
|
|
|
|
|
log.info("[배포] 기존 프로세스 종료 완료");
|
|
|
|
|
} else {
|
|
|
|
|
log.warn("[배포] PID 살아있지만 다른 앱. PID 제거");
|
|
|
|
|
Files.deleteIfExists(PID_FILE_PATH);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
log.warn("[배포] PID 존재하나 죽어있음. 제거");
|
|
|
|
|
Files.deleteIfExists(PID_FILE_PATH);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 교체
|
|
|
|
|
Files.move(LOCAL_TMP_PATH, LOCAL_WAR_PATH, StandardCopyOption.REPLACE_EXISTING);
|
|
|
|
|
@ -128,6 +183,7 @@ public class WarSyncScheduler {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 변경 체크 (파일 사이즈, 수정시간)
|
|
|
|
|
private boolean isWarUpdated(long remoteSize, int remoteMtime) throws IOException {
|
|
|
|
|
if (!Files.exists(META_FILE_PATH)) return true;
|
|
|
|
|
@ -169,4 +225,8 @@ public class WarSyncScheduler {
|
|
|
|
|
Files.writeString(PID_FILE_PATH, String.valueOf(process.pid()));
|
|
|
|
|
log.info("[배포] 새 PID 저장: " + process.pid());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean isProcessAlive(long pid) {
|
|
|
|
|
return ProcessHandle.of(pid).map(ProcessHandle::isAlive).orElse(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|