रिमोट एक्ज़ीक्यूशन के लिए, Bazel के नियमों को अपनाना

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

रिमोट एक्ज़ीक्यूशन की मदद से, Bazel किसी दूसरे प्लैटफ़ॉर्म पर कार्रवाइयां कर सकता है. जैसे, डेटा सेंटर. Bazel, रिमोट एक्ज़ीक्यूशन के लिए gRPC प्रोटोकॉल का इस्तेमाल करता है. bazel-buildfarm की मदद से, रिमोट एक्ज़ीक्यूशन आज़माया जा सकता है. यह एक ओपन-सोर्स प्रोजेक्ट है, जिसका मकसद डिस्ट्रिब्यूटेड रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म उपलब्ध कराना है.

इस पेज पर, अलग-अलग एनवायरमेंट टाइप या प्लैटफ़ॉर्म के बारे में बताने के लिए, यहां दी गई शब्दावली का इस्तेमाल किया गया है:

  • होस्ट प्लैटफ़ॉर्म - जहां Bazel चलता है.
  • एक्ज़ीक्यूशन प्लैटफ़ॉर्म - जहां Bazel की कार्रवाइयां चलती हैं.
  • टारगेट प्लैटफ़ॉर्म - जहां बिल्ड आउटपुट (और कुछ कार्रवाइयां) चलते हैं.

खास जानकारी

रिमोट एक्ज़ीक्यूशन के लिए Bazel बिल्ड को कॉन्फ़िगर करते समय, आपको इस पेज पर बताई गई गाइडलाइन का पालन करना होगा. इससे यह पक्का किया जा सकेगा कि बिल्ड, बिना किसी गड़बड़ी के रिमोट तरीके से एक्ज़ीक्यूट हो. ऐसा रिमोट एक्ज़ीक्यूशन की वजह से होता है. जैसे:

  • आइसोलेटेड बिल्ड ऐक्शन. बिल्ड टूल, स्टेट को बनाए नहीं रखते. साथ ही, उनके बीच डिपेंडेंसी लीक नहीं हो सकती.

  • अलग-अलग एक्ज़ीक्यूशन एनवायरमेंट. लोकल बिल्ड कॉन्फ़िगरेशन, रिमोट एक्ज़ीक्यूशन एनवायरमेंट के लिए हमेशा सही नहीं होता.

इस पेज पर, Bazel के कस्टम बिल्ड और टेस्ट के नियमों को रिमोट एक्ज़ीक्यूशन के लिए लागू करते समय आने वाली समस्याओं के बारे में बताया गया है. साथ ही, यह भी बताया गया है कि इन समस्याओं से कैसे बचा जा सकता है. इसमें इन विषयों के बारे में बताया गया है:

टूलचेन के नियमों के ज़रिए, बिल्ड टूल को लागू करना

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

Scala अगर आपके नियम में इस्तेमाल किए गए टूल के लिए, टूलचेन का कोई नियम मौजूद नहीं है, तो टूलचेन का नियम बनाने पर विचार करें.

इम्प्लिसिट डिपेंडेंसी मैनेज करना

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

उदाहरण के लिए, जब Bazel, स्टेटफ़ुल कंपाइलर को स्थानीय तौर पर foo, बनाने का निर्देश देता है, तो कंपाइलर, foo के बिल्ड आउटपुट के रेफ़रंस बनाए रखता है. इसके बाद, जब Bazel कंपाइलर को bar बनाने का निर्देश देता है, जो foo पर निर्भर करता है, तो कार्रवाई सफलतापूर्वक एक्ज़ीक्यूट होती है. ऐसा तब तक होता है, जब तक दोनों कार्रवाइयों के लिए कंपाइलर का एक ही इंस्टेंस एक्ज़ीक्यूट होता है. हालांकि, BUILD फ़ाइल में, कंपाइलर को लागू करते समय, साफ़ तौर पर यह नहीं बताया जाता कि bar , foo पर निर्भर करता है. स्थानीय तौर पर एक्ज़ीक्यूट करने के लिए, ऐसा करना आम बात है. हालांकि, रिमोट एक्ज़ीक्यूशन के मामले में, हर बिल्ड कार्रवाई के लिए कंपाइलर का अलग इंस्टेंस एक्ज़ीक्यूट होता है. इसलिए, कंपाइलर की स्टेट और bar's की foo पर मौजूद इम्प्लिसिट डिपेंडेंसी खत्म हो जाएगी. साथ ही, बिल्ड फ़ेल हो जाएगा.

डिपेंडेंसी से जुड़ी इन समस्याओं का पता लगाने और उन्हें ठीक करने के लिए, Bazel 0.14.1 में लोकल Docker सैंडबॉक्स की सुविधा उपलब्ध है. इसमें, डिपेंडेंसी के लिए वही पाबंदियां लागू होती हैं जो रिमोट एक्ज़ीक्यूशन के लिए लागू होती हैं. सैंडबॉक्स का इस्तेमाल करके, डिपेंडेंसी से जुड़ी बिल्ड की गड़बड़ियों की पहचान करें और उन्हें ठीक करें. इससे, अपने बिल्ड को रिमोट एक्ज़ीक्यूशन के लिए तैयार किया जा सकता है. ज़्यादा जानकारी के लिए, Docker सैंडबॉक्स की मदद से, Bazel के रिमोट एक्ज़ीक्यूशन से जुड़ी समस्याओं को हल करना लेख पढ़ें.

प्लैटफ़ॉर्म पर निर्भर बाइनरी मैनेज करना

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

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

  • टूल के लिए सोर्स कोड शिप करें या उसका बाहरी रेफ़रंस दें, ताकि उसे रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म के लिए बनाया जा सके.

  • अगर टूल, रिमोट एक्ज़ीक्यूशन एनवायरमेंट (उदाहरण के लिए, टूलचेन कंटेनर) में पहले से इंस्टॉल है और वह काफ़ी स्टेबल है, तो उसे अपने बिल्ड में चलाने के लिए, टूलचेन के नियमों का इस्तेमाल करें.

कॉन्फ़िगर-स्टाइल वाले WORKSPACE के नियम मैनेज करना

Bazel के WORKSPACE के नियमों का इस्तेमाल, बिल्ड के लिए ज़रूरी टूल और लाइब्रेरी के लिए, होस्ट प्लैटफ़ॉर्म की जांच करने के लिए किया जा सकता है. लोकल बिल्ड के लिए, यह Bazel का एक्ज़ीक्यूशन प्लैटफ़ॉर्म भी है. अगर बिल्ड, लोकल बिल्ड टूल और आर्टफ़ैक्ट पर साफ़ तौर पर निर्भर करता है, तो रिमोट एक्ज़ीक्यूशन के दौरान वह फ़ेल हो जाएगा. ऐसा तब होगा, जब रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म, होस्ट प्लैटफ़ॉर्म जैसा नहीं होगा.

WORKSPACE के नियमों से की जाने वाली ये कार्रवाइयां, रिमोट एक्ज़ीक्यूशन के साथ काम नहीं करतीं:

  • बाइनरी बनाना. WORKSPACE के नियमों में कंपाइलेशन की कार्रवाइयां करने से, ऐसी बाइनरी बनती हैं जो रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म के साथ काम नहीं करतीं. ऐसा तब होता है, जब रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म, होस्ट प्लैटफ़ॉर्म से अलग होता है.

  • पैकेज इंस्टॉल करना.pip WORKSPACE के नियमों के ज़रिए इंस्टॉल किए गए pip पैकेज के लिए, ज़रूरी है कि उनकी डिपेंडेंसी, होस्ट प्लैटफ़ॉर्म पर पहले से इंस्टॉल हों. ऐसे पैकेज, खास तौर पर होस्ट प्लैटफ़ॉर्म के लिए बनाए जाते हैं. इसलिए, अगर रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म, होस्ट प्लैटफ़ॉर्म से अलग है, तो वे उसके साथ काम नहीं करेंगे.

  • लोकल टूल या आर्टफ़ैक्ट से सिमलिंक करना. WORKSPACE के नियमों के ज़रिए, होस्ट प्लैटफ़ॉर्म पर इंस्टॉल किए गए टूल या लाइब्रेरी से बनाए गए सिमलिंक की वजह से, रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म पर बिल्ड फ़ेल हो जाएगा. ऐसा इसलिए, क्योंकि Bazel उन्हें ढूंढ नहीं पाएगा. इसके बजाय, स्टैंडर्ड बिल्ड ऐक्शन का इस्तेमाल करके सिमलिंक बनाएं, ताकि सिमलिंक किए गए टूल और लाइब्रेरी, Bazel के runfiles ट्री से ऐक्सेस किए जा सकें. टारगेट फ़ाइलों को बाहरी रिपॉज़िटरी डायरेक्ट्री के बाहर सिमलिंक करने के लिए, repository_ctx.symlink का इस्तेमाल न करें.

  • होस्ट प्लैटफ़ॉर्म में बदलाव करना. Bazel runfiles ट्री के बाहर फ़ाइलें न बनाएं, एनवायरमेंट वैरिएबल न बनाएं, और इसी तरह की अन्य कार्रवाइयां न करें. ऐसा इसलिए, क्योंकि रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म पर, ये कार्रवाइयां उम्मीद के मुताबिक काम नहीं कर सकती हैं.

संभावित तौर पर, नॉन-हर्मेटिक व्यवहार का पता लगाने के लिए, Workspace के नियमों के लॉग का इस्तेमाल किया जा सकता है.

अगर कोई बाहरी डिपेंडेंसी, होस्ट प्लैटफ़ॉर्म पर निर्भर खास कार्रवाइयां करती है, तो आपको उन कार्रवाइयों को WORKSPACE और बिल्ड के नियमों के बीच इस तरह बांटना चाहिए:

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

  • टारगेट के हिसाब से आर्टफ़ैक्ट जनरेट करना या कंपाइल करना और प्लैटफ़ॉर्म में बदलाव करना. इन कार्रवाइयों को, बिल्ड के सामान्य नियमों के ज़रिए एक्ज़ीक्यूट किया जाना चाहिए. बाहरी डिपेंडेंसी के लिए, टारगेट के हिसाब से आर्टफ़ैक्ट बनाने वाली कार्रवाइयों को बिल्ड के दौरान एक्ज़ीक्यूट किया जाना चाहिए.

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

उदाहरण के लिए, cuda और python के लिए, Tensorflow के नियमों के लिए, WORKSPACE के नियम, ये BUILD files बनाते हैं. लोकल एक्ज़ीक्यूशन के लिए, होस्ट एनवायरमेंट की जांच करके बनाई गई फ़ाइलों का इस्तेमाल किया जाता है. रिमोट एक्ज़ीक्यूशन के लिए, एनवायरमेंट वैरिएबल पर मौजूद शर्तों वाले स्टेटमेंट की मदद से, नियम उन फ़ाइलों का इस्तेमाल कर सकता है जिनकी जांच करके उन्हें रिपॉज़िटरी में शामिल किया गया है.

BUILD फ़ाइलों में genrules का एलान किया जाता है. इन्हें स्थानीय और रिमोट, दोनों तरीकों से चलाया जा सकता है. साथ ही, ये ज़रूरी प्रोसेसिंग करती हैं. पहले यह काम, repository_ctx.symlink के ज़रिए किया जाता था. यहां इसका उदाहरण दिया गया है.