@ -16,6 +16,8 @@ use clap::Parser;
use walkdir ::WalkDir ;
use walkdir ::WalkDir ;
use xtask ::{ AYA_BUILD_INTEGRATION_BPF , Errors } ;
use xtask ::{ AYA_BUILD_INTEGRATION_BPF , Errors } ;
const GEN_INIT_CPIO_PATCH : & str = include_str! ( "../patches/gen_init_cpio.c.macos.diff" ) ;
#[ derive(Parser) ]
#[ derive(Parser) ]
enum Environment {
enum Environment {
/// Runs the integration tests locally.
/// Runs the integration tests locally.
@ -231,68 +233,83 @@ pub(crate) fn run(opts: Options) -> Result<()> {
// VM images and report to the user. The end.
// VM images and report to the user. The end.
create_dir_all ( & cache_dir ) . context ( "failed to create cache dir" ) ? ;
create_dir_all ( & cache_dir ) . context ( "failed to create cache dir" ) ? ;
let gen_init_cpio = cache_dir . join ( "gen_init_cpio" ) ;
let gen_init_cpio = cache_dir . join ( "gen_init_cpio" ) ;
let etag_path = cache_dir . join ( "gen_init_cpio.etag" ) ;
{
{
let gen_init_cpio_exists = gen_init_cpio . try_exists ( ) . with_context ( | | {
let dest_path = cache_dir . join ( "gen_init_cpio.c" ) ;
format! ( "failed to check existence of {}" , gen_init_cpio . display ( ) )
let etag_path = cache_dir . join ( "gen_init_cpio.etag" ) ;
let dest_path_exists = dest_path . try_exists ( ) . with_context ( | | {
format! ( "failed to check existence of {}" , dest_path . display ( ) )
} ) ? ;
} ) ? ;
let etag_path_exists = etag_path . try_exists ( ) . with_context ( | | {
let etag_path_exists = etag_path . try_exists ( ) . with_context ( | | {
format! ( "failed to check existence of {}" , etag_path . display ( ) )
format! ( "failed to check existence of {}" , etag_path . display ( ) )
} ) ? ;
} ) ? ;
if ! gen_init_cpio _exists & & etag_path_exists {
if ! dest_path _exists & & etag_path_exists {
println! (
println! (
"cargo:warning=({}).exists()={} != ({})={} (mismatch)" ,
"cargo:warning=({}).exists()={} != ({})={} (mismatch)" ,
gen_init_cpio . display ( ) ,
dest_path . display ( ) ,
gen_init_cpio _exists,
dest_path _exists,
etag_path . display ( ) ,
etag_path . display ( ) ,
etag_path_exists ,
etag_path_exists ,
)
)
}
}
}
let gen_init_cpio_source = {
// Currently unused. Can be used for authenticated requests if needed in the future.
drop ( github_api_token ) ; // Currently unused, but kept around in case we need it in the future.
drop ( github_api_token ) ;
let mut curl = Command ::new ( "curl" ) ;
let mut curl = Command ::new ( "curl" ) ;
curl . args ( [
curl . args ( [
"-sfSL" ,
"-sfSL" ,
"https://raw.githubusercontent.com/torvalds/linux/master/usr/gen_init_cpio.c" ,
"https://raw.githubusercontent.com/torvalds/linux/master/usr/gen_init_cpio.c" ,
] ) ;
"--output" ,
] )
. arg ( & dest_path ) ;
for arg in [ "--etag-compare" , "--etag-save" ] {
for arg in [ "--etag-compare" , "--etag-save" ] {
curl . arg ( arg ) . arg ( & etag_path ) ;
curl . arg ( arg ) . arg ( & etag_path ) ;
}
}
let Output {
let output = curl
status ,
stdout ,
stderr ,
} = curl
. output ( )
. output ( )
. with_context ( | | format! ( "failed to run {curl:?}" ) ) ? ;
. with_context ( | | format! ( "failed to run {curl:?}" ) ) ? ;
let Output { status , .. } = & output ;
if status . code ( ) ! = Some ( 0 ) {
if status . code ( ) ! = Some ( 0 ) {
bail ! ( "{curl:?} failed: stdout={stdout:?} stderr={stderr :?}")
bail ! ( "{curl:?} failed: {output :?}")
}
}
stdout
} ;
if ! gen_init_cpio_source . is_empty ( ) {
let mut patch = Command ::new ( "patch" ) ;
patch
. current_dir ( & cache_dir )
. args ( [ "--quiet" , "--forward" , "--output" , "-" ] )
. stdin ( Stdio ::piped ( ) )
. stdout ( Stdio ::piped ( ) ) ;
let mut patch_child = patch
. spawn ( )
. with_context ( | | format! ( "failed to spawn {patch:?}" ) ) ? ;
let Child { stdin , stdout , .. } = & mut patch_child ;
let mut stdin = stdin . take ( ) . unwrap ( ) ;
stdin
. write_all ( GEN_INIT_CPIO_PATCH . as_bytes ( ) )
. with_context ( | | format! ( "failed to write to {patch:?} stdin" ) ) ? ;
drop ( stdin ) ; // Must explicitly close to signal EOF.
let stdout = stdout . take ( ) . unwrap ( ) ;
let mut clang = Command ::new ( "clang" ) ;
let mut clang = Command ::new ( "clang" ) ;
clang
clang
. args ( [ "-g" , "-O2" , "-x" , "c" , "-" , "-o" ] )
. args ( [ "-g" , "-O2" , "-x" , "c" , "-" , "-o" ] )
. arg ( & gen_init_cpio )
. arg ( & gen_init_cpio )
. stdin ( Stdio ::piped ( ) ) ;
. stdin ( stdout ) ;
let mut clang_child = clang
let clang_child = clang
. spawn ( )
. spawn ( )
. with_context ( | | format! ( "failed to spawn {clang:?}" ) ) ? ;
. with_context ( | | format! ( "failed to spawn {clang:?}" ) ) ? ;
let Child { stdin , .. } = & mut clang_child ;
let output = patch_child
. wait_with_output ( )
let mut stdin = stdin . take ( ) . unwrap ( ) ;
. with_context ( | | format! ( "failed to wait for {patch:?}" ) ) ? ;
stdin
let Output { status , .. } = & output ;
. write_all ( & gen_init_cpio_source )
if status . code ( ) ! = Some ( 0 ) {
. with_context ( | | format! ( "failed to write to {clang:?} stdin" ) ) ? ;
bail ! ( "{patch:?} failed: {output:?}" )
drop ( stdin ) ; // Must explicitly close to signal EOF.
}
let output = clang_child
let output = clang_child
. wait_with_output ( )
. wait_with_output ( )