@@ -11,7 +11,7 @@ use std::io::{Read, Write};
1111use std:: net:: { TcpListener , TcpStream } ;
1212use std:: os:: unix:: fs:: PermissionsExt ;
1313use std:: os:: unix:: io:: { AsRawFd , FromRawFd } ;
14- use std:: path:: Path ;
14+ use std:: path:: { Path , PathBuf } ;
1515use std:: process:: { Child , Command , ExitStatus , Output , Stdio } ;
1616use std:: str:: FromStr ;
1717use std:: sync:: { LazyLock , Mutex } ;
@@ -249,6 +249,39 @@ impl Drop for WindowsDiskConfig {
249249 }
250250}
251251
252+ /// Returns the workspace root directory.
253+ ///
254+ /// As we don't have packages in the workspace root,
255+ /// we walk up until we found the main Cargo.toml file.
256+ fn workspace_root ( ) -> PathBuf {
257+ // The directory of the current crate (integration test).
258+ let mut dir = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
259+
260+ // Currently we have one level of nesting and we probably never change it.
261+ let max_levels = 2 ;
262+
263+ eprintln ! (
264+ "Looking for workspace root: starting with dir={}" ,
265+ dir. to_str( ) . unwrap( )
266+ ) ;
267+
268+ // walk up
269+ for _ in 0 ..max_levels {
270+ dir = dir. parent ( ) . unwrap ( ) . to_path_buf ( ) ;
271+ eprintln ! ( "Checking parent dir: {}" , dir. to_str( ) . unwrap( ) ) ;
272+ let maybe_manifest_file = dir. join ( "Cargo.toml" ) ;
273+ if maybe_manifest_file. exists ( ) {
274+ let content = fs:: read_to_string ( & maybe_manifest_file) . unwrap ( ) ;
275+ if content. contains ( "[workspace]" ) && content. contains ( "Cloud Hypervisor Workspace" ) {
276+ eprintln ! ( "INFO: Found workspace root: {}" , dir. to_str( ) . unwrap( ) ) ;
277+ return dir;
278+ }
279+ }
280+ }
281+
282+ panic ! ( "Could not find workspace root" ) ;
283+ }
284+
252285impl DiskConfig for UbuntuDiskConfig {
253286 fn prepare_cloudinit ( & self , tmp_dir : & TempDir , network : & GuestNetworkConfig ) -> String {
254287 let cloudinit_file_path =
@@ -259,15 +292,16 @@ impl DiskConfig for UbuntuDiskConfig {
259292 fs:: create_dir_all ( & cloud_init_directory)
260293 . expect ( "Expect creating cloud-init directory to succeed" ) ;
261294
262- let source_file_dir = std:: env:: current_dir ( )
263- . unwrap ( )
295+ let source_file_dir = workspace_root ( )
264296 . join ( "test_data" )
265297 . join ( "cloud-init" )
266298 . join ( "ubuntu" )
267299 . join ( "ci" ) ;
268300
269301 [ "meta-data" ] . iter ( ) . for_each ( |x| {
270- rate_limited_copy ( source_file_dir. join ( x) , cloud_init_directory. join ( x) )
302+ let source_file = source_file_dir. join ( x) ;
303+ let cloud_init = cloud_init_directory. join ( x) ;
304+ rate_limited_copy ( source_file, cloud_init)
271305 . expect ( "Expect copying cloud-init meta-data to succeed" ) ;
272306 } ) ;
273307
@@ -1402,11 +1436,19 @@ impl<'a> GuestCommand<'a> {
14021436 }
14031437}
14041438
1439+ /// Returns the absolute path into the workspaces target directory to locate the desired
1440+ /// executable.
1441+ ///
1442+ /// # Arguments
1443+ /// - `cmd`: workspace binary, e.g. `ch-remote` or `cloud-hypervisor`
14051444pub fn clh_command ( cmd : & str ) -> String {
1406- env:: var ( "BUILD_TARGET" ) . map_or (
1407- format ! ( "target/x86_64-unknown-linux-gnu/release/{cmd}" ) ,
1408- |target| format ! ( "target/{target}/release/{cmd}" ) ,
1409- )
1445+ let workspace_root = workspace_root ( ) ;
1446+ let rustc_target = env:: var ( "BUILD_TARGET" ) . unwrap_or ( "x86_64-unknown-linux-gnu" . to_string ( ) ) ;
1447+ let target_artifact_dir = format ! ( "target/{rustc_target}/release" ) ;
1448+ let target_cmd_path = format ! ( "{target_artifact_dir}/{cmd}" ) ;
1449+
1450+ let full_path = workspace_root. join ( & target_cmd_path) ;
1451+ String :: from ( full_path. to_str ( ) . unwrap ( ) )
14101452}
14111453
14121454pub fn parse_iperf3_output ( output : & [ u8 ] , sender : bool , bandwidth : bool ) -> Result < f64 , Error > {
0 commit comments