diff --git a/oci-amd-monitor.py b/oci-amd-monitor.py new file mode 100644 index 0000000..498ee53 --- /dev/null +++ b/oci-amd-monitor.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +"""Monitor and grab Oracle Cloud AMD free-tier instance (VM.Standard.E2.1.Micro).""" +import oci +import time +import smtplib +import sys +from email.mime.text import MIMEText + +import os +from dotenv import load_dotenv +load_dotenv(os.path.join(os.path.dirname(__file__), ".env")) + +COMPARTMENT_ID = os.environ["COMPARTMENT_ID"] +AVAILABILITY_DOMAIN = os.environ["AVAILABILITY_DOMAIN"] +SUBNET_ID = os.environ["SUBNET_ID"] +IMAGE_ID = os.environ.get("AMD_IMAGE_ID", os.environ.get("IMAGE_ID")) +SSH_KEY = os.environ["SSH_KEY"] +DISPLAY_NAME = os.environ.get("AMD_DISPLAY_NAME", "free-amd-caddy") +SHAPE = "VM.Standard.E2.1.Micro" +INTERVAL = 60 +WEEKLY_REPORT_INTERVAL = 7 * 24 * 3600 + +EMAIL_TO = os.environ["EMAIL_TO"] +EMAIL_FROM = os.environ["EMAIL_FROM"] +EMAIL_APP_PASSWORD = os.environ["EMAIL_APP_PASSWORD"] + +def send_email(subject, body): + msg = MIMEText(body) + msg["Subject"] = subject + msg["From"] = EMAIL_FROM + msg["To"] = EMAIL_TO + with smtplib.SMTP_SSL("smtp.gmail.com", 465) as s: + s.login(EMAIL_FROM, EMAIL_APP_PASSWORD) + s.send_message(msg) + +config = oci.config.from_file() +compute = oci.core.ComputeClient(config) + +print(f"Starting AMD instance monitor ({SHAPE})...", flush=True) +start_time = time.time() +last_report = start_time +attempts = 0 +while True: + try: + resp = compute.launch_instance( + oci.core.models.LaunchInstanceDetails( + compartment_id=COMPARTMENT_ID, + availability_domain=AVAILABILITY_DOMAIN, + shape=SHAPE, + image_id=IMAGE_ID, + subnet_id=SUBNET_ID, + display_name=DISPLAY_NAME, + metadata={"ssh_authorized_keys": SSH_KEY}, + ) + ) + instance_id = resp.data.id + msg = f"AMD instance created!\nID: {instance_id}" + print(msg, flush=True) + send_email("OCI AMD Instance Created!", msg) + sys.exit(0) + except oci.exceptions.ServiceError as e: + msg_lower = str(e.message).lower() + if "capacity" in msg_lower or "host" in msg_lower or "limit" in msg_lower or e.status >= 500: + attempts += 1 + print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(time.time() + 8*3600))} {e.message[:80]}. Retrying in {INTERVAL}s...", flush=True) + else: + print(f"Unexpected error: {e.message}", flush=True) + send_email("OCI AMD Monitor Error", str(e.message)) + sys.exit(1) + now = time.time() + if now - last_report >= WEEKLY_REPORT_INTERVAL: + uptime_days = int((now - start_time) / 86400) + send_email( + "OCI AMD Monitor - Weekly Report", + f"Status: Still running, no capacity available.\n" + f"Uptime: {uptime_days} days\n" + f"Attempts since last report: {attempts}\n" + f"Shape: {SHAPE} (1 OCPU, 1GB RAM)", + ) + print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(now + 8*3600))} Weekly report sent.", flush=True) + last_report = now + attempts = 0 + time.sleep(INTERVAL)