@@ -71,12 +71,12 @@ def _fix_efi_bootloader(efi_mount):
7171
7272 log .info ("EFI bootloader fix: BOOTX64.EFI not found, will attempt to create at %s" , boot_dir )
7373 bootx64 = os .path .join (boot_dir , "BOOTX64.EFI" )
74- run_cmd ([ "sudo" , "mkdir" , "-p" , boot_dir ] )
74+ os . makedirs ( boot_dir , exist_ok = True )
7575 log .info ("EFI bootloader fix: created directory %s" , boot_dir )
7676
7777 src = _find_path_case_insensitive (efi_mount , "EFI" , "Microsoft" , "Boot" , "bootmgfw.efi" )
7878 if src :
79- run_cmd ([ "sudo" , "cp" , src , bootx64 ] )
79+ shutil . copy2 ( src , bootx64 )
8080 log .info ("EFI bootloader fix: copied %s -> %s" , src , bootx64 )
8181 return
8282
@@ -155,7 +155,7 @@ def _copy_file(src: str, dst: str) -> str:
155155def _find_ntfs_tool (status_cb = None ) -> str | None :
156156 """Find mkfs.ntfs/mkntfs, installing ntfs-3g if needed. Returns command name or None."""
157157 for candidate in ["mkfs.ntfs" , "mkntfs" ]:
158- if subprocess . run ([ " which" , candidate ], capture_output = True ). returncode == 0 :
158+ if shutil . which ( candidate ) :
159159 return candidate
160160
161161 if status_cb :
@@ -167,21 +167,21 @@ def _find_ntfs_tool(status_cb=None) -> str | None:
167167 ["zypper" , "install" , "-y" , "ntfs-3g" ],
168168 ]
169169 for pm_cmd in pkg_managers :
170- if subprocess . run ([ " which" , pm_cmd [0 ]], capture_output = True ). returncode == 0 :
170+ if shutil . which ( pm_cmd [0 ]) :
171171 run_cmd (["sudo" ] + pm_cmd )
172172 break # stop after the first working package manager
173173
174174 # Re-check after installation attempt
175175 for candidate in ["mkfs.ntfs" , "mkntfs" ]:
176- if subprocess . run ([ " which" , candidate ], capture_output = True ). returncode == 0 :
176+ if shutil . which ( candidate ) :
177177 return candidate # installation succeeded
178178
179179 return None
180180
181181
182182def _ensure_wimlib (status_cb = None ) -> None :
183183 """Install wimlib-imagex if not present. Raises FileNotFoundError if it can't be found after install."""
184- if subprocess . run ([ "which" , " wimlib-imagex"], capture_output = True ). returncode == 0 :
184+ if shutil . which ( " wimlib-imagex") :
185185 return
186186 if status_cb :
187187 status_cb ("wimlib-imagex not found, attempting to install..." )
@@ -192,10 +192,10 @@ def _ensure_wimlib(status_cb=None) -> None:
192192 ["zypper" , "install" , "-y" , "wimtools" ],
193193 ]
194194 for pm_cmd in pkg_managers :
195- if subprocess . run ([ " which" , pm_cmd [0 ]], capture_output = True ). returncode == 0 :
195+ if shutil . which ( pm_cmd [0 ]) :
196196 run_cmd (["sudo" ] + pm_cmd )
197197 break
198- if subprocess . run ([ "which" , " wimlib-imagex"], capture_output = True ). returncode != 0 :
198+ if not shutil . which ( " wimlib-imagex") :
199199 raise FileNotFoundError (
200200 "wimlib-imagex not found. Install manually: sudo pacman -S wimlib / sudo apt install wimtools"
201201 )
@@ -271,20 +271,34 @@ def _copy_efi_boot_files(iso_mount, mount_efi, _status):
271271 if efi_src :
272272 efi_items = os .listdir (efi_src )
273273 _status (f"Found EFI/ with { len (efi_items )} items: { efi_items } " )
274- run_cmd (["sudo" , "cp" , "-r" ] + [os .path .join (efi_src , i ) for i in efi_items ] + [mount_efi ])
274+ for item in efi_items :
275+ src_path = os .path .join (efi_src , item )
276+ dst_path = os .path .join (mount_efi , "EFI" , item )
277+ if os .path .isdir (src_path ):
278+ shutil .copytree (src_path , dst_path , dirs_exist_ok = True )
279+ else :
280+ os .makedirs (os .path .dirname (dst_path ), exist_ok = True )
281+ shutil .copy2 (src_path , dst_path )
275282 _status ("Copied EFI/ tree to EFI partition" )
276283 else :
277284 _status ("WARNING: No EFI directory found in ISO - drive may not be UEFI bootable" )
278285
279286 boot_src = _find_path_case_insensitive (iso_mount , "boot" )
280287 if boot_src :
281- run_cmd (["sudo" , "cp" , "-r" ] + [os .path .join (boot_src , i ) for i in os .listdir (boot_src )] + [mount_efi ])
288+ for item in os .listdir (boot_src ):
289+ src_path = os .path .join (boot_src , item )
290+ dst_path = os .path .join (mount_efi , "boot" , item )
291+ if os .path .isdir (src_path ):
292+ shutil .copytree (src_path , dst_path , dirs_exist_ok = True )
293+ else :
294+ os .makedirs (os .path .dirname (dst_path ), exist_ok = True )
295+ shutil .copy2 (src_path , dst_path )
282296 _status ("Copied boot/ tree to EFI partition" )
283297
284298 for fname in ["bootmgr" , "bootmgr.efi" ]:
285299 src = _find_path_case_insensitive (iso_mount , fname )
286300 if src :
287- run_cmd ([ "sudo" , "cp" , src , f" { mount_efi } / { fname } " ] )
301+ shutil . copy2 ( src , os . path . join ( mount_efi , fname ) )
288302 _status (f"Copied { fname } to EFI partition root" )
289303
290304 _fix_efi_bootloader (mount_efi )
@@ -412,7 +426,7 @@ def _status(msg):
412426
413427 # Step 7: Sync
414428 _status ("Syncing all writes to disk..." )
415- run_cmd ([ "sudo" , " sync" ] )
429+ os . sync ( )
416430 _emit (97 )
417431 _status ("Sync complete" )
418432
0 commit comments