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

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

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

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

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

ภาพรวม

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

  • การดําเนินการของบิลด์ที่แยกออกมา เครื่องมือของบิลด์จะไม่คงสถานะไว้และการอ้างอิงจะไม่รั่วไหลระหว่างนั้น

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

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

การเรียกใช้เครื่องมือสร้างผ่านกฎ Toolchain

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

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

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

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

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

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

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

โดยปกติแล้ว ไบนารีที่สร้างบนแพลตฟอร์มโฮสต์จะไม่สามารถทำงานได้อย่างปลอดภัยบนแพลตฟอร์มการดำเนินการระยะไกลที่กำหนดเอง เนื่องจากการพึ่งพากันอาจไม่ตรงกัน ตัวอย่างเช่น ไบนารี 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 ดังที่แสดงที่นี่