@akash-chowdhury-24/deployhub 2.0.43 → 2.0.44
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/package.json
CHANGED
|
@@ -218,7 +218,24 @@ export function createDockerProvider(config, envName, env = process.env) {
|
|
|
218
218
|
await session.exec(ssh, cmds.pull, {
|
|
219
219
|
timeoutMs: Math.max(session.defaultExecTimeoutMs, 300_000),
|
|
220
220
|
});
|
|
221
|
-
|
|
221
|
+
// `docker rm -f` can return before the name is fully released on a
|
|
222
|
+
// contended dockerd (`--rm` + stop). Re-rm immediately before run and
|
|
223
|
+
// retry name conflicts instead of failing a good deploy.
|
|
224
|
+
let lastRunErr;
|
|
225
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
226
|
+
await session.exec(ssh, cmds.rm);
|
|
227
|
+
try {
|
|
228
|
+
await session.exec(ssh, cmds.run);
|
|
229
|
+
lastRunErr = null;
|
|
230
|
+
break;
|
|
231
|
+
} catch (err) {
|
|
232
|
+
lastRunErr = err;
|
|
233
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
234
|
+
if (!/already in use|Conflict/i.test(msg) || attempt === 3) throw err;
|
|
235
|
+
await new Promise((r) => setTimeout(r, 1000 * attempt));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (lastRunErr) throw lastRunErr;
|
|
222
239
|
const inspected = await session.execUnchecked(
|
|
223
240
|
ssh,
|
|
224
241
|
buildDockerInspectPortsCommand(containerName)
|
|
@@ -80,7 +80,8 @@ export function createSshProvider(config, envName, env = process.env) {
|
|
|
80
80
|
const { connect, exec, defaultExecTimeoutMs } = session;
|
|
81
81
|
const startStopTimeoutMs = Math.min(
|
|
82
82
|
defaultExecTimeoutMs,
|
|
83
|
-
Number(env.DEPLOYHUB_SSH_START_TIMEOUT_MS) ||
|
|
83
|
+
Number(env.DEPLOYHUB_SSH_START_TIMEOUT_MS || process.env.DEPLOYHUB_SSH_START_TIMEOUT_MS) ||
|
|
84
|
+
60_000
|
|
84
85
|
);
|
|
85
86
|
|
|
86
87
|
/**
|
|
@@ -28,8 +28,12 @@ export function createSshExecSession(opts) {
|
|
|
28
28
|
const log = opts.log || { info() {}, error() {} };
|
|
29
29
|
|
|
30
30
|
// Defense-in-depth: never let a stuck SSH channel hang CI indefinitely.
|
|
31
|
-
// Override with DEPLOYHUB_SSH_EXEC_TIMEOUT_MS (ms).
|
|
32
|
-
|
|
31
|
+
// Override with DEPLOYHUB_SSH_EXEC_TIMEOUT_MS (ms). Production default is 120s.
|
|
32
|
+
// Fall back to process.env so sparse credential overlays in tests/CI do not
|
|
33
|
+
// drop a process-level timeout override.
|
|
34
|
+
const defaultExecTimeoutMs =
|
|
35
|
+
Number(env.DEPLOYHUB_SSH_EXEC_TIMEOUT_MS || process.env.DEPLOYHUB_SSH_EXEC_TIMEOUT_MS) ||
|
|
36
|
+
120_000;
|
|
33
37
|
|
|
34
38
|
async function connect() {
|
|
35
39
|
if (!host || !user) {
|
|
@@ -109,15 +109,36 @@ export function createDockerImageDeployContext(config, env = process.env, log) {
|
|
|
109
109
|
if (!hasRegistryCredentials()) return;
|
|
110
110
|
const registry = registryUrl || 'https://index.docker.io/v1/';
|
|
111
111
|
log.info('Logging in to container registry...');
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
const attempts = 3;
|
|
113
|
+
const loopback = /^(127\.0\.0\.1|localhost|\[::1\])/i.test(String(registry));
|
|
114
|
+
let lastErr;
|
|
115
|
+
for (let i = 1; i <= attempts; i++) {
|
|
116
|
+
try {
|
|
117
|
+
await execa(
|
|
118
|
+
'docker',
|
|
119
|
+
['login', registry, '-u', registryUser, '--password-stdin'],
|
|
120
|
+
{
|
|
121
|
+
input: registryToken,
|
|
122
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
123
|
+
env: getDockerEnv(),
|
|
124
|
+
timeout: 60_000,
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
return;
|
|
128
|
+
} catch (err) {
|
|
129
|
+
lastErr = err;
|
|
130
|
+
const execErr = /** @type {{ message?: string, stderr?: string, stdout?: string }} */ (err);
|
|
131
|
+
const combined = `${execErr?.message || ''} ${execErr?.stderr || ''} ${execErr?.stdout || ''}`;
|
|
132
|
+
const transient =
|
|
133
|
+
/timeout|deadline exceeded|connection refused|tls handshake|i\/o timeout|eof|reset by peer|502|503/i.test(
|
|
134
|
+
combined
|
|
135
|
+
);
|
|
136
|
+
if (i === attempts || (!transient && !loopback)) throw err;
|
|
137
|
+
log.warn(`docker login attempt ${i}/${attempts} failed, retrying...`);
|
|
138
|
+
await new Promise((r) => setTimeout(r, 2000 * i));
|
|
119
139
|
}
|
|
120
|
-
|
|
140
|
+
}
|
|
141
|
+
throw lastErr;
|
|
121
142
|
}
|
|
122
143
|
|
|
123
144
|
/**
|