Rework save logic with regard to start instance

Ensure that notifyExit is called if errors occur during startInstance
and createSave request, and rework startInstance save logic to create
a new savegame if no save is present and allow specifying the save to
load.
This commit is contained in:
Hornwitser committed 2020-04-09 16:17:38 +02:00
1 parent 62e38199bd
commit 56ee1fe955
4 files changed
+64 -22

No files matched your search

+2 -4
View File
@@ -243,15 +243,13 @@ The basic operations to start a new instance is the following
node clusterctl create-instance --name "My instance"
node clusterctl assign-instance --instance "My instance" --slave "Local"
node clusterctl create-save --instance "My instance"
node clusterctl start-instance --instance "My instance"
The first line creates the instance configuration on the master server.
The second assigns the instance to a slave which creates the instance
directory and files needed to run the instance on the given slave. The
third line creates a new savegame for the instance. You could also
upload your own save to the instance directory instead. And finally the
fourth line starts the instance.
third line starts the instance, which creates a new save if there are no
save games present.
There are many more commands available with clusterctl. See
`node clusterctl --help` for a full list of them.
+2
View File
@@ -251,6 +251,7 @@ commands.push(new Command({
definition: ['start-instance', "Start instance", (yargs) => {
yargs.options({
'instance': { describe: "Instance to start", nargs: 1, type: 'string', demandOption: true },
'save': { describe: "Save load, defaults to latest", nargs: 1, type: 'string' },
});
}],
handler: async function(args, control) {
@@ -258,6 +259,7 @@ commands.push(new Command({
await link.messages.setInstanceOutputSubscriptions.send(control, { instance_ids: [instanceId] });
let response = await link.messages.startInstance.send(control, {
instance_id: instanceId,
save: args.save || null,
});
},
}));
+1 -1
View File
@@ -298,7 +298,7 @@ messages.startInstance = new Request({
type: 'start_instance',
links: ['control-master', 'master-slave', 'slave-instance'],
requestProperties: {
"instance_id": { type: "integer" },
"save": { type: ["string", "null"] },
},
forwardTo: 'instance',
});
+59 -17
View File
@@ -141,7 +141,6 @@ class Instance extends link.Link{
* @param {String} instanceDir -
* Directory to create the new instance into.
* @param {String} factorioDir - Path to factorio installation.
* @param {Object} options - Options for new instance.
*/
static async create(instanceConfig, instanceDir, factorioDir) {
console.log(`Clusterio | Creating ${instanceDir}`);
@@ -150,7 +149,18 @@ class Instance extends link.Link{
await fs.ensureDir(path.join(instanceDir, "saves"));
}
async start(saveName, slaveConfig, socket) {
/**
* Prepare a save for starting
*
* Writes server settings, links mods, creates a new save if no save is
* passed, and patches it with modules.
*
* @param {String|null} saveName -
* Save to prepare from the instance saves directory. Creates a new
* save if null.
* @returns {String} Name of the save prepared.
*/
async prepare(saveName) {
console.log("Clusterio | Writing server-settings.json");
await this.writeServerSettings();
@@ -168,6 +178,20 @@ class Instance extends link.Link{
await symlinkMods(this, "sharedMods", console);
// Use latest save if no save was specified
if (saveName === null) {
saveName = await fileOps.getNewestFile(
this.path("saves"), (name) => !name.endsWith('.tmp.zip')
);
}
// Create save if no save was found.
if (saveName === null) {
console.log("Clusterio | Creating new save")
await this.server.create("world.zip");
saveName = "world.zip";
}
// Patch save with lua modules from plugins
console.log("Clusterio | Patching save");
@@ -228,7 +252,17 @@ class Instance extends link.Link{
}
await factorio.patch(this.path("saves", saveName), [...modules.values()]);
return saveName;
}
/**
* Start Factorio server
*
* Launches the Factorio server for this instance with the given save.
*
* @param {String} saveName - Name of save game to load.
*/
async start(saveName) {
this.server.on('rcon-ready', () => {
console.log("Clusterio | RCON connection established");
});
@@ -264,7 +298,6 @@ class Instance extends link.Link{
await this.server.stop();
}
}
async getMetricsRequestHandler() {
@@ -281,26 +314,35 @@ class Instance extends link.Link{
return { results };
}
async startInstanceRequestHandler() {
// Find save to start
let latestSave = await fileOps.getNewestFile(
this.path("saves"), (name) => !name.endsWith('.tmp.zip')
);
if (latestSave === null) {
throw new errors.RequestError(
"No savefile was found to start the instance with."
);
async startInstanceRequestHandler(message) {
let saveName = message.data.save;
try {
saveName = await this.prepare(saveName)
} catch (err) {
this.notifyExit();
throw err;
}
await this.start(latestSave, this.config, this.socket);
try {
await this.start(saveName, this.config, this.socket);
} catch (err) {
await this.stop();
throw err;
}
}
async createSaveRequestHandler() {
console.log("Clusterio | Writing server-settings.json");
await this.writeServerSettings();
try {
console.log("Clusterio | Writing server-settings.json");
await this.writeServerSettings();
console.log("Creating save .....");
await symlinkMods(this, "sharedMods", console);
console.log("Creating save .....");
await symlinkMods(this, "sharedMods", console);
} catch (err) {
this.notifyExit();
throw err;
}
this.server.on("exit", () => this.notifyExit());
await this.server.create("world");