اذهب إلى المحتوى

البحث في الموقع

المحتوى عن 'أتمتة'.

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المحتوى


التصنيفات

  • الإدارة والقيادة
  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • السلوك التنظيمي في المؤسسات
  • عالم الأعمال
  • التجارة والتجارة الإلكترونية
  • نصائح وإرشادات
  • مقالات ريادة أعمال عامة

التصنيفات

  • مقالات برمجة عامة
  • مقالات برمجة متقدمة
  • PHP
    • Laravel
    • ووردبريس
  • جافاسكربت
    • لغة TypeScript
    • Node.js
    • React
    • Vue.js
    • Angular
    • jQuery
    • Cordova
  • HTML
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • لغة C#‎
    • ‎.NET
    • منصة Xamarin
  • لغة C++‎
  • لغة C
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • لغة Rust
  • برمجة أندرويد
  • لغة R
  • الذكاء الاصطناعي
  • صناعة الألعاب
  • سير العمل
    • Git
  • الأنظمة والأنظمة المدمجة

التصنيفات

  • تصميم تجربة المستخدم UX
  • تصميم واجهة المستخدم UI
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب GIMP
    • كريتا Krita
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • مقالات DevOps عامة
  • خوادم
    • الويب HTTP
    • البريد الإلكتروني
    • قواعد البيانات
    • DNS
    • Samba
  • الحوسبة السحابية
    • Docker
  • إدارة الإعدادات والنشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
    • ريدهات (Red Hat)
  • خواديم ويندوز
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • شبكات
    • سيسكو (Cisco)

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح
  • مبادئ علم التسويق

التصنيفات

  • مقالات عمل حر عامة
  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • العمل الحر المهني
    • العمل بالترجمة
    • العمل كمساعد افتراضي
    • العمل بكتابة المحتوى

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
    • بريستاشوب
    • أوبن كارت
    • دروبال
  • الترجمة بمساعدة الحاسوب
    • omegaT
    • memoQ
    • Trados
    • Memsource
  • برامج تخطيط موارد المؤسسات ERP
    • تطبيقات أودو odoo
  • أنظمة تشغيل الحواسيب والهواتف
    • ويندوز
    • لينكس
  • مقالات عامة

التصنيفات

  • آخر التحديثات

أسئلة وأجوبة

  • الأقسام
    • أسئلة البرمجة
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات

التصنيفات

  • كتب ريادة الأعمال
  • كتب العمل الحر
  • كتب تسويق ومبيعات
  • كتب برمجة
  • كتب تصميم
  • كتب DevOps

ابحث في

ابحث عن


تاريخ الإنشاء

  • بداية

    نهاية


آخر تحديث

  • بداية

    نهاية


رشح النتائج حسب

تاريخ الانضمام

  • بداية

    نهاية


المجموعة


النبذة الشخصية

تم العثور على 13 نتائج

  1. عند كتابة نص أو مقال ما، فأنت في الأغلب ستضيف له بعض الصور، أو الفيديو أو رسومات لتوضح المحتوى بشكل أكبر. والأغلب أنك ستضيف لكل منه نصا تقوم فيه بشرح مفهوم الصورة، وقد ترغب بترقيم الصور حتى لا يضيع القارئ، وهذا ما سنقوم به عبر استخدام عنصر <figure> مع المُرقمات (counters). عنصر figure إن عنصر <figure> صُمم ليستخدم جنبا إلى جنب مع <figcaption> لاحتواء الصور وما شابه. هذا هو شرح <figure> في وصف لغة HTML الرسمي: هكذا نقوم بإضافة figure : <figure> <img src="path/to/your/image.jpg" alt="" /> <figcaption>Here is the legend for your image<figcaption> </figure> هناك بعض الملاحظات بشأن العنصر: عنصر <figcaption> اختياري. تستطيع استخدام عنصر <figcaption> واحد فقط داخل عنصر <figure>. تستطيع إدراج أيّ عدد تشاء من العناصر داخل <figure>. إذا كنت ستدرج صورة فتستطيع ترك alt فارغة إذا كنت ستدرج <figcaption> حتى لا تقوم برامج قراءة الشاشة بقراءة نفس المحتوى مرّتين. للمزيد من المعلومات حول <figure> ألق نظرة على هذه المصادر: HTML5Doctor Mozilla Developer Network W3C Specification أمثلة: إذا أردت أن تظهر شيفرة برمجية ما، فتستطيع استخدامه بهذه الطريقة: <figure> <code>body { background: white; }</code> <figcaption>Some illustrated code with figure<figcaption> </figure> بدل إدراج صورك بهذه الطريقة: <img src="cute-kitty.jpg" alt="This is a cute kitty!" /> تستطيع إدراجها بهذه الطريقة: <figure> <img src="cute-kitty.jpg" alt="" /> <figcaption>This is a cute kitty!<figcaption> <figure> دعم المتصفحات عنصر <figure> يعتبر من أحد عناصر HTML5 الجديدة، ولذا فهو ليس مدعوما من قبل المتصفحات القديمة (IE 8) ولكن لا أحد يهتم صراحة. ولكن إن كنت مُهتمًا بدعم المُتصفّحات القديمة فتستطيع استخدام html5shiv ليظهر الوسم بشكل عادي. المُرقّمات في CSS أحد أكثر خصائص CSS ديناميكة وأقلها شهرة هي CSS Counter فهي تسمح لك بترقيم العناصر ديناميكيا عبر CSS فحسب، بدون الاستعانة بأيّ شيء آخر. استخدام المرقمات يكون عبر خاصيتين وقيمة وهما: counter-reset والتي تستخدم لتهيئة أو إعادة تهيئة مرقم أو أكثر. counter-increment والتي تستخدم لزيادة قيمة مرقم أو أكثر. ()counter وهي قيمة تستخدمها مع before:: أو after:: والتي تقبل اسم المرقم كقيمة من أجل أن تظهر القيمة. الأمر بسيط. كل ما تقوم به هو تهيئة عدّاد ما بالاسم الذي تريده، ثم تحدد لمجموعة عناصر ما أن تقوم بزيادة تلك القيمة كلنا ظهر أحدها. ويمكن إظهار هذه القيمة عبر CSS باستخدام before:: و after::. مثال بسيط للعداد: /* 1. نقوم بتهيئة المرقم (أو العداد) */ body { counter-reset: thisSuperCoolCounter; } /* 2. نحدد أنه في كل مرة يظهر فيها هذا العنصر نرفع قيمة المرقم */ .myAwesomeElement { counter-increment: thisSuperCoolCounter; } /* 3. نقوم بإظهار قيمة العداد قبل العنصر */ .myAwesomeElement:before { content: counter(thisSuperCoolCounter); } مثال بسيط حسنا نعود للموضوع الأساسي الذي يدور حوله الدرس، نريد ترقيم صورنا حتى تظهر قبلها Fig. 2 – … Fig. 1 – … وهكذا. .article { counter-reset: figures; } .figure { counter-increment: figures; } .figure figcaption:before { content: 'Fig. ' counter(figures) ' - '; } إعداد كل شيء الأساسيات بعد أن فهمنا كيف نستخدم عنصر <figure> وكيف تعمل المرقمات في CSS حان الوقت لاستخدامها في ترقيم الصور. نقوم بإعداد وسم <figure> ببعض الأمور البسيطة: .figure { padding: 0.9em; border: 3px solid #f5bca8; background: #fff; margin: 0 auto 1em; } ثم نريد أن نحاذي الصور في وسط عنصر <figure> ونمنعهم من الخروج عن حجم الحاوي لذا نضيف التالي: .figure img { margin: 0 auto; display: block; max-width: 100%; } الآن بالنسبة لوصف الصّورة (caption) وسنجعلها تبرز أكثر بتوسيطها وجعل الخط بارزًا. فقط تذكر أنّ الهدف من الوصف أن يضيف شرحًا بسيطا، وأن إزالته لن تشكل مشكلة في الفهم فلا داعي لأن تضيف فقرة هناك. .figure figcaption { font-weight: 700; font-size: 0.8em; padding: .5em; text-align: center; color: #fff; background: #f5bca8; } الترقيم حان الوقت لإضافة الترقيم للصور، وإضافته سهلة كما رأينا سابقا. .article { counter-reset: figures; } .figure figcaption { counter-increment: figures; } .figure figcaption:before { content: 'Fig. ' counter(figures) ' - '; } الإضافات البسيطة نريد أن نضيف طريقة سهل لجعل الصور تتمركز على يمين المحتوى أو على يساره، وسنقوم بذلك عبر إضافة التالي: .figure-left { float: left; margin: 0 1em .5em 0; width: -webkit-min-content; width: -moz-min-content; width: min-content; } .figure-right { float: right; margin: 0 0 .5em 1em; width: -webkit-min-content; width: -moz-min-content; width: min-content; } إنّ min-content هي قيمة صحيحة لكل من الخواص التالية min-height min-width max-height max-widthheight width. في حالتنا، نريد من figure أن يكون بأصغر قدر ممكن، أو بالأحرى نريد من عرضه أن يكون هو نفس عرض الصورة التي هي بداخله. لأن figure هو عنصر بحجم كامل (block) فسوف يتمد عرضه إلى كامل الحاوي (100%). نستطيع استخدام float: left أو display: inline-block لجعل عرضه يقل إلى أكبر عنصر داخله، ولكن ماذا سيحدث لو كان الوصف أكبر من حجم الصورة، فستحدث مشكلة. نستطيع أن نحدد عرض العنصر يدويًّا، ولكن الأمر غير منطقي وغير ديناميكي، لهذا استخدمنا قيمة min-content، فهي بكل بساطة تخبر عنصر figure أن يقلل من حجمه إلى حجم الصورة مثال: See the Pen pJLXde by Hsoub Academy (@HsoubAcademy) on CodePen. الخاصية مدعومة من قبل فيرفكس باستخدام -moz- و chrome باستخدام -webkit-. المتصفحات التي لا تدعم الخاصية ستتصرف كما هو متوقع منها، لن يتم تعيين أيّ عرض وسيكون عرضه هو عرض أكبر عنصر داخله. ملاحظة: يوجد قيم أخرى وهي max-content و fit-content و available. اطلع على التوثيق للمزيد من المعلومات. وأخيرًا وليس آخرا، نريد أن نغير أو نحذف العرض الأقصى الذي حددناه للصور التي ستميل لليمين أو لليسار، فإذا أردت أن تأخذ الصور حجمها الطبيعي فاستخدم max-width: none وإذا أردت عرضا أقصى فاستخدم التالي: .figure-right img, .figure-left img { max-width: 300px; /* عدل على حسب حاجتك */ } توافق الشاشات الصغيرة لنتأكد من العناصر التي نحاذيها لا تتصرف بغرابة في شاشات الهواتف الصغيرة سنقوم ببعض التعديلات حتى تأخذ العناصر كامل العرض وتتوسط الصفحة أفقيا: @media (max-width: 767px) { .figure-left, .figure-right { float: none; margin: 0 0 1em 0; width: 100%; } .figure img { max-width: 100%; } } الاستخدام استخدام ما قدمناه شيء بسيط، إما أن تستخدم صورا تستغل كامل المساحة عبر استخدام figure. أو تريد أن تحاذي الصور لليمين أو لليسار فتستخدم كل من figure. وfigure-left. أو figure-right. <figure class='figure'> <img src="path/to/your/image.jpg" alt="" /> <figcaption>Here is the legend for your image<figcaption> </figure> <figure class='figure figure-left'> <img src="path/to/your/image.jpg" alt="" /> <figcaption>Here is the legend for your image<figcaption> </figure> <figure class='figure figure-right'> <img src="path/to/your/image.jpg" alt="" /> <figcaption>Here is the legend for your image<figcaption> </figure> خاتمة هذا كان كل شيء، كل ما تبقى هو أن تطبقها في موقعك، جرب إلقاء نظرة على المثال لترى مثالا عمليا. ترجمة وبتصرّف للمقال: Automatic Figure Numbering with CSS Counters لصاحبه: Hugo Giraudel. جميع حقوق المقال محفوظة لموقع codrops.
  2. يوفر هذا الدرس نظرة عامة على أساسيات نظام تنسيق العناقيد (Cluster orchestration) في Kubernetes. تحتوي كل وحدة على معلومات أساسية عن ميزات ومفاهيم Kubernetes الرئيسية، وتتضمن برنامجًا تعليميًا تفاعليًا عبر الإنترنت. تتيح لك هذه الدروس التفاعلية إدارة عنقود بسيط والتطبيقات العاملة على حاويّات فيه. باستخدام الدروس التفاعلية، يمكنك تعلم ما يلي: نشر تطبيق يعمل ضمن حاوية على عنقود. تحجيم النشر. تحديث التطبيق العامل ضمن حاوية بإصدار جديد من البرنامج. تنقيح التطبيقات العاملة ضمن حاويات. تستخدم البرامج التعليمية منصَّة Katacoda لتشغيل طرفية افتراضية في متصفح الويب يشغّل Minikube، وهو بيئة نشر Kubernetes محلية محدودة الحجم يمكن تشغيلها في أي مكان. لا داعي لتثبيت أي برنامج أو ضبط أي شيء؛ يعمل كل درس تفاعلي مباشرة من متصفح الويب. ما الذي يمكن أن يقدمه لك Kubernetes؟ مع خدمات الويب الحديثة، يتوقع المستخدمون أن تكون التطبيقات متاحة على مدار الساعة طوال أيام الأسبوع، ويتوقع المطورون نشر إصدارات جديدة من هذه التطبيقات عدة مرات في اليوم. يُساعد مفهوم "الحاويات" على تحزيم البرامج لخدمة هذه الأهداف، مما يتيح إصدار التطبيقات وتحديثها بطريقة سهلة وسريعة دون توقف. يساعدك Kubernetes على التأكد من تشغيل هذه التطبيقات الحاوية أينما ومتى تريد، ويساعد في العثور على الموارد والأدوات التي تحتاجها تلك الحاويّات للعمل. Kubernetes هي منصّة مفتوحة المصدر، جاهزة للإنتاج ومصممة بخبرة Google المتراكمة في تنسيق الحاويات، جنبًا إلى جنب مع أفضل الأفكار والممارسات التي يقترحها المجتمع. سننتقل الآن إلى التحدث عن وحدات Kubernetes الأساسية: إنشاء عنقود Kubernetes نشر التطبيق استكشاف التطبيق الإعلان عن التطبيق تحجيم التطبيق تحديث التطبيق 1. استخدام Minikube لإنشاء عنقود Kubernetes عناقيد Kubernetes تنسق Kubernetes عناقيد من الحواسيب عالية التوفّر المتصلة في ما بينها للعمل كوحدة منفردة. تسمح لك التجريدات (Abstractions) في Kubernetes بنشر تطبيقات تعمل ضمن حاويات على عنقود دون ربط الحاويّات بأجهزة مخصوصة. للاستفادة من هذا النموذج الجديد للنشر، يجب تحزيم التطبيقات بطريقة تفصلها عن المضيفات الفردية، أي أنه يجب وضعها في حاويات. التطبيقات العاملة ضمن حاويات أكثر مرونة وتوفّرًا مما كانت عليه في نماذج النشر السابقة، إذ كانت التطبيقات تثبّت مباشرة على أجهزة معينة بصيغة حزم مدمجة شديدة الارتباط بالمضيف. يؤتمت Kubernetes عمليات توزيع حاويّات التطبيقات وجدولتها على عنقود من المضيفات بطريقة أكثر كفاءة. Kubernetes هي منصة مفتوحة المصدر وجاهزة للإنتاج. يتكون عنقود Kubernetes من نوعين من الموارد: القبطان (The Master) الذي ينسق عمل العنقود. العُقَد (Nodes) وهي الموارد العاملة على تشغيل التطبيق. مخطط عنقود القبطان هو المسؤول عن إدارة الدفة. ينسّق القبطان جميع الأنشطة في العنقود، مثل جدولة التطبيقات، والحفاظ على الحالة المرغوبة، وتحجيم التطبيقات، وطرح تحديثات جديدة. العقدة هي آلة افتراضية (VM) أو حاسوب فيزيائي يُستخدم كآلة عاملة في عنقود Kubernetes. تحتوي كل عقدة على Kubelet، وهو وكيل لإدارة العقدة والتواصل مع القبطان. يجب أن تحتوي العقدة أيضًا على أدوات للتعامل مع عمليات الحاوية، مثل Docker أو rkt. يجب أن يحتوي عنقود Kubernetes الذي يتعامل مع حركة البيانات في بيئة إنتاج على ثلاث عقد على الأقل. عندما تنشر تطبيقات على Kubernetes، فأنت تطلب من القبطان تشغيل حاويات التطبيقات. يجدول القبطان الحاويات لتعمل على عقد العنقود. **تتواصل العُقَد مع القبطان باستخدام واجهة تطبيقات Kubernetes التي يبرزها القبطان. يمكن للمستخدمين النهائيين أيضًا استخدام واجهة تطبيقات Kubernetes مباشرةً للتفاعل مع العنقود. يمكن نشر عنقود Kubernetes على الأجهزة الفيزيائية أو الافتراضية على حد السواء. يمكنك بدء التطوير على Kubernetes باستخدام Minikube، وهو إصدار مخفّف من Kubernetes ينشئ آلة افتراضية على جهازك المحلي وينشر عنقودًا بسيطًا يحتوي على عقدة واحدة فقط. يتوفر Minikube لأنظمة لينكس و ماك وويندوز. توفّر طرفية Minikube عمليات التمهيد الأساسية للعمل مع العناقيد، بما في ذلك البدء (Start) والإيقاف (Stop) والحالة (Status) والحذف (Delete). توجد على هذه الصفحة طرفية جاهزة للاستخدام يُثبّت عليها Minikube مسبقا. 2. نشر تطبيق باستخدام kubectl عمليات النشر في Kubernetes يمكن نشر تطبيقات تعمل على حاويّات ضمن منصة Kubernetes بمجرّد توفر عنقود قيد التشغيل. لذا أنشئ إعدادات نشر (Deployment). يوجِّه كائن النشر Kubernetes إلى كيفية إنشاء نظائر (Instances) للتطبيق وتحديثها. يجدول قبطان Kubernetes، بعد إعداد كائن النشر، نظائر التطبيق للعمل على عقد العنقود. تراقب وحدة تحكم (Controller) باستمرار عمل النظائر بعد إنشائها. إنْ تعطلت عقدة مضيفة أو حذفت، فإن وحدة التحكم تستبدلها بعقدة أخرى من العنقود ليعمل عليها التطبيق، ممّا يوفّر آلية للإصلاح الذاتي لمعالجة إخفاق الآلة أو لصيانتها. في عالم ما قبل التنسيق، غالبًا ما كان تُشتخدَم سكربتات تثبيت لبدء التطبيقات، لكن لم توفر الحلول حينئذٍ لاستعادة عمل التطبيق عند إخفاق الآلة. من خلال إنشاء نظائر لتطبيقك والحفاظ على تشغيلها عبر العُقَد، توفر عمليات النشر في Kubernetes نهجًا مختلفًا جذريًا لإدارة التطبيقات. نشر تطبيقك الأول على Kubernetes يمكنك إنشاء عملية نشر وإدارتها باستخدام واجهة سطر أوامر Kubernetes ‏(Kubectl). يستخدم Kubectl واجهة برمجة تطبيقات Kubernetes للتفاعل مع العنقود. في هذا الجزء، ستتعلم أوامر Kubectl الأكثر شيوعًا اللازمة لإنشاء عمليات النشر التي تشغّل تطبيقاتك على عنقود Kubernetes. عندما تنشئ عملية نشر، ستحتاج إلى تحديد صورة حاوية التطبيق وعدد النظائر التي تريد تشغيلها. يمكنك تغيير هذه المعلومات لاحقًا عن طريق تحديث النشر. تناقش النقطتان 5 و 6 من هذا الدرس كيفية تحجيم عمليات النشر وتحديثها. بالنسبة إلى عملية النشر الأولى، ستستخدم تطبيق Node.js معبَّأ في حاوية Docker. (إذا لم تكن قد حاولت بالفعل إنشاء تطبيق Node.js ونشره باستخدام حاوية، فيمكنك القيام بذلك أولاً باتباع الإرشادات من مقال مدخل إلى Kubernetes. 3. استكشاف التطبيق: عرض العناقيد والعُقد الكائنات من نوع Pod عندما أنشأت عملية نشر في الجزء 2 أعلاه، أنشأ Kubernetes كائنًا من نوع Pod لاستضافة نظير من التطبيق. كائنات Pod هي تجريد Kubernetes لتمثيل مجموعة واحدة أو أكثر من حاويات التطبيقات (مثل Docker أو rkt)، إضافة إلى موارد مشتركة بين تلك الحاويات. تشمل تلك الموارد: التخزين المشترك، بصيغة تجزئات (Partitions). الشبكات، مثل عنوان IP فريد لكل عنقود. معلومات حول كيفية تشغيل كل حاوية، مثل إصدار صورة الحاوية أو منافذ معينة لاستخدامها. يصمّم كائن Pod "مضيفًا منطقيًّا" خاصًّا بالتطبيق، ويمكن أن يحتوي على حاويات تطبيق مختلفة مقترنة في ما بينها بإحكام نسبيًا. على سبيل المثال، قد يحتوي الكائن على حاوية تطبيق Node.js بالإضافة إلى حاوية أخرى تغذي البيانات التي سينشرها خادم الويب Node.js الذي يعمل في الحاوية الأولى. تشترك الحاويات الموجودة في كائن واحد عنوانَ IP وفضاء منافذ (Port Space)، كما أنها تشترك دائمًا العقدة والجدولة، وتعمل في سياق مشترك على العقدة نفسها. كائنات Pod هي أصغر وحدة على منصة Kubernetes. عندما تنشئ عملية نشر فإن هذا النشر ينشئ كائنات Pod مع حاويات بداخل الكائن (بدلًا من إنشاء حاويات مباشرة). يرتبط كل كائن Pod بالعقدة التي جُدولت عليها، وتظل هناك حتى الإنهاء (وفقًا لسياسة إعادة التشغيل) أو الحذف. في حالة إخفاق العقدة، تُجدول كائنات Pod متطابقة على العقد الأخرى المتاحة في العنقود. نظرة عامة على كائنات Pod عقد Kubernetes تُشَغَّل كائنات Pod دائمًا على عقدة. العقدة هي آلة عاملة في Kubernetes وقد تكون إما آلة افتراضية أو فيزيائية، حسب العنقود. يدير القبطان كل العُقد. يمكن أن تحتوي العُقدة على عدة كائنات Pod. يتولّى القبطان في Kubernetes جدولة كائنات Pod تلقائيًا على عقد العنقود. تأخذ الجدولة التلقائية من طرف القبطان في الاعتبار الموارد المتاحة لكل عقدة. تُشغِّل كل عقدة Kubernetes على الأقل: Kubelet، عملية مسؤولة عن التواصل بين القبطان و العُقدة؛ تُدير كائنات Pod والحاويات التي تعمل على الجهاز. بيئة تشغيل حاويات (مثل Docker وrkt) مسؤولة عن سحب صورة الحاوية من تقييد (Registry)، فك ضغط الحاوية، وتشغيل التطبيق. نظرة عامة على العقد استكشاف الأخطاء وإصلاحها باستخدام kubectl تحدّثنا في الجزء 2 أعلاه عن واجهة سطر الأوامر kubectl. سنستمر في الحديث عنه في هذا الجزء للحصول على معلومات حول التطبيقات المنشورة وبيئاتها. يمكن تنفيذ العمليات الأكثر شيوعًا باستخدام أوامر kubectl التالية: kubectl get - سرد الموارد. kubectl describe - عرض معلومات تفصيلية حول مورد. kubectl logs - طباعة السجلات من حاوية في كائن Pod. kubectl exec - تنفيذ أمر على حاوية في كائن Pod. يمكنك استخدام هذه الأوامر لمعرفة متى نُشرت التطبيقات، وما حالاتها الراهنة، وأين تعمل وما إعداداتها. الآن بعد أن عرفنا المزيد عن مكونات المجموعة لدينا وسطر الأوامر، دعنا نستكشف تطبيقنا. توجد على هذا الرابط بيئة تفاعلية لعرض العناقيد والعقد واستكشاف أوامر kubectl. 4. الإعلان عن التطبيق للعموم استخدام خدمة للإعلان عن التطبيق الخاص بك نظرة عامة على خدمات Kubernetes كائنات Pod في Kubernetes فانية. وهي في الواقع لها دورة حياة. عند توقّف عقدة عاملة تفقد كل كائنات Pod التي تعمل كانت تعمل على العقدة. قد تعيد وحدة التحكم ReplicaSet بعد ذلك العنقود ديناميكيًّا إلى الحالة المرغوبة من خلال إنشاء كائنات Pod جديدة للحفاظ على تشغيل التطبيق الخاص بك. مثال آخر، فلنفترض سندًا (Backend) لمعالجة الصور مع ثلاث حاويّات متماثلة. هذه النسخ المتماثلة قابلة للاستبدال؛ يجب ألا يهتم نظام الواجهة الأمامية بالنسخ المتماثلة للسند أو حتى في حالة فقد كائن Pod وإعادة إنشائه. ومع ذلك، فإن كل كائن Pod في عنقود Kubernetes له عنوان IP فريد، حتى الكائنات على العقدة نفسها. لذا يجب أن تكون هناك طريقة للتوفيق بين التغييرات تلقائيًا بين كائنات Pod حتى تستمر تطبيقاتك في العمل. الخدمة في Kubernetes عبارة عن تجريد يعرّف مجموعة منطقية من كائنات Pod وسياسة للوصول إليها. تتيح الخدمات اقترانًا فضفاضًا بين كائنات Pod المترابطة في ما بينها. تُعرّف الخدمة باستخدام YAML (وهي الوسيلة المفضّلة) أو JSON، مثل جميع كائنات Kubernetes. عادةً ما تُحدّذ مجموعة كائنات Pod التي تستهدفها الخدمة بواسطة كائن من النوع LabelSelector (انظر أدناه لمعرفة الحالات التي قد تدعوك لإنشاء خدمة بطريقة مغايرة). على الرغم من أن كل كائن Pod لديه عنوان IP فريد، إلّا أنّ تلك العناوين لا تُعرَض خارج العنقود بدون خدمة. تسمح الخدمات لتطبيقاتك بتلقي حركة المرور. يمكن الإعلان عن الخدمات بطرق مختلفة عن طريق تحديد النوع type في ServiceSpec: ClusterIP (قيمة افتراضية): يعرض الخدمة على عنوان IP داخلي في العنقود. يجعل هذا النوع الوصول للخدمة متاحًا فقط من داخل العنقود. NodePort: يعرض الخدمة على نفس المنفذ لكل عقدة محددة في العنقود باستخدام ترجمة عناوين الشبكة (NAT). يتيح الوصول إلى خدمة من خارج العنقود باستخدام عنوان IP العنقود ورقم المنفذ (<NodeIP>:<NodePort>). امتداد للطريقة السابقة (ClusterIP). LoadBalancer : ينشئ موازن حِمْل خارجي في السحابة الحالية (إذا كانت تدعم ذلك) ويعين عنوان IP ثابتًا خارجيًا للخدمة. امتداد للطريقة السابقة (NodePort). ExternalName: يُعلن عن الخدمة باستخدام اسم عشوائي (محدد بواسطة القيمة externalName في المواصفات spec) عن طريق إرجاع سجل CNAME يتضمّن الاسم. لا يُستخدَم أي وكيل (Proxy). يتطلب هذا النوع الإصدار v1.7 أو أعلى من حزمة kube-dns. يمكن العثور على مزيد من المعلومات حول الأنواع المختلفة من الخدمات في الدرس التالي، وأيضًا من خلال هذا المقال. بالإضافة إلى ذلك، يُرجى ملاحظة أن هناك حالات استخدام لا تتضمن فيها الخدمات تحديد حقل selector في المواصفات (spec). لن تنشئ الخدمة في تلك الحالة الكائن الطرفي (Endpoint object) المقابل، وهو ما يسمح للمستخدمين بالتعيين اليدوي للنقاط الطرفية للخدمة. توجد إمكانية أخرى لعدم وجود حقل selector وهي أنك تستخدم النوع ExternalName. الخدمات واللصائق (Labels) توجّه الخدمة البيانات عبر مجموعة من كائنات Pod. الخدمات هي طبقة تجريد تسمح بزوال كائنات Pod وتكرارها دون التأثير على عمل التطبيق في بيئة Kubernetes. تتولّى خدمات Kubernetes اكتشاف كائنات Pod المترابطة (مثل تطبيق يتكوّن من سند وواجهة أمامية) والتوجيه بينها. تتعرّف الخدمات على كائنات Pod المترابطة من خلال المحدّدات واللصائق (Selectors and Labels). المحدّدات هي دوال للتجميع تسمح بإجراء عمليات منطقية على كائنات Kubernetes، أمّا اللصائق فهي أزواج مفاتيح وقيم (Key/Value) مرفقة بالكائنات، ويمكن استخدامها بأي واحدة من الطرق التالية: تعيين كائنات للتطوير والاختبار والإنتاج، تضمين وسوم الإصدار، تصنيف كائن حسب الوسوم. يمكن إرفاق التسميات أو اللصائق (label) بالكائنات في وقت الإنشاء أو لاحقا. يمكن تعديلها في أي وقت. تجربة تفاعلية لعرض التطبيق للعموم باستخدام خدمات Kubernetes. 5. تحجيم التطبيق تشغيل نُسَخ متعددة للتطبيق رأينا أعلاه كيفية إنشاء عملية نشر (Deplyment)، ثم كيفية الإعلان عنها للعموم عبر خدمة. أنشأت عملية النشر كائن Pod واحدًا لتشغيل التطبيق. عندما تزداد حركة البيانات، سنحتاج إلى تحجيم (Scaling) التطبيق لمواكبة طلب المستخدم. يتحقّق التحجيم عن طريق تغيير عدد النظائر المنشورة. نظرة عامة على التحجيم سيضمن تحجيم النشر إنشاء كائنات Pod جديدة وجدولتها على العقد ذات الموارد المتاحة. سيؤدي التحجيم إلى زيادة عدد كائنات Pod إلى الحالة المرغوبة الجديدة. يدعم Kubernetes أيضًا التحجيم التلقائي Autoscaling لكائنات Pod، ولكنّ ذلك خارج نطاق هذا الدرس. التحجيم باتجاه الصفر ممكن أيضًا، وسيؤدي إلى إنهاء جميع كائنات Pod في عملية النشر المحددة. يتطلب تشغيل نسخ متعددة من تطبيق ما طريقة لتوزيع حركة البيانات عليها جميعا. تتضمّن الخدمات موازِن حِمل متكامل من شأنه أن يوزِّع البيانات المارة في الشبكة على جميع كائنات Pod الموجود ضمن نشر متاح للعموم. تراقب الخدماتُ كائنات Pod العاملة باستمرار باستخدام النقاط الطرفية لضمان إرسال البيانات إلى كائنات Pod المتاحة فقط. بمجرد أن يكون لديك نُسَخ متعددة للتطبيق قيد التشغيل، ستتمكن من دحرجة التحديثات دون توقف. سنغطي ذلك في الأجزاء التالية، وهو ما سنراه في الجزء اللاحق. يمكنك تجربة تحجيم التطبيق (بتوسيعه أو تقليصه) عبر هذه الطرفية التفاعلية. 6. تحديث التطبيق التحديث المتدحرج (Rolling update) يتوقع المستخدمون أن تكون التطبيقات متاحة طوال الوقت، ويُنتظر من المطورين أن ينشروا إصدارات جديدة منها عدة مرات في اليوم. في Kubernetes يتم ذلك عن طريق التحديثات المتدحرجة. تسمح التحديثات المتدحرجة بتحديث عمليات النشر دون توقف عن طريق التحديث التدريجي بإحلال كائنات Pod جديدة تدريجيًّا مكان الكائنات الحالية. تُجدول كائنات Pod الجديدة على العُقد التي لديها موارد متاحة. تحدّثنا في الجزء السابق عن تحجيم التطبيق لتشغيل نُسَخ متعددة. هذا الأمر مطلوب لإجراء التحديثات دون التأثير على توفر التطبيق. افتراضيًّا، الحد الأقصى لعدد كائنات Pod التي يمكن أن تكون غير متاحة ولعدد كائنات Pod الجديدة التي يمكن إنشاؤها أثناء التحديث، هو واحد. يمكن ضبط كل واحد من الخيارين إما بالأرقام أو بالنسب المئوية (من كائنات Pod). تؤصدر (Versioned) التحديثات في Kubernetes، ويمكن التراجع عن أي تحديث نشر إلى إصدار سابق (مستقر). نظرة عامة على التحديثات المتدحرجة على غرار تحجيم التطبيق، إذا كان النشر متاحًا للعموم، فإن الخدمة ستوازن حركة البيانات فقط بين كائنات Pod المتاحة أثناء التحديث. كائن Pod متاح هو نظير متوفّر لمستخدمي التطبيق. تسمح التحديثات المتدحرجة بالإجراءات التالية: نقل تطبيق من بيئة إلى أخرى (عبر تحديثات صورة الحاوية). التراجع إلى إصدارات سابقة. التكامل المستمر والتوصيل المستمر للتطبيقات بدون توقف. يمكن استخدام هذه النافذة التفاعلية لاختبار تحديث تطبيق إلى إصدار جديد والتراجع عن ذلك. ترجمة - وبتصرّف - لأجزاء kubernetes basics من توثيق Kubernetes.
  3. 1. مقدمة عن نظام بناء Gradle 1.1. ما هو نظام بناء Gradle Gradle هو نظام بناء إداري للأغراض العامة. يدعم Gradle التنزيل والضبط التلقائي للتبعيات Dependencies أو المكتبات الأخرى. ويدعم مستودعات Maven و Ivy لاستعادة هذه التبعيات. يدعم Gradle المشروع المُتعدد والبناءات ذات النواتج المتعددة. 1.2. المشاريع والمهام في Gradle يتم وصف بناءات جرادل (Gradle Builds) عبر ملف واحد أو عدة ملفات build.gradle متعددة. يوجد عادةً (ملف بناء Build File) واحد على الأقل في المجلد الأصلي للمشروع. يُعرِّف كل ملف بناء مشروعًا ومهامًا لهذا المشروع. تنقسم المشروعات إلى نوعين: شيء يجب بناؤه شيء يجب القيام به ويتكون المشروع من مهام Tasks. تمثل المهمة Task جزءًا من العمل الذي تؤديه أحد الأبنية Builds، على سبيل المثال، تجميع التعليمات البرمجية المصدر (Compile the source code) أو إنشاء Javadoc. تستند ملفات البناء هذه إلى لغة ذات مجال مخصص (Domain Specific Language - DSL).في هذا الملف، يمكنك استخدام مجموعة من التعليمات التصريحية والضرورية (declarative and imperative statements). تستطيع كتابة كود Groovy أو Kotlin متى احتجت إلى ذلك. يمكنك أيضًا إنشاء المهام وتوسيعها ديناميكيًا في وقت التشغيل Runtime. تمثل القائمة التالية ملف بناء بسيط للغاية. task hello { doLast { println 'Hello Gradle' } } لتنفيذ المهمة hello في ملف البناء، اكتب gradle hello في سطر الأوامر في مجلد ملف البناء. إذا اختفى ناتج جرادل Gradle Output، يُمكنك استخدام q- كـ (quiet parameter). gradle hello # alternative add the -q flag gradle -q hello 1.3 التعليقات في ملفات بناء Gradle يُمكنك استخدام التعليقات الفردية والمتعددة الأسطر في ملفات بناء Gradle كما يلي: // تعليق على سطر واحد /* تعليق على أسطر متعددة */ 1.4. إعدادات المشروع والوصف بشكل افتراضي، يستخدم Gradle اسم ال (Directory Name) كاسم مشروع. يمكنك تغيير هذا عن طريق إنشاء ملف settings.gradle في الدليل الذي يُحدد اسم المشروع. rootProject.name ='com.vogella.gradle.first' يمكنك أيضًا إضافة وصف لمشروعك عبر ملف build.gradle: description =""" Example project for a Gradle build Project name: ${project.name} More detailed information here... """ task hello { doLast { println 'Hello Gradle' } } استخدم الأمر gradle project للحصول على معلومات حول مشروعك. تظهر القائمة التالية الناتج. :projects ------------------------------------------------------------ Root project - Example project for a Gradle build Project name: com.vogella.gradle.first More detailed information here... ------------------------------------------------------------ Root project 'com.vogella.gradle.first' - Example project for a Gradle build Project name: com.vogella.gradle.first More detailed information here... No sub-projects To see a list of the tasks of a project, run gradle <project-path>:tasks For example, try running gradle :tasks BUILD SUCCESSFUL Total time: 1.048 secs 2. مكونات Gradle الإضافية (Gradle Plug-ins) يستخدم نظام بناء Gradle مكونات إضافية أو إضافات (Plug-ins) لزيادة وظائفه الأساسية. المكوّن الإضافي هو توسيع لعمل لـ Gradle يضيف عادة بعض المهام المُعدّة مسبقًا. يأتي Gradle مع عدد من المكونات الإضافية، ويمكنك تطوير مكونات إضافية مخصصة. مثال على ذلك هو مُكوِّن جافا الإضافي (Java Plug-in). يُضيف هذا المكوّن الإضافي مهامًا إلى مشروعك والتي تسمح بترجمة شيفرة جافا المصدرية (Java Source Code)، وتشغيل اختبارات الوحدة وإنشاء ملف JAR. يتواجد المكون الإضافي في ملف build.gradle مع التعليمة البرمجية 'apply plugin:'pluginname . على سبيل المثال، الأمر التالي يجعل المكون الإضافي لنظام Android متاحًا لإنشاء Gradle: apply plugin: 'com.android.application' يوفر Gradle أيضًا سجلًا للمكونات الإضافية عبر المكوِّن الإضافي الخاص بالبحث في Gradle والمُسمى بـ Gradle Plugin Search. 2.1. دعم بيئة تطوير متكاملة IDE لـ Gradle. تقوم شركة Gradleware بتطوير برنامج Eclipse Gradle التعليمي عبر مشروع Eclipse Buildship. تتضمن البيئات التطويرية المتكاملة الأخرى IDEs مثل IntelliJ و Android Studio دعمًا جيدًا لـ Gradle. تثبيت وتهيئة Gradle 2.2. المتطلبات يتطلب استخدام Gradle تثبيت عدّة تطوير جافا (JDK (Java Development Kit. 2.3. تحميل واستخراج Gradle يمكن العثور على أحدث إصدار من Gradle على صفحة تنزيل جرادل Gradle Download Page. قم بتنزيل أحدث توزيع متكامل. إنها gradle-${version}-all.zip، حيث تعبّر {version}$ عن الإصدار الحالي. استخرج محتويات الملف المضغوط الذي قمت بتنزيله في مجلد جديد. 2.4. تثبيت Gradle على الويندوز أضف هذا المُجلد الجديد، الذي استخرجت فيه محتويات Gradle في الخطوة السابقة، إلى مُتغير البيئة PATH. بالضغط على Win + Pause، يمكنك فتح إعدادات النظام. أولًا قم باختيار Advanced System Settings، ثم اضغط على زر Environment Variables كما هو موضّح. في نافذة متغيرات البيئة، يجب تعيين متغيرات المستخدم JAVA_HOME و GRADLE_HOME. بعد ذلك، اختر المدخل PATH في (متغيرات النظام System Variables). ثم اضغط على زر التعديل Edit لإضافة ملف bin الخاص بتثبيت Gradle إلى المسار PATH. 2.5. تثبيت Gradle على لينكس/ماك 2.5.1 التثبيت اليدوي يجب أن يشير متغير JAVA_HOME إلى jdk مناسب ويجب أن يكون JAVA_HOME/bin$ جزءًا من متغير بيئة PATH. أضف Gradle إلى المسار عن طريق تنفيذ السطر الآتي في Terminal: export PATH=/usr/local/gradle/FOLDER_TO_WHICH_YOU_EXTRACTED_GRADLE/bin:$PATH 2.5.2 التثبيت مع SDKMAN! SDKMAN! هي أداة سطر أوامر تتيح لك تثبيت إصدارات Gradle المتعددة والتبديل بينها. يتم تشغيله على أي نظام تشغيل يستند إلى UNIX. تثبيت SDKMAN! يمكنك تثبيته من سطر الأوامر. إذا كنت قد قمت بالفعل بتثبيت SDKMAN! يمكنك تخطي هذه الخطوة. curl -s "https://get.sdkman.io" | bash بعد تثبيت SDKMAN! يجب عليك إعادة تشغيل الجهاز قبل استخدامه. تثبيت Gradle وإعداد الإصدار الافتراضي sdk install gradle 6.2.1 sdk default gradle 6.2.1 gradle -v تبديل إصدار Gradle sdk install gradle 6.2.1 # use 6.2.1 for current terminal session sdk use gradle 6.2.1 gradle -v 2.5.3. تحقق من نجاح تثبيت Gradle افتح سطر أوامر واكتب gradle، وسيتم تشغيل المهمة المساعدة الخاصة بـ Gradle بشكل افتراضي. تنبيه: قد يختلف الإصدار المتوافر حاليًا أثناء قراءتك للمقال عن الإصدار المستعمل أثناء ترجمة المقال، لذا نرجو التأكد من هذه النقطة من موقع Gradle الرسمي قبل الاستمرار، فقد يكون هنالك بعض الإختلافات والتحديثات التي أضيفت على أحدث إصدار Gradle عن الإصدارات السابقة. 2.6. استخدام البرنامج الخفي Gradle لتحسين وقت بدء التشغيل يسمح Gradle لنفسه بالبدء كـبرنامج خفي لتجنب بدء تشغيل جهاز جافا الظاهري Java Virtual Machine لكل بنية. لتكوين ذلك: أنشئ ملف يسمى gradle.properties في HOME}/.gradle}$ وإضافة السطر التالي إليه: org.gradle.daemon=true يمكنك أيضًا وضع ملف gradle.properties في المجلد الأصلي لمشروعك وإلزامه بنظام التحكم في الإصدار Control Version System. إذا لم يتم استخدام Gradle لبضع ساعات ، فإن البرنامج الخفي يتوقف تلقائيًا. بتنفيذ Gradle مع الوسيط daemon-- في سطر الأوامر يبدأ البرنامج الخفي gradle. لإيقاف البرنامج الخفي بشكل تفاعلي، استخدم الأمر gradle --stop. 2.7. حدد إعدادات JVM المخصصة لـ Gradle يوفر متغير البيئة GRADLE_OPTS الفرصة لتعيين خيارات JVM محددة لـ Gradle. في استخدام البرنامج الخفي Gradle لتحسين وقت بدء التشغيل، تم تحسين أداء بدء التشغيل JVM، لكن (قاتل الأداء Performance Killer) الآخر للبنيات الكبيرة يمكن أن يكون الحد الأقصى لـ(مساحة كومة heap space) صغيرة جدا. لذلك من المنطقي زيادته في Gradle. يُعرِّف export GRADLE_OPTS=-Xmx1024m أن Gradle يمكنه استخدام 1 غيغابايت كحد أقصى لحجم الكومة. في نظام التشغيل Windows، عادةً ما يتم تعريف متغيرات البيئة عن طريق واجهة مستخدم خاصية النظام. إذا كنت ترغب في ضبط إعدادات JVM على المستوى العالمي ولكن على أساس كل مشروع، أضف إلى الملف ‎/gradle.properties السطر التالي: org.gradle.jvmargs=-Xms2g -Xmx4g -XX\:MaxHeapSize\=3g 2.8. ملف ‎.gitignore النموذجي لمشاريع Gradle إذا كنت تستخدم Git كنظام للتحكم في الإصدار، فيمكنك استخدام ملف gitignore. التالي كقالب لمشروع Gradle. # Android built artifacts *.apk *.ap_ *.dex # Java build artifacts class files *.class # other generated files bin/ gen/ build/ # local configuration file (for Android sdk path, etc) local.properties # OSX files .DS_Store # Eclipse project files .classpath .project # Android Studio *.iml .idea .gradle #NDK obj/ 3. تمرين: إنشاء مشروع Java باستخدام سطر أوامر Gradle يوفر Gradle دعمًا للسقالات Scaffolding Support لإنشاء مشاريع تستند إلى Gradle عبر سطر الأوامر. قم بإنشاء مجلد جديد new directory على نظام الملفات الخاص بك، وانتقل إليه وقم بتشغيل الأمر التالي. gradle init --type java-library --test-framework junit-jupiter يؤدي هذا إلى إنشاء مشروع Java يستند إلى Gradle والذي يستخدم JUnit Jupiter لاختبار الوحدة Unit Testing. يمكنك تشغيل البناء build عبر: gradle build والاختبار الناتج عن هذا البناء عبر: gradle test سيقوم Gradle بإنشاء تقرير اختبار في مجلد /build/reports/tests/test 4. تمرين: تكوين خصائص Gradle عند استخدام أمر gradle للمرة الأولى، يتم إنشاء مجلد gradle. في الدليل {USER_HOME}$. عادة ما يكون home/${yourUserName}/.gradle/ على نظام Linux. بينما يكون C:\Users\${yourUserName}.gradle على نظام Windows. أما على نظام MAC فيكون /Users/${yourUserName}/.gradle. داخل مجلد gradle. هذا، يجب إنشاء ملف gradle.properties مع المحتويات التالية: org.gradle.warning.mode=all الآن سيتم تجاوز الافتراض لخاصية org.gradle.warning.mode (الافتراض هو الملخص). 5. إدارة التبعية لمشاريع جافا 5.1. إدارة التبعيات باستخدام Gradle يسمح Gradle بإدارة classpath من المشاريع الخاصة بك. يمكنه إضافة ملفات JAR أو أدلة أو مشاريع أخرى إلى مسار إنشاء التطبيق الخاص بك. كما يدعم التنزيل التلقائي لتبعيات مكتبة Java. ما عليك سوى تحديد التبعية في ملف بناء Gradle الخاص بك. مما يجعل Gradle يقوم بتنزيل المكتبة بما في ذلك التبعيات العابرة لها أثناء الإنشاء. يتم تحديد مكتبة Java بواسطة Gradle عبر groupId:artifactId:version الخاص بمشروعها (ويُعرف أيضًا باسم GAV في Maven). تحدد هذه الـGAV مكتبة بشكل فريد في إصدار معين. يمكنك استخدام موقع Maven للبحث عن GAV المكتبة في Maven Central. لإضافة تبعية، قم بإضافة إدخال إلى قسم التبعية في ملف build.gradle الخاص بك كما هو موضح في القائمة التالية. dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.squareup.okhttp:okhttp:2.5.0' testCompile 'junit:junit:4.12' } 5.2. تحديد المستودعات للبحث عن التبعيات في ملف البناء الخاص بك، يمكنك تحديد المستودعات البعيدة للبحث عن التبعيات. يدعم Gradle مستودعات Maven و Ivy للبحث عن التبعيات. توضح القائمة التالية كيفية تكوين Maven central كمصدر تبعية. repositories { mavenCentral() } من الممكن أيضًا تكوين الهدف كعنوان URL: repositories { maven { url "http://repo.mycompany.com/maven2" } } توضح القائمة التالية كيفية تحديد تبعية Ivy: repositories { ivy { url "http://repo.mycompany.com/repo" } } يمكنك أيضًا إضافة مستودعات مختلفة مرة واحدة. repositories { maven ("https://repository-achartengine.forge.cloudbees.com/snapshot/") jcenter { url "http://jcenter.bintray.com/" } } يمكنك أيضًا الرجوع إلى الملفات التي ينتجها المشروع من نظام الملفات. apply plugin: 'java' repositories { mavenCentral() } dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+' runtime files('libs/library1.jar', 'libs/library2.jar') runtime fileTree(dir: 'libs', include: '*.jar') compile fileTree(dir: "${System.properties['user.home']}/libs/cargo", include: '*.jar') } } 5.3. إظهار تبعيات المشروع (التبعيات العابرة أيضًا) يعرض الأمر التالي جميع التبعيات العابرة لمشروع Gradle: gradle dependencies 5.4. ذاكرة التخزين المؤقت لـ Gradle وحذف ذاكرة التخزين المؤقت يمكنك تحديث التبعيات في ذاكرة التخزين المؤقت مع خيار سطر الأوامر refresh-dependencies--. يمكنك أيضًا حذف الملفات المخزنة مؤقتًا ضمن gradle/cache./~ مع البناء القادم (next build)، يحاول Gradle تنزيل التبعيات مرة أخرى. 5.5.استثناء التبعيات المتعدية في بعض الأحيان يكون لديك تبعيات على الحزم Packages التي تحدد التبعيات العابرة المتعارضة. أحد الحلول هو استبعاد التبعية من وحدة نمطية محددة: compile 'org.springframework:spring-web:4.3.10.RELEASE' { exclude group: 'com.google.code.gson', module: 'gson' } إذا كان لديك تبعية متعددة تحدد تبعية تريد استبعادها، فيمكنك القيام بذلك على مستوى المشروع: configurations.all { exclude group: 'com.google.code.gson', module: 'gson' } باتباع نفس النهج، يمكننا استبعاد التبعية فقط أثناء وقت التشغيل runtim: configurations.runtime { exclude group: 'com.google.code.gson', module: 'gson' } 5.6. فرض إصدار محدد من تبعية متعدية من الممكن إجبار gradle على اختيار إصدار معين عندما يواجه التبعيات العابرة المتعارضة. ضع في اعتبارك أنه قد تضطر إلى تحديث هذا الإصدار يدويًا عندما تقوم بتحديث الحزم التي تعتمد عليه. configurations.all { resolutionStrategy.force 'com.google.code.gson:gson:2.8.1' } 6. تشغيل بناء Running a build عند بدء إنشاء Gradle عبر سطر الأوامر، تبحث أداة أمر gradle عن ملف يسمى build.gradle في الدليل الحالي. يدعم Gradle أيضًا اختصار المهام، على سبيل المثال، لبدء تشغيل المهمة lars، فإنّ استخدام أمر gradle l يكفي. يجب على الاختصار أن يحدد المهمة بشكل فريد، وإلا سيُظهر Gradle رسالة خطأ، توضح أن الاختصار غامض. يمكن أيضًا استخدام CamelCase للاختصار، على سبيل المثال، يمكن استدعاء المهمة gradle vogellaCompany باستخدام الأمر gradle vC. يمكن تشغيل بناء Gradle عبر الأمر gradle أو gradle -q. الوسائط q- أو quiet-- تجعل تنفيذ Gradle أقل طولًا. يمكن معالجة مهمة محددة كالتالي: gradle -q other، والتي تنفذ المهمة "الأخرى. يمكنك بالطبع أيضًا استخدام السكربت المجمع the Gradle wrapper script، إذا كان ذلك متاحًا. لتحديد ملف بناء مختلف، يمكن استخدام الخيار b buildFileName-. في السيناريوهات التي لا يتوفر فيها اتصال بشبكة، يمكن استخدام المعاملoffline--. يعمل هذا على تشغيل Gradle build دون الاتصال بالإنترنت، مما يعني أن Gradle لا يحاول الوصول إلى الموارد من الشبكة أثناء الإنشاء. على سبيل المثال، للتبعيات من مستودع إنتاج مثل Maven Central أو Bintray. للحصول على ناتج تفصيلي لما يقوم به Gradle، يمكنك تحديد المعامل info--. 7. مهام Gradle 7.1. مهام Gradle الافتراضية يقدم Gradle أيضًا مهامًا لاستكشاف Gradle نفسه، حيث يمكنك تحليل مشروع Gradle باستخدام مهام Gradle الافتراضية. مثال جيد هو مهمة المهام، والتي تعرض المهام المتاحة للمشروع. عند كتابة gradle -q tasks، يتم عرض قائمة بالمهام. يسرد هذا الأمر المهام الأساسية حتى بدون ملف build.gradle. يحاول Gradle أيضًا إعطاء بعض الإرشادات لاستخدام المهام التي تم استدعاؤها، كما هو موضح في الجزء السفلي من إخراج وحدة التحكم. سيقوم الأمر gradle tasks --all أيضًا بسرد المهام التابعة، والتي يتم استدعاؤها قبل المهمة الفعلية. عند تشغيل gradle tasks --all يبدو الناتج مشابهًا تمامًا للملف السابق، باستثناء مهمة init التي تعتمد على المهمة wrapper. 7.2. إنشاء مهام Gradle مخصصة في جزء gradle_runbuild_buildfile، تم إنشاء أول مهمة بسيطة في ملف build.gradle task hello { doLast { println 'Hello Gradle' } } عند تشغيل مهمة مهام gradle -q tasks مع ملف build.gradle هذا، سيتم سرد مهمة hello ضمن "مهام أخرى Other Tasks". تعتبر المهام بدون مجموعة مهام خاصة. على سبيل المثال، لا تُظهر طريقة العرض Gradle Task View الخاصة بـ Eclipse Gradle Plug-in مثل هذه المهام. ولكن يمكن إظهارها عن طريق تنشيط الإدخال الصحيح في قائمة العرض. يمكن تطبيق المجموعات عن طريق خاصية المجموعة group ويمكن تطبيق وصف باستخدام خاصية الوصفdescription. في حالة وجود المجموعة بالفعل، تتم إضافة مهمة hello إليها. إذا كانت المجموعة غير موجودة، فهي موجودة مُسبقًا. task hello { group 'vogella' description 'The hello task greets Gradle by saying "Hello Gradle"' doFirst { println 'Hello Gradle' } doLast { println 'Bye bye Gradle' } } 7.3. هيكل المهمة Task Structure Gradle له مراحل مختلفة، عند العمل مع المهام. بادئ ذي بدء، هناك مرحلة التكوين، حيث يتم تنفيذ الكود، المحدد مباشرة في إغلاق المهمة. يتم تنفيذ كتلة التكوين لكل مهمة متوفرة وليس فقط لتلك المهام، والتي يتم تنفيذها فعليًا فيما بعد. بعد مرحلة التكوين، تقوم مرحلة التنفيذ بعد ذلك بتشغيل الكود داخل عمليات إغلاق doFirst أو doLast لتلك المهام، والتي تم تنفيذها بالفعل. task onlySpecifiesCodeForConfigurationPhase { group 'vogella' description 'Configuration phase task example.' println 'I always get printed even though, I am not invoked' } task anotherUnrelatedTask { doLast { println 'I am in the doLast execution phase' } } عند تنفيذ gradle -q anotherUnrelatedTask، تتم طباعة ما يلي: I always get printed even though, I am not invoked I am in the doLast execution phase تأتي العبارة الأولى من مرحلة التكوين التي يتم فيها تقييم تعريف المهمة onlySpecifiesCodeForConfigurationPhase. 7.4. تبعيات مهمة Task Dependencies يسمح Gradle بتعريف المهام الافتراضية في ملف البناء. يتم تنفيذ هذه، إذا لم يتم تحديد مهام أخرى. يمكن للمهام أيضًا تحديد تبعياتها. كلا الإعدادات موضحة في ملف البناء التالي. defaultTasks 'clean', 'compile' task clean { doLast { println 'Executing the clean task' } } task compile { doLast { println 'Executing the compile task' } } task other(dependsOn: 'compile') { doLast { println "I'm not a default task!" } } task cleanOther { doLast { println "I want to clean up before running!" } } cleanOther.dependsOn clean, compile يمكن أيضًا تنفيذ ارتباطات تنفيذ المهام المحددة مسبقًا للمهام الافتراضية أو المهام من المكونات الإضافية Plug-ins باستخدام طريقة dependOn. على سبيل المثال، عندما يَتعيّن القيام ببعض الأشياء مباشرة بعد تجميع كود جافا: apply plugin: 'java' task invokedAfterCompileJava(dependsOn: 'compileJava') { doLast { println 'This will be invoked right after the compileJava task is done' } } كبديل لإنشاء مهمة جديدة، والتي تعتمد على مهمة 'compileJava'، يمكن أيضًا تطبيق كتلة تنفيذ جديدة مباشرة على مهمة موجودة، على سبيل المثال، المهمة 'compileJava': apply plugin: 'java' compileJava.doFirst { println 'Another action applied to the "compileJava" task' } compileJava.doLast { println 'Another doLast action is also applied' } عند تشغيل المهمة 'javaCompile'، يتم تنفيذ جميع الإجراءات، التي تم تطبيقها على المهمة javaCompile، واحدة تلو الأخرى وفقًا للترتيب الذي تم تطبيقه على المهمة. 7.5. تخطي مهام Skipping Tasks يمكن تخطي المهام عن طريق تمرير إغلاق مُسند predicate closure إلى طريقة onlyIf الخاصة بالمهمة أو عن طريق طرح StopExecutionException: task eclipse { doLast { println 'Hello Eclipse' } } // #1st approach - closure returning true, if the task should be executed, false if not. eclipse.onlyIf { project.hasProperty('usingEclipse') } // #2nd approach - alternatively throw an StopExecutionException() like this eclipse.doFirst { if(!usingEclipse) { throw new StopExecutionException() } } 7.5.1. الوصول إلى متغيرات النظام مثل دليل المستخدم الرئيسي يمكنك الوصول إلى متغيرات النظام. على سبيل المثال، للحصول على دليل المستخدم الرئيسي، استخدم ما يلي: def homePath = System.properties['user.home'] 8. تمرين: مهام Gradle 8.1. استخدام مهمة المهام في Gradle الهدف من هذا التمرين هو الحصول على نظرة عامة حول المهام الافتراضية، والتي يتم تسليمها افتراضيًا. افتح سطر الأوامر وقم بتنفيذ الأمر التالي: gradle -q tasks 8.2. استخدام المهمة help الهدف من هذا التمرين هو الاستفادة من المهمة help المساعدة للحصول على مزيد من المعلومات حول المهام الأخرى، مثل مهمة init. gradle -q help --task init 8.3. إنشاء مشروع Groovy التمرين السابق على علم باستخدام المهمة init: gradle -q init --type groovy-library 8.4. اختياري - إدخال مشروع Groovy جديد يمكن استخدام Eclipse Buildship لإدخال المشروع إلى Eclipse IDE. 8.5 . استخدام مهمة التبعيات من أجل رؤية تبعيات المشروع (بما في ذلك التبعيات)، يجب التذرع بمهمة التبعيات. ./gradlew dependencies إذا تم تنفيذ تمرين الإدخال Buildship الاختياري، فيمكن أيضًا استدعاء مهمة التبعيات باستخدام طريقة العرض Gradle Tasks. 9. استخدام Gradle Wrapper يتيح Gradle Wrapper إمكانية قيام المستخدم بتشغيل البناء باستخدام إصدار مُحدَّد مُسبقًا واستخدام إعدادات Gradle دون تثبيت Gradle محليًا. هذا المُغلِّفWrapper هو برنامج يتكون من سكربتات مرقِّعة-Patch Script على ويندوز، وسكربت للصدفة-Shell Script لأنظمة التشغيل الأخرى مثل لينكس. عند بدء تشغيل Gradle build عبر المجمع، يتم تنزيل الإصدار المحدد من Gradle تلقائيًا ويستخدم لتشغيل البناء. يعد الـWrapper الطريقة المفضلة لبدء إنشاء Gradle، حيث يجعل تنفيذ البناء مستقلًا عن إصدار Gradle المثبت. يمكن إنشاء البرنامج النصي المجمع عن طريق gradle wrapper. نتيجًة لذلك، يمكنك العثور على gradlew للأنظمة المستندة إلى يونكس (أنظمة التشغيل مفتوحة المصدر) و gradlew.bat لأنظمة الويندوز. يمكن استخدام هذه الملفات بدلاً من ذلك لأمر gradle، وإذا لم يتم تثبيت Gradle على الجهاز، فسيتم تنزيل Gradle وتثبيته تلقائيًا. من الممكن أيضًا تحديد مهمة تُحدِّد إصدار البرنامج. إذا تم تنفيذ هذه المهمة، فإنها تنشئ الـWrapper وتُحمِّل الإصدار الصحيح من Gradle. wrapper { gradleVersion = '4.9' } يمكن أيضًا تعريف إصدار Gradle Wrapper، عند إنشائه عبر سطر الأوامر الآتي: gradle wrapper --gradle-version 4.9 بدون هذا الإصدار الصريح، ستقوم Gradle تلقائيًا باختيار أحدث إصدار. 9.1. تكوين GRADLE_OPTS لبرنامج Gradle Wrapper يمكن أيضًا تحديد GRADLE_OPTS داخل ملف gradlew أو gradlew.bat. #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. # You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="-Xmx1024m" #... {more lines} @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS # and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS=-Xmx1024m @rem ... {more lines} 10. تمرين: تكوين مهمة الـ Wrapper تتوفر مهام مثل مهام Gradle Wrapper افتراضيًا ويمكن تعيين خصائص معينة منها، على سبيل المثال، gradleVersion مثل هذا: wrapper { gradleVersion = '4.9' } 11. تمرين - إنشاء مهام Gradle مخصصة 11.1. تمرين: مهمة Hello Gradle قم بإنشاء مهمة helloGradle، والتي تطبع Hello Gradle مع ورشة عمل المجموعة والوصف المناسب. ثم استخدم أمر gradlew tasks/. لرؤية مهمة helloGradle الجديدة في وحدة التحكم أو استخدام Buildship في Eclipse IDE. ثم استدعِ مهمة helloGradle عن طريق استدعاء gradlew hG/. أو مرة أخرى استخدم Buildship في Eclipse IDE. 11.2. تمرين: التبعيات بين المهام قم بإنشاء مهمتين جديدتين الأولى تدعى LearnGroovy، تطبع Learn Groovy، والثانية learnGradle، تطبع 'Learn Gradle'. يجب أن يكون لهذه المهام تبعيات معقولة. 11.3. تمرين: عمل doFirst للمهام قم بتعديل مهمة learnGroovy بحيث تقوم بطباعة *Install Eclipse IDE with Buildship * قبل أن تقوم بطباعة Learn Groovy. 12. تمرين: إنشاء مهمة نسخ يمكن أيضًا إنشاء مهام جديدة واستخلاصها من مهمة أخرى وتحديد خصائص معينة لها. يمكن استخدام نوع المهمة Copy لتحديد هذه المهمة، والتي تكون قادرة على نسخ الملفات. إنشاء مشروع جديد باستخدام ملف build.gradle التالي: task copyFile(type: Copy) { from 'source' into 'destination' } قم بإنشاء مجلد مصدر داخل هذا المشروع وأضف ملف نصي إلى هذا المجلد. عند تشغيل مهمة copyFile، تقوم بنسخ الملف النصي إلى مجلد وجهة جديد. 13. تمرين: تحديد مهمة مخصصة في ملف gradle آخر إنشاء مشروع Gradle جديد، والذي يحتوي على الهيكل التالي. تبدو الفئة CheckWebsite.groovy كما يلي: package com.example import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; class CheckWebsite extends DefaultTask { String url = 'http://www.vogella.com' @TaskAction void checkWebsite() { // check the given website by using the url try { Document doc = Jsoup.connect(url).get(); String title = doc.title(); println title println url } catch (IOException e) { e.printStackTrace(); } } } نظرًا لأن هذا الصنف-Class بها تبعيات خارجية لـ jsoup، يجب إنشاء ملف build.gradle لها. لذلك فإن build.gradle داخل مجلد buildSrc، المسؤول عن بناء فئة CheckWebsite، يبدو كما يلي: plugins { id 'groovy' } repositories { jcenter() } dependencies { compile 'org.jsoup:jsoup:1.8.3' } أخيرًا، يستخدم ملف build.gradle الرئيسي في المجلد الرئيسي نوع مهام جديدة مثل com.example.CheckWebsite. task defaultWebsiteCheck(type: com.example.CheckWebsite) task checkGradleWebsite(type: com.example.CheckWebsite) { url = 'https://docs.gradle.org/' } wrapper { gradleVersion = '4.9' } 14. تمرين: بناء Gradle Trigger من كود جافا يصف هذا التمرين كيفية تشغيل إنشاء gradle من تعليمات كود جافا. 14.1. إنشاء مشاريع جديدة لـGradle قم بإنشاء مشروعين gradle جديدين بأسماء BaseProject (يبدأ هذا المشروع إنشاء gradle) و TargetProject (تم بناء هذا المشروع بواسطة BaseProject). تأكد من أن BaseProject يطبق البرنامج المساعد جافا Java blugin. 14.2. إضافة التبعيات أضِف التبعية التالية إلى BaseProject. compile 'org.gradle:gradle-tooling-api:4.0-rc-2' 14.3. إنشاء TargetProject أُنشئ Class تحت إسم Application بطريقة static main كما يلي: import java.io.File; import org.gradle.tooling.BuildLauncher; import org.gradle.tooling.GradleConnector; import org.gradle.tooling.ProjectConnection; public class Application { public static void main(String[] args) { ProjectConnection connection = GradleConnector.newConnector().forProjectDirectory(new File("path/to/targetproject")).connect(); try { BuildLauncher build = connection.newBuild(); build.forTasks("build"); build.run(); } catch (Exception e) { e.printStackTrace(); } finally { connection.close(); } } } تقوم هذه الطريقة أولاً بإنشاء ProjectConnection للمشروع الذي يجب إنشاؤه ويتصل به. تأكد من استبدال path/to/targetproject بمسار TargetProject. من project connection، يمكن الحصول على BuildLauncher جديد. بمساعدة الدالة ()forTasks يمكنك تحديد مهام gradle التي يجب تنفيذها. يوفر BuildLauncher أيضًا بعض الطرق الأخرى لتكوين البناء. يمكنك، على سبيل المثال، تعيين عوامل بناء gradle أو تغيير إصدار Java لإنشاء المشروع بها. وعن طريق استدعاء الدالة ()run يتم تنفيذ البناء أخيرًا. تأكد من إغلاق الاتصال في البلوك الأخير. 15.بناء مشاريع جافا 15.1. البريمج التكميلي جافا Java plug-in يوفر البريمج التكميلي Java مهامًا لتجميع كود Java وتشغيل اختبارات الوحدة وإنشاء Javadoc وإنشاء ملف JAR. 15.2. تخطيط المشروع الافتراضي لمشاريع Java تفترض هذه المكونات الإضافية إعدادًا معينًا لمشروع Java الخاص بك (على غرار Maven). src/main/java يحتوي على كود جافا الأساسي. src/test/java يحتوي على اختبارات جافا. إذا اتبعت هذا الإعداد، فسيكون ملف البناء التالي كافياً لتجميع مشروع Java واختباره وحزمه. apply plugin: 'java' لبدء التنفيذ، اكتب gradle build في سطر الأوامر. يمكن استخدام SourceSets لتحديد بنية مشروع مختلفة، على سبيل المثال، يتم تخزين المصادر في مجلد src بدلاً من src/main/java. apply plugin: 'java' sourceSets { main { java { srcDir 'src' } } test { java { srcDir 'test' } } } 15.3. إنشاء مشروع Java باستخدام مهمة init لا يدعم Gradle بعد قوالب مشاريع متعددة (تسمى النماذج الأولية archetypes) مثل Maven. لكنه يوفر مهمة init لإنشاء هيكل مشروع Gradle جديد. بدون عوامل إضافية، تنشئ هذه المهمة مشروع Gradle، والذي يحتوي على ملفات gradle wrapper وملف build.gradle و settings.gradle. عند إضافة المعامل type-- مع 'java-library' كقيمة، يتم تنفيذ بناء مشروع java ويحتوي ملف build.gradle على قالب Java معين مع JUnit. سيبدو ملف build.gradle مشابهًا لهذا: /* * ... deleted the generated text for brevity */ // Apply the java plugin to add support for Java apply plugin: 'java' // In this section you declare where to find the dependencies of your project repositories { // Use 'jcenter' for resolving your dependencies. // You can declare any Maven/Ivy/file repository here. jcenter() } // In this section you declare the dependencies for your production and test code dependencies { // The production code uses the SLF4J logging API at compile time compile 'org.slf4j:slf4j-api:1.7.12' // Declare the dependency for your favourite test framework you want to use // TestNG is also supported by the Gradle Test task. Just change the // testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add // 'test.useTestNG()' to your build script. testCompile 'junit:junit:4.12' } يوفر المشروع المستضاف على Github والذي يُدعى Gradle-Templates Project مزيدًا من القوالب تتجاوز مهمة init. يعمل فريق Gradle أيضًا على موضوع النموذج/القالب هذا. عادةً ما يحتوي مشروع Java على إصدار و JRE مُستهدف يتم تجميعه عليه. يمكن تعيين خاصية version و sourceCompatibility في ملف build.gradle. version = 0.1.0 sourceCompatibility = 1.8 عند تعيين خاصية الإصدار، سيتم تغيير اسم الناتج وفقًا لذلك، على سبيل المثال، my-lib-name} -0.1.0.jar} إذا كان الناتج عبارة عن تطبيق جافا قابل للتنفيذ، فيجب أن يكون ملف MANIFEST.MF على دراية بالصنف Class باستخدام الدالة main. apply plugin: 'java' jar { manifest { attributes 'Main-Class': 'com.example.main.Application' } } 16. بناء مشاريع Groovy 16.1. البريمج التكميلي جروفي Groovy Plugin يعمل البريمج التكميلي Groovy في Gradle على تمديد البريمج التكميلي Java ويوفر مهامًا لبرامج Groovy. apply plugin: 'groovy' repositories { mavenCentral() } dependencies { implementation 'org.codehaus.groovy:groovy-all:2.4.5' testImplementation 'junit:junit:4.12' } لكي تبدأ البناء، اكتب gradle build في سطر الأوامر. 16.2. الشكل الافتراضي لمشاريع Groovy تفترض هذه البريمجات التكميلية src/main/groovy يحتوي على الكود الأصلي لـ Groovy. src/test/groovy يحتوي على اختبارات Groovy. src/main/java يحتوي على الكود الأصلي لـ Java. src/test/java يحتوي على اختبارات Java. إذا تتبّعت هذا الإعداد، يكون ملف البناء التالي كافياً لتجميع مشروع Groovy واختباره وتعبئته. 17. اختبارات مع Gradle 17.1. تنفيذ 5 اختبارات JUnit مع Gradle لاستخدام 5 اختبارات جافا، أضف ما يلي إلى نهاية الـ dependencies في ملف 'build.gradle` الخاص بك. استخدم Gradle 6.0 على الأقل لهذا لتجنب المشكلات التي تم إصلاحها بالفعل. dependencies { // more stuff testImplementation(enforcedPlatform("org.junit:junit-bom:5.4.0")) // JUnit 5 BOM testImplementation("org.junit.jupiter:junit-jupiter") } 17.2. اختبار اصطلاحات التسمية لـ Gradle تفحص مهمة "test" في Gradle جميع الفئات المترجمة في المجلد المصدر للمشروع، على سبيل المثال، src/test/java أو /src/test/groovy/. يتم تحديد أصناف JUnit بواسطة: Class أو Super Class يوسِّع TestCase أو GroovyTestCase. الـ Class أو Super Class يُرمز أليهم بـ RunWith@. يحتوي الـ Class أو Super Class على دالة يُرمز إليها بـ Test@. يمكنك تعيين خاصية scanForTestClasses إلى false، إذا كنت لا تريد الكشف التلقائي عن فئة الاختبار. في هذه الحالة، إذا لم يتم تحديد أنماط تضمين/استبعاد إضافية، فإن الإعدادات الافتراضية للفئات المضمنة هي "Tests.class”, “/*Test.class/” والفئات المُستثناة الافتراضية هي"Abstract * .class /*". 17.3. تضمين واستبعاد اختبارات معينة يتم وصف تكوين الاختبار بشكل عام في وصف مهام اختبار جرادل Gradle Test Tasks Description. فئة الاختبار teast Class لديها دوال include وexclude. يمكن استخدام هذه الدوال لتحديد الاختبارات التي يجب تشغيلها بالفعل. تشغيل الاختبارات المضمنة included tests فقط: test { include '**my.package.name/*' } تخطي الاختبارات المستبعدة excluded tests: test { exclude '**my.package.name/*' } 17.4. إظهار كل نواتج الاختبار في الطرفية Terminal بشكل افتراضي، لا يقوم Gradle بطباعة الناتج القياسي لاختباراتك على الطرفية Terminal. لمشاهدة جميع مخرجات اختباراتك، أضف هذا إلى ملف البناء الخاص بك: test { testLogging.showStandardStreams = true } 18. بناء مشاريع متعددة مع Gradle 18.1. إنشاء هيكل بناء مشروع متعدد عادةً لا يتألف تطبيق الأعمال من مشروع / وحدة واحدة فقط ، ولكن يحتوي على العديد من المشاريع، والتي يجب أن يتم بناؤها. لدى Gradle مفهوم المشروع الأساسي The root project، والذي يمكن أن يحتوي على العديد من المشاريع الفرعية. يتم تحديد المشروع الأساسي بواسطة ملف build.gradle، مثل المشاريع الفردية من قبل. لتحديد، ما هي المشاريع التي تنتمي إلى البناء يتم استخدام ملف settings.gradle. على سبيل المثال، قد يكون هناك هيكل المشروع هذا: root_project core ui util settings.gradle وجود بنية المشروع هذا، سيبدو ملف الإعدادات settings.gradle هكذا: include 'core', 'ui', 'util' # altenative way would be #include 'core' #include 'ui' #include 'util' إلى جانب المهمة tasks، يوفر Gradle أيضًا المهمة المساعدة projects، والتي يمكن تنفيذها في المجلد root_project. > gradle projects 18.2. تحديد تكوين بناء عام في ملف build.gradle في التكوينات العامة root_project يمكن تطبيقها على جميع المشاريع أو على المشروعات الفرعية فقط. allprojects { group = 'com.example.gradle' version = '0.1.0' } subprojects { apply plugin: 'java' apply plugin: 'eclipse' } يحدد هذا مجموعة com.example.gradle مشتركة وإصدار 0.1.0 لجميع المشاريع. تُطبِّق نهاية المشروعات الفرعية تكوينات شائعة على جميع المشروعات الفرعية، ولكن ليس على المشروع الأصلي، كما هو الحال في نهاية all projects. 18.3. تكوينات محددة المشروع والتبعيات يمكن أن يكون للـ core و ui و util (هيكل الـ root project في المشروع كما وضحنا ذلك في الجزء 19.1) الخاصين بالمشروعات الفرعية ملف build.gradle خاص بها أيضًا. إذا كانت لديهم احتياجات محددة، والتي لم يتم تطبيقها بالفعل عن طريق التكوين العام للمشروع الأصلي. على سبيل المثال، عادةً ما يكون لمشروع واجهة المستخدم ui تبعية للمشروع الأساسي. لذا يحتاج مشروع واجهة المستخدم إلى ملف build.gradle الخاص به لتحديد هذه التبعية. dependencies { compile project(':core') compile 'log4j:log4j:1.2.17' } يتم تحديد تبعيات المشروع مع دالة المشروع project method. بدلاً من ذلك، يمكنك أيضًا تحديد تبعيات مشروع في ملف build.gradle الأصلي. ولكن يعتبر ممارسة جيدة لتحديد التبعيات في ملفات build.gradle المحدّدة الخاصة بالمشروع، وبالتالي يتم تضمين النهج التالي فقط لغرض العرض التوضيحي. allprojects { apply plugin: 'java' repositories { mavenCentral() } } project(':com.example.core').dependencies { compile project(':com.example.model') compile 'log4j:log4j:1.2.17' } 19. النشر مع Gradle 19.1. كيفية النشر باستخدام Gradle يوفر Gradle عدة طرق لنشر عناصر البناء في مستودعات الإنتاج، مثل Artifactory أو Sonatyp Nexus. 19.2. باستخدام المافن نشر البريمج التكميلي Using the maven-publish plugin الطريقة الأكثر شيوعًا هي استخدام المكون الإضافي maven-publish، والذي يوفره Gradle افتراضيًا. // other plug-ins apply plugin: 'maven-publish' publishing { publications { mavenJava(MavenPublication) { from components.java } } repositories { maven { url "$buildDir/repo" } } } هناك العديد من خيارات النشر ، عندما يتم تطبيق java والمكون الإضافي maven-publish. يمكن إجراء النشر إلى مستودع منفصل مثل هذا: apply plugin: 'groovy' apply plugin: 'maven-publish' group 'workshop' version = '1.0.0' publishing { publications { mavenJava(MavenPublication) { from components.java } } repositories { maven { // default credentials for a nexus repository manager credentials { username 'admin' password 'admin123' } // url to the releases maven repository url "http://localhost:8081/nexus/content/repositories/releases/" } } } يمكن العثور على مزيد من المعلومات حول النشر إلى مستودع Maven للإنتاج هنا: Publish to Maven repository with Gradle. 20. التكامل مع Ant يدعم Gradle تشغيل مهام Ant عبر برنامج Groovy AntBuilder. 21. تحويل مشاريع Groovy إلى Gradle يوفر Gradle مهمة init المحتضنة، والتي تساعد في إنشاء مشاريع Gradle جديدة. يمكن لهذه المهمة أيضًا تحويل ملفات Apache Maven pom.xml إلى ملفات بناء Gradle، إذا كانت جميع المكونات الإضافية المستخدمة في Maven معروفة لهذه المهمة. في هذا الجزء، سيتم تحويل Groovy pom.xml التالي إلى مشروع Gradle. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.app</groupId> <artifactId>example-app</artifactId> <packaging>jar</packaging> <version>1.0.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </project> يؤدي تشغيل gradle init --type pom في سطر الأوامر إلى تكوين Gradle الآتي. تعتمد مهمة init على مهمة Wrapper بحيث يتم أيضًا إنشاء Gradle Wrapper. يشبه ناتج ملف build.gradle الآتي: apply plugin: 'java' apply plugin: 'maven' group = 'com.example.app' version = '1.0.0-SNAPSHOT' description = """""" sourceCompatibility = 1.5 targetCompatibility = 1.5 repositories { maven { url "http://repo.maven.apache.org/maven2" } } dependencies { testImplementation group: 'junit', name: 'junit', version:'4.11' } 22. تطوير مكونات Gradle الإضافية Gradle Plug-ins 22.1. لماذا نُنشيء مكونات Gradle الإضافية؟ كقاعدة عامة، من المفيد أن يكون هناك بناءً تصريحيًا declarative build بأكبر قدر ممكن لأن هذا يُبسِّط التعديلات المستقبلية. لذلك يُنصح بتجنب التعليمات البرمجية المعقدة في ملف بناء Gradle الخاص بك. إذا كنت بحاجة إلى منطق مخصص، فيجب وضعه في مكون إضافي مخصص لـ Gradle. 22.2. Gradle DSL يأتي كل مكون إضافي من Gradle مزودًا بخدمة DSL. لمشاهدة جميع خصائص كائن Gradle، يمكنك استخدام مقتطف التالي من الكود: println variants.properties .sort{it.key} .collect{it} .findAll{!filtered.contains(it.key)} .join('\n') على سبيل المثال، لتحديد المهام التي تعرض جميع خصائص android.applicationVariants (في مشروع أندرويد)، استخدم: task showAndoidVariantsInformation { doLast { android.applicationVariants.all { variants -> println variants.properties .sort{it.key} .collect{it} .findAll{!filtered.contains(it.key)} .join('\n') } } } 23. تمرين: إنشاء برنامجًا مساعدًا بسيطًا Simple Gradle Plugin تعمل الأداة الإضافية java-gradle-plugin على تبسيط إنشاء مكونات إضافية مخصصة لـ Gradle. هذا البرنامج المساعد في طور الإعداد حاليًا. يفعل ما يأتي: تتم إضافة التابع ()gradleApi تلقائيًا. تتم إضافة التابع ()gradleTestKit تلقائيًا. تتم إضافة ملفات واصف المكونات الإضافية الضرورية تلقائيًا. 23.1. إنشاء مشروع Gradle حدِّد Gradle Project < Gradle < Other < new < File في Eclipse لإنشاء مشروع Gradle جديد. ضع com.vogella.gradleplugin ليكون اسم المشروع كما هو موضّح. التزم بالإعدادات الافتراضية للمعالج وقم بإنشاء المشروع. 23.2. قم بتطبيق المكون الإضافي "java-gradle-plugin" غيِّر ملف build.gradle إلى ما يلي: plugins { id 'java-gradle-plugin' } gradlePlugin { plugins { vogellaPlugin { id = 'com.vogella.gradleplugin' implementationClass = 'com.vogella.gradleplugin.MyPlugin' } } } repositories { jcenter() } dependencies { // No need to add gradleApi() here, because it is applied by the 'java-gradle-plugin' plug-in // We want to merge and parse SpotBugs xml files with XSLT compile('net.sf.saxon:Saxon-HE:9.8.0-12') // Use JUnit test framework testImplementation 'junit:junit:4.12' } wrapper { gradleVersion = '4.9' } في مجلد src/main/java/، قم بإنشاء الصنفين Classes التاليتين. package com.vogella.gradleplugin; import org.gradle.api.DefaultTask; import org.gradle.api.tasks.TaskAction; public class MyTask extends DefaultTask { @TaskAction public void myTask() { System.out.println("Hello from vogella task"); } } package com.vogella.gradleplugin; import org.gradle.api.Plugin; import org.gradle.api.Project; public class MyPlugin implements Plugin<Project> { @Override public void apply(Project project) { project.getTasks().create("myTask", MyTask.class); } } قم بتنفيذ المهمة build لإنشاء مكون إضافي وانظر التدريبات التالية حول كيفية نشر المكون الإضافي واستخدامه. 24. تمرين: قم بنشر المكونات الإضافية المخصصة لـ Gradle في مستودع Maven المحلي أضف المكوّن الإضافي Gradle-plugin ومغلِّف النشر publishing closur إلى ملف build.gradle. plugins { id 'java-gradle-plugin' id 'maven-publish' } group = 'com.vogella' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 // ... more code publishing { publications { mavenJava(MavenPublication) { from components.java } } } تتوفر الآن مهام نشر إضافية ويمكن استخدام مهمة publishToMavenLocal لإضافة مكون Gradle الإضافي إلى مستودع Maven المحلي. ./gradlew pTML 25. تمرين: استخدام المكون الإضافي الجديد لاستخدام مكون Gradle الجديد، يجب تحديد تبعية له. إذا دفعت مكونك الإضافي إلى مستودع Maven المحلي، فيجب على Gradle العثور عليه وإتاحته. buildscript { repositories { mavenLocal() } dependencies { classpath 'com.vogella:com.vogella.gradleplugin:0.0.1-SNAPSHOT' } } apply plugin: 'com.vogella.gradleplugin' الآن المهمة الجديدة من com.vogella.gradleplugin يجب أن تكون متاحة: ./gradlew tasks ./gradlew myTask 26. تمرين: -اختياري- نشر المكوّن الإضافي في مدخل المكوّن الإضافي جرادل Gradle Plug-in Portal لنشر مكون إضافي من نوع Gradle في مدخل Gradle Plug-in، يمكن استخدام com.gradle.plugin-publish. قبل تحميل مكونات Gradle الإضافية إلى البوابة ، يجب عليك التسجيل على https://plugins.gradle.org/user/register والحصول على مفاتيح api من ملفك الشخصي. يجب إضافة خصائص gradle.publish.key و gradle.publish.secret إلى gradle.properties. بعد ذلك ، يجب تعديل ملف build.gradle ليتمكن من تحميل مكونات Gradle الإضافية. plugins { id 'java-gradle-plugin' id 'maven-publish' id 'com.gradle.plugin-publish' version '0.9.10' } // more code ... pluginBundle { website = '${Web site for your plugin}' vcsUrl = 'https://github.com/${your-repo}' plugins { vogellaPlugin { id = 'com.vogella.gradleplugin' displayName = 'Vogella Sample Plug-in' description = 'Vogella Sample Plug-in for trying the ' tags = ['Vogella','Training','Gradle','Sample'] // Gradle's plug-in portal does not support SNAPSHOTs version = '0.0.1' } } } يمكن بعد ذلك استخدام المهمة التالية لتحميل المكوّن الإضافي Gradle. ./gradlew publishPlugins عند نشر المكون الإضافي، يمكن استخدام نهايات المكونات الإضافية للاستفادة من مكون Gradle الإضافي. plugins { id "com.vogella.gradleplugin" version "0.0.1" } لذلك يمكن حذف النهايات المطوّلة بشكل أكبر وأيضًا دالة المكوِّن الإضافي apply من الفصول السابقة. المزيد من التفاصيل تجدها هنا. 27. تصحيح إضافات غرادل Gradle Plug-ins 27.1. تنشيط تصحيح الأخطاء عن بُعد يجب تحديد الخصائص التالية في ملف gradle.properties لتمكين تصحيح الأخطاء عن بُعد: org.gradle.daemon=true org.gradle.jvmargs=-XX:+HeapDumpOnOutOfMemoryError -Xmx4g -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5006 عند تشغيل بناء Gradle محليًا باستخدام هذه الإعدادات، يمكن الوصول إلى تصحيح الأخطاء عن بُعد عبر مضيف محلي localhost على المنفذ 5006. 27.2. تصحيح الأخطاء عن بُعد في Eclipse IDE يجب عليك إدخال مكون إضافي معين إلى Eclipse IDE باستخدام أدوات Buildship. بعد ذلك، يمكنك إضافة نقاط التوقف break points إلى الملفات الأساسية للمكون الإضافي. بعد ذلك، افتح تكوين تصحيح الأخطاء Debug Configuration وانقر بزر الفأرة الأيمن فوق Remote Java Application لإنشاء Debug Configuration جديد باستخدام الإعدادات التالية: اضغط على الزر Debug لتشغيل مصحح الأخطاء عن بُعد remote debugger. بعد ذلك، يمكن تشغيل بناء Gradle، الذي يستخدم مكون Gradle الإضافي المطلوب، إما باستخدام طريقة عرض مهام Gradle لأداة Buildship داخل Eclipse IDE أو استدعاء بناء Gradle من سطر الأوامر. عند الوصول إلى نقطة توقف أثناء مهمة Gradle، فإن Eclipse IDE سوف يتوقف عند هذه النقطة. 28. استخدام أدوات تحليل الكود يوفر Gradle عدة مكونات إضافية لتحليل قاعدة الكود لمشروع Gradle. الجدول 1. أدوات تحليل كود Gradle الأداة Plug-in الوصف Checkstyle checkstyle التحقق من صحة قواعد checkstyle، والتي يتم تطبيقها على المشروع. Jacoco jacoco يتحقق من تغطية الاختبار للكود الذي يجري بناؤه. FindBugs findbugs تحليل الكود الثابت للجافا. CodeNarc codenarc تحليل الكود الثابت لـGroovy. PMD pmd يضيف اختبارات جودة الكود لعدة لغات برمجة. JDepend jdepend أداة تحليل التعليمات البرمجية الأخرى لتحليل التبعيات في كود الجافا. table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } 28.1. Jcoco لمشاريع Gradle لاستخدام Jacoco لتحليل مدى تغطية الاختبار-Code Coverage، يجب إضافة الكود التالي إلى ملف build.gradle ذي المستوى الأعلى. plugins { id 'jacoco' } jacocoTestReport { reports { xml.enabled true html.enabled true } } إذا كان لديك مشروع Gradle متعدد المشروعات، فأنت بحاجة إلى إضافة jacocoTestReport والمكون الإضافي jacoco إلى قسم المشاريع الفرعية في ملف build.gradle ذي المستوى الأعلى. plugins { id 'jacoco' } subprojects { apply plugin: 'jacoco' jacocoTestReport { reports { xml.enabled true html.enabled true } } } إذا كنت ترغب في الحصول على ملف xml مدمج لجميع المشروعات الفرعية، على سبيل المثال لاستخدام SonarQube، يمكنك إنشائه بالمهمة التالية في build.gradle ذي المستوى الأعلى. task generateMergedReport(type: JacocoReport) { dependsOn = subprojects.test additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) classDirectories.setFrom files(subprojects.sourceSets.main.output) executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec') reports { xml.enabled true xml.destination file("../coverage-reports/coverage.xml") } } ستقوم هذه المهمة بحفظ ملف XML الموحد في المستوى العلوي من المشروع ضمن تقارير التغطية. أخيرًا لإنشاء ملف xml مدمج، قم بتشغيل Gradle باستخدام المهمة التي تم إنشاؤها generMergedReport. ./gradle clean build generateMergedReport 29. Gradle Gradle Goodness blog series Eclipse Gradle Tooling Publish to Maven repository حقوق النشر والترخيص والكود يتم منح الاستخدام المجاني لأمثلة البرامج بموجب شروط Eclipse Public License 2.0. المقال مترجم وبتصرف للمقال The Gradle build system- Tutorial
  4. عندما تُنشئ خادم أوبونتو 18.04 لأول مرة، فهناك بعض خطوات الإعداد التي ينبغي عليك اتخاذها مبكّرًا كجزء من الإعداد الأساسي. سيزيد ذلك من أمان الخادم وسهولة استخدامه وسيمنحك أساسًا قويًا لاتخاذ إجراءات لاحقة. رغم أنه يمكنك إكمال هذه الخطوات يدويًا، إلا أنه في بعض الأحيان يكون من الأسهل برمجة العمليات عبر سكربت لتوفير الوقت وتفادي الأخطاء البشرية. يشرح هذا الدليل كيفية أتمتة الخطوات الموجودة في دليل إعداد الخادم الأولي في سكربت. ماذا يفعل السكربت؟ يعدّ هذا السكربت بديلًا للتشغيل اليدوي من خلال الطريقة الموضحة في دليل إعداد خادم أوبونتو 18.04 الأولي ودليل إعداد مفاتيح SSH على أوبونتو 18.04. تؤثر المتغيرات التالية على كيفية عمل السكربت: USERNAME: اسم حساب المستخدم العادي الذي ستُنشأ وتمنح له صلاحيات sudo. COPY_AUTHORIZED_KEYS_FROM_ROOT: تحدّد ما إذا كنت تريد نسخ أصول مفتاح SSH من الحساب الجذري root إلى حساب sudo الجديد. OTHER_PUBLIC_KEYS_TO_ADD: مجموعة من السلاسل النصية التي تمثل مفاتيح عامة أخرى تُضاف إلى الحساب sudo. يمكن استخدام هذه بالاختيار بين إضافتها أو جعلها بديلًا لنسخ المفاتيح من الحساب الجذري root. يجب عليك تحديث هذه المتغيرات حسب الحاجة قبل تشغيل السكربت. عند تنفيذ السكربت، تُنفّذ الإجراءات التالية: إنشاء حساب مستخدم عادي مع امتيازات sudo باستخدام الاسم الذي يحدده المتغير USERNAME . إعداد إطار لكلمة المرور الأولية للحساب الجديد: إذا كان الخادم معدًّا لمصادقة الهوية بكلمة المرور، فستُنقل كلمة المرور الإدارية الأصلية التي وُلِّدت لحساب root إلى حساب sudo الجديد. حينها تكون كلمة المرور للحساب الجذري مقفلة. إذا كان الخادم معدًّا لمصادقة الهوية بمفتاح SSH، فستُعيّن كلمة مرور فارغة لحساب sudo. تُعلّم كلمة مرور المستخدم sudo بعلامة "منتهي الصلاحية" مما يوجب تغييرها عند أول تسجيل للدخول. يُنسخ ملف Authorized_keys من الحساب الجذري إلى مستخدم sudo إذا عُيِّن المتغير COPY_AUTHORIZED_KEYS_FROM_ROOT على "صحيح". تُضاف أي مفاتيح معرّفة في OTHER_PUBLIC_KEYS_TO_ADD إلى ملف Authorized_keys للمستخدم sudo. يُعطّل التصديق SSH المستند إلى كلمة المرور في الحساب الجذري root. يُفعّل جدار الحماية UFW مع السماح باتصالات SSH. كيف يُستخدَم السكربت؟ يمكن تنفيذ السكربت بطريقتين: عن طريق إضافته إلى حقل بيانات مستخدم الخادم أثناء الإنشاء أو عن طريق تسجيل الدخول بحساب root وتنفيذه بعد التشغيل. عبر بيانات المستخدم عند إنشاء Droplet على DigitalOcean، يمكنك تحديد بيانات المستخدم، وهو سكربت يُنفّذ أثناء تشغيل الخادم الأولي من أجل إجراء إعدادٍ إضافي. إذا كنت تُنشئ Droplet من لوحة التحكم، فيمكنك تحديد خانة الاختيار "بيانات المستخدم" في قسم تحديد خيارات إضافية. سيظهر لك مربع نصي حيث يمكنك لصق السكربت: إذا كنت تُنشئ Droplet باستخدام واجهة برمجة تطبيقات DigitalOcean، فيمكنك تمرير السكربت باستخدام سمة user_data بدلاً من ذلك. إذا كنت تُنشئ Droplet باستخدام أداة سطر الأوامر doctl، فيمكنك تمرير السكربت باستخدام خيار ‎--user-data-file: $ doctl compute droplet create ... --user-data-file /path/to/script بغض النظر عن الطريقة التي تستخدمها لإضافة بيانات المستخدم، سيُنفّذ السكربت في أول مرة يُشغّل فيها الخادم الجديد. قد تضطر إلى الانتظار لبضع دقائق حتى تكتمل العملية، ولكن بعد ذلك، يمكنك تسجيل الدخول إلى الخادم الخاص بك عبر حساب المستخدم sudo للحصول على أي إعداد إضافي. عند تسجيل الدخول لأول مرة، سيُطلب منك تغيير كلمة المرور الخاصة بك. سينهي الخادم جلسة SSH الحالية بمجرد تقديم بيانات الاعتماد الجديدة الخاصة بك وتأكيدها. بعد ذلك، يمكنك إعادة SSH مرة أخرى مثل العادة. تنفيذ السكربت بعد التشغيل إذا كنت لا ترغب في استخدام بيانات المستخدم، يمكنك أيضًا تشغيل السكربت يدويًا عبر SSH بمجرد تشغيل الخادم. إذا نزّلت السكربت على جهاز الكمبيوتر المحلي الخاص بك، يمكنك تمرير السكربت مباشرةً إلى SSH بكتابة ما يلي: $ ssh root@servers_public_IP "bash -s" -- < /path/to/script/file ينبغي أن تكون الآن قادرًا على تسجيل الدخول باستخدام حساب sudo الخاص بك من أجل أي إعداد إضافي. إذا لم تُنزّل السكربت على جهاز الحاسوب المحلي، فابدأ بتسجيل الدخول إلى الحساب root على الخادم الخاص بك: $ ssh root@servers_public_IP بعد ذلك، نزِّل السكربت الأولي على الخادم: $ curl -L https://raw.githubusercontent.com/do-community/automated-setups/master/Ubuntu-18.04/initial_server_setup.sh -o /tmp/initial_setup.sh افحص السكربت للتأكد من تنزيله بشكل صحيح و حدِّث أي متغيرات ترغب في تغييرها: $ nano /tmp/initial_setup.sh عندما تكون راضيًا عن المعطيات، شغّل السكربت يدويًا باستخدام bash: $ bash /tmp/initial_setup.sh ينبغي أن تكون الآن قادرًا على تسجيل الدخول باستخدام الحساب ذي الصلاحيات sudo لإتمام أي إعدادٍ إضافي. محتويات السكربت يمكنك العثور على السكربت لإعداد الخادم الأولي في مخزن الإعداد التلقائي لمؤسسة DigitalOcean Community GitHub. لنسخ محتويات السكربت أو تنزيلها مباشرةً، انقر فوق الزر (Raw) أعلى النص، أو انقر هنا لعرض المحتويات الأولية مباشرة. لقد أدرجت المحتويات كاملة أيضًا هنا لتسهيل العملية: #!/bin/bash set -euo pipefail ######################## ### SCRIPT VARIABLES ### ######################## # اسم حساب المستخدم العادي الذي ستُنشأ وتمنح له صلاحيات # Name of the user to create and grant sudo privileges USERNAME=sammy # الجديد sudo إلى حساب root من الحساب الجذري SSH تحدّد ما إذا كنت تريد نسخ أصول مفتاح # Whether to copy over the root user's `authorized_keys` file to the new sudo # user. COPY_AUTHORIZED_KEYS_FROM_ROOT=true # sudo مجموعة من السلاسل النصية التي تمثل مفاتيح عامة أخرى تُضاف إلى الحساب # Additional public keys to add to the new sudo user # OTHER_PUBLIC_KEYS_TO_ADD=( # "ssh-rsa AAAAB..." # "ssh-rsa AAAAB..." # ) OTHER_PUBLIC_KEYS_TO_ADD=( ) #################### ### SCRIPT LOGIC ### #################### # ومنحه الصلاحيات sudo إنشاء حساب المستخدم # Add sudo user and grant privileges useradd --create-home --shell "/bin/bash" --groups sudo "${USERNAME}" # تحقق من توفّر الحساب الجذري على كلمة مرور # Check whether the root account has a real password set encrypted_root_pw="$(grep root /etc/shadow | cut --delimiter=: --fields=2)" if [ "${encrypted_root_pw}" != "*" ]; then # تُنقل كلمة المرور الإدارية الأصلية التي وُلِّدت لحساب الجذري إلى الحساب الجديد. حينها تُقفل كلمة المرور للحساب الجذري # Transfer auto-generated root password to user if present # and lock the root account to password-based access echo "${USERNAME}:${encrypted_root_pw}" | chpasswd --encrypted passwd --lock root else # حذف كلمة مرور غير صالحة للمستخدم في حالة استخدام المفاتيح بحيث يمكن تعيين كلمة مرور جديدة دون تقديم قيمة سابقة # Delete invalid password for user if using keys so that a new password # can be set without providing a previous value passwd --delete "${USERNAME}" fi # إنهاء صلاحيات المستخدم العادي لإجباره على تغييرها # Expire the sudo user's password immediately to force a change change --lastday 0 "${USERNAME}" # sudo للمستخدم SSH إنشاء مجلد # Create SSH directory for sudo user home_directory="$(eval echo ~${USERNAME})" mkdir --parents "${home_directory}/.ssh" # نسخ ملف المفاتيح من الحساب الجذري إذا كان ضروريًا # Copy `authorized_keys` file from root if requested if [ "${COPY_AUTHORIZED_KEYS_FROM_ROOT}" = true ]; then cp /root/.ssh/authorized_keys "${home_directory}/.ssh" fi # إضافة المفاتيح الإضافية المتوفرة # Add additional provided public keys for pub_key in "${OTHER_PUBLIC_KEYS_TO_ADD[@]}"; do echo "${pub_key}" >> "${home_directory}/.ssh/authorized_keys" done # SSH ضبط تكوينات ملكية وصلاحيات # Adjust SSH configuration ownership and permissions chmod 0700 "${home_directory}/.ssh" chmod 0600 "${home_directory}/.ssh/authorized_keys" chown --recursive "${USERNAME}":"${USERNAME}" "${home_directory}/.ssh" # إيقاف تسجيل الدخول للحساب الجذري باستعمال كلمة المرور # Disable root SSH login with password sed --in-place 's/^PermitRootLogin.*/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config if sshd -t -q; then systemctl restart sshd fi # SSH بعد إضافة استثناءات UFW تفعيل جدار الحماية # Add exception for SSH and then enable UFW firewall ufw allow OpenSSH ufw --force enable خاتمة يمكن أن يوفر لك إعداد الخادم الأولي تلقائيًا بعض الوقت ويمنحك أساسًا جيدًا لمزيد من الإعداد. إذا كانت هناك خطوات إضافية ترغب في اتخاذها، فيمكنك إما تسجيل الدخول بعد تشغيل السكربت للمتابعة يدويًا، أو إضافة الخطوات في نهاية السكربت لأتمتة العملية. ترجمة -وبتصرف- للمقال Automating Initial Server Setup with Ubuntu 18.04 لصاحبه Justin Ellingwood
  5. Ajenti هي لوحة تحكّم عبر الويب حرّة ومفتوحة المصدر يمكن استخدامها لتنفيذ مجموعة كبيرة ومتنوعة من مهام إدارة الخوادم، علاوةً على إمكانية تغطيتها لمجموعة أخرى من المهام عبر تركيب إضافات add-ons كإضافة Ajenti V والتي تسمح بإدارة عدّة مواقع من خلال لوحة تحكم واحدة. المتطلباتفي هذا الدرس ستحتاج إلى: عنوان نطاق domain مُسجّل ومربوط مع خادوم مُثبّت عليه لوحة التحكم Ajenti مع الإضافة Ajenti V (خلال الدرس سأستخدم النطاق example.com للتوضيح).لوحة التحكم Ajenti مُثبتة ومضبوطة بشكل صحيح مع الإضافة Ajenti V، يمكنك قراءة هذا الدرس لتثبيت Ajenti خطوة بخطوة.ضبط عنوان النطاقيُفترض هنا أنك تستطيع الوصول إلى لوحة تحكّم Ajenti الخاصّة بك عبر المسار https://panel.your_domain_name:8000، وقبل البدء بإعداد موقعك على الرابط http://your_domain_name وضبط عناوين البريد لنطاقك ينبغي علينا القيام ببعض تعديلات DNS الضرورية أولًا. حيث يتوجب علينا إضافة سجّلين (records) للتأكد من أن موقعك وعناوين البريد ستعمل كما ينبغي. إن كنت على DigitalOcean مثلا فاذهب إلى الرابط https://cloud.digitalocean.com/domains واضغط على زر View الأزرق (يبدو على شكل عدسة مُكبّرة) لعنوان النطاق الذي قمت بضبطته أثناء إعداد لوحة تحكم Ajenti وAjenti V. انقر على زر Add Record الأزرق ثم اختر MX، في مربع Enter Hostname النصيّ أدخل @ وأدخل الرقم 10 في مربع Enter Priority النصيّ، ثم اضغط على الزرق الأزرق Create MX Record. إذا كنتَ ستضبط عنوان النطاق الذي تستضيف عليه لوحة التحكم Ajenti فأنتَ بحاجة إلى إضافة سجل نصيّ TXT record. إن كان اسم نطاق على مزود خدمة آخر، فعليك الرجوع إلى أدلة المساعدة الخاصة بواجهة المزود لإضافة سجلّي MX و TXT بنفس الطريقة السابقة. على سبيل المثال إذا كان رابط دخول لوحة التحكم لديك يتمّ عبر المسار panel.example.com عليك حينها إضافة هذا السجل، أما لو كانت اللوحة تتبع لنطاق آخر (مثلا panel.otherdomain.com) فلستَ بحاجةٍ إلى شيء إذًا. لإضافة السجل النصيّ TXT record اضغط مجددًا على الزر الأزرق Add Record واختر TXT. في المربع النصيّ Enter Name أدخل @، وفي مربع Enter Text ألصق: v=spf1 a ip4:your_server_ip ~all (استبدل IP برقم الـIP الخاص بخادومك). اضغط أخيرًا على Create TXT Record. الآن يفترض أن تبدو إعدادات DNS الخاصة بنطاقك كهذه، انتبه أنّ عنوان نطاق سيكون بدلًا النطاق المُستخدم هنا jonaharagon.me. أما ملف المنطقة zone file فسيبدو على النحو التالي: $ORIGIN example.com. $TTL 1800 example.com. IN SOA ns1.digitalocean.com.hostmaster.example.com. 1434177047 10800 3600 604800 1800 example.com. 1800 IN NS ns1.digitalocean.com. example.com. 1800 IN NSns2.digitalocean.com. example.com. 1800 IN NS ns3.digitalocean.com. example.com. 1800 IN A 111.111.111.111 example.com. 1800 IN MX 10example.com. example.com. 1800 IN TXT v=spf1 a ip4:111.111.111.111 ~all panel.example.com. 1800 IN A 111.111.111.111 إنشاء مجلد الموقعفي متصفح الويب لديك انتقل إلى https://panel.example.com وسجّل دخولك إلى Ajenti، من الشريط الجانبي، أسفل قسم Web اختر Websites. عند الدخول الأول قد تظهر لك رسالة بأنّ الميزة غير مُفعّلة بعد، اضغط على Enable لتفعيلها والسماح لـ Ajenti V القيام بعدد من عمليات الضبط اللازمة. الآن من قسم New Website لدينا مربع نصيّ بعنوان Name يمكنك فيه كتابة أي معرّف لموقعك. اضغط على الزر Create، وستلاحظ أن موقعك الجديد قد أدرج أسفل قسم Websites في أعلى الصفحة. اضغط على Manage لإدارته. من أسفل قسم Website Files غيّر srv/new-website/ إلى أي مجلد آخر، على سبيل المثال srv/example.com/ اضغط على الزر Set ثم Create Directory. تذكّر الدليل الذي ستحدّده هنا حيث سنرفع إليه الملفات بعد قليل. ومن أسفل علامة التبويب General ألغ التحديد عن خيار Maintenance mode ثم انقر Apply changes أسفل الصفحة. الآن من علامة التبويب Domains أعلى الصفحة اضغط الزر Add واكتب عنوان النطاق الخاص بك في الحقل النصيّ الظاهر ثم انقر على Apply Changes. إنشاء/رفع ملفات الموقعالآن لدينا مجلّد خاص لملفات الموقع، ويتوجب علينا إنشاء أو رفع بعض الملفات إليه. في الشريط الجانبي وأسفل القسم Tools اختر File Manager، انقر على اسم المجلد الذي أنشأته منذ قليل للدخول إليه مثل srv/example.com/ والذي سيكون فارغًا بطبيعة الحال. هنا يمكنك رفع الملفات والمجلدات التي تريد تزويد موقعك بها. لهذا الدرس التعليمي سوف نُنشئ صفحة "!Hello world" بسيطة للموقع. اضغط على الزر New File أعلى الصفحة ليظهر أمامك ملفٌ جديد باسم new file ضمن المجلد. في نهاية السطر الخاص بالملف اضغط على زر القائمة: في حقل Name غيّر القيمة new file إلى index.html ثم اضغط على Save. افتح نفس القائمة مجددًا واختر Edit لفتح الملف ضمن المحرّر النصيّ Notepad. النصّ التالي هو مثال بسيط للتأكد فقط من أنّ كل شيء يعمل كما ينبغي، وبالتأكيد يمكنك كتابة المحتوى الذي ترغب به: <!DOCTYPE html> <html> <head> <title>This website is working!</title> </head> <body> <h1>Hello, world!</h1> <p>If you can read this correctly, your website is functional!</p> </body> </html>اضغط على Save أعلى المُحرّر، لحفظ التعديلات المُدخلة. أعد الخطوة السابقة لكتابة ملفات أخرى للموقع إن رغبت، أو استخدم مدير الملفات لرفع ملفات كنتَ قد كتبتها بالفعل على جهازك. عُد إلى File Manager ثم توجّه إلى أسفل الصفحة لتجد زرًا باسم Choose File، يمكنك من هنا رفع الملفات إلى موقعك عبر مربع اختيار بسيط. تصفّح موقعكفي متصفح الويب انتقل إلى عنوان موقعك مثل http://example.com، وحالما ترى صفحة "!Hello World" التي قمنا بإنشائها قبل قليل فهذا يعني بأن كلّ شيء يعمل كما يجب. إلى هنا نكون قد أنهينا شرح كيفية إنشاء موقع باستخدام لوحة التحكّم Ajent، سنتحدث الآن عن إنشاء عناوين بريد باستخدام نطاقك الخاص. إنشاء عناوين البريدمن لوحة تحكّم Ajenti الخاصّة بك وأسفل القسم Web انقر على Mail ثم اضغط Enable إذا طلب منك. أسفل New Mailbox يتوجب عليك ملئ عدّة خانات. أدخل في المربع النصيّ Address مُعرّف عنوان البريد الذي يَسبق عادةً الإشارة @، فإذا أدخلت sammy على سبيل المثال فسيكون عنوان البريد كاملًا sammy@example.com، هناك أيضًا قائمة منسدلة لاختيار عنوان النطاق الذي سيُسجّل البريد من خلاله فيما لو كنتَ تدير عدّة مواقع باستخدام Agenti V. أبق خانة Custom domain فارغة، وبعد ذلك انقر على + Mailbox. كما ترى فإن عنوان البريد الجديد سيظهر أسفل القسم Mailboxes ضمن الصفحة. انقر عليه ثم اختر Change password لإدخال كلمة مرور جديدة لصندوقك. اضغط على ENTER ثم Apply Changes أسفل الصفحة. الآن انتقل إلى علامة التبويب Advanced من أعلى الصفحة ومن قسم TLS حدّد صندوق التفعيل بجوارها ثم انقر على Generate new certificate بعد الانتهاء اضغط Apply changes أسفل الصفحة. تزيد هذه الخطوة من آمان اتصالك بصندوق البريد وتحسّن من توافقه مع عملاء البريد الإلكتروني. لاستقبال البريد الخاص بك يمكنك الاتصال عبر أحد عملاء سطح المكتب أو الأجهزة الذكية (مثل Outlook, Thunderbird, K-9 Mail الخ) أو يمكنك تركيب RainLoop كتطبيق وِب للوصول إلى صناديق البريد الخاصة بموقعك من خلال المتصفح عبر Ajenti. إليك أخيرًا معلومات الاتصال بصندوق البريد الخاص بك لتزويدها للعميل الذي ترغب باستخدامه: Username: user@example.com Password: your_mailbox_password IMAP Server: panel.example.com IMAP Port: 143 IMAP Encryption: STARTTLS (Accept all certificates) SMTP Server: panel.example.com SMTP Port: 25 SMTP Encryption: None الخاتمةيُفترض أنك قد نجحت الآن بإنشاء موقع ويب خاص بنطاقك بالإضافة إلى صندوق بريد من خلال لوحة التحكم Ajenti والتي تُمكّنك من إدارتهما بكلّ سهولة في الوقت عينه. ترجمة -وبتصرف- للمقال: Creating a Website and an Email Account on Ajenti V لصاحبه: Jonah Aragon.
  6. المتوّقع منّنا كمساعدين عن بُعد هو التواجد على الإنترنت بشكل دائم لتلبية متطلبات عملائنا، لكن ذلك يؤثر سلبًا على الإنتاجية والصحة. لكن عندما يعتمد مخطط عملك على ذلك، هناك القليل من الخيارات المتوفرة لتكون قادرًا على أخذ استراحة بعيدًا عن الإنترنت دون أن تتأثر خدماتك بذلك، خاصة أنّك تحتاج إلى تسويقها باستمرار. لكن كيف يمكننا القيام بذلك عندما لا يتوقف عالم العمل عبر الانترنت ابدًا؟، الإجابة هي: أتمتة محتوى وسائل التواصل الاجتماعي. ستقدم لنا بريا هورتون عبر هذا المقال مجموعة من النصائح الفعّالة عن كيفية القيام بذلك. تقول بريا: هناك الكثير مما عليك فعله كمساعد عن بعد أو صاحب عمل عبر الإنترنت أو ما يشابه ذلك، الأمر الذي يجعلك غير قادرٍ على الابتعاد عن كل شيء متى ما أردت ذلك لتصفية ذهنك لبضعة أيام. خاصة إذا كان عليك التواجد يوميًا على منصات التواصل الاجتماعي أو كنت تقدم خدمات إدارة حسابات التواصل الاجتماعي، إذ عليك أيضًا الحرص على استمرار تواجد العملاء. نعلم جميعًا أهمية التواجد دائمًا على الانترنت والاستمرار بتقديم محتوى جذاب ومناسب، لكن هل يعني ذلك أنّنا لن نتمكن أبدًا من قضاء عطلة أو أخذ إجازة مرة أخرى؟ طبعًا لا، وهذا يعود جزء منه إلى تقنية بسيطة وجميلة تدعى الأتمتة! في البداية، ماذا تعني أتمتة نشر المحتوى على وسائل التواصل الاجتماعي؟ أتمتة نشر المحتوى على وسائل التواصل الاجتماعي هي تحضير عدد من المنشورات ثم جدولتها لتنشر أوتوماتيكيًا في وقت لاحق تحدّده أنت، ويمكنك القيام بذلك على جميع المنصات تقريبًا بما في ذلك فيسبوك وانستغرام وتويتر ولينكد إن وبينترست …إلخ. ستستمر بإعداد وكتابة المحتوى كما تفعل في العادة، لكن ستُعدّ وتكتب محتوى أكثر يكفي لتغطية كامل فترة إجازتك، سواء للقيام برحلة أو لقضاء الوقت مع أطفالك أو لمشاهدة التلفاز فقط. بعدئذٍ، ستستخدم الأدوات التي سنتحدث عنها عبر دليلنا هذا لجدولة جميع المنشورات وأخذ إجازتك في الوقت الذي تختاره. إليك كيف يمكنك أتمتة نشر محتواك على وسائل التواصل الاجتماعي عبر خطوتين بسيطتين: الخطوة الأولى: تحضير المحتوى إنّ الخطوة الأولى كما ذكرنا سابقًا لأتمتة محتوى وسائل التواصل الاجتماعي هو تحضير وتجميع عملك. قد يستغرق ذلك ساعة أو ثلاث ساعات تبعًا لطول المدة المراد جدولة المنشورات لها. يجب أن يكون لديك جميع المنشورات مكتوبة وجاهزة وكذلك الصور وأي روابط أو اقتباسات جميعها جاهزة للنشر. يمكنك استخدام مواقع الجدولة للقيام بذلك، مثل HootSuite أو PostPlanner أو أي مواقع جدولة أخرى. يمتلك HootSuite نسخة مجانية ويمكنك استخدامها لجدولة المحتوى على تويتر ولينكد إن وانستغرام ويوتيوب وغوغل بلاس وفيسبوك وحتى وردبريس، وبالتالي هو أداة رائعة لتغطية احتياجات على معظم المنصات. وهو واحد من مواقع الجدولة القليلة حاليًا والتي تمكّنك من الجدولة والنشر مباشرة على انستغرام. من المزايا الأخرى التي أحبها في HootSuite هو القدرة على الجدولة على منصات متعددة في الوقت نفسه، بالإضافة إلى إمكانية رؤية جميع المحتوى المجدول على شكل تقويم. PostPlanner هو موقع جدولة آخر أحبه. يمنحك القدرة على إعادة استخدام أكثر منشوراتك نجاحًا بسهولة، بحيث تتمكن من الحفاظ على أفضل منشوراتك لتعيد نشرها في المستقبل. يمكنك أيضًا كما في HootSuite النشر على عدة منصات في الوقت نفسه وكذلك رؤية محتواك المجدول على شكل تقويم بكل سهولة، لكنه يقتصر على فيسبوك وتويتر ولينكد إن فقط، لذا عليك أخذ ذلك في الحسبان. نصيحة: أنا لا أنصح باستخدام مواقع الجدولة لجدولة المحتوى على فيسبوك، لأن الخوارزمية التي يستخدمها فيسبوك قد تسبب الضرر على مدى وصول محتواك للمتابعين عندما يتم استخدام منصة أو طرف ثالث لنشر المحتوى، لذلك يفضّل أن تجدول محتواك عليه بشكل مباشر باستخدام أداة النشر المتوفرة في فيسبوك. يمكنك إيجاد ذلك الخيار بالذهاب إلى صفحة عملك على الفيسبوك ثم الضغط على "أدوات النشر" ثم "المنشورات المجدولة" ثم الضغط على "إضافة" في الأعلى، كما موضّح في الصور التالية: الجدولة على فيسبوك (الخطوة الأولى): الجدولة على فيسبوك (الخطوة الثانية): الجدولة على فيسبوك (الخطوة الثالثة): الخطوة الثانية: جدولة المحتوى الآن بعدما أن قمت بتحضير محتواك وأصبح جاهزًا للنشر، الخطوة التالية هي جدولته ليتم نشره. لجدولة محتواك اتبع الاستراتيجية التي تتبعها عادة للنشر على وسائل التواصل الاجتماعي. على سبيل المثال، إذا كنت تنشر مرة واحدة في اليوم على فيسبوك وأربع مرات في اليوم على تويتر ومرة واحدة في اليوم على انستغرام ومرة واحدة كل بضعة أيام على لينكد إن، استمر باتباع نفس هذا الأسلوب لجدولة منشوراتك للفترة القادمة. الشيء الرائع في HootSuite كما ذكرت سابقًا هو أنّه أحد مواقع الجدولة القليلة القادرة على النشر تلقائيًّا على انستغرام دون الحاجة إلى أن تتلقى تنبيهًا عندما يحين موعد النشر لتقوم أنت بذلك وتفتح التطبيق. هذا يعني أنك تستطيع جدولة جميع محتواك على انستغرام لينشر لاحقًا بشكل مباشر على انستغرام دون الحاجة إلى أن تفعل أي شيء آخر سوى جدولته. إليك بعض من نصائحي المفضلة لأتمتة وجدولة محتواك: 1. لا مشكلة في إعادة الاستخدام إعادة استخدام أفضل محتوى لديك هي طريقة رائعة لإعادة توظيف المحتوى والمنشورات التي سبق أن حققت نجاحًا لك. بالإضافة إلى ذلك سيمكّنك هذا من إعادة عرض أفضل محتوى لديك لمتابعين جدد، لأن خوارزميات معظم المنصات تمنع المتابعين من رؤية جميع منشوراتك، وبالتالي هي طريقة رائعة لعرض محتواك السابق على متابعين جدد. تمتلك العديد من مواقع الجدولة حتى أداة "لإعادة الاستخدام" لتجعل إعادة جدولة منشوراتك الناجحة أمرًا سهلًا. 2. لا تنس استخدام الوسوم (الهاشتاغات) إنّ الهاشتاغات مهمة جدًا لأنها تسمح لأشخاص آخرين خارج دائرة متابعينك برؤية محتواك. فعبر استخدام الهاشتاغات يمكن للأشخاص الوصول إلى محتواك بطرق مختلفة، بما فيها الضغط على نفس الهاشتاغ ضمن منشور آخر لشخص آخر، وبالتالي الوصول إلى منشورك باستخدام الهاشتاغ نفسه. يسمح انستغرام للأشخاص بمتابعة الهاشتاغات، وبالتالي تظهر المنشورات الرائجة الحاوية على هذا الهاشتاغ في صفحاتهم الشخصية. فإذا كان أحد الهاشتاغات التي تستخدمها في منشورك متابع من قبل شخص ما، هناك احتمال أن يظهر منشورك لديه دون أن يكون أحد متابعينك. وإذا كنت تستخدم هاشتاغات وأصبح منشورك رائجًا كفاية، فإنّه يمكنه الظهور في قائمة أفضل تسع منشورات أو في صفحة الاستكشاف الخاصة بأحد هاشتاغاتك أو أكثر. ويجب أن يكون ذلك هدفك الأول في كل منشوراتك على انستغرام، كونه الطريقة الأفضل ليتمكن أشخاص جدد من إيجاد محتواك ومتابعتك. إذا كنت في العادة تضع الهاشتاغات في التعليق الأول على منشوراتك في انستغرام، عليك التخلي عن ذلك الأسلوب عند جدولة منشوراتك (ولا تعطيك معظم الأدوات خيار جدولة التعليق الأول على انستغرام). إذا كنت قلقًا أن يبدو منشورك على انستغرام غير منظّمًا بسبب اختلاط كتاباتك وهاشتاغاتك، إليك هذه النصيحة البسيطة: اترك فراغًا (ثلاث أو أربع أسطر) بين كتاباتك والهاشتاغات، سيساعد ذلك منشورك ليبدو أكثر ترتيبًا وتنظيمًا وأقل تشابكًا. 3. اجعل التجميع والجدولة عادة لك لا تدع القيام بذلك يقتصر فقط على العطل الصيفية والأعياد. أقوم بتحضير المحتوى وجدولة جميع المنشورات الخاصة بي بوقت مسبق على الحسابات الخاصة بي وكذلك على حسابات عملائي، وأقوم بذلك عادة لأسبوعين أو حتى أحيانًا لشهر مُقدّمًا. يوفر ذلك عليّ الكثير من الوقت، وأخصص بالعادة عّدة ساعات أسبوعيًا للقيام به. احرص فقط على أن يكون لديك خطة قبل أن تجلس وتبدأ بجدولة منشوراتك. استغرق الوقت الذي تحتاجه لمعرفة أي نوع من المحتوى ستنشر، ما هي الرسومات والصور التي عليك تحضيرها وأي نوع من المحتوى عليك تجميعه (إيجاد روابط لمقالات ذات صلة أو البحث عن إحصائيات واقتباسات مثيرة للاهتمام ...إلخ). ثق بي، من السهل أن يغمرك ذلك إذا لم يكن لديك خطة واضحة في عقلك قبل أن تبدأ. لكن اعلم أنّ وسائل التواصل الاجتماعي هي حليفك وليست عدوّك. العبرة الأهم من هذا المقال هي أن تدرك أنّه يمكنك أن تبتعد عن وسائل التواصل الاجتماعي والانترنت دون أن يتضرر عملك بذلك. عليك فقط إتباع الخطوات الصحيحة والتخطيط مسبقًا، ولن يدرك متابعينك حتى أنّك في عطلة على الشاطئ وبدون تغطية منذ أربع أيام. لن تساعدك الأتمتة على الابتعاد قليلًا والقيام بمغامرات خططت لها طويًلا فقط، بل يمكنها أيضًا تزويدك بالوقت الإضافي في جميع الأيام على مدار السنة. هي واحدة من أكثر أقسام روتيني الأسبوعي فائدة، فبتخصيص بضع ساعات لجدولة المحتوى الخاص بي أسبوعيًا، أصبح لدي مرونة وحرية أكبر خلال أيامي كي لا أقلق بشأن التواجد يوميًا على الانترنت. هل لديكم أي نصائح لأتمتة محتوى وسائل التواصل الإجتماعي بشكل أفضل؟، شاركونا في التعليقات. ترجمة -وبتصرف- للمقال A Virtual Assistant’s Guide to Automating Social Media Content لصاحبته Mickey Gast
  7. مُراجعة وتحسين إعدادات خدمة الدّعم الفنّي فرصةٌ نادرة لتنظيم عمليّات الدّعم الفنّي وتخليص الفريق من العادات والعناصر غير المرغوبة التي تتراكم كما يتراكم الغبار في منفذ شحن الموبايل. إنّ هدفك الرّئيسي هو تقديم الدّعم المستمر طوال الوقت، لكن إذا توقّفت عند هذه المرحلة، فقد تضيّع فرصة تحسين مستوى الخدمة التي تقدّمها. والخطوة الأولى في تحسين تطبيق الدّعم الفنّي هي وضع بعض الأهداف، سواء كنت قد اخترت للتّو تطبيق دعمٍ فنّي جديد، أو إذا قرّرت أنّ الوقت قد حان لمُراجعة الإعدادات الحاليّة مرّةً أخرى. كيف تخطّط إعدادات الدّعم الفنّي 1. قلّل الاحتكاكات friction بالنّسبة للعملاء لا يجب أن يكون العملاء خبراء في آلية عمل تطبيق الدّعم الفنّي التي تستخدمه ليحصلوا على الدّعم. كلّما كانت تجربة وصولهم إلى إجراء محادثةٍ مع شخصٍ آخر أقرب، كلّما كان ذلك أفضل. وقد ينطوي ذلك على إعادة كتابة الرّسائل الإلكترونيّة والقوالب الافتراضيّة لتستخدم نبرتك، وإزالة أرقام التّذاكر وهويّة العميل إذا لم تكن بحاجةٍ إليها، وتبسيط أيّ شكلٍ من أشكال الدّعم أو نقاط الدّخول للسّؤال فقط عمّا يساعد حقًّا في حلّ مشاكل العملاء. 2. قلّل الاحتكاكات بالنّسبة لفريق الدّعم الفنّي إنّ كلّ مهمّةٍ زائدة، ونقرةٍ إضافيّة، وعمليّةٍ جديدة تضيفها إلى دور فريق الدّعم الفنّي تستغرق وقتًا يضيع من مساعدة العملاء بشكلٍ فعّال. قم بترتيب خدمة الدّعم الفنّي بحيث يتمّ الحفاظ على أكبر قدرٍ ممكن من الوقت والطّاقة لمساعدة العملاء. 3. قلّل من تكرار العمل يستهدف التّحسين أيّ شيءٍ تجد أنّك تعمله أنت أو فريقك مرارًا وتكرارًا. هل يمكنك أتمتة شيءٍ من آلية معالجة التّذاكر؟ هل يمكنك إضافة خطط إضافيّة لسير العمل أو ردود مكتوبة مسبقًا لمعالجة المشاكل الشّائعة؟ 4. لخّص تقاريرك يجب أن تكون لديك فكرةٌ واضحة عمّا تريد قياسه، ومن هذه النّقطة يمكنك العمل على المعلومات التي يجب عليك الحصول عليها في محادثات الدّعم الفنّي. وبوجود هذه المتطلّبات، يمكنك إعداد خدمة الدّعم الفنّي لتجمع المعلومات بأكبر قدرٍ ممكن من الانتظام والبساطة. 5. تخلّص من العناصر غير المرغوب فيها تتجمع لدى فريق الدّعم الفنّي جميع أنواع العناصر التي لم تعد هناك حاجة لها حين يكون الفريق منشغلًا. هل هنالك خطط سير العمل أو مرشحات لم تعد تستخدمها، أو ردود محفوظة قديمة أو غير دقيقة، أو حسابات لأشخاص لم يعودوا ضمن الفريق؟ يحدّ التخلّص من جميع هذه العناصر من إمكانيّة إرسال إجابةٍ خاطئة عن طريق الخطأ، ويوفّر الوقت والجّهد من خلال إظهار الخيارات والمعلومات التي يجب أن يستخدمها أفراد فريقك. القائمة المرجعيّة لإعدادات خدمة الدّعم الفنّي الدّعم الوارد راجع نماذج/صفحات طلبات الدّعم: تحقّق من الوضوح، والإيجاز والدقّة، واحرص على أنه يتم إرسال الطلبات من خلالها بشكلٍ صحيح. تحقّق من البريد الوارد: تأكّد من أنّك لا تفقد أيّ رسائل إلكترونيّة بوصولها إلى مرشحات الرّسائل المزعجة أو العناوين القديمة. راجع الإضافات integrations: قم بفحص الإضافات التي تحتاجها وإزالة الإضافات التي لم تعد تستخدمها ابحث في ملفّات المساعدة والتوثيق: يمكن أن تجد روابط إلى "اتّصل بفريق الدّعم لدينا" والتي تحتاج إلى تحديث أو تعديل لتتناسب مع إعدادات الدّعم التي تمّ تبسيطها مؤخّرًا. إدارة المحادثة أنشئ مجلّدات أو مرشحات: قم بتحديد من يجب أن يرى أيّ تذاكر، وقم بإنشاء هذه المجلّدات المرئيّة فقط. قم بتصنيفها بوضوح لئلّا يضيع فريقك الوقت في بحثا عن المُجلدات الأنسب أنشئ قوانين وخطط سير العمل: قم بأتمتة المهمّات المتكرّرة وخفّف عبء العمل عن فريق الدّعم الفنّي. راجع قوانينك الموجودة: هل هي فعّالة، وهل لا تزال مفيدة؟ قم بدمج وتصفية التّصنيفات والوسوم: عادةً ما تتضاعف الوسوم بسرعة، وغالبًا ما يكون لديك نسخ مكرّرة قريبة من بعضها يمكن دمجها مع بعضها وأخرى قديمة يمكنك إزالتها. أنقص عددها لتصل إلى الوسوم التي تحتاجها للأتمتة وكتابة التّقارير فقط. الرّسائل الصّادرة قم بتحديث قوالب البريد الإلكتروني: تحقّق من اللّغة التي تستخدمها في نبرتك ولهجتك، وقم بمراجعة الوسوم، وتحقّق من دقّة الرّوابط المتضمَّنة. لا تنس التّحقّق من التواقيع footer التي يستخدمها فريق الدّعم الفنّي في رسائلهم. حدّث ردودك المحفوظة: هل الرّدود التي تستخدمها حديثة ودقيقة؟ وهل تتوافق مع أفضل الممارسات الحاليّة لديك؟ وهل هي مصنّفة من أجل الوصول إليها بشكلٍ سهل؟ قم بتوثيق استخدامك خذ بعض الوقت الإضافي لتوثيق قراراتك بعد أن تنتهي من التّنظيف، فوجود وثائق أو ملفّات فيديو كمرجعٍ قصير أمرٌ مفيدٌ حين تقوم بتجديد فريقك الحالي وفي المرّة القادمة التي توظّف فيها أحدًا. وتتضمّن مجالات محاولة التّوثيق ما يلي ما هي التّصنيفات والوسوم التي يجب استخدامها ومتى كيف وأين تحيل المحادثات إلى أشخاص آخرين تحديد المحادثات ومعايير استخدام وإدارة الرّدود التي تمّ حفظها. إنّ مشاركة هذا التوثيق مع الفريق بأكمله يجعل الجّميع أكثر كفاءةً ويحدّ من إمكانيّات انهيار النّظام الذي نظّمته مؤخّرًا تحت كاهل الوسوم التي يتمّ استخدامها بشكلٍ خاطئ وخطط سير العمل المنهارة. عندما تكتمل الإعدادات ويعتاد فريقك على السّرعة، قم بإجراء بعض الاختبارات النّهائيّة لتتأكّد من أنّ كلّ شيءٍ يعمل كما هو متوقَّع. اختبار الإعدادات الجّديدة قم بإعداد حساب بريد إلكتروني مجّاني وأرسل أسئلة اختبار إلى فريق الدّعم الفنّي ليجيبوا عليها باستخدام الإعدادات الجّديدة. وابدأ باختبار ما يلي خطط سير العمل والأتمتات المحفَّزة triggered automation: قم بإنشاء نماذج للأسئلة التي يجب أن تستجيب لها القواعد التي سطّرتها لتتأكّد من أنّها تعمل كما هو متوقَّع. مجموعة من الأسئلة النّموذجيّة: يساعد استخدام أسئلةٍ واقعيّة في ضمان أن تكون لديك أكثر الوسوم والتّصنيفات استخدامًا مُعَدّة مسبقًا. مختلف أنواع العملاء: إذا كنت تقسّم الاستفسارات الواردة بناءً على الفئة التي ينتمي إليها العميل، قم بإنشاء نماذج لكلّ فئةٍ لتتمكّن من تأكيد ظهورها للأشخاص المناسبين. اطلب من أحد الزّملاء أن يقوم بقراءة التوثيق الدّاخلي internal documentation ويستخدمها لمعالجة بعض المحادثات الواردة للتّأكّد من أنّ التوثيق دقيق وكافٍ. وأخيرًا، قم بالرّد على الرّسائل الإلكترونيّة الواردة وراجع تجربة العملاء. هل تمّ تسليم الرّسائل الإلكترونيّة بشكلٍ صحيح، وهل تحتوي على التّفاصيل الصّحيحة؟ إنّ عمليّة تحسين خدمة الدّعم الفنّي لا تنتهي أبدًا، لكنّ التّغيير في أدوات الدّعم الفنّي فرصةٌ للحدّ من الإجراءات، والتّخلّص من بعض البيانات، ويتيح للفريق قضاء وقتٍ أقلّ في العبث بأدواتهم ووقتٍ أكثر في مساعدة العملاء. بعد أن تقوم بتحسين إعدادات الدّعم الفنّي، ضاعف تركيزك على إنشاء خدمة دعمٍ فنّي أكثر سلاسةً للعملاء من خلال تصميم صفحاتٍ أفضل للتّواصل. ترجمة -وبتصرّف- للمقال Optimizing Your Help Desk Setup لصاحبه Mathew Patterson حقوق الصورة البارزة محفوظة لـ Freepik
  8. هل أنت مدرك للخطوات التي يتخذها العميل حتى يوظفك؟ وما الذي يجمع بينكما في النهاية؟ ربما تهدر الكثير من الوقت في فعل وتوضيح نفس الأشياء مرارًا وتكرارًا لكل عميل محتمل. أعلم أنني كنت أقوم بذلك، فقد عملت مع العملاء منذ زمن طويل (حوالي 100,044 سنة انترنيتية)، لذا قررت منذ بضعة أشهر تغيير هذا الوضع وجعل أكثر من نصف عملية جلب العملاء المهتمين لتوظيفي لتنفيذ مشاريع تصميم ويب تتم بشكل آلي. أحبّ إجراء التّجارب. حيث أنني لم أرضَ أبدًا على آلية عمل أي شيء، وأحاول دومًا تغيير الأمور لمعرفة إذا كان هناك شيء ما آخر يعمل بشكل أفضل. لكن على الرغم من ذلك لم أغيّر أي شيء في عملية تأهيل العملاء منذ بدء عملي الحر. وهكذا كانت تتم العملية عادةً: يجد العميل اسمي ورابط موقعي في أسفل الموقع الذي يزوره. ينقر العميل على كلمة "تصميم" في موقعي ويشاهد معرض أعمالي. في حال أُعجب العميل بعملي فإنه يتواصل معي -أحيانًا يرسل رسالة إلكترونية قصيرة وغامضة وأحيانًا يرسل مقالة من 10 صفحات تشرح كل شيء بالتفصيل بدءً من كيف ولماذا بدأ بمشروعه التجاري انتهاءً بالحديث عن حيواناته الأليفة. أرد على رسالته عندما أجد الوقت لذلك وأطلب منه تعبئة مخطط المشروع (وهو عبارة عن وثيقة على Google Doc قمت بإنشائها خصيصًا لهذا الغرض). يراسلني العميل مجددًا بعد تعبئة المخطط ليعلمني بذلك. أراسله من جديد لاقتراح موعد محادثة على السكايب (التاريخ والوقت). ويتكرر الأمر عدة مرات لنتفق في النهاية على موعد يناسبنا سويةً. نتحدث عن المشروع على سكايب حوالي 30-40 دقيقة. ثم اكتب تقرير العمل الذي يفصلّ ثلاثة أشياء: السعر، المخرجات النهائية للعمل (ما الذي سأسلّمه له) والتوقيت. يوقع العميل عليه ويرسل لي دفعة أولى لتحديد تاريخ البدء. أرسل له قائمة بالمهام التي تحتاج إلى الإنجاز قبل أن نبدأ. نبدأ العمل على المشروع. تحتاج كل خطوة من هذه الخطوات الـ 12 إلى القليل من العمل، وبعد كتابتها كان من الواضح أنه من الممكن جعل أول 7 خطوات تتم بشكل آلي، مما يجب أن يوفر الكثير من الوقت ويعطي العميل المحتمل المعلومات التي يحتاجها بسرعة لمعرفة فيما إذا كنت ملائمًا لمشروعه. التأهيل Onboarding، تعريف موجز التأهيل Onboarding هو مصطلح مستعمل في الموارد البشرية للموظفين الجدد، واستخدم فيما بعد من قبل مستسرعي النمو Growth Hackers ومطوري التطبيقات للإشارة إلى تبني وتوجيه الزبون الجديد. تنقسم هذه العملية غالبًا إلى ثلاثة أجزاء: التجهيز، الاستيعاب، والتسريع. التجهيز هو إعطاء الأشخاص الجدد الأدوات لاستخدام ما سجلوا من أجله. لذا عندما تسجل في الانستغرام تعلّمك الشاشات القليلة الأولى كيف تستخدم التطبيق -هذه هي عملية التأهيل الخاصة بهم. وقد وثق Samuel Hulick ذلك: الاستيعاب هو مساعدة المستخدم الجدد على الشعور بأنه ينتمي إلى مجموعة الأشخاص المخلصين لذلك الشخص، الشركة أو التطبيق. وقد فعلت شركة Zappos ذلك من خلال إجراء حلقة تدريبية للموظفين الجدد عن قيم الشركة، حيث لا تعلمهم الشركة ما تقوم به فقط وإنما بما تشعر بأنه مهم أيضًا، إضافة إلى منحهم خيار في نهاية الدورة لأخذ 2000$ نقدًا ومغادرة الشركة. وكما يبدو فإن 1% فقط يغادرون. التسريع هو جعل الشخص الجديد ينضم بسرعة إلى المجتمع الحالي. وأنا أقوم بذلك في قائمتي البريدية من خلال إرسال رسالة ترحيب مخصصة جدًا. لقد استهلكت الكثير من الوقت على هذه العملية وصياغة ما يحدث عندما يشترك شخص ما في قائمتي البريدية، وصياغة رسالة الترحيب، والتي تؤتي ثمارها بشكل كبير جدًا بما يتعلق بتفاعل وبقاء المشتركين. تبدو كل تلك الأشياء في الأعلى نظرية أو حتى مُبهمة بعض الشيء، لكن في جوهرها تحاول جعل الشخص الجديد يشعر بأنه موضع ترحيب، وإعطائه الأدوات التي يحتاجها ليصل إلى ما يريد والتأكد من أنه في المكان الصحيح. إن جعل عملية التأهيل تتم بشكل آلي سيوفر الكثير من الوقت في حال تنفيذها بشكل صحيح. إضافة إلى كونها تقوي التواصل والالتزام من جانب المستخدم. عملية التأهيل الجديدة الخاصة بي هنا تجد الكيفية التي صممت بها عملية التأهيل الخاصة بي لجعلها تتم بشكل آلي ومفيد قدر الإمكان: يجد العميل اسمي ورابط موقعي في أسفل الموقع الذي يزوره. ينقر العميل على كلمة "تصميم" في موقعي ويشاهد معرض أعمالي. في حال أُعجِب العميل بعملي فإنه يُدخل اسمه وبريده الإلكتروني ويتلقى رسالة تحتوي على ملف "البدء" بصيغة PDF، ويتم إضافة معلومات العميل إلى قائمة MailChimp البريدية (مجانية) التي لا ترسل رسائل اعتيادية وإنما ترسل ملف "البدء" بشكل آلي وتُتابع فيما إذا نقر عليه العميل أو لم ينقر. يوضح ملف البدء بشكل مفصلّ أسعاري، آلية عملي، نوعية المشاريع التي أنفذها (ونوعية المشاريع التي لا أنفذها)، كما يجيب على جميع الأسلة الشائعة التي يسألها العملاء عادةً عبر البريد الإلكتروني أو الهاتف. ويتضمن الكثير من توصيات العملاء. يوجد في نهاية ملف البدء رابط لتعبئة مخطط المشروع. مخطط المشروع هو نموذج مستضاف على موقع typeform.com (مجاني) لا يحتاج إلى إعادة توليده لكل شخص جديد، ويتم تخزين إجابات العميل وإعلامي برسالة إلكترونية عند الانتهاء. عند الانتهاء من تعبئة النموذج، تظهر الشاشة الأخيرة التي تحتوي على رابط لتحديد موعد مكالمة سكايب. يوجد نموج حجز مكالمة سكايب في نظام يدعى youcanbook.me (مجاني) والذي يقوم بالمزامنة مع Google Calendar (بالتالي يُظهر فقط أوقات الفراغ في أيام محددة)، وبعد أن يختار وقت فارغ بالنسبة لي نقوم بتبادل رسائل البريد الإلكتروني للتأكيد على الموعد والتذكير. وتتم بقية الخطوات بشكل مشابه للعملية السابقة، حيث يتم إجراء المكالمة وفي حال الاتفاق أكتب تقرير العمل وأحصل على الدفعة المسبقة وأبدأ العمل. ما وجدته في الأشهر القليلة الأولى من تنفيذ الأمور على هذا النحو أن تخوفي من تأجيل العملاء المُحتملين للعمل معي بسبب عدم التواصل معي بشكل فعلي منذ البداية لم يكن في مكانه. حيث سألت كل شخص أتمَّ العملية "هل استمتعت بهذه العملية؟ وهل كان كل شيء على ما يرام على الرغم من أننا لم نتواصل بشكل شخصي حتى المكالمة؟" وكان الجميع سعيدين تمامًا ﻷن العملية كانت سريعة وأجابت على أسئلتهم، وشعروا بالراحة حقًا. ومن أصل ستة أشخاص قاموا بالعملية الجديدة، وظّفني 5 أشخاص لتنفيذ مشاريعهم أما الشخص السادس لم ينتبه إلى أنني غير متاح للعمل لمدة أربع أشهر ولا يستطيع الانتظار كل هذا الوقت. بالنسبة لهؤلاء الأشخاص الستة، فقد وفّرت ساعات من الوقت ﻷنه لم يكن علي الرد على أسئلة أجبت عليها مئات المرات من قبل أو الدخول في حفلة تبادل الرسائل الإلكترونية لتحديد موعد مكالمة السكايب. إن عملية استيعاب الناس بشكل آلي تسمح لهم بالحصول على المعلومات التي يحتاجونها عن عملي التجاري في الوقت الذي يناسبهم. وأنا أقوم بهذه العملية من خلال الإجابة على كل الأسئلة الشائعة التي سبق وأن طُرحت عليّ عن طريق "ملف البدء" المفيد (والمصمم بشكل جيد). وأسرّع العملية عن طريق استخدام أدوات مجانية تسمح للعميل بالانتقال من مرحلة الاطلاع إلى إجراء مكالمة تأكيد المبيع خلال دقائق قليلة (والتي لا تتطلب أي عمل يدوي من طرفي). ترجمة وبتصرف للمقال User onboarding: not just for HR and growth hackers لصاحبه Paul jarvis.
  9. يهدف المسوّقون في عصر التّسويق باستخدام البريد الإلكتروني إلى تقديم ما يريده المشتركون بالضّبط. وتمهّد التكنولوجيا الطّريق لذلك، حيث تسمح أتمتة البريد الإلكتروني وتخصيصه للمسوّقين بإنشاء حملات ملفتة للانتباه تجذب المشتركين. لقد أصبحت الدّورات التعليمية عبر البريد الإلكتروني تلاقي رواجًا، وخاصّةً بالنّسبة للشّركات التي تقدّم خدماتها لشركات أخرى (B2B) التي يجب عليها تثقيف متابعيها حتى تتمكّن من بيع منتجاتها لهم. وفي هذه الدّورات، يقوم المشتركون بالتّسجيل ليستلموا رسائل بريديّة يوميّة، أو أسبوعيّة، أو شهريّة تهدف إلى تثقيفهم حول موضوعٍ ما. وهي أشبه بسلسلة تدوينات مصمّمة بشكلٍ خاص وتصل مباشرةً إلى صندوق بريدهم الإلكتروني. تشجّع الدّورات عبر البريد الإلكتروني على التّفاعل، كما أنّها تساعد في التعرّف جيدًا على علامتك التّجاريّة. كيف يمكنك كمسوّق أن تستخدم الدّورات التعليمية عبر البريد الإلكتروني؟ سوف نستعرض خمسة أشياء عليك معرفتها عند إنشاء سلسلة آليّة من الدّروس عبر البريد الإلكتروني. ما هو مبدأ عمل سلاسل دروس البريد الإلكتروني الآلية؟ تعتمد سلسلة البريد الإلكتروني الآليّة على الأتمتة، حيث يقوم المشترك بالتّسجيل في الدّورة، ومن ثمّ يتلقّى رسائل إلكترونية بشكلٍ منتظم. ويمكنك بهذه الطّريقة أن توصل المحتوى إلى المشتركين وتزوّدهم بالمعرفة. يمكن أن تعمل الدّورات عبر البريد الإلكتروني بمعزل عن الجّهود الأخرى التي تُبذًل في مجال التّسويق بالبريد الإلكتروني، وأن تكون موجّهة إلى حدٍ كبير إلى مجموعاتٍ معيّنة. تستطيع مثلًا إنشاء دورة عبر البريد الإلكتروني للعملاء الجدد لمساعدتهم على التّفاعل مع الخدمات التي تقدّمها. كما يمكنك إنشاء دورة للعملاء المحتملين تقدّم فيها لمحة جديدة عن المجال الذي تنشط فيه مما يجعل شركتك تظهر بمظهر الرّائد في هذا المجال. تقدّم شركة Campaign Monitor دورة مؤتمتة عبر البريد الإلكتروني، حول التّسويق بالبريد الإلكتروني، وهي تتضمّن 9 دروس لمساعدة المسوّقين على تعلّم كيفية إرسال حملة تسويق عبر البريد الإلكتروني تحقّق النّتائج المطلوبة. يستلم المشترك بعد قيامه بالتّسجيل رسائل بريديّة تعلّمه مجموعة متنوّعة من التّكتيكات، وتصل الرّسائل وفقًا لتوقيت محدّد. الدّرس الأوّل: أفكار لعناوين رائعة للرّسائل الدّرس الثّاني: نصائح وحيل للكتابة الدّرس الثّالث: مواقع مجّانيّة للحصول على صور مذهلة لللحملات التّسويقيّة البريد الإلكتروني الدّرس الرّابع: كيفيّة استخدام لوح جوجل التّحليلي Google Analytics Dashboard في التّسويق بالبريد الإلكتروني الدّرس الخامس: كيف نحصل على زيادة بنسبة 127% في النّقرات على روابط الرّسائل click-throughs من خلال إعادة تصميم قوالب البريد الإلكتروني الدّرس السّادس: كيف استخدَم موقع ConversionLab البريد الإلكتروني لتحويل الزوّار الضّائعين إلى إيرادات بقيمة $120,000 الدّرس السّابع: كيف يستخدم BuzzFeed التّسويق بالبريد الإلكتروني لدفع عجلة النّمو الهائل الدّرس الثّامن: كيفيّة دمج تطبيقات الأعمال مع أداة التّسويق عبر البريد الإلكتروني الدّرس التّاسع: كيفيّة اختيار برنامج التّسويق بالبريد الإلكتروني المناسب لنشاطك التّجاري. 1. اختر موضوعا يثير اهتمام متابعيك تهدف الدّورة عبر البريد الإلكتروني إلى تعليم المتابعين شيئًا لا يعرفونه من قبل، لكنّهم مهتمّون بتعلّمه، ويجب عليك أن تفكّر مليًّا عند اختيار الموضوع. يمكنك أوّلًا أن تبحث عن المُحتوى الذي سبق وأن عرف رواجًا جيّدًا على مدوّنتك، أو إجراء بعض الأبحاث حول الكلمات المفتاحيّة الأكثر استخدامًا من طرف مُتابعيك، أو التحدّث مع العملاء بشأن أبرز الصّعوبات التي يواجهونها. تعيد معظم الشّركات استخدام محتوى موجود في مدوناتها أو قواعد المعرفة لديها في دورات البريد الإلكتروني. قام موقع Close.io، وهو نظام إدارة العلاقات مع العملاء CRM موجّه لفرق المبيعات الصّغيرة، بإنشاء دورة عبر البريد الإلكتروني حول مبيعات الشّركات النّاشئة، وخاصّة أنّ فريق العمل في الموقع يعرف تمامًا أهميّة ذلك بالنّسبة للمتابعين. وتكوّنت الدّورة من 13 رسالة بريد إلكتروني، كما تجاوز معدّل فتح معظمها 55%. لدى موقع Buffer عدد من الدّورات عبر البريد الإلكتروني، وتتضمّن ( كيف تصبح خبيرًا على وسائل التّواصل الاجتماعي)، وهي دورة مدّتها 10 أيّام وتساعد المسوّقين على معرفة المزيد عن وسائل التّواصل الاجتماعي. تعلمك هذه الدّورة متى وكيف تنشر على الشّبكات الاجتماعية، وأنواع التّقارير التي يجب أن تريها لمديرك. إنّ تركيز موقع Buffer على هذا الموضوع أمرٌ جيّد، خاصّةً وأنّ منتَجهم عبارة عن برنامج لجدولة المنشورات على وسائل التّواصل الاجتماعي. 2. قم بالترويج للدورة عبر البريد الإلكتروني كما لو أنها منتج يُعَدّ إنشاء دورة عبر البريد الإلكتروني بدايةً جيّدة، وخاصّةً إذا كنت تملك المحتوى بالفعل. ولكن إذا أردت النّجاح، فعليك التّرويج للدّورة التّعليمية كما لو أنّها كانت منتَجًا مستقلًا بذاته. ممّا يعني أنّه عليك تصميم وبناء صفحة هبوط landing page مقنعة، دراسة جدوى تخصيص ميزانية للتّرويج على وسائل التّواصل الاجتماعي، وإضافة دعوة إلى الإجراء في نهاية منشورات المدوّنة لتشجيع القرّاء على التّسجيل. تروّج شركة Campaign Monitor لدورة تعليمية لهامن خلال دعوة إلى الإجراء Call to action في نهاية المنشورات المرتبطة بالموضوع في المدوّنة، وتوصل تلك الدّعوة إلى صفحة هبوط يمكن للنّاس التّسجيل من خلالها. وتبدو الدّعوة إلى الإجراء على الشّكل التالي: أمّا صفحة الهبوط فتبدو على الشّكل التّالي: قد تستمر الدّورة عبر البريد الإلكتروني في جني الفوائد بعد إنشائها بوقتٍ طويل، أي كما هو الحال بالنّسبة للمنتَج. فبعد أن تقوم بإعداد الدّورة عبر البريد الإلكتروني، يمكنك استخدامها لتثقيف العملاء لفترة طويلة. 3. استخدم أسلوب تحرير يجعل الرسائل ممتعة ومفيدة عند إنشاء دورة تعليمية عبر البريد الإلكتروني، يجب أن تحرص على أن تكون قراءة الرّسائل تلك ممتعة. وننصح باستخدام مجموعة المبادئ التّالية للقيام بذلك، بالإضافة إلى قضاء ما يكفي من الوقت في صياغة الدّروس. يمكنك تجربة ما يلي في الكتابة: استخدم صيغة مشكلة- نقاش-حل: اعرض المُشكل الذي تُعالجه، ناقش تأثير المُشكل على النشاطات التّجارية الخاصّة بالقرّاء، ومن ثم قدّم حلّا للمُشكلة. قم بإجراء التّجارب باختبارات A/B. استخدم اسم شخص حقيقي في خانة المُرسل (كأن تُرسل الرّسائل باسم مؤسس الشّركة أو المسؤول عن التّسويق فيه). 4. لا تثقل كاهل المشتركين بالإكثار من المحتوى يهتمّ المشتركون الذين يقومون بالتّسجيل في دورة عبر البريد الإلكتروني بالحصول على المعلومات، لذا لا تثقل كاهلهم بالإكثار من المحتوى. عليك أن تحترم المشتركين وتعطيهم ما يريدونه. ممّا يعني أنّه عليك جعل الرّسائل البريديّة التي ترسلها قصيرة. كما أنّه يجب عليك أن توضّح عدد الرّسائل التي سيتلقّونها منذ البداية. تُعلِم شركة Campaign Monitor المشتركين أن دورة البريد الإلكتروني لديها تتكوّن من 9 أجزاء منذ البداية لكي يعرفوا ما الذي عليهم أن يتوقّعوه. 5. أخبر المشتركين بالخطوة التالية حين تنتهي الدورة يهدف إنشاء الدّورات عبر البريد الإلكتروني إلى تقديم الفائدة للمشتركين. إذا كنت تريد أن تؤدّي دورتك إلى تحويلات، مهما كان تعريفك لتلك التّحويلات، فعليك توجيه المشتركين إلى الخطوة التّالية. يمكن أن تشجّعهم على التّواصل مع فريق المبيعات لديك، أو التّسجيل في دورة أخرى، أو مشاركة الدّورة على وسائل التّواصل الاجتماعي، أو قراءة صفحة الهبوط حول الخدمات التي تقدّمها. لا تتركهم معلَّقين، ونهاية الدّورة فرصةٌ رائعة لإعادة جذب المشتركين. في نهاية الدّورة عبر البريد الإلكتروني، يقدّم موقع Campaign Monitor للمشتركين فرصة التّسجيل للحصول على حساب مجّاني. الخلاصة يمكن أن تثقّف متابعيك من خلال سلسلة رسائل البريد الإلكتروني الآليّة، ليقوموا باتّخاذ قرارات واعية. وتُظهِر الدّورة التّعليمية عبر البريد الإلكتروني أنّ لك تأثيرًا في هذا المجال، ومن خلالها يتعرّف المشتركون أكثر على علامتك التّجاريّة. ومن المرجّح أن يختارك طلّابك عندما يحين وقت الشّراء. ترجمة -وبتصرّف- للمقال 5 Things to Know When Creating an Automated Email Series لصاحبه AARON BEASHEL.
  10. يعتبر Ansible حلًا مناسبًا لأتمتة الأعمال التقنية البسيطة، فإن وجدت نفسك تقوم بتثبيت ووردبريس بشكل متكرر ومُمل، فقد يوفّر عليك Ansible الكثير من الوقت، وباستخدام بعض الأسطر بلغة YAML (وهي لغة توصيف واضحة ومباشرة) سنقوم بأتمتة عملية تثبيت ووردبريس على خادوم يعمل بنظام تشغيل Ubuntu 14.04، وفق الخطوات بصورة أوتوماتيكية. سنستخدم خادومين: أحدهما الخادوم الباني ويتم تشغيل Ansible عليه، والآخر الذي سنقوم بتثبيت ووردبريس عليه باستخدام Ansible. المتطلبات الأولية قبل المتابعة في المقال، سنحتاج للأمور التالية: خادوم يعمل بنظام تشغيل Ubuntu 14.04. سنقوم بتثبيت Ansible على هذا الخادوم (ونشير إليه في المقال بـ الخادوم الباني). سنقوم بتسجيل الدخول إلى هذا الخادوم وجميع الأوامر والملفّات المذكورة في المقال على هذا الخادوم، خادوم آخر يعمل بنظام تشغيل Ubuntu 14.04. سنقوم بتثبيت ووردبريس عليه باستخدام Ansible (وسنشير إليه في المقال بـ خادوم ووردبريس)، حساب مستخدم عادي -على كِلا الخادومين- لا يملك صلاحيات مدير نظام، لكنّه يملك صلاحية تنفيذ الأمر sudo، إضافة مفتاح SSH الخاص بالمستخدم -الذي أنشأناه على الخادوم الباني- إلى المفاتيح المصادقة authorized_keys للمستخدم الذي أنشأناه على خادوم ووردبريس، وينبغي تنفيذ هذه العملية على الخادوم الباني ورفع المفاتيح إلى خادوم ووردبريس. تنفيذ أوامر sudo بدون تأكيد باستخدام كلمة مرور إنّ من الأسرع -ولكن أقل أمانًا- تنفيذ أوامر sudo على خادوم ووردبريس بدون الحاجة لإدخال كلمة مرور تأكيد في كل مرّة. لإعطاء المستخدم على خادوم ووردبريس هذه الإمكانية، سنقوم بتعديل ملف sudoers باستخدام الأمر visudo على سطر الأوامر: $ visudo ومن ثم سنضيف السطر التالي في نهاية الملف: sammy ALL=(ALL) NOPASSWD: ALL ملاحظة: لا تنس استبدال اسم المستخدم (sammy في هذه الحالة) باسم المستخدم الموجود لديك، وتأكد من وضع السطر في نهاية الملف حتى لا يتم تجاوزه بالصلاحيات الافتراضية الموجودة في الملف. نصيحة: قم دومًا باستخدام الأمر visudo عند تعديل ملف sudoers، لأن الأمر سيقوم بالتحقق من التعديلات قبل حفظ الملف ويحميك بالتالي من ارتكاب أخطاء في الملف قد تؤدي إلى منعك من الدخول. حالما تنتهي من تنفيذ العملية السابقة سيغدو بإمكانك تنفيذ الأمر التالي على خادوم ووردبريس بدون إدخال كلمة مرور لتأكيده: $ sudo echo "Hello" وفي بقية المقال، تستطيع تنفيذ الأمر ansible-playbook بدون المُعامل K- كي تتجنب الحاجة لإدخال كلمة المرور للتأكيد بشكل يدوي: $ ansible-playbook playbook.yml -i hosts -u sammy الخطوة الأولى: تثبيت Ansible سنقوم الآن بتثبيت Ansible على الخادوم الباني، ونبدأ بتسجيل الدخول عبر SSH إلى الخادوم وتنفيذ الأمر التالي: $ sudo apt-get install ansible -y وتستطيع التأكد من تثبيت Ansible بتنفيذ الأمر: $ ansible --version حيث ينبغي أن يكون الخرج مشابهًا (وليس بالضرورة مطابقًا) لما يلي: ansible 1.5.4 الخطوة الثانية: إعداد بنية الملفات الآن وبعد أن انتهينا من تثبيت Ansible، دعونا نقوم بإعداد بنية الملفات من أجل Ansible playbook. سنقوم بإنشاء مجلّد على النحو التالي: $ cd ~ $ mkdir wordpress-ansible && cd wordpress-ansible سنقوم الآن بإنشاء ملفّين: الأول يدعى playbook.yml (حيث سنقوم بكتابة الأوامر الخاصة بتثبيت ووردبريس فيه) والثاني يدعى hosts (وهذا يُخبر Ansible عن الخواديم التي سيتم تنفيذ الأوامر عليها): $ touch playbook.yml $ touch hosts إنّ من الأفضل فصل الأوامر بحسب الأدوار، ومن الممكن اعتبار الأدوار كأجزاء من الممكن إعادة استخدامها، وسنقوم في هذا المشروع بإنشاء 4 أدوار: server php mysql wordpress سنقوم بإنشاء مجلد الأدوار في الجذر الرئيسي للمجلد الذي أنشأناه سابقًا wordpress-ansible/~ بتنفيذ الأمر التالي: $ mkdir roles && cd roles والآن سنقوم بتجهيز الأدوار باستخدام أداة من أدوات Ansible تدعى ansible-galaxy، حيث سنقوم من أجل كل دور بتنفيذ الأمر ansible-galaxy init كالتالي: $ ansible-galaxy init server $ ansible-galaxy init php $ ansible-galaxy init mysql $ ansible-galaxy init wordpress ستلاحظ بأن هذا الأمر سيقوم بإنشاء هيكل ملفات متكامل لكل دور من الأدوار، وهذه الخطوة هي إحدى الأمور التي ينصح بها في توثيق Ansible. ما يهمّنا غالبًا هو التعامل مع محتوى ملف tasks/main.yml لكل دور. عند الوصول إلى هذه المرحلة سيكون لدينا الهيكل التالي: [.] |_ playbook.yml |_ hosts |_ [roles] |_ [server] |_ ... |_ [php] |_ ... |_ [mysql] |_ ... |_ [wordpress] |_ ... الخطوة الثالثة: إنشاء الـ Playbook سنقوم الآن بكتابة الأوامر التي ستقوم بتثبيت ووردبريس على خادوم ووردبريس. ملف المخزون hosts يُخبر هذا الملف Ansible بالخواديم التي نرغب بتثبيت ووردبريس عليها، ومن الممكن تنفيذ الأوامر للخواديم أو مجموعة الخواديم المعرّفة في ملف المخزون hosts. سنقوم بتحرير ملف hosts باستخدام محرر nano أو أي محرر آخر تفضّله وكتابة التالي: [wordpress] wordpress_server_ip ملاحظة: من الممكن وضع أي عدد نرغب به من العناوين الرقمية IPs تحت مجموعة [wordpress]. سيؤدي هذا إلى تنفيذ الأوامر على جميع الخواديم المذكورة على افتراض أننا نملك صلاحية استخدام هذه الخواديم. سيمكّننا هذا من تثبيت ووردبريس على أي عدد من الخواديم دفعة واحدة. ملف Playbook يمكن اعتبار هذا الملف كتعريف لتطبيق ووردبريس الذي سنقوم بتثبيته. سيحتوي الملف على جميع الأدوار التي قمنا بإنشائها بغرض تجهيز تطبيق مفيد (ووردبريس في حالتنا). سنقوم بداية بتحرير الملف باستخدام محرر nano أو أي محرر آخر ترغب به: $ nano ~/wordpress-ansible/playbook.yml ومن ثم سنضيف المحتويات التالية إلى الملف، والتي ستُخبر Ansible أية أدوار سيتم تنفيذها على أية خواديم (سيتم تنفيذ الأدوار المذكورة في حالتنا على مجموعة العناوين الرقمية المدرجة في مجموعة wordpress المسجّلة في ملف hosts الذي أنشأناه سابقًا): - hosts: wordpress roles: - server - php - mysql - wordpress والآن لنعد إلى الجذر الرئيسي: $ cd ~/wordpress-ansible/ سنتأكد الآن من أنه من الممكن إجراء اتصال ما بين الخادوم الباني وخادوم ووردبريس من خلال تنفيذ ملف playbook الذي لن يقوم بأي شيء سوى التحقق من الاتصال: $ ansible-playbook playbook.yml -i hosts -u sammy -K ستُطالب بإدخال كلمة المرور لتأكيد الأمر، ولا تنس أن تقوم باستبدال اسم المستخدم بالموجود لديك. سيظهر لنا خرج يشبه التالي عند تنفيذ الأمر: ansible-playbook playbook.yml -i hosts -u sammy -K PLAY [wordpress] ************************************************************** GATHERING FACTS *************************************************************** ok: [188.166.68.134] PLAY RECAP ******************************************************************** 188.166.68.134 : ok=1 changed=0 unreachable=0 failed=0 والذي سيؤكد لنا بأن الاتصال قد تم بنجاح، دون أن يتم تنفيذ أي تعديلات لأننا لم نقم بتحديد أي أوامر لتنفيذها حتى الآن. إن فشل تنفيذ الأمر فتأكّد من أن باستطاعتك تسجيل الدخول إلى خادوم ووردبريس من الخادوم الباني باستخدام مفتاح SSH الذي قمت بنسخه في البداية. الخطوة الثالثة: إنشاء الأدوار دور Server سنقوم بداية بتعريف الأوامر التي سيتم تنفيذها على الخادوم ولهذا الغرض سنقوم بتحرير أوامر دور server. ستقوم الأوامر التي سنصرّح عنها بتثبيت جميع البرمجيات التي سنحتاجها على السيرفر الهدف. نبدأ بتنفيذ الأمر التالي: $ nano roles/server/tasks/main.yml قم بإضافة المحتويات التالية وتأكد من وجود سطر واحد فقط يحتوي على --- (حيث يوجد هذا السطر سلفًا بشكل افتراضي): --- - name: Update apt cache apt: update_cache=yes cache_valid_time=3600 sudo: yes - name: Install required software apt: name={{ item }} state=present sudo: yes with_items: - apache2 - mysql-server - php5-mysql - php5 - libapache2-mod-php5 - php5-mcrypt - python-mysqldb سيقوم المحتوى السابق بما يلي: تحديث خبء apt-cache (تنفيذ الأمر apt-get update)، تثبيت Apache ،MySQL ،PHP وبرمجيات أخرى مرتبطة باستخدام apt-get install. وإن كنت مهتمًّا بمعرفة تفاصيل ما نقوم بتثبيته، فيمكنك الاطلاع على هذا المقال حول تثبيت LAMP على Ubuntu 14.04 بشكل يدوي. سنقوم الآن بتنفيذ ansible-playbook مرة أخرى على النحو التالي: $ ansible-playbook playbook.yml -i hosts -u sammy -K ويفترض هذه المرة أن يكون الخرج بما يشبه التالي: ansible-playbook playbook.yml -i hosts -u sammy -K PLAY [wordpress] ************************************************************** GATHERING FACTS *************************************************************** ok: [188.166.68.134] TASK: [server | Update apt cache] ********************************************* ok: [188.166.68.134] TASK: [server | Install required software] ************************************ changed: [188.166.68.134] => (item=apache2,mysql-server,php5-mysql,php5,libapache2-mod-php5,php5-mcrypt,python-mysqldb) PLAY RECAP ******************************************************************** 188.166.68.134 : ok=3 changed=1 unreachable=0 failed=0 وبعد التنفيذ، ينبغي أن تكون قادرًا على استعراض الصفحة الافتراضية لـ Apache عبر فتح العنوان http://wordpress_server_ip في المتصفح. ملاحظة: إن توقّف تنفيذ الأمر بشكل نهائي عند سطر [TASK: [server | Update apt cache فمن المحتمل أن يكون هناك نقص في الصلاحيات المطلوبة على الخادوم الهدف، لذا تأكّد من أن الوصول باستخدام sudo تم إعداده بشكل صحيح على خادوم ووردبريس. دور PHP سنقوم الآن بتجهيز الأوامر التي تستهدف PHP، ولهذا الغرض سنقوم بتحرير الملف الخاص بهذا الدور: $ nano roles/php/tasks/main.yml ومن ثم سنضيف المحتوى التالي (تأكّد من وجود سطر واحد فقط يحتوي على --- في بداية الملف): --- - name: Install php extensions apt: name={{ item }} state=present sudo: yes with_items: - php5-gd - libssh2-php سيقوم المحتوى السابق بتثبيت الملحقات extensions الضرورية لـ PHP وهي: php5-gd و libssh2-php. دور MySQL سنقوم الآن بإعداد قاعدة بيانات MySQL لموقع ووردبريس، وذلك في دور mysql. سنحتاج من أجل القيام بذلك إلى بعض المتغيّرات، والتي من الممكن تخزينها في ملف المتغيرات الافتراضية defaults/main.yml: $ nano roles/mysql/defaults/main.yml سنضيف في الملف اسم قاعدة البيانات، اسم المستخدم الخاص بالقاعدة، كلمة المرور الخاصة بالمستخدم وبنفس الترتيب، ولا تنس أن تستخدم كلمة مرور معقّدة لأغراض أمنية: --- wp_mysql_db: wordpress wp_mysql_user: wordpress wp_mysql_password: wp_db_password والآن نستخدم nano لتحرير ملف المهام: $ nano roles/mysql/tasks/main.yml ونضيف المحتوى التالي: --- - name: Create mysql database mysql_db: name={{ wp_mysql_db }} state=present - name: Create mysql user mysql_user: name={{ wp_mysql_user }} password={{ wp_mysql_password }} priv=*.*:ALL يقوم المحتوى السابق بـ: إنشاء قاعدة بيانات MySQL، إنشاء مستخدم MySQL، إعطاء المستخدم صلاحية الوصول إلى قاعدة البيانات. وكما ترى فسيتم استخدام قيم المتغيرات بشكل تلقائي من ملف defaults/main.yml عند تنفيذ الأوامر. ملاحظة: توفّر أدوات Ansible أداة ansible-vault والتي تسمح بتخزين كلمات المرور بصورة مشفّرة حتى لا تكون قابلة للقراءة في الملف، ولكن الحديث عن هذا خارج إطار حديثنا الآن. دور WordPress والآن نأتي للحظة التي كنا ننتظرها.. تثبيت ووردبريس. نبدأ بتحرير ملف المهام كالمعتاد: $ nano roles/wordpress/tasks/main.yml وسنقوم بنسخ المحتوى التالي إليه: --- - name: Download WordPress get_url: url=https://wordpress.org/latest.tar.gz dest=/tmp/wordpress.tar.gz validate_certs=no sudo: yes سيقوم المحتوى السابق بتحميل ووردبريس إلى مجلد tmp/ (ويمكن للحذرين أن ينتبهوا إلى أننا قمنا بتعطيل التحقق من الشهادة الأمنية، لأنه سيمنع عملية التحميل). بعد اكتمال التحميل سنقوم بفك ضغط الملف إلى var/www/، وهو المسار الذي يستخدمه Apache لتخزين محتوى الويب، وبالتالي سنضيف الجزء التالي لمحتوى الملف أيضًا: - name: Extract WordPress unarchive: src=/tmp/wordpress.tar.gz dest=/var/www/ copy=no sudo: yes وبعد أن يتم فك ضغط الملفات، سنقوم بتحديث مسار الجذر الافتراضي DocumentRoot في ملف إعدادات Apache كي يشير إلى موقع ووردبريس: - name: Update default Apache site sudo: yes lineinfile: dest=/etc/apache2/sites-enabled/000-default.conf regexp="(.)+DocumentRoot /var/www/html" line="DocumentRoot /var/www/wordpress" notify: - restart apache sudo: yes لاحظ أننا استخدمنا الكتلة notify، والتي نحتاجها عند الرغبة بإعادة تشغيل خدمات بعد أن يتم تنفيذ مهمّة بنجاح، ولا يتم تنفيذ معالجات notify إلا عندما يحصل تغيير على حالة المهمّة. سنقوم بإضافة المعالج الخاص بنا لإعادة تشغيل Apache باستخدام restart apache ويتم ذلك في الملف roles/wordpress/handlers/main.yml: $ nano roles/wordpress/handlers/main.yml نضيف المحتوى التالي: --- - name: restart apache service: name=apache2 state=restarted sudo: yes ويتم تنفيذ هذه المهمّة عندما تتغير حالة المهمّة التي تحتوي على الكتلة notify: restart apache، مما يؤدي إلى إعادة تشغيل الخدمة. إعداد ووردبريس بالعودة إلى roles/wordpress/tasks/main.yml، سنقوم الآن بتجهيز إعدادات موقع ووردبريس، فنقوم أولًا بنسخ ملف الإعدادات config الافتراضي: - name: Copy sample config file command: mv /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php creates=/var/www/wordpress/wp-config.php sudo: yes ومن ثم نقوم بتغيير بعض الثوابت في الملف لتتطابق مع معلومات الاتصال بقاعدة البيانات: - name: Update WordPress config file lineinfile: dest=/var/www/wordpress/wp-config.php regexp="{{ item.regexp }}" line="{{ item.line }}" with_items: - {'regexp': "define\\('DB_NAME', '(.)+'\\);", 'line': "define('DB_NAME', '{{wp_mysql_db}}');"} - {'regexp': "define\\('DB_USER', '(.)+'\\);", 'line': "define('DB_USER', '{{wp_mysql_user}}');"} - {'regexp': "define\\('DB_PASSWORD', '(.)+'\\);", 'line': "define('DB_PASSWORD', '{{wp_mysql_password}}');"} sudo: yes حيث ستقوم المهمّة بجلب معلومات الاتصال بالقاعدة من ملف المتغيّرات الافتراضية الذي قمنا بتحريره سابقًا. بعد الانتهاء من الخطوات السابقة بنجاح، سيكون قد أصبح لدينا ملفّين لدور wordpress، وفيما يلي النسخة الكاملة لمحتوى الملفّين.. ملف roles/wordpress/tasks/main.yml: --- - name: Download WordPress get_url: url=https://wordpress.org/latest.tar.gz dest=/tmp/wordpress.tar.gz validate_certs=no - name: Extract WordPress unarchive: src=/tmp/wordpress.tar.gz dest=/var/www/ copy=no sudo: yes - name: Update default Apache site sudo: yes lineinfile: dest=/etc/apache2/sites-enabled/000-default.conf regexp="(.)+DocumentRoot /var/www/html" line="DocumentRoot /var/www/wordpress" notify: - restart apache - name: Copy sample config file command: mv /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php creates=/var/www/wordpress/wp-config.php sudo: yes - name: Update WordPress config file lineinfile: dest=/var/www/wordpress/wp-config.php regexp="{{ item.regexp }}" line="{{ item.line }}" with_items: - {'regexp': "define\\('DB_NAME', '(.)+'\\);", 'line': "define('DB_NAME', '{{wp_mysql_db}}');"} - {'regexp': "define\\('DB_USER', '(.)+'\\);", 'line': "define('DB_USER', '{{wp_mysql_user}}');"} - {'regexp': "define\\('DB_PASSWORD', '(.)+'\\);", 'line': "define('DB_PASSWORD', '{{wp_mysql_password}}');"} sudo: yes ملف roles/wordpress/handlers/main.yml: --- - name: restart apache service: name=apache2 state=restarted sudo: yes ونكون قد انتهينا. لنقم الآن بتشغيل ansible-playbook لآخر مرة لإعداد موقع ووردبريس: $ ansible-playbook playbook.yml -i hosts -u sammy -K وبعد تنفيذ الأمر ينبغي أن نكون قادرين على تصفّح الموقع عبر طلب عنوانه http://your_server_ip في المتصفح ويمكن الآن متابعة إعداد موقع ووردبريس بشكل يدوي عند هذه المرحلة. الخلاصة تهانينا! ستتمكن الآن من تثبيت مواقع ووردبريس على أي عدد من الخواديم التي تعمل بنظام تشغيل Ubuntu باستخدام أمر واحد: $ ansible-playbook playbook.yml -i hosts -u sammy -K وكل ما تحتاج للقيام به هو إضافة العنوان الرقمي IP إلى قائمة الخواديم المستهدفة في ملف hosts والتأكّد من أن الصلاحيات قد تم إعدادها مسبقًا على الخادوم الهدف. تناولنا في المقال بصورة سريعة كيفية استخدام Ansible لتثبيت مواقع ووردبريس بشكل اوتوماتيكي، وقد تكون مهتمًّا ببعض التحسينات الإضافية الممكنة: تعلّم كيفية استضافة أدوارك الخاصة في الـ Ansible Galaxy. أتمتة عملية الإعداد النهائية لموقع ووردبريس حتى لا يكون هناك حاجة للقيام بأي إعداد يدوي للموقع المطلوب إطلاقًا. ترجمة -وبتصرّف- للمقال How To Automate Installing WordPress on Ubuntu 14.04 Using Ansible لصاحبه Christo Crampton.
  11. هل سبق لك وأن اتّصلت بإحدى الشّركات الكبيرة ( كمزوّد خدمة الإنترنت الخاص بك، أحد شركات بطاقات الائتمان، أو paypal) لتطلب المساعدة في حلّ مشكلةٍ ما ؟ في البداية تسمع صوتًا لطيفًا آليًّا يخبرك أنّك عميلُ الشركة العزيز الذي يهمّهم رضاه. ثم يسألك ذلك الصّوت عن المشكلة التي تواجهها, فتقول مثلًا "أواجه مشكلة في الاتصال بالإنترنت". فيرد عليك "عذرًا. 'وجه شكل الإنترنت' خيار خير صحيح". تضغط على الرقم 0 لعدّة مرّات، ثمّ تجرّب الضغط على (*) لعدّة مرّات لكنّ الصوت الآليّ الوَدود يخبرك مجددًا أنّها خياراتٌ غير صالحة. تقول الآن بصوتٍ مرهق "أرغب في الحديث إلى الدعم الفني". فيرد عليك الصوتُ الآلي "'راغب الحدث الفني' خيار غير صحيح". تفكّر في ترك التعامل مع هذه الشركة، لكنّك تخشى أن تتعرّض لتجربةٍ أسوأ من هذه مع شركةٍ أخرى فتتراجع عن هذا القرار. وبعد أن تفقد الأمل، تقوم بالبحث حلٍ لمشكلتك في جوجل، أو تطلب المساعدة على أحد مواقع التواصل الاجتماعي. هذا النوع من التجارب هو ما يخطر ببال روّاد الأعمال عندما يفكّرون في أَتمتَة (automate) شيءٍ من أعمالهم/مهامّهم: التواصل مع العملاء بطريقةٍ آليّةٌ مصطنعةٌ لا تُرضيهم أو تساعدهم. لكن المثال الذي ذُكر أعلاه مثالٌ على القيام بالأتمتَة (automation) بطريقةٍ خاطئةٍ بالكامل (إلا إذا كان هدفُك هو إغاظة العميل وخسارة رضاه، في هذه الحالة أقترح عليك أن تحاكي هذا المثال بالضّبط). في الواقع، أقوم بأتمتة معظم مهام مشاريعي التّجارية. ليس لديّ خيارٌ آخر، فأنا أُدير أعمالي كمستقل، إضافة إلى 4 كورسات، مدوّنتين صوتيّتين، بعض قوائم البريد الإلكتروني وأكثر- في الوقت نفسه، بنفسي وبدون مساعدةٍ من أحد. لكن على عكس المثال السّابق، أؤتمت أعمالي بشكل لا يسبب إزعاجًا لأي من زبائني. عندما تسجّل في القائمة البريديّة على سبيل المثال، سيتم الترحيب بك برسالةٍ تعبّر لك عن امتناني في قالبٍ جاهز فيه اسمُك. ستعرفُ أنّني لم أكتب هذه الرسالة خصيصًا لك أنت، لكنك لن تنزعج أيضًا من ذلك – كما أتمنى- لأنني قمتُ بأتمتَة تلك الرسالة. وفقًا للدراسات فإنّ 75% من الناس يتوقّعون تلقّي رسالةً ترحيبية عندما يشتركون في نشرةٍ (newsletter) عبر البريد الإلكتروني. ومن وجهة نظر تسويقيّة، تزيد الرسائل الترحيبية العائدات بنسبة 320% أكثر من الرسائل الدعائيّة الأخرى. يقوم أغلب النّاس بأتمتة رسائل الترحيب بمشتركي قوائمهم البريدية الجدد دونَ أي يعوا أنهم في طور عمليّة الأتمتة بالفعل. إذا قمت بأتمتة تلك الرسائل الترحيبيّة بشكلٍ صحيحٍ يتّسق مع هويّتك وهويّة شركتك وبطريقةٍ تُرضي العميل، فسيعود ذلك عليك وعلى نشاطك التّجاري بعائدٍ إيجابي. تعمل الأتمتة بصفتها امتدادًا لهويّتك وهويّة شركتك. ولذلك، فإنها يجب أن تكون بطريقتك الخاصّة وبنبرتك المميّزة، وليس كما تقوم به بعض الشّركات الكبيرة: " عميلُنا العزيز، من فضلك انتظر لمئتين دقيقة حتى تتلقّى ردًا جاهزًا مقَولبًا وغير مفيد". يمكنك أيضًا -بجانب الرسائل الترحيبية- أن تقوم بأتمتة رسائل ذات محتوى مسلٍّ كقصصٍ ممتعة أو شيء من هذا القبيل. قمت بأتمتة معظم مهام عملية تهيئة المستخدمين الجدد للعملاء الجدد في موقعي الخاص بتصميم مواقع الويب. وقد وفّر ذلك عليّ ساعاتٍ من العمل أسبوعيًّا ولم يؤثّر سلبًا -ولو بنسبةٍ بسيطة- على نسبة العملاء المُحتملين الذين قاموا بتوظيفي. باستخدام أدواتٍ مثل Zapier، تستطيع أن تقوم بالأتمتة بذكاءٍ وسهولة، ومن دون الحاجة لكتابة أي سطر برمجي. أستخدمُ Zapier مثلًا لإرسال رسالة أوتوماتيكيًّا كلما فشلت عملية الدّفع مُقابل أحد الكورسات التي أبيعها. هذا يحدث لعدّة مرّات في الأسبوع، لكنّني إن لم أفعل شيئًا حيال فشل تلك التحويلات، سأقوم بخسارة الكثير من أرباحي. ولذلك بدلًا من عدم فعل شيء حيال فشل الحوالات البنكيّة وتمنّي أن يحاول العميل الدفع مرّةً أخرى، أستخدمُ Zapier لأرسل له رسالةً مفادُها أنّه لم يكن الخطأ خطأه، مع بعض التعليمات التي تشرح كيفية الدفع باستخدام وسائل أخرى. تُرسل الرسالة في غضون ثواني من فشل التحويل. تُرسَل من عنوان بريدي الإلكتروني وتُكتب بنفس الطريقة التي أكتب بها الرسائل الشخصية (بدون أحرف كبيرة، بأسلوبي، وبتوقيعي الاعتيادي). ليس عليهم أن يتواصلوا معي مباشرةً لطلب المساعدة، وليس عليهم أن ينتظروني حتى أستيقظ (إذا كانوا يحاولون الدّفع الساعة الثالثة بعد منتصف الليل). يتم التواصل معهم على الفور برسالةٍ لطيفة مع بعض الخطوات البسيطة لحل المشكلة. ربّما تتفاجأ عندما تعلم أنّ هذه الرّسالة لها معدّل نجاح يبلغ 96%. أستخدمُ أيضًا قائمتي البريديّة لأتمتة كل ما يتعلّق بالكورسات التي أقدّمها. قيامي بذلك يسمح لي بإدارة عدد من الكورسات المختلفة مع العديد من الطّلاب في الوقت نفسه. أقدّم خيار فترة التجربة المجّانيّة في معظم كورساتي. فإذا كنت مهتمًا، يمكنك الحصول على بعض الدروس المجّانية عن طريق تسجيل بريدك الإلكتروني. أبدأ عن طريق الأتمتة بواسطة MailChimp في إرسال الرسائل أو الدروس مباشرةً - فينال العميل ما سجّل للحصول عليه على الفور وأرسله له المزيد من العيّنات المجّانيّة والمعلومات بشكلٍ يومي. أستخدم MailChimp أيضًا لاستثناء الطلّاب الذين قاموا بالتسجيل في الكورس والدّفع من الرسائل المؤتمتة التي تحتوي دروسًا مجّانية. مما يعني أنه إذا اشتريت الكورس في فترة التجربة المجّانية (التي تُرسل فيها رسائل مؤتمَتة) سوف تتوقف عن تلقّي تلك الرسائل على الفور. لقد قمتٓ للتوّ بشراء محتوى الكورس على كل حال، لذلك لست بحاجةٍ لتكدّس صندوق بريدك الإلكتروني بالرسائل التي تقدّم لك المحتوى المجّاني. ثم أقوم بإضافة العملاء الذين قاموا بشراء محتوى الكورس لقائمة بريدية أخرى (قائمة ما بعد الشراء). وهذا له عدّة فوائد: أن أريهم كيفية استعمال أدوات الكورس. أن أعلّمهم كيفية الوصول لكل المميزات والدروس التي يحتويها. أن أخبرهم عن كيفية الوصول لأقصى استفادة من محتويات الكورس عدد المشتركين في دوراتي 4000 طالب نٓشِط تقريبًا، وتأتيني رسالةٌ واحدةٌ فقط أسبوعيًا لطلب الدعم/المساعدة، وذلك لأنني أقوم بأتمتَة رسائل البريد الإلكتروني التي تشرح هذه الأمور. معظم الرسائل المؤتمتة التي أرسلها للعملاء بعد الشّراء تحتوي على آلية للتغذية الراجعة ، وذلك لأعرف ما هو رأي العملاء بالكورس الذي اشتروه، للتأكد من أنهم يستفيدون من الكورس بشكلٍ كامل ولأرى ما هي العوائد الإيجابيّة التي حصلوا عليها منه ( وهذه طريقةٌ رائعةٌ للحصول على شهادات التوصية testimonials وقصص النجاح ). يمكنك أيضًا أن تقوم بأتمتة ما يتعلّق بالتغذية الراجعة Feedback بشكلٍ مستقل باستخدام أدوات مثل Typeform لطرح الأسئلة وجمع الإجابات. الإمكانيّات والفوائد التي يمكنك الحصول عليها من أتمتة قائمتك البريدية والشؤون الأخرى في شركتك كثيرةٌ جدًا. وإذا استعملتَ الأتمتة بطريقةٍ صحيحة، فسيسعدُ عملاؤك لعنايتك بهم وباهتمامك الذي يحمل صٓبغةً شخصيّة، حتى وإن كان ذلك بطريقةٍ مؤتمتة. لا تنهج نَهج الشركات الكبيرة -التي تفشل غابًا في العناية بعملائها- في الأتمتة. يمكنك أن تستعمل الأتمتة لتكون امتدادًا لأسلوبك الشخصي المتفرّد ولكي تفيد وتساعد العملاء الذين يريدون ويحتاجون أن يتواصلوا معك ( حتى إن أرادوا ذلك في الساعة الثالثة صباحًا). ترجمة -وبتصرف- للمقال Make automation great again لصاحبه PAUL JARVIS. حقوق الصورة البارزة: Designed by Freepik.
  12. تمّ تصميم أنظمة إدارة الإعدادات لتجعل التحكّم بعدد كبير من الخواديم أمرًا سهلًا لمديري الأنظمة وفرق العمليّات، فهي تسمح لنا بالتحكّم بالعديد من الأنظمة المختلفة بطريقة مؤتمتة من موقع مركزي واحد. وبينما تتوافر العديد من أنظمة إدارة الإعدادات الشائعة من أجل أنظمة Linux، مثل Chef وPuppet، فهي غالبًا معقدة أكثر من حاجة الناس، تُشكّل Ansible بديلًا رائعًا لهذه الخيارات لأنّها تحتوي على عقبات أقل بكثير عند البدء معها. سنناقش في هذا الدّرس كيفيّة تثبيت Ansible على خادوم Ubuntu وسنمر على بعض الأساسيات حول كيفيّة استخدام هذه البرمجيّة. كيف تعمل Ansible؟تعمل Ansible عن طريق إعداد أجهزة العملاء من خلال حاسوب يمتلك مكوّنات Ansible مثبّتة ومُعدّة عليه. تتواصل عبر قنوات SSH الاعتياديّة من أجل استعادة المعلومات من الأجهزة عن بُعد remote، إصدار الأوامر، ونسخ الملفّات، ولهذا السبب لا يتطلّب نظام Ansible تثبيت أي برمجيّات إضافيّة على حواسيب العملاء. هذه هي إحدى الطرق التي تُبسِّط فيها Ansible إدارة الخواديم، فيُمكِن إحضار أي خادوم يمتلك منفذ SSH مُعرَّض تحت مظلّة إعدادات Ansible بغض النظر عن الطور الذي يتواجد فيه ضمن دورة حياته. أي حاسوب نستطيع إدارته عبر SSH نستطيع أيضًا إدارته عبر Ansible. تتخذ Ansible نهج الوحدات modules ممّا يجعل من السهل تمديدها كي تستخدم وظائف من النظام الأساسي للتعامل مع حالات محدّدة، يُمكِن كتابة الوحدات باستخدام أيّة لغة وهي تتخاطب بواسطة JSON المعياريّة. إنّ ملفّات الإعدادات مكتوبة بشكل رئيسي بصيغة تسلسل البيانات YAML نظرًا لطبيعتها التعبيرية وتشابهها مع لغات الرقم markup الشائعة، تتمكن Ansible من التفاعل مع العملاء إمّا من خلال أداة سطر الأوامر أو عبر scripts للإعدادات تُدعى Playbooks. تثبيت Ansible على Ubuntuللبدء باستكشاف Ansible كوسيلة لإدارة خواديمنا المختلفة نحتاج إلى تثبيت برمجيّة Ansible على جهاز واحد على الأقل، سنستخدم خادوم Ubuntu من أجل هذا القسم. إنّ أفضل طريقة للحصول على Ansible في Ubuntu هي إضافة PPA المشروع (أرشيف الحِزَم الشخصية personal package archive) إلى نظامنا. للقيام بذلك على نحو فعال نحتاج لتثبيت الحزمة python-software-properties والتي ستعطينا القدرة على العمل مع PPA بسهولة: sudo apt-get update sudo apt-get install python-software-propertiesبعد أن يتم تثبيت الحزمة نستطيع إضافة Ansible PPA بكتابة الأمر التالي: sudo add-apt-repository ppa:rquillo/ansible نضغط ENTER لقبول إضافة الـ PPA. نحتاج بعدها لتحديث دليل حِزَم نظامنا بحيث يكون على دراية بالحِزَم المتوفرة في PPA، نستطيع بعدها تثبيت برمجيّة Ansible: sudo apt-get update sudo apt-get install ansible نمتلك الآن كافّة البرمجيّات المطلوبة لإدارة خواديمنا من خلال Ansible. إعداد مفاتيح SSHتتخاطب Ansible بالدرجة الأولى كما أشرنا سابقًا مع حواسيب العملاء عبر SSH، وعلى الرغم من أنّها تمتلك القدرة على التعامل مع استيثاق SSH authentication مُعتمِد على كلمة السر فتساعد مفاتيح SSH على إبقاء الأمور أبسط. بإمكاننا إعداد مفاتيح SSH بطريقتين مختلفتين اعتمادًا على إذا ما كنّا نمتلك مسبقًا المفتاح الذي نريد استخدامه. 1- إنشاء زوج مفاتيح SSH جديدإن لم تكن تمتلك مسبقًا زوج مفاتيح SSH ترغب في استخدامه من أجل إدارة Ansible فبإمكانك إنشاء واحد الآن على خادوم Ansible. سنقوم بإنشاء زوج مفاتيح SSH على خادوم Ansible من أجل استيثاقه مع المضيفين الذين يديرهم. نقوم بإنشاء زوج مفاتيح RSA key-pair بكتابة ما يلي عن طريق المستخدم الذي نتحكّم بـ Ansible من خلاله: ssh-keygen سيتم سؤالنا عن تحديد موقع الملف لزوج المفاتيح التي تم إنشاؤها، عبارة سر passphrase، وتأكيد عبارة السّر، نضغط Enter في جميع هذه المراحل لقبول القيم الافتراضيّة. ستكون المفاتيح الجديدة متاحة في دليل ~/.ssh الخاص بالمستخدم، يُدعى المفتاح العام (والذي يمكننا مشاركته) بـ id_rsa.pub، يُدعى المفتاح الخاص (والذي نبقيه بأمان) بـ id_rsa. نستطيع إضافتها إلى لوحة تحكّم DigitalOcean على سبيل المثال (إن كنت على Digital Ocean) للسماح لنا بتضمين مفتاح SSH الخاص بنا في الخواديم الجديدة التي أنشأناها، سيسمح هذا لخادوم Ansible بالدخول إلى الخواديم الجديدة عبر SSH فورًا بدون الحاجة لأي استيثاق آخر. لفعل هذا نضغط على الرابط “SSH Keys” الموجود في قائمة التصفح على اليسار، نضغط في الشاشة الجديدة على زر “Add SSH Key” الموجود في الزاوية العلوية اليمنى: ندخل الاسم الذي نريد ربطه مع هذا المفتاح في الحقل العلوي، ونكتب على خادوم Ansible ما يلي للحصول على محتويات مفتاحنا العام: cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzmGgsqjSFuOBbjZB1sgquKpp3Ty+FgqoLrzjKbbk9VGOH6kM37aAhyxxmTQfe69lhYi/WCai+mrXOyY9IiQbUfZ4jsfPE9DS3zHhmnGiBWA7pedCTJ/Nhf06dmhAJIbExW3uDghbPbzbSA5Ihn1x0F5FXtSMDoFtyjcwUwJxc2z/kk9TKcFSl8qqf4IYBYE7c+EKaYRBjjDP4AQmiwjTPuipsmub7C0OGF0dTMatIa0lok6rwy91nmhCQV6polG0+Fsk4YrY8Yh5xz6wE0lOvc8BwP9nL0zsnw6Ey0MHV9BbMqtyD6x/fCurpIkMHJK4nv79rToSWA0AwoP/bJXh7 demo@ansible0 السلسلة النصية التي تعود لنا هي التي نحتاج لصقها في الحقل الثاني في لوحة تحكّم DigitalOcean: نضغط على “Create SSH Key” لإضافة مفتاحنا إلى لوحة التحكم، نستطيع الآن تضمين مفتاح SSH العام إلى الخواديم الجديدة التي نضيفها مما يسمح لنا بالتواصل مع خادوم Ansible، نحتاج فقط إلى اختيار المفتاح في القسم “Add optional SSH Keys” من عملية إنشاء خادوم جديد: 2- نقل زوج مفاتيح SSH موجود إلى Ansibleإن كنت تمتلك مسبقًا زوج مفاتيح SSH تريد استخدامه من أجل الاستيثاق مع خواديمك فبإمكانك نقل الإعتمادات credentials إلى خادوم Ansible الجديد بدلًا من إنشاء زوج جديد، يمتلك هذا ميّزة بأن يجعلها تعمل تلقائيًّا مع أي خواديم قمت بإعدادها مسبقًا لتستخدم هذا المفتاح. وعلى الحاسوب الآخر حيث قمنا بإعداد استيثاق مفتاح SSH من أجل الخواديم نحصل على المفتاح العام بكتابة ما يلي: cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzmGgsqjSFuOBbjZB1sgquKpp3Ty+FgqoLrzjKbbk9VGOH6kM37aAhyxxmTQfe69lhYi/WCai+mrXOyY9IiQbUfZ4jsfPE9DS3zHhmnGiBWA7pedCTJ/Nhf06dmhAJIbExW3uDghbPbzbSA5Ihn1x0F5FXtSMDoFtyjcwUwJxc2z/kk9TKcFSl8qqf4IYBYE7c+EKaYRBjjDP4AQmiwjTPuipsmub7C0OGF0dTMatIa0lok6rwy91nmhCQV6polG0+Fsk4YrY8Yh5xz6wE0lOvc8BwP9nL0zsnw6Ey0MHV9BbMqtyD6x/fCurpIkMHJK4nv79rToSWA0AwoP/bJXh7 demo@ansible0نحتاج على خادوم Ansible إلى إنشاء دليل مخفي لتخزين المفاتيح، نقوم بتسميته .ssh كي يعلم برنامج SSH أين يجده: mkdir ~/.ssh نقوم بقفل النفاذ إلى هذا الدليل لكي نتمكن نحن فقط من دخوله أو الكتابة إليه: chmod 700 ~/.ssh ننتقل الآن إلى الدليل ونفتح ملفًّا يُدعى id_rsa.pub باستخدام محرّر النصوص: cd ~/.ssh nano id_rsa.pubنلصق خَرْج مفتاحنا العام من حاسوبنا الرئيسي إلى هذا الملف: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzmGgsqjSFuOBbjZB1sgquKpp3Ty+FgqoLrzjKbbk9VGOH6kM37aAhyxxmTQfe69lhYi/WCai+mrXOyY9IiQbUfZ4jsfPE9DS3zHhmnGiBWA7pedCTJ/Nhf06dmhAJIbExW3uDghbPbzbSA5Ihn1x0F5FXtSMDoFtyjcwUwJxc2z/kk9TKcFSl8qqf4IYBYE7c+EKaYRBjjDP4AQmiwjTPuipsmub7C0OGF0dTMatIa0lok6rwy91nmhCQV6polG0+Fsk4YrY8Yh5xz6wE0lOvc8BwP9nL0zsnw6Ey0MHV9BbMqtyD6x/fCurpIkMHJK4nv79rToSWA0AwoP/bJXh7 demo@ansible0 نقوم بحفظ وإغلاق الملف، ونتحقّق من امتلاكه للأذونات الصحيحة بكتابة: chmod 644 id_rsa.pub الآن وبالعودة إلى حاسوبنا المحلّي المضبوط من أجل نفاذ مفاتيح SSH نكتب: cat ~/.ssh/id_rsa -----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEA85hoLKo0hbjgW42QdbIKriqad08vhYKqC684ym25PVRjh+pD N+2gIcl8Zk0H3uvZYWIv1gmsfpq1zsmPSIkG1H2eI7HzxPQ0qMx4ZpxogVgO6XnQ kyfzYX9OnZoQCSGxMVt7g4IWz2820gOSIZ9cdBeRV7UjA6Bbco3MFMCcXNs/5JPU ynBUpfKqn+CGAWBO3PhCmmEQY4wz+AEJosI0z7oqbJrm/AtDhhdHUzGrSGtJaJOq . . . . . . cqsqOEzXAoGBAPMJJ8RrKUBuSjVNkzebst9sBgNadmaoQUoMHUDr8KpCZhWAoHB7 1VKmq7VSphQSruI31qy2M88Uue1knC/nQr1bE1DITZgezETSsDqsAMBo8bqDN6TT qVJgG+TS9BRC+IowuzMVV5mzrfJjkrb+GG+xWSXrTLZMbeeTf+D0SfVo -----END RSA PRIVATE KEY----- سيكون الخَرْج طويلًا جدًّا. نعود الآن إلى خادوم Ansible، نحتاج إلى إنشاء ملف جديد في الدليل ~/.ssh: nano id_rsa نقوم بداخله بلصق نتائج الأمر السابق على حاسوبنا المحلّي: -----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEA85hoLKo0hbjgW42QdbIKriqad08vhYKqC684ym25PVRjh+pD N+2gIcl8Zk0H3uvZYWIv1gmsfpq1zsmPSIkG1H2eI7HzxPQ0qMx4ZpxogVgO6XnQ kyfzYX9OnZoQCSGxMVt7g4IWz2820gOSIZ9cdBeRV7UjA6Bbco3MFMCcXNs/5JPU ynBUpfKqn+CGAWBO3PhCmmEQY4wz+AEJosI0z7oqbJrm/AtDhhdHUzGrSGtJaJOq . . . . . . cqsqOEzXAoGBAPMJJ8RrKUBuSjVNkzebst9sBgNadmaoQUoMHUDr8KpCZhWAoHB7 1VKmq7VSphQSruI31qy2M88Uue1knC/nQr1bE1DITZgezETSsDqsAMBo8bqDN6TT qVJgG+TS9BRC+IowuzMVV5mzrfJjkrb+GG+xWSXrTLZMbeeTf+D0SfVo -----END RSA PRIVATE KEY----- نتأكّد من تضمين أسطر التحديد الموجودة في البداية والنهاية، فهي مطلوبة لكي يكون ملف المفتاح صالحًا، نحفظ الملف ونغلقه. نحتاج لتغيير الأذونات لإبقاء هذا الملف بأمان: chmod 600 id_rsa ستكون Ansible عند هذه النقطة قادرة على استخدام مفاتيح SSH هذه من أجل التواصل مع أي خادوم يمتلك المفتاح مُضمَّنًا عليه. إعداد مضيفي Ansibleتقوم Ansible بتتبّع جميع الخواديم التي يعلم عنها عن طريق ملف المضيفين “hosts”، نحتاج إلى إعداد هذا الملف أوّلًا قبل أن نتمكّن من بدء التواصل مع حواسيبنا الأخرى. نفتح الملف مع صلاحيّات جذريّة root كما يلي: sudo nano /etc/ansible/hosts سنرى ملفًّا يمتلك الكثير من أمثلة الإعدادات، وسيعمل أيّ منها لدينا فعليًّا، لذلك من أجل البدء نقوم بتعليق كافّة أسطر هذا الملف بإضافة “#” قبل كل سطر. سنبقي هذه الأمثلة في هذا الملف لتساعدنا في الإعداد إن أردنا تنفيذ حالات أكثر تعقيدًا في المستقبل. بعد أن يتم تعليق كافّة الأسطر نستطيع البدء بإضافة المضيفين الفعليين لدينا. يكون ملف المضيفين مرنًا إلى حدٍّ ما ويمكن إعداده بعدّة طرق مختلفة، تبدو الصياغة التي سنستخدمها كما يلي: [group_name] alias ansible_ssh_host=server_ip_address إنّ group_name هو وسم تنظيمي يسمح لنا بالإشارة لأي من الخواديم المدرجة بكلمة واحدة، الكنية هي مجرّد اسم للإشارة إلى ذلك الخادوم. لذا نتخيل في حالتنا أننا نمتلك ثلاثة خواديم نريد إعدادها مع Ansible، تكون هذه الخواديم قابلة للوصول من خلال خادوم Ansible بكتابة: ssh root@server_ip_address لن يتم سؤالنا عن كلمة سر إن أعددنا هذا بشكل صحيح، سنفترض أنّ عناوين IP لخواديمنا هي 192.0.2.1، 192.0.2.2، و192.0.2.3، سنقوم بإعداد هذا بحيث نستطيع الإشارة إليها بشكل مفرد كـ host1، host2، وhost3، أو كمجموعة باسم servers. هذه هي الكتلة التي ينبغي إضافتها إلى ملف المضيفين من أجل تحقيق هذا: [servers] host1 ansible_ssh_host=192.0.2.1 host2 ansible_ssh_host=192.0.2.2 host3 ansible_ssh_host=192.0.2.3 يمكن للمضيفين أن يكونوا ضمن مجموعات متعدّدة، وتستطيع المجموعات إعداد مُعامِلات parameters من أجل كل أعضائها، فلنجرّب هذا الآن. إن حاولنا مع إعداداتنا الحاليّة الاتصال بأي من المضيفين عن طريق Ansible فسيفشل الأمر (بافتراض أنّك لا تعمل عن طريق المستخدم الجذري root)، يحدث هذا لأنّه تم تضمين مفاتيح SSH من أجل المستخدم الجذري على الأنظمة البعيدة وستحاول Ansible الاتصال بشكل افتراضي بواسطة المستخدم الحالي، ستعطينا محاولة الاتصال هذا الخطأ: host1 | FAILED => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue نستخدم على خادوم Ansible مستخدمًا يُدعى demo، ستحاول Ansible الاتصال إلى كل مضيف باستخدام ssh demo@server، لن يعمل هذا إن كان المستخدم demo غير موجود على النظام البعيد. نستطيع إنشاء ملف يُخبِر جميع الخواديم في المجموعة servers بالاتصال عن طريق المستخدم الجذري root. لفعل هذا نقوم بإنشاء دليل في بنية إعدادات Ansible يُدعى group_vars، ونستطيع ضمن هذا المجلّد إنشاء ملفّات مُنسّقة عن طريق YAML لكل مجموعة نريد إعدادها: sudo mkdir /etc/ansible/group_vars sudo nano /etc/ansible/group_vars/serversبإمكاننا وضع إعداداتنا هنا، تبدأ ملفّات YAML بـ “—” لذا تأكّد ألّا تنسى ذلك الجزء: --- ansible_ssh_user: rootنحفظ الملف ونغلقه عند الانتهاء. إن أردنا تحديد تفاصيل الإعدادات لكل خادوم بغض النظر عن مجموعته المرتبط بها فبإمكاننا وضع هذه التفاصيل في ملف في المسار /etc/ansible/group_vars/all، يمكن إعداد المضيفين بشكل مفرد بواسطة إنشاء ملفّات في دليل في المسار /etc/ansible/host_vars. استخدام أوامر Ansible بسيطةالآن بعد أن قمنا بإعداد المضيفين وضبطنا تفاصيل الإعدادات بشكلٍ كافٍ للسماح لنا بالاتصال بنجاح إلى مضيفينا، فبإمكاننا تجربة الأمر الأول لنا. نقوم بعمل ping لكل الخواديم التي أعددناها عن طريق كتابة: ansible -m ping allhost1 | success >> { "changed": false, "ping": "pong" } host3 | success >> { "changed": false, "ping": "pong" } host2 | success >> { "changed": false, "ping": "pong" } وهو اختبار بسيط للتأكّد من امتلاك Ansible لاتصال مع كافّة مضيفيه. تعني “all” كافّة المضيفين، وكان بإمكاننا بسهولة تحديد مجموعة كما يلي: ansible -m ping serversنستطيع أيضًا تحديد مضيف بشكل فردي: ansible -m ping host1بإمكاننا تحديد عدّة مضيفين بفصلهم بواسطة نقطتين: ansible -m ping host1:host2المقطع -m ping من الأمر هو تعليمة لـ Ansible كي تستخدم الوحدة “ping”، وهي بشكل مبسّط عبارة عن أوامر نستطيع تنفيذها على مضيفينا عن بُعد، تعمل الوحدة “ping” بعدّة طرق مثل أداة ping العاديّة في Linux، ولكن تقوم بدلًا من ذلك بالتحقّق من أجل اتصال Ansible. لا تأخذ الوحدة ping فعليًّا أيّة مُعطيات arguments، ولكن بإمكاننا تجربة أمر آخر لنرى كيفيّة عمل ذلك، نقوم بتمرير المعطيات إلى script بكتابة –a. تسمح لنا وحدة الصدفة “shell” بإرسال أمر طرفيّة terminal إلى المضيف البعيد واستعادة النتائج، على سبيل المثال لإيجاد استخدام الذاكرة على جهاز مضيفنا host1 نستطيع استخدام: ansible -m shell -a 'free -m' host1 host1 | success | rc=0 >> total used free shared buffers cached Mem: 3954 227 3726 0 14 93 -/+ buffers/cache: 119 3834 Swap: 0 0 0 الخاتمةينبغي أن تمتلك الآن خادوم Ansible مضبوطًا للتواصل مع الخواديم التي ترغب بالتحكم بها، تحقّقنا قدرة Ansible على التواصل مع كل مضيف واستخدمنا الأمر ansible لتنفيذ مهام بسيطة عن بُعد. وعلى الرغم من أنّ هذا مفيد لنا، لم نقم بتغطية أقوى ميّزة في Ansible في هذا الدّرس وهي الـ Playbooks، لقد قمنا بإعداد أساس رائع من أجل العمل مع خواديمنا من خلال Ansible، ولكن الجزء الأكبر سيتم الحديث عنه في درس لاحق عند تغطية كيفيّة استخدام الـ Playbooks لأتمتة الإعدادات لحواسيبنا عن بُعد. ترجمة -وبتصرّف- لـ How to Install and Configure Ansible on an Ubuntu 12.04 VPS لصاحبه Justin Ellingwood.
  13. ما هو Cron؟Cron هي أداة جدولة تسمح لك بتخصيص المهام ليتمّ تشغيلها في أوقاتٍ مضبوطة بشكل مُسبق، حيث يمكن أن تُستخدم لأتمتة أي شيء تقريبًا على نظام التشغيل الخاص بك لا سيما تلك المهام التي يجب أن تُشغّل على فترات منتظمة. تُعتبر Cron أداةً أساسيّة لمديري الأنظمة إذ تبرع في المهام الروتينيّة التي ينبغي تنفيذها كلّ ساعة/يوم بالمقدار الذي تبرع فيه تجاه المهام التي يجب القيام بها مرةً أو مرتين في العام. نناقش في هذا الدرس كيفيّة استخدام Cron من خلال سطر الأوامر، وفهم ملف الضبط الخاص بها، إضافةً إلى حديثنا عن Anacron، وهي الأداة التي يمكن استخدامها لضمان تشغيل المهام حتى عندما يتم إيقاف تشغيل الخادوم لبعض الوقت. سوف نستخدم في درسنا هذا توزيعة Ubuntu 14.04، ويمكنك بالتأكيد تطبيق الشرح هنا على أي توزيعة غنو لينكس أخرى. كيف تعمل Cron؟تبدأ Cron مع إقلاع النظام وتعمل في الخلفية مع باقي خدمات Daemon، وهذا يعني أنها تعمل دون تدخّل من قبل المستخدم مُترقبةً أحداثًا معينة لتشغيل المهام المضبوطة. بالنسبة لـ Cron فإن هذه الأحداث هي مواقيت محدّدة من الزمن، حيث يعمل Cron في الخلفية ويتحقّق كلّ دقيقة فيما إذا كان من المقرّر تشغيل أمر ما هذه الدقيقة، وذلك تبعًا لملف الضبط الخاص به، وفي حال الإيجاب يُنفّذ Cron الأوامر المُحددّة له بشكل مسبق لهذه اللحظة، ومن ثم يعود للعمل ضمن الخلفية مترقبًا الدقائق القادمة، أما في حال النفي فإنه سينتظر لستين ثانية قبل أن يعاود تحقّقه. ونظرًا لأسلوبه في الجدولة والفحص دقيقةً بدقيقة؛ فإنه يعتبر قابلًا للضبط بشكل مرن للغاية، وحالما تُثبّت Cron على توزيعة غنو لينكس لديك فإنه سيضُبط لتشغيل مجموعة متنوعة من المهام. كيفيّة قراءة Crontabيُقرّر Cron ما هي الأوامر التي سيتم تشغيلها وفي أي توقيت من خلال قراءة مجموعة من الملفات التي يُعرف كلّ منها باسم "crontab"، يمكنك على سبيل المثال مشاهدة ملف "crontab" المطبّق على مستوى النظام system-wide بالنظر إلى محتويات الملف "etc/crontab/": less /etc/crontabSHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts –report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts –report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts –report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts –report /etc/cron.monthly )يُمثّل الخرج السابق ملف crontab الخاص بالنظام والذي لا ينبغي تعديل محتوياته في معظم الحالات، لذا يجدر بك دومًا كتابة ملف crontab خاص بك، إضافةً إلى أن الملف الخاص بالنظام معُرض للاستبدال عند تحديث النظام مما يعرّض تعديلات للضياع. بكل الأحوال يحتوي الملف السابق على بضعة أجزاء مُهمّة والتي نحتاج إلى فهمها. يُحدِّد أول سطرين الصدفة shell التي ستُنفذ الأوامر المدرجة، والمسار الذي توجد به هذه الأوامر. بينما يُحدّد ما تبقى من الملف الأوامر المجدولة مع مواقيتها، حيث كل سطر في هذه القائمة يمثّل سِجلًا أو صفًا في جدول، بينما تشير مسافات "tab" إلى أعمدة هذا الجدول، وتُمثّل كل خلية بأعمدة مفصولة بمسافات أو علامات تبويب tabs. أما سطر التعليقات (والذي يبدأ بإشارة #) فيشرح ما يمثّله كل عمود من الأعمدة.جدولة الساعات والدقائق باستخدام Cronيُخصّص العمود الأول لدقائق الساعة التي يفترض أن يُنفذ بها الأمر ويأخذ قيمة ضمن (0-59)، بينما يُحدّد العمود الثاني قيمة "ساعة من اليوم" ضمن (0-23)، وتعني علامة النجمة (*) "كل قيمة ممكنة" وتستخدم كعلامة شاملة. من خلال الجمع بين هذين العمودين نحصل على التوقيت الزمني للأمر. على سبيل المثال يحتوي السطر الثاني في الجدول على الرقم 25 ضمن عمود الدقائق و 6 لعمود الساعات: 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) وهذا يعني أن السطر الثاني سيُشغّل في الساعة 6:25 صباحًا. وبالمثل يُشغِّل السطر الأول الأمر الخاص به في الدقيقة 17 من كل ساعة: 17 * * * * root cd / && run-parts --report /etc/cron.hourly لذا سيتم تشغيله في الساعات 1:17am ،2:17am ،3:17am ...الخ جدولة الأيام باستخدام Cronتُحدّد كلًا من العمود الثالث، الرابع، والخامس؛ الأيام التي يجب أن تُشغِّل الأوامر، حيث يُحدِّد العمود الثالث قيمة "يوم من الشهر" ضمن المجال (1-31) (لا تنسَ أن الشهور مختلفة بعدّد أيامها؛ لذا كن حذرًا)، ويحدّد العمود الرابع أيّ الشهور التي ستُنفّذ فيها الأوامر ويأخذ قيمة من (1-12)، بينما يُحدّد العمود الخامس أي يومٍ من أيام الأسبوع التي يجب أن تنفّذ فيها الأوامر ويأخذ قيمة من (0-7). حيث يمكنك الجدولة باستخدام واحدة "الأسبوع" عوضًا عن "الشهر". إذا لم تتطابق خانتا "اليوم من الأسبوع" و "اليوم من الشهر" فإن الأمرّ سينفّذ إذا تحقّق أيٍ منهما. كما يمكن تحديد أيام الأسبوع والأشهر باستخدام الأحرف الثلاثة الأولى من أسمائها. إضافةً للنجمة يمكن استخدام الشرطة (-) لتحديد نطاق ما، واستخدام الفاصلة (,) لتحديد قيم متعدّدة. كما يمكننا تحديد "فاصل زمني" بإتباع قيمة ما مع إشارة "/"، فعلى سبيل المثال لتنفيذ الأمر كل ساعة يمكننا استخدام "*/2" في عمود الساعات. إذا نظرنا إلى ملف crontab سنلاحظ أن السجل الثالث يُشغّل كل أحد الساعة 6:47 صباحا: 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) أما السجل الرابع فهو يعمل أوّل كل شهر في الساعة 6:52 صباحًا: 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )استخدام اختصارات الوقت للجدولةيمكننا استبدال الأعمدة الخمسة الأولى من كل سجل بـ "مُسمى مختصر" إذا لم يكن لديك طلبًا مُعقّدًا، صيغة الاختصار تبدأ بإشارة "@" ويتلوها مُسمى الفترة. فعلى سبيل المثال يمكننا جدولة أمر بحيث يُنفّد كل أسبوع بتحديد "weekly@" بدلًا من إنشاء سجل بخمسة أعمدة، الخيارات الأخرى هي: "yearly" ،"@monthly" ،"@daily@" و "hourly@" إضافةً لذلك لدينا الاختصار "reboot@" والذي يعمل فقط عند تشغيل النظام وبدء تشغيل cron، ولهذا يُسمى بـ "reboot@" وليس "cron-restart"أو شيئًا من هذا القبيل. ضع في اعتبارك دومًا أن هذه الاختصارات لا توفّر إمكانيات تخصيص الأعمدة الخمسة، وبدلًا من ذلك فإنها تضبط الأوامر بحيث تعمل عند أول لحظة ممكنة تتطابق مع الاختصار. فعلى سبيل المثال يُشغّل الاختصار "monthly@" الأمر في منتصف الليل من أوّل الشهر، ما يعني أن جميع الأوامر المضبوطة على هذا الاختصار ستعمل في وقتٍ واحد، حيث لا إمكانية لترتيب هذه الأوامر كما مع أسلوب الأعمدة الخمسة في الضبط. تخصيص الأوامر والمستخدمين مع Cronيشمل العمود السادس والموجود فقط في ملف crontab الخاص بالنظام على اسم المستخدم الذي سيُنفّد الأمر من خلاله. بينما يُحدّد العمود الأخير الأوامر المطلوب تشغيلها، يمكن للأمر أن يحتوي على علامة النسبة المئوية (%) والتي تعني أن كل ما هو بعدها يتم تمريره إلى الأمر كدخل قياسي. ليعمل ملف crontab بشكل صحيح يجب إنهاء كل سجل مع محرف سطر جديد، هذه ليست مشكلة بالنسبة لمعظم السجلات، لكن تأكد من وجود سطر فارغ بعد آخر مُدخل ضمن الملف، وإلا فإنه لن يعمل كما يجب. استخدام ميزة “run-parts” والأدلةلو تمعّنا في الأوامر المكتوبة ضمن ملف crontab السابق والخاص بالنظام، فسنشاهد إشارة إلى ما يسمى "anacron" (المزيد عن ذلك لاحقًا)، إضافةً لـ "run-parts". يتيح لنا الأمر "run-parts" ببساطة تشغيل كل أمر قابل للتنفيذ ضمن مجلّد محدّد، ويستخدم هذا الأسلوب على نحو واسع مع cron لأنه يتيح لنا تشغيل سكربتات scripts عديدة في توقيتٍ واحد عن طريق وضعها في مكانٍ واحد، وهو ما يسمح لأن يبقى ملف crontab مرتبًا وبسيطًا، ويسمح لنا بجدولة المزيد من المهام عن طريق وضعها (أو إنشاء اختصار لها) كسكربتات في الدليل المناسب بدلًا من تعديل ملف crontab. عادةً ما تُخصّص معظم التوزيعات مجلد لكل فترة بحيث يتم وضع السكربتات بها ليتم تشغيلها في تلك الفترة، فعلى سبيل المثال تخصص توزيعة Ubuntu المجلدات التالية: cron.daily ،cron.hourly cron.monthly وcron.weekly. إنشاء ملفات Crontabs للمستخدمينبعد استعراضنا لأساسيات التعامل مع Cron يمكنك الآن البدء بجدولة المهام الخاصة بك عن طريق استخدام الأمر "crontab". لاحظ أن ملف "crontab" الخاص بك لن يحتوى عمود "المستخدم"، لأنه سيتم تشغيل الأوامر المضمّنة به من خلال امتيازات المستخدم الخاصّة بك. لمعرفة الـ crontab الحالي، اكتب: crontab -l غالبًا فلن يكون هناك ملف مسبق إلا إذا كنت قد أنشأت واحدًا بشكل يدويّ، وفي هذه الحالة فمن الأفضل أخذ نسخة احتياطية من الملف الحالي قبل البدء بالتحرير بحيث يمكنك التراجع عن أي تغييرات قد تقوم بها. لأخذ نسخة احتياطية إلى مجلد المنزل باسم "cron.bak"، نفّذ الأمر: crontab -l > ~/cron.back للبدء بتحرير ملف crontab اكتب: crontab -eno crontab for demouser - using an empty one Select an editor. To change later, run ‘select-editor’. 1. /bin/nanoاستخدام Anacron مع Cronواحدة من أكبر نقاط ضعف Cron افتراضها أن خادومك أو جهاز الحاسوب الخاص بك يعمل طوال الوقت 24/7، حيث يُلغى تنفيذ كل مهمة مجدولة في وقتٍ يكون فيه حاسوبك مطفئًا. يعتبر ذلك مشكلة خطيرة مع الأنظمة التي لا يمكن ضمان تشغيلها طوال الوقت، وكحلّ لهذه المشكلة تم تطوير أداة Anacron المبنية على anachronistic لضمان تنفيذ الأوامر طوال الوقت. يستخدم Anacron المُعاملات غير المُفصّلة في خيارات Cron، وهذا يعني أن Anacron تكمل عمل Cron وليست بديلًا عنه. أسلوب عمل Anacron يعتمد على إنشاء ملفات بأختام زمنية time-stamped عند تنفيذ أمر ما مجدول من خلال Cron، فإذا كان الأمر قد جُدول للتنفيذ بشكل يومي إلا أنه قد تم إيقاف تشغيل الحاسوب في الوقت الذي يفترض أن يُنفّذ به الأمر، فعندما يعمل anacron في المرة التالية سيرى أنه قد مضى أكثر من 24 ساعة على آخر تنفيذ للجدول اليومي وهذا ما يعني فوات موعده، فيقوم بتنفيذ الأوامر المجدولة. تملك الأداة anacron جدولًا للمواعيد مثل Cron يدعى "anacrontab" ويخزّن في دليل "etc/" كذلك. لنلقي نظرة كيف يبدو: less /etc/anacrontab# /etc/anacrontab: configuration file for anacron # See anacron(8) and anacrontab(5) for details. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # These replace cron’s entries 1 5 cron.daily nice run-parts –report /etc/cron.daily 7 10 cron.weekly nice run-parts –report /etc/cron.weekly @monthly 15 cron.monthly nice run-parts –report /etc/cron.monthlyبالعموم فإن بنية الملف شبيهة بملفات crontab السابقة مع عدد أعمدة أقل، وبعض الملاحظات الجديرة بالانتباه. يُحدّد العمود الأول عدد المرات التي يجب تنفيذ الأمر بها تبعًا للأيام، فالقيمة "1" تعني أنّه جيب تشغيل الأمر يوميًا، بينما تشغّل القيمة "3" الأمر كل ثلاثة أيام. يُحدّد العمود الثاني التأخير الزمني قبل تنفيذ الأوامر، حيث لا يعمل Anacron في الخلفية daemon بل يتم تشغيله بشكل صريح لمرة واحدة، وهذا يسمح بتنظيم العمل، فلا تُنفّذ جميع الأوامر دفعةً واحدة. على سبيل المثال يُشغّل السطر الأوّل كل يوم بعد خمس دقائق من استدعاء anacron: 1 5 cron.daily nice run-parts --report /etc/cron.daily بينما يُشغّل السطر التالي أسبوعيًا (كل سبعة أيام) بعد عشرة دقائق من استدعاء anacron: 7 10 cron.weekly nice run-parts --report /etc/cron.weekly يحتوي العمود الثالث على الاسم الذي سيعرّف مهمة السطر في رسائل anacron وفي سجلات النظام، بينما يحتوي العمود الرابع على الأوامر الفعليّة التي سيجري تشغيلها. يمكنك أن ترى أنه قد تم تعيين anacron لتشغيل بعض السكربتات التي تُنفّذ أيضًا من قبل Cron، ولدرء التعارض تلجئ التوزيعات عادةً إلى إعطاء أولوية لإحدى الأداتين على الأخرى بحيث تعمل واحدة منهما فقط على تنفيذ الأمر المجدول. في توزيعة Ubuntu مثلًا يختبر ملف "/etc/crontab/" إذا كانت anacron مُثبّتة على النظام، بحيث يُشغّل السكربتات النصيّة في أدلة cron فقط في حال لم يتم العثور على anacron. بعض التوزيعات تتبع أسلوب آخر بجعل cron يُحدّث الأختام الزمنية ل anacron في كل مرّة يتم فيها تنفيذ مهمة مجدولة مما يمنع anacron عن تنفيذ نفس الأمر عند استدعاءه. خاتمةتعتبر أداتي cron و anacron من أفضل أدوات أتمتة تنفيذ المهام الروتينية، لذا من المهم استيعاب كيفية الاستفادة من نقاط القوّة في كلّ منهما وتجنب نقاط ضعفهما مما يعطيك أقصى قدر من الفائدة والفعالية. ورغم أنه قد يبدو أمر إعدادهم للمرة الأولى مربكًا بعض الشيء، إلا أن ذلك سيوفّر عليك الكثير من الوقت على المدى الطويل في تكرار العمليات مرّةً بعد أخرى دون أن تحتاج غالبًا لتعديلات تذكر على ملفات الإعداد لاحقًا.
×
×
  • أضف...