ssh-client-wrapper 1.8.0 → 1.8.1

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/lib/fork.js CHANGED
@@ -62,9 +62,10 @@ function getMasterPty(hostInfo) {
62
62
  }
63
63
 
64
64
  async function fork(hostInfo, cmd, args, outputCallback) {
65
- return new Promise((resolve, reject)=>{
65
+ let ptyProcess = null;
66
+ const p = new Promise((resolve, reject)=>{
66
67
  debug(`cmd=${cmd}: args=${args}`);
67
- const ptyProcess = spawn(cmd, args, nodePtyOpt);
68
+ ptyProcess = spawn(cmd, args, nodePtyOpt);
68
69
  ptyProcess.onData(buff2String.bind(null, debugVerbose));
69
70
  ptyProcess.onData((data)=>{
70
71
  const output = data.toString();
@@ -97,6 +98,8 @@ async function fork(hostInfo, cmd, args, outputCallback) {
97
98
  return reject(err);
98
99
  });
99
100
  });
101
+ p.pty = ptyProcess;
102
+ return p;
100
103
  }
101
104
  module.exports = {
102
105
  fork,
package/lib/sshExec.js CHANGED
@@ -64,6 +64,9 @@ async function canConnect(hostInfo, timeout = 60) {
64
64
  * @returns {boolean} - true if master session exists
65
65
  */
66
66
  async function existsMaster(hostInfo) {
67
+ const ac = new AbortController();
68
+ const signal = ac.signal;
69
+
67
70
  const args = getSshOption(hostInfo);
68
71
  args.push("-Ocheck");
69
72
 
@@ -72,16 +75,38 @@ async function existsMaster(hostInfo) {
72
75
  output += e;
73
76
  };
74
77
 
78
+ let rt = true; //if timeout occurred during ssh -Ocheck, it will turn to false
79
+ let p;
80
+ const timeout = hostInfo.ConnectTimeout || 60;
81
+ setTimeoutPromise(timeout * 1000, "neverUsedValue", { signal })
82
+ .then(()=>{
83
+ if (p.pty) {
84
+ p.pty.kill();
85
+ }
86
+ rt = false;
87
+ })
88
+ .catch((err)=>{
89
+ if (err.name === "AbortError") {
90
+ debug("timeout was aborted because master session check has done");
91
+ } else {
92
+ throw err;
93
+ }
94
+ });
95
+
96
+
75
97
  try {
76
98
  debug(`check master session: ${sshCmd} ${args.join(" ")}`);
77
- await fork(hostInfo, sshCmd, args, cb);
99
+ p = fork(hostInfo, sshCmd, args, cb);
100
+ await p;
101
+ ac.abort();
78
102
  } catch (err) {
79
103
  if (err.rt !== 255) {
80
104
  debug("check master session failed", err);
81
105
  throw err;
82
106
  }
83
107
  }
84
- return !/Control socket connect.*: No such file or directory/.test(output);
108
+
109
+ return rt && !/Control socket connect.*: No such file or directory/.test(output);
85
110
  }
86
111
 
87
112
  /**
@@ -94,8 +119,13 @@ async function connect(hostInfo, timeout = 60) {
94
119
  return;
95
120
  }
96
121
  debug(`create master ssh session to ${hostInfo.host}`);
97
- const pty = getMasterPty(hostInfo);
98
- hostInfo.masterPty = pty;
122
+
123
+ if (!hostInfo.masterPty) {
124
+ debug(`create master pty for ${hostInfo.host}`);
125
+ hostInfo.masterPty = getMasterPty(hostInfo);
126
+ } else {
127
+ debug(`master pty for ${hostInfo.host} exists`);
128
+ }
99
129
 
100
130
  const ac = new AbortController();
101
131
  const signal = ac.signal;
@@ -105,8 +135,8 @@ async function connect(hostInfo, timeout = 60) {
105
135
  err.host = hostInfo.host;
106
136
  err.user = hostInfo.user;
107
137
  err.port = hostInfo.port;
108
- pty.write("\n");
109
- pty.write("exit\n");
138
+ hostInfo.masterPty.write("\n");
139
+ hostInfo.masterPty.write("exit\n");
110
140
  throw err;
111
141
  })
112
142
  .catch((err)=>{
@@ -119,8 +149,9 @@ async function connect(hostInfo, timeout = 60) {
119
149
  const re = new RegExp(`^${words}`);
120
150
  const p = new Promise((resolve, reject)=>{
121
151
  let done = false;
122
- pty.onData((data)=>{
152
+ hostInfo.masterPty.onData((data)=>{
123
153
  if (done) {
154
+ //safeguard
124
155
  return;
125
156
  }
126
157
  const output = data.toString();
@@ -128,7 +159,7 @@ async function connect(hostInfo, timeout = 60) {
128
159
 
129
160
  if (re.test(output)) {
130
161
  debug("test done. call exit on remotehost");
131
- pty.write("exit\n");
162
+ hostInfo.masterPty.write("exit\n");
132
163
  done = true;
133
164
  resolve();
134
165
  } else if (/Permission denied \(/.test(output)) {
@@ -141,7 +172,7 @@ async function connect(hostInfo, timeout = 60) {
141
172
  reject(new Error("Operation timed out"));
142
173
  }
143
174
  });
144
- pty.onExit((e)=>{
175
+ hostInfo.masterPty.onExit((e)=>{
145
176
  debug("master pty exit", e);
146
177
  resolve(e);
147
178
  });
@@ -151,7 +182,7 @@ async function connect(hostInfo, timeout = 60) {
151
182
  args.push(`echo ${words}`);
152
183
  const cmd = `${sshCmd} ${args.join(" ")}\n`;
153
184
  debugVerbose(cmd);
154
- pty.write(cmd);
185
+ hostInfo.masterPty.write(cmd);
155
186
  await p;
156
187
  ac.abort();
157
188
  debug(`connected to ${hostInfo.host}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ssh-client-wrapper",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "wrapper library for open ssh client and rsync",
5
5
  "keywords": [
6
6
  "ssh",