@@ -10,9 +10,9 @@ use std::cell::OnceCell;
1010use std:: cell:: RefCell ;
1111use std:: path:: Path ;
1212use std:: time:: Duration ;
13- use tracing:: debug;
1413use tracing:: error;
1514use tracing:: info;
15+ use tracing:: { debug, warn} ;
1616
1717use crate :: container:: Container ;
1818use crate :: distrobox;
@@ -386,8 +386,46 @@ impl RootStore {
386386 } ) ;
387387 }
388388
389+ pub async fn run_to_string ( & self , mut cmd : Command ) -> Result < String , anyhow:: Error > {
390+ cmd. stderr = FdMode :: Pipe ;
391+ cmd. stdout = FdMode :: Pipe ;
392+ let output = self . command_runner ( ) . output ( cmd. clone ( ) ) . await ?;
393+ Ok ( String :: from_utf8 ( output. stdout ) . map_err ( |e| {
394+ error ! ( cmd = %cmd, "Failed to parse command output" ) ;
395+ distrobox:: Error :: ParseOutput ( e. to_string ( ) )
396+ } ) ?)
397+ }
398+
399+ pub async fn is_nvidia_host ( & self ) -> Result < bool , distrobox:: Error > {
400+ // uses lspci to check if the host has an NVIDIA GPU
401+ debug ! ( "Checking if host is NVIDIA" ) ;
402+ let cmd = Command :: new ( "lspci" ) ;
403+ let output = self . run_to_string ( cmd) . await ;
404+ match output {
405+ Ok ( output) => {
406+ let is_nvidia = output. contains ( "NVIDIA" ) || output. contains ( "nVidia" ) ;
407+ debug ! ( is_nvidia, "Checked if host is NVIDIA" ) ;
408+ Ok ( is_nvidia)
409+ }
410+ Err ( e) => {
411+ debug ! ( ?e, "Failed to check if host is NVIDIA" ) ;
412+ Ok ( false ) // If we can't run lspci, we assume it's not NVIDIA
413+ }
414+ }
415+ }
416+
389417 pub async fn resolve_host_path ( & self , path : & str ) -> Result < String , distrobox:: Error > {
390- let mut cmd = Command :: new_with_args (
418+ // The path could be a:
419+ // 1. Host path, already resolved to a real location, e.g., "/home/user/Documents/custom-home-folder".
420+ // 2. Path from a flatpak sandbox, e.g., "/run/user/1000/doc/abc123".
421+ // The user may not have the `getfattr`, but we still want to try using it,
422+ // because we don't have an exact way to know if the path is from a flatpak sandbox or not.
423+ // If the path is already a real host path, `getfattr` may return an empty output,
424+ // because it doesn't have the `user.document-portal.host-path` attribute set by the flatpak portal.
425+
426+ debug ! ( ?path, "Resolving host path" ) ;
427+
428+ let cmd = Command :: new_with_args (
391429 "getfattr" ,
392430 [
393431 "-n" ,
@@ -396,30 +434,34 @@ impl RootStore {
396434 path,
397435 ] ,
398436 ) ;
399- cmd. stderr = FdMode :: Pipe ;
400- cmd. stdout = FdMode :: Pipe ;
401437 let output = self
402- . command_runner ( )
403- . output ( cmd)
438+ . run_to_string ( cmd)
404439 . await
405440 . map_err ( |e| distrobox:: Error :: ResolveHostPath ( e. to_string ( ) ) ) ;
406441
407442 let is_from_sandbox = path. starts_with ( "/run/user" ) ;
408443
409- // If the path is not from a flatpak sandbox, we assume it's a regular path, so we can skip the getfattr command error.
410- // If the command was successful, but for some reason the output is empty, we also return the path as is.
411- let stdout = if ( output. is_err ( ) && !is_from_sandbox)
412- || output. as_ref ( ) . map_or ( false , |o| o. stdout . is_empty ( ) )
413- {
414- return Ok ( path. to_string ( ) ) ;
415- } else {
416- output?. stdout
417- } ;
418-
419- Ok ( String :: from_utf8 ( stdout)
420- . map_err ( |e| distrobox:: Error :: ParseOutput ( e. to_string ( ) ) ) ?
421- . trim ( )
422- . to_string ( ) )
444+ match output {
445+ Ok ( resolved_path) => {
446+ debug ! ( ?resolved_path, "Resolved host path" ) ;
447+ if resolved_path. is_empty ( ) {
448+ // If the output is empty, we assume the path is already a real host path.
449+ return Ok ( path. to_string ( ) ) ;
450+ }
451+ Ok ( resolved_path. trim ( ) . to_string ( ) )
452+ }
453+ Err ( e) if !is_from_sandbox => {
454+ debug ! (
455+ ?e,
456+ "Failed to execute getfattr, but path doesn't seem from a sandbox anyway"
457+ ) ;
458+ Ok ( path. trim ( ) . to_string ( ) )
459+ }
460+ Err ( e) => {
461+ debug ! ( ?e, "Failed to resolve host path using getfattr" ) ;
462+ Err ( e)
463+ }
464+ }
423465 }
424466}
425467
0 commit comments