From 4248e57dcb9af83fc90be804fb67b2f9022ae90d Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Tue, 26 Nov 2024 23:14:56 +0000 Subject: [PATCH] Add config migrations (#693) Co-authored-by: Danielv123 --- README.md | 2 +- docs/configuration.md | 4 ++-- packages/controller/src/Controller.ts | 2 +- packages/lib/src/config/classes.ts | 12 +++++++++++- packages/lib/src/config/definitions.ts | 15 ++++++++++++--- test/lib/config/classes.js | 15 +++++++++++++++ test/mock.js | 2 +- 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 092e55b4..8467cfaf 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ For the standalone installation mode you can use If you plan to make your cluster available externally set the address that it will be accessible under with, for example - npx clusteriocontroller config set controller.external_address http://203.0.113.4:1234/ + npx clusteriocontroller config set controller.public_url http://203.0.113.4:1234/ Change the url to reflect the IP, protocol, and port the controller is accessible under, dns names are also supported. If you're planning on making the controller accessible on the internet it's recommended to set up TLS, see the [Setting Up TLS](/docs/setting-up-tls.md) document for more details. diff --git a/docs/configuration.md b/docs/configuration.md index 8299e6c3..c09cafcd 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -51,9 +51,9 @@ interfaces. Defaults to null. -### controller.external_address +### controller.public_url -External address the controller is accessible on. +Public address the controller is accessible on. Currently only used for `clusteriocontroller bootstrap create-ctl-config` in order to give the right url to connect to. This should be a full URL ending with a /. diff --git a/packages/controller/src/Controller.ts b/packages/controller/src/Controller.ts index 405df8b7..1394053c 100644 --- a/packages/controller/src/Controller.ts +++ b/packages/controller/src/Controller.ts @@ -1115,7 +1115,7 @@ export default class Controller { } static calculateControllerUrl(config: lib.ControllerConfig) { - let url = config.get("controller.external_address"); + let url = config.get("controller.public_url"); if (!url) { if (config.get("controller.https_port")) { url = `https://localhost:${config.get("controller.https_port")}/`; diff --git a/packages/lib/src/config/classes.ts b/packages/lib/src/config/classes.ts index 673329e4..4770346c 100644 --- a/packages/lib/src/config/classes.ts +++ b/packages/lib/src/config/classes.ts @@ -187,6 +187,16 @@ export class Config< declare static fieldDefinitions: ConfigDefs; declare ["constructor"]: typeof Config; + /** + * Handle migration between clusterio versions + * + * @param config - Input config read and validated from file + * @returns Output config to be loaded into the class + * @protected + */ + static migrations(config: Static) { + return config; + } fields: Fields; _unknownFields: Record = {}; @@ -223,7 +233,7 @@ export class Config< ) as Fields; if (fields) { - this.update(fields, false, location); + this.update(this.constructor.migrations(fields), false, location); } } diff --git a/packages/lib/src/config/definitions.ts b/packages/lib/src/config/definitions.ts index c26ddf56..4315ade7 100644 --- a/packages/lib/src/config/definitions.ts +++ b/packages/lib/src/config/definitions.ts @@ -1,7 +1,7 @@ // Core definitions for the configuration system import * as classes from "./classes"; import type { PluginNodeEnvInfo, PluginWebpackEnvInfo } from "../plugin"; - +import { Static } from "@sinclair/typebox"; export interface ControllerConfigFields { "controller.name": string; @@ -11,7 +11,7 @@ export interface ControllerConfigFields { "controller.https_port": number | null; "controller.bind_address": string | null; "controller.trusted_proxies": string | null; - "controller.external_address": string | null; + "controller.public_url": string | null; "controller.tls_certificate": string | null; "controller.tls_private_key": string | null; "controller.auth_secret": string; @@ -34,6 +34,15 @@ export interface ControllerConfigFields { */ export class ControllerConfig extends classes.Config { declare static fromJSON: (json: classes.ConfigSchema, location: classes.ConfigLocation) => ControllerConfig; + static migrations(config: Static) { + if (config.hasOwnProperty("controller.external_address")) { + config["controller.public_url"] = config["controller.external_address"]; + delete config["controller.external_address"]; + } + + return config; + } + static fieldDefinitions: classes.ConfigDefs = { "controller.name": { title: "Name", @@ -89,7 +98,7 @@ export class ControllerConfig extends classes.Config { type: "string", optional: true, }, - "controller.external_address": { + "controller.public_url": { title: "Public URL", description: "Public facing URL the controller is hosted on, including the protocol.", type: "string", diff --git a/test/lib/config/classes.js b/test/lib/config/classes.js index cec34c9d..14615f71 100644 --- a/test/lib/config/classes.js +++ b/test/lib/config/classes.js @@ -7,6 +7,14 @@ const CA = lib.ConfigAccess; describe("lib/config/classes", function() { describe("Config", function() { class TestConfig extends lib.Config { + static migrations(config) { + if (config.hasOwnProperty("test.migration")) { + config["alpha.foo"] = config["test.migration"]; + delete config["test.migration"]; + } + return config; + } + static fieldDefinitions = { "alpha.foo": { type: "string", optional: true }, "beta.bar": { type: "object", initialValue: {} }, @@ -60,6 +68,13 @@ describe("lib/config/classes", function() { assert.equal(testInstance.fields["test.enum"], "b"); assert.equal(testInstance.fields["test.priv"], undefined); }); + it("should apply migrations", function() { + const config = new TestConfig("local", { + "test.migration": "foo", + }); + assert.equal(config.get("alpha.foo"), "foo"); + assert.equal(config.fields["test.migration"], undefined); + }); }); describe(".toJSON()", function() { diff --git a/test/mock.js b/test/mock.js index 47bba6aa..460fc5db 100644 --- a/test/mock.js +++ b/test/mock.js @@ -160,7 +160,7 @@ class MockController { this.app.locals.controller = this; this.app.locals.streams = new Map(); this.mockConfigEntries = new Map([ - ["controller.external_address", "test"], + ["controller.public_url", "test"], ["controller.auth_secret", "TestSecretDoNotUse"], ["controller.proxy_stream_timeout", 1], ]);