Build Bazel yang berhasil secara lokal mungkin gagal saat dijalankan dari jarak jauh karena serta batasan yang tidak memengaruhi build lokal. Paling umum penyebab kegagalan tersebut dijelaskan dalam Mengadaptasi Aturan Bazel untuk Eksekusi Jarak Jauh.
Halaman ini menjelaskan cara mengidentifikasi dan menyelesaikan masalah paling umum yang timbul dengan eksekusi jarak jauh yang menggunakan fitur {i>sandbox<i} Docker, yang menerapkan batasan atas build yang sama dengan eksekusi jarak jauh. Hal ini memungkinkan Anda untuk memecahkan masalah build Anda tanpa perlu layanan eksekusi jarak jauh.
Fitur {i>sandbox<i} Docker meniru pembatasan eksekusi jarak jauh sebagai berikut ini:
Tindakan build dijalankan di container toolchain. Anda dapat menggunakan container toolchain untuk menjalankan build Anda secara lokal dan jarak jauh melalui layanan yang mendukung eksekusi jarak jauh dalam container.
Tidak ada data asing yang melewati batas penampung. Hanya secara eksplisit input dan output yang dideklarasikan masuk dan keluar dari container, dan hanya setelah tindakan build terkait berhasil diselesaikan.
Setiap tindakan dijalankan di penampung baru. Penampung baru yang unik yang dibuat untuk setiap tindakan build yang dihasilkan.
Anda dapat memecahkan masalah ini menggunakan salah satu metode berikut:
Memecahkan masalah secara native. Dengan metode ini, Bazel dan tindakan build-nya berjalan secara native di komputer lokal Anda. Docker fitur sandbox menerapkan pembatasan pada build yang sama dengan build dalam proses eksekusi. Namun, metode ini tidak akan mendeteksi alat, status, dan data bocor ke dalam build Anda, yang akan menyebabkan masalah pada eksekusi jarak jauh.
Memecahkan masalah di container Docker. Dengan metode ini, Bazel dan tindakan build-nya berjalan di dalam kontainer Docker, yang memungkinkan Anda mendeteksi alat, status, dan kebocoran data dari ke dalam build, selain menerapkan batasan sama dengan eksekusi jarak jauh. Metode ini memberikan wawasan tentang build meskipun sebagian build gagal. Metode ini bersifat eksperimental dan tidak didukung secara resmi.
Prasyarat
Sebelum Anda mulai memecahkan masalah, lakukan hal berikut jika Anda belum melakukannya:
- Instal Docker dan konfigurasikan izin yang diperlukan untuk menjalankannya.
- Instal Bazel 0.14.1 atau yang lebih baru. Versi sebelumnya tidak mendukung Docker fitur sandbox Anda.
- Menambahkan bazel-toolchains
repo, disematkan ke versi rilis terbaru, ke file
WORKSPACE
build Anda sebagaimana dijelaskan di sini. - Tambahkan tanda ke file
.bazelrc
untuk mengaktifkan fitur. Membuat file di direktori {i>root<i} dari proyek Bazel Anda jika tidak ada. Tanda di bawah adalah sampel referensi. Lihat info terbaru.bazelrc
dalam repo bazel-toolchains dan salin nilai tanda yang ditentukan di sana untuk konfigurasidocker-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
Jika aturan Anda memerlukan alat tambahan, lakukan hal berikut:
Membuat container Docker kustom dengan menginstal alat menggunakan Dockerfile dan membangun gambar secara lokal.
Ganti nilai flag
--experimental_docker_image
di atas dengan nilai image container kustom Anda.
Memecahkan masalah secara native
Metode ini mengeksekusi Bazel dan semua tindakan build-nya langsung di dan merupakan cara yang andal untuk mengonfirmasi apakah build Anda akan berhasil saat yang dijalankan dari jarak jauh.
Akan tetapi, dengan metode ini, alat, biner, dan data yang diinstal secara lokal dapat bocor ke dalam build Anda, terutama jika menggunakan aturan WORKSPACE bergaya konfigurasi. Kebocoran tersebut akan menyebabkan masalah pada eksekusi jarak jauh; mendeteksinya, memecahkan masalah di container Docker selain memecahkan masalah secara native.
Langkah 1: Jalankan build
Menambahkan flag
--config=docker-sandbox
ke perintah Bazel yang dijalankan build Anda. Contoh:bazel --bazelrc=.bazelrc build --config=docker-sandbox target
Jalankan build dan tunggu hingga selesai. Build akan berjalan hingga empat kali lebih lambat dari biasanya karena fitur sandbox Docker.
Anda mungkin mengalami error berikut:
ERROR: 'docker' is an invalid value for docker spawn strategy.
Jika ya, jalankan build lagi dengan flag --experimental_docker_verbose
.
Flag ini memungkinkan pesan error panjang. Kesalahan ini biasanya disebabkan oleh
instalasi Docker yang salah atau tidak adanya izin
untuk mengeksekusinya di bawah
akun pengguna saat ini. Lihat dokumentasi Docker
untuk informasi selengkapnya. Jika masalah berlanjut, lanjutkan ke Pemecahan masalah di container Docker.
Langkah 2: Selesaikan masalah yang terdeteksi
Berikut ini adalah masalah yang paling umum terjadi dan solusinya.
File, alat, biner, atau resource yang dirujuk oleh hierarki runfile Bazel adalah tidak ada.. Pastikan bahwa semua dependensi target yang terpengaruh dideklarasikan secara eksplisit. Lihat Mengelola dependensi implisit untuk informasi selengkapnya.
File, alat, biner, atau resource yang dirujuk oleh jalur absolut atau
PATH
variabel tidak ada. Pastikan bahwa semua alat yang diperlukan telah diinstal dalam container toolchain dan menggunakan aturan toolchain untuk mendeklarasikan dependensi yang mengarah ke sumber daya yang hilang. Lihat Memanggil alat build melalui aturan toolchain untuk informasi selengkapnya.Eksekusi biner gagal. Salah satu aturan build mereferensikan biner dan tidak kompatibel dengan lingkungan eksekusi (container Docker). Lihat Mengelola biner yang bergantung pada platform untuk informasi selengkapnya. Jika Anda tidak dapat menyelesaikan masalah ini, hubungi bazel-discuss@google.com untuk mendapatkan bantuan.
File dari
@local-jdk
tidak ada atau menyebabkan error. Biner Java di komputer lokal Anda bocor ke dalam build sementara tidak kompatibel dengan anotasi. Gunakanjava_toolchain
di aturan dan target Anda, bukan@local_jdk
. Hubungi bazel-discuss@google.com jika Anda memerlukan bantuan lebih lanjut.Error lainnya. Hubungi bazel-discuss@google.com untuk mendapatkan bantuan.
Pemecahan masalah di container Docker
Dengan metode ini, Bazel berjalan di dalam kontainer Docker {i>host<i}, dan build tindakan dieksekusi di dalam container toolchain individual yang dihasilkan oleh Docker fitur sandbox Anda. Sandbox memunculkan container toolchain baru untuk masing-masing dan hanya satu tindakan yang akan dieksekusi di setiap container toolchain.
Metode ini memberikan kontrol yang lebih terperinci atas alat yang diinstal di host lingkungan fleksibel App Engine. Dengan memisahkan eksekusi build dari eksekusinya tindakan membangun dan menjaga alat yang diinstal seminimal mungkin, Anda dapat memverifikasi apakah build memiliki dependensi di lingkungan eksekusi lokal.
Langkah 1: Bangun container
Membuat
Dockerfile
yang membuat container Docker dan menginstal Bazel dengan serangkaian alat build minimal: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
Bangun container sebagai
bazel_container
:docker build -t bazel_container - < Dockerfile
Langkah 2: Mulai penampung
Mulai container Docker menggunakan perintah yang ditunjukkan di bawah ini. Dalam perintah tersebut, mengganti jalur ke kode sumber pada {i>host<i} Anda yang ingin Anda bangun.
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
Perintah ini menjalankan container sebagai root, memetakan soket docker, dan
direktori /tmp
. Hal ini memungkinkan Bazel untuk
menghasilkan kontainer Docker lainnya dan
menggunakan direktori dalam /tmp
untuk berbagi file dengan container tersebut. Sumber Anda
kode tersedia di /src
dalam container.
Perintah sengaja dimulai dari penampung dasar debian:stretch
yang
menyertakan biner yang tidak kompatibel dengan container rbe-ubuntu16-04
yang digunakan sebagai
container toolchain. Jika biner dari lingkungan lokal bocor ke dalam
container toolchain, mereka akan menyebabkan error build.
Langkah 3: Uji penampung
Jalankan perintah berikut dari dalam container Docker untuk mengujinya:
docker ps
bazel version
Langkah 4: Jalankan build
Jalankan build seperti yang ditunjukkan di bawah ini. Pengguna {i>output<i} adalah {i>root<i} sehingga sesuai dengan direktori yang dapat diakses dengan jalur absolut yang sama dari dalam {i>host<i} container yang digunakan Bazel, dari container toolchain yang dihasilkan oleh Docker fitur {i>sandbox<i} di mana tindakan {i>build<i} Bazel berjalan, dan dari komputer tempat kontainer {i>host<i} dan tindakan dijalankan.
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target
Langkah 5: Selesaikan masalah yang terdeteksi
Anda dapat mengatasi kegagalan build sebagai berikut:
Jika build gagal dengan ruang disk "kehabisan disk" Anda dapat meningkatkan dengan memulai container host dengan flag
--memory=XX
di manaXX
adalah ruang {i>disk<i} yang dialokasikan dalam gigabita. Ini bersifat eksperimental dan mungkin mengakibatkan perilaku yang tidak dapat diprediksi.Jika build gagal selama fase analisis atau pemuatan, satu atau beberapa aturan build yang dideklarasikan dalam file WORKSPACE tidak kompatibel dengan eksekusi jarak jauh. Lihat Mengadaptasi Aturan Bazel untuk Eksekusi Jarak Jauh untuk mengetahui penyebab dan solusi yang mungkin.
Jika build gagal karena alasan lain, lihat langkah pemecahan masalah di Langkah 2: Selesaikan masalah yang terdeteksi.