हो सकता है कि स्थानीय तौर पर काम करने वाले Bazel बिल्ड, रिमोट तौर पर चलाए जाने पर काम न करें. ऐसा, उन पाबंदियों और ज़रूरी शर्तों की वजह से होता है जिनका स्थानीय बिल्ड पर कोई असर नहीं पड़ता. ऐसी असफलता की सबसे आम वजहों के बारे में, रिमोट एक्ज़िक्यूशन के लिए बेज़ल रूल को लागू करना लेख में बताया गया है.
इस पेज में Docker सैंडबॉक्स सुविधा की मदद से, रिमोट तरीके से एक्ज़ीक्यूट करने की सुविधा की मदद से आम तौर पर होने वाली समस्याओं की पहचान करने और उन्हें हल करने का तरीका बताया गया है. इसमें, रिमोट तरीके से एक्ज़ीक्यूट किए जाने वाले बिल्ड के बराबर पाबंदियां लगाई जाती हैं. इससे आपको अपने बिल्ड की समस्या को हल करने में मदद मिलती है. इसके लिए, आपको रिमोट एक्ज़ीक्यूशन सेवा की ज़रूरत नहीं होती.
Docker सैंडबॉक्स सुविधा, रिमोट तौर पर एक्ज़ीक्यूट करने की पाबंदियों की नकल इस तरह करती है:
टूलचेन कंटेनर में बनाई गई कार्रवाइयां एक्ज़ीक्यूट करें. एक ही टूलचेन कंटेनर का इस्तेमाल करके, अपने बिल्ड को स्थानीय तौर पर या कहीं से भी चलाया जा सकता है. ऐसा करने के लिए, कंटेनर वाली रिमोट एक्ज़ीक्यूशन की सुविधा का इस्तेमाल किया जा सकता है.
कोई भी अतिरिक्त डेटा, कंटेनर की सीमा से बाहर नहीं जाता. सिर्फ़ साफ़ तौर पर बताए गए इनपुट और आउटपुट, कंटेनर में जाते हैं और उससे बाहर निकलते हैं. ऐसा, उससे जुड़ी बिल्ड ऐक्शन पूरी होने के बाद ही होता है.
हर ऐक्शन, नए कंटेनर में लागू होता है. हर जनरेट किए गए बिल्ड ऐक्शन के लिए, एक नया और यूनीक कंटेनर बनाया जाता है.
इन समस्याओं को हल करने के लिए, इनमें से किसी एक तरीके का इस्तेमाल करें:
समस्या को मूल रूप से हल करना. इस तरीके से, Bazel और उसकी बिल्ड ऐक्शन, आपकी लोकल मशीन पर नेटिव तौर पर चलते हैं. Docker के सैंडबॉक्स की सुविधा, रिमोट से प्रोग्राम चलाने पर लागू होने वाली पाबंदियों के बराबर ही, बिल्ड पर पाबंदियां लगाती है. हालांकि, इस तरीके से आपके बिल्ड में लीक होने वाले लोकल टूल, स्टेटस, और डेटा का पता नहीं चलेगा. इससे, रिमोट तरीके से प्रोग्राम चलाने में समस्याएं आ सकती हैं.
Docker कंटेनर में समस्या हल करना. इस तरीके से, Bazel और उसकी बिल्ड ऐक्शन, Docker कंटेनर में चलते हैं. इससे, आपको स्थानीय मशीन से बिल्ड में लीक होने वाले टूल, स्टेटस, और डेटा का पता लगाने के साथ-साथ, रिमोट से प्रोग्राम चलाने पर लागू होने वाली पाबंदियों के बराबर पाबंदियां भी लगाने में मदद मिलती है. इस तरीके से आपके बिल्ड की अहम जानकारी मिलती है, भले ही बिल्ड के कुछ हिस्से काम न कर रहे हों. यह तरीका एक्सपेरिमेंट के तौर पर उपलब्ध है और इसे आधिकारिक तौर पर इस्तेमाल नहीं किया जा सकता.
ज़रूरी शर्तें
अगर आपने अब तक ऐसा नहीं किया है, तो समस्या हल करने से पहले ये काम करें:
- Docker इंस्टॉल करें और इसे चलाने के लिए ज़रूरी अनुमतियां कॉन्फ़िगर करें.
- Bazel 0.14.1 या इसके बाद का वर्शन इंस्टॉल करें. पिछले वर्शन में Docker सैंडबॉक्स की सुविधा काम नहीं करती.
- यहां बताए गए तरीके से, अपने बिल्ड की
WORKSPACE
फ़ाइल में, रिलीज़ के सबसे नए वर्शन पर पिन किए गए bazel-toolchains रेपो को जोड़ें. - इस सुविधा को चालू करने के लिए, अपनी
.bazelrc
फ़ाइल में फ़्लैग जोड़ें. अगर फ़ाइल मौजूद नहीं है, तो अपने Bazel प्रोजेक्ट की रूट डायरेक्ट्री में फ़ाइल बनाएं. यहां दिए गए फ़्लैग, रेफ़रंस के तौर पर दिए गए हैं. कृपया bazel-toolchains repo में सबसे नई.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
अगर आपके नियमों के लिए ज़्यादा टूल की ज़रूरत है, तो यह तरीका अपनाएं:
Dockerfile का इस्तेमाल करके टूल इंस्टॉल करके और इमेज को लोकल तौर पर बिल्ड करके, कस्टम Docker कंटेनर बनाएं.
ऊपर दिए गए
--experimental_docker_image
फ़्लैग की वैल्यू को अपने कस्टम कंटेनर इमेज के नाम से बदलें.
समस्या को मूल रूप से हल करना
यह तरीका Basel और इसके सभी बिल्ड ऐक्शन को सीधे तौर पर लोकल मशीन पर एक्ज़ीक्यूट करता है. यह इस बात की पुष्टि करने का भरोसेमंद तरीका है कि रिमोट तरीके से लागू करने पर, आपका बिल्ड कामयाब हो पाएगा या नहीं.
हालांकि, इस तरीके से आपके बिल्ड में स्थानीय तौर पर इंस्टॉल किए गए टूल, बाइनरी, और डेटा लीक हो सकता है. खास तौर पर तब, जब यह कॉन्फ़िगर-स्टाइल वर्कस्पेस नियमों का इस्तेमाल करता हो. इस तरह की लीक की वजह से, रिमोट तौर पर प्रोग्राम चलाने में समस्याएं आ सकती हैं. इनका पता लगाने के लिए, Docker कंटेनर में समस्या हल करें. साथ ही, समस्या को सामान्य तरीके से भी हल करें.
पहला चरण: बिल्ड चलाना
Basel कमांड में
--config=docker-sandbox
फ़्लैग जोड़ें, जो आपके बिल्ड को एक्ज़ीक्यूट करता है. उदाहरण के लिए:bazel --bazelrc=.bazelrc build --config=docker-sandbox target
बिल्ड चलाएं और इसके पूरा होने का इंतज़ार करें. Docker सैंडबॉक्स की सुविधा की वजह से, बिल्ड सामान्य से चार गुना धीमे चलेगा.
आपको इस गड़बड़ी का सामना करना पड़ सकता है:
ERROR: 'docker' is an invalid value for docker spawn strategy.
अगर ऐसा किया जाता है, तो --experimental_docker_verbose
फ़्लैग की मदद से बिल्ड को फिर से चलाएं.
इस फ़्लैग की मदद से, गड़बड़ी के बारे में ज़्यादा जानकारी देने वाले मैसेज दिखाए जा सकते हैं. आम तौर पर, यह गड़बड़ी Docker के गलत तरीके से इंस्टॉल होने या मौजूदा उपयोगकर्ता खाते में इसे चलाने की अनुमतियां न होने की वजह से होती है. ज़्यादा जानकारी के लिए, Docker दस्तावेज़ देखें. अगर समस्याएं बनी रहती हैं, तो सीधे Docker कंटेनर में समस्या का हल पर जाएं.
दूसरा चरण: पहचानी गई समस्याओं को ठीक करना
यहां सबसे आम समस्याओं और उन्हें हल करने के तरीकों के बारे में बताया गया है.
Baज़ल रनफ़ाइल ट्री से रेफ़र की गई फ़ाइल, टूल, बाइनरी या संसाधन मौजूद नहीं है.. यह पक्का करें कि जिन टारगेट पर असर पड़ा है उनकी सभी डिपेंडेंसी साफ़ तौर पर एलान की गई हों. ज़्यादा जानकारी के लिए, इंप्लिसिट डिपेंडेंसी मैनेज करना देखें.
ऐब्सलूट पाथ या
PATH
वैरिएबल से जुड़ी फ़ाइल, टूल, बाइनरी या रिसॉर्स मौजूद नहीं हैं. पुष्टि करें कि टूलचेन कंटेनर में सभी ज़रूरी टूल इंस्टॉल किए गए हैं. साथ ही, टूलचेन के नियमों का इस्तेमाल करके, मौजूद न होने वाले संसाधन की जानकारी देने वाली डिपेंडेंसी का सही तरीके से एलान करें. ज़्यादा जानकारी के लिए, टूलचेन के नियमों की मदद से, बिल्ड टूल को शुरू करना देखें.बाइनरी को लागू नहीं किया जा सका. बिल्ड के नियमों में से एक यह है कि एक्ज़ीक्यूशन एनवायरमेंट (डॉकर कंटेनर) के साथ बाइनरी इनऐक्टिव है. ज़्यादा जानकारी के लिए, प्लैटफ़ॉर्म पर निर्भर बाइनरी मैनेज करना देखें. अगर आपको समस्या हल करने में समस्या आ रही है, तो मदद पाने के लिए bazel-discuss@google.com पर संपर्क करें.
@local-jdk
में मौजूद कोई फ़ाइल मौजूद नहीं है या उससे गड़बड़ियां हो रही हैं. आपकी लोकल मशीन पर मौजूद Java बाइनरी, बिल्ड में लीक हो रही हैं, लेकिन इसके साथ काम नहीं करतीं. अपने नियमों और टारगेट में@local_jdk
के बजाय,java_toolchain
का इस्तेमाल करें. अगर आपको और सहायता चाहिए, तो bazel-discuss@google.com पर संपर्क करें.अन्य गड़बड़ियां. सहायता के लिए, bazel-discuss@google.com से संपर्क करें.
Docker कंटेनर में समस्या हल करना
इस तरीके से, Bazel किसी होस्ट Docker कंटेनर में चलता है. साथ ही, Bazel की बिल्ड ऐक्शन, Docker के सैंडबॉक्स की सुविधा से जनरेट किए गए अलग-अलग टूलचेन कंटेनर में लागू होती हैं. सैंडबॉक्स हर बिल्ड ऐक्शन के लिए एक नया टूलचेन कंटेनर बनाता है. साथ ही, हर टूलचेन कंटेनर में सिर्फ़ एक ऐक्शन होता है.
इस तरीके से, होस्ट के एनवायरमेंट में इंस्टॉल किए गए टूल पर ज़्यादा बेहतर तरीके से कंट्रोल किया जा सकता है. बिल्ड के एक्ज़ीक्यूशन के एक्ज़ीक्यूशन को इसके बिल्ड ऐक्शन के एक्ज़ीक्यूशन से अलग करके और इंस्टॉल किए गए टूल को कम से कम रखकर, यह पुष्टि की जा सकती है कि आपका बिल्ड, लोकल एक्ज़ीक्यूशन एनवायरमेंट पर निर्भर करता है या नहीं.
पहला चरण: कंटेनर बनाना
ऐसा
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
कंटेनर को
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
डायरेक्ट्री को माउंट करता है. इससे Basel को अन्य 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 फ़ाइल में बताए गए आपके एक या एक से ज़्यादा बिल्ड नियम, रिमोट तौर पर लागू करने के साथ काम नहीं करते. संभावित वजहों और समाधानों के बारे में जानने के लिए, रिमोट एक्ज़ीक्यूशन के लिए बेज़ल नियमों को अपनाना देखें.
अगर बिल्ड किसी और वजह से पूरा नहीं होता है, तो दूसरा चरण: पाई गई समस्याओं को हल करना में समस्या हल करने का तरीका देखें.