@mountainpass/hooked-cli
Version:
A tool for runnable scripts
157 lines (155 loc) • 6.82 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import fs from 'fs';
import inquirer from 'inquirer';
import YAML from 'yaml';
import defaults from './defaults.js';
import { executeCmd } from './scriptExecutors/$cmd.js';
import logger from './utils/logger.js';
import { Environment } from './utils/Environment.js';
import { loadRootPackageJsonSync } from './utils/packageJson.js';
const packageJson = loadRootPackageJsonSync();
const HEADER = `#
# Hooked configuration file
# See https://github.com/mountain-pass/hooked for more information.
#
# To install the cli: npm i -g @mountainpass/hooked-cli
# To enable yaml validation: https://github.com/mountain-pass/hooked/blob/main/_CONFIG.md#recommended---enable-yaml-schema
#
`;
/**
* Generates a blank hooked.yaml file contents.
*/
export const generateBlankTemplateFileContents = (saltOverride) => {
return `${HEADER}${YAML.stringify(defaults.CONFIG_BLANK(saltOverride), { blockQuote: 'literal' })}`;
};
/** Creates a blank hooked.yaml file. */
export const initialiseConfig = (options) => __awaiter(void 0, void 0, void 0, function* () {
yield writeFile(defaults.getDefaults().HOOKED_FILE, generateBlankTemplateFileContents(), options.force, false);
});
/** Runs openssl to generate the SSL certificates. */
export const initialiseSsl = (options) => __awaiter(void 0, void 0, void 0, function* () {
logger.info('Generating SSL certificates...');
yield executeCmd('initialiseDocker', {
$image: 'mountainpass/hooked',
$cmd: `#!/bin/sh -ve
openssl req -x509 -newkey rsa:2048 -nodes -keyout hooked-key.pem -new -out hooked-cert.pem -subj /CN=localhost -days 3650
`
}, options, {}, new Environment(), { printStdio: true, captureStdout: false }, 60000);
});
/** Writes a docker file, and "up's" the docker service. */
export const initialiseDocker = (options) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b, _c, _d;
if (!fs.existsSync('/var/run/docker.sock')) {
logger.warn('Docker socket file "/var/run/docker.sock" not found. Please update docker-compose.yml.');
}
// write docker compose
const DOCKER_COMPOSE_CONTENTS = `
services:
hooked:
image: mountainpass/hooked:${packageJson.version}
saltOverride?: string | undefined container_name: hooked_${(_a = options.server) !== null && _a !== void 0 ? _a : '4000'}
environment:
- TZ=${(_b = options.timezone) !== null && _b !== void 0 ? _b : 'UTC'}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${defaults.getDefaults().HOOKED_DIR}:${defaults.getDefaults().HOOKED_DIR}
working_dir: ${defaults.getDefaults().HOOKED_DIR}
command:
- --initConfig
- --initSsl
- --config
- ${defaults.getDefaults().HOOKED_FILE}
- --server
- --ssl
- --api-key=${(_c = options.apiKey) !== null && _c !== void 0 ? _c : 'abc'}
ports:
- ${(_d = options.server) !== null && _d !== void 0 ? _d : '4000'}:4000
restart: unless-stopped
logging:
driver: "json-file"
options:
max-file: 5
max-size: 10m`;
logger.info(`Writing docker compose file - ${defaults.getDefaults().DOCKER_COMPOSE_FILE}...`);
yield writeFile(defaults.getDefaults().DOCKER_COMPOSE_FILE, DOCKER_COMPOSE_CONTENTS, options.force, false);
// run docker service
logger.info('Running docker service...');
yield executeCmd('initialiseDocker', {
$cmd: `#!/bin/sh -ve
docker stop hooked || true
docker rm hooked || true
docker compose -f "${defaults.getDefaults().DOCKER_COMPOSE_FILE}" up -d
`
}, options, {}, new Environment(), { printStdio: true, captureStdout: false }, 60000);
});
/**
* Writes a UTF-8 file.
* @param filepath path to write to.
* @param contents the contents of the file.
* @param overwrite if true, overwrites the file if it exists.
* @param errorIfExists if true, throws an error if the file exists.
*/
const writeFile = (filepath, contents, overwrite, errorIfExists) => __awaiter(void 0, void 0, void 0, function* () {
if (fs.existsSync(filepath)) {
if (overwrite) {
logger.info(`Writing config file - ${filepath}`);
fs.writeFileSync(filepath, contents, { encoding: 'utf-8' });
}
else if (errorIfExists) {
throw new Error(`Cannot write, file already exists '${filepath}'. Force overwrite with the --force parameter.`);
}
else {
logger.warn(`Cannot write, file already exists '${filepath}'. Force overwrite with the --force parameter.`);
}
}
else {
logger.info(`Writing config file - ${filepath}`);
fs.writeFileSync(filepath, contents, { encoding: 'utf-8' });
}
});
/**
* Interactively choose an initialiser.
*/
export const init = (options) => __awaiter(void 0, void 0, void 0, function* () {
// throw error
if (options.batch === true) {
throw new Error(`No config file found (interactive prompts disabled). file="${defaults.getDefaults().HOOKED_FILE}".`);
}
// ask user which hooked.yaml template to use (NOTE: even if only one option, still ask user the chance to escape without creating a file!)
// const stdout = new CaptureStream(process.stdout)
yield inquirer.prompt([
{
type: 'list',
name: 'init',
message: 'Create new config from:',
pageSize: defaults.getDefaults().PAGE_SIZE,
choices: [
{ name: 'New Blank template.', value: 'config' },
{ name: 'Create SSL certificates (requires "openssl").', value: 'ssl' },
{ name: 'Create docker compose file and run (requires "docker").', value: 'docker' }
],
loop: true,
// output: stdout
}
]).then((answers) => __awaiter(void 0, void 0, void 0, function* () {
switch (answers.init) {
case 'ssl':
yield initialiseSsl(options);
break;
case 'docker':
yield initialiseDocker(options);
break;
case 'config':
yield initialiseConfig(options);
break;
}
}));
});