mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 23:24:52 +09:00
Move filepath into config class
This commit is contained in:
12 files changed
+51
-62
No files matched your search
@@ -210,7 +210,6 @@ interface InitializeParameters {
|
||||
shouldRun: boolean;
|
||||
clusterLogger: winston.Logger;
|
||||
pluginInfos: lib.PluginNodeEnvInfo[] | null;
|
||||
controllerConfigPath: string | null;
|
||||
controllerConfig: lib.ControllerConfig | null;
|
||||
}
|
||||
|
||||
@@ -334,7 +333,6 @@ async function initialize(): Promise<InitializeParameters> {
|
||||
shouldRun,
|
||||
clusterLogger,
|
||||
pluginInfos: null,
|
||||
controllerConfigPath: null,
|
||||
controllerConfig: null,
|
||||
};
|
||||
}
|
||||
@@ -344,17 +342,17 @@ async function initialize(): Promise<InitializeParameters> {
|
||||
lib.registerPluginMessages(pluginInfos);
|
||||
lib.addPluginConfigFields(pluginInfos);
|
||||
|
||||
let controllerConfig;
|
||||
const controllerConfigPath = args.config;
|
||||
logger.info(`Loading config from ${controllerConfigPath}`);
|
||||
let controllerConfig = new lib.ControllerConfig("controller");
|
||||
try {
|
||||
let jsonConfig = JSON.parse(await fs.readFile(controllerConfigPath, { encoding: "utf8" }));
|
||||
controllerConfig = lib.ControllerConfig.fromJSON(jsonConfig, "controller");
|
||||
controllerConfig = lib.ControllerConfig.fromJSON(jsonConfig, "controller", controllerConfigPath);
|
||||
|
||||
} catch (err: any) {
|
||||
if (err.code === "ENOENT") {
|
||||
logger.info("Config not found, initializing new config");
|
||||
controllerConfig = new lib.ControllerConfig("controller");
|
||||
controllerConfig = new lib.ControllerConfig("controller", undefined, controllerConfigPath);
|
||||
|
||||
} else {
|
||||
throw new lib.StartupError(`Failed to load ${controllerConfigPath}: ${err.message}`);
|
||||
@@ -374,9 +372,7 @@ async function initialize(): Promise<InitializeParameters> {
|
||||
}
|
||||
|
||||
if (command === "config") {
|
||||
await lib.handleConfigCommand(
|
||||
args, controllerConfig, controllerConfigPath
|
||||
);
|
||||
await lib.handleConfigCommand(args, controllerConfig);
|
||||
|
||||
} else if (command === "bootstrap") {
|
||||
await handleBootstrapCommand(args, controllerConfig);
|
||||
@@ -386,7 +382,6 @@ async function initialize(): Promise<InitializeParameters> {
|
||||
args,
|
||||
clusterLogger,
|
||||
pluginInfos,
|
||||
controllerConfigPath,
|
||||
controllerConfig,
|
||||
shouldRun,
|
||||
};
|
||||
@@ -402,17 +397,15 @@ async function startup() {
|
||||
shouldRun,
|
||||
clusterLogger,
|
||||
pluginInfos,
|
||||
controllerConfigPath,
|
||||
controllerConfig,
|
||||
} = await initialize();
|
||||
if (!shouldRun || !pluginInfos || !controllerConfigPath || !controllerConfig) {
|
||||
if (!shouldRun || !pluginInfos || !controllerConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
controller = new Controller(
|
||||
clusterLogger,
|
||||
pluginInfos,
|
||||
controllerConfigPath,
|
||||
controllerConfig,
|
||||
Boolean(args.canRestart),
|
||||
Boolean(args.recovery),
|
||||
|
||||
@@ -50,7 +50,6 @@ export default class Controller {
|
||||
clusterLogger: winston.Logger;
|
||||
/** Array of plugin info objects for known plugins */
|
||||
pluginInfos: lib.PluginNodeEnvInfo[];
|
||||
configPath: string;
|
||||
/** Controller config. */
|
||||
config: lib.ControllerConfig;
|
||||
app: Application;
|
||||
@@ -155,7 +154,6 @@ export default class Controller {
|
||||
constructor(
|
||||
clusterLogger: winston.Logger,
|
||||
pluginInfos: lib.PluginNodeEnvInfo[],
|
||||
configPath: string,
|
||||
config: lib.ControllerConfig,
|
||||
|
||||
/**
|
||||
@@ -184,7 +182,6 @@ export default class Controller {
|
||||
) {
|
||||
this.clusterLogger = clusterLogger;
|
||||
this.pluginInfos = pluginInfos;
|
||||
this.configPath = configPath;
|
||||
this.config = config;
|
||||
|
||||
this.app = express();
|
||||
@@ -586,7 +583,7 @@ export default class Controller {
|
||||
private async _saveDataInternal() {
|
||||
if (this.config.dirty) {
|
||||
this.config.dirty = false;
|
||||
await lib.safeOutputFile(this.configPath, JSON.stringify(this.config, null, "\t"));
|
||||
await lib.safeOutputFile(this.config.filepath!, JSON.stringify(this.config, null, "\t"));
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
|
||||
+6
-5
@@ -209,16 +209,17 @@ async function startControl() {
|
||||
.parse() as CtlArguments
|
||||
;
|
||||
|
||||
logger.verbose(`Loading config from ${args.config}`);
|
||||
let controlConfig;
|
||||
const controlConfigPath = args.config;
|
||||
logger.verbose(`Loading config from ${controlConfigPath}`);
|
||||
try {
|
||||
const jsonConfig = JSON.parse(await fs.readFile(args.config, "utf8"));
|
||||
controlConfig = lib.ControlConfig.fromJSON(jsonConfig, "control");
|
||||
const jsonConfig = JSON.parse(await fs.readFile(controlConfigPath, "utf8"));
|
||||
controlConfig = lib.ControlConfig.fromJSON(jsonConfig, "control", controlConfigPath);
|
||||
|
||||
} catch (err: any) {
|
||||
if (err.code === "ENOENT") {
|
||||
logger.verbose("Config not found, initializing new config");
|
||||
controlConfig = new lib.ControlConfig("control");
|
||||
controlConfig = new lib.ControlConfig("control", undefined, controlConfigPath);
|
||||
|
||||
} else {
|
||||
throw new lib.StartupError(`Failed to load ${args.config}: ${err.message}`);
|
||||
@@ -232,7 +233,7 @@ async function startControl() {
|
||||
|
||||
// Handle the control-config command before trying to connect.
|
||||
if (args._[0] === "control-config") {
|
||||
await lib.handleConfigCommand(args, controlConfig, args.config);
|
||||
await lib.handleConfigCommand(args, controlConfig);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -167,16 +167,17 @@ async function startHost() {
|
||||
lib.registerPluginMessages(pluginInfos);
|
||||
lib.addPluginConfigFields(pluginInfos);
|
||||
|
||||
logger.info(`Loading config from ${args.config}`);
|
||||
let hostConfig;
|
||||
const hostConfigPath = args.config;
|
||||
logger.info(`Loading config from ${hostConfigPath}`);
|
||||
try {
|
||||
const jsonConfig = JSON.parse(await fs.readFile(args.config, "utf8"));
|
||||
hostConfig = lib.HostConfig.fromJSON(jsonConfig, "host");
|
||||
const jsonConfig = JSON.parse(await fs.readFile(hostConfigPath, "utf8"));
|
||||
hostConfig = lib.HostConfig.fromJSON(jsonConfig, "host", hostConfigPath);
|
||||
|
||||
} catch (err: any) {
|
||||
if (err.code === "ENOENT") {
|
||||
logger.info("Config not found, initializing new config");
|
||||
hostConfig = new lib.HostConfig("host");
|
||||
hostConfig = new lib.HostConfig("host", undefined, hostConfigPath);
|
||||
|
||||
} else {
|
||||
throw new lib.StartupError(`Failed to load ${args.config}: ${err.message}`);
|
||||
@@ -186,7 +187,7 @@ async function startHost() {
|
||||
hostConfig.set("host.version", version); // Allows tracking last loaded version
|
||||
|
||||
if (command === "config") {
|
||||
await lib.handleConfigCommand(args, hostConfig, args.config);
|
||||
await lib.handleConfigCommand(args, hostConfig);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -229,7 +230,6 @@ async function startHost() {
|
||||
let hostConnector = new HostConnector(hostConfig, tlsCa, pluginInfos);
|
||||
host = new Host(
|
||||
hostConnector,
|
||||
args.config,
|
||||
hostConfig,
|
||||
tlsCa,
|
||||
pluginInfos,
|
||||
|
||||
@@ -48,14 +48,14 @@ async function discoverInstances(instancesDir: string) {
|
||||
|
||||
try {
|
||||
const jsonConfig = JSON.parse(await fs.readFile(configPath, "utf8"));
|
||||
instanceConfig = lib.InstanceConfig.fromJSON(jsonConfig, "host");
|
||||
instanceConfig = lib.InstanceConfig.fromJSON(jsonConfig, "host", configPath);
|
||||
|
||||
} catch (err: any) {
|
||||
if (err.code === "ENOENT") {
|
||||
continue; // Ignore folders without config.json
|
||||
}
|
||||
|
||||
logger.error(`Error occured while parsing ${configPath}: ${err.message}`);
|
||||
logger.error(`Error occurred while parsing ${configPath}: ${err.message}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -258,7 +258,6 @@ export default class Host extends lib.Link {
|
||||
*/
|
||||
tlsCa?: string;
|
||||
pluginInfos: lib.PluginNodeEnvInfo[];
|
||||
configPath: string;
|
||||
config: lib.HostConfig;
|
||||
|
||||
/** Mapping of plugin name to loaded plugin */
|
||||
@@ -289,7 +288,6 @@ export default class Host extends lib.Link {
|
||||
|
||||
constructor(
|
||||
connector: HostConnector,
|
||||
hostConfigPath: string,
|
||||
hostConfig: lib.HostConfig,
|
||||
tlsCa: string | undefined,
|
||||
pluginInfos: lib.PluginNodeEnvInfo[],
|
||||
@@ -309,7 +307,6 @@ export default class Host extends lib.Link {
|
||||
this.tlsCa = tlsCa;
|
||||
|
||||
this.pluginInfos = pluginInfos;
|
||||
this.configPath = hostConfigPath;
|
||||
this.config = hostConfig;
|
||||
|
||||
this.config.on("fieldChanged", (name, curr, prev) => {
|
||||
@@ -659,6 +656,7 @@ export default class Host extends lib.Link {
|
||||
instanceConfig.update(config, false, "controller");
|
||||
|
||||
let instanceDir = await this._createNewInstanceDir(instanceConfig.get("instance.name"));
|
||||
instanceConfig.filepath = path.join(instanceDir, "instance.json");
|
||||
|
||||
logger.info(`Creating ${instanceDir}`);
|
||||
await Instance.populate_folders(instanceDir);
|
||||
@@ -701,10 +699,7 @@ export default class Host extends lib.Link {
|
||||
_warning: "Changes to this file will be overwritten by the controller's copy.",
|
||||
...instanceInfo.config.toJSON(),
|
||||
};
|
||||
await lib.safeOutputFile(
|
||||
path.join(instanceInfo.path, "instance.json"),
|
||||
JSON.stringify(warnedOutput, null, "\t")
|
||||
);
|
||||
await lib.safeOutputFile(instanceInfo.config.filepath!, JSON.stringify(warnedOutput, null, "\t"));
|
||||
}
|
||||
|
||||
async handleInstanceUnassignInternalRequest(request: lib.InstanceUnassignInternalRequest) {
|
||||
@@ -1157,7 +1152,7 @@ export default class Host extends lib.Link {
|
||||
}
|
||||
|
||||
logger.info("Saving config");
|
||||
await lib.safeOutputFile(this.configPath, JSON.stringify(this.config, null, "\t"));
|
||||
await lib.safeOutputFile(this.config.filepath!, JSON.stringify(this.config, null, "\t"));
|
||||
for (const instanceInfo of this.instanceInfos.values()) {
|
||||
// Save in case host_assigned_game_port changed in the config.
|
||||
await this.saveInstanceConfig(instanceInfo);
|
||||
|
||||
@@ -201,8 +201,9 @@ export class Config<
|
||||
/** Defines the default access locations for the config class */
|
||||
static defaultAccess: ConfigLocation[] = ["controller", "host", "control"];
|
||||
|
||||
fields: Fields;
|
||||
_unknownFields: Record<string, FieldValue> = {};
|
||||
/** Contains the fields and their values */
|
||||
private fields: Fields;
|
||||
private _unknownFields: Record<string, FieldValue> = {};
|
||||
|
||||
/** Set to true when a field in the config is changed. */
|
||||
dirty = false;
|
||||
@@ -213,13 +214,16 @@ export class Config<
|
||||
* Create a new instance of the given config
|
||||
*
|
||||
* @param location -
|
||||
* Location to evaluate access for this instance from
|
||||
* Location to evaluate access for this instance from.
|
||||
* @param fields -
|
||||
* Serialized representation of fields to load.
|
||||
* @param filepath -
|
||||
* Filepath for the config to save to.
|
||||
*/
|
||||
constructor(
|
||||
public location: ConfigLocation,
|
||||
fields?: Static<typeof Config.jsonSchema>,
|
||||
public filepath?: string,
|
||||
) {
|
||||
if (typeof location !== "string") {
|
||||
throw new Error("location must be a string");
|
||||
@@ -306,11 +310,13 @@ export class Config<
|
||||
*
|
||||
* @param json - Serialized config to load.
|
||||
* @param location - Location used for access control.
|
||||
* @param filepath - Filepath for the config to save to.
|
||||
* @returns Instance of this config
|
||||
*/
|
||||
static fromJSON(
|
||||
json: Static<typeof this.jsonSchema>,
|
||||
location: ConfigLocation,
|
||||
filepath?: string,
|
||||
) {
|
||||
// migrate: Pre alpha 14 config format
|
||||
if (typeof json === "object" && json !== null && json.groups instanceof Array) {
|
||||
@@ -326,7 +332,7 @@ export class Config<
|
||||
if (!valid) {
|
||||
throw new Error("Invalid config");
|
||||
}
|
||||
return new this(location, json);
|
||||
return new this(location, json, filepath);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
@@ -3,6 +3,8 @@ import * as classes from "./classes";
|
||||
import type { PluginNodeEnvInfo, PluginWebpackEnvInfo } from "../plugin";
|
||||
import { Static } from "@sinclair/typebox";
|
||||
|
||||
type configFromJSON<T> = (...args: Parameters<typeof classes.Config.fromJSON>) => T;
|
||||
|
||||
export interface ControllerConfigFields {
|
||||
"controller.version": string;
|
||||
"controller.name": string;
|
||||
@@ -36,7 +38,7 @@ export interface ControllerConfigFields {
|
||||
* @extends classes.Config
|
||||
*/
|
||||
export class ControllerConfig extends classes.Config<ControllerConfigFields> {
|
||||
declare static fromJSON: (json: classes.ConfigSchema, location: classes.ConfigLocation) => ControllerConfig;
|
||||
declare static fromJSON: configFromJSON<ControllerConfig>;
|
||||
static migrations(config: Static<typeof this.jsonSchema>) {
|
||||
if (config.hasOwnProperty("controller.external_address")) {
|
||||
config["controller.public_url"] = config["controller.external_address"];
|
||||
@@ -243,7 +245,7 @@ export interface HostConfigFields {
|
||||
* @extends classes.Config
|
||||
*/
|
||||
export class HostConfig extends classes.Config<HostConfigFields> {
|
||||
declare static fromJSON: (json: classes.ConfigSchema, location: classes.ConfigLocation) => HostConfig;
|
||||
declare static fromJSON: configFromJSON<HostConfig>;
|
||||
static fieldDefinitions: classes.ConfigDefs<HostConfigFields> = {
|
||||
"host.version": {
|
||||
type: "string",
|
||||
@@ -375,7 +377,7 @@ export interface InstanceConfigFields {
|
||||
* @extends classes.Config
|
||||
*/
|
||||
export class InstanceConfig extends classes.Config<InstanceConfigFields> {
|
||||
declare static fromJSON: (json: classes.ConfigSchema, location: classes.ConfigLocation) => InstanceConfig;
|
||||
declare static fromJSON: configFromJSON<InstanceConfig>;
|
||||
static migrations(config: Static<typeof this.jsonSchema>) {
|
||||
function boolToEnableDisable(name: string) {
|
||||
if (config.hasOwnProperty(name) && typeof config[name] === "boolean") {
|
||||
@@ -568,7 +570,7 @@ export interface ControlConfigFields {
|
||||
* @extends classes.Config
|
||||
*/
|
||||
export class ControlConfig extends classes.Config<ControlConfigFields> {
|
||||
declare static fromJSON: (json: classes.ConfigSchema, location: classes.ConfigLocation) => ControlConfig;
|
||||
declare static fromJSON: configFromJSON<ControlConfig>;
|
||||
static fieldDefinitions: classes.ConfigDefs<ControlConfigFields> = {
|
||||
"control.controller_url": {
|
||||
description: "URL to connect to the controller at",
|
||||
|
||||
@@ -135,7 +135,6 @@ export function configCommand(yargs: any) {
|
||||
export async function handleConfigCommand(
|
||||
args: Record<string, unknown>,
|
||||
instance: libConfig.Config<any>,
|
||||
configPath: string
|
||||
) {
|
||||
let command = (args._ as string[])[1];
|
||||
|
||||
@@ -165,7 +164,7 @@ export async function handleConfigCommand(
|
||||
|
||||
try {
|
||||
instance.set(args.field as string, args.value);
|
||||
await libFileOps.safeOutputFile(configPath, JSON.stringify(instance, null, "\t"));
|
||||
await libFileOps.safeOutputFile(instance.filepath!, JSON.stringify(instance, null, "\t"));
|
||||
} catch (err) {
|
||||
if (err instanceof libConfig.InvalidField || err instanceof libConfig.InvalidValue) {
|
||||
logger.error(err.message);
|
||||
|
||||
@@ -28,7 +28,7 @@ describe("controller/src/Controller", function() {
|
||||
/** @type {Controller} */
|
||||
let controller, mockInstanceConfig;
|
||||
before(async function() {
|
||||
controller = new Controller({}, [], "", new ControllerConfig("controller"));
|
||||
controller = new Controller({}, [], new ControllerConfig("controller"));
|
||||
mockInstanceConfig = new MockInstanceConfig(new Map([
|
||||
["instance.id", 100], ["instance.name", "test"], ["factorio.settings", []],
|
||||
]));
|
||||
|
||||
@@ -10,7 +10,7 @@ describe("controller/src/WsServer", function() {
|
||||
before(function() {
|
||||
let config = new ControllerConfig("controller");
|
||||
config.set("controller.trusted_proxies", "127.0.0.0/8, ::1");
|
||||
let controller = new Controller({}, [], "", config);
|
||||
let controller = new Controller({}, [], config);
|
||||
wsServer = controller.wsServer;
|
||||
});
|
||||
describe(".remoteAddr()", function() {
|
||||
|
||||
+7
-6
@@ -10,13 +10,14 @@ const { _discoverInstances } = require("@clusterio/host/dist/node/src/Host");
|
||||
describe("Host testing", function() {
|
||||
describe("discoverInstances()", function() {
|
||||
it("should discover test instance", async function() {
|
||||
let instancePath = path.join("test", "file", "instances");
|
||||
let instanceInfos = await _discoverInstances(instancePath);
|
||||
const instancePath = path.join("test", "file", "instances");
|
||||
const instanceInfos = await _discoverInstances(instancePath);
|
||||
|
||||
let referenceConfig = new lib.InstanceConfig("host");
|
||||
referenceConfig.set("instance.id", 1);
|
||||
referenceConfig.set("instance.name", "test");
|
||||
referenceConfig.dirty = false;
|
||||
const configPath = path.join(instancePath, "test", "instance.json");
|
||||
const referenceConfig = new lib.InstanceConfig("host", {
|
||||
"instance.id": 1,
|
||||
"instance.name": "test",
|
||||
}, configPath);
|
||||
|
||||
assert.deepEqual(instanceInfos, new Map([
|
||||
[1, {
|
||||
|
||||
@@ -23,7 +23,7 @@ function connectHost(controller, hostId, plugins) {
|
||||
controller.wsServer.hostConnections.set(hostId, hostConnection);
|
||||
const hostConfig = new lib.HostConfig("host");
|
||||
hostConfig.set("host.id", hostId);
|
||||
return new Host(hostSide, "invalid", hostConfig, undefined, []);
|
||||
return new Host(hostSide, hostConfig, undefined, []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,12 +107,7 @@ describe("Integration of link routing", function() {
|
||||
let controlB;
|
||||
|
||||
beforeEach(function() {
|
||||
controller = new Controller(
|
||||
{},
|
||||
[],
|
||||
"invalid",
|
||||
new lib.ControllerConfig("controller")
|
||||
);
|
||||
controller = new Controller({}, [], new lib.ControllerConfig("controller"));
|
||||
hostA = connectHost(controller, 10, []);
|
||||
hostB = connectHost(controller, 20, []);
|
||||
instanceA1 = connectInstance(controller, hostA, 11);
|
||||
|
||||
Reference in new issue
Block a user