REFACTOR(app): use nsenter for host access

- Replace SSH with nsenter for host access
- Simplify host command execution
This commit is contained in:
2025-12-24 13:46:57 +09:00
parent e035601b95
commit 363716e229
8 changed files with 72 additions and 61 deletions

View File

@@ -15,11 +15,14 @@ spec:
labels: labels:
app: mas app: mas
spec: spec:
hostPID: true # 호스트 프로세스 네임스페이스 접근
serviceAccountName: mas serviceAccountName: mas
containers: containers:
- name: mas - name: mas
image: gitea0213.kro.kr/bluemayne/mas:latest image: gitea0213.kro.kr/bluemayne/mas:latest
imagePullPolicy: Always imagePullPolicy: Always
securityContext:
privileged: true # nsenter 사용을 위한 권한
ports: ports:
- containerPort: 8000 - containerPort: 8000
name: http name: http
@@ -70,7 +73,7 @@ spec:
cpu: "1000m" cpu: "1000m"
volumeMounts: volumeMounts:
- name: projects - name: projects
mountPath: /app/projects mountPath: /mnt/projects
volumes: volumes:
- name: projects - name: projects
hostPath: hostPath:

View File

@@ -16,5 +16,5 @@ commonLabels:
# 이미지 태그 설정 (ArgoCD Image Updater가 자동으로 업데이트) # 이미지 태그 설정 (ArgoCD Image Updater가 자동으로 업데이트)
images: images:
- name: gitea0213.kro.kr/bluemayne/mas - name: gitea0213.kro.kr/bluemayne/mas
newTag: main-sha-761478757e461a432dc761b4c9d9cef8bc811d7b newTag: main-sha-d0fd2a5037d2fc4a31d800a1dfbf9d585aa7534a

View File

@@ -52,11 +52,12 @@ BACKEND_PROMPT = """당신은 Multi-Agent System의 **Backend Code Agent**입니
## 도구 사용 가이드: ## 도구 사용 가이드:
### execute_ssh (호스트 작업용) ⭐ 주로 사용: ### execute_host (호스트 작업용) ⭐ 주로 사용:
- 파일 생성: execute_ssh("cat > /home/ubuntu/Projects/myproject/api/users.py << 'EOF'\\n코드내용\\nEOF") nsenter를 통해 호스트에 직접 접근합니다.
- Git 커밋: execute_ssh("cd /home/ubuntu/Projects/myproject && git add . && git commit -m 'Add user API'") - 파일 생성: execute_host("cat > /home/ubuntu/Projects/myproject/api/users.py << 'EOF'\\n코드내용\\nEOF")
- 테스트 실행: execute_ssh("cd /home/ubuntu/Projects/myproject && pytest tests/") - Git 커밋: execute_host("cd /home/ubuntu/Projects/myproject && git add . && git commit -m 'Add user API'")
- DB 마이그레이션: execute_ssh("cd /home/ubuntu/Projects/myproject && alembic upgrade head") - 테스트 실행: execute_host("cd /home/ubuntu/Projects/myproject && pytest tests/")
- DB 마이그레이션: execute_host("cd /home/ubuntu/Projects/myproject && alembic upgrade head")
### execute_bash (컨테이너 내부용): ### execute_bash (컨테이너 내부용):
- 간단한 검증이나 테스트에만 사용 - 간단한 검증이나 테스트에만 사용

View File

@@ -52,11 +52,12 @@ FRONTEND_PROMPT = """당신은 Multi-Agent System의 **Frontend Code Agent**입
## 도구 사용 가이드: ## 도구 사용 가이드:
### execute_ssh (호스트 작업용) ⭐ 주로 사용: ### execute_host (호스트 작업용) ⭐ 주로 사용:
- 컴포넌트 생성: execute_ssh("cat > /home/ubuntu/Projects/myproject/src/components/UserCard.tsx << 'EOF'\\n코드\\nEOF") nsenter를 통해 호스트에 직접 접근합니다.
- 스타일 추가: execute_ssh("cat > /home/ubuntu/Projects/myproject/src/styles/UserCard.module.css << 'EOF'\\n스타일\\nEOF") - 컴포넌트 생성: execute_host("cat > /home/ubuntu/Projects/myproject/src/components/UserCard.tsx << 'EOF'\\n코드\\nEOF")
- 빌드 테스트: execute_ssh("cd /home/ubuntu/Projects/myproject && npm run build") - 스타일 추가: execute_host("cat > /home/ubuntu/Projects/myproject/src/styles/UserCard.module.css << 'EOF'\\n스타일\\nEOF")
- Git 커밋: execute_ssh("cd /home/ubuntu/Projects/myproject && git add . && git commit -m 'Add UserCard component'") - 빌드 테스트: execute_host("cd /home/ubuntu/Projects/myproject && npm run build")
- Git 커밋: execute_host("cd /home/ubuntu/Projects/myproject && git add . && git commit -m 'Add UserCard component'")
### execute_bash (컨테이너 내부용): ### execute_bash (컨테이너 내부용):
- 간단한 검증에만 사용 - 간단한 검증에만 사용

View File

@@ -22,7 +22,7 @@ INFRASTRUCTURE_PROMPT = """당신은 Multi-Agent System의 **Infrastructure Code
## ⚠️ 실행 환경 ## ⚠️ 실행 환경
- 컨테이너 내부: /app/ - 컨테이너 내부: /app/
- 호스트 시스템 접근: execute_ssh 사용 - 호스트 시스템 접근: execute_host 사용 (nsenter)
- 파일 생성 위치: /home/ubuntu/Projects/ (호스트) - 파일 생성 위치: /home/ubuntu/Projects/ (호스트)
## 역할 ## 역할
@@ -57,10 +57,11 @@ INFRASTRUCTURE_PROMPT = """당신은 Multi-Agent System의 **Infrastructure Code
## 도구 사용 가이드: ## 도구 사용 가이드:
### execute_ssh (호스트 작업용) ⭐ 주로 사용: ### execute_host (호스트 작업용) ⭐ 주로 사용:
- YAML 파일 생성: execute_ssh("cat > /home/ubuntu/Projects/cluster-infrastructure/apps/myapp/deployment.yaml << 'EOF'\\nYAML내용\\nEOF") nsenter를 통해 호스트에 직접 접근합니다.
- kubectl apply: execute_ssh("kubectl apply -f /home/ubuntu/Projects/cluster-infrastructure/apps/myapp/", use_sudo=True) - YAML 파일 생성: execute_host("cat > /home/ubuntu/Projects/cluster-infrastructure/apps/myapp/deployment.yaml << 'EOF'\\nYAML내용\\nEOF")
- Git 커밋: execute_ssh("cd /home/ubuntu/Projects/cluster-infrastructure && git add . && git commit -m 'Add myapp'") - kubectl apply: execute_host("kubectl apply -f /home/ubuntu/Projects/cluster-infrastructure/apps/myapp/", use_sudo=True)
- Git 커밋: execute_host("cd /home/ubuntu/Projects/cluster-infrastructure && git add . && git commit -m 'Add myapp'")
### execute_bash (컨테이너 내부용): ### execute_bash (컨테이너 내부용):
- 간단한 테스트나 검증에만 사용 - 간단한 테스트나 검증에만 사용

View File

@@ -34,10 +34,11 @@ ORCHESTRATOR_PROMPT = """당신은 Multi-Agent System의 **총괄 조율자(Orch
## 사용 가능한 도구 ## 사용 가능한 도구
### execute_ssh (호스트 접근용) ⭐ 주로 사용 ### execute_host (호스트 접근용) ⭐ 주로 사용
- Kubernetes: execute_ssh("kubectl get pods -n mas", use_sudo=True) nsenter를 통해 호스트 네임스페이스에 직접 접근합니다.
- Projects: execute_ssh("ls -la /home/ubuntu/Projects") - Kubernetes: execute_host("kubectl get pods -n mas", use_sudo=True)
- Git: execute_ssh("cd /home/ubuntu/Projects/mas && git status") - Projects: execute_host("ls -la /home/ubuntu/Projects")
- Git: execute_host("cd /home/ubuntu/Projects/mas && git status")
### execute_bash (컨테이너 내부용) ### execute_bash (컨테이너 내부용)
- 컨테이너 파일 조회: execute_bash("ls -la /app") - 컨테이너 파일 조회: execute_bash("ls -la /app")

View File

@@ -41,7 +41,7 @@ RESEARCH_PROMPT = """당신은 Multi-Agent System의 **Research Agent**입니다
``` ```
## 역할 ## 역할
- 호스트 시스템 정보 수집 (SSH 사용) - 호스트 시스템 정보 수집 (nsenter 사용)
- Kubernetes 클러스터 상태 조회 - Kubernetes 클러스터 상태 조회
- PostgreSQL 데이터베이스 탐색 - PostgreSQL 데이터베이스 탐색
- Git 레포지토리 분석 - Git 레포지토리 분석
@@ -50,28 +50,28 @@ RESEARCH_PROMPT = """당신은 Multi-Agent System의 **Research Agent**입니다
## 사용 가능한 도구 ## 사용 가능한 도구
### 1. execute_ssh (호스트 접근용) ⭐ 주로 사용 ### 1. execute_host (호스트 접근용) ⭐ 주로 사용
호스트 시스템(oracle-master)에 접근할 때 사용합니다. nsenter를 통해 호스트 네임스페이스에 직접 접근합니다. SSH보다 빠르고 효율적입니다.
**Kubernetes 조회:** **Kubernetes 조회:**
- execute_ssh("kubectl get pods -n mas", use_sudo=True) - execute_host("kubectl get pods -n mas", use_sudo=True)
- execute_ssh("kubectl get deployments -A", use_sudo=True) - execute_host("kubectl get deployments -A", use_sudo=True)
- execute_ssh("kubectl describe pod mas-xxx -n mas", use_sudo=True) - execute_host("kubectl describe pod mas-xxx -n mas", use_sudo=True)
- execute_ssh("kubectl logs mas-xxx -n mas --tail=50", use_sudo=True) - execute_host("kubectl logs mas-xxx -n mas --tail=50", use_sudo=True)
**Projects 폴더 탐색:** **Projects 폴더 탐색:**
- execute_ssh("ls -la /home/ubuntu/Projects") - execute_host("ls -la /home/ubuntu/Projects")
- execute_ssh("find /home/ubuntu/Projects -name '*.git' -type d") - execute_host("find /home/ubuntu/Projects -name '*.git' -type d")
- execute_ssh("cat /home/ubuntu/Projects/mas/README.md") - execute_host("cat /home/ubuntu/Projects/mas/README.md")
**Git 작업:** **Git 작업:**
- execute_ssh("cd /home/ubuntu/Projects/mas && git log -10 --oneline") - execute_host("cd /home/ubuntu/Projects/mas && git log -10 --oneline")
- execute_ssh("cd /home/ubuntu/Projects/mas && git status") - execute_host("cd /home/ubuntu/Projects/mas && git status")
- execute_ssh("cd /home/ubuntu/Projects/cluster-infrastructure && git branch -a") - execute_host("cd /home/ubuntu/Projects/cluster-infrastructure && git branch -a")
**PostgreSQL 조회 (호스트에서):** **PostgreSQL 조회 (호스트에서):**
- execute_ssh("psql -U bluemayne -h postgresql-primary.postgresql.svc.cluster.local -d postgres -c 'SELECT version()'") - execute_host("psql -U bluemayne -h postgresql-primary.postgresql.svc.cluster.local -d postgres -c 'SELECT version()'")
- execute_ssh("psql -U bluemayne -h postgresql-primary.postgresql.svc.cluster.local -d postgres -c '\\dt'") - execute_host("psql -U bluemayne -h postgresql-primary.postgresql.svc.cluster.local -d postgres -c '\\dt'")
### 2. execute_bash (컨테이너 내부용) ### 2. execute_bash (컨테이너 내부용)
컨테이너 내부 작업에만 사용합니다. 컨테이너 내부 작업에만 사용합니다.

View File

@@ -9,7 +9,7 @@ from typing import Optional
@tool @tool
def execute_bash(command: str, timeout: int = 30, cwd: Optional[str] = None) -> str: def execute_bash(command: str, timeout: int = 30, cwd: Optional[str] = None) -> str:
""" """
Execute a bash command and return the output. Execute a bash command in the container.
Args: Args:
command: Bash command to execute command: Bash command to execute
@@ -20,9 +20,8 @@ def execute_bash(command: str, timeout: int = 30, cwd: Optional[str] = None) ->
Command output or error message Command output or error message
Examples: Examples:
- execute_bash("kubectl get pods -n mas") - execute_bash("ls -la /app")
- execute_bash("git log -5 --oneline", cwd="/app/repos/cluster-infrastructure") - execute_bash("python --version")
- execute_bash("psql -U bluemayne -d postgres -c 'SELECT * FROM users LIMIT 10'")
- execute_bash("curl -s http://prometheus:9090/api/v1/query?query=up") - execute_bash("curl -s http://prometheus:9090/api/v1/query?query=up")
""" """
try: try:
@@ -52,9 +51,9 @@ def execute_bash(command: str, timeout: int = 30, cwd: Optional[str] = None) ->
@tool @tool
def execute_ssh(command: str, host: str = "ubuntu@172.17.0.1", timeout: int = 30, use_sudo: bool = False) -> str: def execute_host(command: str, timeout: int = 30, use_sudo: bool = False) -> str:
""" """
Execute command on oracle-master host via SSH. Execute command on the HOST system using nsenter (NO SSH needed!).
USE THIS for accessing the host system: USE THIS for accessing the host system:
- kubectl commands (Kubernetes cluster management) - kubectl commands (Kubernetes cluster management)
@@ -62,10 +61,13 @@ def execute_ssh(command: str, host: str = "ubuntu@172.17.0.1", timeout: int = 30
- PostgreSQL queries (via psql) - PostgreSQL queries (via psql)
- Git operations on host repositories - Git operations on host repositories
- File system operations on host - File system operations on host
- ALL host system operations
This works by entering the host's namespaces directly from the container.
Much faster than SSH and no authentication needed!
Args: Args:
command: Command to run on the host server command: Command to run on the host system
host: SSH host (default: ubuntu@172.17.0.1)
timeout: Command timeout in seconds (default: 30) timeout: Command timeout in seconds (default: 30)
use_sudo: Whether to prepend 'sudo' to the command (default: False) use_sudo: Whether to prepend 'sudo' to the command (default: False)
@@ -73,25 +75,27 @@ def execute_ssh(command: str, host: str = "ubuntu@172.17.0.1", timeout: int = 30
Command output or error message Command output or error message
Examples: Examples:
- execute_ssh("kubectl get pods -n mas", use_sudo=True) - execute_host("kubectl get pods -n mas", use_sudo=True)
- execute_ssh("ls -la /home/ubuntu/Projects") - execute_host("ls -la /home/ubuntu/Projects")
- execute_ssh("cat /home/ubuntu/Projects/mas/README.md") - execute_host("cat /home/ubuntu/Projects/mas/README.md")
- execute_ssh("cd /home/ubuntu/Projects/mas && git log -5 --oneline") - execute_host("cd /home/ubuntu/Projects/mas && git log -5 --oneline")
- execute_ssh("psql -U bluemayne -h postgresql-primary.postgresql.svc.cluster.local -d postgres -c 'SELECT version()'") - execute_host("psql -U bluemayne -h postgresql-primary.postgresql.svc.cluster.local -d postgres -c 'SELECT version()'")
""" """
try: try:
# Escape quotes in command for SSH
escaped_command = command.replace('"', '\\"')
# Add sudo if requested # Add sudo if requested
if use_sudo: if use_sudo:
escaped_command = f"sudo {escaped_command}" command = f"sudo {command}"
# Build SSH command # Use nsenter to enter host namespaces
ssh_command = f'ssh -o StrictHostKeyChecking=no {host} "{escaped_command}"' # -t 1: target PID 1 (init process on host)
# -m: mount namespace
# -u: UTS namespace (hostname)
# -n: network namespace
# -i: IPC namespace
nsenter_command = f"nsenter -t 1 -m -u -n -i -- {command}"
result = subprocess.run( result = subprocess.run(
ssh_command, nsenter_command,
shell=True, shell=True,
capture_output=True, capture_output=True,
text=True, text=True,
@@ -104,15 +108,15 @@ def execute_ssh(command: str, host: str = "ubuntu@172.17.0.1", timeout: int = 30
output += f"\n[STDERR]:\n{result.stderr}" output += f"\n[STDERR]:\n{result.stderr}"
if result.returncode != 0: if result.returncode != 0:
return f"❌ SSH command failed (exit code {result.returncode}):\n{output}" return f"❌ Host command failed (exit code {result.returncode}):\n{output}"
return f"✅ SSH command executed successfully:\n{output}" return f"✅ Host command executed successfully:\n{output}"
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
return f"❌ SSH command timed out after {timeout} seconds" return f"❌ Host command timed out after {timeout} seconds"
except Exception as e: except Exception as e:
return f"❌ Error executing SSH command: {str(e)}" return f"❌ Error executing host command: {str(e)}"
# Export both tools # Export both tools
bash_tools = [execute_bash, execute_ssh] bash_tools = [execute_bash, execute_host]