Merge remote-tracking branch 'upstream/master' into fix/host-save-details-ownership

This commit is contained in:
bbassie committed 2026-09-13 17:10:00 +00:00
commit 97bab72eb9
16 files changed
+410 -27

No files matched your search

+19 -4
View File
@@ -48,12 +48,16 @@ export default class ControlConnection extends BaseConnection {
this._version = registerData.version;
this.connector.on("connect", () => {
this.connector._socket!.clusterio_ignore_dump = Boolean(this.ws_dumper);
});
// A resume installs a fresh socket, so re-apply the ignore flag or the
// dumper's own frames get echoed back into it and recurse forever.
for (let event of ["connect", "resume"] as const) {
this.connector.on(event, () => {
this.connector._socket!.clusterio_ignore_dump = Boolean(this.ws_dumper);
});
}
this.connector.on("close", () => {
if (this.logTransport) {
logger.remove(this.logTransport);
this._controller.clusterLogger.remove(this.logTransport);
this.logTransport = null;
}
if (this.ws_dumper) {
@@ -288,6 +292,9 @@ export default class ControlConnection extends BaseConnection {
}
async handleInstanceCreateRequest(request: lib.InstanceCreateRequest) {
if ((request.config["instance.assigned_host"] ?? null) !== null) {
throw new lib.RequestError("instance.assigned_host must be set through the assign-host interface");
}
const instanceConfig = new lib.InstanceConfig("controller");
if (request.cloneFromId) {
const baseInstance = this._controller.instances.get(request.cloneFromId);
@@ -1070,6 +1077,11 @@ export default class ControlConnection extends BaseConnection {
}
this._controller.users.deleteUser(user);
for (let controlConnection of this._controller.wsServer.controlConnections.values()) {
if (controlConnection.user.id === user.id) {
controlConnection.connector.terminate();
}
}
if (user.isAdmin) {
this._controller.sendTo("allInstances", new lib.InstanceAdminlistUpdateEvent(name, false));
@@ -1325,6 +1337,9 @@ export default class ControlConnection extends BaseConnection {
}
async handleDebugDumpWsRequest(request: lib.DebugDumpWsRequest) {
if (this.ws_dumper) {
return; // Already dumping
}
this.ws_dumper = data => {
if (this.connector.connected) {
this.send(new lib.DebugWsMessageEvent(data.direction, data.content));
+11 -3
View File
@@ -208,9 +208,17 @@ export default class InstanceManager {
instance.config.set("instance.assigned_host", hostId);
if (newHostConnection) {
await newHostConnection.send(
new lib.InstanceAssignInternalRequest(instanceId, instance.config.toRemote("host")),
);
try {
await newHostConnection.send(
new lib.InstanceAssignInternalRequest(instanceId, instance.config.toRemote("host")),
);
} catch (err) {
// Leave unassigned so the assign can be retried
instance.config.set("instance.assigned_host", null);
instance.status = "unassigned";
this.records.set(instance);
throw err;
}
} else {
instance.status = "unassigned";
}
+3 -1
View File
@@ -119,7 +119,9 @@ export default class UserManager {
roles.add(defaultRoleId);
}
const user = new User(this.records, this._controllerRoles, 0, name, roles);
// Reject tokens issued before the user existed, e.g. for a previous user by the same name
const tokenValidAfter = Math.floor(Date.now() / 1000);
const user = new User(this.records, this._controllerRoles, tokenValidAfter, name, roles);
this.records.set(user);
return user;
}