Docker सैंडबॉक्स की मदद से, Bazel रिमोट एक्ज़ीक्यूशन की समस्या हल करना

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Basel के ऐसे बिल्ड जो स्थानीय तौर पर सफल होते हैं, अगर उन्हें रिमोट तरीके से एक्ज़ीक्यूट नहीं किया जाता है, तो ऐसा हो सकता है: ऐसी पाबंदियां और ज़रूरी शर्तें हैं जिनका असर लोकल बिल्ड पर कोई असर नहीं पड़ता. रिमोट तौर पर प्रोसेस चलाने के लिए Bazel के नियमों को अडैप्ट करना लेख में, इस तरह की गड़बड़ियों की सबसे सामान्य वजहों के बारे में बताया गया है.

इस पेज पर, Docker सैंडबॉक्स की सुविधा का इस्तेमाल करके, रिमोट तरीके से प्रोग्राम चलाने से जुड़ी सबसे आम समस्याओं का पता लगाने और उन्हें हल करने का तरीका बताया गया है. इस सुविधा की वजह से, रिमोट तरीके से प्रोग्राम चलाने पर लगने वाली पाबंदियां, बिल्ड पर भी लागू होती हैं. इससे, रिमोट तौर पर प्रोग्राम चलाने की सेवा के बिना, अपने बिल्ड की समस्या हल की जा सकती है.

Docker सैंडबॉक्स की सुविधा, रिमोट तरीके से प्रोग्राम चलाने पर लगी पाबंदियों की नकल करती है. ये पाबंदियां इस तरह से लागू होती हैं:

  • टूलचेन कंटेनर में बनाई गई कार्रवाइयां एक्ज़ीक्यूट करें. आप भी इनका इस्तेमाल कर सकते हैं आपके बिल्ड को स्थानीय और कहीं से भी किसी सेवा के ज़रिए चलाने के लिए टूलचेन कंटेनर में कंटेनर को रिमोट तौर पर एक्ज़ीक्यूट करने की सुविधा मिलती है.

  • कोई भी अतिरिक्त डेटा, कंटेनर की सीमा से बाहर नहीं जाता. सिर्फ़ साफ़ तौर पर बताया गया है तय किए गए इनपुट और आउटपुट, कंटेनर में जाएंगे और उससे बाहर निकलेंगे. साथ ही, बिल्ड ऐक्शन पूरा होता है.

  • हर ऐक्शन, नए कंटेनर में लागू होता है. एक नया और खास कंटेनर है हर जनरेट किए गए बिल्ड ऐक्शन के लिए बनाया गया.

इन समस्याओं को हल करने के लिए, इनमें से किसी एक तरीके का इस्तेमाल करें:

  • समस्या को मूल रूप से हल करना. इस तरीके से, Bazel और उसकी बिल्ड ऐक्शन, आपकी लोकल मशीन पर नेटिव तौर पर चलते हैं. द डॉकर सैंडबॉक्स सुविधा, रिमोट के बराबर के बिल्ड पर पाबंदियां लगाती है लागू करता है. हालांकि, इस तरीके से आपके बिल्ड में लीक होने वाले लोकल टूल, स्टेटस, और डेटा का पता नहीं चलेगा. इससे, रिमोट तरीके से प्रोग्राम चलाने में समस्याएं आ सकती हैं.

  • Docker कंटेनर में समस्या हल करना. इस तरीके का इस्तेमाल करने पर, Basel और इसकी बिल्ड ऐक्शन, Docker कंटेनर के अंदर चलते हैं, इसकी मदद से, हम आपके लोकल ऐप्लिकेशन से ही टूल, राज्यों, और डेटा लीक होने का पता लगा सकते हैं नई चीज़ें बनाने के साथ-साथ, रिमोट एक्ज़ीक्यूशन के बराबर होती हैं. इस तरीके से, आपको अपने बाइल्ड के बारे में अहम जानकारी मिलती है. भले ही, बाइल्ड के कुछ हिस्से काम न कर रहे हों. इस तरीके को अभी आज़माया जा रहा है और आधिकारिक तौर पर समर्थित नहीं है.

ज़रूरी शर्तें

अगर आपने अब तक ऐसा नहीं किया है, तो समस्या हल करने से पहले ये काम करें:

  • Docker इंस्टॉल करें और इसे चलाने के लिए ज़रूरी अनुमतियां कॉन्फ़िगर करें.
  • Bazel 0.14.1 या इसके बाद का वर्शन इंस्टॉल करें. Docker के पिछले वर्शन में, सैंडबॉक्स की सुविधा काम नहीं करती.
  • यहां बताए गए तरीके से, अपने बिल्ड की WORKSPACE फ़ाइल में, रिलीज़ के सबसे नए वर्शन पर पिन किए गए bazel-toolchains रेपो को जोड़ें.
  • इस सुविधा को चालू करने के लिए, अपनी .bazelrc फ़ाइल में फ़्लैग जोड़ें. अगर फ़ाइल मौजूद नहीं है, तो अपने Bazel प्रोजेक्ट की रूट डायरेक्ट्री में फ़ाइल बनाएं. फ़्लैग नीचे दिए गए हैं एक संदर्भ नमूना है. कृपया नई जानकारी देखें .bazelrc फ़ाइल को बेज़ल-टूलचेन रेपो में सेव करें और तय किए गए फ़्लैग की वैल्यू कॉपी करें कॉन्फ़िगरेशन 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. Dockerfile का इस्तेमाल करके टूल इंस्टॉल करके, पसंद के मुताबिक Docker कंटेनर बनाएं और बिल्डिंग स्थानीय रूप से.

  2. ऊपर दिए गए --experimental_docker_image फ़्लैग के मान को आपके कस्टम कंटेनर की इमेज का नाम.

समस्या को मूल रूप से हल करना

यह तरीका Basel और इसकी सभी बिल्ड ऐक्शन को सीधे लोकल साइट पर एक्ज़ीक्यूट करता है मशीन से होता है और यह पुष्टि करने का एक भरोसेमंद तरीका है कि आपका बिल्ड रिमोट तरीके से चलाया जा सकता है.

हालांकि, इस तरीके से, स्थानीय तौर पर इंस्टॉल किए गए टूल, बाइनरी, और डेटा आपके बिल्ड में लीक हो सकते हैं. ऐसा खास तौर पर तब होता है, जब इसमें कॉन्फ़िगर-स्टाइल WORKSPACE नियमों का इस्तेमाल किया जाता है. इस तरह के लीक होने से, रिमोट तरीके से काम करने में समस्याएं होंगी; इनका पता लगाने के लिए, Docker कंटेनर में समस्या हल करें वह इन समस्याओं को हल करने में आपकी मदद करता है.

चरण 1: बिल्ड चलाएं

  1. --config=docker-sandbox फ़्लैग को बेज़ल कमांड में जोड़ें, जो लागू करता है आपका बिल्ड. उदाहरण के लिए:

    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 कंटेनर में समस्या हल करना लेख पर जाएं.

दूसरा चरण: समस्याओं को हल करना

यहां सबसे आम समस्याओं और उन्हें हल करने के तरीकों के बारे में बताया गया है.

  • Bazel के रनफ़ाइल ट्री में रेफ़र की गई फ़ाइल, टूल, बाइनरी या संसाधन मौजूद नहीं है.. पुष्टि करें कि जिन टारगेट पर असर पड़ा है उनकी सभी डिपेंडेंसी के बारे में साफ़ तौर पर एलान किया गया हो. यहां जाएं: इंप्लिसिट डिपेंडेंसी मैनेज करना हमारा वीडियो देखें.

  • ऐसी फ़ाइल, टूल, बाइनरी या संसाधन मौजूद नहीं है जिसका रेफ़रंस, एब्सोलूट पाथ या PATH वैरिएबल से दिया गया है. पुष्टि करें कि सभी ज़रूरी टूल को टूलचेन कंटेनर और टूलचेन नियमों का इस्तेमाल करके, सही तरीके से उस डिपेंडेंसी के बारे में बताएं जो उपलब्ध संसाधन के बारे में बताती है. ज़्यादा जानकारी के लिए, टूलचेन के नियमों की मदद से, बिल्ड टूल को शुरू करना देखें.

  • बाइनरी कोड लागू नहीं हो पाता है. बिल्ड का कोई एक नियम, बाइनरी का रेफ़रंस दे रहा है एक्ज़ीक्यूशन एनवायरमेंट (Docker कंटेनर) के साथ काम नहीं करता है. ज़्यादा जानकारी के लिए, प्लैटफ़ॉर्म पर निर्भर बाइनरी मैनेज करना देखें. अगर आपको समस्या हल करने में समस्या आ रही है, तो मदद पाने के लिए bazel-discuss@google.com पर संपर्क करें.

  • @local-jdk में मौजूद कोई फ़ाइल मौजूद नहीं है या उससे गड़बड़ियां हो रही हैं. आपकी स्थानीय मशीन पर मौजूद Java बाइनरी, बिल्ड में लीक हो रही हैं. हालांकि, ये बिल्ड के साथ काम नहीं करती हैं. java_toolchain का इस्तेमाल करें के बजाय अपने नियमों और लक्ष्यों में @local_jdk की जगह जोड़ दें. अगर आपको और सहायता चाहिए, तो bazel-discuss@google.com पर संपर्क करें.

  • अन्य गड़बड़ियां. मदद पाने के लिए, bazel-discuss@google.com पर संपर्क करें.

Docker कंटेनर में समस्या हल करना

इस तरीके से, Bazel किसी होस्ट Docker कंटेनर में चलता है. साथ ही, Bazel की बिल्ड ऐक्शन, Docker के सैंडबॉक्स की सुविधा से जनरेट किए गए अलग-अलग टूलचेन कंटेनर में लागू होती हैं. सैंडबॉक्स, हर बिल्ड ऐक्शन के लिए एक नया टूलचेन कंटेनर बनाता है. साथ ही, हर टूलचेन कंटेनर में सिर्फ़ एक ऐक्शन लागू होता है.

इस तरीके से, होस्ट में इंस्टॉल किए गए टूल पर ज़्यादा कंट्रोल मिलता है पर्यावरण को ध्यान में रखकर काम करना. बिल्ड को चलाने की प्रोसेस को, बिल्ड ऐक्शन को चलाने की प्रोसेस से अलग करके और इंस्टॉल किए गए टूल को कम से कम रखकर, यह पुष्टि की जा सकती है कि आपके बिल्ड में, स्थानीय रनटाइम एनवायरमेंट पर कोई डिपेंडेंसी है या नहीं.

पहला चरण: कंटेनर बनाना

  1. एक ऐसा Dockerfile बनाएं जो Docker कंटेनर बनाता हो और Basel को इंस्टॉल करता हो जिनमें बिल्ड टूल का कम से कम सेट मौजूद होता है:

    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
    

दूसरा चरण: कंटेनर शुरू करना

नीचे दिए गए निर्देश का इस्तेमाल करके, 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

यह निर्देश, कंटेनर को रूट की तरह चलाता है, डॉकर सॉकेट को मैप करता है, और माउंट करता है /tmp डायरेक्ट्री. इसकी मदद से बेज़ल अन्य Docker कंटेनर को बड़ा कर पाते हैं और इन कंटेनर के साथ फ़ाइलें शेयर करने के लिए, /tmp में दी गई डायरेक्ट्री का इस्तेमाल करें. आपका सोर्स कोड, कंटेनर में /src पर उपलब्ध है.

यह कमांड, जान-बूझकर debian:stretch बेस कंटेनर से शुरू होता है. इसमें ऐसी बाइनरी शामिल होती हैं जो टूलचैन कंटेनर के तौर पर इस्तेमाल किए जाने वाले rbe-ubuntu16-04 कंटेनर के साथ काम नहीं करती हैं. अगर स्थानीय वातावरण से बाइनरी टूलचेन कंटेनर है, तो उसकी वजह से बिल्ड में गड़बड़ियां होंगी.

तीसरा चरण: कंटेनर की जांच करना

Docker कंटेनर के अंदर से इसकी जांच करने के लिए, यहां दिए गए कमांड चलाएं:

docker ps
bazel version

चौथा चरण: बिल्ड चलाना

नीचे बताए गए तरीके से बिल्ड चलाएं. आउटपुट उपयोगकर्ता रूट होता है, ताकि वह एक ऐसी डायरेक्ट्री जिसे होस्ट के अंदर से उसी ऐब्सलूट पाथ से ऐक्सेस किया जा सकता है कंटेनर जिसमें बेज़ेल चलता है. यह डॉकर से पैदा हुए टूलचेन कंटेनर से लिया गया है एक सैंडबॉक्स सुविधा के साथ वह मशीन जिस पर होस्ट और ऐक्शन कंटेनर चलते हैं.

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

पांचवां चरण: पहचानी गई समस्याओं को ठीक करना

बिल्ड फ़ेल होने की समस्या को इस तरह ठीक किया जा सकता है:

  • अगर बिल्ड "डिस्क में स्टोरेज खत्म हो गया है" होने की वजह से काम नहीं करता है गड़बड़ी हुई है, तो इसे बढ़ाया जा सकता है --memory=XX फ़्लैग के साथ होस्ट कंटेनर शुरू करके सीमा तय करें, जहां XX गीगाबाइट में तय किया गया डिस्क स्टोरेज है. यह सुविधा, एक्सपेरिमेंट के तौर पर उपलब्ध है. इसलिए, ऐसा हो सकता है कि यह अलग तरह का व्यवहार करे.

  • अगर विश्लेषण या लोड करने के दौरान बिल्ड पूरा नहीं होता है, तो इसका मतलब है कि WORKSPACE फ़ाइल में बताए गए आपके एक या एक से ज़्यादा बिल्ड नियम, रिमोट तौर पर चलाए जाने की सुविधा के साथ काम नहीं करते. रिमोट तरीके से एक्ज़ीक्यूट करने के लिए बेज़ल नियमों को अपनाना देखें और समाधान के बारे में जानकारी पाएं.

  • अगर बिल्ड किसी और वजह से पूरा नहीं होता है, तो दूसरा चरण: पाई गई समस्याओं को हल करना में समस्या हल करने का तरीका देखें.