الترحيل (بين الأجهزة)
الترحيل بين الأجهزة (kazma migrate)
Section titled “الترحيل بين الأجهزة (kazma migrate)”انقل تثبيت كاظمه كاملًا — الإعدادات، والأسرار، والذاكرة، وسجل الدردشة، واللقطات، والمهام المجدولة، والأصول — من جهاز إلى آخر (WSL→Windows، أو Linux→Mac، أو خادم→حاسوب محمول) دون الأعطال الصامتة التي يسببها النسخ واللصق الساذج.
ينهار النسخ الساذج للملفات بثلاث طرق محددة: تصبح الخزنة المشفرة غير قابلة لفك التشفير (مفتاح خاطئ)، وتشير المسارات المضمّنة في الملفات إلى مسار ميت /home/user/...، وبيانات Postgres (سجل الدردشة، والإعدادات، ونقاط التفتيش) لا يشملها النسخ إطلاقًا. يمنع kazma migrate الثلاثة جميعًا.
البدء السريع
Section titled “البدء السريع”على الجهاز المصدر:
kazma migrate export --out my-kazma.zipعلى الجهاز الهدف (بعد نسخ my-kazma.zip إليه):
kazma migrate verify my-kazma.zipkazma migrate import my-kazma.zip --workspace /path/to/kazma --dry-run # preview firstkazma migrate import my-kazma.zip --workspace /path/to/kazma # real importهذا كل شيء لتثبيت يعتمد على SQLite. للمصادر المعتمدة على Postgres، انظر § هجرة Postgres أدناه.
ما تحتويه الحزمة
Section titled “ما تحتويه الحزمة”أرشيف .zip يحتوي على:
| الملف | المحتوى |
|---|---|
manifest.json | الإصدار، ونظام/مضيف المصدر، وبصمة sha256 لكل ملف، وبصمة مفتاح الخزنة، وأعداد الجداول |
meta.env | KAZMA_VAULT_KEY + KAZMA_PUBLIC_URL (لازمة لفك تشفير الخزنة + OAuth) |
config.yaml | كل إعدادات ConfigStore (الأسرار مراجع vault:// وليست نصًا صريحًا) |
data/vault.db | مخزن الأسرار المشفر (29+ سرًّا) — ينتقل مع مفتاح الخزنة |
data/*.db | كل قواعد بيانات SQLite (اللقطات، والذاكرة، وcron، والدردشة، ونقاط التفتيش، إلخ) |
data/documents.db | البيانات الوصفية لـذكاء المستندات (الإصدارات، وACL، والتدقيق، والمهام حين تكون على SQLite) عند وجود مخزن المنصة |
document-store/ (شجرة الحزمة) | الكتل المعنونة بالمحتوى + البيانات الوصفية التي يشير إليها فهرس المستندات (documents.db، أو فهرس Postgres في data/postgres.dump؛ شجرة SHA-256 غير قابلة للتغيير). تُستعاد إلى documents.storage_root الهدف |
data/postgres.dump | نسخة Postgres الاحتياطية (فقط عندما يكون المصدر معتمدًا على Postgres) |
data/workspaces.db | جدول مساحات العمل (تُعاد كتابة المسارات الجذرية عند الاستيراد) |
assets/ | كل ما ينتقل غير ذلك من مجلد البيانات: سجل عمّال السرب وقوالبه، ومرفقات الدردشة، والمستندات، والتصديرات، والصور، ومساحة العمل الافتراضية، وأي ملف تحفظه أنت (أو الوكيل) هناك. ولا يُحمَل: هوية التثبيت (install_id)، ونسخه الاحتياطية، وسجلاته، وما يُعاد بناؤه (المتجهات وفهارس الشيفرة) |
pathmap.json | جذر مساحة عمل المصدر + دليل البيانات (لترجمة المسارات) |
ملاحظات مخزن المستندات: لا يحتوي documents.db على أي مسارات مطلقة مضمّنة تحتاج إعادة كتابة (المحتوى معنون بالمحتوى). يأخذ التصدير لقطة من قاعدة البيانات أولًا، ثم ينسخ الكتل والبيانات الوصفية التي تشير إليها؛ والكتلة المُشار إليها المفقودة تُعلِّم الحزمة بأنها ناقصة، فيرفضها verify (ومن ثَمّ import). يَنسخ الاستيراد documents.db الموجود لدى الهدف إلى النسخة الاحتياطية السابقة للاستيراد (بأفضل جهد)، ويُثبِّت القاعدة المُجهَّزة، ويضيف ملفات المحتوى المُجهَّزة التي يفتقدها الهدف (وتُبقى الملفات الموجودة أصلًا)، في جذر مخزن المستندات الذي يُحل بعد استيراد الإعدادات، حتى يُحترم documents.storage_root المخصص؛ ولا يُثبَّت documents.db إلا حين يكون فهرس الهدف على SQLite. ومخزن المستندات الذي تفشل استعادته يُفشل الاستيراد (ok: false؛ منذ 2026-10-13 — كان تحذيرًا بجانب استيراد ناجح). انظر عمليات معالجة المستندات.
مخزن مستندات على Postgres ينتقل فهرسًا وملفات (منذ 2026-10-13). حين تكون البيانات الوصفية للمستندات على Postgres (KAZMA_DOCUMENTS_METADATA_BACKEND=postgres، أو auto/غير مضبوط في تثبيت يعمل على Postgres)، يكون الفهرس داخل data/postgres.dump ويؤخذ أولًا، ثم ينسخ المُصدِّر كل ملف محتوى وبيانات وصفية يشير إليه من جذر التخزين (وحتى ذلك التاريخ كان يقرأ documents.db المحلي الفارغ ولا يحمل أي ملف محتوى). وتقرّر واجهة سطر الأوامر بحسب الخلفيات المضبوطة، إذ لا خدمة عاملة لديها. ويُرفض بالاسم فهرسُ Postgres بجانب طابور SQLite (وضع احتياطي). والتثبيت الذي بياناته الوصفية للمستندات على SQLite بجانب مهام على Postgres يحمل documents.db ومحتواه (والترقيات المقروءة من الطابور) ومهامه داخل data/postgres.dump، مأخوذة في لحظات مختلفة. ولنقل مخزن عند لحظة زمنية واحدة بدلًا من ذلك، استخدم النسخ الاحتياطي المنسَّق للمستندات (python scripts/document_pg_backup.py backup على المصدر؛ وعلى الهدف، بعد kazma migrate import، restore ... --replace-document-tables): انظر معالجة المستندات ← النسخ الاحتياطي.
الثوابت الثلاثة
Section titled “الثوابت الثلاثة”هذه أنماط الانهيار الصامت التي يمنعها kazma migrate:
أ. إقران الخزنة — vault.db + KAZMA_VAULT_KEY ينتقلان معًا
Section titled “أ. إقران الخزنة — vault.db + KAZMA_VAULT_KEY ينتقلان معًا”ملح تشفير الخزنة يعيش داخل vault.db، لذا فقاعدة البيانات غير قابلة لفك التشفير بدون مفتاحها المطابق. تحمل الحزمة كليهما. عند الاستيراد:
- المفاتيح متطابقة → يُثبَّت vault.db وتُفك شيفرات الأسرار. ✅
- مفتاح الهدف فارغ → يُكتب مفتاح الحزمة إلى
.envالهدف. ✅ - المفاتيح مختلفة → يُجهَض الاستيراد إلا إذا مررت
--reset-vault-key(الذي يأخذ نسخة احتياطية من vault.db الموجودة في الهدف أولًا، ثم يكتب مفتاح الحزمة).
kazma migrate import my-kazma.zip --workspace /path --reset-vault-keyب. ترجمة المسارات — إعادة كتابة المسارات المضمّنة تلقائيًا
Section titled “ب. ترجمة المسارات — إعادة كتابة المسارات المضمّنة تلقائيًا”التثبيت المصدر عند /home/user/kazma يكون قد خبّز ذلك المسار داخل workspaces.root_path، وsnapshots.state_json (كتل SupervisorState الكاملة)، ورسائل الدردشة، وحلقات الذاكرة، ومحفزات cron. يعيد المُستورد كتابتها جميعًا إلى المسار الهدف، عبر اصطلاحات فواصل المسار بين أنظمة التشغيل.
# Linux source → Windows targetkazma migrate import my-kazma.zip --workspace "C:\Users\me\kazma"إعادة الكتابة سلسلة فرعية على مستوى البايت (وليست تحليل JSON) لذا تتعامل بكفاءة مع snapshots.db بحجم 300+ MB. ترتيب بادئات المسار يمنع إعادة الكتابة الجزئية (/home/u/kazma لن يُفسد /home/u/kazma-repos/ShipX).
ج. الاستيراد الذرّي — تجهيز → نسخ احتياطي → تبديل
Section titled “ج. الاستيراد الذرّي — تجهيز → نسخ احتياطي → تبديل”الاستيراد لا يمس البيانات الحية أثناء التنفيذ:
- التجهيز — فك ضغط الحزمة إلى
kazma-data/.migrate-staging-<ts>/ - إعادة كتابة المسارات للنسخ المُجهَّزة
- نسخة احتياطية لقواعد البيانات الحية إلى
kazma-data/.migrate-backup-<ts>/ - التبديل: التجهيز → الحي (آمن مع WAL، ملف واحد في كل مرة)
الفشل قبل التبديل يترك البيانات الحية دون مساس. يُحتفظ بدليل التجهيز عند الفشل للفحص. للتراجع: انسخ ملفات .db من دليل النسخة الاحتياطية فوق الملفات الحية.
هجرة Postgres
Section titled “هجرة Postgres”عندما يكون المصدر معتمدًا على Postgres، تتضمن الحزمة أيضًا data/postgres.dump منتَجًا بواسطة pg_dump -Fc (تنسيق مخصص — يتعامل مع كتل bytea أصليًا، أصغر بنحو 7× من النص العادي).
الاكتشاف — pg_dump / pg_restore
Section titled “الاكتشاف — pg_dump / pg_restore”يجد محرك الترحيل الملفات التنفيذية تلقائيًا:
pg_dump/pg_restoreعلىPATHdocker exec ${KAZMA_DB_CONTAINER:-kazma-db} <bin>— الخيار الافتراضي الشائع لنشر Docker- خطأ واضح مع تلميح تثبيت إن لم يتوفر أي منهما
لتجاوز اسم الحاوية:
KAZMA_DB_CONTAINER=my-postgres kazma migrate export --out my-kazma.zipالاستيراد إلى هدف Postgres
Section titled “الاستيراد إلى هدف Postgres”يجب أن يكون لدى الهدف KAZMA_DB_BACKEND=postgres + KAZMA_DATABASE_URL مضبوطَين:
export KAZMA_DB_BACKEND=postgresexport KAZMA_DATABASE_URL=postgresql://kazma:kazma_change_me@127.0.0.1:5433/kazmaexport KAZMA_DB_CONTAINER=kazma-db-winkazma migrate import my-kazma.zip --workspace /path/to/kazma --reset-vault-keyيعيد pg_restore --clean --if-exists إنشاء المخطط (يمكن لقاعدة بيانات الهدف أن تكون فارغة)، ثم يحمل البيانات. تُستعاد ملفات SQLite (الخزنة، والذاكرة، واللقطات) جنبًا إلى جنب.
منفذ Docker الداخلي
Section titled “منفذ Docker الداخلي”عند تشغيل pg_dump / pg_restore عبر docker exec، تُنفَّذ داخل الحاوية، حيث يستمع Postgres على localhost:5432 — وليس على منفذ المضيف المُمرَّر (مثل 5433). يكتشف المحرك حالة Docker ويتجاوز تلقائيًا. تجاوز المنفذ الداخلي إذا كانت حاويتك تستمع في مكان آخر:
KAZMA_DB_INTERNAL_PORT=5432 # default; change only if your container differsمرجع الأوامر
Section titled “مرجع الأوامر”kazma migrate export
Section titled “kazma migrate export”kazma migrate export [--out PATH] [--no-assets]| العلم | الافتراضي | الغرض |
|---|---|---|
--out PATH | kazma-bundle-<timestamp>.zip | مسار حزمة المخرجات |
--no-assets | (الأصول مضمّنة) | يترك ملفات مجلد البيانات خارج الحزمة (حزمة أصغر من الإعدادات وقواعد البيانات). ويظل سجل عمّال السرب وقوالبه ينتقلان |
kazma migrate verify
Section titled “kazma migrate verify”kazma migrate verify BUNDLE [--no-hash]يفحص سلامة الحزمة: البنية، وتوافق البيان، وبصمة sha256 لكل ملف، وبصمة مفتاح الخزنة، وأعداد صفوف الجداول. يتخطى --no-hash إعادة حساب التجزئة (البطيئة) لفحص بنيوي سريع.
kazma migrate import
Section titled “kazma migrate import”kazma migrate import BUNDLE [--workspace PATH] [--reset-vault-key] [--dry-run]| العلم | الافتراضي | الغرض |
|---|---|---|
--workspace PATH | الدليل الحالي | جذر مساحة عمل الهدف (تُعاد كتابة المسارات إليه) |
--reset-vault-key | (إجهاض عند عدم التطابق) | الكتابة فوق مفتاح خزنة الهدف بمفتاح الحزمة (يأخذ نسخة احتياطية من vault.db الموجودة أولًا) |
--dry-run | (استيراد حقيقي) | تحقق + تخطيط فقط؛ دون أي كتابات |
متغيرات البيئة
Section titled “متغيرات البيئة”| المتغير | الافتراضي | الغرض |
|---|---|---|
KAZMA_DB_CONTAINER | kazma-db | اسم حاوية Docker لاكتشاف pg_dump / pg_restore |
KAZMA_DB_INTERNAL_PORT | 5432 | منفذ Postgres الداخلي للحاوية (عند التشغيل عبر docker exec) |
انظر أيضًا: متغيرات البيئة · قابلية النقل · التعافي من الكوارث
التراجع
Section titled “التراجع”كل استيراد ينشئ نسخة احتياطية ما قبل الاستيراد عند kazma-data/.migrate-backup-<ts>/: قواعد البيانات التي استبدلها، وتحت files/ كل ملف لدى الهدف استبدلته الحزمة بملف مختلف. للتراجع:
# Stop Kazma, then copy the backup .db files back over the live onescp kazma-data/.migrate-backup-<ts>/*.db kazma-data/# and the replaced files, if anycp -r kazma-data/.migrate-backup-<ts>/files/. kazma-data/التصدير الذي لا يستطيع قراءة ملف يسمّيه في البيان (manifest)، فيرفض verify (ومن ثَمّ import) تلك الحزمة. والاستيراد الذي لا يستطيع استعادة ملف يبلّغ عنه، ولا يبلّغ عن نجاح، ويترك نسخة الحزمة منه في مجلد التجهيز.
بالنسبة إلى Postgres، فإن pg_restore --clean --if-exists غير متغيّر الأثر (idempotent) — إعادة تشغيل الاستيراد تستعيد من الحزمة بشكل نظيف.

