UNPKG

@zowe/cli

Version:

Zowe CLI is a command line interface (CLI) that provides a simple and streamlined way to interact with IBM z/OS.

186 lines 6.58 kB
"use strict"; /* * This program and the accompanying materials are made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-v20.html * * SPDX-License-Identifier: EPL-2.0 * * Copyright Contributors to the Zowe Project. * */ Object.defineProperty(exports, "__esModule", { value: true }); exports.DaemonDecider = void 0; const fs = require("fs"); const net = require("net"); const os = require("os"); const path = require("path"); const imperative_1 = require("@zowe/imperative"); const DaemonClient_1 = require("./DaemonClient"); const DaemonUtil_1 = require("./DaemonUtil"); // TODO(Kelosky): handle prompting cases from login command // TODO(Kelosky): prompt* broken - hangs, must restart daemon // TODO(Kelosky): colors do not come through on some terminals (must be started via `node lib/main --daemon` to see colors) // TODO(Kelosky): stderr // TODO(Kelosky): plugins install /** * Initial paramter parse to handle conditionally starting as a persistent process (e.g. daemon mode) * @export * @class DaemonDecider */ class DaemonDecider { /** * Creates an instance of DaemonDecider. * @param {string[]} mParms * @memberof DaemonDecider */ constructor(mParms) { this.mParms = mParms; } /** * Initialize our DaemonDecider parse and optionally start the server * @memberof DaemonDecider */ init() { this.initialParse(); if (this.startServer) { this.mServer = net.createServer((c) => { new DaemonClient_1.DaemonClient(c, this.mServer, this.mUser).run(); }); this.mServer.on('error', this.error.bind(this)); this.mServer.on('close', this.close.bind(this)); this.recordDaemonPid(); } } /** * Method to immediately parse or otherwise start the server for later processing from * incoming socket connections. * @memberof DaemonDecider */ runOrUseDaemon() { if (this.mServer) { if (process.platform !== "win32" && imperative_1.IO.existsSync(this.mSocket)) { imperative_1.IO.deleteFile(this.mSocket); } ["exit", "SIGINT", "SIGQUIT", "SIGTERM"].forEach((eventType) => { process.on(eventType, this.close.bind(this, true)); }); this.mServer.maxConnections = 1; this.mServer.listen(this.mSocket, () => { imperative_1.Imperative.api.appLogger.debug(`daemon server bound ${this.mSocket}`); new imperative_1.Console(`info`).info(`server bound ${this.mSocket}`); }); } else { imperative_1.Imperative.parse(); } } /** * Record the process ID of the daemon that is being started for the current user. * On a multi-user system, each user gets his/her own daemon. * * @private * @memberof DaemonDecider */ recordDaemonPid() { const pidForUser = { user: this.mUser, pid: process.pid }; const pidFilePath = path.join(DaemonUtil_1.DaemonUtil.getDaemonDir(), "daemon_pid.json"); const pidForUserStr = JSON.stringify(pidForUser, null, 2); try { fs.writeFileSync(pidFilePath, pidForUserStr); const ownerReadWrite = 0o600; fs.chmodSync(pidFilePath, ownerReadWrite); } catch (err) { throw new Error("Failed to write file '" + pidFilePath + "'\nDetails = " + err.message); } imperative_1.Imperative.api.appLogger.trace("Recorded daemon process ID into " + pidFilePath + "\n" + pidForUserStr); } /** * Server close handler * @private * @memberof DaemonDecider */ close(shouldExit) { imperative_1.Imperative.api.appLogger.debug(`server closed`); if (shouldExit) { process.exit(); } } /** * Server error handler * @private * @param {Error} err * @memberof DaemonDecider */ error(err) { imperative_1.Imperative.api.appLogger.error(`daemon server error: ${err.message}`); throw err; } /** * Perform initial parsing of undocumented parameters * @private * @memberof DaemonDecider */ initialParse() { var _a, _b; if (this.mParms.length > 2) { /** * NOTE(Kelosky): For now, we use an undocumented parameter `--daemon`. If found first, * we bypass `yargs` and begin running this as a persistent Processor. */ const parm = this.mParms[2]; const daemonOffset = parm.indexOf(DaemonDecider.DAEMON_KEY); if (daemonOffset > -1) { this.startServer = true; this.mUser = os.userInfo().username; if (process.platform === "win32") { this.mUser = this.mUser.toLowerCase(); // On windows we use a pipe instead of a socket if (((_b = (_a = process.env) === null || _a === void 0 ? void 0 : _a.ZOWE_DAEMON_PIPE) === null || _b === void 0 ? void 0 : _b.length) > 0) { // user can choose some pipe path this.mSocket = "\\\\.\\pipe\\" + process.env.ZOWE_DAEMON_PIPE; } else { // use default pipe path name this.mSocket = `\\\\.\\pipe\\${this.mUser}\\ZoweDaemon`; } } else { // Linux-like systems use domain sockets this.mSocket = path.join(DaemonUtil_1.DaemonUtil.getDaemonDir(), "daemon.sock"); } imperative_1.Imperative.api.appLogger.debug(`daemon server will listen on ${this.mSocket}`); } } } /** * Get whether or not to start the server * @private * @memberof DaemonDecider */ get startServer() { return this.mStartServer; } /** * Set whether or not to start the server * @private * @memberof DaemonDecider */ set startServer(startServer) { this.mStartServer = startServer; } } exports.DaemonDecider = DaemonDecider; /** * Undocumented paramter for launching in server mode * @private * @static * @memberof DaemonDecider */ DaemonDecider.DAEMON_KEY = "--daemon"; //# sourceMappingURL=DaemonDecider.js.map