Sets restart required when a plugin is updated (#794)

* Template type for load plugin config

* Add plugin update checking

* Add restart icon to instance list

* Add tests

* Log package name when failing to read package json
This commit is contained in:
Cooldude2606 authored and GitHub committed 2025-11-01 16:11:11 +00:00
1 parent 41151d47f0
commit 73cc019d2f
11 files changed
+228 -49

No files matched your search

+60 -1
View File
@@ -1,4 +1,5 @@
"use strict";
const path = require("node:path");
const assert = require("assert").strict;
const { Controller, HostInfo, InstanceInfo } = require("@clusterio/controller");
const { ControllerConfig, Address, RequestError, InstanceConfig, SystemInfo, Role } = require("@clusterio/lib");
@@ -27,8 +28,10 @@ describe("controller/src/Controller", function() {
describe("class Controller", function() {
/** @type {Controller} */
let controller, mockInstanceConfig;
const controllerVersion = require("@clusterio/controller/package.json").version;
before(async function() {
controller = new Controller({}, [], new ControllerConfig("controller"));
const controllerConfig = new ControllerConfig("controller", { "controller.version": controllerVersion });
controller = new Controller({}, [], controllerConfig);
mockInstanceConfig = new MockInstanceConfig(new Map([
["instance.id", 100], ["instance.name", "test"], ["factorio.settings", []],
]));
@@ -233,6 +236,62 @@ describe("controller/src/Controller", function() {
assert(instanceInfo.updatedAtMs === 0, "updatedAtMs incremented");
});
});
describe(".checkRestartRequired()", function() {
beforeEach(function() {
// Would not be needed if controller setup was beforeEach
controller.config.restartRequired = false;
controller.config.set("controller.version", controllerVersion);
controller.config.set("global_chat.load_plugin", true);
controller.pluginInfos[0] = {
name: "global_chat",
requirePath: path.dirname(require.resolve("@clusterio/controller/package.json")),
version: controllerVersion,
};
});
it("returns false when no changes are present", async function() {
controller.pluginInfos[0].webEntrypoint = true;
controller.pluginInfos[0].controllerEntrypoint = true;
const result = await controller.checkRestartRequired();
assert.equal(result, false);
assert.equal(controller.config.restartRequired, false);
});
it("returns false when an unloaded plugin version changes", async function() {
controller.pluginInfos[0].version = "0.0.0";
controller.pluginInfos[0].webEntrypoint = true;
controller.pluginInfos[0].controllerEntrypoint = true;
controller.config.set("global_chat.load_plugin", false);
controller.config.restartRequired = false; // Setting load_plugin requires a restart
const result = await controller.checkRestartRequired();
assert.equal(result, false);
assert.equal(controller.config.restartRequired, false);
});
it("returns true when the config flag is set", async function() {
controller.config.restartRequired = true;
const result = await controller.checkRestartRequired();
assert.equal(result, true);
assert.equal(controller.config.restartRequired, true);
});
it("returns true when clusterio version changes", async function() {
controller.config.set("controller.version", "0.0.0");
const result = await controller.checkRestartRequired();
assert.equal(result, true);
assert.equal(controller.config.restartRequired, true);
});
it("returns true when a controller plugin version changes", async function() {
controller.pluginInfos[0].version = "0.0.0";
controller.pluginInfos[0].controllerEntrypoint = true;
const result = await controller.checkRestartRequired();
assert.equal(result, true);
assert.equal(controller.config.restartRequired, true);
});
it("returns true when a web plugin version changes", async function() {
controller.pluginInfos[0].version = "0.0.0";
controller.pluginInfos[0].webEntrypoint = true;
const result = await controller.checkRestartRequired();
assert.equal(result, true);
assert.equal(controller.config.restartRequired, true);
});
});
});
describe("migrations", function() {
describe("SystemInfo", function() {
+59
View File
@@ -6,6 +6,7 @@ const lib = require("@clusterio/lib");
const Host = require("@clusterio/host/dist/node/src/Host").default;
const Instance = require("@clusterio/host/dist/node/src/Instance").default;
const { _discoverInstances } = require("@clusterio/host/dist/node/src/Host");
const { HostConnector } = require("@clusterio/host/dist/node/host");
describe("Host testing", function() {
describe("discoverInstances()", function() {
@@ -115,5 +116,63 @@ describe("Host testing", function() {
]);
});
});
describe(".checkRestartRequired()", function() {
let host;
beforeEach(function() {
// This can be used more generally, but i did not want to interfere with handleSyncUserListsEvent
const hostVersion = require("@clusterio/host/package.json").version;
const pluginInfos = [{
name: "global_chat",
requirePath: path.dirname(require.resolve("@clusterio/host/package.json")),
version: hostVersion,
}];
const hostConfig = new lib.HostConfig("host", { "host.version": hostVersion });
const hostConnector = new HostConnector(hostConfig, undefined, pluginInfos);
host = new Host(hostConnector, hostConfig, undefined, pluginInfos);
});
it("returns false when no changes are present", async function() {
host.pluginInfos[0].hostEntrypoint = true;
host.pluginInfos[0].instanceEntrypoint = true;
const result = await host.checkRestartRequired();
assert.equal(result, false);
assert.equal(host.config.restartRequired, false);
});
it("returns false when an unloaded plugin version changes", async function() {
host.pluginInfos[0].version = "0.0.0";
host.pluginInfos[0].hostEntrypoint = true;
host.pluginInfos[0].instanceEntrypoint = true;
host.config.set("global_chat.load_plugin", false);
host.config.restartRequired = false; // Setting load_plugin requires a restart
const result = await host.checkRestartRequired();
assert.equal(result, false);
assert.equal(host.config.restartRequired, false);
});
it("returns true when the config flag is set", async function() {
host.config.restartRequired = true;
const result = await host.checkRestartRequired();
assert.equal(result, true);
assert.equal(host.config.restartRequired, true);
});
it("returns true when clusterio version changes", async function() {
host.config.set("host.version", "0.0.0");
const result = await host.checkRestartRequired();
assert.equal(result, true);
assert.equal(host.config.restartRequired, true);
});
it("returns true when a host plugin version changes", async function() {
host.pluginInfos[0].version = "0.0.0";
host.pluginInfos[0].hostEntrypoint = true;
const result = await host.checkRestartRequired();
assert.equal(result, true);
assert.equal(host.config.restartRequired, true);
});
it("returns true when an instance plugin version changes", async function() {
host.pluginInfos[0].version = "0.0.0";
host.pluginInfos[0].instanceEntrypoint = true;
const result = await host.checkRestartRequired();
assert.equal(result, true);
assert.equal(host.config.restartRequired, true);
});
});
});
});