diff --git a/lib/endpoints/vms.js b/lib/endpoints/vms.js index 164003d..3ee7c3e 100644 --- a/lib/endpoints/vms.js +++ b/lib/endpoints/vms.js @@ -336,6 +336,92 @@ VM.vnc = function handlerVmVnc(req, res, next) { }; +/** + * Query the server for the VM's console host and port. + * + * Returns connection details for the VM's console (serial console for KVM, + * zone console for other brands). + * + * @name VmConsole + * @endpoint GET /servers/:server_uuid/vms/:uuid/console + * @section Virtual Machine API + * + * @response 200 Object Request succeeded + * @response 404 Object No such VM + * @response 404 Object No such server + */ + +var vmConsoleTimeoutSeconds = 10; +VM.console = function handlerVmConsole(req, res, next) { + var responded; + + if (validation.ensureParamsValid(req, res, vmValidationRules)) { + next(); + return; + } + + var timeout = setTimeout(function () { + responded = true; + next(new restify.InternalError( + 'Time-out reached waiting for machine_load request to return')); + }, vmConsoleTimeoutSeconds * 1000); + + var types = ['console']; + + req.stash.vm.info( + { req_id: req.getId(), types: types }, + function (error, infoResponse) { + var vminfo; + clearTimeout(timeout); + + if (responded && error) { + req.log.error(error.message); + return; + } + + if (responded) { + req.log.warn('Got a reply back from an expired request'); + return; + } + + if (error) { + if (errDetails(error).restCode === 'VmNotFound') { + next(new restify.ResourceNotFoundError('VM ' + + req.params.uuid + ' not found')); + } else { + next(new restify.InternalError(error.message)); + } + return; + } + + try { + vminfo = JSON.parse(infoResponse); + } catch (e) { + req.log.error({infoResponse: infoResponse, err: e}, + 'failed to parse JSON'); + next(new restify.InternalError( + 'failed to parse JSON response from vm.info')); + return; + } + + // Ensure console info exists + if (!vminfo.console || !vminfo.console.host || !vminfo.console.port) { + next(new restify.ResourceNotFoundError( + 'Console information not available for VM ' + req.params.uuid)); + return; + } + + var host = vminfo.console.host; + var port = vminfo.console.port; + var type = vminfo.console.type; + + res.send({host: host, port: port, type: type}); + next(); + return; + }); +}; + + /** * Modify the system parameters of the VM identified by `:uuid` on server with * UUID `:server_uuid`. @@ -1332,6 +1418,17 @@ function attachTo(http, app) { }), VM.vnc); + http.get( + { path: '/servers/:server_uuid/vms/:uuid/console', name: 'VmConsole' }, + ensure({ + connectionTimeoutSeconds: 60 * 60, + app: app, + serverRunning: true, + prepopulate: ['server', 'vm'], + connected: ['moray'] + }), + VM.console); + // Update VM's properties from the server (resize) http.post( { path: '/servers/:server_uuid/vms/:uuid/update', name: 'VmUpdate' },