/** * ISO Packer * Repacks a directory into a bootable ISO using xorriso */ import { log } from '../logging.ts'; export class IsoPacker { /** * Pack a directory into an ISO */ async pack(sourceDir: string, outputIso: string, volumeLabel?: string): Promise { log.info(`Creating ISO from ${sourceDir}...`); const label = volumeLabel || 'UBUNTU_CUSTOM'; // Use xorriso to create a bootable ISO const command = new Deno.Command('xorriso', { args: [ '-as', 'mkisofs', '-r', '-V', label, '-o', outputIso, '-J', '-joliet-long', '-cache-inodes', '-isohybrid-mbr', '/usr/lib/ISOLINUX/isohdpfx.bin', '-b', 'isolinux/isolinux.bin', '-c', 'isolinux/boot.cat', '-boot-load-size', '4', '-boot-info-table', '-no-emul-boot', '-eltorito-alt-boot', '-e', 'boot/grub/efi.img', '-no-emul-boot', '-isohybrid-gpt-basdat', sourceDir, ], stdout: 'piped', stderr: 'piped', }); const process = command.spawn(); const { code, stderr } = await process.output(); if (code !== 0) { const errorText = new TextDecoder().decode(stderr); throw new Error(`Failed to create ISO: ${errorText}`); } log.success(`ISO created successfully at ${outputIso}`); // Make it hybrid bootable (USB compatible) await this.makeIsohybrid(outputIso); } /** * Make the ISO hybrid bootable (USB-compatible) */ private async makeIsohybrid(isoPath: string): Promise { try { log.info('Making ISO hybrid bootable...'); const command = new Deno.Command('isohybrid', { args: ['--uefi', isoPath], stdout: 'piped', stderr: 'piped', }); const { code } = await command.output(); if (code === 0) { log.success('ISO is now USB-bootable'); } else { log.warn('isohybrid failed, ISO may not be USB-bootable'); } } catch (err: unknown) { const errorMessage = err instanceof Error ? err.message : String(err); log.warn(`isohybrid not available: ${errorMessage}`); } } /** * Check if required tools are installed */ async checkDependencies(): Promise { try { const xorrisoCmd = new Deno.Command('xorriso', { args: ['--version'], stdout: 'null', stderr: 'null', }); const { code } = await xorrisoCmd.output(); return code === 0; } catch { return false; } } /** * Ensure dependencies are installed */ async ensureDependencies(): Promise { const hasXorriso = await this.checkDependencies(); if (!hasXorriso) { log.error('xorriso is not installed!'); log.info('Install xorriso:'); log.info(' Ubuntu/Debian: sudo apt install xorriso syslinux-utils'); log.info(' macOS: brew install xorriso syslinux'); throw new Error('Missing dependency: xorriso'); } } }