parent
e5fc75f306
commit
4c4ce1834b
8 changed files with 182 additions and 8 deletions
@ -0,0 +1,18 @@ |
|||||||
|
import { spawnSync } from 'child_process'; |
||||||
|
|
||||||
|
import SERVER_PATHS from './consts/SERVER_PATHS'; |
||||||
|
|
||||||
|
export const mkfifo = (...args: string[]) => { |
||||||
|
const { error, stderr } = spawnSync(SERVER_PATHS.usr.bin.mkfifo.self, args, { |
||||||
|
encoding: 'utf-8', |
||||||
|
timeout: 3000, |
||||||
|
}); |
||||||
|
|
||||||
|
if (error) { |
||||||
|
throw error; |
||||||
|
} |
||||||
|
|
||||||
|
if (stderr) { |
||||||
|
throw new Error(stderr); |
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,139 @@ |
|||||||
|
import assert from 'assert'; |
||||||
|
import { RequestHandler } from 'express'; |
||||||
|
import { createReadStream, existsSync, rmSync, statSync } from 'fs'; |
||||||
|
import path from 'path'; |
||||||
|
|
||||||
|
import { REP_UUID } from '../../consts/REG_EXP_PATTERNS'; |
||||||
|
import SERVER_PATHS from '../../consts/SERVER_PATHS'; |
||||||
|
|
||||||
|
import { dbQuery, sub } from '../../accessModule'; |
||||||
|
import { mkfifo } from '../../mkfifo'; |
||||||
|
import { sanitizeQS } from '../../sanitizeQS'; |
||||||
|
|
||||||
|
export const getServerDetail: RequestHandler = (request, response) => { |
||||||
|
const { serverUUID } = request.params; |
||||||
|
const { ss, resize } = request.query; |
||||||
|
|
||||||
|
const isScreenshot = sanitizeQS(ss, { |
||||||
|
returnType: 'boolean', |
||||||
|
}); |
||||||
|
|
||||||
|
console.log(`serverUUID=[${serverUUID}],isScreenshot=[${isScreenshot}]`); |
||||||
|
|
||||||
|
try { |
||||||
|
assert( |
||||||
|
REP_UUID.test(serverUUID), |
||||||
|
`Server UUID must be a valid UUID; got [${serverUUID}]`, |
||||||
|
); |
||||||
|
} catch (assertError) { |
||||||
|
console.log( |
||||||
|
`Failed to assert value when trying to get server detail; CAUSE: ${assertError}.`, |
||||||
|
); |
||||||
|
|
||||||
|
response.status(500).send(); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (isScreenshot) { |
||||||
|
let requestHostUUID: string, serverHostUUID: string; |
||||||
|
|
||||||
|
try { |
||||||
|
requestHostUUID = sub('host_uuid', { |
||||||
|
subModuleName: 'Get', |
||||||
|
}).stdout; |
||||||
|
} catch (subError) { |
||||||
|
console.log(`Failed to get local host UUID; CAUSE: ${subError}`); |
||||||
|
|
||||||
|
response.status(500).send(); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
console.log(`requestHostUUID=[${requestHostUUID}]`); |
||||||
|
|
||||||
|
try { |
||||||
|
[[serverHostUUID]] = dbQuery(` |
||||||
|
SELECT server_host_uuid |
||||||
|
FROM servers |
||||||
|
WHERE server_uuid = '${serverUUID}';`).stdout;
|
||||||
|
} catch (queryError) { |
||||||
|
console.log(`Failed to get server host UUID; CAUSE: ${queryError}`); |
||||||
|
|
||||||
|
response.status(500).send(); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
console.log(`serverHostUUID=[${serverHostUUID}]`); |
||||||
|
|
||||||
|
const imageFileName = `${serverUUID}_screenshot`; |
||||||
|
const imageFilePath = path.join(SERVER_PATHS.tmp.self, imageFileName); |
||||||
|
|
||||||
|
try { |
||||||
|
if (existsSync(imageFilePath)) { |
||||||
|
if (!statSync(imageFilePath).isFIFO()) { |
||||||
|
rmSync(imageFilePath); |
||||||
|
mkfifo(imageFilePath); |
||||||
|
} |
||||||
|
} else { |
||||||
|
mkfifo(imageFilePath); |
||||||
|
} |
||||||
|
|
||||||
|
const namedPipeReadStream = createReadStream(imageFilePath, { |
||||||
|
encoding: 'utf-8', |
||||||
|
}); |
||||||
|
|
||||||
|
namedPipeReadStream.once('data', (data) => { |
||||||
|
response.status(200).send({ screenshot: data.toString().trim() }); |
||||||
|
|
||||||
|
namedPipeReadStream.close(); |
||||||
|
}); |
||||||
|
} catch (prepPipeError) { |
||||||
|
console.log(`Failed to prepare named pipe; CAUSE: ${prepPipeError}`); |
||||||
|
|
||||||
|
response.status(500).send(); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
let resizeArgs = sanitizeQS(resize, { |
||||||
|
returnType: 'string', |
||||||
|
}); |
||||||
|
|
||||||
|
if (!/^\d+x\d+$/.test(resizeArgs)) { |
||||||
|
resizeArgs = ''; |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
sub('insert_or_update_jobs', { |
||||||
|
subParams: { |
||||||
|
file: __filename, |
||||||
|
line: 0, |
||||||
|
job_command: |
||||||
|
SERVER_PATHS.usr.sbin['anvil-get-server-screenshot'].self, |
||||||
|
job_data: `server-uuid=${serverUUID} |
||||||
|
request-host-uuid=${requestHostUUID} |
||||||
|
resize=${resizeArgs}`,
|
||||||
|
job_name: `get_server_screenshot::${serverUUID}`, |
||||||
|
job_title: 'job_0356', |
||||||
|
job_description: 'job_0357', |
||||||
|
job_progress: 0, |
||||||
|
job_host_uuid: serverHostUUID, |
||||||
|
}, |
||||||
|
}).stdout; |
||||||
|
} catch (subError) { |
||||||
|
console.log( |
||||||
|
`Failed to queue fetch server screenshot job; CAUSE: ${subError}`, |
||||||
|
); |
||||||
|
|
||||||
|
response.status(500).send(); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
} else { |
||||||
|
// For getting sever detail data.
|
||||||
|
|
||||||
|
response.status(200).send(); |
||||||
|
} |
||||||
|
}; |
@ -1,2 +1,3 @@ |
|||||||
export { createServer } from './createServer'; |
export { createServer } from './createServer'; |
||||||
export { getServer } from './getServer'; |
export { getServer } from './getServer'; |
||||||
|
export { getServerDetail } from './getServerDetail'; |
||||||
|
@ -1,9 +1,16 @@ |
|||||||
import express from 'express'; |
import express from 'express'; |
||||||
|
|
||||||
import { createServer, getServer } from '../lib/request_handlers/server'; |
import { |
||||||
|
createServer, |
||||||
|
getServer, |
||||||
|
getServerDetail, |
||||||
|
} from '../lib/request_handlers/server'; |
||||||
|
|
||||||
const router = express.Router(); |
const router = express.Router(); |
||||||
|
|
||||||
router.get('/', getServer).post('/', createServer); |
router |
||||||
|
.get('/', getServer) |
||||||
|
.get('/:serverUUID', getServerDetail) |
||||||
|
.post('/', createServer); |
||||||
|
|
||||||
export default router; |
export default router; |
||||||
|
Loading…
Reference in new issue