Skip to content

Commit f5a5cb9

Browse files
committed
Merge branch 'main' of github.com:emagedoc/CodeClash
2 parents 992e9a9 + 22a428b commit f5a5cb9

14 files changed

Lines changed: 667 additions & 156 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
3+
# Avoid consuming lots of storage by chatty docker logs
4+
5+
set -euo pipefail
6+
7+
# Configure Docker log rotation
8+
cat <<EOF > /etc/docker/daemon.json
9+
{
10+
"log-driver": "json-file",
11+
"log-opts": {
12+
"max-size": "10m",
13+
"max-file": "3"
14+
}
15+
}
16+
EOF
17+
18+
# Restart Docker to apply changes
19+
systemctl restart docker

aws/setup/batch/push.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""Push AWS resources defined in JSON files to AWS."""
33

44
import argparse
5+
import base64
56
import json
67
import logging
78
from pathlib import Path
@@ -194,20 +195,37 @@ def push_job_definition(job_data: dict, batch_client) -> None:
194195
logger.info(f"✅ Successfully pushed job definition: {job_name}:{revision}")
195196

196197

198+
def _add_user_data_to_launch_template(template_data: dict, user_data_path: Path) -> None:
199+
"""Add user data from the specified path to the template data."""
200+
if user_data_path.exists():
201+
logger.info(f"Adding user data from {user_data_path.name}")
202+
user_data_script = user_data_path.read_text()
203+
encoded_user_data = base64.b64encode(user_data_script.encode()).decode()
204+
template_data["LaunchTemplateData"]["UserData"] = encoded_user_data
205+
else:
206+
logger.warning(f"User data file not found: {user_data_path}")
207+
208+
197209
def _update_launch_template(template_data: dict, existing_template: dict, ec2_client) -> None:
198-
"""Update existing launch template by creating a new version."""
210+
"""Update existing launch template by creating a new version and setting it as default."""
199211
template_name = template_data["LaunchTemplateName"]
212+
template_id = existing_template["LaunchTemplateId"]
200213
logger.info(f"Launch template {template_name} already exists, creating new version")
201214

202215
create_params = {
203-
"LaunchTemplateId": existing_template["LaunchTemplateId"],
216+
"LaunchTemplateId": template_id,
204217
"LaunchTemplateData": template_data["LaunchTemplateData"],
205218
}
206219

207220
response = ec2_client.create_launch_template_version(**create_params)
208221
version = response["LaunchTemplateVersion"]["VersionNumber"]
209222

210-
logger.info(f"✅ Successfully created new version {version} for launch template: {template_name}")
223+
# Set the new version as the default
224+
ec2_client.modify_launch_template(LaunchTemplateId=template_id, DefaultVersion=str(version))
225+
226+
logger.info(
227+
f"✅ Successfully created new version {version} for launch template: {template_name} and set as default"
228+
)
211229

212230

213231
def _create_launch_template(template_data: dict, ec2_client) -> None:
@@ -227,10 +245,13 @@ def _create_launch_template(template_data: dict, ec2_client) -> None:
227245
logger.info(f"✅ Successfully created launch template: {template_name}")
228246

229247

230-
def push_launch_template(template_data: dict, ec2_client) -> None:
248+
def push_launch_template(template_data: dict, ec2_client, *, user_data_path: Path | None = None) -> None:
231249
"""Push EC2 launch template to AWS."""
232250
template_name = template_data["LaunchTemplateName"]
233251

252+
if user_data_path is not None:
253+
_add_user_data_to_launch_template(template_data, user_data_path)
254+
234255
try:
235256
response = ec2_client.describe_launch_templates(LaunchTemplateNames=[template_name])
236257
existing_template = response["LaunchTemplates"][0]
@@ -257,7 +278,8 @@ def push_file(json_path: Path, region: str) -> None:
257278
case "job_definition.json":
258279
push_job_definition(data, boto3.client("batch", region_name=region))
259280
case "launch_template.json":
260-
push_launch_template(data, boto3.client("ec2", region_name=region))
281+
user_data_path = json_path.parent / "launch_template_user_data.sh"
282+
push_launch_template(data, boto3.client("ec2", region_name=region), user_data_path=user_data_path)
261283
case _:
262284
logger.error(f"Unknown filename: {filename}")
263285
raise ValueError(f"Unknown filename: {filename}")

aws/setup/docker/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Docker images for AWS
2+
3+
tl;dr: Call `./build_and_push_all.sh`, then `./clean_old_tags.py`

codeclash/viewer/app.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,25 @@ def get_models_from_metadata(log_dir: Path) -> list[str]:
107107
return models
108108

109109

110+
def get_game_name_from_metadata(log_dir: Path) -> str:
111+
"""Extract game name from metadata.json if it exists"""
112+
metadata = load_metadata(log_dir)
113+
if not metadata:
114+
return ""
115+
116+
# Try to get game name from different possible locations in metadata
117+
game_name = metadata.get("config", {}).get("game", {}).get("name")
118+
if game_name:
119+
return game_name
120+
121+
# Fallback to game.name if config.game.name doesn't exist
122+
game_name = metadata.get("game", {}).get("name")
123+
if game_name:
124+
return game_name
125+
126+
return ""
127+
128+
110129
def get_readme_first_line(log_dir: Path) -> str:
111130
"""Extract the first line from readme.txt if it exists"""
112131
readme_file = log_dir / "readme.txt"
@@ -168,6 +187,7 @@ def scan_directory(directory: Path, relative_path: str = ""):
168187
round_info = get_round_count_from_metadata(item)
169188
models = get_models_from_metadata(item)
170189
readme_first_line = get_readme_first_line(item)
190+
game_name = get_game_name_from_metadata(item)
171191
game_folders.add(current_relative)
172192
all_folders.append(
173193
{
@@ -176,6 +196,7 @@ def scan_directory(directory: Path, relative_path: str = ""):
176196
"round_info": round_info, # Now stores (completed, total) tuple or None
177197
"models": models,
178198
"readme_first_line": readme_first_line,
199+
"game_name": game_name,
179200
"is_game": True,
180201
"depth": depth,
181202
"parent": relative_path if relative_path else None,
@@ -190,6 +211,7 @@ def scan_directory(directory: Path, relative_path: str = ""):
190211
"round_info": None,
191212
"models": [],
192213
"readme_first_line": "",
214+
"game_name": "",
193215
"is_game": False,
194216
"depth": depth,
195217
"parent": relative_path if relative_path else None,
@@ -670,6 +692,27 @@ def unescape_content(value):
670692
return value.replace("\\n", "\n")
671693

672694

695+
def get_folder_name(path):
696+
"""Extract the folder name from a path"""
697+
if not path:
698+
return ""
699+
from pathlib import Path
700+
701+
return Path(path).name
702+
703+
704+
def get_parent_folder(path):
705+
"""Extract the parent folder name from a path"""
706+
if not path:
707+
return ""
708+
from pathlib import Path
709+
710+
parent = Path(path).parent
711+
if str(parent) == "." or str(parent) == "/":
712+
return ""
713+
return parent.name
714+
715+
673716
def get_navigation_info(selected_folder: str) -> dict[str, str | None]:
674717
"""Get previous and next game folders for navigation"""
675718
# Get all game folders
@@ -733,6 +776,8 @@ def render_game_viewer(folder_path: Path, selected_folder: str) -> str:
733776
# Register the custom filters
734777
app.jinja_env.filters["nl2br"] = nl2br
735778
app.jinja_env.filters["unescape_content"] = unescape_content
779+
app.jinja_env.filters["get_folder_name"] = get_folder_name
780+
app.jinja_env.filters["get_parent_folder"] = get_parent_folder
736781

737782

738783
@app.route("/")

0 commit comments

Comments
 (0)