Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions deploy/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions deploy/saturn/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,53 @@ module "container" {
"-subscription=${google_pubsub_subscription.queue.name}",
"-parallel=${var.parallelism}",
]

# Environment variables for Docker-in-Docker path translation
env = [
{
name = "SCAFFOLD_HOST_PATH"
value = "/var/lib/saturn/scaffolds"
},
{
name = "SCAFFOLD_CONTAINER_PATH"
value = "/scaffolds"
},
{
name = "EXECUTION_IMAGE"
value = "${var.image}"
}
]

# Mount Docker socket and scaffolds directory from host
volumeMounts = [
{
mountPath = "/var/run/docker.sock"
name = "docker-socket"
readOnly = false
},
{
mountPath = "/scaffolds"
name = "scaffolds"
readOnly = false
}
]
}

# Mount host Docker socket and scaffolds directory
volumes = [
{
name = "docker-socket"
hostPath = {
path = "/var/run/docker.sock"
}
},
{
name = "scaffolds"
hostPath = {
path = "/var/lib/saturn/scaffolds"
}
}
]
}

resource "google_compute_instance_template" "this" {
Expand Down
36 changes: 29 additions & 7 deletions saturn/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build go app
FROM golang:1.23.4-bookworm AS go
FROM golang:1.25-bookworm AS go

ENV BUILD_HOME /build
WORKDIR $BUILD_HOME
Expand All @@ -18,12 +18,12 @@ FROM eclipse-temurin:21-jdk
# Setup - Install JDK8 (base image provides JDK21)
# Add Ubuntu universe repository for openjdk-8
RUN apt-get update && \
apt-get install -y software-properties-common && \
add-apt-repository ppa:openjdk-r/ppa -y && \
apt-get update && \
apt-get install -y openjdk-8-jdk && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
apt-get install -y software-properties-common && \
add-apt-repository ppa:openjdk-r/ppa -y && \
apt-get update && \
apt-get install -y openjdk-8-jdk && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Copy Python executable, libraries, standard library, site-packages, include files, binary files, and Python path
COPY --from=python /usr/local/bin/python3.12 /usr/local/bin/python3.12
Expand All @@ -36,6 +36,28 @@ ENV PYTHONPATH=/usr/local/lib/python3.12:/usr/local/lib/python3.12/site-packages
# Install google cloud package for use in the scaffold
RUN python3.12 -m pip install google-cloud-storage

# Install Docker CLI for containerized execution
# Note: We only install the CLI, not the daemon. Saturn will use the host's Docker daemon via socket mounting.
RUN apt-get update && \
apt-get install -y \
ca-certificates \
curl \
gnupg && \
install -m 0755 -d /etc/apt/keyrings && \
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \
chmod a+r /etc/apt/keyrings/docker.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null && \
apt-get update && \
apt-get install -y docker-ce-cli && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Create battlecode user for running containerized tasks
# Use UID/GID 10000 to avoid conflicts with existing system users
RUN groupadd -g 10000 battlecode && \
useradd -u 10000 -g battlecode -m -s /bin/bash battlecode

ENV APP_HOME /app
WORKDIR $APP_HOME

Expand Down
38 changes: 29 additions & 9 deletions saturn/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: dev-fetch-secret dev-build dev-compile dev-execute dev-shell dev-shell-saturn dev-clean help
.PHONY: dev-fetch-secret dev-build dev-compile-py dev-compile-java dev-execute-py dev-execute-java dev-shell dev-shell-saturn dev-clean help
.PHONY: dev-docker-up dev-docker-down dev-docker-logs dev-docker-rebuild dev-pubsub-interactive
.PHONY: dev-list-runs dev-clean-runs dev-view-run

Expand All @@ -9,8 +9,10 @@ help: ## Show this help message
@echo ' make dev-fetch-secret # Fetch secrets from GCP'
@echo ' make dev-build # Build Docker images'
@echo ' make dev-docker-up # Start all services (creates new run)'
@echo ' make dev-compile # Test compilation'
@echo ' make dev-execute # Test execution'
@echo ' make dev-compile-py # Test Python compilation'
@echo ' make dev-compile-java # Test Java compilation'
@echo ' make dev-execute-py # Test Python execution'
@echo ' make dev-execute-java # Test Java execution'
@echo ' make dev-pubsub-interactive # Interactive Pub/Sub client'
@echo ''
@echo 'Run Management:'
Expand Down Expand Up @@ -49,7 +51,9 @@ dev-build: ## Build all Docker images
@cd development && docker-compose build
@echo "✓ Docker images built"

dev-compile: ## Send a compile message
# Template for compile operations
# Usage: $(call run-compile,language)
define run-compile
@# Check if a run is active
@if [ ! -f development/runs/latest ]; then \
echo "Error: No active run found. Start services with 'make dev-docker-up' first."; \
Expand All @@ -60,21 +64,24 @@ dev-compile: ## Send a compile message
$(eval REQUEST_ID := $(shell date +%Y%m%d_%H%M%S))
@# Create request directory structure
@mkdir -p development/runs/$(RUN_ID)/requests/compile_$(REQUEST_ID)
@echo "Creating compile request: compile_$(REQUEST_ID)"
@echo "Creating compile request for $(1): compile_$(REQUEST_ID)"
@# Generate config from template
@sed \
-e 's|{{REPORT_PATH}}|/development/runs/$(RUN_ID)/requests/compile_$(REQUEST_ID)/report.txt|g' \
-e 's|{{BINARY_PATH}}|/development/runs/$(RUN_ID)/requests/compile_$(REQUEST_ID)/binary.zip|g' \
development/configs/compile.template.json \
development/configs/compile-$(1).template.json \
> development/runs/$(RUN_ID)/requests/compile_$(REQUEST_ID)/config.json
@echo "✓ Config generated: development/runs/$(RUN_ID)/requests/compile_$(REQUEST_ID)/config.json"
@# Send compile message with generated config
@docker exec saturn-pubsub-dev ./pubsubclient publish-json testing-saturn /development/runs/$(RUN_ID)/requests/compile_$(REQUEST_ID)/config.json
@echo "✓ Compile message sent"
@echo "✓ Request ID: compile_$(REQUEST_ID)"
@echo "✓ Output directory: development/runs/$(RUN_ID)/requests/compile_$(REQUEST_ID)/"
endef

dev-execute: ## Send an execute message
# Template for execute operations
# Usage: $(call run-execute,language)
define run-execute
@# Check if a run is active
@if [ ! -f development/runs/latest ]; then \
echo "Error: No active run found. Start services with 'make dev-docker-up' first."; \
Expand All @@ -85,19 +92,32 @@ dev-execute: ## Send an execute message
$(eval REQUEST_ID := $(shell date +%Y%m%d_%H%M%S))
@# Create request directory structure
@mkdir -p development/runs/$(RUN_ID)/requests/execute_$(REQUEST_ID)
@echo "Creating execute request: execute_$(REQUEST_ID)"
@echo "Creating execute request for $(1): execute_$(REQUEST_ID)"
@# Generate config from template
@sed \
-e 's|{{REPORT_PATH}}|/development/runs/$(RUN_ID)/requests/execute_$(REQUEST_ID)/report.txt|g' \
-e 's|{{REPLAY_PATH}}|/development/runs/$(RUN_ID)/requests/execute_$(REQUEST_ID)/replay.bc25java|g' \
development/configs/execute.template.json \
development/configs/execute-$(1).template.json \
> development/runs/$(RUN_ID)/requests/execute_$(REQUEST_ID)/config.json
@echo "✓ Config generated: development/runs/$(RUN_ID)/requests/execute_$(REQUEST_ID)/config.json"
@# Send execute message with generated config
@docker exec saturn-pubsub-dev ./pubsubclient publish-json testing-saturn /development/runs/$(RUN_ID)/requests/execute_$(REQUEST_ID)/config.json
@echo "✓ Execute message sent"
@echo "✓ Request ID: execute_$(REQUEST_ID)"
@echo "✓ Output directory: development/runs/$(RUN_ID)/requests/execute_$(REQUEST_ID)/"
endef

dev-compile-py:
$(call run-compile,py3)

dev-compile-java:
$(call run-compile,java21)

dev-execute-py:
$(call run-execute,py3)

dev-execute-java:
$(call run-execute,java21)

dev-shell-pubsub: ## Open shell in Pub/Sub container
@docker exec -it saturn-pubsub-dev bash
Expand Down
3 changes: 2 additions & 1 deletion saturn/cmd/saturn/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
scaffoldRoot *string = flag.String("scaffold", "/scaffolds", "the root directory for saving scaffolds")
parallelism *uint = flag.Uint("parallel", 1, "the number of scaffolds to run in parallel")
onSaturn *bool = flag.Bool("onsaturn", true, "run on saturn")
executionImage *string = flag.String("execution-image", os.Getenv("EXECUTION_IMAGE"), "the docker image to isolate compile/execution tasks")
)

func main() {
Expand Down Expand Up @@ -58,7 +59,7 @@ func main() {
)
for i = 0; i < *parallelism; i++ {
root := filepath.Join(*scaffoldRoot, strconv.FormatUint(uint64(i), 10))
multiplexer, err := run.NewScaffoldMultiplexer(root, secret, *onSaturn)
multiplexer, err := run.NewScaffoldMultiplexer(root, secret, *onSaturn, *executionImage)
if err != nil {
log.Ctx(ctx).Fatal().Err(err).Msg("Could not initialize scaffold multiplexer.")
}
Expand Down
23 changes: 23 additions & 0 deletions saturn/development/configs/bc25/compile-java21.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"episode": {
"name": "bc25java",
"language": "java21",
"scaffold": "https://github.com/battlecode/battlecode25-scaffold"
},
"metadata": {
"report-url": "{{REPORT_PATH}}",
"task-type": "compile"
},
"details": {
"source": {
"bucket": "local",
"name": "/development/test-data/source/java21.zip"
},
"binary": {
"bucket": "local",
"name": "{{BINARY_PATH}}"
},
"team-name": "test",
"package": "examplefuncsplayer"
}
}
23 changes: 23 additions & 0 deletions saturn/development/configs/bc25/compile-py3.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"episode": {
"name": "bc25python",
"language": "py3",
"scaffold": "https://github.com/battlecode/battlecode25-scaffold"
},
"metadata": {
"report-url": "{{REPORT_PATH}}",
"task-type": "compile"
},
"details": {
"source": {
"bucket": "local",
"name": "/development/test-data/source/py3.zip"
},
"binary": {
"bucket": "local",
"name": "{{BINARY_PATH}}"
},
"team-name": "test",
"package": "examplefuncsplayer"
}
}
43 changes: 43 additions & 0 deletions saturn/development/configs/bc25/execute-java21.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"episode": {
"name": "bc25",
"language": "java21",
"scaffold": "https://github.com/battlecode/battlecode25-scaffold"
},
"metadata": {
"report-url": "{{REPORT_PATH}}",
"task-type": "execute"
},
"details": {
"maps": ["fix", "galaxy", "gridworld", "quack", "sierpinski"],
"replay": {
"bucket": "local",
"name": "{{REPLAY_PATH}}"
},
"alternate-order": true,
"a": {
"source": {
"bucket": "local",
"name": "/development/test-data/source/bc25-java21.zip"
},
"binary": {
"bucket": "local",
"name": "/development/test-data/binary/bc25-java21.zip"
},
"team-name": "test1",
"package": "examplefuncsplayer"
},
"b": {
"source": {
"bucket": "local",
"name": "/development/test-data/source/bc25-java21.zip"
},
"binary": {
"bucket": "local",
"name": "/development/test-data/binary/bc25-java21.zip"
},
"team-name": "test2",
"package": "examplefuncsplayer"
}
}
}
43 changes: 43 additions & 0 deletions saturn/development/configs/bc25/execute-py3.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"episode": {
"name": "bc25python",
"language": "py3",
"scaffold": "https://github.com/battlecode/battlecode25-scaffold"
},
"metadata": {
"report-url": "{{REPORT_PATH}}",
"task-type": "execute"
},
"details": {
"maps": ["fix", "galaxy", "gridworld", "quack", "sierpinski"],
"replay": {
"bucket": "local",
"name": "{{REPLAY_PATH}}"
},
"alternate-order": true,
"a": {
"source": {
"bucket": "local",
"name": "/development/test-data/source/py3.zip"
},
"binary": {
"bucket": "local",
"name": "/development/test-data/binary/py3.zip"
},
"team-name": "test1",
"package": "examplefuncsplayer"
},
"b": {
"source": {
"bucket": "local",
"name": "/development/test-data/source/py3.zip"
},
"binary": {
"bucket": "local",
"name": "/development/test-data/binary/py3.zip"
},
"team-name": "test2",
"package": "examplefuncsplayer"
}
}
}
Loading
Loading