diff --git a/packages/lib/plugin.js b/packages/lib/plugin.js index 3d1e96fe..4dd71d08 100644 --- a/packages/lib/plugin.js +++ b/packages/lib/plugin.js @@ -286,6 +286,20 @@ class BaseMasterPlugin { */ async onInstanceStatusChanged(instance, prev) { } + /** + * Called when the value of an instance config field changed. + * + * Invoked after the value of the config field given by `field` has + * changed on an instance. + * + * @param {Object} instance - The instance the config changed on. + * @param {module:lib/config.ConfigGroup} group - + * The group who's field got changed on. + * @param {string} field - Name of the field that changed. + * @param {*} prev - The previous value of the field. + */ + async onInstanceConfigFieldChanged(instance, group, field, prev) { } + /** * Called before collecting Prometheus metrics * diff --git a/packages/master/src/ControlConnection.js b/packages/master/src/ControlConnection.js index 85e818bd..b640a005 100644 --- a/packages/master/src/ControlConnection.js +++ b/packages/master/src/ControlConnection.js @@ -174,6 +174,7 @@ class ControlConnection extends BaseConnection { let instance = { config: instanceConfig, status: "unassigned" }; this._master.instances.set(instanceId, instance); await libPlugin.invokeHook(this._master.plugins, "onInstanceStatusChanged", instance, null); + this._master.addInstancePluginHooks(instance); } async deleteInstanceRequestHandler(message, request) { diff --git a/packages/master/src/Master.js b/packages/master/src/Master.js index a1d680df..b6741603 100644 --- a/packages/master/src/Master.js +++ b/packages/master/src/Master.js @@ -151,6 +151,10 @@ class Master { this.userManager = new UserManager(this.config); await this.userManager.load(path.join(databaseDirectory, "users.json")); + for (let instance of this.instances.values()) { + this.addInstancePluginHooks(instance); + } + // Make sure we're actually going to listen on a port let httpPort = this.config.get("master.http_port"); let httpsPort = this.config.get("master.https_port"); @@ -305,7 +309,8 @@ class Master { let instanceConfig = new libConfig.InstanceConfig("master"); await instanceConfig.load(serializedConfig); let status = instanceConfig.get("instance.assigned_slave") === null ? "unassigned" : "unknown"; - instances.set(instanceConfig.get("instance.id"), { config: instanceConfig, status }); + let instance = { config: instanceConfig, status }; + instances.set(instanceConfig.get("instance.id"), instance); } } catch (err) { @@ -356,6 +361,12 @@ class Master { } } + addInstancePluginHooks(instance) { + instance.config.on("fieldChanged", (group, field, prev) => { + libPlugin.invokeHook(this.plugins, "onInstanceConfigFieldChanged", instance, group, field, prev); + }); + } + async loadPlugins() { for (let pluginInfo of this.pluginInfos) { if (!this.config.group(pluginInfo.name).get("load_plugin")) { diff --git a/packages/master/src/SlaveConnection.js b/packages/master/src/SlaveConnection.js index 5dbea73f..c2487efe 100644 --- a/packages/master/src/SlaveConnection.js +++ b/packages/master/src/SlaveConnection.js @@ -98,6 +98,7 @@ class SlaveConnection extends BaseConnection { instanceConfig.set("instance.assigned_slave", this._id); let newInstance = { config: instanceConfig, status: instanceData.status }; this._master.instances.set(instanceConfig.get("instance.id"), newInstance); + this._master.addInstancePluginHooks(newInstance); await libLink.messages.assignInstance.send(this, { instance_id: instanceConfig.get("instance.id"), serialized_config: instanceConfig.serialize("slave"),