feat(striker-ui-api): add fetch server screenshot endpoint logic

main
Tsu-ba-me 3 years ago
parent e5fc75f306
commit 4c4ce1834b
  1. 14
      striker-ui-api/src/lib/accessModule.ts
  2. 3
      striker-ui-api/src/lib/consts/SERVER_PATHS.ts
  3. 18
      striker-ui-api/src/lib/mkfifo.ts
  4. 2
      striker-ui-api/src/lib/request_handlers/buildGetRequestHandler.ts
  5. 139
      striker-ui-api/src/lib/request_handlers/server/getServerDetail.ts
  6. 1
      striker-ui-api/src/lib/request_handlers/server/index.ts
  7. 2
      striker-ui-api/src/routes/file.ts
  8. 11
      striker-ui-api/src/routes/server.ts

@ -5,8 +5,8 @@ import SERVER_PATHS from './consts/SERVER_PATHS';
const execAnvilAccessModule = ( const execAnvilAccessModule = (
args: string[], args: string[],
options: SpawnSyncOptions = { options: SpawnSyncOptions = {
timeout: 10000,
encoding: 'utf-8', encoding: 'utf-8',
timeout: 10000,
}, },
) => { ) => {
const { error, stdout, stderr } = spawnSync( const { error, stdout, stderr } = spawnSync(
@ -31,7 +31,7 @@ const execAnvilAccessModule = (
output = stdout; output = stdout;
console.warn( console.warn(
`Failed to parse anvil-access-module output [${output}]; error: [${stdoutParseError}]`, `Failed to parse anvil-access-module output [${output}]; CAUSE: [${stdoutParseError}]`,
); );
} }
@ -63,6 +63,14 @@ const execModuleSubroutine = (
args.push('--sub-params', JSON.stringify(subParams)); args.push('--sub-params', JSON.stringify(subParams));
} }
console.log(
`...${subModuleName}->${subName} with params: ${JSON.stringify(
subParams,
null,
2,
)}`,
);
const { stdout } = execAnvilAccessModule(args, spawnSyncOptions); const { stdout } = execAnvilAccessModule(args, spawnSyncOptions);
return { return {
@ -102,8 +110,6 @@ const dbJobAnvilSyncShared = (
subParams.job_host_uuid = jobHostUUID; subParams.job_host_uuid = jobHostUUID;
} }
console.log(JSON.stringify(subParams, null, 2));
return execModuleSubroutine('insert_or_update_jobs', { subParams }).stdout; return execModuleSubroutine('insert_or_update_jobs', { subParams }).stdout;
}; };

@ -6,12 +6,15 @@ const EMPTY_SERVER_PATHS: ServerPath = {
incoming: {}, incoming: {},
}, },
}, },
tmp: {},
usr: { usr: {
bin: { bin: {
mkfifo: {},
sed: {}, sed: {},
}, },
sbin: { sbin: {
'anvil-access-module': {}, 'anvil-access-module': {},
'anvil-get-server-screenshot': {},
'anvil-provision-server': {}, 'anvil-provision-server': {},
'anvil-sync-shared': {}, 'anvil-sync-shared': {},
'striker-parse-os-list': {}, 'striker-parse-os-list': {},

@ -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);
}
};

@ -23,7 +23,7 @@ const buildGetRequestHandler =
}), }),
)); ));
} catch (queryError) { } catch (queryError) {
console.log(`Query error: ${queryError}`); console.log(`Failed to execute query; CAUSE: ${queryError}`);
response.status(500).send(); response.status(500).send();

@ -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';

@ -174,7 +174,7 @@ router
try { try {
({ stdout: queryStdout } = dbWrite(query)); ({ stdout: queryStdout } = dbWrite(query));
} catch (queryError) { } catch (queryError) {
console.log(`Query error: ${queryError}`); console.log(`Failed to execute query; CAUSE: ${queryError}`);
response.status(500).send(); response.status(500).send();
} }

@ -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…
Cancel
Save