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 faad4a4e..2a1bc0e7 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 @@ -4,13 +4,13 @@ import path from 'path'; import _ from 'lodash'; import { ILogger } from '@certd/pipeline'; import iconv from 'iconv-lite'; -import {SshAccess} from "../access"; +import { SshAccess } from '../access'; export class AsyncSsh2Client { conn: ssh2.Client; logger: ILogger; connConf: ssh2.ConnectConfig; - windows:boolean = false; - encoding:string; + windows = false; + encoding: string; constructor(connConf: SshAccess, logger: ILogger) { this.connConf = connConf; this.logger = logger; @@ -19,7 +19,7 @@ export class AsyncSsh2Client { } convert(buffer: Buffer) { - if(this.encoding){ + if (this.encoding) { return iconv.decode(buffer, this.encoding); } return buffer.toString(); @@ -77,7 +77,7 @@ export class AsyncSsh2Client { reject(err); return; } - let data: string = ''; + let data = ''; stream .on('close', (code: any, signal: any) => { this.logger.info(`[${this.connConf.host}][close]:code:${code}`); @@ -88,14 +88,16 @@ export class AsyncSsh2Client { } }) .on('data', (ret: Buffer) => { - const out = this.convert(ret) - data += out + const out = this.convert(ret); + data += out; this.logger.info(`[${this.connConf.host}][info]: ` + out.trimEnd()); }) - .stderr.on('data', (ret:Buffer) => { - const err = this.convert(ret) - data += err - this.logger.info(`[${this.connConf.host}][error]: ` + err.trimEnd()); + .stderr.on('data', (ret: Buffer) => { + const err = this.convert(ret); + data += err; + this.logger.info( + `[${this.connConf.host}][error]: ` + err.trimEnd() + ); }); }); }); @@ -118,15 +120,15 @@ export class AsyncSsh2Client { resolve(output); }) .on('data', (ret: Buffer) => { - const data = this.convert(ret) + const data = this.convert(ret); this.logger.info('' + data); output.push(data); }) - .stderr.on('data', (ret:Buffer) => { - const data = this.convert(ret) + .stderr.on('data', (ret: Buffer) => { + const data = this.convert(ret); output.push(data); this.logger.info(`[${this.connConf.host}][error]: ` + data); - }); + }); stream.end(script + '\nexit\n'); }); }); @@ -153,30 +155,39 @@ export class SshClient { } * @param options */ - async uploadFiles(options: { connectConf: SshAccess; transports: any }) { - const { connectConf, transports } = options; + async uploadFiles(options: { + connectConf: SshAccess; + transports: any; + mkdirs: boolean; + }) { + const { connectConf, transports, mkdirs } = options; await this._call({ connectConf, callable: async (conn: AsyncSsh2Client) => { const sftp = await conn.getSftp(); this.logger.info('开始上传'); for (const transport of transports) { - let filePath = path.dirname(transport.remotePath); - let mkdirCmd = `mkdir -p ${filePath} `; - if(conn.windows){ - if(filePath.indexOf("/") > -1){ - this.logger.info("--------------------------") - this.logger.info("请注意:windows下,文件目录分隔应该写成\\而不是/") - this.logger.info("--------------------------") - } - const spec = await conn.exec(`echo %COMSPEC%`); - if (spec.toString().trim() === '%COMSPEC%') { - mkdirCmd = `New-Item -ItemType Directory -Path "${filePath}" -Force`; - } else { - mkdirCmd = `if not exist "${filePath}" mkdir "${filePath}"`; + if (mkdirs !== false) { + const filePath = path.dirname(transport.remotePath); + let mkdirCmd = `mkdir -p ${filePath} `; + if (conn.windows) { + if (filePath.indexOf('/') > -1) { + this.logger.info('--------------------------'); + this.logger.info( + '请注意:windows下,文件目录分隔应该写成\\而不是/' + ); + this.logger.info('--------------------------'); + } + const spec = await conn.exec('echo %COMSPEC%'); + if (spec.toString().trim() === '%COMSPEC%') { + mkdirCmd = `New-Item -ItemType Directory -Path "${filePath}" -Force`; + } else { + mkdirCmd = `if not exist "${filePath}" mkdir "${filePath}"`; + } } + await conn.exec(mkdirCmd); } - await conn.exec(mkdirCmd); + await conn.fastPut({ sftp, ...transport }); } this.logger.info('文件全部上传成功'); diff --git a/packages/ui/certd-server/src/plugins/plugin-host/plugin/upload-to-host/index.ts b/packages/ui/certd-server/src/plugins/plugin-host/plugin/upload-to-host/index.ts index dc0a0650..2cd8aa1c 100644 --- a/packages/ui/certd-server/src/plugins/plugin-host/plugin/upload-to-host/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-host/plugin/upload-to-host/index.ts @@ -48,6 +48,7 @@ export class UploadCertToHostPlugin extends AbstractTaskPlugin { required: true, }) cert!: CertInfo; + @TaskInput({ title: '主机登录配置', helper: 'access授权', @@ -59,13 +60,24 @@ export class UploadCertToHostPlugin extends AbstractTaskPlugin { }) accessId!: string; + @TaskInput({ + title: '自动创建远程目录', + helper: '是否自动创建远程目录,如果关闭则你需要自己确保远程目录存在', + default: true, + component: { + name: 'a-switch', + vModel: 'checked', + }, + }) + mkdirs = true; + @TaskInput({ title: '仅复制到当前主机', helper: '开启后,将直接复制到当前主机某个目录,不上传到主机,由于是docker启动,实际上是复制到docker容器内的“证书保存路径”,你需要事先在docker-compose.yaml中配置主机目录映射: volumes: /your_target_path:/your_target_path', + default: false, component: { name: 'a-switch', - default: false, vModel: 'checked', }, }) @@ -135,6 +147,7 @@ export class UploadCertToHostPlugin extends AbstractTaskPlugin { remotePath: keyPath, }, ], + mkdirs: this.mkdirs, }); this.logger.info( '证书上传成功:crtPath=',