fix(striker-ui-api): add replacement for power control nodes, subnodes

main
Tsu-ba-me 2 years ago
parent 408e3ba78e
commit f49c510468
  1. 2
      striker-ui-api/src/lib/consts/SERVER_PATHS.ts
  2. 51
      striker-ui-api/src/lib/request_handlers/command/buildHostPowerHandler.ts
  3. 139
      striker-ui-api/src/lib/request_handlers/command/buildPowerHandler.ts
  4. 8
      striker-ui-api/src/lib/request_handlers/command/index.ts
  5. 3
      striker-ui-api/src/lib/request_handlers/command/poweroffHost.ts
  6. 3
      striker-ui-api/src/lib/request_handlers/command/poweroffStriker.ts
  7. 3
      striker-ui-api/src/lib/request_handlers/command/rebootHost.ts
  8. 3
      striker-ui-api/src/lib/request_handlers/command/rebootStriker.ts
  9. 3
      striker-ui-api/src/lib/request_handlers/command/startAn.ts
  10. 3
      striker-ui-api/src/lib/request_handlers/command/startSubnode.ts
  11. 3
      striker-ui-api/src/lib/request_handlers/command/stopAn.ts
  12. 3
      striker-ui-api/src/lib/request_handlers/command/stopSubnode.ts
  13. 16
      striker-ui-api/src/routes/command.ts
  14. 15
      striker-ui-api/src/types/BuildPowerJobParamsFunction.d.ts

@ -30,8 +30,10 @@ const EMPTY_SERVER_PATHS: ServerPath = {
'anvil-manage-keys': {},
'anvil-manage-power': {},
'anvil-provision-server': {},
'anvil-safe-stop': {},
'anvil-sync-shared': {},
'anvil-update-system': {},
'striker-boot-machine': {},
'striker-initialize-host': {},
'striker-manage-install-target': {},
'striker-manage-peers': {},

@ -1,51 +0,0 @@
import { RequestHandler } from 'express';
import SERVER_PATHS from '../../consts/SERVER_PATHS';
import { job } from '../../accessModule';
import { stderr } from '../../shell';
type DistinctJobParams = Omit<
JobParams,
'file' | 'line' | 'job_data' | 'job_progress'
>;
const MANAGE_HOST_POWER_JOB_PARAMS: {
poweroff: DistinctJobParams;
reboot: DistinctJobParams;
} = {
poweroff: {
job_command: `${SERVER_PATHS.usr.sbin['anvil-manage-power'].self} --poweroff -y`,
job_name: 'poweroff::system',
job_title: 'job_0010',
job_description: 'job_0008',
},
reboot: {
job_command: `${SERVER_PATHS.usr.sbin['anvil-manage-power'].self} --reboot -y`,
job_name: 'reboot::system',
job_title: 'job_0009',
job_description: 'job_0006',
},
};
export const buildHostPowerHandler: (
task?: 'poweroff' | 'reboot',
) => RequestHandler =
(task = 'reboot') =>
async (request, response) => {
const subParams: JobParams = {
file: __filename,
...MANAGE_HOST_POWER_JOB_PARAMS[task],
};
try {
await job(subParams);
} catch (subError) {
stderr(`Failed to ${task} host; CAUSE: ${subError}`);
return response.status(500).send();
}
response.status(204).send();
};

@ -0,0 +1,139 @@
import assert from 'assert';
import { RequestHandler } from 'express';
import { LOCAL, REP_UUID, SERVER_PATHS } from '../../consts';
import { job, query } from '../../accessModule';
import { sanitize } from '../../sanitize';
import { stderr } from '../../shell';
/**
* Notes on power functions:
* * poweroff, reboot targets the striker this express app operates on
* * start, stop targets subnode or DR host
*/
const MANAGE_HOST_POWER_JOB_PARAMS: Record<
PowerTask,
BuildPowerJobParamsFunction
> = {
poweroff: () => ({
job_command: `${SERVER_PATHS.usr.sbin['anvil-manage-power'].self} --poweroff -y`,
job_name: 'poweroff::system',
job_title: 'job_0010',
job_description: 'job_0008',
}),
reboot: () => ({
job_command: `${SERVER_PATHS.usr.sbin['anvil-manage-power'].self} --reboot -y`,
job_name: 'reboot::system',
job_title: 'job_0009',
job_description: 'job_0006',
}),
start: ({ uuid } = {}) => ({
job_command: `${SERVER_PATHS.usr.sbin['striker-boot-machine'].self} --host-uuid '${uuid}'`,
job_description: 'job_0335',
job_name: `set_power::on`,
job_title: 'job_0334',
}),
stop: ({ isStopServers, uuid } = {}) => ({
job_command: `${
SERVER_PATHS.usr.sbin['anvil-safe-stop'].self
} --power-off ${isStopServers ? '--stop-servers' : ''}`,
job_description: 'job_0333',
job_host_uuid: uuid,
job_name: 'set_power::off',
job_title: 'job_0332',
}),
};
const queuePowerJob = async (
task: PowerTask,
options?: BuildPowerJobParamsOptions,
) => {
const subParams: JobParams = {
file: __filename,
...MANAGE_HOST_POWER_JOB_PARAMS[task](options),
};
return await job(subParams);
};
export const buildPowerHandler: (
task: PowerTask,
) => RequestHandler<{ uuid?: string }> =
(task) => async (request, response) => {
const {
params: { uuid },
} = request;
try {
if (uuid) {
assert(
REP_UUID.test(uuid),
`Param UUID must be a valid UUIDv4; got [${uuid}]`,
);
}
} catch (error) {
stderr(`Failed to ${task} host; CAUSE: ${error}`);
return response.status(400).send();
}
try {
await queuePowerJob(task, { uuid });
} catch (error) {
stderr(`Failed to ${task} host ${uuid ?? LOCAL}; CAUSE: ${error}`);
return response.status(500).send();
}
response.status(204).send();
};
export const buildAnPowerHandler: (
task: Extract<PowerTask, 'start' | 'stop'>,
) => RequestHandler<{ uuid: string }> = (task) => async (request, response) => {
const {
params: { uuid },
} = request;
const anUuid = sanitize(uuid, 'string', { modifierType: 'sql' });
try {
assert(
REP_UUID.test(anUuid),
`Param UUID must be a valid UUIDv4; got: [${anUuid}]`,
);
} catch (error) {
stderr(`Failed to assert value during power operation on anvil subnode`);
return response.status(400).send();
}
let rows: [[node1Uuid: string, node2Uuid: string]];
try {
rows = await query(
`SELECT anvil_node1_host_uuid, anvil_node2_host_uuid
FROM anvils WHERE anvil_uuid = '${anUuid}';`,
);
assert.ok(rows.length, 'No entry found');
} catch (error) {
stderr(`Failed to get anvil subnodes' UUID; CAUSE: ${error}`);
return response.status(500).send();
}
for (const hostUuid of rows[0]) {
try {
await queuePowerJob(task, { isStopServers: true, uuid: hostUuid });
} catch (error) {
stderr(`Failed to ${task} host ${hostUuid}; CAUSE: ${error}`);
return response.status(500).send();
}
}
return response.status(204).send();
};

@ -1,5 +1,9 @@
export * from './getHostSSH';
export * from './poweroffHost';
export * from './rebootHost';
export * from './poweroffStriker';
export * from './rebootStriker';
export * from './runManifest';
export * from './startAn';
export * from './startSubnode';
export * from './stopAn';
export * from './stopSubnode';
export * from './updateSystem';

@ -1,3 +0,0 @@
import { buildHostPowerHandler } from './buildHostPowerHandler';
export const poweroffHost = buildHostPowerHandler('poweroff');

@ -0,0 +1,3 @@
import { buildPowerHandler } from './buildPowerHandler';
export const poweroffStriker = buildPowerHandler('poweroff');

@ -1,3 +0,0 @@
import { buildHostPowerHandler } from './buildHostPowerHandler';
export const rebootHost = buildHostPowerHandler('reboot');

@ -0,0 +1,3 @@
import { buildPowerHandler } from './buildPowerHandler';
export const rebootStriker = buildPowerHandler('reboot');

@ -0,0 +1,3 @@
import { buildAnPowerHandler } from './buildPowerHandler';
export const startAn = buildAnPowerHandler('start');

@ -0,0 +1,3 @@
import { buildPowerHandler } from './buildPowerHandler';
export const startSubnode = buildPowerHandler('start');

@ -0,0 +1,3 @@
import { buildAnPowerHandler } from './buildPowerHandler';
export const stopAn = buildAnPowerHandler('stop');

@ -0,0 +1,3 @@
import { buildPowerHandler } from './buildPowerHandler';
export const stopSubnode = buildPowerHandler('stop');

@ -2,9 +2,13 @@ import express from 'express';
import {
getHostSSH,
poweroffHost,
rebootHost,
poweroffStriker,
rebootStriker,
runManifest,
startAn,
startSubnode,
stopAn,
stopSubnode,
updateSystem,
} from '../lib/request_handlers/command';
@ -12,9 +16,13 @@ const router = express.Router();
router
.put('/inquire-host', getHostSSH)
.put('/poweroff-host', poweroffHost)
.put('/reboot-host', rebootHost)
.put('/poweroff-host', poweroffStriker)
.put('/reboot-host', rebootStriker)
.put('/run-manifest/:manifestUuid', runManifest)
.put('/start-an/:uuid', startAn)
.put('/start-subnode/:uuid', startSubnode)
.put('/stop-an/:uuid', stopAn)
.put('/stop-subnode/:uuid', stopSubnode)
.put('/update-system', updateSystem);
export default router;

@ -0,0 +1,15 @@
type PowerTask = 'poweroff' | 'reboot' | 'start' | 'stop';
type PowerJobParams = Omit<
JobParams,
'file' | 'line' | 'job_data' | 'job_progress'
>;
type BuildPowerJobParamsOptions = {
isStopServers?: boolean;
uuid?: string;
};
type BuildPowerJobParamsFunction = (
options?: BuildPowerJobParamsOptions,
) => PowerJobParams;
Loading…
Cancel
Save