Skip to content

Commit 1ef9451

Browse files
authored
Merge pull request #11 from DMU-DebugVisual/inseong2
personalization
2 parents 25f9b64 + 6093904 commit 1ef9451

File tree

2 files changed

+44
-43
lines changed

2 files changed

+44
-43
lines changed

docker-compose.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# 서버 루트 파일에 들어가 있는 docker-compose.yml
2-
# flask-server 컨테이너에 들어가있는 거 X
3-
41
services:
52
backend:
63
build:
@@ -14,6 +11,8 @@ services:
1411
- debug-net
1512
depends_on:
1613
- flask
14+
links: # ✅ 추가: 백엔드에서 'flask-server'로 접근 가능
15+
- flask:flask-server
1716

1817
flask:
1918
build:
@@ -66,4 +65,4 @@ services:
6665

6766
networks:
6867
debug-net:
69-
driver: bridge
68+
driver: bridge

server/app.py

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import subprocess
33
import httpx
44
import sys
5+
import uuid
6+
import shutil
57
from flask import Flask, request, jsonify
68
from openai import OpenAI
79
from dotenv import load_dotenv
@@ -55,11 +57,13 @@ def echo():
5557
print("❌ JSON 파싱 실패:", e)
5658
return "Invalid JSON", 400
5759

58-
# 공통 코드 실행 함수
60+
# 공통 코드 실행 함수 (🔧 격리 디렉터리 + 정리 로직 추가)
5961
def execute_code(code, input_data, lang):
60-
base_dir = '/home/ec2-user/Zivorp_Spike/server/code'
61-
flask_dir = '/usr/src/app/code'
62-
os.makedirs(base_dir, exist_ok=True)
62+
# 호스트 경로(왼쪽) ↔ Flask 컨테이너 경로(오른쪽) 바인드:
63+
# docker-compose.yml: /home/ec2-user/Zivorp_Spike/server/code:/usr/src/app/code
64+
base_dir = '/home/ec2-user/Zivorp_Spike/server/code' # 호스트에서 마운트되는 경로
65+
flask_dir = '/usr/src/app/code' # Flask 컨테이너 내부 경로
66+
os.makedirs(flask_dir, exist_ok=True)
6367

6468
file_map = {
6569
'c': ('main.c', 'c-compiler'),
@@ -70,38 +74,39 @@ def execute_code(code, input_data, lang):
7074
if lang not in file_map:
7175
return None, f"❌ 지원하지 않는 언어입니다: {lang}"
7276

77+
# 🔹 요청별 격리 디렉터리 생성
78+
job_id = f"job-{uuid.uuid4().hex[:12]}"
79+
job_dir_flask = os.path.join(flask_dir, job_id) # 컨테이너 내부 경로
80+
os.makedirs(job_dir_flask, exist_ok=True)
81+
7382
filename, image = file_map[lang]
74-
code_path = os.path.join(flask_dir, filename)
75-
input_path = os.path.join(flask_dir, 'input.txt')
83+
code_path = os.path.join(job_dir_flask, filename)
84+
input_path = os.path.join(job_dir_flask, 'input.txt')
7685

7786
with open(code_path, 'w') as f:
78-
f.write(code)
87+
f.write(code or "")
7988

8089
with open(input_path, 'w') as f:
81-
f.write(input_data)
90+
f.write(input_data or "")
8291

92+
# 언어별 실행 커맨드 (작업 디렉터리는 /code/<job_id>)
8393
if lang == 'python':
84-
docker_cmd = [
85-
'docker', 'run', '--rm',
86-
'-v', f'{base_dir}:/code',
87-
'-w', '/code', image,
88-
'python', filename
89-
]
94+
run_cmd = ['python', filename]
9095
elif lang == 'java':
91-
docker_cmd = [
92-
'docker', 'run', '--rm',
93-
'-v', f'{base_dir}:/code',
94-
'-w', '/code', image,
95-
'sh', '-c', 'javac Main.java && java Main'
96-
]
97-
elif lang == 'c':
98-
docker_cmd = [
99-
'docker', 'run', '--rm',
100-
'-v', f'{base_dir}:/code',
101-
'-w', '/code', image,
102-
'sh', '-c', 'gcc main.c -o program && ./program'
103-
]
104-
96+
run_cmd = ['sh', '-c', 'javac Main.java && java Main']
97+
else: # 'c'
98+
run_cmd = ['sh', '-c', 'gcc main.c -o program && ./program']
99+
100+
# 🔹 컴파일러 컨테이너에 호스트 base_dir를 /code로 마운트하고
101+
# 작업디렉터리를 /code/<job_id>로 지정하여 격리 실행
102+
docker_cmd = [
103+
'docker', 'run', '--rm',
104+
'-v', f'{base_dir}:/code',
105+
'-w', f'/code/{job_id}',
106+
# (선택 권장 안전옵션)
107+
# '--network','none','--cpus','1','-m','256m','--pids-limit','128',
108+
image, *run_cmd
109+
]
105110
print("🐳 Docker 실행 명령어:", ' '.join(docker_cmd))
106111

107112
try:
@@ -112,16 +117,14 @@ def execute_code(code, input_data, lang):
112117
text=True,
113118
timeout=10
114119
)
120+
return result, None
115121
except subprocess.TimeoutExpired:
116-
return {
117-
"stdout": "",
118-
"stderr": "",
119-
"exitCode": -1,
120-
"success": False,
121-
"error": "⏰ 실행 시간이 초과되었습니다."
122-
}, None
123-
124-
return result, None
122+
# run_code가 CompletedProcess 형태를 기대하므로 맞춰서 반환
123+
timeout_cp = subprocess.CompletedProcess(docker_cmd, returncode=124, stdout='', stderr='⏰ 실행 시간이 초과되었습니다.')
124+
return timeout_cp, None
125+
finally:
126+
# 🔹 실행 후 항상 격리 디렉터리 정리 (호스트에도 반영됨)
127+
shutil.rmtree(job_dir_flask, ignore_errors=True)
125128

126129
@app.route('/run', methods=['POST'])
127130
def run_code():
@@ -165,7 +168,7 @@ def visualize_code():
165168

166169
try:
167170
data = request.get_json(force=True)
168-
print("✅ JSON 파싱 성공:", data, flush=True)
171+
print("✅ JSON 수신 성공:", data, flush=True)
169172
except Exception as e:
170173
print(f"❌ JSON 파싱 실패: {e}", flush=True)
171174
return jsonify({"error": "JSON 파싱 오류", "message": str(e)}), 400
@@ -210,6 +213,5 @@ def visualize_code():
210213
}), 200 if result.returncode == 0 else 400
211214

212215

213-
214216
if __name__ == '__main__':
215217
app.run(host="0.0.0.0", port=5050)

0 commit comments

Comments
 (0)