diff --git a/exAiChatBot-chatbot2.0-agent b/exAiChatBot-chatbot2.0-agent index aa4a80a..74d37bc 160000 --- a/exAiChatBot-chatbot2.0-agent +++ b/exAiChatBot-chatbot2.0-agent @@ -1 +1 @@ -Subproject commit aa4a80abcb54fff21b778ea6d9fb091ab65cf6dc +Subproject commit 74d37bc5e5c8ab116cb5fa68ed583c5e9defcc08 diff --git a/local-dev/bin/rsync b/local-dev/bin/rsync new file mode 100755 index 0000000..59b082d --- /dev/null +++ b/local-dev/bin/rsync @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +# Minimal rsync stand-in for Windows Git Bash (tar-over-ssh). +# Supports the flags used by server-dev/sync-submodules-rsync.sh: +# rsync -az [--delete] [--exclude PATTERN ...] SRC/ HOST:DEST/ +set -euo pipefail + +DELETE=false +EXCLUDES=() +ARGS=() + +while (($#)); do + case "$1" in + -az|-a|-z|-v|-q|-P|--progress) shift ;; + --delete) DELETE=true; shift ;; + --exclude) + EXCLUDES+=("$2"); shift 2 ;; + --exclude=*) + EXCLUDES+=("${1#--exclude=}"); shift ;; + -*) + # ignore unknown short/long flags used by callers + shift ;; + *) + ARGS+=("$1"); shift ;; + esac +done + +if ((${#ARGS[@]} < 2)); then + echo "rsync-shim: need SRC and DEST" >&2 + exit 1 +fi + +SRC="${ARGS[0]}" +DEST="${ARGS[1]}" + +# Git Bash /d/foo → Windows D:/foo (OpenSSH scp 용) +to_win_path() { + local p="$1" + if [[ "${p}" =~ ^/([a-zA-Z])/(.*)$ ]]; then + local drive rest + drive="$(echo "${BASH_REMATCH[1]}" | tr 'a-z' 'A-Z')" + rest="${BASH_REMATCH[2]}" + echo "${drive}:/${rest}" + else + echo "${p}" + fi +} + +copy_file_remote() { + local src_file="$1" + local dest="$2" + local win_src + win_src="$(to_win_path "${src_file}")" + if [[ -f "${win_src}" || -f "${src_file}" ]]; then + local local_src="${src_file}" + [[ -f "${win_src}" ]] && local_src="${win_src}" + scp -o BatchMode=yes -q "${local_src}" "${dest}" && return 0 + fi + # fallback: tar stream single file + local base dir + base="$(basename "${src_file}")" + dir="$(cd "$(dirname "${src_file}")" && pwd)" + local host="${dest%%:*}" + local remote="${dest#*:}" + local remote_dir remote_base + if [[ "${remote}" == */ ]]; then + remote_dir="${remote%/}" + remote_base="${base}" + else + remote_dir="$(dirname "${remote}")" + remote_base="$(basename "${remote}")" + fi + ssh -o BatchMode=yes "${host}" "mkdir -p '${remote_dir}'" + tar -C "${dir}" -cf - "${base}" \ + | ssh -o BatchMode=yes "${host}" "tar -C '${remote_dir}' -xf - && if [[ '${remote_base}' != '${base}' ]]; then mv '${remote_dir}/${base}' '${remote_dir}/${remote_base}'; fi" +} + +# file → file copy (overlay yml etc.) +if [[ -f "${SRC}" && "${DEST}" == *:* ]]; then + copy_file_remote "${SRC}" "${DEST}" + exit 0 +fi + +# normalize trailing slash semantics like rsync SRC/ +SRC_DIR="${SRC%/}" +if [[ ! -d "${SRC_DIR}" ]]; then + # allow copying a single file into a remote dir + if [[ -f "${SRC_DIR}" ]]; then + copy_file_remote "${SRC_DIR}" "${DEST}" + exit 0 + fi + echo "rsync-shim: source not found: ${SRC}" >&2 + exit 1 +fi + +if [[ "${DEST}" != *:* ]]; then + echo "rsync-shim: only remote DEST (host:path) supported" >&2 + exit 1 +fi + +HOST="${DEST%%:*}" +REMOTE_PATH="${DEST#*:}" +REMOTE_PATH="${REMOTE_PATH%/}" + +TAR_EXCLUDES=() +for pat in "${EXCLUDES[@]}"; do + TAR_EXCLUDES+=(--exclude "${pat}") +done + +ssh -o BatchMode=yes "${HOST}" "mkdir -p '${REMOTE_PATH}'" + +if $DELETE; then + # wipe remote dir contents then unpack (approx --delete) + # 서버 public-* 등이 root/docker 소유일 수 있어 실패해도 이어서 덮어쓴다 + ssh -o BatchMode=yes "${HOST}" \ + "chmod -R u+w '${REMOTE_PATH}' 2>/dev/null || true; \ + find '${REMOTE_PATH}' -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null || true" \ + || true +fi + +# shellcheck disable=SC2086 +tar -C "${SRC_DIR}" "${TAR_EXCLUDES[@]}" -cf - . \ + | ssh -o BatchMode=yes "${HOST}" "tar -C '${REMOTE_PATH}' -xf -" + +echo "rsync-shim: synced ${SRC_DIR}/ -> ${HOST}:${REMOTE_PATH}/" diff --git a/local-dev/run-start-all-server-windows.sh b/local-dev/run-start-all-server-windows.sh new file mode 100755 index 0000000..73825ce --- /dev/null +++ b/local-dev/run-start-all-server-windows.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Windows (Git Bash) helper for ./start-all-server.sh +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +export PATH="${ROOT_DIR}/local-dev/bin:/c/Program Files/nodejs:/c/Program Files/Git/usr/bin:${PATH}" +export GIT_SSH_COMMAND="${GIT_SSH_COMMAND:-ssh -o BatchMode=yes -o ConnectTimeout=20}" +# Git Bash/MSYS 가 /chatbot/app 같은 env 를 Windows 경로로 바꾸지 않게 +export MSYS_NO_PATHCONV=1 +export MSYS2_ARG_CONV_EXCL='*' + +# Prefer Windows OpenSSH (has the exdev key) +if [[ -x /c/Windows/System32/OpenSSH/ssh.exe ]]; then + export GIT_SSH_COMMAND="/c/Windows/System32/OpenSSH/ssh.exe -o BatchMode=yes -o ConnectTimeout=20" + export PATH="/c/Windows/System32/OpenSSH:${PATH}" +fi + +cd "${ROOT_DIR}" +echo "[windows] node=$(command -v node) $(node -v 2>/dev/null || true)" +echo "[windows] npm=$(command -v npm)" +echo "[windows] rsync=$(command -v rsync)" +echo "[windows] ssh=$(command -v ssh)" + +# smoke checks +ssh -o BatchMode=yes -o ConnectTimeout=15 aidev@chatbot.exdev.co.kr 'echo SSH_CHATBOT_OK' +git ls-remote origin HEAD >/dev/null +echo "[windows] Gitea git OK" + +exec bash ./start-all-server.sh "$@"