Implement mod pack loading for shared mods

Wipe and reconstruct the instances' mods/ folder using the configured
ModPack for the case were the mods folder is shared with the master
server.  This assumes the master server will check the mod checksums
before sending the start request.
This commit is contained in:
Hornwitser committed 2022-11-10 00:28:50 +01:00
1 parent 0ebb2f5858
commit fb4ffaffed
14 files changed
+124 -165

No files matched your search

+1
View File
@@ -265,6 +265,7 @@ describe("Integration of Clusterio", function() {
);
await execCtl(`instance config set-prop test factorio.settings visibility "'${value}'"`);
await execCtl("instance config set-prop test factorio.settings require_user_verification false");
await execCtl("instance config set test factorio.mod_pack 12");
});
});
+9
View File
@@ -8,6 +8,7 @@ const phin = require("phin");
const util = require("util");
const events = require("events");
const libData = require("@clusterio/lib/data");
const libLink = require("@clusterio/lib/link");
const { LineSplitter } = require("@clusterio/lib/stream");
const { ConsoleTransport, logger } = require("@clusterio/lib/logging");
@@ -220,6 +221,14 @@ before(async function() {
controlConnector.token = controlToken;
control = new TestControl(controlConnector);
await controlConnector.connect();
const testPack = new libData.ModPack();
testPack.id = 12;
testPack.name = "subspace_storage-pack";
testPack.factorioVersion = "1.1.0";
testPack.mods.set("subspace_storage", { name: "clusterio_lib", enabled: true, version: "0.1.2" });
testPack.mods.set("subspace_storage", { name: "subspace_storage", enabled: true, version: "1.99.8" });
libLink.messages.createModPack.send(control, { mod_pack: testPack.toJSON() });
});
after(async function() {
-67
View File
@@ -1,11 +1,8 @@
"use strict";
const assert = require("assert").strict;
const path = require("path");
const fs = require("fs-extra");
const libLink = require("@clusterio/lib/link");
const libConfig = require("@clusterio/lib/config");
const Instance = require("@clusterio/slave/src/Instance");
const Slave = require("@clusterio/slave/src/Slave");
describe("Slave testing", function() {
@@ -13,70 +10,6 @@ describe("Slave testing", function() {
libConfig.InstanceConfig.finalize();
});
describe("symlinkMods()", function() {
let testDir = path.join("temp", "test", "symlink");
let instance;
before(async function() {
// Remove previous test output
await fs.remove(testDir);
// Add some test mods
await fs.outputFile(path.join(testDir, "shared", "mod_a.zip"), "a");
await fs.outputFile(path.join(testDir, "shared", "mod_b.zip"), "b");
await fs.outputFile(path.join(testDir, "shared", "mod.dat"), "c");
await fs.outputFile(path.join(testDir, "shared", "mod-list.json"), "d");
let instanceConfig = new libConfig.InstanceConfig("slave");
await instanceConfig.init();
instanceConfig.set("instance.name", "test");
instance = new Instance(
{}, new libLink.VirtualConnector(), path.join(testDir, "instance"), "factorioDir", instanceConfig
);
await fs.outputFile(instance.path("mods", "mod_i.zip"), "i");
});
it("should link mods and data files", async function() {
await Instance._symlinkMods(instance, path.join(testDir, "shared"));
assert.equal(await fs.readFile(instance.path("mods", "mod_a.zip"), "utf-8"), "a");
assert.equal(await fs.readFile(instance.path("mods", "mod_b.zip"), "utf-8"), "b");
assert.equal(await fs.readFile(instance.path("mods", "mod.dat"), "utf-8"), "c");
assert.equal(await fs.readFile(instance.path("mods", "mod-list.json"), "utf-8"), "d");
assert.equal(await fs.readFile(instance.path("mods", "mod_i.zip"), "utf-8"), "i");
});
it("should ignore directories", async function() {
await fs.ensureDir(path.join(testDir, "shared", "dir"));
await Instance._symlinkMods(instance, path.join(testDir, "shared"));
assert(!await fs.exists(instance.path("mods", "dir"), "utf-8"), "dir was unxpectedly linked");
});
it("should ignore files", async function() {
await fs.outputFile(path.join(testDir, "shared", "file"), "f");
await Instance._symlinkMods(instance, path.join(testDir, "shared"));
assert(!await fs.exists(instance.path("mods", "file"), "utf-8"), "dir was unxpectedly linked");
});
it("should unlink removed mods", async function() {
// This does not work on Windows
if (process.platform === "win32") {
this.skip();
}
await fs.unlink(path.join(testDir, "shared", "mod_a.zip"));
await Instance._symlinkMods(instance, path.join(testDir, "shared"));
await assert.rejects(fs.lstat(instance.path("mods", "mod_a.zip")), { code: "ENOENT" });
assert.equal(await fs.readFile(instance.path("mods", "mod_b.zip"), "utf-8"), "b");
assert.equal(await fs.readFile(instance.path("mods", "mod.dat"), "utf-8"), "c");
assert.equal(await fs.readFile(instance.path("mods", "mod-list.json"), "utf-8"), "d");
assert.equal(await fs.readFile(instance.path("mods", "mod_i.zip"), "utf-8"), "i");
});
});
describe("discoverInstances()", function() {
it("should discover test instance", async function() {
let instancePath = path.join("test", "file", "instances");