Agent Skill
2/7/2026

build-orchestrator

Orchestrate builds across multiple remote servers. Manage dependencies, monitor status, collect results, and alert on failures.

J
jayleekr
0GitHub Stars
1Views
npx skills add jayleekr/jays-treasure-trove

SKILL.md

Namebuild-orchestrator
DescriptionOrchestrate builds across multiple remote servers. Manage dependencies, monitor status, collect results, and alert on failures.

name: build-orchestrator description: Orchestrate builds across multiple remote servers. Manage dependencies, monitor status, collect results, and alert on failures. memory: project context: fork allowed-tools: Bash(ssh *), Bash(scp *), Read, Write, Grep disable-model-invocation: false

Build Orchestrator

여러 리모트 빌드 서버를 조율하는 오케스트레이터.

🖥️ Server Registry

AliasHostPurposeBuild Type
yoctoyocto-builderYocto 이미지 빌드bitbake (자체 병렬)
hostccu2-builderCCU2 Host 빌드build.py
testtest-runner통합 테스트pytest

📊 Current Status

Server Connectivity: !for h in yocto-builder ccu2-builder test-runner; do echo -n "$h: "; ssh -o ConnectTimeout=2 -o BatchMode=yes $h "echo OK" 2>/dev/null || echo "OFFLINE"; done

Active Jobs: !for h in yocto-builder ccu2-builder test-runner; do jobs=$(ssh -o ConnectTimeout=2 $h "pgrep -f 'bitbake|build.py|pytest' | wc -l" 2>/dev/null) [ "$jobs" != "" ] && [ "$jobs" != "0" ] && echo "$h: $jobs processes" done || echo "No active jobs"

🔧 Usage

단일 서버 빌드

/build-orchestrator yocto linux-s32
/build-orchestrator host container-manager
/build-orchestrator test container-manager

파이프라인 (의존성 관리)

/build-orchestrator pipeline:
  1. yocto: build linux-s32
  2. host: build container-manager (after 1)
  3. test: run tests (after 2)

병렬 빌드 (독립적)

/build-orchestrator parallel:
  - yocto: build linux-s32
  - host: build vam
  - host: build dpm

🔄 Workflow

1. Parse Request

사용자 요청에서 추출:

  • Servers: 사용할 서버들
  • Tasks: 각 서버에서 실행할 작업
  • Dependencies: 작업 간 의존성
  • Mode: sequential | parallel | pipeline

2. Start Remote Jobs

각 서버에 SSH로 작업 시작 (백그라운드):

# nohup으로 SSH 끊겨도 계속 실행
ssh $SERVER "nohup $COMMAND > /tmp/build-$TIMESTAMP.log 2>&1 &"

# 또는 tmux 세션으로
ssh $SERVER "tmux new -d -s build-$TIMESTAMP '$COMMAND'"

3. Monitor Progress

주기적으로 상태 확인:

# 프로세스 확인
ssh $SERVER "pgrep -f '$PATTERN'"

# 로그 tail
ssh $SERVER "tail -5 /tmp/build-$TIMESTAMP.log"

# 에러 체크
ssh $SERVER "grep -E 'ERROR|FAILED' /tmp/build-$TIMESTAMP.log | tail -3"

4. Handle Dependencies

# 의존성 체크
while not all_done:
    for task in pending_tasks:
        if task.dependencies_complete():
            start_task(task)
    sleep(30)
    update_status()

5. Collect Results & Alert

# 결과 수집
scp $SERVER:/tmp/build-$TIMESTAMP.log ./results/

# Discord 알림 (OpenClaw 통해)
# message(action="send", target="jaylee_59200", message="✅ Build complete!")

📋 Pipeline Definition

YAML 형식

pipeline:
  name: ccu2-full-build
  
  stages:
    - name: yocto-image
      server: yocto-builder
      command: "./build.py -ncpb -j 16 -p 16"
      workdir: /workspace/CCU_GEN2.0_SONATUS.manifest/mobis
      timeout: 3h
      
    - name: host-build
      server: ccu2-builder
      command: "./build.py --module container-manager"
      workdir: /workspace/ccu-2.0
      depends_on: []  # 독립적
      timeout: 30m
      
    - name: integration-test
      server: test-runner
      command: "pytest -v test_container.py"
      workdir: /workspace/snt-integration-tests
      depends_on: [host-build]  # host-build 완료 후 실행
      timeout: 1h
      
  on_failure:
    - notify: discord
    - retry: 1
    
  on_success:
    - notify: discord
    - archive: true

실행

/build-orchestrator run pipeline.yaml

🔔 Notification Integration

Discord (via OpenClaw)

# 빌드 시작
message(action="send", channel="discord", target="jaylee_59200",
        message="🚀 Pipeline started: ccu2-full-build")

# 단계 완료
message(action="send", channel="discord", target="jaylee_59200",
        message="✅ Stage 1/3 complete: yocto-image (45min)")

# 실패
message(action="send", channel="discord", target="jaylee_59200",
        message="❌ Stage 2 FAILED: host-build\nError: CMake error in container-manager")

# 전체 완료
message(action="send", channel="discord", target="jaylee_59200",
        message="🎉 Pipeline complete: ccu2-full-build (2h 15min)")

📊 Status Dashboard

실시간 상태 확인:

/build-orchestrator status

┌─────────────────────────────────────────────────────┐
│  CCU2 Full Build Pipeline                           │
├─────────────────────────────────────────────────────┤
│  Stage 1: yocto-image    [████████░░] 80%  45min   │
│  Stage 2: host-build     [waiting]                  │
│  Stage 3: integration    [waiting]                  │
├─────────────────────────────────────────────────────┤
│  Errors: 0  Warnings: 12  ETA: 1h 30min            │
└─────────────────────────────────────────────────────┘

🛠️ Scripts

orchestrator.py

#!/usr/bin/env python3
"""Build Orchestrator - Manage builds across remote servers"""

import subprocess
import json
import time
from dataclasses import dataclass
from typing import List, Dict, Optional

@dataclass
class Task:
    name: str
    server: str
    command: str
    workdir: str
    depends_on: List[str]
    timeout: int
    status: str = "pending"
    pid: Optional[int] = None
    log_file: Optional[str] = None

class Orchestrator:
    def __init__(self, pipeline_file: str):
        self.tasks: Dict[str, Task] = {}
        self.load_pipeline(pipeline_file)
    
    def load_pipeline(self, path: str):
        """Load pipeline from YAML"""
        pass
    
    def start_task(self, task: Task):
        """Start task on remote server"""
        timestamp = int(time.time())
        log_file = f"/tmp/build-{task.name}-{timestamp}.log"
        
        cmd = f"ssh {task.server} 'cd {task.workdir} && nohup {task.command} > {log_file} 2>&1 & echo $!'"
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
        
        task.pid = int(result.stdout.strip())
        task.log_file = log_file
        task.status = "running"
    
    def check_status(self, task: Task) -> str:
        """Check if task is still running"""
        cmd = f"ssh {task.server} 'ps -p {task.pid} > /dev/null 2>&1 && echo running || echo done'"
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
        return result.stdout.strip()
    
    def get_result(self, task: Task) -> str:
        """Get task result (success/failed)"""
        cmd = f"ssh {task.server} 'tail -1 {task.log_file} | grep -q SUCCESS && echo success || echo failed'"
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
        return result.stdout.strip()
    
    def run(self):
        """Run the pipeline"""
        while not all(t.status == "done" for t in self.tasks.values()):
            for task in self.tasks.values():
                if task.status == "pending":
                    deps_done = all(
                        self.tasks[d].status == "done" 
                        for d in task.depends_on
                    )
                    if deps_done:
                        self.start_task(task)
                
                elif task.status == "running":
                    if self.check_status(task) == "done":
                        task.status = "done"
                        result = self.get_result(task)
                        print(f"Task {task.name}: {result}")
            
            time.sleep(30)

⚠️ Error Handling

상황처리
SSH 연결 실패3회 재시도 후 알림
빌드 실패로그 수집 → 알림 → 선택적 재시도
타임아웃프로세스 kill → 알림
서버 다운대체 서버 사용 (설정된 경우)

🔧 Configuration

~/.build-orchestrator/config.yaml:

servers:
  yocto-builder:
    host: 192.168.1.101
    user: build
    workdir: /workspace/CCU_GEN2.0_SONATUS.manifest
    
  ccu2-builder:
    host: 192.168.1.102
    user: build
    workdir: /workspace/ccu-2.0
    
  test-runner:
    host: 192.168.1.103
    user: test
    workdir: /workspace/snt-integration-tests

notifications:
  discord:
    enabled: true
    target: jaylee_59200
    
  telegram:
    enabled: true
    chat_id: 514675395

defaults:
  timeout: 2h
  retry: 1
  parallel_limit: 3

Build Orchestrator v1.0 | 리모트 서버 오케스트레이션

Skills Info
Original Name:build-orchestratorAuthor:jayleekr