[DB 선택 대화형 프롬프트] - setup/lib/db_select.sh: 설치 시 SQLite/PostgreSQL/PostgreSQL+pgvector 선택 - DB_TYPE 환경변수로 무인 설치 지원 - pgvector 자동 빌드/설치 (소스 빌드 폴백 포함) - .env DATABASE_URL 자동 기록 [Vector DB] - docker-compose.yml: postgres를 pgvector/pgvector:pg15 이미지로 교체 - Qdrant: docker profile=vector 로 선택적 활성화 - docs/vector_db_guide.md: pgvector/Qdrant 사용법 + 시나리오 [Gitea 온프레미스 Git 서버] - docker-compose.yml: gitea/gitea:1.21-rootless 서비스 추가 - setup/lib/gitea_setup.sh: 공통 설치/초기화 함수 - setup/gitea_init.sh: 독립 실행형 초기화 스크립트 - 관리자 계정 생성 - guardia 조직 + GUARDiA 저장소 생성 - main 브랜치 보호 (PR + 리뷰 1명 필수) - develop 브랜치 생성 - 개발자 계정 (engineer1/2, pm1, admin) + feature/이름/init 브랜치 자동 생성 - 현재 소스 자동 push [브랜치 전략] main : 보호 브랜치, PR 필수, 리뷰 1명 필수 develop : 통합 브랜치, force-push 금지 feature/이름/기능: 개인 개발 브랜치 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
299 lines
9.9 KiB
Bash
299 lines
9.9 KiB
Bash
#!/bin/bash
|
|
# ==============================================================
|
|
# GUARDiA Gitea 설치 + 자동 초기화 공통 함수
|
|
# ==============================================================
|
|
# 기능:
|
|
# - Gitea 바이너리 설치 및 systemd 등록
|
|
# - 관리자 계정 자동 생성
|
|
# - GUARDiA 조직 + 레파지토리 생성
|
|
# - 개발자 계정 + 개인 브랜치 자동 생성
|
|
# - main 브랜치 보호 (PR 필수)
|
|
#
|
|
# 브랜치 전략:
|
|
# main - 보호 브랜치, PR + 리뷰 1명 필수
|
|
# develop - 통합 브랜치
|
|
# feature/이름/기능명 - 개인 개발 브랜치
|
|
# ==============================================================
|
|
|
|
GITEA_VER="${GITEA_VER:-1.21.11}"
|
|
GITEA_HOME="/opt/gitea"
|
|
GITEA_DATA="/var/lib/gitea"
|
|
GITEA_PORT="${GITEA_PORT:-3000}"
|
|
GITEA_ADMIN="${GITEA_ADMIN:-gitadmin}"
|
|
GITEA_ADMIN_PW="${GITEA_ADMIN_PW:-Gitea@guardia!}"
|
|
GITEA_ADMIN_EMAIL="${GITEA_ADMIN_EMAIL:-admin@guardia.local}"
|
|
GITEA_ORG="${GITEA_ORG:-guardia}"
|
|
GITEA_REPO="${GITEA_REPO:-GUARDiA}"
|
|
GITEA_BASE="http://localhost:${GITEA_PORT}"
|
|
GITEA_MIRROR="${GITEA_MIRROR:-https://dl.gitea.com/gitea/${GITEA_VER}}"
|
|
|
|
|
|
install_gitea() {
|
|
echo ""
|
|
echo "=== Gitea 설치 (포트 ${GITEA_PORT}) ==="
|
|
|
|
# 1. 시스템 계정 생성
|
|
id git &>/dev/null || useradd -r -s /bin/bash -d "$GITEA_DATA" git
|
|
|
|
# 2. 디렉토리 생성
|
|
mkdir -p "$GITEA_HOME" "$GITEA_DATA"/{custom,data,log,repositories}
|
|
chown -R git:git "$GITEA_DATA"
|
|
|
|
# 3. 바이너리 설치
|
|
ARCH="$(uname -m)"
|
|
case "$ARCH" in
|
|
x86_64) GITEA_ARCH="amd64" ;;
|
|
aarch64) GITEA_ARCH="arm64" ;;
|
|
*) GITEA_ARCH="amd64" ;;
|
|
esac
|
|
|
|
GITEA_BIN="gitea-${GITEA_VER}-linux-${GITEA_ARCH}"
|
|
|
|
if [[ ! -f "/usr/local/bin/gitea" ]]; then
|
|
info "Gitea $GITEA_VER 다운로드..."
|
|
wget -q "${GITEA_MIRROR}/${GITEA_BIN}" -O /tmp/gitea \
|
|
|| fail "Gitea 다운로드 실패 — GITEA_MIRROR 환경변수 설정"
|
|
install -m 755 /tmp/gitea /usr/local/bin/gitea
|
|
ok "Gitea 바이너리 설치: /usr/local/bin/gitea"
|
|
else
|
|
info "Gitea 이미 설치됨"
|
|
fi
|
|
|
|
# 4. Gitea 설정 파일
|
|
mkdir -p "$GITEA_DATA/custom/conf"
|
|
cat > "$GITEA_DATA/custom/conf/app.ini" << APPINI
|
|
[DEFAULT]
|
|
RUN_USER = git
|
|
RUN_MODE = prod
|
|
|
|
[server]
|
|
HTTP_ADDR = 0.0.0.0
|
|
HTTP_PORT = ${GITEA_PORT}
|
|
ROOT_URL = http://localhost:${GITEA_PORT}/
|
|
DISABLE_SSH = false
|
|
SSH_PORT = 22022
|
|
|
|
[database]
|
|
DB_TYPE = sqlite3
|
|
PATH = ${GITEA_DATA}/data/gitea.db
|
|
|
|
[repository]
|
|
ROOT = ${GITEA_DATA}/repositories
|
|
|
|
[log]
|
|
ROOT_PATH = ${GITEA_DATA}/log
|
|
MODE = file
|
|
LEVEL = info
|
|
|
|
[security]
|
|
INSTALL_LOCK = true
|
|
SECRET_KEY = $(openssl rand -hex 32 2>/dev/null || date | md5sum | head -c 32)
|
|
INTERNAL_TOKEN = $(openssl rand -hex 32 2>/dev/null || date +%s | md5sum | head -c 32)
|
|
|
|
[service]
|
|
DISABLE_REGISTRATION = false
|
|
REQUIRE_SIGNIN_VIEW = false
|
|
DEFAULT_KEEP_EMAIL_PRIVATE = true
|
|
|
|
[git]
|
|
DEFAULT_BRANCH = main
|
|
APPINI
|
|
|
|
chown -R git:git "$GITEA_DATA"
|
|
|
|
# 5. systemd 서비스
|
|
cat > /etc/systemd/system/gitea.service << GITSVC
|
|
[Unit]
|
|
Description=Gitea (Git service)
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=git
|
|
Group=git
|
|
WorkingDirectory=${GITEA_DATA}
|
|
Environment="USER=git" "HOME=${GITEA_DATA}" "GITEA_WORK_DIR=${GITEA_DATA}"
|
|
ExecStart=/usr/local/bin/gitea web --config ${GITEA_DATA}/custom/conf/app.ini
|
|
Restart=always
|
|
RestartSec=3
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
GITSVC
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable gitea
|
|
systemctl start gitea
|
|
|
|
# Gitea 기동 대기
|
|
info "Gitea 기동 대기 중..."
|
|
local attempt=0
|
|
until curl -sf "http://localhost:${GITEA_PORT}/api/v1/version" -o /dev/null 2>/dev/null; do
|
|
sleep 3
|
|
((attempt++))
|
|
[[ $attempt -ge 20 ]] && { warn "Gitea 기동 타임아웃"; break; }
|
|
done
|
|
ok "Gitea 서비스 시작 완료 (http://localhost:${GITEA_PORT})"
|
|
}
|
|
|
|
|
|
init_gitea_repos() {
|
|
echo ""
|
|
echo "=== Gitea 초기화 (조직·저장소·브랜치) ==="
|
|
|
|
local api="${GITEA_BASE}/api/v1"
|
|
local auth_header="Authorization: Basic $(echo -n "${GITEA_ADMIN}:${GITEA_ADMIN_PW}" | base64)"
|
|
|
|
# 1. 관리자 계정 생성
|
|
_wait_gitea
|
|
|
|
gitea admin user create \
|
|
--username "$GITEA_ADMIN" \
|
|
--password "$GITEA_ADMIN_PW" \
|
|
--email "$GITEA_ADMIN_EMAIL" \
|
|
--admin \
|
|
--config "$GITEA_DATA/custom/conf/app.ini" \
|
|
2>/dev/null || info "관리자 계정 이미 존재"
|
|
|
|
ok "관리자 계정: $GITEA_ADMIN"
|
|
|
|
# 2. 조직 생성
|
|
curl -sf -X POST "$api/orgs" \
|
|
-H "$auth_header" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"username\":\"${GITEA_ORG}\",\"visibility\":\"private\",\"description\":\"GUARDiA ITSM\"}" \
|
|
-o /dev/null 2>/dev/null \
|
|
|| info "조직 이미 존재: $GITEA_ORG"
|
|
ok "조직 생성: $GITEA_ORG"
|
|
|
|
# 3. GUARDiA 메인 저장소 생성
|
|
curl -sf -X POST "$api/orgs/${GITEA_ORG}/repos" \
|
|
-H "$auth_header" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"name\":\"${GITEA_REPO}\",\"description\":\"GUARDiA ITSM 플랫폼\",\"private\":true,\"default_branch\":\"main\",\"auto_init\":true}" \
|
|
-o /dev/null 2>/dev/null \
|
|
|| info "저장소 이미 존재: ${GITEA_ORG}/${GITEA_REPO}"
|
|
ok "저장소 생성: ${GITEA_ORG}/${GITEA_REPO}"
|
|
|
|
# 초기화 후 저장소가 생성될 때까지 대기
|
|
sleep 3
|
|
|
|
# 4. develop 브랜치 생성
|
|
curl -sf -X POST "$api/repos/${GITEA_ORG}/${GITEA_REPO}/branches" \
|
|
-H "$auth_header" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"new_branch_name":"develop","old_branch_name":"main"}' \
|
|
-o /dev/null 2>/dev/null \
|
|
|| info "develop 브랜치 이미 존재"
|
|
ok "develop 브랜치 생성"
|
|
|
|
# 5. main 브랜치 보호 규칙 설정 (PR 필수)
|
|
curl -sf -X POST "$api/repos/${GITEA_ORG}/${GITEA_REPO}/branch_protections" \
|
|
-H "$auth_header" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"branch_name": "main",
|
|
"enable_push": false,
|
|
"enable_push_whitelist": true,
|
|
"push_whitelist_usernames": ["'"${GITEA_ADMIN}"'"],
|
|
"require_signed_commits": false,
|
|
"enable_status_check": false,
|
|
"required_approvals": 1,
|
|
"enable_approvals_whitelist": false,
|
|
"merge_whitelist_usernames": ["'"${GITEA_ADMIN}"'"]
|
|
}' \
|
|
-o /dev/null 2>/dev/null \
|
|
|| info "main 브랜치 보호 이미 설정됨"
|
|
ok "main 브랜치 보호 설정 (PR + 리뷰 1명 필수)"
|
|
|
|
# 6. 현재 Git 소스를 Gitea에 push
|
|
if [[ -d "${GUARDIA_ROOT:-/opt/guardia}/.git" ]]; then
|
|
info "기존 소스를 Gitea에 push..."
|
|
local gitea_url="http://${GITEA_ADMIN}:${GITEA_ADMIN_PW}@localhost:${GITEA_PORT}/${GITEA_ORG}/${GITEA_REPO}.git"
|
|
git -C "${GUARDIA_ROOT:-/opt/guardia}" remote remove gitea 2>/dev/null || true
|
|
git -C "${GUARDIA_ROOT:-/opt/guardia}" remote add gitea "$gitea_url"
|
|
git -C "${GUARDIA_ROOT:-/opt/guardia}" push gitea main 2>/dev/null \
|
|
&& ok "소스 push 완료 → Gitea main 브랜치" \
|
|
|| warn "소스 push 실패 — 나중에 수동으로 push"
|
|
git -C "${GUARDIA_ROOT:-/opt/guardia}" push gitea develop 2>/dev/null || true
|
|
fi
|
|
|
|
ok "Gitea 초기화 완료"
|
|
echo ""
|
|
info "Gitea URL: http://localhost:${GITEA_PORT}"
|
|
info "관리자 계정: ${GITEA_ADMIN} / ${GITEA_ADMIN_PW}"
|
|
info "저장소: ${GITEA_BASE}/${GITEA_ORG}/${GITEA_REPO}"
|
|
info ""
|
|
info "=== 브랜치 전략 ==="
|
|
info " main : 보호 브랜치 (PR + 리뷰 1명 필수)"
|
|
info " develop : 통합 브랜치 (feature 브랜치 merge 대상)"
|
|
info " feature/이름/기능명 : 개인 개발 브랜치"
|
|
info ""
|
|
info " 새 개발자 브랜치 생성:"
|
|
info " git checkout develop"
|
|
info " git checkout -b feature/홍길동/신기능"
|
|
info " git push -u gitea feature/홍길동/신기능"
|
|
}
|
|
|
|
|
|
create_dev_user() {
|
|
local username="$1"
|
|
local password="${2:-Dev@guardia!}"
|
|
local email="${3:-${username}@guardia.local}"
|
|
|
|
local api="${GITEA_BASE}/api/v1"
|
|
local auth_header="Authorization: Basic $(echo -n "${GITEA_ADMIN}:${GITEA_ADMIN_PW}" | base64)"
|
|
|
|
# 사용자 생성
|
|
curl -sf -X POST "$api/admin/users" \
|
|
-H "$auth_header" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"username\":\"${username}\",\"password\":\"${password}\",\"email\":\"${email}\",\"login_name\":\"${username}\",\"source_id\":0,\"send_notify\":false,\"must_change_password\":false}" \
|
|
-o /dev/null 2>/dev/null \
|
|
|| { info "사용자 이미 존재: $username"; return; }
|
|
|
|
# 조직에 팀 멤버 추가
|
|
local team_id
|
|
team_id=$(curl -sf "$api/orgs/${GITEA_ORG}/teams" \
|
|
-H "$auth_header" 2>/dev/null \
|
|
| python3 -c "import sys,json; teams=json.load(sys.stdin); t=[t for t in teams if t.get('name')=='Developers']; print(t[0]['id'] if t else '')" 2>/dev/null)
|
|
|
|
if [[ -z "$team_id" ]]; then
|
|
# Developers 팀 생성
|
|
team_id=$(curl -sf -X POST "$api/orgs/${GITEA_ORG}/teams" \
|
|
-H "$auth_header" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"name\":\"Developers\",\"permission\":\"write\",\"units\":[\"repo.code\",\"repo.issues\",\"repo.pulls\"]}" \
|
|
2>/dev/null \
|
|
| python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null)
|
|
fi
|
|
|
|
if [[ -n "$team_id" ]]; then
|
|
# 팀에 사용자 추가
|
|
curl -sf -X PUT "$api/teams/${team_id}/members/${username}" \
|
|
-H "$auth_header" -o /dev/null 2>/dev/null
|
|
# 팀에 저장소 추가
|
|
curl -sf -X PUT "$api/teams/${team_id}/repos/${GITEA_ORG}/${GITEA_REPO}" \
|
|
-H "$auth_header" -o /dev/null 2>/dev/null
|
|
fi
|
|
|
|
# 개인 브랜치 생성 (feature/이름/init)
|
|
curl -sf -X POST "$api/repos/${GITEA_ORG}/${GITEA_REPO}/branches" \
|
|
-H "$auth_header" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"new_branch_name\":\"feature/${username}/init\",\"old_branch_name\":\"develop\"}" \
|
|
-o /dev/null 2>/dev/null
|
|
|
|
ok "개발자 계정 + 브랜치 생성: $username (feature/${username}/init)"
|
|
}
|
|
|
|
|
|
_wait_gitea() {
|
|
local attempt=0
|
|
until curl -sf "http://localhost:${GITEA_PORT}/api/v1/version" -o /dev/null 2>/dev/null; do
|
|
sleep 2
|
|
((attempt++))
|
|
[[ $attempt -ge 30 ]] && { fail "Gitea 서비스 응답 없음"; return; }
|
|
done
|
|
}
|