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

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

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

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

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

खास जानकारी

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

  • बिल्ड से जुड़ी कार्रवाइयां. बिल्ड टूल स्थिति को बरकरार नहीं रखते हैं और निर्भरता उनके बीच लीक नहीं हो सकती हैं.

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

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

टूलचेन नियमों की मदद से, बिल्ड टूल शुरू करना

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

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

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

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

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

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

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

आम तौर पर, होस्ट प्लैटफ़ॉर्म पर बनाई गई बाइनरी, मेल न खाने वाली डिपेंडेंसी की वजह से आर्बिट्ररी रिमोट एक्ज़ीक्यूशन प्लैटफ़ॉर्म पर सुरक्षित तरीके से काम नहीं कर पाती. उदाहरण के लिए, 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 के ज़रिए पहले की गई थी, जैसा कि यहां दिखाया गया है.