Create the certificate in memory, insert it into the DB, and save it to a text file instead.
103 lines
3 KiB
JavaScript
103 lines
3 KiB
JavaScript
const { fork } = require('node:child_process')
|
|
const { createHash } = require('node:crypto')
|
|
const { createWriteStream } = require('node:fs')
|
|
const { readFile } = require('node:fs/promises')
|
|
const { EOL } = require('node:os')
|
|
const { join } = require('node:path')
|
|
|
|
require('../../lib/environment-helper')
|
|
const db = require('../../lib/db')
|
|
|
|
const { EXIT } = require('./consts')
|
|
const CLI = require('./cli')
|
|
|
|
const help_message = "Create and insert fake machines into the DB."
|
|
|
|
const cli = CLI({
|
|
grammar: [
|
|
[["--help"], "Show this help message"],
|
|
[["--machine", "PATH"], "Path to the machine's source code root"],
|
|
[["--device_ids_path", "PATH"], "Where to save the list of device IDs"],
|
|
[["-n", "NUMBER"], "Number of fake machines to create"],
|
|
[["--replace_existing"], "Remove machines of previous runs"],
|
|
],
|
|
})
|
|
|
|
const help = (exit_code) => {
|
|
console.log("Usage: lamassu-server-stress-testing machines ARGS...")
|
|
console.log(help_message)
|
|
cli.help()
|
|
return exit_code
|
|
}
|
|
|
|
const close_stream = (stream) => (
|
|
new Promise((resolve, reject) => (
|
|
stream.close((err) => err ? reject(err) : resolve())
|
|
))
|
|
)
|
|
|
|
const compute_machine_id = cert => {
|
|
cert = cert.split('\r\n')
|
|
const raw = Buffer.from(cert.slice(1, cert.length-2).join(''), 'base64')
|
|
return createHash('sha256').update(raw).digest('hex')
|
|
}
|
|
|
|
const create_fake_machine = async (device_ids_file, self_sign, i) => {
|
|
console.log("creating machine", i)
|
|
const { cert } = await self_sign.generateCertificate()
|
|
const device_id = compute_machine_id(cert)
|
|
await db.none(
|
|
`INSERT INTO devices (device_id, cassette1, cassette2, paired, display, created, name, last_online, location)
|
|
VALUES ($1, 0, 0, 't', 't', now(), $2, now(), '{}'::json)`,
|
|
[device_id, `machine_${i}`]
|
|
)
|
|
device_ids_file.write(device_id + EOL)
|
|
console.log("created machine", i, "with device ID", device_id)
|
|
}
|
|
|
|
const create_fake_machines = async ({ machine, device_ids_path, n, replace_existing }) => {
|
|
n = parseInt(n)
|
|
if (Number.isNaN(n) || n <= 0) {
|
|
console.error("Expected n to be a positive number, got", n)
|
|
return help(EXIT.BADARGS)
|
|
}
|
|
|
|
const device_ids_file = createWriteStream(device_ids_path, {
|
|
flags: replace_existing ? "w" : "a",
|
|
mode: 0o640,
|
|
flush: true,
|
|
})
|
|
if (replace_existing) await db.none("DELETE FROM devices")
|
|
|
|
const self_sign = require(join(process.cwd(), machine, "lib", "self_sign"))
|
|
for (let i = 0; i < n; i++)
|
|
await create_fake_machine(device_ids_file, self_sign, i)
|
|
|
|
await close_stream(device_ids_file)
|
|
|
|
return EXIT.OK
|
|
}
|
|
|
|
const run = async (args) => {
|
|
const [err, options, positional] = cli.parse(args)
|
|
if (err) {
|
|
console.error(err)
|
|
return help(EXIT.BADARGS)
|
|
}
|
|
|
|
if (options.help)
|
|
return help(EXIT.OK)
|
|
|
|
const missing_options = ["n", "machine", "device_ids_path"].filter((opt) => !options[opt])
|
|
if (missing_options.length > 0) {
|
|
console.error("The following options are required:", missing_options.join(", "))
|
|
return help(EXIT.BADARGS)
|
|
}
|
|
|
|
return await create_fake_machines(options)
|
|
}
|
|
|
|
module.exports = {
|
|
help_message,
|
|
run,
|
|
}
|