-
Notifications
You must be signed in to change notification settings - Fork 268
Add log upload support for build target failed #587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fb8e05f
2913a73
d809137
6e9aa8d
b61b4a3
2e0c17d
b286cfc
3966f7f
da15453
6fb5913
0ff4a6d
69378cf
41a3b90
eacea5b
b5f5e92
82f1c48
dd62589
2d3efa4
1df6f36
1365e59
82c574d
98f645e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| #!/usr/bin/env python3 | ||
|
|
||
| import os | ||
| import subprocess | ||
| from pathlib import Path | ||
| import sys | ||
| import platform | ||
| import argparse | ||
|
|
||
|
|
||
| def log(*args): | ||
| print(*args) | ||
| sys.stdout.flush() | ||
|
|
||
|
|
||
| def is_windows(): | ||
| return platform.system().lower() == "windows" | ||
|
|
||
|
|
||
| def normalize_path(p: Path) -> str: | ||
| return str(p).replace("\\", "/") if is_windows() else str(p) | ||
|
Comment on lines
+20
to
+21
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can probably use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ohh - did not know that.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of forking |
||
|
|
||
|
|
||
| def index_log_files(build_dir: Path, amdgpu_family: str): | ||
| log_dir = build_dir / "logs" | ||
| index_file = log_dir / "index.html" | ||
|
|
||
| # TODO: Fork indexer.py locally to avoid relying on an external GitHub source at runtime. | ||
| indexer_path = build_dir / "indexer.py" | ||
|
erman-gurses marked this conversation as resolved.
|
||
|
|
||
| if log_dir.is_dir(): | ||
| log(f"[INFO] Found '{log_dir}' directory. Indexing '*.log' files...") | ||
| subprocess.run( | ||
| ["python", str(indexer_path), "-f", "*.log", normalize_path(log_dir)], | ||
| check=True, | ||
| ) | ||
| else: | ||
| log(f"[WARN] Log directory '{log_dir}' not found. Skipping indexing.") | ||
| return | ||
|
|
||
| if index_file.exists(): | ||
| log( | ||
| f"[INFO] Rewriting links in '{index_file}' with AMDGPU_FAMILIES={amdgpu_family}..." | ||
| ) | ||
| content = index_file.read_text() | ||
| updated = content.replace( | ||
| 'a href=".."', f'a href="../../index-{amdgpu_family}.html"' | ||
| ) | ||
|
erman-gurses marked this conversation as resolved.
Outdated
|
||
| index_file.write_text(updated) | ||
| log("[INFO] Log index links updated.") | ||
| else: | ||
| log(f"[WARN] '{index_file}' not found. Skipping link rewrite.") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| parser = argparse.ArgumentParser(description="Create HTML index for log files.") | ||
| parser.add_argument( | ||
| "--build-dir", | ||
| type=Path, | ||
| default=Path(os.getenv("BUILD_DIR", "build")), | ||
| help="Build directory containing logs (default: 'build' or $BUILD_DIR)", | ||
| ) | ||
| parser.add_argument( | ||
| "--amdgpu-family", | ||
| type=str, | ||
| default=os.getenv("AMDGPU_FAMILIES"), | ||
| help="AMDGPU family name (default: $AMDGPU_FAMILIES)", | ||
| ) | ||
| args = parser.parse_args() | ||
|
|
||
| if not args.amdgpu_family: | ||
| log("[ERROR] --amdgpu-family not provided and AMDGPU_FAMILIES env var not set") | ||
| sys.exit(1) | ||
|
|
||
| index_log_files(args.build_dir, args.amdgpu_family) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| #!/usr/bin/env python3 | ||
| """ | ||
| upload_logs_to_s3.py | ||
|
|
||
| Uploads log files and index.html to an S3 bucket using the AWS CLI. | ||
| """ | ||
|
|
||
| import os | ||
|
marbre marked this conversation as resolved.
Outdated
|
||
| import sys | ||
| import glob | ||
| import shutil | ||
| import argparse | ||
| import subprocess | ||
| from pathlib import Path | ||
|
|
||
|
|
||
| def log(*args, **kwargs): | ||
| print(*args, **kwargs) | ||
| sys.stdout.flush() | ||
|
|
||
|
|
||
| def check_aws_cli_available(): | ||
| if not shutil.which("aws"): | ||
| log("[ERROR] AWS CLI not found in PATH.") | ||
| sys.exit(1) | ||
|
|
||
|
|
||
| def run_aws_cp(source_path: Path, s3_destination: str, content_type: str = None): | ||
| if source_path.is_dir(): | ||
| cmd = ["aws", "s3", "cp", str(source_path), s3_destination, "--recursive"] | ||
| else: | ||
| cmd = ["aws", "s3", "cp", str(source_path), s3_destination] | ||
|
|
||
| if content_type: | ||
| cmd += ["--content-type", content_type] | ||
| try: | ||
| log(f"[INFO] Running: {' '.join(cmd)}") | ||
| subprocess.run(cmd, check=True) | ||
| except subprocess.CalledProcessError as e: | ||
| log(f"[ERROR] Failed to upload {source_path} to {s3_destination}: {e}") | ||
|
|
||
|
|
||
| def upload_logs_to_s3(s3_base_path: str, build_dir: Path): | ||
| log_dir = build_dir / "logs" | ||
|
|
||
| if not log_dir.is_dir(): | ||
| log(f"[INFO] Log directory {log_dir} not found. Skipping upload.") | ||
| return | ||
|
|
||
| # Upload .log files | ||
| log_files = list(log_dir.glob("*.log")) | ||
| if not log_files: | ||
| log("[WARN] No .log files found. Skipping log upload.") | ||
| else: | ||
| run_aws_cp(log_dir, s3_base_path, content_type="text/plain") | ||
|
|
||
| # Upload index.html | ||
| index_path = log_dir / "index.html" | ||
| if index_path.is_file(): | ||
| index_s3_dest = f"{s3_base_path}/index.html" | ||
| run_aws_cp(index_path, index_s3_dest, content_type="text/html") | ||
| log(f"[INFO] Uploaded {index_path} to {index_s3_dest}") | ||
| else: | ||
| log(f"[INFO] No index.html found at {log_dir}. Skipping index upload.") | ||
|
|
||
|
|
||
| def main(): | ||
| check_aws_cli_available() | ||
|
|
||
| repo_root = Path(__file__).resolve().parent.parent | ||
| default_build_dir = repo_root / "build" | ||
|
|
||
| parser = argparse.ArgumentParser(description="Upload logs to S3.") | ||
| parser.add_argument( | ||
| "--build-dir", | ||
| type=Path, | ||
| default=default_build_dir, | ||
| help="Path to the build directory (default: <repo_root>/build)", | ||
| ) | ||
| parser.add_argument( | ||
| "--s3-base-path", | ||
| type=str, | ||
| required=True, | ||
| help="Base S3 path to upload logs to, e.g. s3://bucket/run-id-platform/logs/family", | ||
| ) | ||
| args = parser.parse_args() | ||
|
|
||
| upload_logs_to_s3(args.s3_base_path, args.build_dir) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
Uh oh!
There was an error while loading. Please reload this page.