From 80980bbf1635d22d60fbec2a1e772da6976eb5b9 Mon Sep 17 00:00:00 2001 From: Eng-Omar-Hussein Date: Mon, 27 Jul 2026 00:05:12 +0300 Subject: [PATCH] first commit --- README.md | 40 ++++ common-mortakaz/integration-1.md | 76 +++++++ common-mortakaz/integration-2.md | 83 ++++++++ common-qabilah/qabilah-profile.txt | 1 + q1-deploy-monitor/.dockerignore | 8 + q1-deploy-monitor/Dockerfile | 30 +++ q1-deploy-monitor/README.md | 97 +++++++++ q1-deploy-monitor/app/main.py | 83 ++++++++ q1-deploy-monitor/dashboard.html | 232 +++++++++++++++++++++ q1-deploy-monitor/health-check.py | 104 ++++++++++ q1-deploy-monitor/health-check.sh | 42 ++++ q1-deploy-monitor/requirements.txt | 2 + q2-postmortem/postmortem-report.md | 180 ++++++++++++++++ q3-cicd/README.md | 108 ++++++++++ q3-cicd/workflow.yml | 158 ++++++++++++++ q4-scalability/architecture.png | Bin 0 -> 201076 bytes q4-scalability/calculations.md | 105 ++++++++++ q5-mithal-monitor/dashboard.html | 243 ++++++++++++++++++++++ q5-mithal-monitor/monitor.py | 320 +++++++++++++++++++++++++++++ 19 files changed, 1912 insertions(+) create mode 100644 README.md create mode 100644 common-mortakaz/integration-1.md create mode 100644 common-mortakaz/integration-2.md create mode 100644 common-qabilah/qabilah-profile.txt create mode 100644 q1-deploy-monitor/.dockerignore create mode 100644 q1-deploy-monitor/Dockerfile create mode 100644 q1-deploy-monitor/README.md create mode 100644 q1-deploy-monitor/app/main.py create mode 100644 q1-deploy-monitor/dashboard.html create mode 100644 q1-deploy-monitor/health-check.py create mode 100644 q1-deploy-monitor/health-check.sh create mode 100644 q1-deploy-monitor/requirements.txt create mode 100644 q2-postmortem/postmortem-report.md create mode 100644 q3-cicd/README.md create mode 100644 q3-cicd/workflow.yml create mode 100644 q4-scalability/architecture.png create mode 100644 q4-scalability/calculations.md create mode 100644 q5-mithal-monitor/dashboard.html create mode 100644 q5-mithal-monitor/monitor.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..05a2629 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Ghaymah SRE Exam Repository + +This repository collects the solutions and supporting material for the Ghaymah SRE exam. Each folder contains one task answer or a shared reference used by multiple answers. + +## Repository Layout + +| Folder | Purpose | +|---|---| +| `q1-deploy-monitor/` | Deploying a sample API on Ghaymah Containers, with health checks, dashboard, and monitoring scripts. | +| `q2-postmortem/` | Blameless postmortem for a service outage and the follow-up remediation plan. | +| `q3-cicd/` | GitHub Actions CI/CD workflow with staging and production deployment flow. | +| `q4-scalability/` | Scalability and load-balancing calculations, including container sizing and scaling strategy. | +| `q5-mithal-monitor/` | Self-contained monitor for mithal.space with a browser dashboard and HTTP metrics endpoint. | +| `common-mortakaz/` | Shared integration ideas with products discovered through Mortakaz. | +| `common-qabilah/` | Shared profile/reference material used by the exam answers. | + +## What Each Task Covers + +`q1-deploy-monitor/` includes a Flask API, Dockerfile, and monitoring utilities for deployment on Ghaymah Containers. + +`q2-postmortem/` documents the incident analysis, root cause, impact, timeline, and corrective actions. + +`q3-cicd/` describes a CI/CD pipeline that builds once, deploys to staging, and requires manual approval before production. + +`q4-scalability/` explains the traffic assumptions, the container count calculation, and the recommended auto-scaling strategy. + +`q5-mithal-monitor/` provides a standalone Python monitor plus `dashboard.html` for live visibility into latency, uptime, DNS, SSL, and search checks. + +## Quick Start + +If you want to inspect a specific answer, open the relevant folder directly. For the runnable tasks: + +- Open `q1-deploy-monitor/dashboard.html` in a browser to view the monitoring UI. +- Run `q1-deploy-monitor/health-check.py` or `q1-deploy-monitor/health-check.sh` against the deployed service. +- Run `q5-mithal-monitor/monitor.py` to collect checks and serve the dashboard locally. + +## Notes + +- The repository is organized as a set of independent answers, so there is no single top-level application to build. +- Most documentation is written in Arabic to match the exam format, while this README serves as the entry point. diff --git a/common-mortakaz/integration-1.md b/common-mortakaz/integration-1.md new file mode 100644 index 0000000..dea9a9c --- /dev/null +++ b/common-mortakaz/integration-1.md @@ -0,0 +1,76 @@ +# اقتراح تكامل #1 — قُمرة × ghaymah.systems + +**المنتج:** [قُمرة](https://qumra.cloud) — عبدالستار عبده (مكتشف عبر [مرتكز](https://www.mortakaz.com/projects/682aed54040fd8289890828d)) + +--- + +## 1. وصف المنتج + +قُمرة منصة عربية متكاملة (SaaS) لإنشاء المتاجر الإلكترونية والمواقع +الاحترافية دون الحاجة لخبرة تقنية — بناء متجر، إضافة منتجات، بوابات دفع، +ولوحة تحكم، كل ذلك بواجهة عربية بسيطة. المنصة تخدم بالفعل آلاف التجار +العرب، وتنمو بشكل مستمر مع مواسم الشراء (رمضان، الجمعة البيضاء، الأعياد). + +## 2. كيف يتكامل مع ghaymah.systems + +قُمرة حاليًا تدير البنية التحتية لآلاف المتاجر بشكل مباشر أو عبر مزود +سحابي واحد. التكامل المقترح يحوّل ghaymah.systems إلى **طبقة الاستضافة +والتوسع الافتراضية** لكل متجر يُنشأ عبر قُمرة: + +- عند إنشاء تاجر لمتجر جديد على قُمرة → يُنشأ تلقائيًا (عبر API استدعاء) + container معزول على غيمة لهذا المتجر (multi-tenant عبر namespaces). +- بيانات كل متجر (كتالوج المنتجات، الطلبات، الصور) تُخزَّن على + **Ghaymah Block Storage** الخاص بذلك الـ tenant، مما يضمن عزل البيانات + وسهولة أخذ snapshots لكل متجر بشكل مستقل. +- عند مواسم الذروة (الجمعة البيضاء)، تُفعّل قُمرة auto-scaling عبر HPA + الخاص بغيمة لكل متجر يشهد ارتفاعًا في الزيارات، دون أن يؤثر ذلك على + باقي المتاجر (multi-tenant isolation). +- استخدام CDN/edge caching من غيمة لتسريع تحميل صفحات المتاجر للزوار. + +### رسم توضيحي مبسّط (Architecture Sketch) + +``` +تاجر قُمرة (Dashboard) + │ ينشئ متجر جديد + ▼ + Qumra API / Orchestrator + │ + ▼ + ┌───────────────────────────────────────────────┐ + │ ghaymah.systems (Cloud) │ + │ │ + │ Load Balancer (متعدد المتاجر) │ + │ │ │ + │ ▼ │ + │ Store A Container Store B Container ... │ + │ │ │ │ + │ ▼ ▼ │ + │ Block Storage A Block Storage B │ + │ (منتجات/طلبات) (منتجات/طلبات) │ + └───────────────────────────────────────────────┘ + │ + ▼ + الزائر النهائي (عميل المتجر) +``` + +## 3. القيمة المضافة للمستخدم النهائي + +- **للتاجر:** استضافة أسرع وأكثر استقرارًا خصوصًا في مواسم الذروة، بدون + الحاجة لفهم أي تفاصيل تقنية عن الخوادم — التوسع يحدث تلقائيًا وشفافيًا. +- **للزائر/العميل:** زمن استجابة أقل لصفحات المتجر، واستمرارية الخدمة + حتى مع ارتفاع الطلب المفاجئ (مثلًا حملة إعلانية ناجحة). +- **لقُمرة كمنصة:** تقليل تكلفة البنية التحتية عبر نموذج استهلاك حسب + الاستخدام (pay-per-tenant)، وتوفير SLA أعلى لعملائها التجاريين + بالاعتماد على مزود سحابي عربي متخصص بدل الاعتماد الكامل على مزود أجنبي. + +## 4. التحديات التقنية أو التجارية المحتملة + +- **تقنيًا:** بناء طبقة orchestration موثوقة تربط API قُمرة بـ API غيمة + لإنشاء/حذف الموارد تلقائيًا لكل متجر (idempotency ومعالجة الأخطاء أمر حرج). +- **الهجرة:** نقل المتاجر القائمة فعليًا من البنية الحالية إلى غيمة دون + توقف خدمة (zero-downtime migration) قد يستغرق وقتًا وتخطيطًا دقيقًا. +- **الأمان والعزل:** ضمان عزل تام بين بيانات المتاجر المختلفة (multi-tenancy) + ومنع أي تسرّب بين containers مشتركة الموارد. +- **تجاريًا:** الاتفاق على نموذج تسعير عادل بين الطرفين (هل التكلفة على + قُمرة أم تُمرَّر جزئيًا للتاجر؟) وتحديد من يتحمل SLA النهائي أمام + المستخدم. diff --git a/common-mortakaz/integration-2.md b/common-mortakaz/integration-2.md new file mode 100644 index 0000000..b9c139c --- /dev/null +++ b/common-mortakaz/integration-2.md @@ -0,0 +1,83 @@ +# اقتراح تكامل #2 — الباحث الذكي × mithal.space + +**المنتج:** [الباحث الذكي / Seeker Engine](https://seekerengine.com) — +أحمد رامي (مكتشف عبر [مرتكز](https://www.mortakaz.com/projects/6a29ce37c100ecc87a9e47e4)) + +--- + +## 1. وصف المنتج + +منصة تعليمية تفاعلية موجهة للمجتمع التقني العربي، تتيح للمستخدمين إنشاء +**"كبسولات معرفية"** (شروحات قصيرة عن تقنية أو أداة جديدة) ومشاركتها، +مع دعم الصور والتفاعل عبر الإعجابات والتعليقات. المحتوى بالكامل من +المستخدمين (UGC) وباللغة العربية. + +## 2. كيف يتكامل مع mithal.space + +mithal.space (مختبرات مِثال) مؤسسة بحثية غير ربحية متخصصة في الذكاء +الاصطناعي لمنطقة الشرق الأوسط وشمال أفريقيا، مع تركيز طبيعي على نماذج +اللغة العربية. التكامل المقترح يجعل مِثال **الطبقة الذكية** التي تعالج +محتوى الباحث الذكي: + +- **تلخيص وتوسيم تلقائي:** عند نشر كبسولة معرفية، يُستدعى نموذج لغوي + عربي من مِثال لاستخراج tags تلقائية وتصنيف الكبسولة ضمن الأقسام + المناسبة (بدل الاعتماد الكامل على تصنيف المستخدم اليدوي). +- **فحص جودة ومراجعة المحتوى:** استخدام نموذج مِثال للكشف عن التكرار + (كبسولات مشابهة سابقًا موجودة) والمحتوى الضعيف/المضلل قبل النشر. +- **مساعد بحث ذكي:** إضافة خاصية "اسأل عن هذا الموضوع" تتيح للمستخدم طرح + سؤال متابعة على كبسولة معينة، يُجاب عليه عبر نموذج مِثال بالاستناد على + محتوى المنصة نفسها (RAG على قاعدة الكبسولات). +- **توصيات مخصصة:** تحليل سلوك القراءة والإعجابات لتوليد توصيات كبسولات + ذات صلة لكل مستخدم. + +### رسم توضيحي مبسّط (Architecture Sketch) + +``` +المستخدم ينشئ كبسولة معرفية + │ + ▼ + Seeker Engine (الباحث الذكي) + │ (Webhook / API عند النشر) + ▼ + ┌─────────────────────────────────┐ + │ mithal.space (AI) │ + │ │ + │ نموذج لغوي عربي │ + │ ├─ توسيم تلقائي (Tags) │ + │ ├─ فحص تكرار/جودة │ + │ └─ تلخيص قصير │ + └─────────────────────────────────┘ + │ نتيجة المعالجة (JSON) + ▼ + تحديث الكبسولة + عرضها للمجتمع + │ + ▼ + سؤال متابعة من مستخدم آخر ──► RAG على قاعدة الكبسولات ──► إجابة +``` + +## 3. القيمة المضافة للمستخدم النهائي + +- **لصانع المحتوى:** تقليل الجهد اليدوي في التصنيف والتوسيم، وملاحظات + فورية إن كان الموضوع مكررًا أو يحتاج تحسينًا قبل النشر. +- **للقارئ:** اكتشاف أسهل للمحتوى ذي الصلة، وإمكانية الحصول على إجابات + مباشرة على أسئلته دون البحث اليدوي بين عشرات الكبسولات. +- **للمنصة:** رفع جودة المحتوى العربي التقني المتراكم، وتمييزها كمنصة + "ذكية" تدعمها جهة بحثية متخصصة في الذكاء الاصطناعي العربي — وهو عامل + تفاضلي (differentiator) واضح أمام منصات مشابهة. +- **لمِثال:** بيانات تدريب/تقييم حقيقية (real-world Arabic tech content) + لتحسين نماذجها، ضمن اتفاقية استخدام بيانات واضحة وشفافة. + +## 4. التحديات التقنية أو التجارية المحتملة + +- **جودة النموذج على المحتوى التقني:** المصطلحات التقنية غالبًا إنجليزية + داخل نص عربي (code-switching)، ما يتطلب أن يتعامل نموذج مِثال جيدًا مع + هذا المزيج اللغوي. +- **زمن الاستجابة:** إن كانت المعالجة (تلخيص/توسيم) تحدث لحظة النشر، + يجب أن تكون سريعة كفاية حتى لا تُبطئ تجربة النشر (يُفضّل معالجة + غير متزامنة عبر queue مع تحديث لاحق للكبسولة). +- **الخصوصية وملكية البيانات:** الاتفاق الواضح على من يملك حقوق استخدام + محتوى المستخدمين لتحسين نماذج مِثال البحثية، مع الحصول على موافقة + المستخدمين إن استُخدمت بياناتهم في التدريب. +- **تجاريًا:** مِثال مؤسسة بحثية غير ربحية — قد لا يكون لديها نموذج + API تجاري جاهز بـ SLA واضح، ما يتطلب اتفاقية شراكة بحثية/تجريبية بدل + عقد تجاري تقليدي في المرحلة الأولى. diff --git a/common-qabilah/qabilah-profile.txt b/common-qabilah/qabilah-profile.txt new file mode 100644 index 0000000..5a6c9b4 --- /dev/null +++ b/common-qabilah/qabilah-profile.txt @@ -0,0 +1 @@ +https://qabilah.com/profile/omar7ussein/professional-profile \ No newline at end of file diff --git a/q1-deploy-monitor/.dockerignore b/q1-deploy-monitor/.dockerignore new file mode 100644 index 0000000..41783c3 --- /dev/null +++ b/q1-deploy-monitor/.dockerignore @@ -0,0 +1,8 @@ +__pycache__/ +*.pyc +.git +.gitignore +*.log +status.json +.venv/ +README.md diff --git a/q1-deploy-monitor/Dockerfile b/q1-deploy-monitor/Dockerfile new file mode 100644 index 0000000..c2b8daa --- /dev/null +++ b/q1-deploy-monitor/Dockerfile @@ -0,0 +1,30 @@ +# ---- Base image ----------------------------------------------------------- +FROM python:3.11-slim AS base + +# Prevent .pyc files & enable unbuffered logging (important for container logs) +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PORT=8080 + +WORKDIR /app + +# ---- Install dependencies first (better layer caching) -------------------- +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# ---- Copy application code ------------------------------------------------- +COPY app/ ./app/ + +# ---- Run as a non-root user (security best practice) ----------------------- +RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser +USER appuser + +EXPOSE 8080 + +# ---- Container-level health check ----------------------------------------- +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD python -c "import urllib.request,sys; \ + sys.exit(0) if urllib.request.urlopen('http://127.0.0.1:8080/health', timeout=3).status == 200 else sys.exit(1)" + +# ---- Production WSGI server ------------------------------------------------- +CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--workers", "2", "--threads", "4", "--timeout", "30", "app.main:app"] diff --git a/q1-deploy-monitor/README.md b/q1-deploy-monitor/README.md new file mode 100644 index 0000000..3dcf7fa --- /dev/null +++ b/q1-deploy-monitor/README.md @@ -0,0 +1,97 @@ +# نشر تطبيق ومراقبته على غيمة (Ghaymah Containers) + +حل كامل لنشر واجهة برمجية (API) بسيطة على منصة الحاويات في `ghaymah.systems`، مع سكربت مراقبة ولوحة تحكم مباشرة. + +## محتويات المشروع +``` +. +├── Dockerfile +├── requirements.txt +├── .dockerignore +├── app/ +│ └── main.py # تطبيق Flask + /health + /metrics +├── health-check.sh # سكربت مراقبة بلغة bash (فحص كل 30 ثانية) +├── health-check.py +└── dashboard.html # لوحة مراقبة (HTML/CSS/JS) تعمل من المتصفح مباشرة +``` + +## 1) بناء واختبار الصورة محليًا +```bash +docker build -t sample-api:latest . +docker run --rm -p 8080:8080 sample-api:latest + +# في نافذة أخرى +curl http://localhost:8080/health +curl http://localhost:8080/metrics +``` + +## 2) النشر على ghaymah.systems + +منصة الحاويات في Ghaymah تدعم النشر إما عبر ربط مستودع Git (بناء تلقائي من الـ Dockerfile) أو عبر دفع صورة جاهزة إلى سجل الحاويات الخاص بها. الخطوات العامة: + +1. سجّل الدخول إلى console الخاص بـ **ghaymah.systems**. +2. من قسم **Containers**، اختر **New Service / Deploy Container**. +3. اختر مصدر النشر: + - **Git Repository**: اربط المستودع الذي يحتوي هذا المشروع (يجب أن يحتوي على `Dockerfile` في الجذر) — المنصة تبني الصورة تلقائيًا من الـ Dockerfile. + - **أو Container Registry**: ابنِ وادفع الصورة يدويًا: + ```bash + docker build -t //sample-api:1.0 . + docker push //sample-api:1.0 + ``` + ثم أدخل مسار الصورة هذا عند إنشاء الخدمة. +4. اضبط إعدادات الخدمة: + - **Port**: `8080` (نفس المنفذ في `EXPOSE` وفي `PORT` env). + - **Health Check Path**: `/health` (المنصة تستخدمه لمعرفة جاهزية الحاوية). + - **Environment Variables**: أضف `PORT=8080` إن احتاج الأمر. + - **Resources**: ابدأ بأصغر خطة (0.5 vCPU / 256-512MB) كافية لهذا التطبيق التجريبي. +5. اضغط **Deploy**. بعد اكتمال النشر ستحصل على رابط عام مثل: + `https://sample-api-xxxx.ghaymah.systems` +6. تحقق من النشر: + ```bash + curl https://sample-api-xxxx.ghaymah.systems/health + ``` + +> ملاحظة: أسماء الأزرار والحقول الدقيقة قد تختلف قليلًا حسب نسخة الواجهة الحالية على `ghaymah.systems` — الخطوات أعلاه تعكس تدفق العمل القياسي لمنصات الحاويات (Container-as-a-Service)، راجع `docs.ghaymah.cloud` لأي تفاصيل محدّثة. + +## 3) تشغيل سكربت المراقبة + +بعد النشر، شغّل سكربت المراقبة موجّهًا إلى الرابط العام للتطبيق: + +```bash +# Python (الخيار الموصى به) +python health-check.py --url https://sample-api-xxxx.ghaymah.systems --interval 30 + +# أو bash +chmod +x monitor.sh +./monitor.sh https://sample-api-xxxx.ghaymah.systems 30 +``` + +السكربت يقوم بـ: +- فحص `/health` كل 30 ثانية. +- تسجيل الحالة وزمن الاستجابة في `monitor.log`. +- كتابة آخر نتيجة في `status.json`. +- إطلاق تنبيه (`ALERT`) في السجل بعد 3 فحوصات فاشلة متتالية. + +يمكن تشغيله كخدمة نظام دائمة (systemd) أو كحاوية منفصلة (sidecar) بجانب التطبيق نفسه. + +## 4) لوحة المراقبة (Dashboard) + +افتح `dashboard.html` مباشرة في المتصفح (لا يحتاج خادمًا، ملف ثابت واحد): + +1. أدخل الرابط العام للتطبيق في حقل الاتصال، مثل: + `https://sample-api-xxxx.ghaymah.systems` +2. اضغط **اتصال**. + +تعرض اللوحة: +- **الحالة**: مؤشر أخضر (يعمل) / أحمر (متوقف)، مع نبض حي عند التشغيل السليم. +- **زمن الاستجابة**: آخر قيمة + رسم بياني لآخر 30 قراءة. +- **عدد الطلبات**: القيمة الإجمالية القادمة من `/metrics`. +- **مدة التشغيل** وسجل مباشر لكل عملية فحص. + +اللوحة تستدعي `/metrics` كل 5 ثوانٍ عبر `fetch()` مباشرة من المتصفح؛ التطبيق (`main.py`) يضيف ترويسة `Access-Control-Allow-Origin: *` لذلك لا حاجة لخادم وسيط. + +## ملاحظات إنتاجية (Production Notes) +- التطبيق يعمل بمستخدم غير جذري (`non-root user`) داخل الحاوية. +- يُستخدم `gunicorn` كخادم WSGI إنتاجي بدلاً من خادم التطوير المدمج في Flask. +- `HEALTHCHECK` مضمّن في الـ Dockerfile نفسه، بالإضافة إلى فحص خارجي (`health-check.py`) — طبقتا مراقبة مستقلتان. +- للتوسع: يمكن رفع عدد النسخ (replicas) من إعدادات الخدمة في Ghaymah دون تعديل الكود. diff --git a/q1-deploy-monitor/app/main.py b/q1-deploy-monitor/app/main.py new file mode 100644 index 0000000..13bbdd8 --- /dev/null +++ b/q1-deploy-monitor/app/main.py @@ -0,0 +1,83 @@ +""" +Simple Python API service. +Exposes: + GET / -> basic info + GET /health -> liveness/readiness probe + GET /metrics -> runtime metrics consumed by the monitoring dashboard +""" + +import os +import time +import threading +from datetime import datetime, timezone + +from flask import Flask, jsonify + +app = Flask(__name__) + +START_TIME = time.time() + +# --- In-memory metrics (thread-safe) -------------------------------------- +_lock = threading.Lock() +_metrics = { + "requests_total": 0, + "total_response_time_ms": 0.0, +} + + +@app.before_request +def _start_timer(): + from flask import g + g.start_time = time.perf_counter() + + +@app.after_request +def _record_metrics(response): + from flask import g + elapsed_ms = (time.perf_counter() - getattr(g, "start_time", time.perf_counter())) * 1000 + with _lock: + _metrics["requests_total"] += 1 + _metrics["total_response_time_ms"] += elapsed_ms + # Allow the standalone dashboard.html to call this API from any origin + response.headers["Access-Control-Allow-Origin"] = "*" + return response + + +@app.route("/") +def index(): + return jsonify({ + "service": "sample-api", + "message": "API is running. See /health and /metrics." + }) + + +@app.route("/health") +def health(): + """Used by the container platform's health checks and the monitor.py script.""" + return jsonify({ + "status": "healthy", + "timestamp": datetime.now(timezone.utc).isoformat(), + "uptime_seconds": round(time.time() - START_TIME, 2), + }), 200 + + +@app.route("/metrics") +def metrics(): + """Used by dashboard.html to render live stats.""" + with _lock: + total = _metrics["requests_total"] + total_time = _metrics["total_response_time_ms"] + avg_ms = round(total_time / total, 2) if total else 0.0 + + return jsonify({ + "status": "healthy", + "uptime_seconds": round(time.time() - START_TIME, 2), + "requests_total": total, + "avg_response_time_ms": avg_ms, + "timestamp": datetime.now(timezone.utc).isoformat(), + }) + + +if __name__ == "__main__": + port = int(os.environ.get("PORT", 8080)) + app.run(host="0.0.0.0", port=port) diff --git a/q1-deploy-monitor/dashboard.html b/q1-deploy-monitor/dashboard.html new file mode 100644 index 0000000..a08dbc2 --- /dev/null +++ b/q1-deploy-monitor/dashboard.html @@ -0,0 +1,232 @@ + + + + + +لوحة مراقبة التطبيق + + + +
+
+
+

لوحة مراقبة التطبيق

+
فحص كل 5 ثوانٍ · Ghaymah Containers
+
+
+ + +
+
+ +
+
+
الحالة
+
+
+
غير متصل
+
+
+
+
زمن الاستجابة
+
--
+
+
+
عدد الطلبات
+
--
+
+
+
مدة التشغيل
+
--
+
+
+ +
+
زمن الاستجابة (آخر 30 قراءة)
+ +
+ +
+ +
يعتمد على نقاط الوصول /health و /metrics · يعمل بالكامل من المتصفح
+
+ + + + diff --git a/q1-deploy-monitor/health-check.py b/q1-deploy-monitor/health-check.py new file mode 100644 index 0000000..8335fc6 --- /dev/null +++ b/q1-deploy-monitor/health-check.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +""" +Lightweight uptime/health monitor. + +Polls the target app's /health endpoint every CHECK_INTERVAL seconds, +logs status + response time, and writes the latest result to a JSON +file (status.json) that can be consumed by other tools or dashboards. + +Usage: + python health-check.py --url https://your-app.ghaymah.systems + python health-check.py --url https://your-app.ghaymah.systems --interval 30 +""" + +import argparse +import json +import logging +import time +import urllib.request +import urllib.error +from datetime import datetime, timezone + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(levelname)s] %(message)s", + handlers=[ + logging.FileHandler("monitor.log"), + logging.StreamHandler(), + ], +) +log = logging.getLogger("monitor") + +STATUS_FILE = "status.json" +FAILURE_THRESHOLD = 3 # consecutive failures before raising an "ALERT" + + +def check_health(url: str, timeout: float = 5.0): + start = time.perf_counter() + try: + with urllib.request.urlopen(url, timeout=timeout) as resp: + elapsed_ms = round((time.perf_counter() - start) * 1000, 2) + body = json.loads(resp.read().decode()) + return { + "ok": resp.status == 200, + "http_status": resp.status, + "response_time_ms": elapsed_ms, + "body": body, + } + except urllib.error.HTTPError as e: + elapsed_ms = round((time.perf_counter() - start) * 1000, 2) + return {"ok": False, "http_status": e.code, "response_time_ms": elapsed_ms, "error": str(e)} + except Exception as e: # DNS errors, timeouts, connection refused, etc. + elapsed_ms = round((time.perf_counter() - start) * 1000, 2) + return {"ok": False, "http_status": None, "response_time_ms": elapsed_ms, "error": str(e)} + + +def write_status(result: dict, consecutive_failures: int): + payload = { + "timestamp": datetime.now(timezone.utc).isoformat(), + "status": "healthy" if result["ok"] else "unhealthy", + "http_status": result.get("http_status"), + "response_time_ms": result.get("response_time_ms"), + "consecutive_failures": consecutive_failures, + } + with open(STATUS_FILE, "w") as f: + json.dump(payload, f, indent=2) + + +def main(): + parser = argparse.ArgumentParser(description="Poll /health endpoint on an interval.") + parser.add_argument("--url", required=True, help="Base URL of the app, e.g. https://myapp.ghaymah.systems") + parser.add_argument("--interval", type=int, default=30, help="Seconds between checks (default: 30)") + args = parser.parse_args() + + health_url = args.url.rstrip("/") + "/health" + log.info("Starting monitor for %s every %ss", health_url, args.interval) + + consecutive_failures = 0 + + while True: + result = check_health(health_url) + write_status(result, consecutive_failures) + + if result["ok"]: + if consecutive_failures > 0: + log.info("Service RECOVERED after %d failed check(s).", consecutive_failures) + consecutive_failures = 0 + log.info("OK status=%s response_time=%sms", result["http_status"], result["response_time_ms"]) + else: + consecutive_failures += 1 + log.warning( + "FAIL attempt=%d status=%s error=%s", + consecutive_failures, result.get("http_status"), result.get("error"), + ) + if consecutive_failures >= FAILURE_THRESHOLD: + log.error("ALERT: %s has failed %d consecutive health checks!", args.url, consecutive_failures) + + time.sleep(args.interval) + + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + log.info("Monitor stopped by user.") diff --git a/q1-deploy-monitor/health-check.sh b/q1-deploy-monitor/health-check.sh new file mode 100644 index 0000000..7f97df9 --- /dev/null +++ b/q1-deploy-monitor/health-check.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# +# Simple bash health monitor - polls /health every 30s. +# Usage: ./monitor.sh https://your-app.ghaymah.systems [interval_seconds] + +set -euo pipefail + +BASE_URL="${1:?Usage: $0 [interval_seconds]}" +INTERVAL="${2:-30}" +HEALTH_URL="${BASE_URL%/}/health" +LOG_FILE="monitor.log" +FAILURE_THRESHOLD=3 +failures=0 + +log() { + echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ") [$1] $2" | tee -a "$LOG_FILE" +} + +log "INFO" "Starting monitor for $HEALTH_URL every ${INTERVAL}s" + +while true; do + start_ns=$(date +%s%N) + http_code=$(curl -o /tmp/health_resp.json -s -w "%{http_code}" --max-time 5 "$HEALTH_URL" || echo "000") + end_ns=$(date +%s%N) + elapsed_ms=$(( (end_ns - start_ns) / 1000000 )) + + if [ "$http_code" == "200" ]; then + if [ "$failures" -gt 0 ]; then + log "INFO" "Service RECOVERED after $failures failed check(s)." + fi + failures=0 + log "INFO" "OK status=$http_code response_time=${elapsed_ms}ms" + else + failures=$((failures + 1)) + log "WARN" "FAIL attempt=$failures status=$http_code" + if [ "$failures" -ge "$FAILURE_THRESHOLD" ]; then + log "ERROR" "ALERT: $BASE_URL has failed $failures consecutive health checks!" + fi + fi + + sleep "$INTERVAL" +done diff --git a/q1-deploy-monitor/requirements.txt b/q1-deploy-monitor/requirements.txt new file mode 100644 index 0000000..b733f8f --- /dev/null +++ b/q1-deploy-monitor/requirements.txt @@ -0,0 +1,2 @@ +flask==3.0.3 +gunicorn==22.0.0 diff --git a/q2-postmortem/postmortem-report.md b/q2-postmortem/postmortem-report.md new file mode 100644 index 0000000..2ce1410 --- /dev/null +++ b/q2-postmortem/postmortem-report.md @@ -0,0 +1,180 @@ +# تقرير ما بعد الحادثة (Postmortem) +## انقطاع خدمة sample-api لمدة 45 دقيقة بسبب OOMKilled متكرر + +| الحقل | القيمة | +|---|---| +| **معرّف الحادثة** | INC-2026-0726-01 | +| **الخدمة المتأثرة** | `sample-api` (Ghaymah Containers) | +| **تاريخ الحادثة** | 26 يوليو 2026 | +| **مدة الانقطاع** | 45 دقيقة (14:05 – 14:50 UTC) | +| **الخطورة (Severity)** | SEV-2 — تعطّل كامل للخدمة، بدون فقدان بيانات | +| **الحالة** | مغلق — الإجراءات التصحيحية قيد التنفيذ | +| **معدّ التقرير** | فريق SRE | +| **نوع التقرير** | Blameless Postmortem | + +--- + +## 1. الملخص التنفيذي + +توقفت خدمة `sample-api` عن الاستجابة لمدة 45 دقيقة نتيجة دخولها في حلقة إعادة تشغيل متكررة (**CrashLoop**) بسبب قتل الحاوية من قبل نظام إدارة الذاكرة في المضيف (**OOMKilled**، exit code 137). السبب الجذري هو عدم تطابق بين حد الذاكرة (memory limit) المضبوط للحاوية وحجم الذاكرة الفعلي الذي يحتاجه التطبيق تحت الحمل، مع غياب أي تنبيه استباقي (proactive alert) قبل وصول الاستهلاك للحد الأقصى. تمت استعادة الخدمة برفع حد الذاكرة يدويًا وإعادة نشر الخدمة. لا يوجد فقدان بيانات، والتأثير كان محصورًا في عدم توفر الـ API (Full Outage) للمستخدمين خلال فترة الحادثة. + +--- + +## 2. الأثر (Impact) + +- **التوفر:** 0% استجابة ناجحة من `/health` و `/metrics` خلال 45 دقيقة. +- **المستخدمون المتأثرون:** جميع الطلبات الواردة على النطاق العام للخدمة (HTTP 502/504 من طبقة الـ ingress بعد فشل كل محاولات إعادة التشغيل المتتالية). +- **البيانات:** لا يوجد فقدان بيانات (الخدمة عديمة الحالة / stateless). +- **السمعة/SLA:** تجاوز الحادث ميزانية الخطأ الشهرية (error budget) لهذه الخدمة بنسبة تقديرية 60%. + +--- + +## 3. الجدول الزمني (Timeline) — بتوقيت UTC + +| الوقت | الحدث | +|---|---| +| 13:42 | ارتفاع تدريجي وغير ملحوظ في استهلاك الذاكرة بعد نشر تحديث يضيف معالجة استجابات أكبر (JSON payloads) دون تحرير كائنات مؤقتة بشكل كافٍ. | +| 14:05 | استهلاك الذاكرة يصل لحد الحاوية (512MB) → **OOMKilled** الأولى، exit code 137. المنصة تعيد تشغيل الحاوية تلقائيًا (restart policy: Always). | +| 14:06–14:20 | حلقة CrashLoopBackOff: الحاوية تُقتل مجددًا خلال ثوانٍ من كل إعادة تشغيل بسبب تحميل الحالة القديمة/التخزين المؤقت الذي يستهلك الذاكرة بسرعة من جديد. عدد مرات إعادة التشغيل: 9 خلال 14 دقيقة. | +| 14:22 | فحص `health-check.py` الخارجي يسجّل 3 فشل متتالي على `/health` → تسجيل `ALERT` في `monitor.log` (لا يوجد تنبيه فوري لفريق العمل لأن السكربت كان يعمل يدويًا بدون تكامل مع قناة إشعارات). | +| 14:31 | أحد المهندسين يلاحظ الانقطاع أثناء فحص روتيني (لم يكن هناك تنبيه تلقائي يوقظ الفريق — **فجوة كشف أولى**). | +| 14:33 | بدء التحقيق: مراجعة سجلات الحاوية على console غيمة، ملاحظة أحداث `OOMKilled` المتكررة. | +| 14:40 | تحديد السبب المباشر: حد الذاكرة المضبوط (512MB) غير كافٍ لحجم البيانات المعالجة بعد آخر تحديث. | +| 14:45 | رفع حد الذاكرة إلى 1024MB مؤقتًا وإعادة نشر الخدمة (rolling restart). | +| 14:50 | الخدمة تستقر، `/health` يعيد 200 باستمرار لمدة 10 دقائق متتالية. **إغلاق الحادثة.** | +| 15:30 | مراجعة ما بعد الحادثة (هذا التقرير) وفتح بنود الإجراءات التصحيحية. | + +--- + +## 4. تحليل السبب الجذري (Root Cause Analysis — 5 Whys) + +1. **لماذا توقفت الخدمة؟** + لأن الحاوية كانت تُقتل بشكل متكرر من قبل نواة النظام (OOM Killer) — exit code 137. +2. **لماذا قُتلت الحاوية؟** + لأن استهلاك الذاكرة الفعلي تجاوز حد الذاكرة (memory limit) المضبوط للحاوية على منصة غيمة. +3. **لماذا تجاوز الاستهلاك الحد؟** + لأن آخر تحديث للتطبيق أضاف معالجة لحمولات JSON أكبر مع احتفاظ بكائنات في الذاكرة (buffers/caches) دون تحرير كافٍ، ولم يُختبر تحت حمل واقعي قبل النشر. +4. **لماذا لم يُكتشف هذا قبل النشر أو فور حدوثه؟** + لأنه لا يوجد اختبار حمل (load/soak test) ضمن خط النشر، ولا يوجد تنبيه استباقي على نسبة استهلاك الذاكرة (كان الاعتماد فقط على فحص `/health` بعد فشل الخدمة فعليًا، وهو كشف "بعد الحقيقة" لا استباقي). +5. **لماذا لم تتعافَ الخدمة تلقائيًا رغم إعادة التشغيل التلقائي؟** + لأن سياسة إعادة التشغيل لم تكن مقترنة بأي تعديل ذاتي في الموارد (auto-scaling/right-sizing)، فكانت الحاوية تدخل في نفس ظرف نفاد الذاكرة عند كل إعادة تشغيل (Crash Loop) بدل التعافي. + +**السبب الجذري النهائي:** +غياب سياسة توسّع تلقائي مرتبطة باستهلاك الذاكرة الفعلي، مع تحديد ثابت وغير كافٍ لحدود الموارد (static under-provisioned memory limit)، وغياب مراقبة استباقية لاستهلاك الذاكرة قبل الوصول لنقطة القتل. + +--- + +## 5. ما الذي سار بشكل جيد / ما الذي لم يسر بشكل جيد + +**سار بشكل جيد:** +- إعادة التشغيل التلقائي للحاوية منع الحاجة لتدخل يدوي لإعادة تشغيلها. +- التطبيق عديم الحالة، فلم يحدث فقدان أو تلف بيانات. +- سكربت `health-check.py` سجّل الحادثة بدقة زمنية (توقيت أول فشل متتالي) وساعد في بناء الجدول الزمني. + +**لم يسر بشكل جيد:** +- لا يوجد تنبيه فوري (Slack/Email/SMS) عند فشل الفحوصات — الاعتماد على ملاحظة بشرية عرضية أخّر الاستجابة حوالي 9 دقائق. +- لا توجد مراقبة لاستهلاك الذاكرة كنسبة مئوية من الحد (memory usage %) قبل وقوع OOM. +- حدود الموارد (requests/limits) لم تُراجَع بعد آخر تحديث للكود. +- لا يوجد اختبار حمل ضمن CI/CD قبل النشر للإنتاج. + +--- + +## 6. الإجراءات التصحيحية (Action Items) + +| # | الإجراء | الأولوية | المسؤول | الموعد المستهدف | +|---|---|---|---|---| +| 1 | ضبط تنبيهات فورية (Alerting) عند تجاوز استهلاك الذاكرة 80% من الحد لمدة > 3 دقائق | عالية | SRE | خلال 3 أيام | +| 2 | تطبيق سياسة auto-scaling أفقي/عمودي مبنية على الذاكرة (تفاصيل في القسم 7) | عالية | SRE / Platform | خلال أسبوع | +| 3 | إضافة اختبار حمل (load test) إلى خط CI/CD قبل أي نشر للإنتاج | متوسطة | فريق التطوير | خلال أسبوعين | +| 4 | ربط `health-check.py` بقناة تنبيه فعلية (Webhook/Slack) بدل الاكتفاء بملف سجل محلي | عالية | SRE | خلال 3 أيام | +| 5 | مراجعة الكود المسؤول عن معالجة الحمولات الكبيرة وتحرير الذاكرة (buffer/cache) بشكل صريح | عالية | فريق التطوير | خلال أسبوع | +| 6 | إضافة مقياس `memory_usage_percent` إلى `/metrics` ولوحة المراقبة | متوسطة | فريق التطوير | خلال أسبوعين | +| 7 | توثيق حادثة OOMKilled ضمن Runbook التشغيل مع خطوات الاستجابة القياسية | منخفضة | SRE | خلال أسبوعين | + +--- + +## 7. سياسة Auto-Scaling المقترحة لمنصة غيمة (منع التكرار) + +الهدف: منع دخول الخدمة في CrashLoop بسبب نفاد الذاكرة، عبر ثلاث طبقات حماية مكمّلة لبعضها: **تحديد صحيح للموارد**، **توسّع أفقي عند الضغط**، و**حواجز أمان تمنع القتل المفاجئ**. + +### 7.1 تصحيح حدود الموارد (Right-Sizing) — الأساس قبل أي auto-scaling +```yaml +resources: + requests: + memory: "512Mi" # الحد الأدنى المضمون للحاوية + cpu: "250m" + limits: + memory: "768Mi" # هامش أمان 50% فوق الاستهلاك الطبيعي المُقاس + cpu: "500m" +``` +> القاعدة: `limit` يجب أن يكون أعلى من أعلى استهلاك ملاحظ فعليًا (p99) بهامش لا يقل عن 30-50%، وليس رقمًا تقديريًا ثابتًا. يُعاد قياس هذه الأرقام بعد كل تغيير جوهري في الكود. + +### 7.2 التوسّع الأفقي التلقائي (Horizontal Auto-scaling) حسب الذاكرة +```yaml +autoscaling: + min_replicas: 2 # لا تقل عن نسختين لتفادي نقطة فشل واحدة + max_replicas: 6 + metrics: + - type: memory + target_utilization_percent: 65 # التوسّع قبل الوصول لحد الخطر بكثير + - type: cpu + target_utilization_percent: 70 + scale_up: + cooldown_seconds: 60 # استجابة سريعة عند الضغط + scale_down: + cooldown_seconds: 300 # تهدئة أبطأ لتفادي "التذبذب" (flapping) +``` +- التوسّع يعتمد على **متوسط استهلاك الذاكرة عبر جميع النسخ**، وليس نسخة واحدة، لتفادي توسّع كاذب بسبب Memory Leak في نسخة واحدة فقط. +- `min_replicas: 2` يضمن استمرار الخدمة أثناء إعادة تشغيل أي نسخة. + +### 7.3 حواجز أمان تمنع الدخول في CrashLoop +| الآلية | الإعداد المقترح | +|---|---| +| **Restart Policy** | `Always` مع `backoff` تصاعدي (5s → 10s → 20s ... حتى 5 دقائق) لمنع استهلاك الموارد بمحاولات إعادة تشغيل سريعة متتالية | +| **Startup/Readiness Probe** | فحص `/health` مع `initial_delay=10s`، `period=10s`، `failure_threshold=3` — لا تُدخل النسخة حركة مرور إلا بعد استقرارها | +| **Liveness Probe منفصل عن Readiness** | لتفادي إعادة تشغيل نسخة تعاني بطئًا مؤقتًا وليس تعطلًا كاملًا | +| **Pod Disruption Budget المكافئ** | الحفاظ على نسخة واحدة صحية على الأقل أثناء أي تحديث أو إعادة توسّع | +| **Circuit breaker على مستوى التطبيق** | رفض الطلبات الكبيرة (حد أقصى لحجم body) بدل معالجتها ثم الانهيار | + +### 7.4 لماذا هذا يمنع تكرار هذا الحادث تحديدًا +- **التوسّع عند 65%** يعطي وقتًا كافيًا لإضافة نسخ جديدة *قبل* وصول أي نسخة لحد الذاكرة الفعلي (768Mi)، بدل انتظار القتل ثم إعادة التشغيل في نفس الظرف. +- **الحد الأعلى المرفوع مع هامش الأمان** يمنع التصادم مع نفس نقطة الفشل التي وقعت سابقًا (512Mi غير كافٍ). +- **`min_replicas: 2`** يعني أن فشل نسخة واحدة (حتى لو حدث OOM لأي سبب مستقبلي) لا يعني انقطاع الخدمة بالكامل — النسخة الأخرى تستمر بخدمة الطلبات أثناء إعادة التشغيل. + +--- + +## 8. الكشف المبكر باستخدام أدوات مراقبة غيمة + +الهدف: الانتقال من **كشف تفاعلي** (بعد توقف الخدمة فعليًا) إلى **كشف استباقي** (قبل وصول الاستهلاك لنقطة الخطر بدقائق). + +### 8.1 المقاييس (Metrics) الواجب مراقبتها +| المقياس | مصدره | لماذا يهم | +|---|---|---| +| نسبة استهلاك الذاكرة من الحد (`memory_usage / memory_limit`) | Container Metrics في console غيمة | المؤشر الأهم — يكشف الاتجاه التصاعدي قبل القتل بدقائق | +| عدد مرات إعادة التشغيل (`restart_count`) خلال نافذة زمنية | Container Events | ارتفاع مفاجئ = علامة CrashLoop مبكرة | +| رمز الخروج (`exit_code = 137`) | Container Logs/Events | توقيع مباشر لحدث OOMKilled تحديدًا (يميّزه عن أعطال أخرى) | +| زمن استجابة `/health` و `/metrics` | Application-level (سكربت `health-check.py` + لوحة المراقبة) | يكشف التدهور التدريجي (latency يرتفع قبل الانهيار الكامل غالبًا) | +| معدل الأخطاء 5xx من الـ ingress | منصة غيمة (Edge/Load Balancer metrics) | يعكس الأثر الفعلي على المستخدمين | + +### 8.2 التنبيهات المقترحة (Alert Rules) +| التنبيه | الشرط | الخطورة | القناة | +|---|---|---|---| +| اقتراب من حد الذاكرة | `memory_usage_percent > 75%` لمدة 5 دقائق متواصلة | تحذير (Warning) | Slack/Email | +| خطر وشيك | `memory_usage_percent > 90%` لمدة 2 دقيقة | حرج (Critical) | Slack + استدعاء (Page) | +| حدث OOMKilled | ظهور `exit_code=137` مرة واحدة | حرج فوري | Page مباشر | +| CrashLoop | `restart_count >= 3` خلال 10 دقائق | حرج | Page مباشر | +| تدهور زمن الاستجابة | متوسط زمن استجابة `/health` يرتفع 3 أضعاف عن خط الأساس | تحذير | Slack | + +### 8.3 كيف يمنع هذا تكرار الحادث تحديدًا +في حادثة اليوم، كان الاستهلاك يتصاعد تدريجيًا بين 13:42 و14:05 (23 دقيقة) قبل أول عملية قتل — وهي نافذة زمنية كانت كافية تمامًا لإطلاق تنبيه "اقتراب من حد الذاكرة" عند تجاوز 75%، مما كان يسمح بالتدخل (زيادة الحد أو التوسّع اليدوي) قبل وصول الخدمة لنقطة الانهيار الكامل بدقائق طويلة، بدل اكتشاف الحادثة بعد 26 دقيقة من توقف الخدمة فعليًا. + +### 8.4 تكامل عملي مع أدوات المشروع الحالية +- تحديث `main.py` لإضافة حقل `memory_usage_percent` إلى استجابة `/metrics` (عبر قراءة `/sys/fs/cgroup/memory.current` و`memory.max` داخل الحاوية). +- ربط `health-check.py` بقناة Webhook (Slack Incoming Webhook) بدلاً من الاكتفاء بـ `monitor.log`، بحيث يُرسل تنبيهًا فوريًا بدل انتظار مراجعة يدوية للسجل. +- عرض `memory_usage_percent` كبطاقة إضافية في `dashboard.html` مع تلوين تحذيري (أصفر عند 75%+، أحمر عند 90%+) لإعطاء رؤية بصرية مباشرة لفريق التشغيل. + +--- + +## الخلاصة + +الحادثة نتجت عن تحديد ثابت وغير كافٍ لحدود الذاكرة تصادم مع زيادة حقيقية في استهلاك التطبيق، وتفاقم أثرها بسبب غياب تنبيه استباقي وغياب توسّع تلقائي يمتص الضغط قبل الوصول لنقطة القتل. الإجراءات التصحيحية في هذا التقرير (right-sizing + auto-scaling أفقي + تنبيهات استباقية) تعالج السبب الجذري مباشرة، وتقلّل احتمال تكرار حادثة مشابهة من "شبه مؤكد" إلى "نادر جدًا" إذا نُفّذت جميعها خلال الجدول الزمني المحدد أعلاه. diff --git a/q3-cicd/README.md b/q3-cicd/README.md new file mode 100644 index 0000000..9ee8868 --- /dev/null +++ b/q3-cicd/README.md @@ -0,0 +1,108 @@ +# بناء CI/CD Pipeline على غيمة (GitHub Actions + Ghaymah Container Registry) + +## محتويات +``` +.github/workflows/workflow.yml # الـ workflow الكامل +README.md # هذا التوثيق +``` + +--- + +## 1) نظرة عامة على الـ Pipeline + +3 مراحل متسلسلة (jobs)، كل مرحلة تعتمد على نجاح ما قبلها: + +``` +build-and-push ──▶ deploy-staging ──▶ deploy-production + (بناء + فحص (نشر تلقائي، (⏸ موافقة يدوية + + رفع للسجل) بدون موافقة) مطلوبة قبل التنفيذ) +``` + +- **build-and-push**: يبني صورة Docker، يشغّلها محليًا داخل الـ runner ويتحقق من `/health` (بوابة جودة أساسية) قبل رفعها فعليًا إلى **Ghaymah Container Registry**. +- **deploy-staging**: ينشر الصورة تلقائيًا على بيئة `staging` فور نجاح البناء — بدون تدخل بشري، لأن الهدف من staging هو تحقق سريع ومستمر. +- **deploy-production**: نفس صورة staging (بدون إعادة بناء) تُنشر على `production`، لكن **الوظيفة لا تبدأ التنفيذ إلا بعد موافقة يدوية** (تفاصيل القسم التالي). + +--- + +## 2) الموافقة اليدوية (Manual Approval) قبل الإنتاج + +الطريقة المعتمدة في الـ workflow هي **GitHub Environments** — وهي الآلية الرسمية والموصى بها من GitHub لهذا الغرض (وليس كودًا مخصصًا يفتح "تذكرة" أو ينتظر تعليقًا). + +### كيفية الإعداد (مرة واحدة فقط، من واجهة المستودع): +1. اذهب إلى **Settings → Environments** في مستودع GitHub. +2. أنشئ بيئة باسم `production` (يجب أن يطابق الاسم بالضبط ما هو مكتوب في `environment: name: production` داخل الـ workflow). +3. فعّل **Required reviewers** وأضف الأشخاص أو الفريق المخوّل بالموافقة على نشر الإنتاج (مثال: قائد الفريق التقني أو مسؤول SRE). +4. (اختياري لكن موصى به) فعّل **Wait timer** (مثلاً 0-5 دقائق) كطبقة أمان إضافية، و**Deployment branches** لتقييد النشر على فرع `main` فقط. +5. أضف أسرار الإنتاج (Secrets) الخاصة بهذه البيئة تحديدًا (`GHAYMAH_API_TOKEN` لبيئة production منفصل عن نفس المتغير في staging) — هذا يمنع تسريب صلاحيات الإنتاج حتى لو تم تشغيل job آخر بالخطأ. + +### كيف يعمل عمليًا +عندما يصل تنفيذ الـ workflow إلى job **deploy-production**، يتوقف تلقائيًا في حالة **"Waiting"** ولا تُنفَّذ أي خطوة داخله (بما فيها تسجيل الدخول لـ Ghaymah CLI) حتى يوافق أحد المراجعين المخوّلين من تبويب **Actions** في GitHub. هذا يضمن أن الكود الذي وصل فعليًا إلى staging وتحقق من صحته هو نفسه الذي يُنشر للإنتاج — دون إعادة بناء، ودون فجوة زمنية تسمح بتغييرات غير مراجعة. + +--- + +## 3) الفرق بين بيئة Staging وبيئة Production + +| الجانب | Staging | Production | +|---|---|---| +| **الغرض** | تحقق نهائي قبل الإنتاج: هل يعمل الكود على بنية تحتية شبيهة بالإنتاج؟ | خدمة المستخدمين الفعليين مباشرة | +| **آلية النشر** | تلقائي بالكامل فور نجاح البناء (CD حقيقي) | يدوي الموافقة، تلقائي التنفيذ بعدها | +| **حجم الموارد** | أصغر (نسخة واحدة أو نسختان، موارد أقل) لتقليل التكلفة | مطابق للحمل الحقيقي المتوقع، مع auto-scaling فعّال | +| **البيانات** | بيانات وهمية/مقنّعة (synthetic/masked data)، لا تُستخدم بيانات مستخدمين حقيقية أبدًا | بيانات حقيقية حساسة، تخضع لسياسات الخصوصية والنسخ الاحتياطي | +| **حساسية الأسرار (Secrets)** | مفاتيح API تجريبية/محدودة الصلاحية | مفاتيح إنتاج كاملة الصلاحية، معزولة تمامًا في GitHub Environment منفصل | +| **المراقبة والتنبيهات** | مراقبة أساسية (health checks) دون تنبيهات استدعاء (paging) | مراقبة كاملة + تنبيهات فورية (Slack/Page) عند أي شذوذ، حسب سياسات الحادثة الموثقة سابقًا | +| **النطاق (Domain)** | `*-staging.ghaymah.systems` أو نطاق فرعي داخلي | النطاق العام الفعلي للخدمة | +| **قابلية إعادة الإنشاء** | يمكن إعادة تدميرها وإنشاؤها في أي وقت دون قلق | تغييرات البنية تمر عبر مراجعة/موافقة، أي تعديل مباشر عليها له أثر تشغيلي | +| **من يوافق على النشر إليها** | لا أحد — تلقائي بالكامل | مراجع مخوّل محدد مسبقًا (Required Reviewer) | + +**الخلاصة العملية:** staging هي "بروفة" مطابقة قدر الإمكان للإنتاج تُستخدم لاكتشاف الأخطاء قبل وصولها للمستخدمين، بينما production هي البيئة الوحيدة التي يُسمح فيها بموافقة بشرية صريحة كحاجز أخير قبل التأثير على المستخدمين الحقيقيين. + +--- + +## 4) الربط مع Ghaymah CLI + +### أ) التثبيت (داخل الـ workflow أو محليًا) +```bash +curl -fsSL https://cli.ghaymah.systems/install.sh | sh +ghaymah --version +``` +> ملاحظة: عنوان التثبيت وأسماء الأوامر أعلاه مبنية على النمط القياسي لأدوات CLI الخاصة بمنصات الحاويات (deploy/login/logs). يُرجى التأكد من الأمر الدقيق ورابط التثبيت من `docs.ghaymah.cloud` أو console الحساب، حيث إن تفاصيل الواجهة قد تختلف عن الأمثلة هنا. + +### ب) المصادقة (Authentication) +لا تُستخدم بيانات اعتماد شخصية داخل الـ pipeline أبدًا. بدلًا من ذلك: +1. يُنشأ **API Token** مخصص لبيئة CI/CD من لوحة تحكم غيمة (Settings → API Tokens أو ما يعادلها)، بصلاحيات محدودة (نشر/سحب صور فقط، وليس صلاحيات إدارية كاملة). +2. يُخزَّن هذا التوكن كسر (Secret) في GitHub: + - `GHAYMAH_REGISTRY_TOKEN` — لتسجيل الدخول لسجل الحاويات (`docker/login-action`). + - `GHAYMAH_API_TOKEN` — لتنفيذ أوامر `ghaymah deploy` عبر الـ CLI. +3. تسجيل الدخول داخل الـ workflow: + ```bash + ghaymah auth login --token "$GHAYMAH_API_TOKEN" + ``` + +### ج) الربط مع سجل الحاويات (Container Registry) +تسجيل الدخول لسجل الحاويات يتم عبر الأمر القياسي لـ Docker (متوافق مع أي سجل OCI، بما فيه سجل غيمة): +```bash +echo "$GHAYMAH_REGISTRY_TOKEN" | docker login registry.ghaymah.systems \ + --username "$GHAYMAH_REGISTRY_USER" --password-stdin +``` +وهذا بالضبط ما يقوم به `docker/login-action@v3` المستخدم في الـ workflow، مع الاستفادة من إدارة GitHub الآمنة للأسرار بدل كتابتها في نص الأوامر. + +### د) أوامر النشر الأساسية +```bash +# نشر صورة على خدمة معيّنة (staging أو production حسب --env) +ghaymah deploy --service --image //: --env --wait + +# متابعة سجلات الخدمة بعد النشر +ghaymah logs --service --follow + +# التحقق من حالة الخدمة والنسخ الحالية +ghaymah status --service + +# التراجع عن نشر فاشل (Rollback) إلى آخر نسخة مستقرة +ghaymah rollback --service +``` + +### هـ) أفضل الممارسات المطبّقة في هذا الـ Pipeline +- **صورة واحدة تنتقل عبر كل البيئات**: تُبنى مرة واحدة في `build-and-push` وتُنشر بنفس الوسم (tag) على staging ثم production — لا إعادة بناء بين البيئتين، لضمان أن ما يُختبر هو نفسه ما يُنشر. +- **فصل الأسرار حسب البيئة**: أسرار `staging` منفصلة تمامًا عن أسرار `production` عبر GitHub Environments، فحتى لو تم اختراق بيئة staging لا يتأثر الإنتاج. +- **بوابة جودة قبل الرفع**: فحص `/health` يتم داخل الـ runner *قبل* دفع الصورة فعليًا إلى السجل، لتفادي رفع صور معطوبة. +- **موافقة يدوية = حاجز بشري واحد واضح**: بدل انتشار موافقات متفرقة في أدوات متعددة، الموافقة مركزية في نفس واجهة GitHub Actions التي يراقبها الفريق أصلًا. diff --git a/q3-cicd/workflow.yml b/q3-cicd/workflow.yml new file mode 100644 index 0000000..d4a86c3 --- /dev/null +++ b/q3-cicd/workflow.yml @@ -0,0 +1,158 @@ +name: CI/CD - Build, Push, Deploy (Ghaymah) + +# يعمل تلقائيًا عند الدفع لفرع main، أو يدويًا لأي فرع/بيئة عبر workflow_dispatch +on: + push: + branches: ["main"] + workflow_dispatch: + inputs: + image_tag: + description: "وسم اختياري إضافي للصورة (افتراضيًا: git SHA)" + required: false + default: "" + +# صلاحيات أقل ما يمكن (least privilege) +permissions: + contents: read + packages: write + +env: + # عنوان سجل الحاويات الخاص بغيمة - عدّله حسب مشروعك + GHAYMAH_REGISTRY: registry.ghaymah.systems + GHAYMAH_NAMESPACE: my-team + IMAGE_NAME: sample-api + +jobs: + # --------------------------------------------------------------------- + # 1) بناء الصورة واختبارها ورفعها إلى Ghaymah Container Registry + # --------------------------------------------------------------------- + build-and-push: + name: Build & Push Image + runs-on: ubuntu-latest + outputs: + image_ref: ${{ steps.vars.outputs.image_ref }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set image tag variables + id: vars + run: | + SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7) + TAG="${{ github.event.inputs.image_tag }}" + if [ -z "$TAG" ]; then TAG="$SHORT_SHA"; fi + IMAGE_REF="${GHAYMAH_REGISTRY}/${GHAYMAH_NAMESPACE}/${IMAGE_NAME}:${TAG}" + echo "image_ref=${IMAGE_REF}" >> "$GITHUB_OUTPUT" + echo "Building: ${IMAGE_REF}" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # تسجيل الدخول إلى سجل حاويات غيمة عبر بيانات اعتماد مخزّنة كـ GitHub Secrets + - name: Log in to Ghaymah Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.GHAYMAH_REGISTRY }} + username: ${{ secrets.GHAYMAH_REGISTRY_USER }} + password: ${{ secrets.GHAYMAH_REGISTRY_TOKEN }} + + - name: Build image + uses: docker/build-push-action@v6 + with: + context: . + push: false + load: true + tags: | + ${{ steps.vars.outputs.image_ref }} + ${{ env.GHAYMAH_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + # اختبار سريع للتأكد أن /health يستجيب قبل الرفع للسجل (بوابة جودة أساسية) + - name: Smoke test the built image + run: | + docker run -d --name smoke -p 8080:8080 ${{ steps.vars.outputs.image_ref }} + for i in $(seq 1 10); do + if curl -sf http://localhost:8080/health; then echo "Health check passed"; break; fi + echo "Waiting for app to start... ($i/10)"; sleep 2 + done + curl -sf http://localhost:8080/health || (docker logs smoke && exit 1) + docker stop smoke + + - name: Push image to Ghaymah Registry + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: | + ${{ steps.vars.outputs.image_ref }} + ${{ env.GHAYMAH_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest + + # --------------------------------------------------------------------- + # 2) نشر تلقائي على STAGING فور نجاح البناء - بدون موافقة يدوية + # --------------------------------------------------------------------- + deploy-staging: + name: Deploy to Staging + needs: build-and-push + runs-on: ubuntu-latest + environment: + name: staging + url: https://sample-api-staging.ghaymah.systems + steps: + - name: Install Ghaymah CLI + run: | + curl -fsSL https://cli.ghaymah.systems/install.sh | sh + ghaymah --version + + - name: Authenticate Ghaymah CLI + run: ghaymah auth login --token "${{ secrets.GHAYMAH_API_TOKEN }}" + + - name: Deploy image to staging service + run: | + ghaymah deploy \ + --service sample-api-staging \ + --image "${{ needs.build-and-push.outputs.image_ref }}" \ + --env staging \ + --wait + + - name: Verify staging health + run: | + curl -sf https://sample-api-staging.ghaymah.systems/health + + # --------------------------------------------------------------------- + # 3) نشر على PRODUCTION - يتطلب موافقة يدوية (Manual Approval) + # الموافقة تُنفَّذ عبر GitHub Environment "production" المحمي بمراجعين + # مطلوبين (Required Reviewers) من إعدادات المستودع، وليس بكود مخصص. + # --------------------------------------------------------------------- + deploy-production: + name: Deploy to Production (Manual Approval Required) + needs: [build-and-push, deploy-staging] + runs-on: ubuntu-latest + environment: + name: production # <-- هذا السطر يفعّل بوابة الموافقة اليدوية المضبوطة في إعدادات المستودع + url: https://sample-api.ghaymah.systems + steps: + - name: Install Ghaymah CLI + run: | + curl -fsSL https://cli.ghaymah.systems/install.sh | sh + ghaymah --version + + - name: Authenticate Ghaymah CLI + run: ghaymah auth login --token "${{ secrets.GHAYMAH_API_TOKEN }}" + + - name: Deploy image to production service + run: | + ghaymah deploy \ + --service sample-api-production \ + --image "${{ needs.build-and-push.outputs.image_ref }}" \ + --env production \ + --strategy rolling \ + --wait + + - name: Verify production health + run: | + curl -sf https://sample-api.ghaymah.systems/health + + - name: Post-deploy smoke check on /metrics + run: | + curl -sf https://sample-api.ghaymah.systems/metrics diff --git a/q4-scalability/architecture.png b/q4-scalability/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..f13d215670d5931bb8da556a55c38efbd04d9eda GIT binary patch literal 201076 zcmeFZ^;^_w+dq!$s=F$(1|q$?C`wD0fCVM`nlv=0 z2sAXmz4+}U{7ENTPz`>Pa(kfXrsZVi=3(YyNuz4!_SC`2&B50EPj^cfS6e4XVSd4z z{1Uu>+PJwrb(InjK>zRG;CFJd7Wiz4>3~o9{pmw}R~j0&FUWt#9J?^GG{I*ttwt(0B{r)FDSlYr(+|dfC=I_Q9Or5^b<0PN-26l+?pOHk|NeM( z+__-xe}04fTtwgO_uy&tf;7{sja1F zVabo-GtAX5wQ_NGF7~ct_gyB+?k^uNMXyb@>mD5*pWnFjNIjHQ+8|pkDX*vo{-Qyx zH=6anHbziTFzD@D4R7ywO)ahH*x2jr?Cd)`JGq!SF}pEht*@^yH$@#CpnxmntqqGc zcCShfIDBOg_S?o#ce;j@|9)jhqGWo0KCh_5;G<9`QOycR3MoVJV%P~9ntw~!_Ng1Z zynQXvb#_0#oERo}6smA)Ws*I8e6W6do78?B!FzK)H-bYTqOj13@BW!SB0Sd6D}pML zl9GXQm6eq?3&R+@kxFMi`I9t9XSukz3~D?h4i9}wztq>mjUNRE|W@Va=EIa;@isu7#A1KSbk&CCry8-CQ4{5kUerTZ#<_q zx3y{CzyI>@zrWD4u@$^|^E64;Z+N~MwUA@px6+_9=DU^zSE#>mpvNICZMZh&SAfFm zP`|#tXf@yrpQxutr+^KNaqBSk9st)n70KYxE= zT|rmAzIeadqnq}7o9JPpA7QAxRUkz(oBj&*OEqTBZKmr^DSE(EPRrllAJ20BaY9DM zRlnWY>jou1t+5wIrdwKDdp8%zc)vY&zxD3dcD-3R6W^5wuL1)}kIJ4|>@HN`cW2V+ zFf(0$VJigVRA7O9Y-&2byWXpAm(gomTXQM-EdzT#lc^~ zuzovXy|X&$4Y!Tb)HLsPhwtc}9}>44t=ZAhbePL@8r`Y@AG>v6mYn(EhgB)VlUv?@fDt7Z#jO73P`7>a?_>s@yu6=q?P*4k- zxYMXnlC(!b{TmvZu$K|AEY$f7${xX93|ycPJam^v{VrX&@VAGDhoz+@m#8S}H645Z z=NA!5>gt6JHqWcq<_hcbDk}%68?k(bc>zazM5d76Xs8v1#9d9Nx&xiexf8$sYV+yY zb30OA^e?~sqOGl+(buPa?dn(itwoB`!-qLLkB^;tpOAo+bam8y@+6~SV}wExefs@R z%;Jdt^XJdGZ`^ofU=V+fT{Z)*heuqzBIfUt)Yl(B{+ZD4;p&P_eW;YZ>p2x?eKuhF z*Hf=;zP$Y1t}iDdEj=A?-r!Q&E0rYaDqmQ;nFq@)Ghn3n5yAiHV9O<3A>`vrNt#dI zfSEof8xVb~h9+VAde7l1Fe?rB&Q^%VsUS7N|Hv;%CtuHGmPPLwhau57PIc~RckVRB zXQ^)T=TGf>=MRKc;)GCISt_`>n>2kTaE-H};wBZ9YUJ_-x9KDgyY(5t%Z2#j;$nkx zhuj$69epT#B_27?>b++(8TdG>jg5^(U8hti?&P|kb946YNngI)JviK3+TEQiEb~}O zW(vBL!}$60U({|6mDE(T(`V*V6CA6Hb;9-<*_rJoCHl9=gLi_0gGI^x+3M_m+dmXm zH#fNq-Ro&fMSM1S;r6q>?6$@V^sdkLk_a9t0e$fP;oYwfmj&L7Q$#~o1J!<&%mZ5vC5#z1#jZ{<40TynPLjo3yg}U&{<##hhs4}68 zgeCuaKYpXiWp)g2Ujfv-8^Xfr^TjDCDZ85sy06b4qhX=tfJMNjq@p5H6ERYau}|2X zoSMplZ`6^z9MznWt`H6#PKl9mwx#LD!Likkgut!`EzNh5NWGUV?y8_L z|7`?42=<{aG!@ucebDPR=7*GNnM87;Dr5MB*+?>;%a75cHA4>M)yY=T$DeK!8ns~m z!5ZZf6H{w$wnld2XswU^_fL1C9St8n`gr`*xf^0)I>@cIv_vK(B1?sFKvw_!`LnyUyzvcg?jEQO|LNk@C8ed43k&Jb zo&{0|i=(96W*%3#igR$>JAeMXl%JF$BO_x=b8`gT{6GINrK{(=jy0xHS% zZy6cmA3yfocGnp#pJZT*iXOrDBRd;ZVCl?^jQf^Pp4^a=Gv$m@937Qi-Pq88 zebJYzWxcb#txc>yqwVHa_V?d^zyI*zPjPW^ywjM;!5&?aCtqt*Qx}wXxACvP!_v5M z^X4N8;dLIgYE)1v+}U;Y?`Do6WPZ?M>`XZ?x(97@T)8 zh6F3<5*tyyxw#oxE^s&SR_S56IZ~>J)(JoEI=jasXs#8$65b@0T#>TBzfYAa^R@)I zgJJ!0!eXu;r=%hxM^XR;*H>bxT#B~%7D8IN^~A+bMhD&0 z(a|5qN{;^UA>;k~Csoze@ZP#%Gpc5izcr@xJU@QwePm=>NXXf$%F3p(y3}|vbY8NI z4`2kWL2;Z4=K{Gxy)ldx<>FET7easGLfYZMp03Z>RKBSx@#RieYW+{Df!FZ(&*qB= z?i-(&h>nU%|L31y5EMKxp!?Tff7x}XWg6h^u31}u+dFpKPXX!ssUc@4cFH}VEn^Fl zH6{e-hw)ltep^XmPNNxZZ7RWYC!v3AFaM}s`NrHnN)r+ig4`wTb z>*~7Mp6K;LKAg?iUhcjsXOvFSAa0w>Y<~~vBl?{R-qQy#Cv&)MVMPXn zRpoN616~pu^>#eLF&;e#PtkW{N$yh-plLMHyzrK-W0wmBp@+k@)mU{VT@C7>trnzGxv&3hHjs2|mij*ir!(pXNl#2lW&nmh+DJv|R>nB_V#Dg%Y>&+%HD zie4=J4^_bZ@ORjePDVvd-*BGggFw%Z`q#9krq{1u$IK6E44C*N!7Z;E%>Cvz z)yC+zMXA``7@&u}Q(EbmAcl6^nbdOIAPMJF|3L0^uAWZrCfR-SASFINuVTz!nMe1~ z&izm+ARvI^J%^5$Tnl8Xx-6i#{K5=rE+*cymI)Ur)2qwN?_Mix$fpdii6Velr_coD zUMe9cSJyKkEh)(*BBG6ulq{7vJ2A$+FK0UE_Lk~|2?twaM<2Voij>0F0NdJj|Gkzz zbXnlA$|!9IURZZeX59zlt$82&qr=~7_g9sNYkfRkVPF@y?JXSj(2BQlSKI>h??l|G z_CMUQE=@57TG4x)?$$@M`as=XUjR2A2Rqa32owekgn|k`E7sA`K^-VeflJ9ln%Z2g zM*(0yq@8xbwreYY{p!`M+|f=UG<$UHL=umbl!0M|qo@PBl-mb*C)$~Q15X;i!WKcG zq1@4aX&Aell{4ktJA}U|0*+I?N9g)=hODrS(`88dj(Q1dJJ){<*kV zpe#_UO?PXVUDUQGqsQ-9`C!oxy87~C$3w=}*x1RKch1i% znIfz-M_u3Okan^^*d62X6}N!~U{)f{#icmrzZa@gu#Z|AT0q_AOl-P+@_`s29QE zCB7Em?A%m>wLOrEGVhH%rHhnE=m8&3obm7LNRn+Jlq$;@xHxe@q8v1A8STqq95tG7l8v~bI1w!NIj0SB02eCz&>Z>pr< zZkc1%Bqt&?;7pHvG6z1qe}4(tjqx|lYKZ%*XA;7Y!Usi6vvzYB8x$mEF4)Z%9i}!? zY(bDcSihJMHZhaut+o&A87Xgo9=)JgHI2{N3&pu@FPq71^hH(guQrRRTR);V_1}5* zEsPb1ki?$*725G--g^rbB35lT>cb?<2Wz}afyb3x7BG1t_Le8wU#$kd();`KJ-!&G z!XW5=%$!FVJsP^O#Ea$x(UwaCHc&h_Cc@=z2(3Oty>-l8uVn;Y4y8*?*BJ8(XgW{6 zFaY=Z`+Ib9S3GV=AQ;7dpg@q^pRPccprCyOFSGh^ckbWUr6voED2UB(J)&eux-p!6 zKy;w33u?K|_6}x$Tae;4&AL04P{sLK|(s=--v8MitrPiG#+a`2$bOWm5?fvnhSS;q2tN&hmrEBEX_IS}&b01^9V)H8G zsQ_HAMV^WQ{RDLF-oauEheMVEK48z@tIgNlmTEniWdVr&f-|bpght&BLXn;1-9C?q zh*Pv=Zo)T@d7Bac<;M*NAS;mG*Bu=i_GX(RsLkMj@)3YhitlRiw@~JEuQl0<4>K`J za?=$KJBCnAv5vq3v32Uxlasa`iR6toVRhz1wT|ZIZdlE*XlaNF~19X{^AuH_Mh>e#TyQ0$%YPkO72d&q=*M4G(r5_7?RO zLvrD&EWlX|tQKx=>KoJ?yR^Fs@@Tolxa?z{-jv zI}%i(x${-j03E6Rd0~yC3+ZpO_^rY^F(&_|1hIwF3Fbz4yJ!&MB(WFTlw%Lm1c)CB zVTV)v37F}s<|jSywQ0aLhAze8KqAAC(G@doalNQvBCHoci*JZKQ*%mk7c+V~-!-!N zXafq)=~)SxA1tmf!YM{^>Zl&mNI+h>%z9S_Ugg!PF$m}<~v=0_#7tCRhAxq{cS zQb2|@-Wv4@Z#Z}1DNFdR)uJqwDwP+fOc8ElH`5giJ?B?o?8q82!MRa^+CvqQ@M30h z*fDvY>GS)v$GQB%#yqZwh=}UFMd|41Xv+<;6DLkoPlQ!@Z&5t7_4I7k1VJjvN9yhR zS{85uD7CM}&?NYzjc!pzw-1pOLyQmC}bfu_~`q$w%d7WxthuC>s**@69M2Gpx zjRE4_fEAvTk&$80SpLA%v-0qeyuUvwua+W<1K5!j_;((0ds_=uaurG`EP2iWe^wdb zU>p zWW2F|xkxVGW!~-XEY~Hd(LKf<6ph)OGFPBiGYb`brq&BTfR};95}Q|shIbIdkH=j! z0>mi0J5$fi+Svq%@hthv7w^FhJ<`TxtmzCQWNrHQ=j$8eI&N>4!zN9rJ2O2sMTJM1 zoBHNa0ub;#L<$fVz6V-|lCrXvib_a7Zco*zW~G`_jinG?W43(2bVgQ|flAiN6DJHt zWN+MPDq8s29Ch>ts^$`LPshv4OANjC^tey&X6to$NYT$;lZgK-9nSozx}3dVp5=%B$df3T|PG`I48d>DJ>21 z_c=sh2NuQ+nAgkOyLo6x5ug|dBHBPUU%l4l-QkKpYy$bKDoZWNinQW@fG7+o%Ah!- zqBvE5&dzdyL`Z+>(hWX7RSgY|%hSgX=S$T^-DVyog!^oAmI83*ullJ8+`I)y%-)s) zsOk8?bR1NbOl(1Qi(|U)=KPRF@rcWdle8jseKvT9Ax%x&Q*VK?e+Wf%O@W%_no++k zKf+gc;>KKn_0zIix`D5Z z_tqi~z;&+k#5YhmyP%)C!AFvkUoH^r5jW}Elx~KoL^-DIX?{+V1E&%w^s|6vBq>q63EeMZ{GX{ zYNJ&B+-8CkG4)5iLJquFR8V7Ut1?i06o{4Ylag@sJTc7fF`(CUgS8}rv1{-ez<$x3 z-TeOjF<3N1lM*D<#li@9$)I)Ri=l_}fUH6N<4XvZzJ6T+Fgo05tl6s=;D)wy{d|+M zg+3cp9Gi?cvhe8pO^d!OP@dNFmM%>sCORPe#VTCbf8W!~XHUp4NatR4jPqh*|+!J17;IJv}{nB(pPN>CheL`VX?; z@@5+tO#7C9aLoIMD-Xp(%PeLDP)`fo8*>W_yxF~- zvBbK=>M!HkV&H-GT#GfzgQdpP$=LoWRkGDT-UE>53?3syl~+Xqu0j~q4b^V(8$Arf&wOynZIAXdeuBO zW(uXSrLC>+?ZxW|n@>wiv%{xL(0p|K7opkhu46Xji@7ATjI|G4uXg#uFO4>GGjH;4T^dsCu9Q0e(tm?-t7?SZBbG2POJMi8N>B)AOV3XB9-bdN9O<55_uqcrP(=asn*W;3`{Cgs zEl(LefHDC3UGT&WCncua;=t*cijmfB3}H+sED>AhcVT-#sm(8|SF!ZpHoG%)BnR!Y zK0(l_cB6cEi~Z5;q5J$`YI{O^xc1iSY7ethP3~X!T0CxXfinmF-b!MXTDvt$g4d~S zmf$fe$d)@vrRMo8R_P8Hd(;kH^>cSGkKxr%vuyR}s@R8X+4A@OuPZ$5#I3k{xW`Va z@p7%7Fl};>ydI(?wYf+!EUY`s0@7vVxC5;fcZ#jDbAJEJ>vOCG)bl273D07j&Zotpa4(pkk14fVy_J`sn~3Zm*t< zNjTd&y+|RD9h(uNS@Q>xY5<3Vf21%_J$voFg*JO%k8 z@~(lj%mqM#O6Mg_0uEGUR=!T`?o6lfI&O`)cFwJ~X1|vqE>_REHPGu`;Y{0tR`g*$ z`KH-FQysPUYP~mv=GWa~0Mf!Ue!N)<*yujAn?B3{if>2;JxuRCU)SZZ{&7y#FROej|Q+Rkng&p#Oh6)F}LBDt5; z*%ZP!Faz)X#@sCr9q92C%s`S=;e#^_{9W@yrL9u#DTI-ky)s1Z@|r{e!^s+1B|9C( zIsyQ+Q^#&JvQH{tz*43xS6G;vrwvU`jZ5oVS!KaOEdX~0TUi;8&7+~oF=RM=caG+E zw5PW>HOXTX&wb2Z(ZnP<*>ha*V7Y!PaE@2s+*i01>T|rf6S1L$3c5HfX4$U6;;E=J zzzRvgRB=jf%9*uc1P?kMFrs5}H*ehhC2e(?SVAdKDCn0da!1QXDU0YwnuJAs^BO;R@}U_d@V-APA4YnJUf4jXX-=z4n+b zV88h^A}eeV7Rt%(oZ(k(Vd>IOHB)MRDu%*XtY!9>(~;W@e9H()2-t-f0EX09FU-~c z$^0M-cpD@FTkYVRMqAn>E6YUk$?u+qowRo#08i$*mRx9h^>WG0Z- zf-kO#H_g%-7C?s3)LX9$nf1TMg#%x`8v^ZMZy6iFafPuE3Bm9=ZU!YT+yW}~O z`nugw7uaF>Y73S0ZJ+?SV7%&8V2U*@S^fVW(5ygEwyO*>6HNSft{MBTygM!a+|{Lo zZ}d_P{Dn#IiAjQO2YS+ond81NoLP4`oRgDtqv7j)9&p&;onKZUB=bNt0=l#ghA6a@k1N95cn53|AmVeFFMFNK7RbJK~k(Sl(`U=(E~0ndLIuc7d*Fa z)eNT-#GS;{*g#;r6fC~%y*~37(1g>4aPTB3Pqm4EdBwe;?657gN_uqhE4 zcLR~7StW|b z91N|pR%|+|ODuzTwxUx~OfxyWq49v}aR`ASD7}W|4oF#Ojfpc{$}cb`0LqxvX)qkZ z7ZZy&69=nYU;n@dw0$VPtZ?S_%a=K@8m+Jn4gl%_tLRX2%D?t(V8I2td@&gDnGxRi z@?}uU?*Qu%bZORj#`WacD>j3_=etgK1d{dRlfUZ3$QuF5A6$??p`r>k?%a7^jwa_p z)tcR2u?TuAnF_@iR;5AG&zs`$%?%9?z@QZ|6!V(+MjI3^mkF01&8MuWC|Gld!f0;+ zCAo34X#7?#dRUK*5$PXRv4-4ubh~|0R1^;MEBn?MK7`msU03Jk;ZcUy8JKb~jcxG| zR0Q~4{sWKI%I*lvq%2^PQDS*3cO^PAdZ^s;9KYSWdsoCNWM!rXkTt^i0_$WTpcFi$ zb|3%wi4ddv)5r|_f~x)^98g9kS>MVZKEE<>>gwtu9`3!svl@jawSC1F*(GY%;8B5N z`w`^Q{Dxo##>2}Y;o$@SoREuO_)PZ*DM0D-2EP{R0wX*X}-MKk9 z(nk_2NQh}vyYg*r7oaM(RzTU(By@d|LN+&Vf>#MWyuTV#7l)Q}`S}nZML9*sCgR|8 zuraU>9v8~C4&b{`oQivboNi={fT`V}yZ`TNuCdJ52)g-t8k0{vphknhZcVC=F_}1a z{3KJ@$+A;UPEH$C61j+?saY(hprkj^7AFjQQivP_X+Bv$ZAbohArx;V3(|J~?t zt&|}bwfpk&Oyx+^yv!4+7a1L$iG%>IUd>PhPdu=15e27x00dji__HZ73N;mL2s&*}GYI>>5 z09x&Te0c?Gm`_U#&ZM@*;mZKT3xVqAX&NDTh%l1V(sWclXX{>-c`h=>WDZgf?Fm~| zAnOO)UB_T|{ma(b@cgG{W8V~iO2V3m9xq^+}hBn^FQD@=olz84XA&z^`rh< z3PF@lQ1J6|?F8V~WSRE5=}x!>Q`}VoB7P9J$G=<|+U_@WGTis~`ilS_j)>=SLtq^j zL}y5~J~`DMbR^hQGZ6a_+HbG1YPTbB68!x5be(T3Y@-t|mG}ML+L*mBT1{lbW*Pae z{Nd$esB2l@vt{I}^+9iLe~d>%LxEOK97#=Dwa3SyrLj=KP-^Z@BbCJ?UfqC=gIUii zgj_Kb8>;m`STd+P^Z>Gr*piTH!Vj0D)1e%I;im%bMA6*AuQZ=ty@l}g{ylI+o6449d9CoiKod}z>zV2%QXg{{s~u% zChLHDXKd+ekJ3e%3&+>38pTX4s46R$?tGY5R>h5~`f|WxZ)tj1xSmyo2g8rAKP+wA|Om za$fG_Xr$xf#VIW53EyLsD#RTIyOyo$GSBPE7h(WKf?yg($;!)Z@hCn?yWbY}R1PcF zAq)bOs2%ul>M3GmHhRog{>EH>l5Jf)7x<0$Q1&PC+2W9vnLA$k1-xF`7>hLpx4$_#BoF7F!UHm`ZnA zV~_Gc?3#^GV8crkmTSk~xK*d%CLicL+tA`|YG?r<$6eJ;d6SU)AvrkdDnJ@TeKM#6A`;YX{Snz)z5!JM5Gcmm`)>M&${y_t6RuVB zxGvxa;`j(Dk&*e3ntB*HK0XeyHj`4aF8*cJlYLqI`?7M6szF^-zlMKrXh2kXiCxjf zyL0!qIM*=+V8D%!GcDZO0n=*g^WeSP}sG)n)il?0?7gw?`;Z!)@T z<_0}`MiX2|+op=f6#V=t9EhIw=*J@BJ}vV}y;?_AzfPGW1IwLZ)Q;atSUT}YAS#qu z{Jo)-EzvQz%&u)ZrBe%{!)PfT@PiQ(88rVMAnF#b`7|_*w;@RK5sYtR*LJ)?&9-$Y zqj3LtH6!Ds&*AP4<5p2eOP+tpcO+5ZaE6wa1gbuEWA3OgS!S<=@@rxK{d^f;h#v-8 zD*E~PLEvr6ezs?FxY$CsY7hyn626(W|8_O~yji5*g-lu|y+vD7)=i}>h{WLZ%>1YMKo|srsc$C0xPGGF`AHLdpS*q7o`ToH zeHDc(B7Z=NZMeLB|2;3hxo1X2d7!qG*I14(`m=ark98t0#VLlUK0R&d+FnTI)`R-!;j(Tdivh-wDd0e@+s`&we?wfs=IiW+`=c=MVf0?`6wP~Q42Fc{ zD@5&e4E3`2=|q&}_`}#jHNlXNR)8S8J7Qdkko#e?`Rz;&1X}*Z7y1uAmXlwG`{GWYKAmUO zF9?HvjVrfpRj`sXNan z6A*BZzxakR<}fB)cJ~7$jj}GM=Qj0>$%*yvTa&9oWRH}#&Q=JRIr{DZOy?(WS z!#AD7q)kX}1)`^j;RaMAvsqz&PR{Bcy$(xT?q?va9HpoaN_1P!5~Ns69SbIvP@4sw z-8e&CFbsMf$Pne`jR_VLzrLz(T&=BgdI0=rQROj?Sl*on3*>~thgR4?+R#E{$kzEA zmrR+wl$?&ei3C}OxJ9QVq^0e*m(K(AeF?cE5KIy89Xxd;^Vr?p2!TD>dOLOm6G2wS zAhYrq4Ff-7*{P!`)ej&WS>i>2u?m=M&~SEch&TtL%IX@ATx0=)TU}j+rKb&GFaybS z1k$maxw1q~GMjKHgcZG;>FDcDSHQZd7+z^$xN^k?9P$jvAr6X$!ICwc*M4MVrpp01L);k=}O>^hY z9hgce9&(9*f368N%UJ5!!_0tEpoBK%=*gC7L_;9S%41B!OM(2haZZD+2DzXoo@Tk#LUG=sk<9;U$3!fbPp!SLke%Cs=kP#G3^WWpc+Cq0s`vlw^k~_K$|cK zYdPe_SY46v4*B8bvu>ju9YulN)&1%Di?-w_2#x(Sv=a~L3^Qa2a}k~lr(jJ#Q%<)9eCkv$=K9Zzdthc-mvcM-#|QLEtp7oX0-u4m$)qeyAaz zzC>2(w(B;X$hJ~@NPm`D>@G}FgbtNMp`rq&6ehMo}Ia9*#?PoL;)4`*$fR7Cxoy_xpg_D z8AgI|q>-wUUQrPa<`KHG4uVz2l9K(=$8OcRrDie{xwyWGXHRveKpFoV8>Y`HzhY@+ z6|Z`zoGD%cN??-l#6v~Je$Z#nl3_#JO1zE(dhNab8`k~oi&J!B4gkR-E?gK#509nZ zdyNDGaE^MG@LYIxc#B>`5$c4m9)>bQwIC>>wTY>*4wgCN(yB8 z`&T+sAPUV??~<^%xJd2IcEV3!&w$&h4Ou=~vN%j-z`FFr`34SLRbD%3s8j$6rRyZA zMVMHLH+Fn~pIOlSC0K6SIE#L$6!cnJ?dqahfLcKNE6ci@=ju8=YFm7eo1F|UTEI|Q zCn8|NaEnn=QOo)QdEn_wR|x0&@1b!&%FmzwaasDQiJL}47;)O8Pi6qJtZn?A&CUIY z_*I!CiLftF3eEPm#saJdFEcY^<&H!OuDm+ax<0F`b0ykN(chmayW8YxS1{FXs8@6O zH4IqoIn57t2a?aSNIX)F|1|+k1_{IL)yrs}0MUFEL|^;4U|jqY1JPRJ()GRFR)J~q zEz%dL#OoklYwImS?io@o%#PNx!+7gXM^=f)du4w@HQ?55|I*&BdN1(Gk)u>=%(>@~ zw7V?rKC~+RJI(hiFywh#rW|%Vl2EChFKLb!Us_XYooM*>jS3)C&_SGuOV+YQq#g}% zzbtSEo6Yb3>`J{?y+rikx$3|decY&GQ5>qLwjR-@`>r3v5d+CXQ5wFWIUyE54{vx_ zSU>2N`W)gbrjXq#eVf$O^ssilCpeG{%WZ^TZqcyJ#!RA72Mh|w+KtN(zJo^O|tbm(|QK(2Hg$McC`!I!OMTXQL zQhXuBR*-SE@xa+>wt5-dd%ftKn*CL-Ks0Q8{HWJ7n*Ner@(aJE(OU1F$yi8;*~sk8 z3xiODGD`wxh6Pk-h{R^O! zF_!x+f8L`vNAkj2>M~{|qJ0pg+ClELFUKKCkrBb{o``ASB1j6gdaghkBIfrGARXpT zkgu>K4c}Zb6N+0;Il5)zu5AY+Fu-H=>kq=1M28nA)$D^Ig%4V>bMPAT(f*ox^^d?g zo`rmC<;j1Bt!AY*dewt@uGT06Zh0 zzGI13=p#q7qfBJO0ia_9j6a-QR!FuHj+fKZ-BUIXY9m36!kg}F=dJ0p1NEY$r zIhG8F2;`a7)4&87m#nM_!DES=SyaMdaM^{7Sr~3F%FqEoQBX}ijRb80v1)*7E9N+2 zqsNBlbc6f_xKKCAo6yGWK-hweubT)m9EOJsDia|hIyt!j)J>gO6Dg(C)Knw_ad>bZ zx)QG8YddDZ*t+7%V%0Po81E{jXaJ6oFU9s@bp5WY2T-$gd31Pn{fRr0oU!}|4-h{a z)@2?Ds;et28gNg@d=?C$)<>j;ebuy`Szdk`%7l5#Bx3W(G5&=zf0Z_r^e01zU}gtH z3}qk%U&uso8A8aQd*z|Y?#L%W;Q-&<4N|EKV|8OiTA!@6f0UfCraVf2KU&!-6 z*yXu;^*&%kWat6{hDfG^L*d-O%v$AI2LU2u;t6PJuT>EC~kfT4ob)m3Ep2vFsf z7>?RMU~#k;@%{DJomgWrMX*IR!8}LS1E{TWe8P@AVD2CT2Fc#kW~BjGSh*+Zh?T>Q z`Sz4*jJQKElrk765;gncDQbHmAI6n%`lY+*WKqWej_nUjR2@2PMD?tC$G}J=DK$L;&aIRe?t% zlckqxTIW|yYP}g9qd?rWFHA~>8DyB7h(Y2ru>Y|8ezqf(D@dJ+PIMrq^*~@CCz?kW z0)D9wH9}Z6P^Hv{D&0B+0@r;{guuWv=uVG+eMJ!KT*5d zqD&pB3Wg*`F2q>8e0-1?Aq*!C*LX!WEHOgZBM>E-XTLe0unv=NACk1Zpm0K;Y!z`H zzmF(UNQ@UkC(%(B{*EgUSOil+_NdZ=bPW`B#I5z-Hd`ZgKxf8+`(g|45E%{zpCu^h zH1aAcDZ{$RxD_B;2&#@T-SR8~`~OeK_d?~fh55X1;-Puz{z%!a2>X#4xhlVTbG>#0M$2WllX*;=&(~V8el^uP;;W2?h)*et_~2 zCP>|SRmJT`YdYJ@6M$BX){@P4n&aOkCtIy7iFlQuEhV8gKKU>Yy|)6?p+3-C6E(4Vgh#|`=~z@jjN_4c-BEWgj=&G`@80UgYWuTWQ82lYsT`{#pckEN z4P#Zk0PUVsszJVP$UaUK>g){|#|mbR?oe+_;PLSURx%5rL7|$z+#y9?e@+#X3xf2hrjTf@%`qS8N8B~eYb}rU#ja|l`kO)HjaHy$g z;116mYjpEmhK%DG{rEVeN*Q^g0 zS}O5nRO2k8(0zzM1hT%naPgu@fPcf!*xI^aW1E^<7?oCFx9?zS=COsC8iHB`LKLyQ;l!Qfl9g>i~le+#icTi06-(K*NkkP3{arlZ>-JeGKTPzRth z1d3m8e1AcArJxk117N&2`-@BZIbx9sgooOvF|c5Mh{a?@NCvP&>iZI-Es>Xa4KfMp zq3z7`v$MI^lRfW30T(0}UlkNg?dgR1N|?r2tQ*^wF-{3b4ItAyV77O)L{BY^K@^$n z8{Uuz^P;wkBhu?r2~O~}UTaq9QKJ=!auWjFDv$P34%L@}fPTcDY-BG-i^Je=aI_iB zA~&xDP=2AYGlF614M4euM%nPVAkptZ`uKdM#uMedRC~lPez%vYV(d@=i2LUP=MNAW z`*mZcyEh9B<^7S_eM=1DF5~S`#SZD$a0d7ui*Omo0f~&Bx`DpjZMn>EwLQAo=DbUsDK!MS|eft?} zTFLy|>&bl|1gBcjy1MWu#!BZa9EMt^4n%CeXM=QDuvv_?hZq#V8deNzU@9a??n6V) z8{Vseyvf4qXx*dzy|FFCqjw#QoR0w_Is5q(`+JzZRV730--1Nkq5k-h$|!85XVeJU zNq7vnerNtmva+&)9NwXo)zy$;H_1zV!_NYVuYMqn_Ih!-1?|axQ3bW-yYzwlwQld( zyqjFOC=dy1oLW)^$f6uQ&Im(US*nCDS!nS7`DZ!>`$8b~Z9HJ=MC6XCJv)qE4%*r)i6SyF`ex5d1?%c6149Ry*&N9`1L>k{4`}hnG$fQ!7n+A zGxRudDk0@{EoUWxF!%fvTRwi`7>!-0+!{X@&HnNA`Jq<+<|1VQ*33@16em*q0EC9@ zSH>HtV|4-ea33AeKGyfw1Pqdvi7-B4zhD(nT3QNl4~@6CzQypp3Yl#Jb?ZLFzuZGP zAgKq#2XXMmZAiO_MpWZv+V?OLIGJMSt+o7QuPI6F6h&wpW{@<}^HNwMm8LC3gd9h< zT_%%oqEO1~%O_hG#0M%Pm>oYLS7d6z(IntjYDKY$y^0K}<2_e8#l{9DO<@RG~8F5xuz8Ej2Y%fLGXkk$tfAS*isj+Fiup^Vqg(sS9B@_y!{o$-#acOx zLG6iiLk*kU$k3*rCZ(E4*MMWL>(xD4#NR@dLLjf6`o_wU%GE%8jgyE=-~z| zekw2^yw@L}svz(v>bw2hzuC&#gG~aH(32e0o_$ZoTR2mM1Mf%~&XRzMxBUxKn<=HE z4`KTu>Xcnd{r~DL-~&5F!>}pfSsO^aB1;F@tRpG03Hmz|2m=L`<4OswM&jsU6*y8O z6=3cR%<1()EMJTl?GG3F8EobcyX%5-rU-sOCPE=HgGDC(hA`D`vuTEoRjL+^{cSUf z9LWAdBxNX?|F%oR#R7<)#0y#Gf%C=T7Kv?dUUK=^s-xsm? zCRzQ=iOxs{IA2P5^Hy?lGub%na*rhqsT~Q(l zra!q~1 zL8(AMgM1iEE{sz%h2pY+y3K;d-}RnL3qd?EBXW!Pe00sT!C?BHXT-&k+HS`u!hX{BXg~+GTwdTUO%R$vLKkC zvn#u?yxav{5R1eDAgy{AP!|$5S5qq=S`Cv&`d;((6e`fLeyCMwcQ#pYkyVqVRH6Mu zgFJSQT}+PM!5Ai5J^IW&8n*;NH&c9D_{i!QR%u$2$zOJ<1BC!Qa>c>ms4U zc%Wg(^qB#SM8U`~pJOkK`Wr*2MK#4AQ_GJZgbXz#!+4Mx9niFXK{Q_wQA((LN{ENQ zxqt;M)bsr_0~Wvn{*U4ftB#sG$nY%CKu0~LI`tG;1f&zxcrN_$$G>yJUtXPQD>rq1 zg-%yv{S0SgyhE@i_zg(pmwwn7m`eA97nm)|Ru0UKVg4|qFiE@TgG-n$cf`y08e&xL zz_?J=#;|Z9Nq-YKVD7gI_oA+wWU@BfzC3nW;jlQ){asg zI_fzg3QxZ5E&=K%LN;Mxn}VuZyyKNvS7@E=r32Bb0kEiW6OG|0y+#rVg(TLH3%z?c z-VVliNm874o#PF1JaGI0Tw-@W&X67k$&mnbg|oZ64x%Jrs3Kq+3{lUq#bmv!+8nmW zh3!Nt^Me+Ad;=1e2yTUQQZj}%KtjF5#FS^-ThLWztE-*6=8FhgF7EFAa570AfPLg# z9yp034ir<3S$D|641k`DSp7&;r6KGoj05C?oBjwH_(dkYUcP*Jdd}0!3!w$bOwi=g z*drL1Dc<$^`SXcxW&co**%rY5ZkQKGW|2?Rjb#rG>S2{~Dqt`ld0fDOO>yUTpjaeC zy;Xcp^PQaofG!->0n45Q+CelNO9DZ97+`OKoHnF+NyQeY@Mv;}qZ|z=F2H~?!8ziV zk*VcfS(ux{f<=P0Xgp^(Toy;#3l0q>fkX!f7}x^%%K?5s?Mh9TaxZh#c2x!687AbV zF{?j+hujc14Dy5Mq*dqdH#w!VVKP__=S}p$F2>XG!tONYsG+Lg1_@2Cc zAdDYE5d!y{mXFsSVV+@w;?94i3YEav+sa9qA|K`2aLKMsT}E$AEn zJ}U%tC(a4Xf3DDp4EgN zNUCz3W?K4SeicXtr0um;RLWq`?B|l{t}JwLQ=Ca>9tVW}VaDSINE*m74;>vb$Qc)Y ze#j_4aF(I<9SbMK82tC}hAeK5^s*PPfW!Xt&p($gU)~HSa%N>`^9TuP=H_xCb2e61 zvm0$N;R28c&eNy@p2Gv@X<%6MNXUU15YXWU-VNHOUC&iL;IF9Gm~z#7<~W#SjZ31F zgf;|g7hAe?T(lkT7CsiF8C@_+zzv~i8M!axyc})K=(fs`nPyc3v9Hv0d%xedK>eBi11uzE( zU6)Hj;yxg8jfroft`r%_Q~eG3a~MfSC>s1P(7iD^_E$n+Ze|9~aguT#e~BFO1Lv^7 zpS({}Z%?Rr1OOzjZx$JP>H$UG$jl2gw{@6T(%li?gYSY=iQu*C*Li^A{pWlPjnMb+ zk>syET<36|++FyorK#zL2dxuGbifk|A)u$@bp$6^Ajc5F$yqSUtAX5QnXMKChzdu1 zypXxq?TPR>N@Jp=Yb%OkSZak|tUDr>G$MO44`rXnVgV@)Xfbnrxt`aqr)WTnfGsl# zQ$Uckg07|sCpZ)q+e<^T@$P?47JTNN1}B<8piR@kq2atEa&pVz!O~uv!wH(ot`X-( zBlO_1b(JN&L}X+I-msy9#<3#{<&r&^P3VE+OIp}WJt!L+F7a$IhW#-_^50X~Ha-EM zK)A&RRW|~h&;_*<^9Mc6Cmm}nCdmnS$3wUJABa!^LA=Qr(i9wa^K3W#zvm*Jvw_lt z9Kv%gI%cg*#AzPd`&^lu92^P+2amwii?O4=jZKbKdv&qnFTdpd1?m83LdHWD&`%&R zSBRXX)hGVnGZ&xUhRH4^HMIga836$S3YZx9KhD#9VnevtVlha#0H(d54)kfvRj^eCQ`|IHvK|DW?1AJHK* zKK~zk?;X`-y7mh*<5sr~w&U24GNTmfDgx52AR-`Lq=`sxLV(a=bkwmxl-{Evy#(n! zDk3F7=m7#m1QJ>(p#%t!?|S0w_d92ub^iU%_nx)0)(rCSB)OlvT=jSTE_JBXhw$MI z%cnnc6@G&3sxj$zxa-3HzbPGic7SR}f@2U81S|759jw|FsA|rdDdc=r)>&PVsAeP5 zr5|6+`TyO0)c>$U!c6?1A@%zY`6jXn|3fp%Ig0tsr;veP$dEJ&SGnYuz$yTb*=JzF5a_SQsRPyYca{bKHu2)nQ(p^ad8@A5ltzQ2t8uKxM`yRPwV zQ7}PyRMuVr2G(l#L72xk@~;t& zSNtX2I>apFkf>g)xd222ff2yYzw6l{_zbI42tn}z&%%nSwc~JA=|pV!an&1#L|#S} z7o+&EK~Xc85fZ3|EN*rwK3}4IvrFIhJc^p9^c-P$F8xC}34W|t81=l~`)uynp|9Zj z?-8o{iHqyo0;C0zJgQFenYtl{4?bTXZu@4QmPH6q8$bh4S@5%GJWPG{P_*_yi1=EAWXyqld)JF0J}&w zSCMbm;;j1ghq2Da7S%a&rXK$_m}{<{2mpP@1@Z-N#(zqL-yeAYec#&Jnis~r)ZI+; zHC*N@P4me$nGk4f#O9=3hu?2?bC{ZYY!@?IDE<4~yWU5fgvsG@)_m|_eZGc<=7K4{ zxOEA!!QKdH>*$EF@PKoHZ8m*|7w&sQg$)T{kK9?$7DdW4c}@b@4I4e6V1dK_zH<dCgPq$SKa<7u`4q5%&2vs4-Itx^P2Z6Ep4I@4<3#t@K`aHmyK@S z0x@+!9{^=N>DmbOUXM>x))j~)J&oNgDw$nO!)%%Y34-w;$xu%{H#)j!F9BEW`vf8& zcPlKtyq>3qP!)^as7j`sFTF+n!FGP}fYQH?XCnyg$xdK6Ln@O1!{dpceiG`CxqpzwgHUzMdfs+)cLUAgw5R87*f~JV|j)%Ad8Pb9wm%_tI8{8baQBXJEY2nx&q{mj|Nsd(`1YT0-ngb zZ)(r5*NR2zzwFE@%)0)1H&2Wz)XpV=w4ULJMlLRCiyuDIM_pjUEU~G#wkPwhZA^~@ z&Y1uMWkc{9iv=8Edyw&fQ<-y^*q2XUrlZx3ZmYQu9n(3c-u}G|;$nMwFdd(+JUt9v z`^%R%p*pK+cvz2xCX#|$$Ue40`|Gl((2~gx(5=gXa_>$ZKC4N9xn+YU6 z;NUkmlFgwUbT7BlyCZGpKr~SX#KPGS>5^1KoAaxA-v(FD4pV=b-=l8s^ShJu;bPO> z+*ifbe!rBR?SycDHs6nY`m`GO-4Oauh#%!Z@B-pQwZ@143EARO_)dPspsQy^b%C{1 z8(d7r!UI#pTZdTXW8e9V!orRl%KzMi1p#P-q0PDvsl5XNZwO^WTd0S=pWmO6QHIem zF~SIAlvR+`$cUBQ42?SB#GF%A@>_TX;Ew3jRQ*-v(!ztd9}$?I8Z+5a=iwVb)+|x3 ziY)z`fWKEh1%N50l~*S!GxYF9U00cvymEVsOmEARYXdPMW>p9u>ES^y)C-84Wp+EX zJJJe85R^Q8*vANJZ%XZEy#i?3hYs-f^t{~BozZk(Vk5FiX6pNG|+fM zLQ(BK&|aB}$s-eW(ZA<1=Ljkfg#Okw%K%t9FtVn_re!B$L+-p=w+^zC?{w33zLQ98 zV;kg}nDPmmCsb4z2F%cz;zCu#qlZucPG!}$vC5x7v3Vx8P4=d@Iq=2RzGhPIJ?m%V zFF;YrX#fON3#5q%3kglvW7Oo4TkhX#cmq(gC2DB);}=Jgbi9+I;^VU*Sb7_ZC5sg! z(i$UXx`}GI^PRzfe-2)3Fn#jO{S*X&;2_C2B6b+pnZM&A{g>=bVqvcA%JOs4QeDW? zy)G+_*b_M=bYKDR0)YUi3Kf;l)AvV#R_52kJ|*IB&4B)Uly|_xIQfF7!PL}o*zun) z&z#{U=UWwn%`WN`dm!A}LQ{0~ zNN!;r)_O-;;Mt zq%fizRifc{^=jp@%hk$#LBmul?a)y511FS>e%HA&J~jFlfWQz=l=%JZB~VtT7DHn7 zOCskOZy+di$EFhYKM0Y-M~;Yxs;k@Gw-;AYxeOU-iEGC{1?8x*;eiEpS zkje?LY=JZ60Kh$JdK>9|r7r*wbwp7)?ufw5P-PU54lhF<+~l?b^~*EFOm%khqyRez zq?J+{d|JaL1<$;}7bJL=j>6%c#7Rz~%JM28}^Zqu|w~TCOJMjGXhYMm7+6`!k`m4TZP^ zQ>HP(RmAD;>bQXw021eql$W;aIHtxVCtKL`Y#G^i2aa`6+&zUvMQ4nHf(FJq zZZ-1uN+pC!MMXwRx{pD+;P)%LpqR{lBG%#leQ}YD?~_w->`bnEVorcNTSCPTx$La+FMUwg3Axagwl+w^SiI~7 z*ob*PD>%5)4kYu++9AE%;Oery+Q0&C+pjvjxmsgi_i}SX3N>89+v@@eNIY62Qq{aC3)|+K(=_w3 zQME|21Zo!=d;o#~upe2_&N1fOqncPCAu@3u$s154mOcaM_I-Ipj!4K-``akmT~}B4 z#0_!_k%=U$Gx9ChiG}1kDCy{uJ(qXGSHY#Pr?72!IRA1{H5f;Oiz&E3raQnn{U3j^ z1MuPM+`hPWtq~|5LK;=<-A6CD^k~-|Ni(v;$Gw*?IObb!im>vrkv)JwOQx@PIov8Jx4}S}!AstYhJ$HyW3oq$v>f zLM$C6WA5UfC(rWb_ARZR)BQ_Xxw>D1?*&*=J}kHLJISUSlAzTAMV5c3R)dINcqh-U zZIC_-_zdys3^l6eG!@-xzOzgHO43 znc<=oOubp@8;BPzM&$+SZLFJ_-m7sS3M8Jjt%AoDSBJO;%o>TdRM%k+HEnr$lDQE- zEL^@H9$w+2U9co+p3K={b3$kTSMul0FUB_Xf4Yh~j2&z&HCq{=Q1s9gpQm$`EL{+h zS9Ow}7%6R(6&7BHwiF$+HC<&$0=JSRDJfYp$Wn>xJk4tPrKPfxN(O50R*~xTu6}IL zcYVviw*8<~>vP6E0aK~Q1~EnY*p)nBtZ(2t9N5*?w(+yyBN^WJnb-geQ>(MakPnK% zVD!?-S2Y_a$sVDF8^@4|<|6$2?040gn}T>UzMcB&RTe_n0*~$UFXIW`HMuj@HCLXl zCSI_qX=4=|rEXq^!Zl?`1?d`0Wzl3EB4d&x^WJ~ye%_C_hPDV|<#nL6p@bk8K$g8q z?rVy|t+lnauvMy^>GMIC{`f;FVEOjriOeWn^C4+5vF2F@aHAhl-r?ux2Ta{Rfx#Ol zBnGxmCNWtb+?4P4#!7&iEj=SWhD?P-3%|O6w_y1BwV zvI$^ekaBoP?uciXY;GmUHY=g1FA-JM=SGe}jbt&lfZAPHxVOM=0a>?iSWd)tpG zApIrV0DixH`}SM6PY! z*QfKh+){wzTdKg}Tml4CJh^8cK77u9!qrn~I*ZXRCMw`e`-K|WQ>uNmcn=+ty<2tL zJjG-_)qtCUtMM{;!NJ<3feA=pc8}Duj2x*xN~Ui=x%kexOwnkWVDy{ZrWpm*#LBQs zyA0M5?OEbfY!xz5x|jdgSsN%WwM*G4d6u+zEpqSv*uO;$aE&03owj)B>s0@TF(u!c zdk>``!V0jCKfu0x(=j*Po8@`R->*VKR9Vv@GRo)tbUe3!l97{FrN~QuWsPd)Z2p-@ z=wkxthsi?3NP5NLfy)Md$^k{i8-M9_03Vpoa{q^-cp2XFg?+Yh?>~ld0Sl!}Ie>|; zF5%a196i8$+S-~@Gy#g%Bg0K87K*hdC{Povq79Lp?U%Em5R>GlU$KC*f*qKx?e0VTc+Oi;iGQMlQ zbZaX*E)EA+hnabNdA!c}u75<&5t3nz@00~S27?K-mom@|UWSpp#$hl+L&M1ZfU}zd zveSg&5xmVh$!oLX13-)PB=X8v%Y6oG9WW41c=I)!x4HZe++N1M=!BT`wY7gBwS-Da z8J`0OQdb{qPL})N2?T;6zq0o&z+Xc*B3pm|z-B1PsZ^|lZ0~#d?UlFzdM>MuBTA!B z{%GgsJ5HU>F?UaZ!{SeQaDVmnDSaicFN}ZA5B9;td=2MMivi!k5os!rD2MO8WYp)< zUFP%nez_3;g@0x5pv8>U%?%z0K+Z*u-pSN$fIRJUR^j{VPp2JRu3hCj%?bs3bbMmU zEPv~Gr7J@S*6}v@Hirih89x#{8Z(Cw!*}DV-gQNO0~Z#$@!T#@3A6*<(_5-d^CAFA ze9j*`He6=P=!g5%Q6gp%CV3?RY&l^C1wGd1QzbGg?-(&`ECz!CX!(fBJhI`!43K(S zcquQftn}_+QgZ8p14urn<&Ud}2kE04~V%Rv10P23~&oV-bP zcD5bn%9U#JDam3m<-7@PNM{MlbUMTJhxM0R##WIk$vVzbkM_crXU98JpxUxu5Ei^>YdLF zNNGX-yE{~%Mh}W*i?eMn7TfFiH1f00C1bYpKtvA?jeZ2H%TOAB6YwMQ#DDU;=oo zeCWvZCd7Xufrhvht82wXd~~kFSO|RH^of>ujwruH_l;ah&hqi%Au^_dp|h{;Oj&+40(yOHqjcw-2EC=4|=_umfQgmhO^lcc%H zt>3O`HiE*{Q1+ecN)8;X1H*c~z$k4)C47IOjeGA=Nh_8~)EAXt=y6ik*7PR{Kp*5WANQ zM0+y;XEoK($N<#YdAI2aq}$Qnz57ah2=a)9_%6*BL3Pbov#av&5J{b18X7=~8G~k- z?y5Aje9GAeS-XD(V!8IOuldcyn!6h$_2okuyr>pL#&X0(t5u<+%yFxPR#-EuT9Zg5 zJu)1$G+Q+8Pm)gQoi0#b{`>+5kz_-4ne}T-3fkjwFdt$vyxuLW1zFkd{LBz0u zvW=+}G{qF^{{ZueBS|i_{Uim5<~>VN*;gXoyShbM8o(m;0(f&mT?K zeP#xGQ)TLRN~yf_HbQ6W@=wgoSv4Z*LXccLXjL3Xp6kIVlF7job`)J@K6Zux9uf=} z(n&r4;qz%v0FeQa;&m;9o2`3NRF0e52tu9X2Bj+QWnRY!7;A{$jVxK8m$F-m#Tr8{ z1%PtbBdgH!Ceoe3ed%#8B~KjOCRry*l#m<_j;1%y6?V+|@Ik&7V%c?fe}?)>@`EiBHZdpiLB$u`2}PLsNMRuW{apnnf|#mIt;hn%JVB4LOoa9%B1IYL zi3Cwgr1uBJsI2BH-3B+ySLypqFJFEKC43N=$(MJ#3)*W9P12{mV+66Edy-Y9Q9!$a+o$(Tomj&P-Oi0@wFS*ZyM#s zN*y4Tz6Zn~lnT5B^g3_Bp`+*<*pSsqcqD=pG&nJWc-rUsQ-~I}l(nr&PLVhgs_Z*k zp|&|0RiwXU;PgG9vE6d8+5>A(xj@Lded^>Y;r_Yo6~&1K;cW0Bute77(b0nweKOM0 zCO|3Lo~+gPw*D#T@cX_coV3L^Z1|6*e$!XOn4Wo#(SsoI2PAm&?iy+ZOrK9j59Ba{ zM!@Q^Ywm}*%MsFny?c#d%Y*F{XPz1#ZM4ePxb&3;1u#fC4v65$_5lq84ge6Qj<@lF zt~t<21NTL)3CBc?R-{rl-*rrIrlM?$8gYqB$~=fjoVU{(Ua z)DnugNE_P1z4rp`Z5Y^Dgu}xheRVFl9UAyWY}+>QkGQ~NJipj zMvJYgvNdx(tqLk-OkyVmycX|5u+bV4QC>biNOkQ!+p%8-1Z+qV2a!D=w(-dN1?L}k zP`>{t6M|2lfgC49BjV*<*R;!rRLlX`S?rGm7r>6~@omP%bGVpJb3dguV8#xdb+Hjd zh)x&`19*;6HK@rzdZqDQdBmoxD~mSXtBHM|nK=VQUmYF4AB~ezRu-%flDe}Q1xMvq zC?MQDhu1^WPHtfTC7zo&C+FUE8zMfpz?>$*8weB%-ZjNImvkDeRgk7tTV>`gZI?!h z9e5zRYl5rUr~+v!`85G>6u_l&J?DZo^N$^`Bi{?yyiHWwYVmRdR4`(!LA63&uom)| zTXuY{o5tih^utx$m&Oqm7iNY1?qr(IK ze4GQ2axXL*X&(qB9hoN_+Io7#;$0niEnGG2_9oU^q7>A;zzWh64 z>gtqP1ZZ83XxK?rL5bs#Ep z%SK;6oyE~Z-z5Jw8KP3KC+{-ln5S{*pR2B?Tsf%zJnP9yTn zg|w@|uc8)&RnK;LnwoTukd3*Y?n~p8OpC~elC4r9zPb#sj8!+A#!Tok5)!$yY)B{C zv3a=N?^T3@R|Gr-gkQ#J5|GQ?X3H3dYzGZTp7;9l0HWBIU|&F?&wR<VJ}(RfT5U{k#zf*oF%`&T>74A zh}Q-HXNN0gJNX~zOTtUfkN$eB{Hf+u(4@Zfd-0nd9dG_9sJWMzp_B3sG{`kUOdmud zp2J>+xckNwO&HvtPC$*jhH$)!u#Iqcj+PHoihG@4wi*gJ=%g}8l8Ps>6h)|ijs|2q zIYCM$P6%Qx?<~x(UoQl~#ts!c`-JsZ#I`kgoppifS@QTo`&>O_b$|c#>B)?-=B>1@ zUub4f{EHTN^&aY!irAteBF78jQd4a%op4ff`%%g?S*t@RdVZj+XH6Tb zOP0P};Stt)!mV1$Q&w;avd&aK{2aSk9z3#!ayl|( zaXobvC&q=$cWgtUoPttjNr@!1jbqy56n&=qZiTMtYo;4!W;o2?EGoS+ee%s%M7t?v z^vKdy8`v=y&JPsB8463eQ+MxLPT9UZV3w?)&j@SBzAwr1CVK*t74Iy**1m0UbFxvr zO-nQ-{%jhiJ**1?C_TIBp8VpfY9PfjwOW5J;^MbDK=T?Cbk~in zq33(FL(iJNH+Yvg=}KtPhXRr}sJu>CZ}TW1f(;)lpjze79GPA@7NKl-=T0nmJLA)& zx{T(=W3u+%Utg*zbvv}SsxpU?rloonx0buR3M{qkTa#lTM}2B#Wn~KL;HB%|4yK=-T~ZM&_02$=0O)`btG7*PM6Hdo_eWcMuG>Kr z?jDpKFZDVP(H-|Na0-uZh9%f&5x`uC{_|7 z&JR_h)E53=Qjg--jBjWYyvD*6jKnC23We1t36;^|y z+IOTTUg)^8uLH}60j)^bQTKuMqAen@Th62D ztgQy^nJBj9dxN$C0KT9O$!@&qVCBNYrE?FyeN5>iXB##KF|5^6kvS$}PGEufHM6Wt z9;iZE`#&^}zuPBsJ&tZ)pkUYZ?bG@uO)cuFK!}iGX5A~O2g-!}B9v1S#6+>t#Y8n1 z3@}X`f(t~NI@1HT%w-Xs)JR~6cIeJvAoXx?CZ^Qiglg;;Og*G~K{`08Ut%jOEu!_P z8hb!x;Unc-@Yh!4uxrP)D^6#nc_BL-Vyx>+SPvKPk$v3`?;*tSlwbZg$i%sq)$xQ* zK1xt@F`)vjoN=xxNQ3jn#!20fLfU_lla>$)s`zP_;AE2E}t8QHTNDLyb&?A+K^ED{u8ZX4| znvHQG#svW@xvOiuZR?{vb=Br$kYYfjBDJJjcQ~zarZ?ANWRvRRJCp3xT{cI8ChN9n zrGij)$Q0DSwNqY@09zXthm)@sK)}8EnK?P)GIbSaz$_sgHa%aPsjwT9n3&iae^$1+ zojC*hAgtET9vS=YQbiOk9o8n!!b>0g*}lPv!hK-iw3Tl&Pvl!70A`sT91+g#Y>QE~ zFOQo;u5ky){)nuDfBWs992@{#J$>QF)z$vcEgIW}{tI05OE`xJNaPjv@YKI+e*UL7 zaXucoVQ)m?e}h}Yt^k5e|It`gRh3B&pxe3gss;ylHM$M1$)4u=__m47fNT0-$U(Q1 z5npI$7i*FSbH<%4)!R$11IOkF)K>Am+mr!nr+-1Lquk9J5{jz6WNQ+Xgmi;ipAt(`KFxGkf8TNxntzH@`;qp&eWgCjW(e=x5)} z`jM`5?Z0n`l{WAD<`)K&`t22R`Y-%>Kyhv9C?4jYDA9)eBa52=A_entDb~SC~g#7*0Sw%9CSiL|o#4=0nUE|`K)q~{= zyK)-}b5T%L=b>Bx(u^NHH1PZ|unupd8u`%~b#)=+MbAclth8lS+5hmSq4lE{{onjP zf6+=fV{=c!7%V1MC!}oZ#@LU4;<`|R>@99jsJ*?Xt1>md%MD*W`c;LwSz(fc z3@IOIA=DIx9@suAi_%pRMsAZZ1~TkFZW-aXs??ywC$bM`jg<*mEY8l$a_k6!R@LJ% zrdF>ZXIExm2UAOf1;7Sw2Y94XMm5?24Kp!AS)(jZjIP=n!fiZuDc{)&X=|Q+IllZNh&JyrVhLwZ9~Y4Hilg@ zics}+l`#G%4DBQ=gx~Q51rPT+R*FY@O^{*K7O?G1!9bv^Knjd3-S#Orw2*W&@DAIz zlPgRpThH0q*}%*=2D1EiZHc8wu_!9EYj&todwZoD+l)|&e|-EiR|oH(!*E<>Av4w_ zxc%Tt#?928!E{i8YN(+_(eZqbTKOHj_B+xIVDnt$+-lfu9Up7X-fV2eD&R`BVfU%} zj_Yeq9Khj4Y@vrKa_Jk_A=p|qt-!~m6eXhD3M@@Uev98-hbrEdYX8g?W)HEkQ=m4Q z_lPD(AJS7213BtMkL2QVJ#P09!$#2S%$N_@4rc21S4v(G{=^Ba-N zGb9;Y;Fesz#led<;!b3FVQ4P_TOZ1yJ;2SR3=03m_288wc@P}Z2M?S;$U;y#8SpdZ zzG7TE=_B}&TKWta3KK77+g%%+L5_Uu=*}qJhe#B7g$;8QAM(%t&Qb>%|9=+=`Jb`= zX9oV;%z&GDH8R%IM!BZAmRYl615;~KmPdC+(JpJ~1dUCO#E(ji`OA6fj z;Iw!S^!D?ha|*9IT9XtMthZW1?L0#Bp>=Lc+%_e2A}j65d|C_K{B7dXIV$`t+zqUI zRisPk$Q}~O0Wb=zH^|%l{11Y3g|h8qXYY-xRrfW$X3gD!>kD4LBeqhQ>KTZc2LIxR z;ZqdX6jZerGy;o*OGbucGxhHP#ok9w>?n?Ubf8F!L{+<0_ zuk5h>$`=J>0d%iqGtNLfI7Z@KLFnPq;$qFJvWy6XaVz8^_TK7GKfdZz8v1N?;CPe% zan*pjd;(h&7TI(r{F8TZSKIwyCn>he1ENm+a{AHfDIP!*om`1k{dC-N=9 z&@05QO!g?og{z(QP+A$X@Lpa7{tRbC!*XjOw%6AEuJ7yX82nItBlV^WqTRzxytbQc zmnKLxs*OAXeTWUf=Y>oX>ozn2s9X8yw!UG_?th2yn~I4^>z*i91?70Rr(uwc=8Ae>k!APMr|M3?c_4V&xULchG82Qff9*pb>D} zPX)h%zW(v?b>58!))(v13XU#@M$x2HFOw1UCy8?vrWBJLs8PCbD>lzOWk#S<2K_Qn z+(&tHeP!%ut&+8W8`(Vj92lW5z-Ut?BaUhh*;sXJJ5Rm(#59I zWZ$6zH*ydyU+_A`ec1eiI81Ws3cXL25;DUwG#K(VC+EdzqlnQovTCm|Q}ysL)BO zSu8=B<9-9F^9I#6MN6+}Q)lzBzP)TVvn=~?7|#CbAY{kXF1K!)W#{LTeS^L(bWRPI znoF2~SmARGK+|JopI}COEeuVQ9FDfSH#`TM1IziMHp|kyPm5yp8YKq8Z~{Kfj`N3@ z_AjC#$?1#vamUCgk5T=`AaaTvU2jvi4@5ZNECz4Hz(;dT)4-{QQi&6MJoIi{j5q{n zxa~EUosRk9D}0S5jDP<3^rb&P2gnkN%hf96oTRvWDp5F_5KN1GXdHrAFhyHk& z|4)795;r;`6z^&_29I6|AKbM%8N*Uzu9##|zkM%-sSeBMh+ko+?}**bw?s5)O&%u_%jH{- zTC$%=!LRuq!C4L?vJb>{BIm<=yQ_5U)~S}|CBDbu@!uEg@097WIfIsHcA|^tm1Dvhdg2^a>ltXMp{``QQx0>qTr~^ocwTH z)$zL83d{ODueGT)){GE4p7+|8+vpkc<-VLb*_i`jCQN&BVkYe-@%^=>;tW??c@v}e z?<+2-D*3c`sBNLT4%VaAJu}Dus@p>Q*B0fp+_bu&-W@01Iut`dglL}l@GH3Lnw_ny zwJueOI?_f=p3pA7yYf6w z(h@6Ym!6$75((iBZ&%Xq!^%D_ueZ1f{hu_)TMp?GUX8F;*GYZ7cB{{Y6KWoWQ1dKe zkDB6IbHZne3u+{ddwa9>f|bf=UJ0ZqIjn_UQrup!@t@d}ndwnJr(8P+`oXJ#9g?lj z0?9J2Ah_lod4Kbv;yPh1Q#RyNa-K99!jR8Fy-^y&0Sxh^8cm^mO`9Jj=AZMO3TKqgTiTW$BYY3eb2{BZ{eqQcx&0g;t4sH2dn#;RlOzL|Na!Zn2 zD6L0Kd5u-|Lrbf!z7HDBQOGonD`>M?s>iR}WJp?dxQ4n7#~K-XG!N>e``b)?9$MXu znj)75Zc}Y=_N+a0R@ zV@@>Ia zOg(S zLN6tT^by;VVvr%)Kbqt3?dhXtWC}J{hpy9I^Be{JNhv@sesFa#WqH4I;nG zHw+k9rpP7Tkab&p2;v|?L$;E=JT$i6(SW-d$IZ`NTNl#Oj|>?OaLu*7h_RX)sMH=T zm(qf+AqJ&(+9q*sO@AJxQE^eJdOmLT%&Bq=TgpRm=^>;s=zU|WGkvG#mFBzl&#Rx& z?#pi`3f73i)Su^NlA4JVSB~O~^jRJPwK6i2Zc69p`#u<21-6(ejxMCZ@y$dQH*Z3l z@onEBS?C!jLR_CGhfv067yeKUm{`e7NgCba(I(3`Boup@xd&{#&Ks(z`&8jTZEtlW zs=ro94YAsn8hj;=FYunU8uiQa)S#5h4F&t}pZ%vkoM6Sk?(0xNoV1I7tkK6pJ-jHB zf2ao1zG8x;YpXX=v5Svwb({8F!L&k~^d}l)^C_D_YF^E`h*z+Sj`wHdGb-8&j&cRk zD&wd=6t)*N|IWypt>%I56OV_rNx0@i#YtB38z@|rh==OTXSYU&h+|RO5vpfBwwe_T z>&yuzg11fiLY?b2zM|8i{%qhZ+>oM)U(UC*n#qZ3Z)yhJA**0XdQz=EJ}ih`M?O&^Ln)L-ED2CzE{nF@lOwXBYm>C@Oc$n`Tju@~ z2|y7_3AfjjfsJKn95YpAnPm+Jnj%*mz4hS{rU^q?@6-q+T6?$dSzi#wwL}$LU#~7Z z!0uV>nVkxEZ@(Tn#-n}???)8v$_{?&=0+1xmB*>CB-c!cQkuZ$;C+dod(C2O7!tLT zjs#(Z%sr@U8*=mQ5_%W%FR>)_RBEr$V7d!kejN72rk7$mWucp}q5m-~QwdLknnCH^ zpZ>n{z@W>_G~-L2lmAk}(esX>Vw0&wj+fxjiOI%FwS!NZkymu`u(|xa*Krz1=S-+y z{3Q7eR^0V`wTf26H2U^PQT>=`b79>MMqjaXD^8#eor&p9oP)(PalIV}ErDwl^E7cH zjWx@6VohRcqf=2!twRY3c;{;-t`^u9DPx_HlESp(gd=pH{w)LkTx|vFr=ueFLk|bc z3Ips+;@q!K#7YfVbU##zl^)D5WLZmxx;=WMtQ9dyR@W4if8Xg!2a7`z*28l5{=vT0 z<>aYs*Ly?;*oCy+q>u{zj@sH{O@Zz#`rE0fL_XG(gf->2$q+53ZpzYN6tM-v_H}r) zI&q@Uj>-@|E<3qkFBlq#QyN{?xP-(sSh0xF_l7G^h7$eQ#YEoO1DwizjeL|@|D%Ga z%V~wmT3`y4>-TScpN@g!5{g{}Qab%`xzf^slFFPI@ID3h$$KJN? zWGLNuPNsgh)pISvg)#+nq;=}DbBaDK{<#yCq{1%xAes)=kj^T-_0OY8btB3lbu$S} zWnTPU-52$9a5m@MtpQOKHq1$%o#p}qM1EidXO0nZ$gH~$ewI!dZrEt>o8RJKuRl$u zE(MICK&$&@yW+@Chn3aZwIe3Gy)B#j%s%FiCWA#3eAMa#-4D2VkY&c}CB-+|>$sf{ zS%2cQz8zdnBY5~}rqy{+P%a_NFBE1@s*Z6WKAPp=UL_5Zb}_8i(+?Xmb*rnOxsD2Z z(D?+P0@F<0y{YgB=|intn}vrSSZy8eJVAG&THm~7&3b~_?8vde-*83GpJA;C^OH*{ zQ~qr$ar6hZ?8+HTAiuY$mSu2#dOJZu!74&YOR2;~Y3-)(R`P1xzwK=2P`a4IglK5B zEZ%Pt7rwErv|bssYV2_{j{ftu(+lg?1A6kcwB@<}#nK^5o}2u5(k13xUnj^$d)9OE zd3@vgYDS~#Xdch$3DVx-tz(~ZUq;P0iuC&}! zd!rm1TNPXbq&YFM5#DVz z1rLaJ3^P~#+t9jx8O^IU!Mn%P;_8${_p6H6Dxr1Ap*^0B6`2gd(CuL>ReMia?QYR# z-74P6!M9T%gY>S<6!0tCZK>V+#B~g!*laYS0k_QqN*LaoI^^zeoEs&HY3$xp_-H z1}$P_HD5X{`Zzngl(#(u`~TawjvpzfH+Is;f-R!x>Ko(~o%WX6;Gw95D!)rb zDKaN*%lXmH_L$i{`>23B7!7Gl$`M~mSGS~mPb3}-@g6+?A!MZn%=)En%z0<)3VS>E zAjaDx*6fSxZD~veG6^3@+||gRWLC9Rxn6vtbjzn}$^Y))pS2PN$8~CPC&XJ2?XN+{ zhm6;Ws7vIJwjQ)i94bfDVi4mAcHUcy;XrF^1rJ%yvHHRCqE5sXrJCI{Nqx=V+uLi$ z_`JT30}~QIv`~D+2ui*_{&63H34Hvi3^u_{KTr1;U%BUcMYpO}u1D64C2J$&ybsZ@ zM`sCrxVEH_aCak>zpD0*%ORcy;&_r5|N7}sBAla%*5ya!F*HQE_WTY z=>0x3uRS9lBj;yb*3)x;;;YX(x#XF@E44?2h!|fQJgygZgn;3gQ0eNK_JO_KIJ4Bg zB;9=W(Gz=+e*%eWVrU)5fYAA1n=fIPbmnrmU$a>@BmQ%C$IsrqdqYBkLDC}fpD(V8 z%4aoO2d*}(Pt=FH^(fdaKCGcuvlB?kK_~#D~{&RWy@p!MX4U4TU8Cs;RZmW}K_zm`)D){TkT`kWg&B{e&3S4RSyz<2E1{j6dROM6Pgmz}tqFCHw9yX`9noTWI zz#h2in&*ITBG4J307~)4zEr&U~(!e`q?}Ss7gI zOT>(pPgWd@Cg0MIjH}?-qZ0Q-nI!VxiH46JU^V%5VQ#5}NrD6ox%$EZF z-hO_YqngxE3S&fsd1GW-X7ZH7CFP?Uu$2JMvwzg+�O-mQ)gn8)A0OSEF8wMLh? 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

AG8S97?vaowex@lo>3-)I0mMFgv`tC>88k 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%0D0T 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 literal 0 HcmV?d00001 diff --git a/q4-scalability/calculations.md b/q4-scalability/calculations.md new file mode 100644 index 0000000..a364a47 --- /dev/null +++ b/q4-scalability/calculations.md @@ -0,0 +1,105 @@ +# Q4 — Scalability & Load Balancing (Ghaymah Cloud) + +## 1. Architecture + +See `architecture.png` in this folder. + +Flow: **Clients (15,000 req/s) → Load Balancer (round-robin + health checks) → +Container Auto-Scaling Pool (39 containers) → In-Memory Cache / Database + +Ghaymah Block Storage**. + +- The front tier (load balancer + containers) is **stateless** and scales + horizontally. +- The data tier (database) is **stateful** and relies on Ghaymah Block Storage + for durability, decoupled from the container lifecycle. + +--- + +## 2. Container Capacity Calculation + +**Given:** +- Total incoming load: `15,000 req/s` +- Capacity per container: `500 req/s` +- Safety margin: `30%` (to absorb traffic spikes and node/container failures) + +**Formula:** + +``` +Required capacity = Total load × (1 + margin) + = 15,000 × 1.30 + = 19,500 req/s + +Containers needed = Required capacity / Capacity per container + = 19,500 / 500 + = 39 containers +``` + +**Result: 39 containers** + +| Tier | Count | Purpose | +|---|---|---| +| Min replicas (baseline) | 30 | Covers the raw 15,000 req/s | +| Target / desired | 39 | Includes the 30% margin | +| Max replicas (HPA ceiling) | 50–55 | Extra headroom for burst traffic | + +**Recommendation:** configure the Horizontal Pod Autoscaler (HPA) on a +composite metric — `requests-per-second` (via a Prometheus adapter) as the +primary signal and `CPU utilization` as a secondary safeguard — rather than +CPU alone, since CPU can lag behind real request pressure. + +--- + +## 3. Cold Start Strategy for New Containers + +1. **Pre-warmed pool (warm standby)** — keep 2–3 idle, already-running + containers outside the active traffic path so bursts are absorbed + instantly instead of waiting for a container to be built from scratch. +2. **Slim, optimized images** — use minimal base images (Alpine/distroless), + reduce layers, and pre-pull images on nodes to avoid registry pull latency + during scale-out events. +3. **Strict readiness probes** — a container only joins the load balancer + pool after passing a `readinessProbe` (DB/cache connectivity check), + preventing 503s from traffic sent to a not-yet-ready instance. +4. **Predictive/scheduled scaling alongside reactive HPA** — if peak hours + are known (campaigns, daily traffic peaks), trigger scheduled scale-up + 5–10 minutes ahead of the peak instead of relying solely on reactive HPA, + which lags behind the metrics collection window. +5. **Connection pooling & pre-warmed init** — open DB/cache connections in an + init container or internal warm-up endpoint before the first real request + arrives, instead of lazy-initializing on first use. +6. **Graceful scale-down** — use a `preStop` hook and a proper + `terminationGracePeriodSeconds` to drain in-flight requests before + terminating containers during scale-in, avoiding dropped requests on the + way down. + +--- + +## 4. Ghaymah Block Storage for Stateful Workloads + +The containers above are intentionally **stateless** — any of them can be +killed and replaced without losing data. Anything that needs durable state +(database, message queues, uploaded files) must be decoupled from the +container's lifecycle — this is where **Block Storage** comes in: + +- **Decouples data from container lifecycle** — a block volume is attached + to a container/VM as an independent raw block device. If the container is + rescheduled or fails, the same volume is re-attached to the new + instance/node without data loss — unlike ephemeral container storage, + which is wiped on restart. +- **Best fit** — relational databases (PostgreSQL/MySQL), messaging systems + (Kafka/RabbitMQ), and any workload needing low-latency random I/O, since + block storage offers near-local-disk performance versus object storage. +- **High availability** — one block volume per database replica (never share + a single volume across concurrently-active instances); pair it with + application-level replication (e.g., Postgres streaming replication) + rather than relying on storage replication alone. +- **Snapshots & backup** — schedule periodic snapshots (daily minimum, plus + before any structural change/upgrade) to keep RPO/RTO low. +- **Vertical scalability** — volumes can typically be resized as data grows + without downtime, complementing the horizontal scaling of the stateless + container tier. + +**Summary:** the front tier (load balancer + container pool) scales +horizontally and fast because it's stateless, while the data tier relies on +Ghaymah Block Storage for durability and consistency, with an in-memory +cache absorbing read pressure and reducing latency. diff --git a/q5-mithal-monitor/dashboard.html b/q5-mithal-monitor/dashboard.html new file mode 100644 index 0000000..b3f7786 --- /dev/null +++ b/q5-mithal-monitor/dashboard.html @@ -0,0 +1,243 @@ + + + + + +لوحة مراقبة mithal.space + + + +

+
+
+

لوحة مراقبة mithal.space

+
Latency · Uptime · SSL · DNS · Search Response
+
+
آخر تحديث: --
+
+ +
+
+ + + + +
+
Uptime (24 ساعة)
+
--%
+
-- فحص
+
+
+ +
+
شهادة SSL
+
-- يوم
+
--
+
تنتهي في--
+
+ +
+
آخر قياس
+
Latency--
+
DNS--
+
Search--
+
HTTP Status--
+
+
+ +
+
زمن الاستجابة (آخر ساعة)
+ +
+ +
+
آخر 10 فحوصات
+ + + + + +
الوقتالحالةLatencyDNSSearchSSL (أيام)
+
+ +
يقرأ من /api/metrics · يُحدَّث كل 30 ثانية
+
+ + + + diff --git a/q5-mithal-monitor/monitor.py b/q5-mithal-monitor/monitor.py new file mode 100644 index 0000000..e0e15ea --- /dev/null +++ b/q5-mithal-monitor/monitor.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python3 +""" +monitor.py +========== +سكربت مراقبة ذاتي الاكتفاء (بدون أي مكتبات خارجية) لموقع mithal.space. + +يقوم بأمرين معًا: + 1. تشغيل خمسة فحوصات كل 60 ثانية (Latency, Uptime, SSL, DNS, Search) + وتخزين النتائج في ملف JSON Lines محلي (data.jsonl). + 2. تشغيل خادم HTTP بسيط يقدّم dashboard.html ويعرض بيانات مجمّعة + عبر /api/metrics حتى تعمل اللوحة مباشرة بفتح المتصفح على الخادم. + +التشغيل: + python monitor.py + python monitor.py --interval 60 --port 8080 + python monitor.py --once # فحص واحد فقط بدون تشغيل خادم (مناسب لجدولة cron) + +النشر على غيمة (ghaymah.systems): + هذا الملف مستقل تمامًا (لا يحتاج pip install لأي حزمة)، لذا يمكن نشره + داخل أي حاوية Python رسمية بأمر تشغيل واحد: + FROM python:3.11-slim + COPY monitor.py dashboard.html /app/ + WORKDIR /app + EXPOSE 8080 + CMD ["python", "monitor.py"] + اضبط Health Check Path على /health ومنفذ الخدمة على 8080 من console غيمة. +""" + +import argparse +import json +import os +import socket +import ssl +import threading +import time +import urllib.error +import urllib.request +from datetime import datetime, timedelta, timezone +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import urlparse, urlencode + +# -------------------------------------------------------------------------- +# الإعدادات (قابلة للتعديل عبر متغيرات البيئة) +# -------------------------------------------------------------------------- +TARGET_URL = os.environ.get("TARGET_URL", "https://mithal.space") +SEARCH_PATH = os.environ.get("SEARCH_PATH", "/search") +SEARCH_QUERY_PARAM = os.environ.get("SEARCH_QUERY_PARAM", "q") +SEARCH_QUERY_VALUE = os.environ.get("SEARCH_QUERY_VALUE", "test") +REQUEST_TIMEOUT = float(os.environ.get("REQUEST_TIMEOUT", 10)) +DATA_FILE = os.environ.get("DATA_FILE", "data.jsonl") +MAX_RECORDS = int(os.environ.get("MAX_RECORDS", 3000)) # ~50 ساعة عند فحص كل دقيقة + +_parsed = urlparse(TARGET_URL) +HOSTNAME = _parsed.hostname +PORT_443 = 443 + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +DASHBOARD_FILE = os.path.join(BASE_DIR, "dashboard.html") + +_store_lock = threading.Lock() + + +# -------------------------------------------------------------------------- +# 1) الفحوصات الخمسة +# -------------------------------------------------------------------------- +def check_dns(hostname: str = HOSTNAME) -> dict: + """يقيس زمن تحليل اسم النطاق (DNS resolution).""" + start = time.perf_counter() + try: + socket.getaddrinfo(hostname, PORT_443) + return {"ok": True, "dns_ms": round((time.perf_counter() - start) * 1000, 2)} + except socket.gaierror as e: + return {"ok": False, "dns_ms": round((time.perf_counter() - start) * 1000, 2), "error": str(e)} + + +def check_ssl(hostname: str = HOSTNAME, port: int = 443) -> dict: + """يفحص صلاحية شهادة SSL وتاريخ انتهائها.""" + try: + ctx = ssl.create_default_context() + with socket.create_connection((hostname, port), timeout=REQUEST_TIMEOUT) as sock: + with ctx.wrap_socket(sock, server_hostname=hostname) as ssock: + cert = ssock.getpeercert() + not_after = datetime.strptime(cert["notAfter"], "%b %d %H:%M:%S %Y %Z").replace(tzinfo=timezone.utc) + days_remaining = (not_after - datetime.now(timezone.utc)).days + return {"ok": True, "valid": True, "expires_at": not_after.isoformat(), "days_remaining": days_remaining} + except ssl.SSLCertVerificationError as e: + return {"ok": True, "valid": False, "error": str(e)} + except Exception as e: + return {"ok": False, "valid": False, "error": str(e)} + + +def _timed_get(url: str): + """طلب GET بسيط عبر urllib مع قياس الزمن وإرجاع (status_code, elapsed_ms, error).""" + start = time.perf_counter() + req = urllib.request.Request(url, headers={"User-Agent": "mithal-monitor/1.0"}) + try: + with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp: + elapsed_ms = round((time.perf_counter() - start) * 1000, 2) + return resp.getcode(), elapsed_ms, None + except urllib.error.HTTPError as e: + elapsed_ms = round((time.perf_counter() - start) * 1000, 2) + return e.code, elapsed_ms, None # كود HTTP فعلي (مثل 404/500) وليس خطأ اتصال + except Exception as e: + elapsed_ms = round((time.perf_counter() - start) * 1000, 2) + return None, elapsed_ms, str(e) + + +def check_latency(url: str = TARGET_URL) -> dict: + """يقيس زمن استجابة الصفحة الرئيسية ويحدد حالة توفر الموقع (uptime).""" + status_code, elapsed_ms, error = _timed_get(url) + up = status_code is not None and 200 <= status_code < 400 + return {"ok": error is None, "up": up, "status_code": status_code, "latency_ms": elapsed_ms, "error": error} + + +def check_search(base_url: str = TARGET_URL) -> dict: + """يرسل استعلام بحث فعلي ويقيس زمن الرد بمعزل عن الصفحة الرئيسية.""" + query = urlencode({SEARCH_QUERY_PARAM: SEARCH_QUERY_VALUE}) + search_url = base_url.rstrip("/") + SEARCH_PATH + "?" + query + status_code, elapsed_ms, error = _timed_get(search_url) + return {"ok": error is None, "status_code": status_code, "search_response_ms": elapsed_ms, "error": error} + + +def run_full_check() -> dict: + """ينفّذ جميع الفحوصات الخمسة ويجمعها في سجل واحد جاهز للتخزين.""" + dns_result = check_dns() + latency_result = check_latency() + ssl_result = check_ssl() + search_result = check_search() + + return { + "timestamp": datetime.now(timezone.utc).isoformat(), + "target": TARGET_URL, + "up": latency_result.get("up", False), + "status_code": latency_result.get("status_code"), + "latency_ms": latency_result.get("latency_ms"), + "dns_ms": dns_result.get("dns_ms"), + "ssl_valid": ssl_result.get("valid"), + "ssl_days_remaining": ssl_result.get("days_remaining"), + "ssl_expires_at": ssl_result.get("expires_at"), + "search_response_ms": search_result.get("search_response_ms"), + "search_status_code": search_result.get("status_code"), + "error": latency_result.get("error") or ssl_result.get("error") or search_result.get("error"), + } + + +# -------------------------------------------------------------------------- +# 2) التخزين (JSON Lines) - قابل للتبديل بسهولة إلى append_to_csv أدناه +# -------------------------------------------------------------------------- +def append_to_store(record: dict, path: str = DATA_FILE, max_lines: int = MAX_RECORDS): + """يضيف سجل فحص جديد كسطر JSON، ويقلّم الملف عند تجاوز max_lines.""" + with _store_lock: + with open(path, "a", encoding="utf-8") as f: + f.write(json.dumps(record, ensure_ascii=False) + "\n") + + with open(path, "r", encoding="utf-8") as f: + lines = f.readlines() + if len(lines) > max_lines: + with open(path, "w", encoding="utf-8") as f: + f.writelines(lines[-max_lines:]) + + +def append_to_csv(record: dict, path: str = "data.csv"): + """بديل اختياري: تخزين نفس السجل بصيغة CSV مسطّحة (جدول بيانات).""" + import csv + file_exists = os.path.exists(path) + with _store_lock: + with open(path, "a", newline="", encoding="utf-8") as f: + writer = csv.DictWriter(f, fieldnames=list(record.keys())) + if not file_exists: + writer.writeheader() + writer.writerow(record) + + +def read_all_records(path: str = DATA_FILE) -> list: + if not os.path.exists(path): + return [] + records = [] + with _store_lock: + with open(path, "r", encoding="utf-8") as f: + for line in f: + line = line.strip() + if not line: + continue + try: + records.append(json.loads(line)) + except json.JSONDecodeError: + continue + return records + + +# -------------------------------------------------------------------------- +# 3) التجميع لأجل /api/metrics (uptime 24h, latency آخر ساعة، SSL، آخر 10) +# -------------------------------------------------------------------------- +def build_metrics_payload() -> dict: + records = read_all_records() + now = datetime.now(timezone.utc) + + def parse_ts(r): + try: + return datetime.fromisoformat(r["timestamp"]) + except Exception: + return None + + last_24h = [r for r in records if (ts := parse_ts(r)) and now - ts <= timedelta(hours=24)] + uptime_percent = round(100 * sum(1 for r in last_24h if r.get("up")) / len(last_24h), 2) if last_24h else None + + last_hour = [r for r in records if (ts := parse_ts(r)) and now - ts <= timedelta(hours=1)] + latency_series = [ + {"timestamp": r["timestamp"], "latency_ms": r.get("latency_ms")} + for r in last_hour if r.get("latency_ms") is not None + ] + + latest = records[-1] if records else {} + ssl_info = { + "valid": latest.get("ssl_valid"), + "days_remaining": latest.get("ssl_days_remaining"), + "expires_at": latest.get("ssl_expires_at"), + } + + last_10 = records[-10:][::-1] + + return { + "uptime_24h_percent": uptime_percent, + "checks_in_24h": len(last_24h), + "latency_series": latency_series, + "ssl": ssl_info, + "last_checks": last_10, + "latest": latest, + "generated_at": now.isoformat(), + } + + +# -------------------------------------------------------------------------- +# 4) حلقة المراقبة في الخلفية (تعمل كل CHECK_INTERVAL ثانية) +# -------------------------------------------------------------------------- +def collector_loop(interval: int): + while True: + try: + record = run_full_check() + append_to_store(record) + status = "UP" if record["up"] else "DOWN" + print(f"[{record['timestamp']}] {status} http={record['status_code']} " + f"latency={record['latency_ms']}ms dns={record['dns_ms']}ms " + f"ssl_days={record['ssl_days_remaining']} search={record['search_response_ms']}ms") + if record.get("error"): + print(f" -> ملاحظة: {record['error']}") + except Exception as e: + print(f"[collector] خطأ غير متوقع: {e}") + time.sleep(interval) + + +# -------------------------------------------------------------------------- +# 5) خادم HTTP بسيط (بدون Flask) يقدّم dashboard.html + /api/metrics + /health +# -------------------------------------------------------------------------- +class DashboardHandler(BaseHTTPRequestHandler): + def _send_json(self, payload: dict, status: int = 200): + body = json.dumps(payload, ensure_ascii=False).encode("utf-8") + self.send_response(status) + self.send_header("Content-Type", "application/json; charset=utf-8") + self.send_header("Access-Control-Allow-Origin", "*") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + + def do_GET(self): + if self.path in ("/", "/dashboard.html"): + if os.path.exists(DASHBOARD_FILE): + with open(DASHBOARD_FILE, "rb") as f: + body = f.read() + self.send_response(200) + self.send_header("Content-Type", "text/html; charset=utf-8") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + else: + self._send_json({"error": "dashboard.html not found next to monitor.py"}, 404) + elif self.path == "/health": + self._send_json({"status": "healthy"}) + elif self.path == "/api/metrics": + self._send_json(build_metrics_payload()) + else: + self._send_json({"error": "not found"}, 404) + + def log_message(self, fmt, *args): + pass # تعطيل سجلات الخادم الافتراضية المزعجة؛ نطبع فقط سجلات الفحص + + +def run_server(port: int): + server = ThreadingHTTPServer(("0.0.0.0", port), DashboardHandler) + print(f"Dashboard server running on http://0.0.0.0:{port} (health: /health, api: /api/metrics)") + server.serve_forever() + + +# -------------------------------------------------------------------------- +# نقطة الدخول +# -------------------------------------------------------------------------- +def main(): + parser = argparse.ArgumentParser(description="Monitor mithal.space + serve dashboard.") + parser.add_argument("--interval", type=int, default=60, help="ثواني بين كل فحص (افتراضي 60)") + parser.add_argument("--port", type=int, default=int(os.environ.get("PORT", 8080))) + parser.add_argument("--once", action="store_true", help="نفّذ فحصًا واحدًا فقط بدون تشغيل الخادم (مناسب لـ cron)") + args = parser.parse_args() + + if args.once: + record = run_full_check() + append_to_store(record) + print(json.dumps(record, indent=2, ensure_ascii=False)) + return + + collector_thread = threading.Thread(target=collector_loop, args=(args.interval,), daemon=True) + collector_thread.start() + + run_server(args.port) + + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("\nتم إيقاف المراقبة بواسطة المستخدم.")