A simple, powerful CLI tool to spin up OpenIndiana virtual machines with QEMU
at main 3.0 kB view raw
1import chalk from "chalk"; 2 3export async function setupQemuBridge(bridgeName: string): Promise<void> { 4 const bridgeConfPath = "/etc/qemu/bridge.conf"; 5 const bridgeConfContent = await Deno.readTextFile(bridgeConfPath).catch( 6 () => "", 7 ); 8 if (bridgeConfContent.includes(`allow ${bridgeName}`)) { 9 console.log( 10 chalk.greenBright( 11 `QEMU bridge configuration for ${bridgeName} already exists.`, 12 ), 13 ); 14 return; 15 } 16 17 console.log( 18 chalk.blueBright( 19 `Adding QEMU bridge configuration for ${bridgeName}...`, 20 ), 21 ); 22 23 const cmd = new Deno.Command("sudo", { 24 args: [ 25 "sh", 26 "-c", 27 `mkdir -p /etc/qemu && echo "allow ${bridgeName}" >> ${bridgeConfPath}`, 28 ], 29 stdin: "inherit", 30 stdout: "inherit", 31 stderr: "inherit", 32 }); 33 const status = await cmd.spawn().status; 34 35 if (!status.success) { 36 console.error( 37 chalk.redBright( 38 `Failed to add QEMU bridge configuration for ${bridgeName}.`, 39 ), 40 ); 41 Deno.exit(status.code); 42 } 43 44 console.log( 45 chalk.greenBright( 46 `QEMU bridge configuration for ${bridgeName} added successfully.`, 47 ), 48 ); 49} 50 51export async function createBridgeNetworkIfNeeded( 52 bridgeName: string, 53): Promise<void> { 54 const bridgeExistsCmd = new Deno.Command("ip", { 55 args: ["link", "show", bridgeName], 56 stdout: "null", 57 stderr: "null", 58 }); 59 60 const bridgeExistsStatus = await bridgeExistsCmd.spawn().status; 61 if (bridgeExistsStatus.success) { 62 console.log( 63 chalk.greenBright(`Network bridge ${bridgeName} already exists.`), 64 ); 65 await setupQemuBridge(bridgeName); 66 return; 67 } 68 69 console.log(chalk.blueBright(`Creating network bridge ${bridgeName}...`)); 70 const createBridgeCmd = new Deno.Command("sudo", { 71 args: ["ip", "link", "add", bridgeName, "type", "bridge"], 72 stdin: "inherit", 73 stdout: "inherit", 74 stderr: "inherit", 75 }); 76 77 let status = await createBridgeCmd.spawn().status; 78 if (!status.success) { 79 console.error( 80 chalk.redBright(`Failed to create network bridge ${bridgeName}.`), 81 ); 82 Deno.exit(status.code); 83 } 84 85 const bringUpBridgeCmd = new Deno.Command("sudo", { 86 args: ["ip", "link", "set", "dev", bridgeName, "up"], 87 stdin: "inherit", 88 stdout: "inherit", 89 stderr: "inherit", 90 }); 91 status = await bringUpBridgeCmd.spawn().status; 92 if (!status.success) { 93 console.error( 94 chalk.redBright(`Failed to bring up network bridge ${bridgeName}.`), 95 ); 96 Deno.exit(status.code); 97 } 98 99 console.log( 100 chalk.greenBright(`Network bridge ${bridgeName} created and up.`), 101 ); 102 103 await setupQemuBridge(bridgeName); 104} 105 106export function generateRandomMacAddress(): string { 107 const hexDigits = "0123456789ABCDEF"; 108 let macAddress = "52:54:00"; 109 110 for (let i = 0; i < 3; i++) { 111 macAddress += ":"; 112 for (let j = 0; j < 2; j++) { 113 macAddress += hexDigits.charAt( 114 Math.floor(Math.random() * hexDigits.length), 115 ); 116 } 117 } 118 119 return macAddress; 120}