ssh-client-wrapper 2.2.3 → 2.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +1 -0
- package/.eslintrc.json +24 -153
- package/Dockerfile +4 -6
- package/Dockerfile-bullseye +7 -0
- package/Dockerfile-buster +7 -0
- package/README.md +0 -6
- package/docker-compose.yml +23 -3
- package/lib/fork.js +12 -12
- package/lib/index.js +11 -41
- package/lib/rsyncExec.js +9 -9
- package/lib/sshExec.js +23 -23
- package/lib/util.js +17 -14
- package/package.json +8 -7
- package/run_test_all.sh +11 -0
- package/test/interface.js +48 -50
- package/test/rsyncExec.js +72 -73
- package/test/sshExec.js +40 -40
- package/test/testUtil/testFiles.js +7 -8
- package/test/util.js +12 -13
package/.dockerignore
CHANGED
package/.eslintrc.json
CHANGED
|
@@ -1,163 +1,34 @@
|
|
|
1
1
|
{
|
|
2
|
-
"root": true,
|
|
3
|
-
"extends": [
|
|
4
|
-
"eslint"
|
|
5
|
-
],
|
|
6
|
-
"plugins": [
|
|
7
|
-
"node",
|
|
8
|
-
"jsdoc"
|
|
9
|
-
],
|
|
10
2
|
"env": {
|
|
11
|
-
"
|
|
12
|
-
"
|
|
3
|
+
"browser": true,
|
|
4
|
+
"commonjs": true,
|
|
5
|
+
"es2021": true
|
|
13
6
|
},
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
],
|
|
20
|
-
"arrow-body-style": [
|
|
21
|
-
"error",
|
|
22
|
-
"always"
|
|
23
|
-
],
|
|
24
|
-
"arrow-spacing": [
|
|
25
|
-
"error",
|
|
26
|
-
{
|
|
27
|
-
"before": false,
|
|
28
|
-
"after": false
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
"camelcase": [
|
|
32
|
-
"error",
|
|
33
|
-
{
|
|
34
|
-
"properties": "never"
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
"eqeqeq": [
|
|
38
|
-
"error",
|
|
39
|
-
"always",
|
|
40
|
-
{
|
|
41
|
-
"null": "ignore"
|
|
42
|
-
}
|
|
43
|
-
],
|
|
44
|
-
"func-style": [
|
|
45
|
-
"error",
|
|
46
|
-
"declaration",
|
|
47
|
-
{
|
|
48
|
-
"allowArrowFunctions": true
|
|
49
|
-
}
|
|
50
|
-
],
|
|
51
|
-
"indent": [
|
|
52
|
-
"error",
|
|
53
|
-
2,
|
|
54
|
-
{
|
|
55
|
-
"SwitchCase": 1
|
|
56
|
-
}
|
|
57
|
-
],
|
|
58
|
-
"lines-around-comment": [
|
|
59
|
-
"error",
|
|
60
|
-
{
|
|
61
|
-
"beforeBlockComment": true,
|
|
62
|
-
"beforeLineComment": false
|
|
63
|
-
}
|
|
64
|
-
],
|
|
65
|
-
"lines-between-class-members": [
|
|
66
|
-
"error",
|
|
67
|
-
"always",
|
|
68
|
-
{
|
|
69
|
-
"exceptAfterSingleLine": true
|
|
70
|
-
}
|
|
71
|
-
],
|
|
72
|
-
"newline-per-chained-call": "error",
|
|
73
|
-
"no-use-before-define": [
|
|
74
|
-
"error",
|
|
75
|
-
{
|
|
76
|
-
"functions": false
|
|
77
|
-
}
|
|
78
|
-
],
|
|
79
|
-
"no-warning-comments": "warn",
|
|
80
|
-
"padded-blocks": [
|
|
81
|
-
"error",
|
|
82
|
-
"never"
|
|
83
|
-
],
|
|
84
|
-
"padding-line-between-statements": [
|
|
85
|
-
"error",
|
|
86
|
-
{
|
|
87
|
-
"blankLine": "any",
|
|
88
|
-
"prev": [
|
|
89
|
-
"const",
|
|
90
|
-
"let",
|
|
91
|
-
"var"
|
|
92
|
-
],
|
|
93
|
-
"next": "*"
|
|
7
|
+
"extends": ["standard"],
|
|
8
|
+
"overrides": [
|
|
9
|
+
{
|
|
10
|
+
"env": {
|
|
11
|
+
"node": true
|
|
94
12
|
},
|
|
95
|
-
|
|
96
|
-
"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"class",
|
|
101
|
-
"do",
|
|
102
|
-
"for",
|
|
103
|
-
"function",
|
|
104
|
-
"multiline-block-like",
|
|
105
|
-
"switch",
|
|
106
|
-
"try",
|
|
107
|
-
"while"
|
|
108
|
-
]
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"blankLine": "any",
|
|
112
|
-
"prev": [
|
|
113
|
-
"const",
|
|
114
|
-
"let",
|
|
115
|
-
"var",
|
|
116
|
-
"for",
|
|
117
|
-
"while",
|
|
118
|
-
"do",
|
|
119
|
-
"block-like",
|
|
120
|
-
"multiline-block-like"
|
|
121
|
-
],
|
|
122
|
-
"next": [
|
|
123
|
-
"block-like",
|
|
124
|
-
"do",
|
|
125
|
-
"for",
|
|
126
|
-
"multiline-block-like",
|
|
127
|
-
"switch",
|
|
128
|
-
"try",
|
|
129
|
-
"while"
|
|
130
|
-
]
|
|
13
|
+
"files": [
|
|
14
|
+
".eslintrc.{js,cjs}"
|
|
15
|
+
],
|
|
16
|
+
"parserOptions": {
|
|
17
|
+
"sourceType": "script"
|
|
131
18
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
"module.exports"
|
|
140
|
-
],
|
|
141
|
-
"require-unicode-regexp": "off",
|
|
142
|
-
"node/no-unsupported-features": [
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"parserOptions": {
|
|
22
|
+
"ecmaVersion": "latest"
|
|
23
|
+
},
|
|
24
|
+
"rules": {
|
|
25
|
+
"semi": [
|
|
143
26
|
"error",
|
|
144
|
-
{
|
|
145
|
-
"version": 10
|
|
146
|
-
}
|
|
147
|
-
],
|
|
148
|
-
"jsdoc/require-hyphen-before-param-description": [
|
|
149
|
-
"warn",
|
|
150
27
|
"always"
|
|
151
28
|
],
|
|
152
|
-
"
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
"jsdoc/require-jsdoc": "off",
|
|
157
|
-
"jsdoc/require-param": "off",
|
|
158
|
-
"jsdoc/require-returns": "off"
|
|
159
|
-
},
|
|
160
|
-
"parserOptions": {
|
|
161
|
-
"ecmaVersion": 2018
|
|
29
|
+
"quotes": [
|
|
30
|
+
"error",
|
|
31
|
+
"double"
|
|
32
|
+
]
|
|
162
33
|
}
|
|
163
34
|
}
|
package/Dockerfile
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# syntax=docker/dockerfile:1
|
|
2
|
-
FROM --platform=linux/amd64 node:
|
|
3
|
-
#FROM --platform=linux/amd64 node:hydrogen-bullseye-slim
|
|
4
|
-
#FROM --platform=linux/amd64 node:hydrogen-buster-slim
|
|
2
|
+
FROM --platform=linux/amd64 node:20-bookworm-slim
|
|
5
3
|
|
|
6
|
-
WORKDIR /work
|
|
4
|
+
WORKDIR /work/ssh-client-wrapper
|
|
7
5
|
RUN apt-get update && apt -y install ssh rsync bzip2 python3 g++ build-essential
|
|
8
|
-
COPY ./
|
|
9
|
-
RUN
|
|
6
|
+
COPY ./ ./
|
|
7
|
+
RUN npm install
|
package/README.md
CHANGED
|
@@ -4,9 +4,3 @@
|
|
|
4
4
|
[](https://codeclimate.com/github/so5/ssh-client-wrapper/maintainability)
|
|
5
5
|
# ssh-client-wrapper
|
|
6
6
|
open ssh client wrapper library for nodejs
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# how to test on local machine
|
|
10
|
-
```
|
|
11
|
-
docker-compose up --build
|
|
12
|
-
```
|
package/docker-compose.yml
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
version: "3.8"
|
|
2
2
|
services:
|
|
3
|
-
|
|
3
|
+
testbed:
|
|
4
4
|
image: naoso5/test-sshd
|
|
5
5
|
ports:
|
|
6
|
-
- 4000:22
|
|
6
|
+
- "4000:22"
|
|
7
7
|
container_name: testbed
|
|
8
8
|
tester:
|
|
9
9
|
build:
|
|
@@ -14,4 +14,24 @@ services:
|
|
|
14
14
|
TEST_PW: passw0rd
|
|
15
15
|
TEST_HOST: testbed
|
|
16
16
|
working_dir: /work/ssh-client-wrapper
|
|
17
|
-
command: bash -c "mkdir /root/.ssh 2>/dev/null; npm run
|
|
17
|
+
command: bash -c "mkdir /root/.ssh 2>/dev/null; npm run mocha"
|
|
18
|
+
tester-bullseye:
|
|
19
|
+
build:
|
|
20
|
+
context: .
|
|
21
|
+
dockerfile: Dockerfile-bullseye
|
|
22
|
+
environment:
|
|
23
|
+
TEST_USER: testuser
|
|
24
|
+
TEST_PW: passw0rd
|
|
25
|
+
TEST_HOST: testbed
|
|
26
|
+
working_dir: /work/ssh-client-wrapper
|
|
27
|
+
command: bash -c "mkdir /root/.ssh 2>/dev/null; npm run mocha"
|
|
28
|
+
tester-buster:
|
|
29
|
+
build:
|
|
30
|
+
context: .
|
|
31
|
+
dockerfile: Dockerfile-buster
|
|
32
|
+
environment:
|
|
33
|
+
TEST_USER: testuser
|
|
34
|
+
TEST_PW: passw0rd
|
|
35
|
+
TEST_HOST: testbed
|
|
36
|
+
working_dir: /work/ssh-client-wrapper
|
|
37
|
+
command: bash -c "mkdir /root/.ssh 2>/dev/null; npm run mocha"
|
package/lib/fork.js
CHANGED
|
@@ -11,8 +11,8 @@ const nodePtyOpt = {
|
|
|
11
11
|
windowsHide: true
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
function sshLoginCallback(output, ptyProcess, pw, ph, logger = debugSendPty) {
|
|
15
|
-
return new Promise((resolve, reject)=>{
|
|
14
|
+
function sshLoginCallback (output, ptyProcess, pw, ph, logger = debugSendPty) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
16
|
if (reNewHostPrompt.test(output)) {
|
|
17
17
|
sendPty(ptyProcess, "yes\n", logger, 17);
|
|
18
18
|
resolve();
|
|
@@ -26,10 +26,10 @@ function sshLoginCallback(output, ptyProcess, pw, ph, logger = debugSendPty) {
|
|
|
26
26
|
if (typeof pw === "function") {
|
|
27
27
|
debug("call password callback function");
|
|
28
28
|
pw()
|
|
29
|
-
.then((v)=>{
|
|
29
|
+
.then((v) => {
|
|
30
30
|
sendPty(ptyProcess, `${v}\n`, logger, 30);
|
|
31
31
|
})
|
|
32
|
-
.catch((e)=>{
|
|
32
|
+
.catch((e) => {
|
|
33
33
|
reject(e);
|
|
34
34
|
});
|
|
35
35
|
resolve();
|
|
@@ -44,10 +44,10 @@ function sshLoginCallback(output, ptyProcess, pw, ph, logger = debugSendPty) {
|
|
|
44
44
|
if (typeof ph === "function") {
|
|
45
45
|
debug("call passphrase callback function");
|
|
46
46
|
ph()
|
|
47
|
-
.then((v)=>{
|
|
47
|
+
.then((v) => {
|
|
48
48
|
sendPty(ptyProcess, `${v}\n`, logger, 45);
|
|
49
49
|
})
|
|
50
|
-
.catch((e)=>{
|
|
50
|
+
.catch((e) => {
|
|
51
51
|
reject(e);
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -58,7 +58,7 @@ function sshLoginCallback(output, ptyProcess, pw, ph, logger = debugSendPty) {
|
|
|
58
58
|
/**
|
|
59
59
|
* create pty for master ssh session and store to hostInfo.masterPty
|
|
60
60
|
*/
|
|
61
|
-
function createMasterPty(hostInfo) {
|
|
61
|
+
function createMasterPty (hostInfo) {
|
|
62
62
|
debug("fork pty for master connection");
|
|
63
63
|
|
|
64
64
|
if (hostInfo.masterPty) {
|
|
@@ -69,13 +69,13 @@ function createMasterPty(hostInfo) {
|
|
|
69
69
|
hostInfo.masterPty = ptyProcess;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
async function fork(hostInfo, cmd, args, timeout, outputCallback) {
|
|
73
|
-
return new Promise((resolve, reject)=>{
|
|
72
|
+
async function fork (hostInfo, cmd, args, timeout, outputCallback) {
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
74
|
debug(`cmd=${cmd}: args=${args}`);
|
|
75
75
|
const ptyProcess = spawn(cmd, args, nodePtyOpt);
|
|
76
76
|
let ac = null;
|
|
77
77
|
if (timeout > 0) {
|
|
78
|
-
ac = watchDogTimer(timeout, cmd, ()=>{
|
|
78
|
+
ac = watchDogTimer(timeout, cmd, () => {
|
|
79
79
|
ptyProcess.kill();
|
|
80
80
|
const err = new Error(`watchdog timer expired ${timeout}`);
|
|
81
81
|
err.code = "TIMEEXPIRE";
|
|
@@ -85,7 +85,7 @@ async function fork(hostInfo, cmd, args, timeout, outputCallback) {
|
|
|
85
85
|
ptyProcess.onData(buff2String.bind(null, debugVerbose));
|
|
86
86
|
|
|
87
87
|
if (hostInfo !== null) {
|
|
88
|
-
ptyProcess.onData(async (data)=>{
|
|
88
|
+
ptyProcess.onData(async (data) => {
|
|
89
89
|
const output = data.toString();
|
|
90
90
|
sshLoginCallback(output, ptyProcess, hostInfo.password, hostInfo.passphrase)
|
|
91
91
|
.catch(reject);
|
|
@@ -102,7 +102,7 @@ async function fork(hostInfo, cmd, args, timeout, outputCallback) {
|
|
|
102
102
|
if (typeof outputCallback === "function") {
|
|
103
103
|
ptyProcess.onData(buff2String.bind(null, outputCallback));
|
|
104
104
|
}
|
|
105
|
-
ptyProcess.onExit(({ exitCode, signal })=>{
|
|
105
|
+
ptyProcess.onExit(({ exitCode, signal }) => {
|
|
106
106
|
debug("onExit", exitCode, signal);
|
|
107
107
|
|
|
108
108
|
if (ac !== null) {
|
package/lib/index.js
CHANGED
|
@@ -32,7 +32,7 @@ const { isArrayOfString, sanityCheck } = require("./util.js");
|
|
|
32
32
|
* @param {string[]} hostInfo.sshOpt - additional options for ssh
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
|
-
const logAndReject = (message)=>{
|
|
35
|
+
const logAndReject = (message) => {
|
|
36
36
|
debug(message);
|
|
37
37
|
return Promise.reject(new Error(message));
|
|
38
38
|
};
|
|
@@ -42,11 +42,11 @@ const logAndReject = (message)=>{
|
|
|
42
42
|
* @constructor
|
|
43
43
|
*/
|
|
44
44
|
class SshClientWrapper {
|
|
45
|
-
constructor(hostInfo) {
|
|
45
|
+
constructor (hostInfo) {
|
|
46
46
|
debug("constructor called for", hostInfo.host);
|
|
47
47
|
debugVerbose("hostInfo=", hostInfo);
|
|
48
|
-
sanityCheck(hostInfo);
|
|
49
48
|
this.hostInfo = { ...hostInfo };
|
|
49
|
+
sanityCheck(this.hostInfo);
|
|
50
50
|
this.hostInfo.masterPty = null;
|
|
51
51
|
this.hostInfo.rsyncVersion = null;
|
|
52
52
|
|
|
@@ -67,10 +67,8 @@ class SshClientWrapper {
|
|
|
67
67
|
* @param {Integer} timeout - timeout in secconds
|
|
68
68
|
* @param { Function } outputCallback - call back routine for output
|
|
69
69
|
* @returns {Integer} - Return code of cmd.
|
|
70
|
-
*
|
|
71
|
-
* If stdout and stderr is array, last 5 line of stdout and stderr is stored in them.
|
|
72
70
|
*/
|
|
73
|
-
async exec(cmd, timeout = 0, outputCallback = null) {
|
|
71
|
+
async exec (cmd, timeout = 0, outputCallback = null) {
|
|
74
72
|
debug("exec called", cmd);
|
|
75
73
|
|
|
76
74
|
if (typeof cmd !== "string" || cmd === "") {
|
|
@@ -79,7 +77,6 @@ class SshClientWrapper {
|
|
|
79
77
|
return sshExec(this.hostInfo, cmd, timeout, outputCallback);
|
|
80
78
|
}
|
|
81
79
|
|
|
82
|
-
|
|
83
80
|
/**
|
|
84
81
|
* execute ls command and return output
|
|
85
82
|
* @param {string} target - file or directory path to watch
|
|
@@ -87,38 +84,11 @@ class SshClientWrapper {
|
|
|
87
84
|
* @param {Integer} timeout - timeout in secconds
|
|
88
85
|
* @returns {string[]} - output from ls
|
|
89
86
|
*/
|
|
90
|
-
async ls(target, lsOpt = [], timeout = 0) {
|
|
87
|
+
async ls (target, lsOpt = [], timeout = 0) {
|
|
91
88
|
debug("ls called", target, lsOpt);
|
|
92
89
|
return ls(this.hostInfo, target, lsOpt, timeout);
|
|
93
90
|
}
|
|
94
91
|
|
|
95
|
-
/**
|
|
96
|
-
* Execute command repeatedly until specified keyword is found in stdout and/or stderr.
|
|
97
|
-
* @param {string} cmd - Cmdline which will be executed.
|
|
98
|
-
* @param {RegExp} regexp - End condition.
|
|
99
|
-
* @param {number} retryDelay - Duration between each try (in sec).
|
|
100
|
-
* @param {number} maxRetry - Max retry count.
|
|
101
|
-
* @returns {Integer} - Return code of cmd.
|
|
102
|
-
*/
|
|
103
|
-
async watch(cmd, regexp, retryDelay = 3, maxRetry = null) {
|
|
104
|
-
debug("watch called", cmd, regexp, retryDelay, maxRetry);
|
|
105
|
-
|
|
106
|
-
if (typeof cmd !== "string") {
|
|
107
|
-
return logAndReject("cmd must be string");
|
|
108
|
-
}
|
|
109
|
-
if (!(regexp instanceof RegExp)) {
|
|
110
|
-
const err = new Error("illegal regexp specified");
|
|
111
|
-
err.regexp = regexp;
|
|
112
|
-
err.cmd = cmd;
|
|
113
|
-
err.retryDelay = retryDelay;
|
|
114
|
-
err.maxRetry = maxRetry;
|
|
115
|
-
return Promise.reject(new Error("err"));
|
|
116
|
-
}
|
|
117
|
-
//not implemented yet !!!
|
|
118
|
-
return this.exec(cmd, ()=>{
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
92
|
/**
|
|
123
93
|
* Send file or directory and its child to server.
|
|
124
94
|
* @param {string[]} src - File or directory name which to be recieve.
|
|
@@ -127,13 +97,13 @@ class SshClientWrapper {
|
|
|
127
97
|
* @param {Integer} timeout - timeout in secconds
|
|
128
98
|
* @returns {Promise} - Resolved with undefined when file transfer is done.
|
|
129
99
|
*/
|
|
130
|
-
async send(src, dst, opt = [], timeout = 0) {
|
|
100
|
+
async send (src, dst, opt = [], timeout = 0) {
|
|
131
101
|
debug("send called", src, dst, opt);
|
|
132
102
|
|
|
133
103
|
if (!isArrayOfString(src)) {
|
|
134
104
|
return logAndReject("src must be array of string");
|
|
135
105
|
}
|
|
136
|
-
if (!src.some((e)=>{
|
|
106
|
+
if (!src.some((e) => {
|
|
137
107
|
return e !== "";
|
|
138
108
|
})) {
|
|
139
109
|
return logAndReject("src must contain non-empty string");
|
|
@@ -158,13 +128,13 @@ class SshClientWrapper {
|
|
|
158
128
|
* @param {Integer} timeout - timeout in secconds
|
|
159
129
|
* @returns {Promise} - Resolved with undefined when file transfer is done.
|
|
160
130
|
*/
|
|
161
|
-
async recv(src, dst, opt = [], timeout = 0) {
|
|
131
|
+
async recv (src, dst, opt = [], timeout = 0) {
|
|
162
132
|
debug("recv called", src, dst, opt);
|
|
163
133
|
|
|
164
134
|
if (!isArrayOfString(src)) {
|
|
165
135
|
return logAndReject("src must be array of string");
|
|
166
136
|
}
|
|
167
|
-
if (!src.some((e)=>{
|
|
137
|
+
if (!src.some((e) => {
|
|
168
138
|
return e !== "";
|
|
169
139
|
})) {
|
|
170
140
|
return logAndReject("src must contain non-empty string");
|
|
@@ -186,7 +156,7 @@ class SshClientWrapper {
|
|
|
186
156
|
* @param {Integer} timeout - timeout in secconds
|
|
187
157
|
* @returns {Promise} - Resolved with true on success, otherwise rejected with Error.
|
|
188
158
|
*/
|
|
189
|
-
async canConnect(timeout = 60) {
|
|
159
|
+
async canConnect (timeout = 60) {
|
|
190
160
|
debug("canConnect called with timeout=", timeout);
|
|
191
161
|
debugVerbose("hostInfo=", this.hostInfo);
|
|
192
162
|
|
|
@@ -199,7 +169,7 @@ class SshClientWrapper {
|
|
|
199
169
|
/**
|
|
200
170
|
* Disconnect master session
|
|
201
171
|
*/
|
|
202
|
-
async disconnect() {
|
|
172
|
+
async disconnect () {
|
|
203
173
|
debug(`disconnect from ${this.hostInfo.host} called`);
|
|
204
174
|
disconnect(this.hostInfo);
|
|
205
175
|
}
|
package/lib/rsyncExec.js
CHANGED
|
@@ -9,9 +9,9 @@ const { fork } = require("./fork.js");
|
|
|
9
9
|
|
|
10
10
|
const { sshCmd, rsyncCmd, getSshOption } = require("./util.js");
|
|
11
11
|
|
|
12
|
-
async function checkRsyncVersion(timeout) {
|
|
12
|
+
async function checkRsyncVersion (timeout) {
|
|
13
13
|
const rt = {};
|
|
14
|
-
await fork(null, rsyncCmd, ["--version"], timeout, (output)=>{
|
|
14
|
+
await fork(null, rsyncCmd, ["--version"], timeout, (output) => {
|
|
15
15
|
const result = /^rsync *version *(\d+)\.(\d+)\.(\d+).*$/m.exec(output);
|
|
16
16
|
|
|
17
17
|
if (result) {
|
|
@@ -33,13 +33,13 @@ async function checkRsyncVersion(timeout) {
|
|
|
33
33
|
*
|
|
34
34
|
* this function execute rsync -avv --copy-unsafe-links src rsync://[user@]host[:port]/dst
|
|
35
35
|
*/
|
|
36
|
-
async function send(hostInfo, argSrc, dst, rsyncOpt, timeout) {
|
|
36
|
+
async function send (hostInfo, argSrc, dst, rsyncOpt, timeout) {
|
|
37
37
|
await connect(hostInfo);
|
|
38
|
-
const promises = await Promise.allSettled(argSrc.map((e)=>{
|
|
38
|
+
const promises = await Promise.allSettled(argSrc.map((e) => {
|
|
39
39
|
return glob(e);
|
|
40
40
|
}));
|
|
41
41
|
const src = promises
|
|
42
|
-
.map((e, i)=>{
|
|
42
|
+
.map((e, i) => {
|
|
43
43
|
if (e.status !== "fulfilled") {
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
@@ -48,10 +48,10 @@ async function send(hostInfo, argSrc, dst, rsyncOpt, timeout) {
|
|
|
48
48
|
}
|
|
49
49
|
return e.value;
|
|
50
50
|
})
|
|
51
|
-
.filter((e)=>{
|
|
51
|
+
.filter((e) => {
|
|
52
52
|
return e !== null;
|
|
53
53
|
})
|
|
54
|
-
.flatMap((e)=>{
|
|
54
|
+
.flatMap((e) => {
|
|
55
55
|
return e;
|
|
56
56
|
});
|
|
57
57
|
|
|
@@ -87,7 +87,7 @@ async function send(hostInfo, argSrc, dst, rsyncOpt, timeout) {
|
|
|
87
87
|
* @param {Object} hostInfo - hostinfo object
|
|
88
88
|
* @returns {boolean} - rsync command version is higher than 3.2.4 or not
|
|
89
89
|
*/
|
|
90
|
-
async function isNewRsync(hostInfo) {
|
|
90
|
+
async function isNewRsync (hostInfo) {
|
|
91
91
|
if (!hostInfo.rsyncVersion ||
|
|
92
92
|
!Number.isInteger(hostInfo.rsyncVersion.major) ||
|
|
93
93
|
!Number.isInteger(hostInfo.rsyncVersion.minor) ||
|
|
@@ -107,7 +107,7 @@ async function isNewRsync(hostInfo) {
|
|
|
107
107
|
*
|
|
108
108
|
* this function execute rsync -av --copy-unsafe-links rsync://[user@]host[:port]/src dst
|
|
109
109
|
*/
|
|
110
|
-
async function recv(hostInfo, argSrc, dst, rsyncOpt, timeout) {
|
|
110
|
+
async function recv (hostInfo, argSrc, dst, rsyncOpt, timeout) {
|
|
111
111
|
await connect(hostInfo);
|
|
112
112
|
const src = `${hostInfo.host}:${argSrc.join(" ")}`;
|
|
113
113
|
const sshArgs = getSshOption(hostInfo, true);
|