"""서버 로컬에서 Gitea push (HTTP 크기 제한 우회)""" import paramiko, sys, os, subprocess sys.stdout.reconfigure(encoding='utf-8', errors='replace') # 서버에서 각 repo의 git clone을 생성하는 방식 # 서버의 /opt/repos/에 로컬 clone → Gitea에 push (localhost, 크기 제한 없음) client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=30) sftp = client.open_sftp() def run(label, cmd, timeout=120): print(f' [{label}]') _, o, e = client.exec_command(cmd, timeout=timeout) out = o.read().decode('utf-8', errors='replace').strip() err = e.read().decode('utf-8', errors='replace').strip() if out: print(f' {out[:300]}') if err: bad = [l for l in err.splitlines() if not any(k in l.lower() for k in ['warn','hint','note'])] if bad: print(f' ERR: {bad[-1]}') return out # 서버에 /opt/repos 디렉토리 생성 run('mkdir repos', 'mkdir -p /opt/repos') REPOS = { "zioinfo-web": "zio/zioinfo-web", "guardia-itsm": "zio/guardia-itsm", "guardia-manager": "zio/guardia-manager", "guardia-messenger": "zio/guardia-messenger", "guardia-docs": "zio/guardia-docs", } NEW_REPOS = ["guardia-manager", "guardia-messenger", "guardia-docs"] # 신규 Gitea 저장소 생성 print('\n[Gitea 신규 저장소 생성]') for name in NEW_REPOS: run(f'create {name}', f""" curl -sf -X DELETE 'http://localhost:3000/api/v1/repos/zio/{name}' \ -u 'zio:Zio@Admin2026!' 2>/dev/null curl -sf -X POST 'http://localhost:3000/api/v1/user/repos' \ -H 'Content-Type: application/json' \ -u 'zio:Zio@Admin2026!' \ -d '{{"name":"{name}","private":false,"auto_init":false}}' 2>/dev/null | \ python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('full_name','created'))" 2>/dev/null """) # 번들 파일 전송 + 서버에서 push print('\n[번들 전송 + push]') for local, gitea in REPOS.items(): local_path = f"C:/GUARDiA/repos/{local}" bundle_path = f"C:/GUARDiA/repos/{local}.bundle" server_bundle = f"/opt/repos/{local}.bundle" print(f'\n {local} → {gitea}') # 번들 생성 (더 작은 크기) print(f' bundle 생성 중...') r = subprocess.run(['git', '-C', local_path, 'bundle', 'create', bundle_path, '--all'], capture_output=True, text=True, timeout=120) if r.returncode != 0: print(f' bundle 실패: {r.stderr[:100]}') continue size = os.path.getsize(bundle_path) // (1024*1024) print(f' bundle 크기: {size}MB') # 서버에 번들 전송 print(f' 서버 전송 중...') sftp.put(bundle_path, server_bundle) print(f' 전송 완료') # 서버에서 bundle → Gitea push gitea_url = f"http://zio:Zio%40Admin2026%21@localhost:3000/{gitea}.git" run(f'push {local}', f""" rm -rf /tmp/{local}_tmp git clone {server_bundle} /tmp/{local}_tmp 2>/dev/null cd /tmp/{local}_tmp git remote set-url origin '{gitea_url}' git push origin main --force 2>&1 | tail -3 rm -rf /tmp/{local}_tmp {server_bundle} echo "push done" """, timeout=180) # 로컬 번들 삭제 os.remove(bundle_path) sftp.close() client.close() print('\n=== 완료 ===')