/** * Machine Remove Command * Remove a machine from the machine pool */ import { askConfirm, withInterviewSession } from '../../services/bus-interview'; import { getMachineByHostname, getMachineByIp, getModulesOnMachine, removeMachine, } from '../../services/machine-pool'; import { celiloIntro, celiloOutro } from '../prompts'; import type { CommandResult } from '../types'; /** * Handle machine remove command * * @param args - Command arguments [hostname] * @param flags - Command flags (--force) */ export async function handleMachineRemove( args: string[], flags: Record = {}, ): Promise { try { celiloIntro('Remove Machine'); // Get identifier from args (hostname or IP) const identifier = args[0]; if (!identifier) { return { success: false, error: 'Hostname or IP address is required\n\nUsage: celilo machine remove ', }; } // Look up by IP first, then by hostname const isIp = /^\d+\.\d+\.\d+\.\d+$/.test(identifier); const machine = isIp ? await getMachineByIp(identifier) : await getMachineByHostname(identifier); if (!machine) { return { success: false, error: `Machine not found: ${identifier}`, }; } const hostname = machine.hostname; // Derived from the same source placement uses (celilo#773), so the two // cannot disagree. Previously this refused to remove an empty machine over // a module that no longer existed, and let an occupied one be removed. const occupants = getModulesOnMachine(machine.id); if (occupants.length > 0) { console.log(`\nError: Machine '${hostname}' has ${occupants.length} assigned module(s):`); for (const moduleId of occupants) { console.log(` - ${moduleId}`); } console.log('\nModules must be unassigned or shut down before removing the machine.\n'); return { success: false, error: 'Cannot remove machine with assigned modules', }; } // Confirm deletion if (!flags.force) { const confirmed = await withInterviewSession(() => askConfirm({ scope: `machine:${hostname}`, key: 'remove', message: `Remove machine '${hostname}' (${machine.ipAddress})?`, defaultValue: false, }), ); if (!confirmed) { return { success: false, error: 'Cancelled by user' }; } } // Remove the machine await removeMachine(machine.id); celiloOutro(`Machine '${hostname}' removed successfully!`); return { success: true, message: `Removed machine: ${hostname}`, }; } catch (error) { return { success: false, error: `Failed to remove machine: ${error instanceof Error ? error.message : String(error)}`, }; } }