บิลด์ Bazel ที่สำเร็จในเครื่องอาจล้มเหลวเมื่อดำเนินการจากระยะไกลเนื่องจากข้อจำกัดและข้อกำหนดที่ไม่มีผลต่อบิลด์ในเครื่อง สาเหตุที่พบบ่อยที่สุด ของความล้มเหลวดังกล่าวอธิบายไว้ในการปรับกฎของ Bazel สำหรับการดำเนินการจากระยะไกล
หน้านี้อธิบายวิธีระบุและแก้ไขปัญหาที่พบบ่อยที่สุดซึ่งเกิดขึ้นกับการดำเนินการจากระยะไกลโดยใช้ฟีเจอร์แซนด์บ็อกซ์ของ Docker ซึ่งกำหนดข้อจำกัดในการบิลด์เท่ากับการดำเนินการจากระยะไกล ซึ่งช่วยให้คุณ แก้ปัญหาการบิลด์ได้โดยไม่ต้องใช้บริการการดำเนินการจากระยะไกล
ฟีเจอร์แซนด์บ็อกซ์ Docker จะจำลองข้อจำกัดของการดำเนินการจากระยะไกลดังนี้
สร้างการดำเนินการที่จะเรียกใช้ในคอนเทนเนอร์ของชุดเครื่องมือ คุณสามารถใช้คอนเทนเนอร์ชุดเครื่องมือเดียวกันเพื่อเรียกใช้บิลด์ในเครื่องและจากระยะไกลผ่านบริการที่รองรับการดำเนินการจากระยะไกลแบบคอนเทนเนอร์
ไม่มีข้อมูลภายนอกข้ามขอบเขตคอนเทนเนอร์ เฉพาะอินพุตและเอาต์พุตที่ประกาศอย่างชัดเจนเท่านั้นที่จะเข้าและออกจากคอนเทนเนอร์ และจะทำได้หลังจากที่การดำเนินการบิลด์ที่เชื่อมโยงเสร็จสมบูรณ์แล้วเท่านั้น
การดำเนินการแต่ละอย่างจะทำงานในคอนเทนเนอร์ใหม่ ระบบจะสร้างคอนเทนเนอร์ใหม่ที่ไม่ซ้ำกัน สำหรับการดำเนินการบิลด์แต่ละรายการที่สร้างขึ้น
คุณแก้ปัญหาเหล่านี้ได้โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
การแก้ปัญหาโดยตรง ในวิธีนี้ Bazel และการดำเนินการบิลด์จะทำงานในเครื่องของคุณโดยตรง ฟีเจอร์แซนด์บ็อกซ์ Docker จะกำหนดข้อจำกัดในการสร้างเทียบเท่ากับการดำเนินการจากระยะไกล อย่างไรก็ตาม วิธีนี้จะไม่ตรวจพบเครื่องมือ สถานะ และ การรั่วไหลของข้อมูลในบิลด์ ซึ่งจะทำให้เกิดปัญหากับการดำเนินการจากระยะไกล
การแก้ปัญหาในคอนเทนเนอร์ Docker วิธีนี้ช่วยให้ Bazel และการดำเนินการบิลด์ทำงานภายในคอนเทนเนอร์ Docker ซึ่งช่วยให้คุณตรวจหาเครื่องมือ สถานะ และข้อมูลที่รั่วไหลจากเครื่อง ในเครื่องไปยังบิลด์ได้ นอกเหนือจากการกำหนดข้อจำกัด ที่เท่ากับการดำเนินการจากระยะไกล วิธีนี้จะให้ข้อมูลเชิงลึกเกี่ยวกับการ บิลด์ แม้ว่าบางส่วนของการบิลด์จะล้มเหลวก็ตาม วิธีนี้เป็นเวอร์ชันทดลอง และไม่ได้รับการสนับสนุนอย่างเป็นทางการ
ข้อกำหนดเบื้องต้น
ก่อนที่จะเริ่มแก้ปัญหา ให้ทำดังนี้หากคุณยังไม่ได้ดำเนินการ
- ติดตั้ง Docker และกำหนดค่าสิทธิ์ที่จำเป็นในการเรียกใช้
- ติดตั้ง Bazel 0.14.1 ขึ้นไป เวอร์ชันก่อนหน้าไม่รองรับฟีเจอร์แซนด์บ็อกซ์ Docker
- เพิ่มที่เก็บ bazel-toolchains
ที่ปักหมุดไว้กับเวอร์ชันล่าสุดลงในไฟล์
WORKSPACE
ของบิลด์ ตามที่อธิบายไว้ที่นี่ - เพิ่ม Flag ลงในไฟล์
.bazelrc
เพื่อเปิดใช้ฟีเจอร์ สร้างไฟล์ในไดเรกทอรีรูทของโปรเจ็กต์ Bazel หากยังไม่มี โดยแฟล็กด้านล่าง เป็นตัวอย่างอ้างอิง โปรดดูไฟล์.bazelrc
ล่าสุด ในที่เก็บ bazel-toolchains แล้วคัดลอกค่าของแฟล็กที่กำหนด ไว้ที่นั่นสำหรับการกำหนดค่า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
หากกฎของคุณต้องใช้เครื่องมือเพิ่มเติม ให้ทำดังนี้
สร้างคอนเทนเนอร์ Docker ที่กำหนดเองโดยการติดตั้งเครื่องมือโดยใช้ Dockerfile และสร้าง อิมเมจในเครื่อง
แทนที่ค่าของแฟล็ก
--experimental_docker_image
ด้านบนด้วย ชื่อของอิมเมจคอนเทนเนอร์ที่กำหนดเอง
การแก้ปัญหาโดยตรง
วิธีนี้จะเรียกใช้ Bazel และการดำเนินการบิลด์ทั้งหมดโดยตรงในเครื่อง ภายใน และเป็นวิธีที่เชื่อถือได้ในการยืนยันว่าบิลด์จะสำเร็จหรือไม่เมื่อ เรียกใช้จากระยะไกล
อย่างไรก็ตาม วิธีนี้อาจทำให้เครื่องมือ ไบนารี และข้อมูลที่ติดตั้งในเครื่องรั่วไหล เข้าสู่บิลด์ โดยเฉพาะอย่างยิ่งหากใช้กฎ WORKSPACE รูปแบบการกำหนดค่า การรั่วไหลดังกล่าวจะทำให้เกิดปัญหากับการดำเนินการจากระยะไกล หากต้องการตรวจหา ให้แก้ปัญหาในคอนเทนเนอร์ Docker นอกเหนือจากการแก้ปัญหาในเครื่อง
ขั้นตอนที่ 1: เรียกใช้บิลด์
เพิ่มแฟล็ก
--config=docker-sandbox
ลงในคำสั่ง Bazel ที่เรียกใช้ บิลด์ เช่นbazel --bazelrc=.bazelrc build --config=docker-sandbox target
เรียกใช้บิลด์และรอให้เสร็จสมบูรณ์ การสร้างจะทำงานช้ากว่าปกติสูงสุด 4 เท่าเนื่องจากฟีเจอร์แซนด์บ็อกซ์ของ Docker
คุณอาจพบข้อผิดพลาดต่อไปนี้
ERROR: 'docker' is an invalid value for docker spawn strategy.
หากทำเช่นนั้น ให้เรียกใช้บิลด์อีกครั้งโดยใช้แฟล็ก --experimental_docker_verbose
โดยแฟล็กนี้จะเปิดใช้ข้อความแสดงข้อผิดพลาดแบบละเอียด โดยปกติแล้วข้อผิดพลาดนี้เกิดจาก
การติดตั้ง Docker ที่ไม่ถูกต้องหรือไม่มีสิทธิ์ในการเรียกใช้ภายใต้
บัญชีผู้ใช้ปัจจุบัน ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบของ Docker
หากปัญหายังคงอยู่ ให้ข้ามไปที่การแก้ปัญหาในคอนเทนเนอร์ Docker
ขั้นตอนที่ 2: แก้ไขปัญหาที่ตรวจพบ
ปัญหาที่พบบ่อยที่สุดและวิธีแก้ไขโดยอ้อมมีดังนี้
ไม่มีไฟล์ เครื่องมือ ไบนารี หรือทรัพยากรที่อ้างอิงโดยทรี Runfiles ของ Bazel ยืนยันว่ามีการประกาศอย่างชัดเจนถึงการขึ้นต่อกันทั้งหมดของเป้าหมายที่ได้รับผลกระทบ ดูข้อมูลเพิ่มเติมได้ที่ การจัดการการอ้างอิงโดยนัย
ไม่มีไฟล์ เครื่องมือ ไบนารี หรือทรัพยากรที่อ้างอิงโดยเส้นทางแบบสัมบูรณ์หรือ
PATH
ตัวแปร ยืนยันว่าได้ติดตั้งเครื่องมือที่จำเป็นทั้งหมดภายใน คอนเทนเนอร์ Toolchain และใช้กฎ Toolchain เพื่อประกาศ การอ้างอิงที่ชี้ไปยังทรัพยากรที่ขาดหายไปอย่างถูกต้อง ดูข้อมูลเพิ่มเติมได้ที่ เรียกใช้เครื่องมือบิลด์ผ่านกฎ Toolchainการดำเนินการไบนารีล้มเหลว กฎการสร้างข้อใดข้อหนึ่งอ้างอิงไบนารีที่เข้ากันไม่ได้กับสภาพแวดล้อมการดำเนินการ (คอนเทนเนอร์ Docker) ดูข้อมูลเพิ่มเติมได้ที่ การจัดการไบนารีที่ขึ้นอยู่กับแพลตฟอร์ม หากแก้ปัญหาไม่ได้ โปรดติดต่อ bazel-discuss@google.com เพื่อขอความช่วยเหลือ
ไฟล์จาก
@local-jdk
ขาดหายไปหรือทำให้เกิดข้อผิดพลาด ไบนารี Java ในเครื่องของคุณรั่วไหลไปยังบิลด์ในขณะที่ใช้ร่วมกันไม่ได้ ใช้java_toolchain
ในกฎและเป้าหมายแทน@local_jdk
โปรดติดต่อ bazel-discuss@google.com หากต้องการความช่วยเหลือเพิ่มเติมข้อผิดพลาดอื่นๆ โปรดติดต่อ bazel-discuss@google.com เพื่อขอความช่วยเหลือ
การแก้ปัญหาในคอนเทนเนอร์ Docker
ในวิธีนี้ Bazel จะทำงานภายในคอนเทนเนอร์ Docker ของโฮสต์ และการดำเนินการบิลด์ของ Bazel จะทำงานภายในคอนเทนเนอร์ Toolchain แต่ละรายการที่ฟีเจอร์แซนด์บ็อกซ์ของ Docker สร้างขึ้น แซนด์บ็อกซ์จะสร้างคอนเทนเนอร์ Toolchain ใหม่เอี่ยมสำหรับการดำเนินการบิลด์แต่ละรายการ และจะมีการดำเนินการเพียง 1 รายการในคอนเทนเนอร์ Toolchain แต่ละรายการ
วิธีนี้ช่วยให้ควบคุมเครื่องมือที่ติดตั้งในสภาพแวดล้อมโฮสต์ได้อย่างละเอียดยิ่งขึ้น การแยกการดำเนินการบิลด์จากการดำเนินการ การดำเนินการบิลด์ และการลดเครื่องมือที่ติดตั้งให้เหลือน้อยที่สุดจะช่วยให้คุณตรวจสอบได้ว่า บิลด์มีทรัพยากร Dependency ในสภาพแวดล้อมการดำเนินการในเครื่องหรือไม่
ขั้นตอนที่ 1: สร้างคอนเทนเนอร์
สร้าง
Dockerfile
ที่สร้างคอนเทนเนอร์ Docker และติดตั้ง Bazel ด้วยชุดเครื่องมือบิลด์ขั้นต่ำ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
ขั้นตอนที่ 2: เริ่มคอนเทนเนอร์
เริ่มคอนเทนเนอร์ 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
คำสั่งนี้จะเรียกใช้คอนเทนเนอร์ในฐานะรูท โดยแมปซ็อกเก็ต Docker และเชื่อมต่อไดเรกทอรี /tmp
ซึ่งช่วยให้ Bazel สร้างคอนเทนเนอร์ Docker อื่นๆ และใช้ไดเรกทอรีภายใต้ /tmp
เพื่อแชร์ไฟล์กับคอนเทนเนอร์เหล่านั้นได้ ซอร์สโค้ดของคุณอยู่ที่ /src
ภายในคอนเทนเนอร์
คำสั่งนี้ตั้งใจเริ่มต้นจากdebian:stretch
คอนเทนเนอร์ฐานที่
มีไบนารีที่ใช้ไม่ได้กับคอนเทนเนอร์ rbe-ubuntu16-04
ที่ใช้เป็น
คอนเทนเนอร์ Toolchain หากไบนารีจากสภาพแวดล้อมในเครื่องรั่วไหลไปยังคอนเทนเนอร์ Toolchain จะทำให้เกิดข้อผิดพลาดในการสร้าง
ขั้นตอนที่ 3: ทดสอบคอนเทนเนอร์
เรียกใช้คำสั่งต่อไปนี้จากภายในคอนเทนเนอร์ Docker เพื่อทดสอบ
docker ps
bazel version
ขั้นตอนที่ 4: เรียกใช้บิลด์
เรียกใช้บิลด์ดังที่แสดงด้านล่าง ผู้ใช้เอาต์พุตคือรูทเพื่อให้สอดคล้องกับ ไดเรกทอรีที่เข้าถึงได้ด้วยเส้นทางแบบสัมบูรณ์เดียวกันจากภายในโฮสต์ คอนเทนเนอร์ที่ Bazel ทำงานอยู่ จากคอนเทนเนอร์ Toolchain ที่ฟีเจอร์แซนด์บ็อกซ์ Docker สร้างขึ้น ซึ่งการดำเนินการบิลด์ของ Bazel ทำงานอยู่ และจากเครื่องในเครื่อง ที่คอนเทนเนอร์โฮสต์และการดำเนินการทำงานอยู่
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target
ขั้นตอนที่ 5: แก้ไขปัญหาที่ตรวจพบ
คุณแก้ไขการสร้างที่ไม่สำเร็จได้โดยทำดังนี้
หากบิลด์ล้มเหลวเนื่องจากข้อผิดพลาด "พื้นที่ในดิสก์ไม่เพียงพอ" คุณสามารถเพิ่มขีดจำกัดนี้ได้โดยเริ่มคอนเทนเนอร์โฮสต์ด้วยแฟล็ก
--memory=XX
โดยที่XX
คือพื้นที่ในดิสก์ที่จัดสรรเป็นกิกะไบต์ ฟีเจอร์นี้อยู่ในขั้นทดลองและอาจ ส่งผลให้เกิดลักษณะการทำงานที่ไม่คาดคิดหากการสร้างล้มเหลวในระหว่างขั้นตอนการวิเคราะห์หรือการโหลด แสดงว่ากฎการสร้างอย่างน้อย 1 รายการที่ประกาศไว้ในไฟล์ WORKSPACE ไม่สามารถใช้ร่วมกับการดำเนินการจากระยะไกลได้ ดูสาเหตุที่เป็นไปได้และวิธีแก้ปัญหาได้ที่การปรับกฎ Bazel สำหรับการดำเนินการจากระยะไกล
หากบิลด์ล้มเหลวด้วยเหตุผลอื่น โปรดดูขั้นตอนการแก้ปัญหาในขั้นตอนที่ 2: แก้ไขปัญหาที่ตรวจพบ