Remote Build

The remote build feature allows you to run build commands on a remote machine via SSH. This is useful when:

  • The build requires software not installed locally (e.g., Vivado for FPGA synthesis)

  • The build is resource-intensive and you want to offload it to a server

  • You need to run builds on a specific machine with licensed software

Basic Usage

Import the run_remote_build function from ygrader:

from ygrader import run_remote_build, RemoteBuildError

Then call it in your grading callback:

def grading_handler(lab_name, student_code_path, repo_url, tag, **kwargs):
    run_remote_build(
        remote_host="server.example.com",
        remote_work_path="/tmp/grading",
        repo_url=repo_url,
        tag=tag,
        commands=[
            ("lab_tools/adder", ["make", "sim"]),
        ],
        files_to_copy=["lab_tools/adder/output.txt"],
        student_code_path=student_code_path,
    )

How It Works

The run_remote_build function performs these steps:

  1. SSH Connection Test: Verifies SSH connectivity to the remote host

  2. Clone Repository: Clones the student’s repo at the specified tag on the remote machine

  3. Run Commands: Executes each command in sequence from the specified directory

  4. Copy Files Back: Uses SCP to copy specified output files back to the local machine

  5. Cleanup: Removes the remote clone (unless cleanup=False)

Parameters

Parameter

Type

Description

remote_host

str

SSH hostname (e.g., "server.example.com" or "user@server")

remote_work_path

str

Base path on remote machine for cloning (e.g., "/tmp/grading")

repo_url

str

Git repository URL to clone

tag

str

Git tag or branch to checkout

commands

List[Tuple[str, List[str]]]

List of (relative_path, command_list) tuples

files_to_copy

List[str]

File paths relative to repo root to copy back

student_code_path

Path

Local directory to copy files into

cleanup

bool

Delete remote clone after completion (default: True)

use_username_subdir

bool

Create username subdirectory under work path (default: True)

env_setup

str

Shell command(s) to run before each command (e.g., "source settings.sh")

output

TextIO

File object for output (default: sys.stdout)

Example: FPGA Synthesis with Vivado

def grading_handler(lab_name, student_code_path, repo_url, tag, output=None, **kwargs):
    print("Running remote build for FPGA synthesis...", file=output)
    
    run_remote_build(
        remote_host="fpga-server.example.com",
        remote_work_path="/nvme/grading",
        repo_url=repo_url,
        tag=tag,
        commands=[
            ("lab_tools/logic_functions", ["make", "implement"]),
        ],
        files_to_copy=["lab_tools/logic_functions/work"],
        student_code_path=student_code_path,
        env_setup="source /tools/Xilinx/Vivado/2024.1/settings64.sh",
        output=output,
    )

SSH Configuration

The remote build uses SSH with these options:

  • BatchMode: Fails if password is required (use SSH keys)

  • StrictHostKeyChecking=accept-new: Automatically accepts new host keys

  • ConnectTimeout=10: 10 second connection timeout

  • X11 forwarding disabled: Prevents X11 errors

Setting Up SSH Keys

Ensure you have passwordless SSH access to the remote host:

# Generate SSH key if you don't have one
ssh-keygen -t ed25519

# Copy public key to remote server
ssh-copy-id user@server.example.com

# Test connection
ssh user@server.example.com echo "Connected!"

Error Handling

The function raises RemoteBuildError on failure:

from ygrader import run_remote_build, RemoteBuildError

try:
    run_remote_build(...)
except RemoteBuildError as e:
    print(f"Remote build failed: {e}")
    # e.command_output contains the command's stdout/stderr

Username Subdirectory

By default, use_username_subdir=True creates a subdirectory named after the SSH user under remote_work_path. This prevents conflicts when multiple TAs grade simultaneously:

/tmp/grading/
├── ta1/
│   └── student-repo/
└── ta2/
    └── student-repo/

Set use_username_subdir=False to clone directly in remote_work_path.

Output Logging

All SSH and SCP commands are logged with prefixes:

  • [SSH] - Remote commands

  • [SCP] - File copy operations

When using parallel build mode, output goes to per-student log files automatically.