From fc5701f24313000c37e71043decd893562e1fb18 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 23 Jan 2024 16:23:09 +0100 Subject: [PATCH] Fix instance auto start Bypass the Link layer and invoke the handleInstanceStartRequest method directly on the Instance object during the host's instance auto start phase. --- .eslintrc.js | 1 + CHANGELOG.md | 1 + README.md | 1 - packages/host/src/Host.ts | 2 +- test/integration/clusterio.js | 39 ++++++++++++++++++++++++++++++++++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 3cf36d34..1487649a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -35,6 +35,7 @@ module.exports = { "rules": { "prefer-arrow-callback": "off", "no-invalid-this": "off", + "valid-jsdoc": "off", "node/no-unpublished-import": "off", "node/no-unpublished-require": "off", }, diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bab77a0..dc84398d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fixed a memory leak on every request sent over the WebSocket. - Fixed assertion error on closing or invalidating a link with messages forwarded from a virtual link. - Fixed host hanging if stopped while an instance is in the process of creating a save during startup. +- Fixed `instance.auto_start` option. ## Version 2.0.0-alpha.14 diff --git a/README.md b/README.md index 10be24e6..0857fc07 100644 --- a/README.md +++ b/README.md @@ -268,7 +268,6 @@ If you want to use a different user for the command line interface, you can gene ## Known Issues -- The `instance.auto_start` option is currently is broken and will not work, turn it off and do not use it for now. - When the `server_select` plugin is installed you may see `[error] Unhandled event server_select:UpdateInstancesEvent` logged when starting an instance. This should be ignored as it does not indicate an error occured. - After migrating from Alpha 13 to Alpha 14 running an instance data export fails with the error `Upload failed: 401 Unauthorized` due to the host token being issued to a slave. diff --git a/packages/host/src/Host.ts b/packages/host/src/Host.ts index 7381ad36..06a23809 100644 --- a/packages/host/src/Host.ts +++ b/packages/host/src/Host.ts @@ -1056,7 +1056,7 @@ export default class Host extends lib.Link { if (instanceInfo.config.get("instance.auto_start")) { try { let instanceConnection = await this._connectInstance(instanceId); - await instanceConnection.send(new lib.InstanceStartRequest()); + await instanceConnection.instance.handleInstanceStartRequest(new lib.InstanceStartRequest()); } catch (err: any) { logger.error( `Error during auto startup for ${instanceInfo.config.get("instance.name")}:\n${err.stack}`, diff --git a/test/integration/clusterio.js b/test/integration/clusterio.js index dcb3c36d..d34b8a0d 100644 --- a/test/integration/clusterio.js +++ b/test/integration/clusterio.js @@ -17,6 +17,7 @@ const { } = require("./index"); +/** @returns {Promise>} */ async function getInstances() { let instances = await getControl().send(new lib.InstanceDetailsListRequest()); return new Map(instances.map(instance => [instance.id, instance])); @@ -27,6 +28,10 @@ async function checkInstanceStatus(id, status) { assert.equal(instances.get(44).status, status, "incorrect instance status"); } +async function spawnAltHost(config = "alt-host-config.json") { + return await spawn("alt-host:", `node ../../packages/host run --config ${config}`, /Started host/); +} + async function startAltHost() { let config = "alt-host-config.json"; let configPath = path.join("temp", "test", config); @@ -38,7 +43,7 @@ async function startAltHost() { await exec(`node ../../packages/host --config ${config} config set host.instances_directory alt-instances`); await exec(`node ../../packages/host --config ${config} config set host.factorio_directory ../../factorio`); await exec(`node ../../packages/host --config ${config} config set host.mods_directory alt-mods`); - return await spawn("alt-host:", `node ../../packages/host run --config ${config}`, /Started host/); + return await spawnAltHost(config); } async function stopAltHost(hostProcess) { @@ -200,6 +205,38 @@ describe("Integration of Clusterio", function() { assert(await fs.pathExists(clusterioLib), "mod was not downloaded by the test"); }); }); + it("should auto start instances with auto_start enabled", async function() { + slowTest(this); + + let hostProcess; + try { + hostProcess = await startAltHost(); + await execCtl("instance create alt-start --id 97"); + await execCtl("instance assign alt-start 5"); + await execCtl("instance config set alt-start instance.auto_start true"); + await stopAltHost(hostProcess); + hostProcess = await spawnAltHost(); + // Stop the host immediatly to test the handling of stopping + // instances while automatically started and a save is being created + await stopAltHost(hostProcess); + hostProcess = await spawnAltHost(); + let status; + // Wait for instance status to become running. + for (let i = 0; i < 100; i++) { + const instances = await getInstances(); + status = instances.get(97)?.status ?? "not_present"; + if (status === "running") { + break; + } + await wait(100); // Try again 10 times per second. + } + assert.equal(status, "running"); + await execCtl("instance stop alt-start"); + await execCtl("instance delete alt-start"); + } finally { + await stopAltHost(hostProcess); + } + }); }); describe("clusterioctl", function() {