From d5bfcdb6de1dcc1702155442e2e00237d0bbb6e5 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Wed, 4 Sep 2024 18:29:39 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8Dwindows=E4=B8=8B?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E6=89=A7=E8=A1=8C=E7=AC=AC=E4=BA=8C=E6=9D=A1?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/acme-client/src/index.js | 2 +- .../src/plugin/cert-plugin/acme.ts | 3 +- packages/ui/certd-server/package.json | 1 + .../src/plugins/plugin-host/lib/ssh.ts | 60 +++++++++++++++---- .../plugin/host-shell-execute/index.ts | 4 +- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/packages/core/acme-client/src/index.js b/packages/core/acme-client/src/index.js index 4e83c9f65..5c82b3f94 100644 --- a/packages/core/acme-client/src/index.js +++ b/packages/core/acme-client/src/index.js @@ -32,7 +32,7 @@ exports.directory = { */ exports.crypto = require('./crypto'); -exports.forge = require('./crypto/forge'); +// exports.forge = require('./crypto/forge'); /** * Axios diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/acme.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/acme.ts index d94fa515e..c9aa6e482 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/acme.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/acme.ts @@ -81,6 +81,7 @@ export class AcmeService { if (conf.key == null) { conf.key = await this.createNewKey(); await this.saveAccountConfig(email, conf); + this.logger.info(`创建新的Accountkey:${email}`); } let directoryUrl = ""; if (isTest) { @@ -124,7 +125,7 @@ export class AcmeService { } async createNewKey() { - const key = await acme.forge.createPrivateKey(); + const key = await acme.crypto.createPrivateKey(2048); return key.toString(); } diff --git a/packages/ui/certd-server/package.json b/packages/ui/certd-server/package.json index d5276c322..1b5a74893 100644 --- a/packages/ui/certd-server/package.json +++ b/packages/ui/certd-server/package.json @@ -64,6 +64,7 @@ "pg": "^8.12.0", "reflect-metadata": "^0.1.13", "ssh2": "^1.15.0", + "strip-ansi": "^7.1.0", "svg-captcha": "^1.4.0", "tencentcloud-sdk-nodejs": "^4.0.44", "typeorm": "^0.3.20" diff --git a/packages/ui/certd-server/src/plugins/plugin-host/lib/ssh.ts b/packages/ui/certd-server/src/plugins/plugin-host/lib/ssh.ts index 8cb304f15..fca1a52a2 100644 --- a/packages/ui/certd-server/src/plugins/plugin-host/lib/ssh.ts +++ b/packages/ui/certd-server/src/plugins/plugin-host/lib/ssh.ts @@ -3,8 +3,8 @@ import ssh2, { ConnectConfig } from 'ssh2'; import path from 'path'; import * as _ from 'lodash-es'; import { ILogger } from '@certd/pipeline'; -import iconv from 'iconv-lite'; import { SshAccess } from '../access/index.js'; +import stripAnsi from 'strip-ansi'; export class AsyncSsh2Client { conn: ssh2.Client; logger: ILogger; @@ -18,7 +18,7 @@ export class AsyncSsh2Client { this.encoding = connConf.encoding; } - convert(buffer: Buffer) { + convert(iconv: any, buffer: Buffer) { if (this.encoding) { return iconv.decode(buffer, this.encoding); } @@ -79,6 +79,7 @@ export class AsyncSsh2Client { this.logger.info('script 为空,取消执行'); return; } + const iconv = await import('iconv-lite'); return new Promise((resolve, reject) => { this.logger.info(`执行命令:[${this.connConf.host}][exec]: ` + script); this.conn.exec(script, (err: Error, stream: any) => { @@ -97,7 +98,7 @@ export class AsyncSsh2Client { } }) .on('data', (ret: Buffer) => { - const out = this.convert(ret); + const out = this.convert(iconv, ret); data += out; this.logger.info(`[${this.connConf.host}][info]: ` + out.trimEnd()); }) @@ -106,7 +107,7 @@ export class AsyncSsh2Client { this.logger.error(err); }) .stderr.on('data', (ret: Buffer) => { - const err = this.convert(ret); + const err = this.convert(iconv, ret); data += err; this.logger.info(`[${this.connConf.host}][error]: ` + err.trimEnd()); }); @@ -123,22 +124,33 @@ export class AsyncSsh2Client { return; } const output: string[] = []; + function ansiHandle(data: string) { + data = data.replace(/\[[0-9]+;1H/g, '\n'); + data = stripAnsi(data); + return data; + } stream .on('close', () => { this.logger.info('Stream :: close'); resolve(output); }) .on('data', (ret: Buffer) => { - const data = this.convert(ret); - this.logger.info('' + data); + const data = ansiHandle(ret.toString()); + this.logger.info(data); output.push(data); }) + .on('error', (err: any) => { + reject(err); + this.logger.error(err); + }) .stderr.on('data', (ret: Buffer) => { - const data = this.convert(ret); + const data = ansiHandle(ret.toString()); output.push(data); this.logger.info(`[${this.connConf.host}][error]: ` + data); }); - stream.end(script + '\nexit\n'); + //保证windows下正常退出 + const exit = '\r\nexit\r\n'; + stream.end(script + exit); }); }); } @@ -189,7 +201,7 @@ export class SshClient { mkdirCmd = `if not exist "${filePath}" mkdir "${filePath}"`; } } - await conn.exec(mkdirCmd); + await conn.shell(mkdirCmd); } await conn.fastPut({ sftp, ...transport }); @@ -204,9 +216,17 @@ export class SshClient { const { connectConf } = options; if (_.isArray(script)) { script = script as Array; - script = script.join('\n'); + if (connectConf.windows) { + script = script.join('\r\n'); + } else { + script = script.join('\n'); + } + } else { + if (connectConf.windows) { + script = script.replaceAll('\n', '\r\n'); + } } - this.logger.info('执行命令:', script); + this.logger.info('命令:', script); return await this._call({ connectConf, callable: async (conn: AsyncSsh2Client) => { @@ -215,8 +235,22 @@ export class SshClient { }); } - async shell(options: { connectConf: SshAccess; script: string }): Promise { - const { connectConf, script } = options; + //废弃 + async shell(options: { connectConf: SshAccess; script: string | Array }): Promise { + let { script } = options; + const { connectConf } = options; + if (_.isArray(script)) { + script = script as Array; + if (connectConf.windows) { + script = script.join('\r\n'); + } else { + script = script.join('\n'); + } + } else { + if (connectConf.windows) { + script = script.replaceAll('\n', '\r\n'); + } + } return await this._call({ connectConf, callable: async (conn: AsyncSsh2Client) => { diff --git a/packages/ui/certd-server/src/plugins/plugin-host/plugin/host-shell-execute/index.ts b/packages/ui/certd-server/src/plugins/plugin-host/plugin/host-shell-execute/index.ts index bc304d975..3800d1467 100644 --- a/packages/ui/certd-server/src/plugins/plugin-host/plugin/host-shell-execute/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-host/plugin/host-shell-execute/index.ts @@ -40,11 +40,11 @@ export class HostShellExecutePlugin extends AbstractTaskPlugin { const { script, accessId } = this; const connectConf = await this.accessService.getById(accessId); const sshClient = new SshClient(this.logger); - const ret = await sshClient.exec({ + await sshClient.shell({ connectConf, script, }); - this.logger.info('exec res:', ret); + // this.logger.info('exec res:', ret); } }