تحديد مشاكل تنفيذ "بازيل" عن بُعد وحلّها باستخدام Docker Sandbox

ويمكن أن يتعذّر إنشاء تطبيقات Bazel الناجحة على المستوى المحلي عند تنفيذها عن بُعد بسبب القيود والمتطلّبات التي لا تؤثر في الإصدارات المحلية. يتم توضيح الأسباب الأكثر شيوعًا لحالات التعذُّر هذه في تعديل قواعد Bazel للتنفيذ عن بُعد.

تصف هذه الصفحة كيفية تحديد المشاكل الأكثر شيوعًا التي تنشأ عن التنفيذ عن بُعد باستخدام ميزة "وضع الحماية من Docker" وحلّها، والتي تفرض قيودًا على الإصدار تساوي القيود المفروضة على التنفيذ عن بُعد. يتيح لك ذلك تحديد المشاكل في الإصدار وحلّها بدون الحاجة إلى خدمة تنفيذ عن بُعد.

تعمل ميزة وضع الحماية في Docker على محاكاة قيود التنفيذ عن بُعد على النحو التالي:

  • تنفيذ الإجراءات في حاويات سلسلة الأدوات. يمكنك استخدام حاويات سلاسل الأدوات نفسها لتشغيل إصدارك محليًا وعن بُعد عبر خدمة تدعم التنفيذ عن بُعد في الحاوية.

  • لا توجد بيانات عابرة تتجاوز حدود الحاوية. ولا يتم إدخال سوى الإدخالات والمخرجات المُعلن عنها صراحةً واخرج من الحاوية، وبعد اكتمال إجراء الإصدار المرتبط بنجاح فقط.

  • يتم تنفيذ كل إجراء في حاوية جديدة. يتم إنشاء حاوية جديدة وفريدة لكل إجراء إصدار مدرَج.

يمكنك تحديد هذه المشاكل وحلّها باستخدام إحدى الطرق التالية:

  • تحديد المشاكل وحلّها في الأصل بهذه الطريقة، يتم تشغيل Bazel وإجراءات الإصدار التابعة لها في الأصل على جهازك المحلي. تفرض ميزة وضع الحماية في Docker قيودًا على الإصدار تساوي القيود المفروضة على التنفيذ عن بُعد. ومع ذلك، لن تتعرّف هذه الطريقة على الأدوات والحالات المحلية وتسرّب البيانات في الإصدار، ما سيؤدي إلى مشاكل في التنفيذ عن بُعد.

  • تحديد المشاكل وحلّها في حاوية Docker من خلال هذه الطريقة، يتم تشغيل Bazel وإجراءات الإصدار داخل حاوية Docker، ما يسمح لك برصد الأدوات وحالات البيانات وتسرُّبها من الجهاز المحلي إلى البنية، بالإضافة إلى قيود مهيبة تساوي لعمليات التنفيذ عن بُعد. تقدّم هذه الطريقة إحصاءات مفيدة عن الإصدار حتى إذا فشلت أجزاء من الإصدار. هذه الطريقة تجريبية وليست معتمدة رسميًا.

المتطلبات الأساسية

قبل بدء تحديد المشاكل وحلّها، ما يلي إذا لم تكن قد فعلت ذلك من قبل:

  • ثبِّت Docker واضبط الأذونات المطلوبة لتشغيلها.
  • ثبّت Bazel 0.14.1 أو إصدار أحدث. ولا تدعم الإصدارات السابقة ميزة وضع الحماية من Docker.
  • أضِف تقرير bazel-toolchains المثبّت على أحدث إصدار، إلى ملف WORKSPACE على النحو الموضّح هنا.
  • يُرجى إضافة علامات إلى ملف .bazelrc لتفعيل هذه الميزة. أنشِئ الملف في الدليل الجذري لمشروع Bazel إذا لم يكن متوفّرًا. تمثل العلامات أدناه نموذجًا مرجعيًا. يُرجى الاطّلاع على أحدث ملف .bazelrc في تقرير bazel-toolchains ونسخ قيم العلامات التي تم تحديدها لضبط docker-sandbox.
# Docker Sandbox Mode
build:docker-sandbox --host_javabase=<...>
build:docker-sandbox --javabase=<...>
build:docker-sandbox --crosstool_top=<...>
build:docker-sandbox --experimental_docker_image=<...>
build:docker-sandbox --spawn_strategy=docker --strategy=Javac=docker --genrule_strategy=docker
build:docker-sandbox --define=EXECUTOR=remote
build:docker-sandbox --experimental_docker_verbose
build:docker-sandbox --experimental_enable_docker_sandbox

إذا كانت قواعدك تتطلب أدوات إضافية، نفّذ ما يلي:

  1. أنشئ حاوية Docker مخصصة من خلال تثبيت الأدوات باستخدام Dockerfile وإنشاء الصورة محليًا.

  2. استبدِل قيمة العلامة --experimental_docker_image أعلاه باسم صورة الحاوية المخصّصة.

تحديد المشاكل وحلّها في الأصل

تعمل هذه الطريقة على تنفيذ Bazel وجميع إجراءات الإصدار الخاصة بها على الجهاز المحلي مباشرةً، كما أنها طريقة موثوقة لتأكيد نجاح عملية الإنشاء عند تنفيذها عن بُعد.

وباستخدام هذه الطريقة، يمكن أن تسرب الأدوات المثبتة محليًا والبرامج الثنائية والبيانات إلى الإصدار، لا سيما إذا كانت تستخدم قواعد ضبط وضع WORKSPACE. وسيؤدي هذا التسريب إلى حدوث مشاكل في التنفيذ عن بُعد؛ لاكتشافها، عليك تحديد المشاكل وحلّها في حاوية Docker بالإضافة إلى تحديد المشاكل وحلّها في الأصل.

الخطوة 1: تشغيل الإصدار

  1. أضِف العلامة --config=docker-sandbox إلى الأمر Bazel الذي تنفيذ إصدارك. مثال:

    bazel --bazelrc=.bazelrc build --config=docker-sandbox target
    
  2. شغِّل الإصدار وانتظر حتى يكتمل. سيتم تشغيل الإصدار ما يصل إلى أربعة أضعاف أبطأ من المعتاد بسبب ميزة وضع الحماية في Docker.

قد يظهر لك الخطأ التالي:

ERROR: 'docker' is an invalid value for docker spawn strategy.

وفي هذه الحالة، عليك تشغيل الإصدار مرة أخرى باستخدام العلامة --experimental_docker_verbose. تمكِّن هذه العلامة من ظهور رسائل خطأ مطوَّلة. عادةً ما يحدث هذا الخطأ بسبب خطأ في تثبيت Docker أو عدم توفّر أذونات لتنفيذه ضمن حساب المستخدم الحالي. لمزيد من المعلومات، يمكنك الاطّلاع على مستندات Docker. في حال استمرار حدوث المشاكل، يمكنك التخطي إلى تحديد المشاكل وحلّها في حاوية Docker.

الخطوة 2: حلّ المشاكل التي تمّ رصدها

في ما يلي المشاكل الأكثر شيوعًا والحلول البديلة.

  • لم يتم تضمين ملف أو أداة أو برنامج ثنائي أو مورد تمت الإشارة إليه من خلال شجرة ملفات تشغيل Bazel. تأكد من أنه تم الإعلان بشكل صريح عن جميع تبعيات الأهداف المتأثرة. راجع إدارة التبعيات الضمنية للحصول على مزيد من المعلومات.

  • الملف أو الأداة أو البرنامج الثنائي أو المورد المشار إليه من خلال المسار المطلق أو المتغيّر PATH مفقود. تأكّد من أنّ جميع الأدوات المطلوبة مثبّتة داخل حاوية "سلسلة الأدوات" واستخدِم قواعد الأداة للإعلان بشكل صحيح عن العناصر التابعة التي تشير إلى المورد المفقود. يمكنك الاطّلاع على استدعاء أدوات الإصدار من خلال قواعد سلاسل المفاتيح للحصول على مزيد من المعلومات.

  • تعذّر التنفيذ الثنائي. تشير إحدى قواعد الإصدار إلى برنامج ثنائي غير متوافق مع بيئة التنفيذ (حاوية Docker). يمكنك الاطّلاع على إدارة البرامج الثنائية التي تستند إلى النظام الأساسي للحصول على مزيد من المعلومات. إذا لم تتمكن من حل المشكلة، يُرجى التواصل مع bazel-مناقشة@google.com للحصول على مساعدة.

  • ملف من @local-jdk مفقود أو يتسبب في حدوث أخطاء. يتم تسريب البرامج الثنائية في جافا على جهازك المحلي أثناء عدم توافقها. استخدِم java_toolchain في القواعد والأهداف بدلاً من @local_jdk. تواصل معنا على bazel-discuss@google.com إذا كنت بحاجة إلى مزيد من المساعدة.

  • أخطاء أخرى يُرجى التواصل مع bazel-مناقشة@google.com للحصول على مساعدة.

تحديد المشاكل وحلّها في حاوية Docker

بهذه الطريقة، تعمل Bazel داخل حاوية Docker خارجية، ويتم تنفيذ إجراءات إصدار Bazel داخل حاويات سلاسل الأدوات الفردية الناشئة عن ميزة "وضع الحماية في Docker". ينتج عن وضع الحماية حاوية جديدة ضمن سلسلة أدوات لكل إجراء إصدار ويتم تنفيذ إجراء واحد فقط في كل حاوية سلسلة أدوات.

وتوفّر هذه الطريقة تحكّمًا أكثر دقة في الأدوات المثبّتة في بيئة المضيف. من خلال فصل عملية تنفيذ الإصدار عن تنفيذ إجراءات الإصدار والحد من الأدوات المثبّتة على الجهاز، يمكنك التحقّق مما إذا كان لإصدارك أي تبعيات على بيئة التنفيذ المحلية.

الخطوة 1: إنشاء الحاوية

  1. أنشئ Dockerfile يُنشئ حاوية Docker ويثبّت Bazel باستخدام مجموعة بسيطة من أدوات الإنشاء:

    FROM debian:stretch
    
    RUN apt-get update && apt-get install -y apt-transport-https curl software-properties-common git gcc gnupg2 g++ openjdk-8-jdk-headless python-dev zip wget vim
    
    RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
    
    RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
    
    RUN apt-get update && apt-get install -y docker-ce
    
    RUN wget https://releases.bazel.build/<latest Bazel version>/release/bazel-<latest Bazel version>-installer-linux-x86_64.sh -O ./bazel-installer.sh && chmod 755 ./bazel-installer.sh
    
    RUN ./bazel-installer.sh
    
  2. إنشاء الحاوية باسم bazel_container:

    docker build -t bazel_container - < Dockerfile
    

الخطوة 2: بدء الحاوية

ابدأ حاوية Docker باستخدام الأمر الموضَّح أدناه. في الأمر، استبدل المسار إلى رمز المصدر في المضيف الذي تريد إنشاؤه.

docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /tmp:/tmp \
  -v your source code directory:/src \
  -w /src \
  bazel_container \
  /bin/bash

يُشغِّل هذا الأمر الحاوية كجذر، ويربط مقبس docker، ويثبِّت الدليل /tmp. ويتيح ذلك لتطبيق Bazel إنتاج حاويات Docker أخرى واستخدام الأدلة ضمن /tmp لمشاركة الملفات مع هذه الحاويات. يكون رمز المصدر الخاص بك متوفرًا على /src في الحاوية.

يبدأ الأمر عمدًا من الحاوية الأساسية debian:stretch التي تتضمن ثنائيات غير متوافقة مع الحاوية rbe-ubuntu16-04 المستخدمة كحاوية الأداة. في حال تسرُّب البرامج الثنائية من البيئة المحلية إلى حاوية أدوات الأداة، سيؤدي ذلك إلى حدوث أخطاء في الإصدار.

الخطوة 3: اختبار الحاوية

شغِّل الأوامر التالية من داخل حاوية Docker لاختبارها:

docker ps
bazel version

الخطوة 4: تشغيل الإصدار

شغِّل الإصدار كما هو موضّح أدناه. المستخدم الناتج هو الجذر بحيث يتوافق مع دليل يمكن الوصول إليه بالمسار المطلق نفسه من داخل حاوية المضيف التي يتم تشغيل Bazel فيها، من حاويات سلاسل الأدوات التي تنتجها ميزة وضع الحماية في Docker. أي إجراءات إصدار Bazel قيد التشغيل، ومن الجهاز المحلي الذي يتم تشغيل حاويات المضيف والإجراء عليه.

bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target

الخطوة 5: حلّ المشاكل التي تمّ رصدها

يمكنك حلّ حالات تعذُّر الإصدار كما يلي:

  • إذا تعذّر الإصدار مع ظهور رسالة الخطأ " نفدت مساحة القرص"، يمكنك زيادة هذا الحدّ الأقصى من خلال بدء حاوية المضيف بالعلامة --memory=XX حيث XX هي مساحة القرص المخصّصة بالغيغابايت. هذا تجريبي وقد يؤدي إلى سلوك غير متوقع.

  • وفي حال تعذُّر الإصدار أثناء مرحلة التحليل أو التحميل، يعني ذلك أن قاعدة أو أكثر من قواعد الإصدار المذكورة في ملف WORKSPACE غير متوافقة مع التنفيذ عن بُعد. راجع تعديل قواعد Bazel للتنفيذ عن بُعد للحصول على الأسباب المحتملة والحلول البديلة.

  • إذا أخفق الإصدار لأي سبب آخر، راجع خطوات تحديد المشاكل وحلّها في الخطوة 2: حل المشاكل التي تم اكتشافها.