การปรับกฎของ Bazel เพื่อการเรียกใช้ระยะไกล

หน้านี้มีไว้สำหรับผู้ใช้ Bazel ที่เขียนกฎการสร้างและการทดสอบที่กำหนดเอง ซึ่งต้องการทำความเข้าใจข้อกำหนดสำหรับกฎ Bazel ในบริบทของการดำเนินการระยะไกล

การดำเนินการระยะไกลช่วยให้ Bazel ดำเนินการในแพลตฟอร์มอื่นได้ เช่น ศูนย์ข้อมูล Bazel ใช้ โปรโตคอล gRPC สำหรับการดำเนินการระยะไกล คุณลองใช้การดำเนินการระยะไกลกับ bazel-buildfarm, ซึ่งเป็นโปรเจ็กต์โอเพนซอร์สที่มีเป้าหมายเพื่อจัดหาแพลตฟอร์มการดำเนินการระยะไกลแบบกระจาย

หน้านี้ใช้คำศัพท์ต่อไปนี้เมื่ออ้างถึงสภาพแวดล้อมประเภทต่างๆ หรือ แพลตฟอร์ม:

  • แพลตฟอร์มโฮสต์ - แพลตฟอร์มที่ Bazel ทำงาน
  • แพลตฟอร์มการดำเนินการ - แพลตฟอร์มที่การดำเนินการของ Bazel ทำงาน
  • แพลตฟอร์มเป้าหมาย - แพลตฟอร์มที่เอาต์พุตบิลด์ (และการดำเนินการบางอย่าง) ทำงาน

ภาพรวม

เมื่อกำหนดค่าบิลด์ Bazel สำหรับการดำเนินการระยะไกล คุณต้องทำตามหลักเกณฑ์ที่อธิบายไว้ในหน้านี้เพื่อให้แน่ใจว่าบิลด์จะดำเนินการระยะไกลโดยไม่มีข้อผิดพลาด ซึ่งเป็นผลมาจากลักษณะของการดำเนินการระยะไกล ดังนี้

  • การดำเนินการสร้างแบบแยก เครื่องมือสร้างจะไม่เก็บสถานะไว้และทรัพยากร Dependency จะไม่รั่วไหลระหว่างเครื่องมือ

  • สภาพแวดล้อมการดำเนินการที่หลากหลาย การกำหนดค่าบิลด์ในเครื่องอาจไม่เหมาะกับสภาพแวดล้อมการดำเนินการระยะไกลเสมอไป

หน้านี้อธิบายปัญหาที่อาจเกิดขึ้นเมื่อใช้กฎการสร้างและการทดสอบ Bazel ที่กำหนดเองสำหรับการดำเนินการระยะไกล รวมถึงวิธีหลีกเลี่ยงปัญหาดังกล่าว โดยจะครอบคลุมหัวข้อต่อไปนี้

การเรียกใช้เครื่องมือบิลด์ผ่านกฎ Toolchain

กฎ Toolchain ของ Bazel เป็นผู้ให้บริการการกำหนดค่าที่บอกกฎการสร้างว่าจะใช้เครื่องมือสร้างใด เช่น คอมไพเลอร์และตัวเชื่อมโยง และวิธีกำหนดค่าเครื่องมือเหล่านั้นโดยใช้พารามิเตอร์ที่กำหนดโดยผู้สร้างกฎ กฎ Toolchain ช่วยให้กฎการสร้างและการทดสอบเรียกใช้เครื่องมือสร้างในลักษณะที่คาดการณ์ได้และกำหนดค่าไว้ล่วงหน้า ซึ่งเข้ากันได้กับการดำเนินการระยะไกล ตัวอย่างเช่น ใช้กฎ Toolchain แทนการเรียกใช้เครื่องมือสร้างผ่าน PATH, JAVA_HOME หรือตัวแปรอื่นๆ ในเครื่องที่อาจไม่ได้ตั้งค่าเป็นค่าที่เทียบเท่า (หรือไม่ได้ตั้งค่าเลย) ในสภาพแวดล้อมการดำเนินการระยะไกล

ปัจจุบันมีกฎ Toolchain สำหรับกฎการสร้างและการทดสอบ Bazel สำหรับ Scala, Rust, และ Go, และกฎ Toolchain ใหม่กำลังอยู่ระหว่างการพัฒนาสำหรับภาษาและเครื่องมืออื่นๆ เช่น Bash หากไม่มีกฎ Toolchain สำหรับเครื่องมือที่กฎของคุณใช้ ให้พิจารณา สร้างกฎ Toolchain

การจัดการทรัพยากร Dependency โดยนัย

หากเครื่องมือสร้างเข้าถึงทรัพยากร Dependency ในการดำเนินการสร้างได้ การดำเนินการเหล่านั้นจะล้มเหลวเมื่อดำเนินการระยะไกล เนื่องจากระบบจะดำเนินการสร้างระยะไกลแต่ละรายการแยกจากการดำเนินการอื่นๆ เครื่องมือสร้างบางรายการจะเก็บสถานะไว้ในการดำเนินการสร้างและเข้าถึงทรัพยากร Dependency ที่ไม่ได้รวมไว้ในการเรียกใช้เครื่องมืออย่างชัดเจน ซึ่งจะทำให้การดำเนินการสร้างระยะไกลล้มเหลว

ตัวอย่างเช่น เมื่อ Bazel สั่งให้คอมไพเลอร์ที่เก็บสถานะสร้าง foo ในเครื่อง คอมไพเลอร์จะเก็บข้อมูลอ้างอิงถึงเอาต์พุตการบิลด์ของ foo ไว้ จากนั้นเมื่อ Bazel สั่งให้คอมไพเลอร์สร้าง bar ซึ่งขึ้นอยู่กับ foo โดยไม่ได้ระบุทรัพยากร Dependency นั้นอย่างชัดเจนในไฟล์ BUILD เพื่อรวมไว้ในการเรียกใช้คอมไพเลอร์ การดำเนินการจะดำเนินการได้สำเร็จตราบใดที่อินสแตนซ์คอมไพเลอร์เดียวกันดำเนินการสำหรับการดำเนินการทั้ง 2 รายการ (ซึ่งเป็นลักษณะปกติของการดำเนินการในเครื่อง) อย่างไรก็ตาม เนื่องจากในสถานการณ์การดำเนินการระยะไกล การดำเนินการบิลด์แต่ละรายการจะเรียกใช้อินสแตนซ์คอมไพเลอร์แยกกัน สถานะคอมไพเลอร์และทรัพยากร Dependency โดยนัยของ bar ที่มีต่อ foo จะหายไปและการบิลด์จะล้มเหลว

Bazel 0.14.1 มีแซนด์บ็อกซ์ Docker ในเครื่อง ซึ่งมีข้อจำกัดเดียวกันสำหรับทรัพยากร Dependency กับการดำเนินการระยะไกล เพื่อช่วยตรวจหาและกำจัดปัญหาทรัพยากร Dependency เหล่านี้ ใช้แซนด์บ็อกซ์เพื่อเตรียมบิลด์สำหรับการดำเนินการระยะไกลโดยระบุและแก้ไขข้อผิดพลาดในการสร้างที่เกี่ยวข้องกับทรัพยากร Dependency ดูข้อมูลเพิ่มเติมได้ที่ การแก้ปัญหาการดำเนินการระยะไกลของ Bazel ด้วยแซนด์บ็อกซ์ Docker

การจัดการไบนารีที่ขึ้นอยู่กับแพลตฟอร์ม

โดยปกติแล้ว ไบนารีที่สร้างในแพลตฟอร์มโฮสต์จะไม่สามารถดำเนินการได้อย่างปลอดภัยในแพลตฟอร์มการดำเนินการระยะไกลที่กำหนด เนื่องจากทรัพยากร Dependency อาจไม่ตรงกัน ตัวอย่างเช่น ไบนารี SingleJar ที่มาพร้อมกับ Bazel จะกำหนดเป้าหมายเป็นแพลตฟอร์มโฮสต์ อย่างไรก็ตาม สำหรับการดำเนินการระยะไกล จะต้องคอมไพล์ SingleJar เป็นส่วนหนึ่งของกระบวนการสร้างโค้ดเพื่อให้กำหนดเป้าหมายเป็นแพลตฟอร์มการดำเนินการระยะไกล (ดูตรรกะการเลือก เป้าหมาย)

อย่าจัดส่งไบนารีของเครื่องมือสร้างที่บิลด์ของคุณต้องใช้พร้อมกับซอร์สโค้ด เว้นแต่คุณจะมั่นใจว่าไบนารีเหล่านั้นจะทำงานได้อย่างปลอดภัยในแพลตฟอร์มการดำเนินการ แต่ให้ทำอย่างใดอย่างหนึ่งต่อไปนี้

  • จัดส่งหรืออ้างอิงซอร์สโค้ดของเครื่องมือจากภายนอกเพื่อให้สร้างเครื่องมือสำหรับแพลตฟอร์มการดำเนินการระยะไกลได้

  • ติดตั้งเครื่องมือไว้ล่วงหน้าในสภาพแวดล้อมการดำเนินการระยะไกล (เช่น คอนเทนเนอร์ Toolchain) หากเครื่องมือมีความเสถียรเพียงพอ และใช้กฎ Toolchain เพื่อเรียกใช้เครื่องมือในการสร้าง

การจัดการกฎ WORKSPACE ในรูปแบบการกำหนดค่า

คุณสามารถใช้กฎ WORKSPACE ของ Bazel เพื่อตรวจสอบเครื่องมือและไลบรารีที่การบิลด์ต้องใช้ในแพลตฟอร์มโฮสต์ ซึ่งสำหรับการบิลด์ในเครื่องก็คือแพลตฟอร์มการดำเนินการของ Bazel ด้วย หากบิลด์ขึ้นอยู่กับเครื่องมือสร้างและอาร์ติแฟกต์ในเครื่องอย่างชัดเจน บิลด์จะล้มเหลวระหว่างการดำเนินการระยะไกลหากแพลตฟอร์มการดำเนินการระยะไกลไม่เหมือนกับแพลตฟอร์มโฮสต์

การดำเนินการต่อไปนี้ที่กฎ WORKSPACE ดำเนินการไม่เข้ากันกับการดำเนินการระยะไกล

  • การสร้างไบนารี การดำเนินการคอมไพเลชันในกฎ WORKSPACE จะส่งผลให้เกิดไบนารีที่ไม่เข้ากันกับแพลตฟอร์มการดำเนินการระยะไกลหากแพลตฟอร์มการดำเนินการระยะไกลแตกต่างจากแพลตฟอร์มโฮสต์

  • การติดตั้งแพ็กเกจ pip pip แพ็กเกจที่ติดตั้งผ่าน WORKSPACE กฎกำหนดให้ต้องติดตั้งทรัพยากร Dependency ของแพ็กเกจไว้ล่วงหน้าในแพลตฟอร์มโฮสต์ แพ็กเกจดังกล่าวที่สร้างขึ้นสำหรับแพลตฟอร์มโฮสต์โดยเฉพาะจะไม่เข้ากันกับแพลตฟอร์มการดำเนินการระยะไกลหากแพลตฟอร์มการดำเนินการระยะไกลแตกต่างจากแพลตฟอร์มโฮสต์

  • การสร้างลิงก์สัญลักษณ์ไปยังเครื่องมือหรืออาร์ติแฟกต์ในเครื่อง ลิงก์สัญลักษณ์ไปยังเครื่องมือหรือไลบรารีที่ติดตั้งในแพลตฟอร์มโฮสต์ซึ่งสร้างผ่านกฎ WORKSPACE จะทำให้บิลด์ล้มเหลวในแพลตฟอร์มการดำเนินการระยะไกล เนื่องจาก Bazel จะค้นหาเครื่องมือหรือไลบรารีเหล่านั้นไม่พบ แต่ให้สร้างลิงก์สัญลักษณ์โดยใช้การดำเนินการสร้างมาตรฐานเพื่อให้เครื่องมือและไลบรารีที่สร้างลิงก์สัญลักษณ์เข้าถึงได้จากทรี runfiles ของ Bazel อย่าใช้ repository_ctx.symlink เพื่อสร้างลิงก์สัญลักษณ์ไปยังไฟล์เป้าหมายนอกไดเรกทอรีที่เก็บภายนอก

  • การเปลี่ยนแปลงแพลตฟอร์มโฮสต์ หลีกเลี่ยงการสร้างไฟล์นอกทรี Bazel runfiles การสร้างตัวแปรสภาพแวดล้อม และการดำเนินการที่คล้ายกัน เนื่องจาก ไฟล์และตัวแปรเหล่านั้นอาจทำงานไม่เป็นไปตามที่คาดไว้ในแพลตฟอร์มการดำเนินการระยะไกล

คุณสามารถใช้ บันทึกกฎ Workspace เพื่อช่วยค้นหาลักษณะการทำงานที่อาจไม่เป็นไปตามหลักการแยกส่วน

หากทรัพยากร Dependency ภายนอกดำเนินการบางอย่างที่ขึ้นอยู่กับแพลตฟอร์มโฮสต์ คุณควรแยกการดำเนินการเหล่านั้นระหว่างกฎ WORKSPACE และกฎการบิลด์ ดังนี้

  • การตรวจสอบแพลตฟอร์มและการแจกแจงทรัพยากร Dependency การดำเนินการเหล่านี้ปลอดภัยที่จะดำเนินการในเครื่องผ่านกฎ WORKSPACE ซึ่งสามารถตรวจสอบไลบรารีที่ติดตั้ง ดาวน์โหลดแพ็กเกจที่ต้องสร้าง และเตรียมอาร์ติแฟกต์ที่จำเป็นสำหรับการคอมไพเลชัน สำหรับการดำเนินการระยะไกล กฎเหล่านี้ต้องรองรับการใช้อาร์ติแฟกต์ที่ตรวจสอบไว้ล่วงหน้าด้วยเพื่อระบุข้อมูลที่จะได้รับตามปกติระหว่างการตรวจสอบแพลตฟอร์มโฮสต์ อาร์ติแฟกต์ที่ตรวจสอบไว้ล่วงหน้าช่วยให้ Bazel อธิบายทรัพยากร Dependency ได้ราวกับว่าทรัพยากรเหล่านั้นอยู่ในเครื่อง ใช้คำสั่งแบบมีเงื่อนไขหรือแฟล็ก --override_repository สำหรับการดำเนินการนี้

  • การสร้างหรือคอมไพล์อาร์ติแฟกต์ที่เฉพาะเจาะจงกับเป้าหมายและการเปลี่ยนแปลงแพลตฟอร์ม การดำเนินการเหล่านี้ต้องดำเนินการผ่านกฎการสร้างปกติ การดำเนินการที่สร้างอาร์ติแฟกต์ที่เฉพาะเจาะจงกับเป้าหมายสำหรับทรัพยากร Dependency ภายนอกต้องดำเนินการระหว่างการสร้าง

คุณสามารถใช้กฎ WORKSPACE เพื่อส่งไฟล์ที่สร้างขึ้นเพื่อให้สร้างอาร์ติแฟกต์ที่ตรวจสอบไว้ล่วงหน้าสำหรับการดำเนินการระยะไกลได้ง่ายขึ้น คุณสามารถเรียกใช้กฎเหล่านั้นในสภาพแวดล้อมการดำเนินการใหม่แต่ละรายการ เช่น ภายในคอนเทนเนอร์ Toolchain แต่ละรายการ และตรวจสอบเอาต์พุตของบิลด์การดำเนินการระยะไกลในที่เก็บซอร์สโค้ดเพื่อใช้อ้างอิง

ตัวอย่างเช่น สำหรับกฎของ Tensorflow สำหรับ cuda และ python, กฎ WORKSPACE จะสร้าง BUILD files ต่อไปนี้ สำหรับการดำเนินการในเครื่อง ระบบจะใช้ไฟล์ที่สร้างขึ้นโดยการตรวจสอบสภาพแวดล้อมโฮสต์ สำหรับการดำเนินการระยะไกล คำสั่งแบบมีเงื่อนไขในตัวแปรสภาพแวดล้อมจะช่วยให้กฎใช้ไฟล์ที่ตรวจสอบแล้วในที่เก็บได้

ไฟล์ BUILD จะประกาศ genrules ที่สามารถเรียกใช้ได้ทั้งในเครื่องและระยะไกล และดำเนินการประมวลผลที่จำเป็น ซึ่งก่อนหน้านี้ดำเนินการผ่าน repository_ctx.symlink ดังที่แสดง ไว้ที่นี่