Fix DNS2 self-updater path and sync live dashboard version UI
This commit is contained in:
@@ -14,6 +14,9 @@ const {
|
|||||||
} = require('../input-validator');
|
} = require('../input-validator');
|
||||||
|
|
||||||
describe('Input Validator', () => {
|
describe('Input Validator', () => {
|
||||||
|
function fail(message) {
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
describe('ValidationError', () => {
|
describe('ValidationError', () => {
|
||||||
it('has correct name, message, field, and statusCode', () => {
|
it('has correct name, message, field, and statusCode', () => {
|
||||||
|
|||||||
@@ -524,9 +524,7 @@ describe('Health Routes', () => {
|
|||||||
it('returns error when no url parameter provided', async () => {
|
it('returns error when no url parameter provided', async () => {
|
||||||
const { app } = createApp();
|
const { app } = createApp();
|
||||||
const res = await request(app).get('/api/health/probe');
|
const res = await request(app).get('/api/health/probe');
|
||||||
// ValidationError is not imported at module scope, so this throws a ReferenceError
|
expect(res.status).toBe(400);
|
||||||
// which the error handler catches as a 500
|
|
||||||
expect(res.status).toBe(500);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -256,7 +256,9 @@ module.exports = function({ docker, caddy, servicesStateManager, portLockManager
|
|||||||
const existing = docker.client.getContainer(containerName);
|
const existing = docker.client.getContainer(containerName);
|
||||||
await existing.remove({ force: true });
|
await existing.remove({ force: true });
|
||||||
await new Promise(r => setTimeout(r, 1000));
|
await new Promise(r => setTimeout(r, 1000));
|
||||||
} catch (_) {}
|
} catch (_) {
|
||||||
|
// No stale container to remove
|
||||||
|
}
|
||||||
|
|
||||||
const container = await docker.client.createContainer(containerConfig);
|
const container = await docker.client.createContainer(containerConfig);
|
||||||
await container.start();
|
await container.start();
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ async function handleExec(ws, containerId, log) {
|
|||||||
if (chunks.length > 0 && Buffer.concat(chunks).toString().includes('/bash')) {
|
if (chunks.length > 0 && Buffer.concat(chunks).toString().includes('/bash')) {
|
||||||
shell = '/bin/bash';
|
shell = '/bin/bash';
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {
|
||||||
|
// Fall back to /bin/sh when bash detection fails
|
||||||
|
}
|
||||||
|
|
||||||
execInstance = await container.exec({
|
execInstance = await container.exec({
|
||||||
Cmd: [shell],
|
Cmd: [shell],
|
||||||
@@ -96,21 +98,27 @@ async function handleExec(ws, containerId, log) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {
|
||||||
|
// Treat message as raw terminal input if JSON parsing fails
|
||||||
|
}
|
||||||
// Regular terminal input
|
// Regular terminal input
|
||||||
execStream.write(data);
|
execStream.write(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on('close', () => {
|
ws.on('close', () => {
|
||||||
if (execStream) {
|
if (execStream) {
|
||||||
try { execStream.destroy(); } catch (_) {}
|
try { execStream.destroy(); } catch (_) {
|
||||||
|
// Ignore stream teardown errors on socket close
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on('error', (err) => {
|
ws.on('error', (err) => {
|
||||||
log.warn('exec', 'WebSocket error', { containerId, error: err.message });
|
log.warn('exec', 'WebSocket error', { containerId, error: err.message });
|
||||||
if (execStream) {
|
if (execStream) {
|
||||||
try { execStream.destroy(); } catch (_) {}
|
try { execStream.destroy(); } catch (_) {
|
||||||
|
// Ignore stream teardown errors after websocket errors
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,9 @@ const { APP, REGEX, TIMEOUTS } = require('../constants');
|
|||||||
const { validateServiceConfig, isValidPort } = require('../input-validator');
|
const { validateServiceConfig, isValidPort } = require('../input-validator');
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('../fs-helpers');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../pagination');
|
||||||
const { ValidationError, NotFoundError } = require('../errors');
|
const { ValidationError, NotFoundError, ConflictError } = require('../errors');
|
||||||
const { resolveServiceUrl } = require('../url-resolver');
|
const { resolveServiceUrl } = require('../url-resolver');
|
||||||
const { success, error: errorResponse } = require('../response-helpers');
|
const { success, error: errorResponse } = require('../response-helpers');
|
||||||
const { ConflictError, ValidationError, NotFoundError } = require('../errors');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Services route factory
|
* Services route factory
|
||||||
|
|||||||
Reference in New Issue
Block a user