'use strict'; module.exports = function(socket, options) { return Promise.try(() => { return Promise.all([ socket.execute("query-commands"), socket.execute("query-block") ]); }).then((commands, blockDevices) => { let commandList = commands.map((item) => item.name); let supportsBlockdevChangeMedium = commandList.includes("blockdev-change-medium"); let cdromDevices = blockDevices.filter((devices) => device.device.match(/^ide[0-9]-cd[0-9]$/)); return { create: function() { }, getSupportedFeatures: function() { return [ "start", "stop", "forceStop", "forceReset", "insertDisk", "ejectDisk", "forceEjectDisk", "inspectDisk", "vncPassword" ]; }, getStatus: function() { return socket.execute("query-status"); }, start: function() { // FIXME }, stop: function(force = false) { return Promise.try(() => { if (force) { socket.execute("quit"); } else { socket.execute("system_powerdown"); } }); }, reset: function(force = true) { return Promise.try(() => { if (force) { socket.execute("system_reset"); } else { throw new NotImplementedError("ACPI reset is not available for QEMU/KVM"); } }); }, suspend: function() { return socket.execute("stop"); }, unsuspend: function() { return socket.execute("cont"); }, insertDisk: function(path, options = {}) { return Promise.try(() => { if (cdromDevices.length === 0) { throw new Error("No CD-ROM devices available"); } else { if (supportsBlockdevChangeMedium) { return socket.execute("blockdev-change-medium", { device: cdromDevices[0].device, filename: path, format: options.format }); } else { if (options.format != null) { throw new Error("QEMU/QMP version does not allow for specifying the image format"); } else { return socket.execute("change", { device: cdromDevices[0].device, target: path }); } } } }) }, ejectDisk: function(force = false) { return Promise.try(() => { if (cdromDevices.length === 0) { throw new Error("No CD-ROM devices available"); } else { return socket.execute("eject", { device: cdromDevices[0].device }); } }) }, inspectDisk: function() { // FIXME: Normalized format? return Promise.try(() => { if (cdromDevices.length === 0) { throw new Error("No CD-ROM devices available"); } else { return Promise.try(() => { return socket.execute("query-block"); }).then((blockDevices) => { return blockDevices.filter((device) => device.device === cdromDevices[0].device); }); } }); } } }); }