עדכון עצמי של הליבה

איך אתר WIZZO CMS מעדכן את הליבה של עצמו מהשרת הראשי, שלבי התהליך, בדיקות לפני ואחרי, חזרה אוטומטית, ערוצי latest ו-stable וטבלאות הלוג

⏱ 7 דק' קריאה 1344 מילים ערוך דף זה ב-GitHub

הליבה של WIZZO CMS (התיקייה system/core באתר) מתעדכנת מתוך האתר עצמו: האתר שואל את השרת הראשי של Wizzo מה הגרסה הנוכחית, מוריד ZIP, מחליף את תיקיית הליבה ומסנכרן סכמת בסיס נתונים, פאנלים ומשימות cron. הדף הזה מתאר את התהליך שלב אחר שלב, מה נבדק לפני ואחרי ההחלפה, מתי מתבצעת חזרה אוטומטית אחורה, ומה בדיוק נוגעים בו ומה לא.

הרכיבים#

רכיבקובץרץ עלתפקיד
השרת הראשי, check_versioncontrollers/check_version.phpwizzocms40.wizzo.co.il בלבדעונה "מה הגרסה", בונה ומגיש את ה-ZIP, מייצא סכמת בסיס נתונים, פאנלים, cron ו-JS, ומפיק הערות שחרור
הלקוח, "מרכז עדכונים"admin/wizzo_update.php (ADMINMODULE_wizzo_update)כל אתרמבצע את ההחלפה והסנכרונים, מנהל את הלוג וממשק הפאנל
core_pingcontrollers/core_ping.phpכל אתרGET /system/core_ping מחזיר {ok, version, db, php} בלי מטמון. זה מבחן ה"האם הליבה החדשה עלתה"
גשר הסוכניםcontrollers/agent_mcp.php, פעולה wizzo_updateכל אתרמאפשר לשרת הסוכנים להפעיל את אותו תהליך עם channel ו-check_only. ראו גשר agent_mcp
version.txtsystem/core/version.txtכל אתרמחרוזת הגרסה, למשל 5.0.115. ראו גרסאות
הערה

הקובץ check_version.php מוחרג מה-ZIP עצמו, ולכן אתר לקוח לעולם לא מקבל את קוד השרת הראשי ולא את טוקן ה-GitHub שמונח רק אצלו. הערות השחרור (מה נכנס) מגיעות לאתר כתשובה מהשרת הראשי, לא מ-.git מקומי.

איך מפעילים עדכון#

דרךפרטים
הפאנל{admin}/wizzo_update, כפתור "עדכון גרסה". הפאנל קורא ל-{admin}/wizzo_update/get בלי channel, כלומר לערוץ latest
ערוץ מפורש{admin}/wizzo_update/get?channel=stable (דרך סשן מנהל)
שרת הסוכניםפעולת wizzo_update ב-agent_mcp עם channel, check_only ו-force

הפלט של get הוא טקסט: true בהצלחה, false בכישלון. כל מילה נוספת שנדפסת אחריו (למשל שגיאת יצירת טבלה מהסנכרון) גורמת לממשק להציג שגיאה, למרות שהחלפת הליבה עצמה כבר בוצעה.

שימו לב
get הוא בקשת GET בלי אסימון CSRF. מנהל מחובר שפותח כתובת מתוך דף זדוני יכול להפעיל עדכון. זה ממצא ידוע בביקורת. כל עוד הוא פתוח, אל תשאירו מנהלים מחוברים בדפדפן שגולש לאתרים לא מהימנים.

התהליך שלב אחר שלב#

ADMINMODULE_wizzo_update::get() מבצע את הרצף הבא:

  1. רישום עוגן. יוצר את CRM_wizzo_update_log אם חסרה, קורא את head_sha של העדכון המוצלח הקודם, ושואל את השרת הראשי (/head) מה ה-sha הנוכחי. ה-sha נרשם ללוג רק אחרי הצלחה. כשל בשלב הזה לא עוצר עדכון.
  2. מה מוצע. GET {MASTER}/get?ver=<מותקן>&format=json&channel=latest|stable מחזיר {ok, version, channel, url, sha256, size, php_floor}, או {ok, up_to_date: true}. מאסטר ישן שעונה טקסט מקבל את המסלול הישן (כתובת ZIP גולמית, בלי חתימה).
  3. עדכון לא נדרש. אם אין גרסה חדשה בערוץ, לא יורד ZIP ולא מוחלפת ליבה, אבל שלב 11 (הסנכרונים) עדיין רץ. כך "הרצה כפויה" מסנכרנת טבלאות ופאנלים גם בלי גרסה חדשה.
  4. בדיקה מקדימה (preflight). נכשל עם סיבה קצרה ביומן, ושום קובץ לא נוגע: php_too_old <יש> < <נדרש>, no_zip_extension, disk_full <פנוי> < <נדרש> (הנדרש הוא הגדול מבין 64MB ופי 4 מגודל ה-ZIP), db_unreachable.
  5. הורדה. copy() בזרימה (timeout של 600 שניות) לקובץ ZIP בתיקיית העבודה. קובץ קטן מ-1KB נחשב כשל.
  6. אימות sha256. במסלול ה-JSON, אי-התאמה היא zip_checksum_mismatch והקובץ נמחק.
  7. פריסה בצד. הפריסה היא לתיקייה core_new_<ts> לצד הליבה החיה, שממשיכה לשרת. אם חסרים core.php או version.txt, היא נמחקת (broken_extraction).
  8. החלפה. שני rename: core אל core_bup_<ts>, ואז core_new_<ts> אל core. אם השני נכשל, הראשון מוחזר מיד (swap_in_failed).
  9. בדיקה אחרי (postflight). בקשה לאתר עצמו, {env_url}/system/core_ping?_wz=<rand> (עד 60 שניות, ללא מטמון). תשובה 5xx, גוף שאינו ה-JSON של core_ping, db: false, או גרסה שונה מהצפויה, מחזירות את הליבה הישנה אוטומטית ביומן postflight_failed ... (rolled back to <גרסה>). אם אין תשובת HTTP בכלל (DNS, חומת אש פנימית), הבדיקה נחשבת עוברת, כי הליבה לא נשפטת על רשת השרת.
  10. הצלחה. מדפיס true, רושם ל-CRM_wizzo_update_log (status=success), ושומר את חמשת גיבויי core_bup_* האחרונים.
  11. סנכרונים. בסדר: protect_system_folder() (שותל את .htaccess של /system/), update_db(), update_panel(), update_cron_system(), update_js(). אחריהם attaches_version עולה ב-1 (שובר מטמון נכסים בדפדפנים), מטמון params מנוקה, ו-external_mcp::flush() מנקה את רשימת הכלים שה-gateway מגיש.
טיפ

בדיקת מצב בלי לגעת בכלום: GET https://wizzocms40.wizzo.co.il/system/check_version/check?ver=<גרסה>&format=json&channel=stable מחזיר installed, latest, stable, channel, target, stable_fallback, update_available, php_floor ו-php_master. בלי format=json התשובה היא הגרסה או up_to_date.

// maintenance script: is an update waiting, and can this PHP take it?
$ver = trim(file_get_contents(CONFIG::$core_path . "/version.txt"));
$ctx = stream_context_create(["http" => ["timeout" => 20, "ignore_errors" => true]]);
$j = json_decode((string)@file_get_contents(
    "https://wizzocms40.wizzo.co.il/system/check_version/check?ver=" . rawurlencode($ver)
    . "&format=json&channel=stable", false, $ctx), true);

if (!empty($j["update_available"]) && version_compare(PHP_VERSION, $j["php_floor"], ">="))
{
    // run the update itself only from the panel: {admin}/wizzo_update
}

ערוצים: latest ו-stable#

ערוץמה הואמתי
latest (ברירת מחדל)version.txt החי של השרת הראשי ברגע הבקשה. ה-ZIP נבנה פעם אחת לכל גרסה וטביעת אצבע של העץ, תחת נעילת flockכל פרסום לשרת הראשי מגיע מיד
stableהגרסה ש-promote הקפיא: releases/stable.txt ו-releases/core-<ver>.zip עם .sha256אתרים שמבקשים אותו במפורש

אם אין גרסה קפואה או שה-ZIP שלה חסר, stable נופל ל-latest והתשובה כוללת stable_fallback: true. ההקפאה (promote) דורשת סוד בוט ומקפיאה רק את הגרסה שהשרת הראשי מריץ באותו רגע (נשמרות חמש גרסאות אחרונות). פרסום גרסה לכל הצי הוא החלטה של אדם, לא של סשן אוטומטי.

אין באתר פרמטר קבוע שבוחר ערוץ: הערוץ נבחר בבקשה. סביבת פיתוח מקומית בדרך כלל לא מריצה את הפאנל כלל, אלא מציבה את api/core כ-symlink או checkout של הריפו.

מה מוחלף ומה לא#

  • מוחלפת רק התיקייה system/core (שהיא api/core בריפו). application/, themes/, storage/, CONFIG_USER, המטמון ו-system/market_settings.json לא נוגעים.
  • system/js מוחלפת בשלמותה בתהליך נפרד (update_js), ובלי גיבוי אטומי: התיקייה הישנה עוברת ל-js_bup_<ts> לפני הפריסה, ואם הפריסה נכשלת לא חוזרים אליה אוטומטית.
  • שינויים מקומיים בתוך core/ נמחקים בעדכון הבא, והם נשארים רק בגיבוי core_bup_<ts> לחמישה עדכונים. אין מנגנון patch או overlay, ולכן כל התאמה שייכת ל-application/.
  • בסיס נתונים: update_db() רק מוסיף טבלאות, עמודות ואינדקסים (טבלה חדשה בקידוד utf8mb4). הוא לא מוחק, ומרחיב עמודה רק כשזו הרחבה בטוחה.
  • פאנלים: update_panel() מעדכן שורות ב-adminPanel_panels לפי panel_name (טקסט, אייקון, extra_perms, perm_developer), מוסיף אפשרויות חסרות, ויוצר קטגוריה רק לפאנל חדש.
  • משימות cron: update_cron_system() הוא מקור אמת: משימות בקטגוריה 1 ("מערכת") שאינן בשרת הראשי נמחקות מהאתר. שדות ריצה (last_run, next_run, runs_count) נשמרים. משימות שלכם שייכות לקטגוריה אחרת.
אזהרה

אל תוסיפו משימות cron מותאמות בקטגוריה 1: העדכון הבא ימחק אותן. ואל תערכו קבצים בתוך system/core באתר חי: העדכון הבא ידרוס אותם.

שימו לב

סנכרוני בסיס הנתונים, הפאנלים וה-cron אינם ניתנים להרצה "יבשה" או לחזרה אחורה. הדברים היחידים שיש להם חזרה אוטומטית הם החלפת הליבה עצמה. בדקו מקום פנוי בדיסק לפני עדכון: core_bup_* שנשמרים (חמישה) הם עותקים מלאים של הליבה.

טבלאות ופרמטרים#

מהאיפהתוכן
CRM_wizzo_update_logהאתרid, date_created, admin_id (0 = אוטומטי), status (success או failed), error_text, from_version, to_version, head_sha, prev_sha, commits_count, ai_summary, ai_summary_date
CRM_params.wizzo_update_pendingהאתרמטמון ה-HTML של "מה מחכה", מפתח <גרסה>|<sha>
CRM_params.attaches_versionהאתרמונה לשבירת מטמון נכסים, עולה ב-1 בכל עדכון
core_bup_<ts>/, core_new_<ts>/, core_failed_<ts>/, js_bup_<ts>/system/ באתרגיבויים ותיקיות ביניים. נשמרים חמישה אחרונים מכל סוג גיבוי
CRM_params.github_api_token, bot_api_secret, מטמוני wizzo_update_changes_cache ו-wizzo_update_version_bumpsהשרת הראשי בלבדטוקן קריאה ל-GitHub, סוד הבוט להקפאה ולאימות טוקן, ומטמוני סיכומי ה-AI
SELECT date_created, status, from_version, to_version, error_text
FROM CRM_wizzo_update_log
ORDER BY id DESC
LIMIT 5

קודי השגיאה שמופיעים ב-error_text: master_unreachable, php_too_old, no_zip_extension, disk_full, db_unreachable, zip_download_failed, zip_checksum_mismatch, cannot_open_zip, broken_extraction, swap_out_failed, swap_in_failed, postflight_failed.

הערות שחרור בפאנל#

לשונית "מה מחכה" שואלת את השרת הראשי: GET {MASTER}/changes?ver=<מותקן>&from_sha=<קודם> מחזיר רשימת commits מסוכמת, עם סיכום שנוצר ב-WizzoAI ונשמר פעם אחת בשרת הראשי עבור כל הצי. נושא commit שמסומן [security] או [breaking] מדליק דגל מודגש בפאנל. כל תשובה מהרשת מפורקת ומורכבת מחדש לפני שהיא נכנסת לעמוד כ-HTML.

מידע

הסיכום של הערות השחרור שולח לשירות AI את נושאי ה-commits של הליבה (לא קוד האתר שלכם). ראו מארחים חיצוניים.

ראו גם#

מצאתם טעות או חוסר? תקנו את הדף או פתחו Issue בריפו. התיעוד נכתב מתוך הקוד של ליבה 5.0.115.