integration-ebpf: invalidate on bpf-linker

Extract the symlink-to-bpf-linker logic from integration-test to xtask
and use it in a new build script in integration-ebpf, causing ebpf
probes to be rebuilt when bpf-linker changes. Previously bpf-linker
changes would rebuild integration-test, but not integration-ebpf,
resulting in stale tests.

Note that this still doesn't address the possibility that a new
bpf-linker is added to the PATH ahead of the cached one. Solving this in
the general case would require rebuild-if-changed-env=PATH *and*
rebuild-if-changed={every-directory-in-PATH} which would likely mean far
too much cache invalidation.
reviewable/pr677/r9
Tamir Duberstein 1 year ago
parent 0168396604
commit e276c07f73
No known key found for this signature in database

@ -8,6 +8,9 @@ publish = false
aya-bpf = { path = "../../bpf/aya-bpf" }
aya-log-ebpf = { path = "../../bpf/aya-log-ebpf" }
[build-dependencies]
xtask = { path = "../../xtask" }
[[bin]]
name = "log"
path = "src/log.rs"

@ -0,0 +1,23 @@
use std::{env, path::PathBuf};
use xtask::{create_symlink_to_binary, AYA_BUILD_INTEGRATION_BPF};
fn main() {
println!("cargo:rerun-if-env-changed={}", AYA_BUILD_INTEGRATION_BPF);
let build_integration_bpf = env::var(AYA_BUILD_INTEGRATION_BPF)
.as_deref()
.map(str::parse)
.map(Result::unwrap)
.unwrap_or_default();
if build_integration_bpf {
let out_dir = env::var_os("OUT_DIR").unwrap();
let out_dir = PathBuf::from(out_dir);
let bpf_linker_symlink = create_symlink_to_binary(&out_dir, "bpf-linker").unwrap();
println!(
"cargo:rerun-if-changed={}",
bpf_linker_symlink.to_str().unwrap()
);
}
}

@ -25,5 +25,4 @@ tokio = { version = "1.24", default-features = false, features = [
[build-dependencies]
cargo_metadata = { version = "0.15.4", default-features = false }
which = { version = "4.4.0", default-features = false }
xtask = { path = "../../xtask" }

@ -12,21 +12,16 @@ use std::{
use cargo_metadata::{
Artifact, CompilerMessage, Dependency, Message, Metadata, MetadataCommand, Package, Target,
};
use which::which;
use xtask::{exec, LIBBPF_DIR};
use xtask::{create_symlink_to_binary, exec, AYA_BUILD_INTEGRATION_BPF, LIBBPF_DIR};
fn main() {
const AYA_BUILD_INTEGRATION_BPF: &str = "AYA_BUILD_INTEGRATION_BPF";
println!("cargo:rerun-if-env-changed={}", AYA_BUILD_INTEGRATION_BPF);
let build_integration_bpf = match env::var_os(AYA_BUILD_INTEGRATION_BPF) {
None => false,
Some(s) => {
let s = s.to_str().unwrap();
s.parse::<bool>().unwrap()
}
};
let build_integration_bpf = env::var(AYA_BUILD_INTEGRATION_BPF)
.as_deref()
.map(str::parse)
.map(Result::unwrap)
.unwrap_or_default();
const INTEGRATION_EBPF_PACKAGE: &str = "integration-ebpf";
@ -137,28 +132,11 @@ fn main() {
}
}
// Create a symlink in the out directory to work around the fact that cargo ignores anything
// in `$CARGO_HOME`, which is also where `cargo install` likes to place binaries. Cargo will
// stat through the symlink and discover that bpf-linker has changed.
//
// This was introduced in https://github.com/rust-lang/cargo/commit/99f841c.
{
let bpf_linker = which("bpf-linker").unwrap();
let bpf_linker_symlink = out_dir.join("bpf-linker");
match fs::remove_file(&bpf_linker_symlink) {
Ok(()) => {}
Err(err) => {
if err.kind() != std::io::ErrorKind::NotFound {
panic!("failed to remove symlink: {err}")
}
}
}
std::os::unix::fs::symlink(&bpf_linker, &bpf_linker_symlink).unwrap();
println!(
"cargo:rerun-if-changed={}",
bpf_linker_symlink.to_str().unwrap()
);
}
let bpf_linker_symlink = create_symlink_to_binary(&out_dir, "bpf-linker").unwrap();
println!(
"cargo:rerun-if-changed={}",
bpf_linker_symlink.to_str().unwrap()
);
let mut cmd = Command::new("cargo");
cmd.args([

@ -14,3 +14,4 @@ proc-macro2 = "1"
quote = "1"
syn = "2"
tempfile = "3"
which = { version = "4.4.0", default-features = false }

@ -1,5 +1,13 @@
use anyhow::{anyhow, Context as _, Result};
use std::process::Command;
use std::{
fs,
path::{Path, PathBuf},
process::Command,
};
use which::which;
pub const AYA_BUILD_INTEGRATION_BPF: &str = "AYA_BUILD_INTEGRATION_BPF";
pub const LIBBPF_DIR: &str = "xtask/libbpf";
pub fn exec(cmd: &mut Command) -> Result<()> {
let status = cmd
@ -14,4 +22,25 @@ pub fn exec(cmd: &mut Command) -> Result<()> {
}
}
pub const LIBBPF_DIR: &str = "xtask/libbpf";
// Create a symlink in the out directory to work around the fact that cargo ignores anything
// in `$CARGO_HOME`, which is also where `cargo install` likes to place binaries. Cargo will
// stat through the symlink and discover that the binary has changed.
//
// This was introduced in https://github.com/rust-lang/cargo/commit/99f841c.
//
// TODO(https://github.com/rust-lang/cargo/pull/12369): Remove this when the fix is available.
pub fn create_symlink_to_binary(out_dir: &Path, binary_name: &str) -> Result<PathBuf> {
let binary = which(binary_name).unwrap();
let symlink = out_dir.join(binary_name);
match fs::remove_file(&symlink) {
Ok(()) => {}
Err(err) => {
if err.kind() != std::io::ErrorKind::NotFound {
return Err(err).context(format!("failed to remove symlink {}", symlink.display()));
}
}
}
std::os::unix::fs::symlink(binary, &symlink)
.with_context(|| format!("failed to create symlink {}", symlink.display()))?;
Ok(symlink)
}

@ -8,6 +8,7 @@ use std::{
use anyhow::{Context as _, Result};
use cargo_metadata::{Artifact, CompilerMessage, Message, Target};
use clap::Parser;
use xtask::AYA_BUILD_INTEGRATION_BPF;
#[derive(Debug, Parser)]
pub struct BuildOptions {
@ -35,7 +36,7 @@ pub struct Options {
pub fn build(opts: BuildOptions) -> Result<Vec<(String, PathBuf)>> {
let BuildOptions { release, target } = opts;
let mut cmd = Command::new("cargo");
cmd.env("AYA_BUILD_INTEGRATION_BPF", "true").args([
cmd.env(AYA_BUILD_INTEGRATION_BPF, "true").args([
"build",
"--tests",
"--message-format=json",

Loading…
Cancel
Save