From 6fc3abafd50b3dbdac973a2d98df73472badfb2b Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 22 Feb 2023 02:24:54 +0100 Subject: [PATCH] Rename Slave to Host The role of a slave as a host for Factorio servers is not well reflected in its name and has caused confusion among users. Rename slave to host to better reflect its role as a host of Factorio servers. --- .github/workflows/node.js.yml | 2 +- .gitignore | 2 +- CHANGELOG.md | 26 +-- Dockerfile | 2 +- README.md | 40 ++-- docker-compose.yml | 4 +- docs/communication.md | 4 +- docs/config-system.md | 12 +- docs/configuration.md | 52 ++--- docs/contributing.md | 4 +- docs/devs/protocol.md | 28 +-- docs/jsdoc.json | 4 +- docs/managing-a-cluster.md | 22 +-- docs/setting-up-tls.md | 4 +- docs/writing-plugins.md | 66 +++---- package.json | 2 +- packages/controller/README.md | 6 +- packages/controller/controller.js | 38 ++-- packages/controller/src/BaseConnection.js | 22 +-- packages/controller/src/ControlConnection.js | 182 +++++++++--------- packages/controller/src/Controller.js | 52 ++--- .../{SlaveConnection.js => HostConnection.js} | 54 +++--- packages/controller/src/WsServer.js | 42 ++-- packages/controller/src/routes.js | 22 +-- packages/create/create.js | 102 +++++----- packages/ctl/README.md | 4 +- packages/ctl/ctl.js | 6 +- packages/ctl/src/commands.js | 62 +++--- packages/{slave => host}/README.md | 30 +-- packages/{slave/slave.js => host/host.js} | 118 ++++++------ .../{slave => host}/lua/clusterio_lib/api.lua | 0 .../lua/clusterio_lib/changelog.txt | 0 .../lua/clusterio_lib/info.json | 0 .../lua/export/clusterio_api.lua | 0 .../{slave => host}/lua/export/control.lua | 0 .../lua/export/data-final-fixes.lua | 0 packages/{slave => host}/lua/export/info.json | 0 .../lua/export/settings-final-fixes.lua | 0 .../{slave => host}/modules/clusterio/api.lua | 0 .../modules/clusterio/impl.lua | 0 .../modules/clusterio/module.json | 0 .../modules/clusterio/serialize.lua | 0 packages/{slave => host}/package.json | 8 +- .../{slave/src/Slave.js => host/src/Host.js} | 44 ++--- packages/{slave => host}/src/Instance.js | 36 ++-- .../{slave => host}/src/InstanceConnection.js | 26 +-- packages/lib/README.md | 2 +- packages/lib/command.js | 36 ++-- packages/lib/config/definitions.js | 68 +++---- packages/lib/factorio/export.js | 4 +- packages/lib/link/messages.js | 122 ++++++------ packages/lib/logging.js | 22 +-- packages/lib/logging_utils.js | 26 +-- packages/lib/plugin.js | 98 +++++----- packages/lib/schema.js | 2 +- packages/lib/shared_commands.js | 2 +- packages/lib/users.js | 26 +-- .../src/components/AssignInstanceModal.jsx | 36 ++-- .../{SlaveViewPage.jsx => HostViewPage.jsx} | 38 ++-- .../{SlavesPage.jsx => HostsPage.jsx} | 70 +++---- .../web_ui/src/components/InstanceList.jsx | 36 ++-- .../src/components/InstanceViewPage.jsx | 16 +- packages/web_ui/src/components/LogConsole.jsx | 4 +- packages/web_ui/src/components/SavesList.jsx | 16 +- packages/web_ui/src/index.jsx | 2 +- packages/web_ui/src/model/host.jsx | 77 ++++++++ packages/web_ui/src/model/slave.jsx | 77 -------- packages/web_ui/src/pages.jsx | 18 +- packages/web_ui/src/util/websocket.jsx | 50 ++--- plugins/global_chat/README.md | 2 +- plugins/global_chat/info.js | 2 +- plugins/global_chat/instance.js | 2 +- plugins/global_chat/test/plugin.js | 2 +- plugins/inventory_sync/README.md | 2 +- plugins/inventory_sync/info.js | 12 +- plugins/inventory_sync/instance.js | 8 +- plugins/player_auth/README.md | 2 +- plugins/player_auth/info.js | 6 +- plugins/player_auth/instance.js | 2 +- plugins/player_auth/test/plugin.js | 4 +- plugins/research_sync/README.md | 2 +- plugins/research_sync/controller.js | 8 +- plugins/research_sync/info.js | 8 +- plugins/statistics_exporter/README.md | 2 +- plugins/statistics_exporter/info.js | 2 +- plugins/subspace_storage/README.md | 2 +- plugins/subspace_storage/controller.js | 4 +- plugins/subspace_storage/dole.js | 2 +- plugins/subspace_storage/dole_nn_base.js | 20 +- plugins/subspace_storage/info.js | 14 +- plugins/subspace_storage/instance.js | 6 +- test/controller/routes.js | 2 +- test/file/log/test-2021-12-10.log | 12 +- test/{slave.js => host.js} | 52 ++--- test/{slave => host}/Instance.js | 4 +- test/integration/clusterio.js | 88 ++++----- test/integration/index.js | 38 ++-- test/lib/command.js | 24 +-- test/lib/logging_utils.js | 8 +- test/lib/plugin.js | 4 +- test/mock.js | 14 +- 101 files changed, 1168 insertions(+), 1168 deletions(-) rename packages/controller/src/{SlaveConnection.js => HostConnection.js} (79%) rename packages/{slave => host}/README.md (64%) rename packages/{slave/slave.js => host/host.js} (67%) rename packages/{slave => host}/lua/clusterio_lib/api.lua (100%) rename packages/{slave => host}/lua/clusterio_lib/changelog.txt (100%) rename packages/{slave => host}/lua/clusterio_lib/info.json (100%) rename packages/{slave => host}/lua/export/clusterio_api.lua (100%) rename packages/{slave => host}/lua/export/control.lua (100%) rename packages/{slave => host}/lua/export/data-final-fixes.lua (100%) rename packages/{slave => host}/lua/export/info.json (100%) rename packages/{slave => host}/lua/export/settings-final-fixes.lua (100%) rename packages/{slave => host}/modules/clusterio/api.lua (100%) rename packages/{slave => host}/modules/clusterio/impl.lua (100%) rename packages/{slave => host}/modules/clusterio/module.json (100%) rename packages/{slave => host}/modules/clusterio/serialize.lua (100%) rename packages/{slave => host}/package.json (79%) rename packages/{slave/src/Slave.js => host/src/Host.js} (95%) rename packages/{slave => host}/src/Instance.js (97%) rename packages/{slave => host}/src/InstanceConnection.js (74%) rename packages/web_ui/src/components/{SlaveViewPage.jsx => HostViewPage.jsx} (60%) rename packages/web_ui/src/components/{SlavesPage.jsx => HostsPage.jsx} (74%) create mode 100644 packages/web_ui/src/model/host.jsx delete mode 100644 packages/web_ui/src/model/slave.jsx rename test/{slave.js => host.js} (61%) rename test/{slave => host}/Instance.js (98%) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index c3a3923d..4ac09a14 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -26,7 +26,7 @@ jobs: node-version: ${{ matrix.node-version }} - run: pnpm i --no-optional --no-frozen-lockfile - run: wget -q -O factorio.tar.gz https://www.factorio.com/get-download/latest/headless/linux64 && tar -xf factorio.tar.gz && rm factorio.tar.gz - - run: node packages/lib/build_mod --source-dir packages/slave/lua/clusterio_lib --output-dir temp/test/mods + - run: node packages/lib/build_mod --source-dir packages/host/lua/clusterio_lib --output-dir temp/test/mods - run: wget -q -O temp/test/mods/subspace_storage_1.99.8.zip -L https://github.com/clusterio/subspace_storage/releases/download/1.99.6/subspace_storage_1.99.8.zip - name: Run tests if: ${{ matrix.node-version != '12.x' }} diff --git a/.gitignore b/.gitignore index 97266127..7f4bb816 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,7 @@ Factorio* /plugin-list.json /config-controller.json /config-control.json -/config-slave.json +/config-host.json pnpm-lock.yaml mod_cache.json /static/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c37c33b..7ee98779 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,11 @@ Removed the Hotpatch scenario and the depency on it for getting code into the game. Added a save patcher than runs before starting up Factorio that patches in lua modules based on the event_loader lib into the savegame. Regular freeplay games can now be used with Clusterio and will be compatible without having to convert them to Hotpatch. -- Daemonized slaves. - Slaves now have the ability to run multiple Factorio instances, starting and stopping them individually. +- Daemonized hosts. + Hosts now have the ability to run multiple Factorio instances, starting and stopping them individually. To manage this the local command line interface has been replaced with a remote interface on the controller that can be accessed through the clusterioctl cli tool. -- Rewritten the communication between slaves and the controller from scratch. - The new system is based on a WebSocket connection between the slaves and the controller and provides efficient validated bi-directonal communication. +- Rewritten the communication between hosts and the controller from scratch. + The new system is based on a WebSocket connection between the hosts and the controller and provides efficient validated bi-directonal communication. - Rewritten the plugin system from scratch. Plugins now inherit from a base class and use the same WebSocket connection Clusterio uses to communicate. - New configuration system with support for initializing configs when needed, modifying config entries using built-in commands, and updating instance configuration remotely. @@ -37,8 +37,8 @@ Previously this was handled by the playerManager plugin. - Added stripping of long paths in the Factorio server log. - Added option to configure maximum number of commands to send in parallel. -- Added option to auto start instances on slave startup. -- Added metric mapping of slave and instance ids to their names, allowing them to be displayed by name in queries that join with the mapping. +- Added option to auto start instances on host startup. +- Added metric mapping of host and instance ids to their names, allowing them to be displayed by name in queries that join with the mapping. - Added option to configure timeout for exported Prometheus metrics. - Added option to set address to bind HTTP(S) port to. - Added an overview of the installed plugins to the web interface. @@ -69,16 +69,16 @@ - Removed factorio_version from config. The version installed is auto detected and used instead. - Removed the playerManager specific command CLI tools/delete_player.js. -- Creating an instance, assigning it to a slave, creating a save for an instance and starting an instance is now four separate commands. -- Removed oddball limits to slaves.json size. -- Moved slave specific and instance specific configuration into their own configuration files. +- Creating an instance, assigning it to a host, creating a save for an instance and starting an instance is now four separate commands. +- Removed oddball limits to hosts.json size. +- Moved host specific and instance specific configuration into their own configuration files. - Removed unused binary option from plugin config. - Removed info and shout command from globalChat plugin - Removed mirrorAllChat and enableCrossServerShout configuration options for globalChat plugin. - Removed UPSdisplay plugin. UPS statistics is exported by the statistics exporter plugin. - Controller now defaults to hosting on https on port 8443. - Renamed master to controller. -- Renamed client to slave. +- Renamed slave/client to host. - Removed rotation of factorio-current.log files. ### Breaking Changes @@ -101,7 +101,7 @@ - Removed the remoteCommands plugin and the old runCommand interface. Breaks playerManager and external tools sending commands. - Removed broken serverManager plugin. -- Removed fields info, time, rconPort, rconPassword, serverPort, unique, mods, instanceName, playerCount, mac, and meta from the slaves in the slave database. +- Removed fields info, time, rconPort, rconPassword, serverPort, unique, mods, instanceName, playerCount, mac, and meta from the hosts in the host database. - Removed getInstanceName and lib/clusterTools. Breaks playerManager, and discordChat. - Removed the /api/rconPasswords, and /api/slaves endpoints. @@ -110,7 +110,7 @@ Breaks researchSync, and UPSdisplay. - Removed the hello event from the socket connection handshake. Breaks playerManager, trainTeleports, serverSelect, and discordChat -- Changed the format of database/slaves.json. +- Changed the format of database/hosts.json. - Removed the output file subscription system. Breaks inventoryImports, playerManager, trainTeleports, serverSelect and researchSync. - Removed the factorioOutput hook from instance plugins. @@ -135,7 +135,7 @@ - Removed msBetweenCommands config option. The RCON is instead limited to 5 concurrent commands. - Removed allowRemoteCommandExecution config option. - Remote commands are always allowed with the move to controller managing slaves/instances. + Remote commands are always allowed with the move to controller managing hosts/instances. - Removed `--databaseDirectory`, `--controllerPort`, and `--sslPort` command line arguments from the controller. - Implemented a new config system that replaces the old. Breaks all plugins. diff --git a/Dockerfile b/Dockerfile index a6052df5..babd6bfa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,7 @@ RUN pnpm install COPY --from=subspace_storage_builder /subspace_storage/dist/ /clusterio/mods/ # Build Lua library mod -RUN node packages/lib/build_mod --build --source-dir packages/slave/lua/clusterio_lib \ +RUN node packages/lib/build_mod --build --source-dir packages/host/lua/clusterio_lib \ && mv dist/* mods/ \ && mkdir temp \ && mkdir temp/test \ diff --git a/README.md b/README.md index 9ef6594a..7de44352 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ If you are starting a new cluster, it's highly recommended to use the 2.0 alpha. * [Managing Factorio mods](#managing-factorio-mods) * [Setting up shared storage](#setting-up-shared-storage) * [Running Clusterio](#running-clusterio) -* [Setting up remote slaves](#setting-up-remote-slaves) +* [Setting up remote hosts](#setting-up-remote-hosts) * [Setting up clusterioctl](#setting-up-clusterioctl) * [Common problems](#Common-problems) @@ -128,7 +128,7 @@ Clusterio has *very* limited support for using docker. sudo docker run --name controller -e MODE=controller -p 1234:8080 -d -it --restart=unless-stopped danielvestol/clusterio - sudo docker run --name slave -e MODE=slave -e INSTANCE=world1 -v /srv/clusterio/instances:/clusterio/instances -p 1235:34167 -it --restart=unless-stopped danielvestol/clusterio + sudo docker run --name host -e MODE=host -e INSTANCE=world1 -v /srv/clusterio/instances:/clusterio/instances -p 1235:34167 -it --restart=unless-stopped danielvestol/clusterio The -v flag is used to specify the instance directory. Your instances (save files etc) will be stored there. @@ -175,9 +175,9 @@ Then tell clusterio that this plugin exists by adding it as a plugin. npx clusteriocontroller plugin add @clusterio/plugin-subspace_storage -This adds it to the default `plugin-list.json` file which in the shared folder setup is loaded by controller, slave and ctl. -If you have slaves or ctl installed on separate computers (or directories) then you need to repeat the plugin install process for all of them. -The clusteriocontroller, clusterioslave and clusterioctl commands has the plugin sub-command so you do not need to install clusteriocontroller to add plugins, instead use the clusterio command you have available. +This adds it to the default `plugin-list.json` file which in the shared folder setup is loaded by controller, host and ctl. +If you have hosts or ctl installed on separate computers (or directories) then you need to repeat the plugin install process for all of them. +The clusteriocontroller, clusteriohost and clusterioctl commands has the plugin sub-command so you do not need to install clusteriocontroller to add plugins, instead use the clusterio command you have available. For development purposes the `plugin add` command supports adding plugins by the absolute path to them, or a relative path that must start with either . or .. (which will then be resolved to an absolute path). @@ -189,10 +189,10 @@ You can change the port used with the command npx clusteriocontroller config set controller.http_port 1234 -When changing the port you will also need to change the address slaves connect with. +When changing the port you will also need to change the address hosts connect with. For the standalone installation mode you can use - npx clusterioslave config set slave.controller_url http://localhost:1234/ + npx clusteriohost config set host.controller_url http://localhost:1234/ If you plan to make your cluster available externally set the address that it will be accessible under with, for example @@ -208,7 +208,7 @@ See the [readme for @clusterio/controller](/packages/controller/README.md) for m ## Managing Factorio mods -Clusterio currently only provides a manual method for running mods on servers by copying them either to each instance's individual `mods` folder, or by copying them into a slave installation's `sharedMods` folder which will link/copy them to the `mods` folder of each instance on that slave if the file doesn't already exist in the `mods` folder for that instance. +Clusterio currently only provides a manual method for running mods on servers by copying them either to each instance's individual `mods` folder, or by copying them into a host installation's `sharedMods` folder which will link/copy them to the `mods` folder of each instance on that host if the file doesn't already exist in the `mods` folder for that instance. Mods are copied from `sharedMods` on Windows and symlinked on Linux, this means that when mods are removed from `sharedMods` the mods will also be removed from the instance's `mods` folder on Linux if it got there by being linked by Clusterio, but not on Windows. For managing the mod settings, the `mod-settings.dat` and `mod-list.json` files will also be linked/copied over if present in `sharedMods`, but since Factorio creates these files automatically it might be necessary to delete them from each instance's `mods` folder for changes to them in `sharedMods` to take effect. @@ -219,45 +219,45 @@ Better remote management of mods is a planned feature. ## Setting up shared storage The chests teleporting items to and from the shared storage on the controller has been moved into the Subspace Storage mod and plugin. -To get this to work you will need to install the Subspace Storage plugin and copy the [Subspace Storage mod](https://mods.factorio.com/mod/subspace_storage) and the [Clusterio Lib mod](https://mods.factorio.com/mod/clusterio_lib) into the `sharedMods` folder on each slave installation. +To get this to work you will need to install the Subspace Storage plugin and copy the [Subspace Storage mod](https://mods.factorio.com/mod/subspace_storage) and the [Clusterio Lib mod](https://mods.factorio.com/mod/clusterio_lib) into the `sharedMods` folder on each host installation. Do not install the [Clusterio mod](https://mods.factorio.com/mod/clusterio), this was for the old 1.2.x version of Clusterio and is not compatible with Clusterio 2.0. ## Running Clusterio -After completing the installation start up the controller and at least one slave separately. -The installer provides the `run-controller` and `run-slave` scripts to make this simple. +After completing the installation start up the controller and at least one host separately. +The installer provides the `run-controller` and `run-host` scripts to make this simple. Once the controller process is running you can log into the web interface which is hosted by default on http://localhost:8080/ (adjust the port number if you changed it), use the admin authentication token provided from the installation to log in. -The basics of setting up a Factorio server from the web interface is to create an instance, assign it to a slave and then click start. +The basics of setting up a Factorio server from the web interface is to create an instance, assign it to a host and then click start. ### Running via Systemd -The install script creates systemd service scripts for clusteriocontroller and clusterioslave (if applicable) to start up as the user than ran the installer. +The install script creates systemd service scripts for clusteriocontroller and clusteriohost (if applicable) to start up as the user than ran the installer. If you have copied these files over to `/etc/systemd/system/` then you can startup Clusterio as a background service using: #### To start as a service run: sudo systemctl start clusteriocontroller # for the controller - sudo systemctl start clusterioslave # for each server hosting a slave + sudo systemctl start clusteriohost # for each physical server intended to host Factorio servers #### To automatically get it to start on boot: sudo systemctl enable clusteriocontroller # for the controller - sudo systemctl enable clusterioslave # for each server hosting a slave + sudo systemctl enable clusteriohost # for each physical server intended to host Factorio servers -## Setting up remote slaves +## Setting up remote hosts -Run the installer as described in the installation section and choose "Slave only" as the operating mode to install, it'll ask for a controller URL and an authentication token. -The URL is the same as what is needed to connect to the web interface, and the authentication token can be generated on the Slaves page in the web interface. -Once you start up the slave it should show up in the Slaves list and be available for assigning and running instances on. +Run the installer as described in the installation section and choose "Host only" as the operating mode to install, it'll ask for a controller URL and an authentication token. +The URL is the same as what is needed to connect to the web interface, and the authentication token can be generated on the Hosts page in the web interface. +Once you start up the host it should show up in the Hosts list and be available for assigning and running instances on. ## Setting up clusterioctl -There's a command line interface available for Clusterio which is installed separately with the same installer as for the controller and slave. +There's a command line interface available for Clusterio which is installed separately with the same installer as for the controller and host. Run the installer as described in the installation section and choose "Ctl only" as the operating mode to install, you can do this in the same directory as you have installed other Clusterio component(s) to. The installer will ask for a controller URL and an authentication token, these are the same as you would use to connect to the web interface. If you want to use a different user for the command line interface, you can generate an authentication token for an existing user with diff --git a/docker-compose.yml b/docker-compose.yml index cf6123f4..a46d2210 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,6 +4,6 @@ services: controller: build: . command: npx clusteriocontroller run - slave: + host: build: . - command: npx clusterioslave run + command: npx clusteriohost run diff --git a/docs/communication.md b/docs/communication.md index 63805da9..077baa15 100644 --- a/docs/communication.md +++ b/docs/communication.md @@ -11,8 +11,8 @@ Links represents one side of a two way communication pipe, connectors deal with The Link class represents one side of a two way communication channel where the actual communication is done by a connector associated with the link. The link also knows what the endpoint types it's connected to are via the source and target attributes. -The endpoint types currently implemented are controller, slave, instance, and control. -Although slave and instances run in the same Node.js program they use virtual links to communicate between them in order to simplify the communication architecture. +The endpoint types currently implemented are controller, host, instance, and control. +Although host and instances run in the same Node.js program they use virtual links to communicate between them in order to simplify the communication architecture. Upon creation the link will register with the connector in order to receive and process messages from it. The messages received are validated using the validator registered for the type of the message. diff --git a/docs/config-system.md b/docs/config-system.md index c1bc4a3f..3cfdec8b 100644 --- a/docs/config-system.md +++ b/docs/config-system.md @@ -2,7 +2,7 @@ This document describes the implementation and inner working of the configuration system in Clusterio, and unless you're developing Clusterio it's probably not going to be very useful for you. -Clusterio uses a group based configuration system to manage settings for the controller, instances, slaves, and the clusterioctl utility. +Clusterio uses a group based configuration system to manage settings for the controller, instances, hosts, and the clusterioctl utility. Plugins get their own config group for the controller and instances which they can add their own fields to. The fields are defined early in the startup, and the groups and their fields for disabled plugins will still be created. @@ -17,10 +17,10 @@ The `define` method takes an object as argument with the following properties: **access**: The locations this config field can be read and modified from. - This is an array of strings which can contain the values `"controller"`, `"slave"` and `"control"`. + This is an array of strings which can contain the values `"controller"`, `"host"` and `"control"`. If a party is missing in this array then that party will not receive the value of this field when the config is shared, and will be unable to modify the field. Takes the value of `defaultAccess` set on the config group class if not passed. - Note that instance config groups should have both `"controller"` and `"slave"` for all of its fields or unexpected behaviour may occur. + Note that instance config groups should have both `"controller"` and `"host"` for all of its fields or unexpected behaviour may occur. **type**: The type of config value this field will support. @@ -73,6 +73,6 @@ Values for all config fields are created when the config is initialized, as well Once a field has a value it is never automatically removed, even if the field or group it was part of no longer exists. This ensures that plugin configuration is not lost should the server be started up without the plugins that defined the configuration installed. -For instance configs, they are kept on the controller and serialized and sent over to the relevant slaves on startup. -This makes it possible to edit instance configs when the slave the instance is on is offline. -A copy is also stored in the instance directory on the slave, and this config will be deliverd to the controller on slave startup, which enables instances to be copied between clusters as long as their IDs are unique. +For instance configs, they are kept on the controller and serialized and sent over to the relevant hosts on startup. +This makes it possible to edit instance configs when the host the instance is on is offline. +A copy is also stored in the instance directory on the host, and this config will be deliverd to the controller on host startup, which enables instances to be copied between clusters as long as their IDs are unique. diff --git a/docs/configuration.md b/docs/configuration.md index b819d720..8299e6c3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -76,7 +76,7 @@ Defaults to "database/certificates/cert.key". ### controller.auth_secret -Base64 encoded authentication secret used to verify tokens issued to slaves, users, and sessions. +Base64 encoded authentication secret used to verify tokens issued to hosts, users, and sessions. This should contain 256 bytes of random data, and if changed will cause all tokens become invalid. Keep this secret if leaked an attacker could easily compromise the cluster. @@ -104,7 +104,7 @@ Defaults to 60. ### controller.metrics_timeout -Timeout in seconds before a call to gather metrics from a slave times out. +Timeout in seconds before a call to gather metrics from a host times out. This should be less than both the timeout and collection interval configured for the collection job in Prometheus. Defaults to 8. @@ -134,24 +134,24 @@ Plugins not loaded on the controller will not be loaded on instances. Defaults to true. -## Slave Configuration +## Host Configuration -### slave.name +### host.name -Name of the slave. -Shows up in slave lists and is used to reference this slave in the clusterioctl command line interface. +Name of the host. +Shows up in host lists and is used to reference this host in the clusterioctl command line interface. -Defaults to "New Slave". +Defaults to "New Host". -### slave.id +### host.id -Immutable numeric id of the slave which uniquely identifies this slave in the cluster. +Immutable numeric id of the host which uniquely identifies this host in the cluster. Defaults to a random 31 bit number. -### slave.factorio_directory +### host.factorio_directory Directory to look for the Factorio server(s) in. This can either point to a Factorio server directory, or to a directory containing multiple versions of the Factorio server. @@ -159,46 +159,46 @@ This can either point to a Factorio server directory, or to a directory containi Defaults to "factorio". -### slave.instances_directory +### host.instances_directory Directory to store instances in. -One sub-directory will be created in it for each instance assigned to this slave and these sub-directories will contain logs, saves, and various auto generated configuration files for the instances. +One sub-directory will be created in it for each instance assigned to this host and these sub-directories will contain logs, saves, and various auto generated configuration files for the instances. Defaults to "instances". -### slave.controller_url +### host.controller_url URL to connect to the controller to. Defaults to "http://localhost:8080/". -### slave.controller_token +### host.controller_token Access token used for authenticating with the controller. -You can generate an access token with `clusterioctl slave generate-token --id `, or use the `clusterioctl slave create-config` to create a new slave config with the correct url and token in it. +You can generate an access token with `clusterioctl host generate-token --id `, or use the `clusterioctl host create-config` to create a new host config with the correct url and token in it. Defaults to "enter token here". -### slave.tls_ca +### host.tls_ca Path to certificate in PEM format to use for validating a TLS connection to the controller. -If you have a self signed certificate on the controller you will need to copy the certificate to your slaves and set it as the certificate authority with this option. +If you have a self signed certificate on the controller you will need to copy the certificate to your hosts and set it as the certificate authority with this option. Defaults to null meaning use Node.js's default set of trusted certificate authorities. -### slave.public_address +### host.public_address -External address instances hosted on this slave can be accessed on. +External address instances hosted on this host can be accessed on. This is used by plugins like Server Select to give the correct address to switch between instances in-game. Defaults to "localhost". -### slave.max_reconnect_delay +### host.max_reconnect_delay Maximum delay in seconds to wait after connection to the controller is dropped before attempting to reconnect to it. The actual delay on each reconnect will be a random number between 0 and this configured value to avoid all clients trying to reconnect at the same time. @@ -222,19 +222,19 @@ Imutable numeric id of the instance which uniquely identifies this instance in t Defaluts to a random 31 bit integer. -### instance.assigned_slave +### instance.assigned_host -Slave this instance is assigned to. +Host this instance is assigned to. To change this you need to use the separate assign instance interface. -After being assigned to a slave the directory for the instance is created on the slave. +After being assigned to a host the directory for the instance is created on the host. Defaults to null meaning not assigned. ### instance.auto_start -If enabled start this instance when the slave it is assigned to is started up. -Does not affect start or stop of the instance while the slave is running. +If enabled start this instance when the host it is assigned to is started up. +Does not affect start or stop of the instance while the host is running. Defaults to false. @@ -242,7 +242,7 @@ Defaults to false. ### factorio.version Version of Factorio to use for this instance. -Can be a version like "1.0.0" or special string "latest" meaning the latest version of Factorio found on the slave. +Can be a version like "1.0.0" or special string "latest" meaning the latest version of Factorio found on the host. Defaults to "latest". diff --git a/docs/contributing.md b/docs/contributing.md index e140ee90..0d767e02 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -69,14 +69,14 @@ The `plugins/` directory contains the core plugins for the project and can be ad The documentation uses the binaries provided by the packages, but for the development environment you will need to call the packages directly: npx clusteriocontroller -> node packages/controller - npx clusterioslave -> node packages/slave + npx clusteriohost -> node packages/host npx clusterioctl -> node packages/ctl Note that to use `clusterioctl` you will have to create a control config first: node packages/controller bootstrap create-ctl-config [admin-user] -Once you've set up the cluster you can use `node packages/controller run` to run the controller and `node packages/slave run` to run the slave which connects to the controller. +Once you've set up the cluster you can use `node packages/controller run` to run the controller and `node packages/host run` to run the host which connects to the controller. For web development on the controller there are also the following flags: diff --git a/docs/devs/protocol.md b/docs/devs/protocol.md index 9fa61fbd..230ad045 100644 --- a/docs/devs/protocol.md +++ b/docs/devs/protocol.md @@ -12,8 +12,8 @@ Events and requests are defined as instances of the `Request` and `Event` classe All messages sent and received are validated with JSON schemas to catch potential errors in sending messages and avoid having to write lots of validation code in message handlers. Messages are sent by calling the `.send()` method of the message instance and passing a `Link` instance to send it over and the data to send. -For the controller there's a `Link` instance for each slave and control connection stored in the `WsServer` class. -For slaves the `Slave` instance is a link to the controller, and each `Instance` instance is an in-memory link to the `Slave` instance and has a corresponding `InstanceConnection` link stored on the `Slave` instance. +For the controller there's a `Link` instance for each host and control connection stored in the `WsServer` class. +For hosts the `Host` instance is a link to the controller, and each `Instance` instance is an in-memory link to the `Host` instance and has a corresponding `InstanceConnection` link stored on the `Host` instance. For ctl and web_ui there's a `Control` instance that acts as the link to the controller. Messages received invokes message handlers that were registered when the link was brought up. @@ -24,7 +24,7 @@ The handlers are defined on the link class itself for core messages, and on the ## Connection flow Clients connect via WebSocket to the `/api/socket` endpoint and upon establishing connection to the server the connection is in the handshake phase and the server will send a `hello` message to the client. -If the client has no previous session with the server it sends a `register_slave` or `register_control` message depending on what kind of client it is to the server. +If the client has no previous session with the server it sends a `register_host` or `register_control` message depending on what kind of client it is to the server. If the register is valid then the server will respond with a `ready` message with a session token and the connection has left the handshake phase, otherwise the server will close the connection with a WebSocket close code indicating the kind of failure. Upon leaving the handshake phase both parties should start sending heartbeat messages with the sequence number of the last received message. @@ -33,7 +33,7 @@ Messages sent over the link should be stored in a send buffer and only cleared f If the connection goes stale or is unexpectedly closed the client can reastablish the same session by connecting to the server again and sending a `resume` message after received the `hello` from the server. If the session resume is successful then the server will respond with a `continue` message and the connection is active again. The client should then re-send all messages it has in its send buffer that is greater than the `last_seq` number in the `continue` message. -Otherwise the server will respond with `invalidate` and the client is expected to drop its send buffer start a new session with `register_slave` or `register_control`. +Otherwise the server will respond with `invalidate` and the client is expected to drop its send buffer start a new session with `register_host` or `register_control`. ![Connection flow](../assets/connection_flow.svg) @@ -102,17 +102,17 @@ Sent by the controller when the WebSocket connection has been opened. - `plugins: Object` - Object mapping plugin names to plugin version for plugins that are loaded on the controller. -#### `register_slave` +#### `register_host` -Slave handshake for establishing a new connection session. +Host handshake for establishing a new connection session. - `token: string` - Authentication token. - `agent: string` - Human readable string of the software connecting. -- `version: string` - The protocol version of the slave, e.g. "2.0.0". -- `name: string` - Name of the slave. -- `id: integer` - ID of the slave. +- `version: string` - The protocol version of the host, e.g. "2.0.0". +- `name: string` - Name of the host. +- `id: integer` - ID of the host. - `plugins: Object` - - Object mapping plugin names to plugin version for plugins that are available on the slave. + Object mapping plugin names to plugin version for plugins that are available on the host. #### `register_control` @@ -235,15 +235,15 @@ Server hello after opening the WebSocket. } ``` -Slave registering a new connection session. +Host registering a new connection session. ```json { "seq": null, - "type": "register_slave", + "type": "register_host", "data": { "token": "xyzabc123", - "agent": "Clusterio Slave", + "agent": "Clusterio Host", "version": "2.0.0", "name": "Foo", "id": 123 @@ -265,4 +265,4 @@ Controller reply signaling the session is established and ready. } ``` -Slave and controller can now send events and requests over the connection. +Host and controller can now send events and requests over the connection. diff --git a/docs/jsdoc.json b/docs/jsdoc.json index 96368a55..777c03a5 100644 --- a/docs/jsdoc.json +++ b/docs/jsdoc.json @@ -13,8 +13,8 @@ "include": [ "packages/controller/src/", "packages/controller/controller.js", - "packages/slave/src/", - "packages/slave/slave.js", + "packages/host/src/", + "packages/host/host.js", "packages/ctl/src/", "packages/ctl/ctl.js", "packages/lib/", diff --git a/docs/managing-a-cluster.md b/docs/managing-a-cluster.md index 7c4fe792..261d4241 100644 --- a/docs/managing-a-cluster.md +++ b/docs/managing-a-cluster.md @@ -8,25 +8,25 @@ Before `clusterioctl` can be used it needs to be configured for the cluster it w The easiest way to do this is to run `npx clusteriocontroller bootstrap create-ctl-config ` on the controller, which creates the necessary `config-control.json` for managing the cluster as the given user. -## Slaves +## Hosts -### List slaves +### List hosts - ctl> slave list + ctl> host list -Lists all slaves. +Lists all hosts. ### Generate token - ctl> slave generate-token [--id ] + ctl> host generate-token [--id ] -Generate a token for a slave. `--id` is the slave id. +Generate a token for a host. `--id` is the host id. ### Create config - ctl> slave create-config [--id ] [--name ] [--generate-token ] [--output ] + ctl> host create-config [--id ] [--name ] [--generate-token ] [--output ] -Create a slave config. `--id` id the slave id. `--name` is the slave name. `--generate-token` decides whether to also generate a token, defaulting to `0`. `--output` is the filename for the output of the config; Default is "config-slave.json", "-" for stdout. +Create a host config. `--id` id the host id. `--name` is the host name. `--generate-token` decides whether to also generate a token, defaulting to `0`. `--output` is the filename for the output of the config; Default is "config-host.json", "-" for stdout. ## Instances @@ -85,11 +85,11 @@ To be written. Edit instance config in a text editor. Once file is saved and editor has been exited, config values will be read back in. `instance` is the instance to edit, `editor` is the editor to use. If `editor` is not given, clusterioctl will read from the `EDITOR` or `VISUAL` enviroment variables. -### Assign instance to slave +### Assign instance to host - ctl> instace assign [slave] + ctl> instace assign [host] -Assigns instance to slave. `instance` is instance to assign, `slave` is slave to assign to. If `slave` is not provided, instance will be unassigned. +Assigns instance to host. `instance` is instance to assign, `host` is host to assign to. If `host` is not provided, instance will be unassigned. ## Users diff --git a/docs/setting-up-tls.md b/docs/setting-up-tls.md index c8d90c06..93c47c9e 100644 --- a/docs/setting-up-tls.md +++ b/docs/setting-up-tls.md @@ -63,9 +63,9 @@ This creates a private key file named `key.pem` and a public certificate file na npx clusteriocontroller config set controller.tls_certificate cert.pem npx clusteriocontroller config set controller.tls_private_key key.pem -Additionally you will need copy the `cert.pem` file to all of the computers you want to set up as slaves and configure it as the `slave.tls_ca` option: +Additionally you will need copy the `cert.pem` file to all of the computers you want to set up as hosts and configure it as the `host.tls_ca` option: - npx clusterioslave config set slave.tls_ca cert.pem + npx clusteriohost config set host.tls_ca cert.pem You will also need to copy the `cert.pem` file to all of the computers you want to remotely manage the cluster via clusterctl and configure it as `control.tls_ca` option: diff --git a/docs/writing-plugins.md b/docs/writing-plugins.md index bb86c67e..026efc5a 100644 --- a/docs/writing-plugins.md +++ b/docs/writing-plugins.md @@ -41,7 +41,7 @@ The usual guides for creating such packages apply. At minimum the `package.json` file must contain a version entry. A possible workflow for developing plugins is to place the plugin in a sub-directory of where clusterio has been installed, and rely on Node.js searching up the folder heirarchy for it to find `@clusterio/lib`. -To add it to `plugin-list.json` so that it gets loaded use the `plugin add ` sub-command to either clusteriocontroller, clusterioslave or clusterioctl. +To add it to `plugin-list.json` so that it gets loaded use the `plugin add ` sub-command to either clusteriocontroller, clusteriohost or clusterioctl. Note that it's important that the path starts with ./ or ../ (use .\ or ..\ on Windows). For a plugin the most important file is the `info.js` file. @@ -157,7 +157,7 @@ The async init method is always called immediatly after the constructor, so ther ## Logging Messages The base plugin classes provide a winston logger for logging messages to the shared cluster log. -For instances a copy of the log is also stored on the slave the instance is on. +For instances a copy of the log is also stored on the host the instance is on. To use it, pass a string to one of the log levels functions, for example: ```js @@ -209,7 +209,7 @@ For example in info.js: const libConfig = require("@clusterio/lib/config"); class ControllerConfigGroup extends libConfig.PluginConfigGroup { } -ControllerConfigGroup.defaultAccess = ["controller", "slave", "control"]; +ControllerConfigGroup.defaultAccess = ["controller", "host", "control"]; ControllerConfigGroup.groupName = "foo_frobber"; ControllerConfigGroup.define({ name: "level", @@ -314,7 +314,7 @@ For RCON, commands longer than 50 characters may end up being executed after sho ## Defining Link Messages You will most likely have to communicate with the controller or other instances in your plugin for it to do anything useful. -For this there's a WebSocket communication channel established between the slaves and the controller that plugins can define their own messages to send over it. +For this there's a WebSocket communication channel established between the hosts and the controller that plugins can define their own messages to send over it. This channel is bi-directional and all messages sent over it are validated with a JSON schema (see [this guide][guide] for an introduction to writing JSON schema). [guide]: https://json-schema.org/learn/getting-started-step-by-step.html @@ -335,7 +335,7 @@ The Event constructor takes an object of properties that define the event, for e messages: { startFrobnication: new libLink.Event({ type: "foo_frobber:start_frobnication", - links: ["controller-slave", "slave-instance"], + links: ["controller-host", "host-instance"], forwardTo: "instance", eventRequired: ["frobnication_type"], eventProperties: { @@ -346,9 +346,9 @@ messages: { }, ``` -This specifies an event that can be sent from the controller to a slave, and from a slave to an instance. +This specifies an event that can be sent from the controller to a host, and from a host to an instance. It also specifies that the event must contain the property `frobnication_type`, with a string value in the data payload and that it may optionally contain a boolean `urgent` property. -It will also be forwarded by slaves to a specific instance. +It will also be forwarded by hosts to a specific instance. The following properties are recognized by the Event constructor: @@ -361,17 +361,17 @@ The type of the message sent over the socket will have the suffix `_event` appen #### links An array of strings describing which links this event can be sent over. -Direction matters, `"controller-slave"` means the event can be sent from the controller to the slave, but can't be sent back the other way, unless `"slave-controller"` is also present in the links array. +Direction matters, `"controller-host"` means the event can be sent from the controller to the host, but can't be sent back the other way, unless `"host-controller"` is also present in the links array. -The available endpoints are `controller`, `slave`, `instance`, and `control`. -Controller talks with slave and control, and slave talks to instance. -The full chain must be specified as the individual links in order for a message to travers multiple hops, (i.e., for a message to go from controller to instance it must have both `"controller-slave"` and `"slave-instance"` in the links array). +The available endpoints are `controller`, `host`, `instance`, and `control`. +Controller talks with host and control, and host talks to instance. +The full chain must be specified as the individual links in order for a message to travers multiple hops, (i.e., for a message to go from controller to instance it must have both `"controller-host"` and `"host-instance"` in the links array). See `forwardTo` and `broadcastTo` for ways to forward an event to the next link in a chain. #### forwardTo Target to forward an event to. -Can either be `"controller"`, to indicate a slave should forward it to the controller, or `"instance"`, to indicate it should be forwarded to the instances specified by the `instance_id` event property. +Can either be `"controller"`, to indicate a host should forward it to the controller, or `"instance"`, to indicate it should be forwarded to the instances specified by the `instance_id` event property. This works by using a default handler for the event at the links that forward it. #### broadcastTo @@ -379,7 +379,7 @@ This works by using a default handler for the event at the links that forward it Target to broadcast this message towards. A value of "instance" means the event will be broadcast to all instances downstream of the target it's sent to, but not back from where it came from. Currently, only "instance" is supported. -This means that sending the event to a slave from an instance will cause it to be broadcast to all instances of that slave except for the instance it came from. +This means that sending the event to a host from an instance will cause it to be broadcast to all instances of that host except for the instance it came from. #### eventRequired @@ -394,7 +394,7 @@ This is equivalent to using the `properties` keyword in JSON schema, except that See [this guide][guide] for an introduction to writing JSON schemas. The forwardTo and broadcastTo can be combined such that specifying `"controller"` as the forwardTo value and `"instance"` as the broadcastTo value will cause the event to be broadcast to all instances in the cluster. -For this to work, you will need to specify `instance-slave`, `slave-controller`, `controller-slave`, and `slave-instance` as the links. +For this to work, you will need to specify `instance-host`, `host-controller`, `controller-host`, and `host-instance` as the links. Keep in mind when forwarding events that if the target an event is being forwarded to is not online, the event will be dropped. Use a request if you need a confirmation that the message was received. @@ -410,7 +410,7 @@ For example, the following could be defined in `info.js`: messages: { reportFrobnication: new libLink.Request({ type: "foo_frobber:report_frobnication", - links: ["controller-slave", "slave-instance"], + links: ["controller-host", "host-instance"], forwardTo: "instance", requestRequired: ["verbosity"], requestProperties: { @@ -427,10 +427,10 @@ messages: { }, ``` -This specifies a request that can be sent from the controller to a slave, and from a slave to an instance. +This specifies a request that can be sent from the controller to a host, and from a host to an instance. The request data must contain the property `verbosity` with an integer number as the value, as well as the `instance_id` property (implied by `forwardTo: "instance"`) and it may also contain a boolean `special` property. It also defines that the response sent must contain a `report` property mapping to an array of strings. -When received by a slave, it will also be forwarded to the instance specified by `instance_id`. +When received by a host, it will also be forwarded to the instance specified by `instance_id`. The following properties are recognized by the Request constructor: @@ -443,17 +443,17 @@ The type of the message sent over the socket will have the suffix `_request` app #### links An array of strings describing which links this request can be sent over. -Direction matters; `"controller-slave"` means the request can be sent from the controller to the slave and the slave can reply to the controller, but the slave can't send a request to the controller unless `"slave-controller"` is also present in the links array. +Direction matters; `"controller-host"` means the request can be sent from the controller to the host and the host can reply to the controller, but the host can't send a request to the controller unless `"host-controller"` is also present in the links array. -The available endpoints are `controller`, `slave`, `instance`, and `control`. -Controller talks with slave and control, and slave talks to instance. -The full chain must be specified as the individual links in order for a message to travers multiple hops, (i.e., for a message to go from controller to instance it must have both `"controller-slave"` and `"slave-instance"` in the links array). +The available endpoints are `controller`, `host`, `instance`, and `control`. +Controller talks with host and control, and host talks to instance. +The full chain must be specified as the individual links in order for a message to travers multiple hops, (i.e., for a message to go from controller to instance it must have both `"controller-host"` and `"host-instance"` in the links array). See `forwardTo` for ways to forward a request to the next link in a chain. #### forwardTo Target to forward the request to. -Can either be `"controller"` to indicate a slave should forward it to the controller when receiving it from an instance, or `"instance"` to indicate it should be forwarded to the instances specified by the `instance_id` request property. +Can either be `"controller"` to indicate a host should forward it to the controller when receiving it from an instance, or `"instance"` to indicate it should be forwarded to the instances specified by the `instance_id` request property. This works by using a default handler for the request by the links that forward it. #### requestRequired @@ -480,7 +480,7 @@ Same as the requestProperties only for the response sent back by the target. ## Sending Link Messages Link messages are sent by calling the `.send()` method on the Event/Request instance with the link you want to send it over and the data to send. -For `InstancePlugin` code the link to the slave is the `instance` itself, which is accessible through the `.instance` property of the `InstancePlugin`. +For `InstancePlugin` code the link to the host is the `instance` itself, which is accessible through the `.instance` property of the `InstancePlugin`. The `.info` property of the plugin class exposes the data exported from the plugin's `info.js` module. In other words: @@ -497,26 +497,26 @@ For the Request class the send method is async and returns the response data rec ### Handling connection events There are a few connection related events that plugins neeed to repsond to in order to avoid data loss and connection problems. -The most important is the prepare disconnect for the link between controller and slave. -This is signaled to `ControllerPlugin` classes via the `onPrepareSlaveDisconnect` hook and to `InstancePlugin` classes via the `onPrepareControllerDisconnect` hook. +The most important is the prepare disconnect for the link between controller and host. +This is signaled to `ControllerPlugin` classes via the `onPrepareHostDisconnect` hook and to `InstancePlugin` classes via the `onPrepareControllerDisconnect` hook. After the prepare disconnect the connection will be closed, which will result in pending requests and events being dropped. Plugins must respond to the prepare disconnect by stopping any processess it does that send events or requests over the link in question. -This can be accomplished either through listening for the prepare disconnect hook, or by checking the `connected` property of the `SlaveConnection` class and `Slave` class on the controller and slave respectively. +This can be accomplished either through listening for the prepare disconnect hook, or by checking the `connected` property of the `HostConnection` class and `Host` class on the controller and host respectively. For example the sending of an event from an `InstancePlugin` class can be stopped while the connection is not connected, not in the dropped state, and not in the process of discunnecting by using the following code: ```js -if (this.slave.connected) { +if (this.host.connected) { this.info.messages.frobnicate.send(this.instance, { foo: "bar" }); } ``` If the event or request needs to be sent to the controller it can be put into a queue stored on the plugin instance and sent out when the connection is established again. -The re-establishement of the connection is notified to plugins via the `connect` event to the `onControllerConnectionEvent` and `onSlaveConnectionEvent` hooks. +The re-establishement of the connection is notified to plugins via the `connect` event to the `onControllerConnectionEvent` and `onHostConnectionEvent` hooks. -The second connection event which is of lesser importance to respond to is the `drop` connection event served through `onControllerConnectionEvent` for `InstancePlugin` classes and through `onSlaveConnectionEvent` for `ControllerPlugin` classes. -This is raised when the connection between the controller and slave in question is lost, most likely due to networking issues. -When in the dropped state the slave will keep trying to reconnect to the controller in order to re-establish it, and if successful no events or requests will be lost. +The second connection event which is of lesser importance to respond to is the `drop` connection event served through `onControllerConnectionEvent` for `InstancePlugin` classes and through `onHostConnectionEvent` for `ControllerPlugin` classes. +This is raised when the connection between the controller and host in question is lost, most likely due to networking issues. +When in the dropped state the host will keep trying to reconnect to the controller in order to re-establish it, and if successful no events or requests will be lost. However while in the dropped state any requests and events sent gets queued up in memory until the connection is either re-established or the session times out. This means that if your plugin sends a lot of events or requests, they can end up being queued up in a buffer and sent out all at once the connection is re-estabished. To avoid this you should be throtteling and/or stopping your requests/events after `drop` has been raised, and continue back as normal when `resume` is raised. @@ -557,8 +557,8 @@ const barMetric = new Gauge( barMetric.labels(String(this.instance.id)).set(someValue); ``` -Metrics are automatically registered to the default registry, and this default registry is automatically polled by the controller on slaves. -This means that it's important that you place the definition of the metric at module level so that it's not created more than once over the lifetime of a slave. +Metrics are automatically registered to the default registry, and this default registry is automatically polled by the controller on hosts. +This means that it's important that you place the definition of the metric at module level so that it's not created more than once over the lifetime of a host. Since the metrics remember their values and would continue to be exported after an instance is shutdown, there's code at instance shutdown that removes all the values where the `instance_id` label matches the id of the instance shut down. For statistics you need to update on collection there's an `onMetrics` hook on both controller and instance plugins that is run before the metrics in the default registry are collected. diff --git a/package.json b/package.json index 63ab56b9..9e54a877 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@clusterio/ctl": "workspace:*", "@clusterio/lib": "workspace:*", "@clusterio/controller": "workspace:*", - "@clusterio/slave": "workspace:*", + "@clusterio/host": "workspace:*", "eslint": "^8.18.0", "eslint-plugin-node": "^11.1.0", "express": "^4.16.2", diff --git a/packages/controller/README.md b/packages/controller/README.md index 32bc0b85..a953686e 100644 --- a/packages/controller/README.md +++ b/packages/controller/README.md @@ -1,7 +1,7 @@ # Clusterio Controller Communication hub for Clusterio clusters. -The controller forwards data between Clusterio slaves connected to it and allows the cluster to be remotely managed through WebSocket connections to it either by using the included web interface or the Clusterio ctl command line utility. +The controller forwards data between Clusterio hosts connected to it and allows the cluster to be remotely managed through WebSocket connections to it either by using the included web interface or the Clusterio ctl command line utility. # Usage @@ -35,7 +35,7 @@ For example, installing the Subspace Storage plugin: npm install @clusterio/plugin-subspace_storage npx clusteriocontroller plugin add @clusterio/plugin-subspace_storage -Since the `plugin-list.json` is shared between controller, slave and ctl you usually only need to do this once per machine. +Since the `plugin-list.json` is shared between controller, host and ctl you usually only need to do this once per machine. #### `plugin remove ` @@ -49,7 +49,7 @@ For example, uninstalling the Subspace Storage plugin: npx clusteriocontroller plugin remove subspace_storage npm uninstall @clusterio/plugin-subspace_storage -Since the `plugin-list.json` is shared between controller, slave and ctl you usually only need to do this once per machine. +Since the `plugin-list.json` is shared between controller, host and ctl you usually only need to do this once per machine. #### `plugin list` diff --git a/packages/controller/controller.js b/packages/controller/controller.js index 94622fc1..0812196f 100755 --- a/packages/controller/controller.js +++ b/packages/controller/controller.js @@ -3,7 +3,7 @@ /** * Clusterio controller * - * Facilitates communication between slaves and control of the cluster + * Facilitates communication between hosts and control of the cluster * through WebSocet connections, and hosts a webserver for browser * interfaces and Prometheus statistics export. It is remotely controlled * by {@link module:ctl/ctl}. @@ -45,19 +45,19 @@ let controller; void new libPrometheus.Gauge( - "clusterio_controller_slave_mapping", - "Mapping of Slave ID to name", + "clusterio_controller_host_mapping", + "Mapping of Host ID to name", { - labels: ["slave_id", "slave_name"], + labels: ["host_id", "host_name"], callback: function(gauge) { gauge.clear(); - if (!controller || !controller.slaves) { + if (!controller || !controller.hosts) { return; } - for (let [id, slave] of controller.slaves) { + for (let [id, host] of controller.hosts) { gauge.labels({ - slave_id: String(id), - slave_name: slave.name, + host_id: String(id), + host_name: host.name, }).set(1); }; }, @@ -66,9 +66,9 @@ void new libPrometheus.Gauge( void new libPrometheus.Gauge( "clusterio_controller_instance_mapping", - "Mapping of Instance ID to name and slave", + "Mapping of Instance ID to name and host", { - labels: ["instance_id", "instance_name", "slave_id"], + labels: ["instance_id", "instance_name", "host_id"], callback: function(gauge) { gauge.clear(); if (!controller || !controller.instances) { @@ -78,7 +78,7 @@ void new libPrometheus.Gauge( gauge.labels({ instance_id: String(id), instance_name: String(instance.config.get("instance.name")), - slave_id: String(instance.config.get("instance.assigned_slave")), + host_id: String(instance.config.get("instance.assigned_host")), }).set(1); } }, @@ -92,16 +92,16 @@ void new libPrometheus.Gauge( ); void new libPrometheus.Gauge( - "clusterio_controller_active_slaves", - "How many slaves are currently connected to the controller", - { callback: function(gauge) { gauge.set(controller.wsServer.slaveConnections.size); }} + "clusterio_controller_active_hosts", + "How many hosts are currently connected to the controller", + { callback: function(gauge) { gauge.set(controller.wsServer.hostConnections.size); }} ); void new libPrometheus.Gauge( "clusterio_controller_connected_clients_count", "How many clients are currently connected to this controller", { labels: ["type"], callback: async function(gauge) { - gauge.labels("slave").set(controller.wsServer.slaveConnections.size); + gauge.labels("host").set(controller.wsServer.hostConnections.size); gauge.labels("control").set(controller.wsServer.controlConnections.length); }, }, @@ -139,10 +139,10 @@ async function handleBootstrapCommand(args, controllerConfig) { // eslint-disable-next-line no-console console.log(user.createToken(controllerConfig.get("controller.auth_secret"))); - } else if (subCommand === "generate-slave-token") { + } else if (subCommand === "generate-host-token") { // eslint-disable-next-line no-console console.log(jwt.sign( - { aud: "slave", slave: args.id }, + { aud: "host", host: args.id }, Buffer.from(controllerConfig.get("controller.auth_secret"), "base64") )); @@ -217,8 +217,8 @@ async function initialize() { yargs .command("create-admin ", "Create a cluster admin") .command("generate-user-token ", "Generate authentication token for the given user") - .command("generate-slave-token ", "Generate authentication token for the given slave", yargs => { - yargs.positional("id", { describe: "ID of the slave", type: "number" }); + .command("generate-host-token ", "Generate authentication token for the given host", yargs => { + yargs.positional("id", { describe: "ID of the host", type: "number" }); }) .command("create-ctl-config ", "Create clusterioctl config for the given user", yargs => { yargs.option("output", { diff --git a/packages/controller/src/BaseConnection.js b/packages/controller/src/BaseConnection.js index 07463634..3206b805 100644 --- a/packages/controller/src/BaseConnection.js +++ b/packages/controller/src/BaseConnection.js @@ -31,33 +31,33 @@ class BaseConnection extends libLink.Link { let instance = this._controller.instances.get(message.data.instance_id); if (!instance) { return; } - let slaveId = instance.config.get("instance.assigned_slave"); - if (slaveId === null) { return; } + let hostId = instance.config.get("instance.assigned_host"); + if (hostId === null) { return; } - let connection = this._controller.wsServer.slaveConnections.get(slaveId); + let connection = this._controller.wsServer.hostConnections.get(hostId); if (!connection || connection.closing) { return; } if (event.plugin && !connection.plugins.has(event.plugin)) { return; } event.send(connection, message.data); } - async broadcastEventToSlaves(message, event) { - for (let slaveConnection of this._controller.wsServer.slaveConnections.values()) { + async broadcastEventToHosts(message, event) { + for (let hostConnection of this._controller.wsServer.hostConnections.values()) { // Do not broadcast back to the source - if (slaveConnection === this) { continue; } - if (slaveConnection.connector.closing) { continue; } - if (event.plugin && !slaveConnection.plugins.has(event.plugin)) { continue; } + if (hostConnection === this) { continue; } + if (hostConnection.connector.closing) { continue; } + if (event.plugin && !hostConnection.plugins.has(event.plugin)) { continue; } - event.send(slaveConnection, message.data); + event.send(hostConnection, message.data); } } async broadcastEventToInstance(message, event) { - await this.broadcastEventToSlaves(message, event); + await this.broadcastEventToHosts(message, event); } async prepareDisconnectRequestHandler(message, request) { - await libPlugin.invokeHook(this._controller.plugins, "onPrepareSlaveDisconnect", this); + await libPlugin.invokeHook(this._controller.plugins, "onPrepareHostDisconnect", this); this._disconnecting = true; this.connector.setClosing(); return await super.prepareDisconnectRequestHandler(message, request); diff --git a/packages/controller/src/ControlConnection.js b/packages/controller/src/ControlConnection.js index acc89075..7b9f865f 100644 --- a/packages/controller/src/ControlConnection.js +++ b/packages/controller/src/ControlConnection.js @@ -44,9 +44,9 @@ class ControlConnection extends BaseConnection { */ this.user = user; - this.slaveSubscriptions = { + this.hostSubscriptions = { all: false, - slave_ids: [], + host_ids: [], }; this.instanceSubscriptions = { @@ -78,7 +78,7 @@ class ControlConnection extends BaseConnection { this.logSubscriptions = { all: false, controller: false, - slave_ids: [], + host_ids: [], instance_ids: [], }; @@ -118,65 +118,65 @@ class ControlConnection extends BaseConnection { this._controller.config.setProp(field, prop, value, "control"); } - async listSlavesRequestHandler(message) { + async listHostsRequestHandler(message) { let list = []; - for (let slave of this._controller.slaves.values()) { + for (let host of this._controller.hosts.values()) { list.push({ - agent: slave.agent, - version: slave.version, - id: slave.id, - name: slave.name, - public_address: slave.public_address || null, - connected: this._controller.wsServer.slaveConnections.has(slave.id), + agent: host.agent, + version: host.version, + id: host.id, + name: host.name, + public_address: host.public_address || null, + connected: this._controller.wsServer.hostConnections.has(host.id), }); } return { list }; } - async setSlaveSubscriptionsRequestHandler(message) { - this.slaveSubscriptions = message.data; + async setHostSubscriptionsRequestHandler(message) { + this.hostSubscriptions = message.data; } - slaveUpdated(slave, update) { + hostUpdated(host, update) { if ( - this.slaveSubscriptions.all - || this.slaveSubscriptions.slave_ids.includes(slave.id) + this.hostSubscriptions.all + || this.hostSubscriptions.host_ids.includes(host.id) ) { - libLink.messages.slaveUpdate.send(this, update); + libLink.messages.hostUpdate.send(this, update); } } - generateSlaveToken(slaveId) { + generateHostToken(hostId) { return jwt.sign( - { aud: "slave", slave: slaveId }, + { aud: "host", host: hostId }, Buffer.from(this._controller.config.get("controller.auth_secret"), "base64") ); } - async generateSlaveTokenRequestHandler(message) { - let slaveId = message.data.slave_id; - if (slaveId === null) { - slaveId = Math.random() * 2**31 | 0; + async generateHostTokenRequestHandler(message) { + let hostId = message.data.host_id; + if (hostId === null) { + hostId = Math.random() * 2**31 | 0; } - return { token: this.generateSlaveToken(slaveId) }; + return { token: this.generateHostToken(hostId) }; } - async createSlaveConfigRequestHandler(message) { - let slaveConfig = new libConfig.SlaveConfig("control"); - await slaveConfig.init(); + async createHostConfigRequestHandler(message) { + let hostConfig = new libConfig.HostConfig("control"); + await hostConfig.init(); - slaveConfig.set("slave.controller_url", this._controller.getControllerUrl()); + hostConfig.set("host.controller_url", this._controller.getControllerUrl()); if (message.data.id !== null) { - slaveConfig.set("slave.id", message.data.id); + hostConfig.set("host.id", message.data.id); } if (message.data.name !== null) { - slaveConfig.set("slave.name", message.data.name); + hostConfig.set("host.name", message.data.name); } if (message.data.generate_token) { - this.user.checkPermission("core.slave.generate_token"); - slaveConfig.set("slave.controller_token", this.generateSlaveToken(slaveConfig.get("slave.id"))); + this.user.checkPermission("core.host.generate_token"); + hostConfig.set("host.controller_token", this.generateHostToken(hostConfig.get("host.id"))); } - return { serialized_config: slaveConfig.serialize() }; + return { serialized_config: hostConfig.serialize() }; } async getInstanceRequestHandler(message) { @@ -186,7 +186,7 @@ class ControlConnection extends BaseConnection { return { id, name: instance.config.get("instance.name"), - assigned_slave: instance.config.get("instance.assigned_slave"), + assigned_host: instance.config.get("instance.assigned_host"), game_port: instance.game_port || null, status: instance.status, }; @@ -198,7 +198,7 @@ class ControlConnection extends BaseConnection { list.push({ id: instance.config.get("instance.id"), name: instance.config.get("instance.name"), - assigned_slave: instance.config.get("instance.assigned_slave"), + assigned_host: instance.config.get("instance.assigned_host"), game_port: instance.game_port || null, status: instance.status, }); @@ -218,14 +218,14 @@ class ControlConnection extends BaseConnection { libLink.messages.instanceUpdate.send(this, { id: instance.config.get("instance.id"), name: instance.config.get("instance.name"), - assigned_slave: instance.config.get("instance.assigned_slave"), + assigned_host: instance.config.get("instance.assigned_host"), game_port: instance.game_port || null, status: instance.status, }); } } - // XXX should probably add a hook for slave reuqests? + // XXX should probably add a hook for host reuqests? async createInstanceRequestHandler(message) { let instanceConfig = new libConfig.InstanceConfig("controller"); await instanceConfig.load(message.data.serialized_config); @@ -269,7 +269,7 @@ class ControlConnection extends BaseConnection { async deleteInstanceRequestHandler(message, request) { let instance = this._controller.getRequestInstance(message.data.instance_id); - if (instance.config.get("instance.assigned_slave") !== null) { + if (instance.config.get("instance.assigned_host") !== null) { await this.forwardRequestToInstance(message, request); } this._controller.instances.delete(message.data.instance_id); @@ -288,13 +288,13 @@ class ControlConnection extends BaseConnection { } async updateInstanceConfig(instance) { - let slaveId = instance.config.get("instance.assigned_slave"); - if (slaveId !== null) { - let connection = this._controller.wsServer.slaveConnections.get(slaveId); + let hostId = instance.config.get("instance.assigned_host"); + if (hostId !== null) { + let connection = this._controller.wsServer.hostConnections.get(hostId); if (connection) { await libLink.messages.assignInstance.send(connection, { instance_id: instance.config.get("instance.id"), - serialized_config: instance.config.serialize("slave"), + serialized_config: instance.config.serialize("host"), }); } } @@ -302,8 +302,8 @@ class ControlConnection extends BaseConnection { async setInstanceConfigFieldRequestHandler(message) { let instance = this._controller.getRequestInstance(message.data.instance_id); - if (message.data.field === "instance.assigned_slave") { - throw new libErrors.RequestError("instance.assigned_slave must be set through the assign-slave interface"); + if (message.data.field === "instance.assigned_host") { + throw new libErrors.RequestError("instance.assigned_host must be set through the assign-host interface"); } if (message.data.field === "instance.id") { @@ -323,38 +323,38 @@ class ControlConnection extends BaseConnection { } async assignInstanceCommandRequestHandler(message, request) { - let { slave_id, instance_id } = message.data; + let { host_id, instance_id } = message.data; let instance = this._controller.getRequestInstance(instance_id); - // Check if target slave is connected - let newSlaveConnection; - if (slave_id !== null) { - newSlaveConnection = this._controller.wsServer.slaveConnections.get(slave_id); - if (!newSlaveConnection) { - // The case of the slave not getting the assign instance message + // Check if target host is connected + let newHostConnection; + if (host_id !== null) { + newHostConnection = this._controller.wsServer.hostConnections.get(host_id); + if (!newHostConnection) { + // The case of the host not getting the assign instance message // still have to be handled, so it's not a requirement that the - // target slave be connected to the controller while doing the + // target host be connected to the controller while doing the // assignment, but it is IMHO a better user experience if this // is the case. - throw new libErrors.RequestError("Target slave is not connected to the controller"); + throw new libErrors.RequestError("Target host is not connected to the controller"); } } - // Unassign from currently assigned slave if it is connected. - let currentAssignedSlave = instance.config.get("instance.assigned_slave"); - if (currentAssignedSlave !== null && slave_id !== currentAssignedSlave) { - let oldSlaveConnection = this._controller.wsServer.slaveConnections.get(currentAssignedSlave); - if (oldSlaveConnection && !oldSlaveConnection.connector.closing) { - await libLink.messages.unassignInstance.send(oldSlaveConnection, { instance_id }); + // Unassign from currently assigned host if it is connected. + let currentAssignedHost = instance.config.get("instance.assigned_host"); + if (currentAssignedHost !== null && host_id !== currentAssignedHost) { + let oldHostConnection = this._controller.wsServer.hostConnections.get(currentAssignedHost); + if (oldHostConnection && !oldHostConnection.connector.closing) { + await libLink.messages.unassignInstance.send(oldHostConnection, { instance_id }); } } // Assign to target - instance.config.set("instance.assigned_slave", slave_id); - if (slave_id !== null) { - await libLink.messages.assignInstance.send(newSlaveConnection, { + instance.config.set("instance.assigned_host", host_id); + if (host_id !== null) { + await libLink.messages.assignInstance.send(newHostConnection, { instance_id, - serialized_config: instance.config.serialize("slave"), + serialized_config: instance.config.serialize("host"), }); } else { instance.status = "unassigned"; @@ -383,7 +383,7 @@ class ControlConnection extends BaseConnection { let ready = new Promise((resolve, reject) => { stream.events.on("source", resolve); stream.events.on("timeout", () => reject( - new libErrors.RequestError("Timed out establishing stream from slave") + new libErrors.RequestError("Timed out establishing stream from host") )); }); ready.catch(() => {}); @@ -411,29 +411,29 @@ class ControlConnection extends BaseConnection { } let sourceInstance = this._controller.getRequestInstance(instance_id); let targetInstance = this._controller.getRequestInstance(target_instance_id); - let sourceSlaveId = sourceInstance.config.get("instance.assigned_slave"); - let targetSlaveId = targetInstance.config.get("instance.assigned_slave"); - if (sourceSlaveId === null) { - throw new libErrors.RequestError("Source instance is not assigned a slave"); + let sourceHostId = sourceInstance.config.get("instance.assigned_host"); + let targetHostId = targetInstance.config.get("instance.assigned_host"); + if (sourceHostId === null) { + throw new libErrors.RequestError("Source instance is not assigned a host"); } - if (targetSlaveId === null) { - throw new libErrors.RequestError("Target instance is not assigned a slave"); + if (targetHostId === null) { + throw new libErrors.RequestError("Target instance is not assigned a host"); } - // Let slave handle request if source and target is on the same slave. - if (sourceSlaveId === targetSlaveId) { + // Let host handle request if source and target is on the same host. + if (sourceHostId === targetHostId) { return await this.forwardRequestToInstance(message, request); } // Check connectivity - let sourceSlaveConnection = this._controller.wsServer.slaveConnections.get(sourceSlaveId); - if (!sourceSlaveConnection || sourceSlaveConnection.closing) { - throw new libErrors.RequestError("Source slave is not connected to the controller"); + let sourceHostConnection = this._controller.wsServer.hostConnections.get(sourceHostId); + if (!sourceHostConnection || sourceHostConnection.closing) { + throw new libErrors.RequestError("Source host is not connected to the controller"); } - let targetSlaveConnection = this._controller.wsServer.slaveConnections.get(targetSlaveId); - if (!targetSlaveConnection || targetSlaveConnection.closing) { - throw new libErrors.RequestError("Target slave is not connected to the controller"); + let targetHostConnection = this._controller.wsServer.hostConnections.get(targetHostId); + if (!targetHostConnection || targetHostConnection.closing) { + throw new libErrors.RequestError("Target host is not connected to the controller"); } // Create stream to proxy from target to source @@ -448,8 +448,8 @@ class ControlConnection extends BaseConnection { // Ignore errors if not listening for them to avoid crash. stream.events.on("error", () => { /* ignore */ }); - // Establish push from source slave to stream, this is done first to - // ensure the file size is known prior to the target slave pull. + // Establish push from source host to stream, this is done first to + // ensure the file size is known prior to the target host pull. await Promise.all([ this._controller.forwardRequestToInstance(libLink.messages.pushSave, { instance_id, @@ -459,7 +459,7 @@ class ControlConnection extends BaseConnection { events.once(stream.events, "source"), ]); - // Establish pull from target slave to stream and wait for completion. + // Establish pull from target host to stream and wait for completion. let result = await this._controller.forwardRequestToInstance(libLink.messages.pullSave, { instance_id: target_instance_id, stream_id: stream.id, @@ -668,8 +668,8 @@ class ControlConnection extends BaseConnection { } updateLogSubscriptions() { - let { all, controller, slave_ids, instance_ids } = this.logSubscriptions; - if (all || controller || slave_ids.length || instance_ids.length) { + let { all, controller, host_ids, instance_ids } = this.logSubscriptions; + if (all || controller || host_ids.length || instance_ids.length) { if (!this.logTransport) { this.logTransport = new libLoggingUtils.LinkTransport({ link: this }); this._controller.clusterLogger.add(this.logTransport); @@ -684,10 +684,10 @@ class ControlConnection extends BaseConnection { async queryLogRequestHandler(message) { let observeDuration = queryLogTime.startTimer(); - let { all, controller, slave_ids, instance_ids } = message.data; + let { all, controller, host_ids, instance_ids } = message.data; let log; - if (!all && controller && !slave_ids.length && !instance_ids.length) { + if (!all && controller && !host_ids.length && !instance_ids.length) { log = await this._controller.queryControllerLog(message.data); } else { log = await this._controller.queryClusterLog(message.data); @@ -886,7 +886,7 @@ class ControlConnection extends BaseConnection { user.isAdmin = admin; this._controller.userUpdated(user); - this.broadcastEventToSlaves({ data: { name, admin }}, libLink.messages.adminlistUpdate); + this.broadcastEventToHosts({ data: { name, admin }}, libLink.messages.adminlistUpdate); } async setUserBannedRequestHandler(message) { @@ -904,7 +904,7 @@ class ControlConnection extends BaseConnection { user.isBanned = banned; user.banReason = reason; this._controller.userUpdated(user); - this.broadcastEventToSlaves({ data: { name, banned, reason }}, libLink.messages.banlistUpdate); + this.broadcastEventToHosts({ data: { name, banned, reason }}, libLink.messages.banlistUpdate); } async setUserWhitelistedRequestHandler(message) { @@ -921,7 +921,7 @@ class ControlConnection extends BaseConnection { user.isWhitelisted = whitelisted; this._controller.userUpdated(user); - this.broadcastEventToSlaves({ data: { name, whitelisted }}, libLink.messages.whitelistUpdate); + this.broadcastEventToHosts({ data: { name, whitelisted }}, libLink.messages.whitelistUpdate); } async deleteUserRequestHandler(message) { @@ -935,13 +935,13 @@ class ControlConnection extends BaseConnection { this._controller.userUpdated(user); if (user.is_admin) { - this.broadcastEventToSlaves({ data: { name, admin: false }}, libLink.messages.adminlistUpdate); + this.broadcastEventToHosts({ data: { name, admin: false }}, libLink.messages.adminlistUpdate); } if (user.is_whitelisted) { - this.broadcastEventToSlaves({ data: { name, whitelisted: false }}, libLink.messages.whitelistUpdate); + this.broadcastEventToHosts({ data: { name, whitelisted: false }}, libLink.messages.whitelistUpdate); } if (user.is_banned) { - this.broadcastEventToSlaves({ data: { name, banned: false, reason: "" }}, libLink.messages.banlistUpdate); + this.broadcastEventToHosts({ data: { name, banned: false, reason: "" }}, libLink.messages.banlistUpdate); } } diff --git a/packages/controller/src/Controller.js b/packages/controller/src/Controller.js index 2427fe16..3f68a4d1 100644 --- a/packages/controller/src/Controller.js +++ b/packages/controller/src/Controller.js @@ -61,10 +61,10 @@ class Controller { this.app.locals.streams = new Map(); /** - * Mapping of slave id to slave info + * Mapping of host id to host info * @type {Map} */ - this.slaves = null; + this.hosts = null; /** * Mapping of instance id to instance info @@ -145,7 +145,7 @@ class Controller { return (await Promise.all([ libFileOps.directorySize(path.join(this.logDirectory, "cluster")), libFileOps.directorySize(path.join(this.logDirectory, "controller")), - libFileOps.directorySize(path.join(this.logDirectory, "slave")), + libFileOps.directorySize(path.join(this.logDirectory, "host")), ])).reduce((a, v) => a + v, 0); } @@ -192,7 +192,7 @@ class Controller { let databaseDirectory = this.config.get("controller.database_directory"); await fs.ensureDir(databaseDirectory); - this.slaves = await Controller.loadSlaves(path.join(databaseDirectory, "slaves.json")); + this.hosts = await Controller.loadHosts(path.join(databaseDirectory, "hosts.json")); this.instances = await Controller.loadInstances(path.join(databaseDirectory, "instances.json")); this.modPacks = await Controller.loadModPacks(path.join(databaseDirectory, "mod-packs.json")); this.userManager = new UserManager(this.config); @@ -313,8 +313,8 @@ class Controller { } let databaseDirectory = this.config.get("controller.database_directory"); - if (this.slaves) { - await Controller.saveSlaves(path.join(databaseDirectory, "slaves.json"), this.slaves); + if (this.hosts) { + await Controller.saveHosts(path.join(databaseDirectory, "hosts.json"), this.hosts); } if (this.instances) { @@ -344,7 +344,7 @@ class Controller { logger.info("Goodbye"); } - static async loadSlaves(filePath) { + static async loadHosts(filePath) { let serialized; try { serialized = JSON.parse(await fs.readFile(filePath)); @@ -365,8 +365,8 @@ class Controller { return new Map(serialized); } - static async saveSlaves(filePath, slaves) { - await libFileOps.safeOutputFile(filePath, JSON.stringify([...slaves.entries()], null, 4)); + static async saveHosts(filePath, hosts) { + await libFileOps.safeOutputFile(filePath, JSON.stringify([...hosts.entries()], null, 4)); } static async loadInstances(filePath) { @@ -378,7 +378,7 @@ class Controller { for (let serializedConfig of serialized) { let instanceConfig = new libConfig.InstanceConfig("controller"); await instanceConfig.load(serializedConfig); - let status = instanceConfig.get("instance.assigned_slave") === null ? "unassigned" : "unknown"; + let status = instanceConfig.get("instance.assigned_host") === null ? "unassigned" : "unknown"; let instance = { config: instanceConfig, status }; instances.set(instanceConfig.get("instance.id"), instance); } @@ -543,14 +543,14 @@ class Controller { } } - slaveUpdated(slave) { + hostUpdated(host) { let update = { - agent: slave.agent, - version: slave.version, - id: slave.id, - name: slave.name, - public_address: slave.public_address || null, - connected: this.wsServer.slaveConnections.has(slave.id), + agent: host.agent, + version: host.version, + id: host.id, + name: host.name, + public_address: host.public_address || null, + connected: this.wsServer.hostConnections.has(host.id), }; for (let controlConnection of this.wsServer.controlConnections) { @@ -558,7 +558,7 @@ class Controller { continue; } - controlConnection.slaveUpdated(slave, update); + controlConnection.hostUpdated(host, update); } } @@ -801,9 +801,9 @@ class Controller { } /** - * Forward the given request to the slave contaning the instance + * Forward the given request to the host contaning the instance * - * Finds the slave which the instance with the given instance ID is + * Finds the host which the instance with the given instance ID is * currently assigned to and forwards the request to that instance. * The request data must have an instance_id parameter. * @@ -815,17 +815,17 @@ class Controller { */ async forwardRequestToInstance(request, data) { let instance = this.getRequestInstance(data.instance_id); - let slaveId = instance.config.get("instance.assigned_slave"); - if (slaveId === null) { - throw new libErrors.RequestError("Instance is not assigned to a slave"); + let hostId = instance.config.get("instance.assigned_host"); + if (hostId === null) { + throw new libErrors.RequestError("Instance is not assigned to a host"); } - let connection = this.wsServer.slaveConnections.get(slaveId); + let connection = this.wsServer.hostConnections.get(hostId); if (!connection) { - throw new libErrors.RequestError("Slave containing instance is not connected"); + throw new libErrors.RequestError("Host containing instance is not connected"); } if (request.plugin && !connection.plugins.has(request.plugin)) { - throw new libErrors.RequestError(`Slave containing instance does not have ${request.plugin} plugin`); + throw new libErrors.RequestError(`Host containing instance does not have ${request.plugin} plugin`); } return await request.send(connection, data); diff --git a/packages/controller/src/SlaveConnection.js b/packages/controller/src/HostConnection.js similarity index 79% rename from packages/controller/src/SlaveConnection.js rename to packages/controller/src/HostConnection.js index 3b5975be..1f302b1c 100644 --- a/packages/controller/src/SlaveConnection.js +++ b/packages/controller/src/HostConnection.js @@ -9,14 +9,14 @@ const BaseConnection = require("./BaseConnection"); /** - * Represents the connection to a slave + * Represents the connection to a host * * @extends module:controller/src/BaseConnection - * @alias module:controller/src/SlaveConnection + * @alias module:controller/src/HostConnection */ -class SlaveConnection extends BaseConnection { +class HostConnection extends BaseConnection { constructor(registerData, connector, controller) { - super("slave", connector, controller); + super("host", connector, controller); this._agent = registerData.agent; this._id = registerData.id; @@ -25,7 +25,7 @@ class SlaveConnection extends BaseConnection { this.plugins = new Map(Object.entries(registerData.plugins)); this._checkPluginVersions(); - this._controller.slaves.set(this._id, { + this._controller.hosts.set(this._id, { agent: this._agent, id: this._id, name: this._name, @@ -38,15 +38,15 @@ class SlaveConnection extends BaseConnection { // eslint-disable-next-line no-loop-func this.connector.on(event, () => { for (let plugin of this._controller.plugins.values()) { - plugin.onSlaveConnectionEvent(this, event); + plugin.onHostConnectionEvent(this, event); } }); } this.connector.on("close", () => { - // Update status to unknown for instances on this slave. + // Update status to unknown for instances on this host. for (let instance of this._controller.instances.values()) { - if (instance.config.get("instance.assigned_slave") !== this._id) { + if (instance.config.get("instance.assigned_host") !== this._id) { continue; } @@ -63,13 +63,13 @@ class SlaveConnection extends BaseConnection { for (let [name, version] of this.plugins) { let info = pluginInfos.get(name); if (!info) { - logger.warn(`Slave ${this._name} has plugin ${name} ${version} which the controller does not have`); + logger.warn(`Host ${this._name} has plugin ${name} ${version} which the controller does not have`); continue; } if (info.version !== version) { logger.warn( - `Slave ${this._name} has plugin ${name} ${version} which does not match the version of this ` + + `Host ${this._name} has plugin ${name} ${version} which does not match the version of this ` + `plugin on the controller (${info.version})` ); } @@ -77,15 +77,15 @@ class SlaveConnection extends BaseConnection { for (let [name, info] of pluginInfos) { if (!this.plugins.has(name)) { - logger.warn(`Slave ${this._name} is missing plugin ${name} ${info.version}`); + logger.warn(`Host ${this._name} is missing plugin ${name} ${info.version}`); } } } /** - * ID of the slave this connection is connected to + * ID of the host this connection is connected to * - * @returns {number} slave ID. + * @returns {number} host ID. */ get id() { return this._id; @@ -95,17 +95,17 @@ class SlaveConnection extends BaseConnection { let instance = this._controller.instances.get(message.data.instance_id); // It's possible to get updates from an instance that does not exist - // or is not assigned to the slave it originated from if it was - // reassigned or deleted while the connection to the slave it was + // or is not assigned to the host it originated from if it was + // reassigned or deleted while the connection to the host it was // originally on was down at the time. - if (!instance || instance.config.get("instance.assigned_slave") !== this._id) { + if (!instance || instance.config.get("instance.assigned_host") !== this._id) { logger.warn(`Got bogus update for instance id ${message.data.instance_id}`); return; } // We may receive status changed where the status hasn't changed // from our perspective if the connection was down at the time it - // changed. Slaves also send status updates on assignInstance which + // changed. Hosts also send status updates on assignInstance which // for hacky reason is also used to push config changes and // restablish status after a connection loss. if (instance.status === message.data.status) { @@ -123,23 +123,23 @@ class SlaveConnection extends BaseConnection { async updateInstancesRequestHandler(message) { // Push updated instance configs for (let instance of this._controller.instances.values()) { - if (instance.config.get("instance.assigned_slave") === this._id) { + if (instance.config.get("instance.assigned_host") === this._id) { await libLink.messages.assignInstance.send(this, { instance_id: instance.config.get("instance.id"), - serialized_config: instance.config.serialize("slave"), + serialized_config: instance.config.serialize("host"), }); } } - // Assign instances the slave has but controller does not + // Assign instances the host has but controller does not for (let instanceData of message.data.instances) { let instanceConfig = new libConfig.InstanceConfig("controller"); - await instanceConfig.load(instanceData.serialized_config, "slave"); + await instanceConfig.load(instanceData.serialized_config, "host"); let controllerInstance = this._controller.instances.get(instanceConfig.get("instance.id")); if (controllerInstance) { // Check if this instance is assigned somewhere else. - if (controllerInstance.config.get("instance.assigned_slave") !== this._id) { + if (controllerInstance.config.get("instance.assigned_host") !== this._id) { await libLink.messages.unassignInstance.send(this, { instance_id: controllerInstance.config.get("instance.id"), }); @@ -159,13 +159,13 @@ class SlaveConnection extends BaseConnection { continue; } - instanceConfig.set("instance.assigned_slave", this._id); + instanceConfig.set("instance.assigned_host", this._id); let newInstance = { config: instanceConfig, status: instanceData.status }; this._controller.instances.set(instanceConfig.get("instance.id"), newInstance); this._controller.addInstanceHooks(newInstance); await libLink.messages.assignInstance.send(this, { instance_id: instanceConfig.get("instance.id"), - serialized_config: instanceConfig.serialize("slave"), + serialized_config: instanceConfig.serialize("host"), }); await libPlugin.invokeHook(this._controller.plugins, "onInstanceStatusChanged", newInstance, null); } @@ -197,8 +197,8 @@ class SlaveConnection extends BaseConnection { async logMessageEventHandler(message) { this._controller.clusterLogger.log({ ...message.data.info, - slave_id: this._id, - slave_name: this._name, + host_id: this._id, + host_name: this._name, }); } @@ -224,4 +224,4 @@ class SlaveConnection extends BaseConnection { } } -module.exports = SlaveConnection; +module.exports = HostConnection; diff --git a/packages/controller/src/WsServer.js b/packages/controller/src/WsServer.js index a85ff49e..f32bb1cd 100644 --- a/packages/controller/src/WsServer.js +++ b/packages/controller/src/WsServer.js @@ -9,7 +9,7 @@ const libSchema = require("@clusterio/lib/schema"); const ControlConnection = require("./ControlConnection"); const packageVersion = require("../package").version; -const SlaveConnection = require("./SlaveConnection"); +const HostConnection = require("./HostConnection"); const WsServerConnector = require("./WsServerConnector"); @@ -41,8 +41,8 @@ class WsServer { /** @type {Array} */ this.controlConnections = []; - /** @type {Map} */ - this.slaveConnections = new Map(); + /** @type {Map} */ + this.hostConnections = new Map(); /** @type {Map} */ this.activeConnectors = new Map(); /** @type {Set} */ @@ -68,8 +68,8 @@ class WsServer { disconnectTasks.push(controlConnection.disconnect(1001, "Server Quit")); } - for (let slaveConnection of this.slaveConnections.values()) { - disconnectTasks.push(slaveConnection.disconnect(1001, "Server Quit")); + for (let hostConnection of this.hostConnections.values()) { + disconnectTasks.push(hostConnection.disconnect(1001, "Server Quit")); } logger.info(`WsServer | Waiting for ${disconnectTasks.length} connectors to close`); @@ -212,15 +212,15 @@ ${err.stack}` // Validate token let user; try { - if (type === "register_slave") { + if (type === "register_host") { let tokenPayload = jwt.verify( data.token, Buffer.from(this.controller.config.get("controller.auth_secret"), "base64"), - { audience: "slave" } + { audience: "host" } ); - if (tokenPayload.slave !== data.id) { - throw new Error("missmatched slave id"); + if (tokenPayload.host !== data.id) { + throw new Error("missmatched host id"); } } else if (type === "register_control") { @@ -262,34 +262,34 @@ ${err.stack}` }); let additionalReadyData = {}; - if (type === "register_slave") { - let connection = this.slaveConnections.get(data.id); + if (type === "register_host") { + let connection = this.hostConnections.get(data.id); if (connection) { - logger.verbose(`WsServer | disconnecting existing connection for slave ${data.id}`); + logger.verbose(`WsServer | disconnecting existing connection for host ${data.id}`); await connection.disconnect(1008, "Registered from another connection"); } logger.info( - `WsServer | registered slave ${data.name} (${data.id}) using agent ${data.agent} ${data.version}` + `WsServer | registered host ${data.name} (${data.id}) using agent ${data.agent} ${data.version}` ); - if (data.agent === "Clusterio Slave" && data.version !== packageVersion) { + if (data.agent === "Clusterio Host" && data.version !== packageVersion) { logger.warn( `Host ${data.name} (${data.id}) connected using version ${data.version} which does not match the ` + `version of the controller is currently running (${packageVersion}). It may not work as expected.` ); } - connection = new SlaveConnection(data, connector, this.controller); + connection = new HostConnection(data, connector, this.controller); connector.on("close", () => { - if (this.slaveConnections.get(data.id) === connection) { - this.slaveConnections.delete(data.id); - this.controller.slaveUpdated(this.controller.slaves.get(data.id)); + if (this.hostConnections.get(data.id) === connection) { + this.hostConnections.delete(data.id); + this.controller.hostUpdated(this.controller.hosts.get(data.id)); } else { - logger.warn("Unlisted SlaveConnection closed"); + logger.warn("Unlisted HostConnection closed"); } }); - this.slaveConnections.set(data.id, connection); - this.controller.slaveUpdated(this.controller.slaves.get(data.id)); + this.hostConnections.set(data.id, connection); + this.controller.hostUpdated(this.controller.hosts.get(data.id)); } else if (type === "register_control") { diff --git a/packages/controller/src/routes.js b/packages/controller/src/routes.js index 2322558c..a1270df6 100644 --- a/packages/controller/src/routes.js +++ b/packages/controller/src/routes.js @@ -49,14 +49,14 @@ async function getMetrics(req, res, next) { let requests = []; let timeout = req.app.locals.controller.config.get("controller.metrics_timeout") * 1000; - for (let slaveConnection of req.app.locals.controller.wsServer.slaveConnections.values()) { - if (!slaveConnection.connected) { + for (let hostConnection of req.app.locals.controller.wsServer.hostConnections.values()) { + if (!hostConnection.connected) { continue; } requests.push(libHelpers.timeout( - libLink.messages.getMetrics.send(slaveConnection).catch(err => { + libLink.messages.getMetrics.send(hostConnection).catch(err => { if (!(err instanceof libErrors.SessionLost)) { - logger.error(`Unexpected error gathering metrics from slave:\n${err.stack}`); + logger.error(`Unexpected error gathering metrics from host:\n${err.stack}`); } return null; }), @@ -80,7 +80,7 @@ async function getMetrics(req, res, next) { resultMap.set(result.metric.name, result); } else { - // Merge metrics received by multiple slaves + // Merge metrics received by multiple hosts mergeSamples(resultMap.get(result.metric.name), result); } } @@ -123,7 +123,7 @@ function getPlugins(req, res) { res.send(plugins); } -function validateSlaveToken(req, res, next) { +function validateHostToken(req, res, next) { let token = req.header("x-access-token"); if (!token) { res.sendStatus(401); @@ -134,7 +134,7 @@ function validateSlaveToken(req, res, next) { jwt.verify( token, Buffer.from(req.app.locals.controller.config.get("controller.auth_secret"), "base64"), - { audience: "slave" } + { audience: "host" } ); } catch (err) { @@ -356,7 +356,7 @@ async function uploadSave(req, res) { let timeout = new Promise((_, reject) => { proxyStream.events.on("timeout", () => { stream.resume(); - reject(new Error("Timed out establishing stream to slave")); + reject(new Error("Timed out establishing stream to host")); }); }); @@ -609,7 +609,7 @@ function addRouteHandlers(app) { app.get("/metrics", (req, res, next) => getMetrics(req, res, next).catch(next)); app.get("/api/plugins", getPlugins); app.put("/api/upload-export", - validateSlaveToken, + validateHostToken, (req, res, next) => uploadExport(req, res).catch(next) ); app.put("/api/stream/:id", (req, res, next) => putStream(req, res).catch(next)); @@ -628,8 +628,8 @@ function addRouteHandlers(app) { const webRoutes = [ "/", "/controller", - "/slaves", - "/slaves/:id/view", + "/hosts", + "/hosts/:id/view", "/instances", "/instances/:id/view", "/mods", diff --git a/packages/create/create.js b/packages/create/create.js index 2736cb40..867527e3 100755 --- a/packages/create/create.js +++ b/packages/create/create.js @@ -117,11 +117,11 @@ async function execController(args) { return await execFile(path.join("node_modules", ".bin", `clusteriocontroller${scriptExt}`), args); } -async function execSlave(args) { +async function execHost(args) { if (dev) { - return await execFile("node", [path.join("packages", "slave"), ...args]); + return await execFile("node", [path.join("packages", "host"), ...args]); } - return await execFile(path.join("node_modules", ".bin", `clusterioslave${scriptExt}`), args); + return await execFile(path.join("node_modules", ".bin", `clusteriohost${scriptExt}`), args); } async function execCtl(args) { @@ -131,7 +131,7 @@ async function execCtl(args) { return await execFile(path.join("node_modules", ".bin", `clusterioctl${scriptExt}`), args); } -function validateSlaveToken(token) { +function validateHostToken(token) { let parts = token.split("."); if (parts.length !== 3) { throw new InstallError("Invalid token"); @@ -144,7 +144,7 @@ function validateSlaveToken(token) { throw new InstallError("Invalid token"); } - if (parsed.aud !== "slave" || !Number.isInteger(parsed.slave)) { + if (parsed.aud !== "host" || !Number.isInteger(parsed.host)) { throw new InstallError("Invalid token"); } } @@ -197,8 +197,8 @@ async function installClusterio(mode, plugins) { if (["standalone", "controller"].includes(mode)) { components.push("@clusterio/controller"); } - if (["standalone", "slave"].includes(mode)) { - components.push("@clusterio/slave"); + if (["standalone", "host"].includes(mode)) { + components.push("@clusterio/host"); } if (mode === "ctl") { components.push("@clusterio/ctl"); @@ -281,22 +281,22 @@ WantedBy=multi-user.target } } - if (["standalone", "slave"].includes(mode)) { + if (["standalone", "host"].includes(mode)) { if (process.platform === "win32") { await safeOutputFile( - "run-slave.cmd", - "@echo off\n.\\node_modules\\.bin\\clusterioslave.cmd run\n" + "run-host.cmd", + "@echo off\n.\\node_modules\\.bin\\clusteriohost.cmd run\n" ); } else { await safeOutputFile( - "run-slave.sh", - "#!/bin/sh\nexec ./node_modules/.bin/clusterioslave run\n", + "run-host.sh", + "#!/bin/sh\nexec ./node_modules/.bin/clusteriohost run\n", { mode: 0o755 }, ); await safeOutputFile( - "systemd/clusterioslave.service", + "systemd/clusteriohost.service", `[Unit] -Description=Clusterio Slave +Description=Clusterio Host [Service] User=${os.userInfo().username} @@ -304,7 +304,7 @@ Group=${await groupIdToName(os.userInfo().gid)} WorkingDirectory=${process.cwd()} KillMode=mixed KillSignal=SIGINT -ExecStart=${process.cwd()}/node_modules/.bin/clusterioslave run --log-level=warn +ExecStart=${process.cwd()}/node_modules/.bin/clusteriohost run --log-level=warn [Install] WantedBy=multi-user.target @@ -324,9 +324,9 @@ async function inquirerMissingArgs(args) { message: "Operating mode to install", default: "standalone", choices: [ - { name: "Standalone (install both controller and slave on this computer)", value: "standalone" }, + { name: "Standalone (install both controller and host on this computer)", value: "standalone" }, { name: "Controller only", value: "controller" }, - { name: "Slave only", value: "slave" }, + { name: "Host only", value: "host" }, { name: "Ctl only", value: "ctl" }, { name: "Plugins only", value: "plugins" }, ], @@ -350,18 +350,18 @@ async function inquirerMissingArgs(args) { ], answers); } - if (answers.mode === "slave") { - if (args.slaveName) { answers.slaveName = args.slaveName; } + if (answers.mode === "host") { + if (args.hostName) { answers.hostName = args.hostName; } answers = await inquirer.prompt([ { type: "input", - name: "slaveName", - message: "Name of slave", + name: "hostName", + message: "Name of host", }, ], answers); } - if (["slave", "ctl"].includes(answers.mode)) { + if (["host", "ctl"].includes(answers.mode)) { if (args.controllerUrl) { answers.controllerUrl = args.controllerUrl; } answers = await inquirer.prompt([ { @@ -381,11 +381,11 @@ async function inquirerMissingArgs(args) { ], answers); } - if (answers.mode === "slave") { - validateSlaveToken(answers.controllerToken); + if (answers.mode === "host") { + validateHostToken(answers.controllerToken); } - if (["standalone", "slave"].includes(answers.mode)) { + if (["standalone", "host"].includes(answers.mode)) { let myIp = "localhost"; if (args.publicAddress) { answers.publicAddress = args.publicAddress; @@ -532,25 +532,25 @@ async function main() { }) .option("mode", { nargs: 1, describe: "Operating mode to install", - choices: ["standalone", "controller", "slave", "ctl", "plugins"], + choices: ["standalone", "controller", "host", "ctl", "plugins"], }) .option("admin", { nargs: 1, describe: "Admin account name [standalone/controller]", type: "string", }) - .option("slave-name", { - nargs: 1, describe: "Slave name [slave]", type: "string", + .option("host-name", { + nargs: 1, describe: "Host name [host]", type: "string", }) .option("controller-url", { - nargs: 1, describe: "Controller URL [slave/ctl]", type: "string", + nargs: 1, describe: "Controller URL [host/ctl]", type: "string", }) .option("controller-token", { - nargs: 1, describe: "Controller authentication token [slave/ctl]", type: "string", + nargs: 1, describe: "Controller authentication token [host/ctl]", type: "string", }) .option("public-address", { - nargs: 1, describe: "DNS/IP Address to connect to this server [standalone/slave]", type: "string", + nargs: 1, describe: "DNS/IP Address to connect to this server [standalone/host]", type: "string", }) .option("factorio-dir", { - nargs: 1, describe: "Path to Factorio installation [standalone/slave]", type: "string", + nargs: 1, describe: "Path to Factorio installation [standalone/host]", type: "string", }) .option("plugins", { array: true, describe: "Plugins to install", type: "string", @@ -602,32 +602,32 @@ async function main() { } if (answers.mode === "standalone") { - logger.info("Setting up slave"); - await execSlave(["config", "set", "slave.name", "local"]); + logger.info("Setting up host"); + await execHost(["config", "set", "host.name", "local"]); - let result = await execSlave(["config", "show", "slave.id"]); - let slaveId = Number.parseInt(result.stdout.split("\n").slice(-2)[0], 10); + let result = await execHost(["config", "show", "host.id"]); + let hostId = Number.parseInt(result.stdout.split("\n").slice(-2)[0], 10); - result = await execController(["bootstrap", "generate-slave-token", slaveId]); - let slaveToken = result.stdout.split("\n").slice(-2)[0]; + result = await execController(["bootstrap", "generate-host-token", hostId]); + let hostToken = result.stdout.split("\n").slice(-2)[0]; - await execSlave(["config", "set", "slave.controller_token", slaveToken]); - await execSlave(["config", "set", "slave.public_address", answers.publicAddress]); - await execSlave(["config", "set", "slave.factorio_directory", answers.factorioDir]); + await execHost(["config", "set", "host.controller_token", hostToken]); + await execHost(["config", "set", "host.public_address", answers.publicAddress]); + await execHost(["config", "set", "host.factorio_directory", answers.factorioDir]); } - if (answers.mode === "slave") { - logger.info("Setting up slave"); - let slaveId = JSON.parse(Buffer.from(answers.controllerToken.split(".")[1], "base64")).slave; - await execSlave(["config", "set", "slave.id", slaveId]); - await execSlave(["config", "set", "slave.name", answers.slaveName]); - await execSlave(["config", "set", "slave.controller_url", answers.controllerUrl]); - await execSlave(["config", "set", "slave.controller_token", answers.controllerToken]); - await execSlave(["config", "set", "slave.public_address", answers.publicAddress]); - await execSlave(["config", "set", "slave.factorio_directory", answers.factorioDir]); + if (answers.mode === "host") { + logger.info("Setting up host"); + let hostId = JSON.parse(Buffer.from(answers.controllerToken.split(".")[1], "base64")).host; + await execHost(["config", "set", "host.id", hostId]); + await execHost(["config", "set", "host.name", answers.hostName]); + await execHost(["config", "set", "host.controller_url", answers.controllerUrl]); + await execHost(["config", "set", "host.controller_token", answers.controllerToken]); + await execHost(["config", "set", "host.public_address", answers.publicAddress]); + await execHost(["config", "set", "host.factorio_directory", answers.factorioDir]); } - if (!dev && ["standalone", "controller", "slave"].includes(answers.mode)) { + if (!dev && ["standalone", "controller", "host"].includes(answers.mode)) { logger.info("Writing run scripts"); await writeScripts(answers.mode); } diff --git a/packages/ctl/README.md b/packages/ctl/README.md index 8daeb6c9..8ac84d33 100644 --- a/packages/ctl/README.md +++ b/packages/ctl/README.md @@ -37,7 +37,7 @@ For example, installing the Subspace Storage plugin: npm install @clusterio/plugin-subspace_storage npx clusterioctl plugin add @clusterio/plugin-subspace_storage -Since the `plugin-list.json` is shared between controller, slave and ctl you usually only need to do this once per machine. +Since the `plugin-list.json` is shared between controller, host and ctl you usually only need to do this once per machine. #### `plugin remove ` @@ -51,7 +51,7 @@ For example, uninstalling the Subspace Storage plugin: npx clusterioctl plugin remove subspace_storage npm uninstall @clusterio/plugin-subspace_storage -Since the `plugin-list.json` is shared between controller, slave and ctl you usually only need to do this once per machine. +Since the `plugin-list.json` is shared between controller, host and ctl you usually only need to do this once per machine. #### `plugin list` diff --git a/packages/ctl/ctl.js b/packages/ctl/ctl.js index 8000e783..8eeb56c4 100755 --- a/packages/ctl/ctl.js +++ b/packages/ctl/ctl.js @@ -83,7 +83,7 @@ class Control extends libLink.Link { async accountUpdateEventHandler() { } - async slaveUpdateEventHandler() { } + async hostUpdateEventHandler() { } async instanceUpdateEventHandler() { } @@ -98,12 +98,12 @@ class Control extends libLink.Link { async setLogSubscriptions({ all = false, controller = false, - slave_ids = [], + host_ids = [], instance_ids = [], max_level = null, }) { await libLink.messages.setLogSubscriptions.send(this, { - all, controller, slave_ids, instance_ids, max_level, + all, controller, host_ids, instance_ids, max_level, }); } diff --git a/packages/ctl/src/commands.js b/packages/ctl/src/commands.js index 07fc8255..b6d647bd 100644 --- a/packages/ctl/src/commands.js +++ b/packages/ctl/src/commands.js @@ -237,39 +237,39 @@ controllerPluginCommands.add(new libCommand.Command({ controllerCommands.add(controllerPluginCommands); -const slaveCommands = new libCommand.CommandTree({ name: "slave", description: "Slave management" }); -slaveCommands.add(new libCommand.Command({ - definition: [["list", "l"], "List slaves connected to the controller"], +const hostCommands = new libCommand.CommandTree({ name: "host", description: "Host management" }); +hostCommands.add(new libCommand.Command({ + definition: [["list", "l"], "List hosts connected to the controller"], handler: async function(args, control) { - let response = await libLink.messages.listSlaves.send(control); + let response = await libLink.messages.listHosts.send(control); print(asTable(response.list)); }, })); -slaveCommands.add(new libCommand.Command({ - definition: ["generate-token", "Generate token for a slave", (yargs) => { - yargs.option("id", { type: "number", nargs: 1, describe: "Slave id" }); +hostCommands.add(new libCommand.Command({ + definition: ["generate-token", "Generate token for a host", (yargs) => { + yargs.option("id", { type: "number", nargs: 1, describe: "Host id" }); }], handler: async function(args, control) { - let slaveId = typeof args.id === "number" ? args.id : null; - let response = await libLink.messages.generateSlaveToken.send(control, { slave_id: slaveId }); + let hostId = typeof args.id === "number" ? args.id : null; + let response = await libLink.messages.generateHostToken.send(control, { host_id: hostId }); print(response.token); }, })); -slaveCommands.add(new libCommand.Command({ - definition: ["create-config", "Create slave config", (yargs) => { - yargs.option("id", { type: "number", nargs: 1, describe: "Slave id", default: null }); - yargs.option("name", { type: "string", nargs: 1, describe: "Slave name", default: null }); +hostCommands.add(new libCommand.Command({ + definition: ["create-config", "Create host config", (yargs) => { + yargs.option("id", { type: "number", nargs: 1, describe: "Host id", default: null }); + yargs.option("name", { type: "string", nargs: 1, describe: "Host name", default: null }); yargs.option("generate-token", { type: "boolean", nargs: 0, describe: "Generate authentication token", default: false, }); yargs.option("output", { - type: "string", nargs: 1, describe: "Path to output config (- for stdout)", default: "config-slave.json", + type: "string", nargs: 1, describe: "Path to output config (- for stdout)", default: "config-host.json", }); }], handler: async function(args, control) { - let response = await libLink.messages.createSlaveConfig.send(control, { + let response = await libLink.messages.createHostConfig.send(control, { id: args.id, name: args.name, generate_token: args.generateToken, }); @@ -430,7 +430,7 @@ instanceConfigCommands.add(new libCommand.Command({ throw new libErrors.CommandError(`No editor avalible. Checked CLI input, EDITOR and VISUAL env vars Try "ctl controller config edit "`); } - let disallowedList = {"instance.id": 0, "instance.assigned_slave": 0, "factorio.settings": 0}; + let disallowedList = {"instance.id": 0, "instance.assigned_host": 0, "factorio.settings": 0}; let allConfigElements = await serializedConfigToString( response.serialized_config, libConfig.InstanceConfig, @@ -487,16 +487,16 @@ instanceConfigCommands.add(new libCommand.Command({ instanceCommands.add(instanceConfigCommands); instanceCommands.add(new libCommand.Command({ - definition: ["assign [slave]", "Assign instance to a slave", (yargs) => { + definition: ["assign [host]", "Assign instance to a host", (yargs) => { yargs.positional("instance", { describe: "Instance to assign", type: "string" }); - yargs.positional("slave", { describe: "Slave to assign to or unassign if none", type: "string" }); + yargs.positional("host", { describe: "Host to assign to or unassign if none", type: "string" }); }], handler: async function(args, control) { let instanceId = await libCommand.resolveInstance(control, args.instance); - let slaveId = args.slave ? await libCommand.resolveSlave(control, args.slave) : null; + let hostId = args.host ? await libCommand.resolveHost(control, args.host) : null; await libLink.messages.assignInstanceCommand.send(control, { instance_id: instanceId, - slave_id: slaveId, + host_id: hostId, }); }, })); @@ -1586,19 +1586,19 @@ logCommands.add(new libCommand.Command({ yargs.options({ "all": { describe: "Follow the whole cluster log", nargs: 0, type: "boolean", default: false }, "controller": { describe: "Follow log of the controller", nargs: 0, type: "boolean", default: false }, - "slave": { describe: "Follow log of given slave", nargs: 1, type: "string", default: null }, + "host": { describe: "Follow log of given host", nargs: 1, type: "string", default: null }, "instance": { describe: "Follow log of given instance", nargs: 1, type: "string", default: null }, }); }], handler: async function(args, control) { - if (!args.all && !args.controller && !args.slave && !args.instance) { - logger.error("At least one of --all, --controller, --slave and --instance must be passed"); + if (!args.all && !args.controller && !args.host && !args.instance) { + logger.error("At least one of --all, --controller, --host and --instance must be passed"); process.exitCode = 1; return; } let instance_ids = args.instance ? [await libCommand.resolveInstance(control, args.instance)] : []; - let slave_ids = args.slave ? [await libCommand.resolveSlave(control, args.slave)] : []; - await control.setLogSubscriptions({ all: args.all, controller: args.controller, slave_ids, instance_ids }); + let host_ids = args.host ? [await libCommand.resolveHost(control, args.host)] : []; + await control.setLogSubscriptions({ all: args.all, controller: args.controller, host_ids, instance_ids }); control.keepOpen = true; }, })); @@ -1608,7 +1608,7 @@ logCommands.add(new libCommand.Command({ yargs.options({ "all": { describe: "Query the whole cluster log", nargs: 0, type: "boolean", default: false }, "controller": { describe: "Query log of the controller", nargs: 0, type: "boolean", default: false }, - "slave": { describe: "Query log of given slave", nargs: 1, type: "string", default: null }, + "host": { describe: "Query log of given host", nargs: 1, type: "string", default: null }, "instance": { describe: "Query log of given instance", nargs: 1, type: "string", default: null }, "max-level": { describe: "Maximum log level to return", nargs: 1, type: "string", default: null }, "limit": { describe: "Max number of entries to return", nargs: 1, type: "number", default: 1000 }, @@ -1616,17 +1616,17 @@ logCommands.add(new libCommand.Command({ }); }], handler: async function(args, control) { - if (!args.all && !args.controller && !args.slave && !args.instance) { - logger.error("At least one of --all, --controller, --slave and --instance must be passed"); + if (!args.all && !args.controller && !args.host && !args.instance) { + logger.error("At least one of --all, --controller, --host and --instance must be passed"); process.exitCode = 1; return; } let instance_ids = args.instance ? [await libCommand.resolveInstance(control, args.instance)] : []; - let slave_ids = args.slave ? [await libCommand.resolveSlave(control, args.slave)] : []; + let host_ids = args.host ? [await libCommand.resolveHost(control, args.host)] : []; let result = await libLink.messages.queryLog.send(control, { all: args.all, controller: args.controller, - slave_ids, + host_ids, instance_ids, max_level: args.maxLevel, limit: args.limit, @@ -1663,7 +1663,7 @@ debugCommands.add(new libCommand.Command({ async function registerCommands(controlPlugins, yargs) { const rootCommands = new libCommand.CommandTree({ name: "clusterioctl", description: "Manage cluster" }); rootCommands.add(controllerCommands); - rootCommands.add(slaveCommands); + rootCommands.add(hostCommands); rootCommands.add(instanceCommands); rootCommands.add(modPackCommands); rootCommands.add(modCommands); diff --git a/packages/slave/README.md b/packages/host/README.md similarity index 64% rename from packages/slave/README.md rename to packages/host/README.md index 45a489ce..418e36ac 100644 --- a/packages/slave/README.md +++ b/packages/host/README.md @@ -1,28 +1,28 @@ -# Clusterio Slave +# Clusterio Host Node hosting Factorio servers in a Clusterio cluster. -Clusterio slaves connect to the controller and waits for commands from the controller to start up and stop instances. -A cluster can have any number of slaves in it located on different computers, and each slave can host any number of instances each of which is a Factorio server that talks with the rest of the cluster. +Clusterio hosts connect to the controller and waits for commands from the controller to start up and stop instances. +A cluster can have any number of hosts in it located on different computers, and each host can host any number of instances each of which is a Factorio server that talks with the rest of the cluster. ## Usage - npx clusterioslave + npx clusteriohost Common options: - * `--plugin-list ` JSON file to use for storing the list of plugins that are available to the slave. + * `--plugin-list ` JSON file to use for storing the list of plugins that are available to the host. Defaults to `plugin-list.json` and will be created if it does not exist. See the `plugin` command for managing this list. - * `--config ` JSON file to use for storing configuration for the slave. - Defaults to `config-slave.json` and will be created if it does not exist. + * `--config ` JSON file to use for storing configuration for the host. + Defaults to `config-host.json` and will be created if it does not exist. See the `config` command for inspecting and modifying the configuration. ### `plugin ` -Configure plugins available to be loaded by the slave. +Configure plugins available to be loaded by the host. The available plugins will be loaded unless they have been disabled in the configuration, see the config command for disabling plugins. @@ -34,9 +34,9 @@ A relative path must start with ./ or ../ (or .\ and ..\ on Windows) otherwise i For example, installing the Subspace Storage plugin: npm install @clusterio/plugin-subspace_storage - npx clusterioslave plugin add @clusterio/plugin-subspace_storage + npx clusteriohost plugin add @clusterio/plugin-subspace_storage -Since the `plugin-list.json` is shared between controller, slave and ctl you usually only need to do this once per machine. +Since the `plugin-list.json` is shared between controller, host and ctl you usually only need to do this once per machine. #### `plugin remove ` @@ -47,10 +47,10 @@ Removing and unistalling a plugin is usually not neccessary as the functions pro For example, uninstalling the Subspace Storage plugin: - npx clusterioslave plugin remove subspace_storage + npx clusteriohost plugin remove subspace_storage npm uninstall @clusterio/plugin-subspace_storage -Since the `plugin-list.json` is shared between controller, slave and ctl you usually only need to do this once per machine. +Since the `plugin-list.json` is shared between controller, host and ctl you usually only need to do this once per machine. #### `plugin list` @@ -60,8 +60,8 @@ Lists the plugins set up to be available by name followed by path. ### `config` -Manage the slave configuration offline. -This should only be used when the slave is stopped, otherwise the config read might be out of date and config changes will be overwritten when the slave shuts down. +Manage the host configuration offline. +This should only be used when the host is stopped, otherwise the config read might be out of date and config changes will be overwritten when the host shuts down. #### `config set [value]` @@ -85,7 +85,7 @@ Lists up all configuration entries with their currently configured values. ### `run` -Runs the slave. +Runs the host. ## See Also diff --git a/packages/slave/slave.js b/packages/host/host.js similarity index 67% rename from packages/slave/slave.js rename to packages/host/host.js index 8bf9d58e..fae49687 100755 --- a/packages/slave/slave.js +++ b/packages/host/host.js @@ -1,16 +1,16 @@ #!/usr/bin/env node /** - * Clusterio slave + * Clusterio host * * Connects to the controller and hosts Factorio servers that can * communicate with the cluster. It is remotely controlled by {@link * module:controller/controller}. * - * @module slave/slave + * @module host/host * @author Danielv123, Hornwitser * @example - * npx clusterioslave run + * npx clusteriohost run */ "use strict"; const fs = require("fs-extra"); @@ -30,44 +30,44 @@ const libSharedCommands = require("@clusterio/lib/shared_commands"); const { ConsoleTransport, FilteredTransport, levels, logger } = require("@clusterio/lib/logging"); const libLoggingUtils = require("@clusterio/lib/logging_utils"); -const Slave = require("./src/Slave"); +const Host = require("./src/Host"); -class SlaveConnector extends libLink.WebSocketClientConnector { - constructor(slaveConfig, tlsCa, pluginInfos) { +class HostConnector extends libLink.WebSocketClientConnector { + constructor(hostConfig, tlsCa, pluginInfos) { super( - slaveConfig.get("slave.controller_url"), - slaveConfig.get("slave.max_reconnect_delay"), + hostConfig.get("host.controller_url"), + hostConfig.get("host.max_reconnect_delay"), tlsCa ); - this.slaveConfig = slaveConfig; + this.hostConfig = hostConfig; this.pluginInfos = pluginInfos; } register() { - logger.info("Connector | registering slave"); + logger.info("Connector | registering host"); let plugins = {}; for (let pluginInfo of this.pluginInfos) { plugins[pluginInfo.name] = pluginInfo.version; } - this.sendHandshake("register_slave", { - token: this.slaveConfig.get("slave.controller_token"), - agent: "Clusterio Slave", + this.sendHandshake("register_host", { + token: this.hostConfig.get("host.controller_token"), + agent: "Clusterio Host", version, - id: this.slaveConfig.get("slave.id"), - name: this.slaveConfig.get("slave.name"), - public_address: this.slaveConfig.get("slave.public_address"), + id: this.hostConfig.get("host.id"), + name: this.hostConfig.get("host.name"), + public_address: this.hostConfig.get("host.public_address"), plugins, }); } } -async function startSlave() { +async function startHost() { // argument parsing const args = yargs - .scriptName("slave") + .scriptName("host") .usage("$0 [options]") .option("log-level", { nargs: 1, @@ -84,8 +84,8 @@ async function startSlave() { }) .option("config", { nargs: 1, - describe: "slave config file to use", - default: "config-slave.json", + describe: "host config file to use", + default: "config-host.json", type: "string", }) .option("plugin-list", { @@ -95,8 +95,8 @@ async function startSlave() { type: "string", }) .command("plugin", "Manage available plugins", libSharedCommands.pluginCommand) - .command("config", "Manage Slave config", libSharedCommands.configCommand) - .command("run", "Run slave") + .command("config", "Manage Host config", libSharedCommands.configCommand) + .command("run", "Run host") .demandCommand(1, "You need to specify a command to run") .strict() .argv @@ -106,21 +106,21 @@ async function startSlave() { // Migration from alpha-10 single file logs, note that we can't use // the logger here as it's not initalized yet. /* eslint-disable no-console */ - let slaveLogDirectory = path.join(args.logDirectory, "slave"); - if (!await fs.pathExists(slaveLogDirectory) && await fs.pathExists("slave.log")) { - console.log("Migrating slave log..."); - await fs.ensureDir(slaveLogDirectory); - await libLoggingUtils.migrateLogs("slave.log", slaveLogDirectory, "slave-%DATE%.log"); - console.log("Migration complete, you should delete slave.log now"); + let hostLogDirectory = path.join(args.logDirectory, "host"); + if (!await fs.pathExists(hostLogDirectory) && await fs.pathExists("host.log")) { + console.log("Migrating host log..."); + await fs.ensureDir(hostLogDirectory); + await libLoggingUtils.migrateLogs("host.log", hostLogDirectory, "host-%DATE%.log"); + console.log("Migration complete, you should delete host.log now"); } /* eslint-enable no-console */ } logger.add(new winston.transports.DailyRotateFile({ format: winston.format.json(), - filename: "slave-%DATE%.log", + filename: "host-%DATE%.log", utc: true, - dirname: path.join(args.logDirectory, "slave"), + dirname: path.join(args.logDirectory, "host"), })); if (args.logLevel !== "none") { logger.add(new ConsoleTransport({ @@ -133,7 +133,7 @@ async function startSlave() { let command = args._[0]; if (command === "run") { - logger.info(`Starting Clusterio slave ${version}`); + logger.info(`Starting Clusterio host ${version}`); } logger.info(`Loading available plugins from ${args.pluginList}`); @@ -158,14 +158,14 @@ async function startSlave() { libConfig.finalizeConfigs(); logger.info(`Loading config from ${args.config}`); - let slaveConfig = new libConfig.SlaveConfig("slave"); + let hostConfig = new libConfig.HostConfig("host"); try { - await slaveConfig.load(JSON.parse(await fs.readFile(args.config))); + await hostConfig.load(JSON.parse(await fs.readFile(args.config))); } catch (err) { if (err.code === "ENOENT") { logger.info("Config not found, initializing new config"); - await slaveConfig.init(); + await hostConfig.init(); } else { throw new libErrors.StartupError(`Failed to load ${args.config}: ${err.message}`); @@ -173,49 +173,49 @@ async function startSlave() { } if (command === "config") { - await libSharedCommands.handleConfigCommand(args, slaveConfig, args.config); + await libSharedCommands.handleConfigCommand(args, hostConfig, args.config); return; } // If we get here the command was run - await fs.ensureDir(slaveConfig.get("slave.instances_directory")); - await fs.ensureDir(slaveConfig.get("slave.mods_directory")); + await fs.ensureDir(hostConfig.get("host.instances_directory")); + await fs.ensureDir(hostConfig.get("host.mods_directory")); await fs.ensureDir("modules"); // Set the process title, shows up as the title of the CMD window on windows // and as the process name in ps/top on linux. - process.title = "clusterioSlave"; + process.title = "clusterioHost"; // make sure we have the controller access token - if (slaveConfig.get("slave.controller_token") === "enter token here") { + if (hostConfig.get("host.controller_token") === "enter token here") { logger.fatal("ERROR invalid config!"); logger.fatal( "Controller requires an access token for socket operations. As clusterio\n"+ - "slaves depends upon this, please set your token using the command npx\n"+ - "clusterioslave config set slave.controller_token . You can generate an\n"+ - "auth token using npx clusterioctl generate-slave-token." + "hosts depends upon this, please set your token using the command npx\n"+ + "clusteriohost config set host.controller_token . You can generate an\n"+ + "auth token using npx clusterioctl generate-host-token." ); process.exitCode = 1; return; } // make sure url ends with / - if (!slaveConfig.get("slave.controller_url").endsWith("/")) { + if (!hostConfig.get("host.controller_url").endsWith("/")) { logger.fatal("ERROR invalid config!"); - logger.fatal("slave.controller_url must end with '/'"); + logger.fatal("host.controller_url must end with '/'"); process.exitCode = 1; return; } let tlsCa = null; - let tlsCaPath = slaveConfig.get("slave.tls_ca"); + let tlsCaPath = hostConfig.get("host.tls_ca"); if (tlsCaPath) { tlsCa = await fs.readFile(tlsCaPath); } - let slaveConnector = new SlaveConnector(slaveConfig, tlsCa, pluginInfos); - let slave = new Slave(slaveConnector, slaveConfig, tlsCa, pluginInfos); + let hostConnector = new HostConnector(hostConfig, tlsCa, pluginInfos); + let host = new Host(hostConnector, hostConfig, tlsCa, pluginInfos); // Handle interrupts let secondSigint = false; @@ -229,7 +229,7 @@ async function startSlave() { secondSigint = true; logger.info("Caught interrupt signal, shutting down"); - slave.shutdown(); + host.shutdown(); }); let secondSigterm = false; process.on("SIGTERM", () => { @@ -242,19 +242,19 @@ async function startSlave() { secondSigterm = true; logger.info("Caught termination signal, shutting down"); - slave.shutdown(); + host.shutdown(); }); process.on("SIGHUP", () => { logger.info("Terminal closed, shutting down"); - slave.shutdown(); + host.shutdown(); }); - slaveConnector.once("connect", () => { - logger.add(new libLoggingUtils.LinkTransport({ link: slave })); + hostConnector.once("connect", () => { + logger.add(new libLoggingUtils.LinkTransport({ link: host })); }); - await slaveConnector.connect(); - logger.info("Started slave"); + await hostConnector.connect(); + logger.info("Started host"); } if (module === require.main) { @@ -266,15 +266,15 @@ I version of clusterio. Expect things to break. I +==========================================================+ ` ); - startSlave().catch(err => { + startHost().catch(err => { if (err instanceof libErrors.AuthenticationFailed) { logger.fatal(err.message); } else if (err instanceof libErrors.StartupError) { logger.fatal(` -+-----------------------------------+ -| Unable to to start clusterioslave | -+-----------------------------------+ ++----------------------------------+ +| Unable to to start clusteriohost | ++----------------------------------+ ${err.stack}` ); @@ -289,7 +289,7 @@ ${err.original.stack}` } else { logger.fatal(` +------------------------------------------------------------+ -| Unexpected error occured while starting slave, please | +| Unexpected error occured while starting host, please | | report it to https://github.com/clusterio/clusterio/issues | +------------------------------------------------------------+ ${err.stack}` diff --git a/packages/slave/lua/clusterio_lib/api.lua b/packages/host/lua/clusterio_lib/api.lua similarity index 100% rename from packages/slave/lua/clusterio_lib/api.lua rename to packages/host/lua/clusterio_lib/api.lua diff --git a/packages/slave/lua/clusterio_lib/changelog.txt b/packages/host/lua/clusterio_lib/changelog.txt similarity index 100% rename from packages/slave/lua/clusterio_lib/changelog.txt rename to packages/host/lua/clusterio_lib/changelog.txt diff --git a/packages/slave/lua/clusterio_lib/info.json b/packages/host/lua/clusterio_lib/info.json similarity index 100% rename from packages/slave/lua/clusterio_lib/info.json rename to packages/host/lua/clusterio_lib/info.json diff --git a/packages/slave/lua/export/clusterio_api.lua b/packages/host/lua/export/clusterio_api.lua similarity index 100% rename from packages/slave/lua/export/clusterio_api.lua rename to packages/host/lua/export/clusterio_api.lua diff --git a/packages/slave/lua/export/control.lua b/packages/host/lua/export/control.lua similarity index 100% rename from packages/slave/lua/export/control.lua rename to packages/host/lua/export/control.lua diff --git a/packages/slave/lua/export/data-final-fixes.lua b/packages/host/lua/export/data-final-fixes.lua similarity index 100% rename from packages/slave/lua/export/data-final-fixes.lua rename to packages/host/lua/export/data-final-fixes.lua diff --git a/packages/slave/lua/export/info.json b/packages/host/lua/export/info.json similarity index 100% rename from packages/slave/lua/export/info.json rename to packages/host/lua/export/info.json diff --git a/packages/slave/lua/export/settings-final-fixes.lua b/packages/host/lua/export/settings-final-fixes.lua similarity index 100% rename from packages/slave/lua/export/settings-final-fixes.lua rename to packages/host/lua/export/settings-final-fixes.lua diff --git a/packages/slave/modules/clusterio/api.lua b/packages/host/modules/clusterio/api.lua similarity index 100% rename from packages/slave/modules/clusterio/api.lua rename to packages/host/modules/clusterio/api.lua diff --git a/packages/slave/modules/clusterio/impl.lua b/packages/host/modules/clusterio/impl.lua similarity index 100% rename from packages/slave/modules/clusterio/impl.lua rename to packages/host/modules/clusterio/impl.lua diff --git a/packages/slave/modules/clusterio/module.json b/packages/host/modules/clusterio/module.json similarity index 100% rename from packages/slave/modules/clusterio/module.json rename to packages/host/modules/clusterio/module.json diff --git a/packages/slave/modules/clusterio/serialize.lua b/packages/host/modules/clusterio/serialize.lua similarity index 100% rename from packages/slave/modules/clusterio/serialize.lua rename to packages/host/modules/clusterio/serialize.lua diff --git a/packages/slave/package.json b/packages/host/package.json similarity index 79% rename from packages/slave/package.json rename to packages/host/package.json index 78d59b72..dbc0a401 100644 --- a/packages/slave/package.json +++ b/packages/host/package.json @@ -1,15 +1,15 @@ { - "name": "@clusterio/slave", - "description": "Implementation of Clusterio slave server", + "name": "@clusterio/host", + "description": "Implementation of Clusterio host server", "author": "Hornwitser", "license": "MIT", "version": "2.0.0-alpha.13", - "main": "slave.js", + "main": "host.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "bin": { - "clusterioslave": "./slave.js" + "clusteriohost": "./host.js" }, "keywords": [ "factorio" diff --git a/packages/slave/src/Slave.js b/packages/host/src/Host.js similarity index 95% rename from packages/slave/src/Slave.js rename to packages/host/src/Host.js index 306c73ba..169e1e9a 100644 --- a/packages/slave/src/Slave.js +++ b/packages/host/src/Host.js @@ -49,7 +49,7 @@ async function discoverInstances(instancesDir) { let instanceInfos = new Map(); for (let entry of await fs.readdir(instancesDir, { withFileTypes: true })) { if (entry.isDirectory()) { - let instanceConfig = new libConfig.InstanceConfig("slave"); + let instanceConfig = new libConfig.InstanceConfig("host"); let configPath = path.join(instancesDir, entry.name, "instance.json"); try { @@ -81,16 +81,16 @@ async function discoverInstances(instancesDir) { } /** - * Handles running the slave + * Handles running the host * * Connects to the controller over the WebSocket and manages intsances. - * @alias module:slave/src/Slave + * @alias module:host/src/Host */ -class Slave extends libLink.Link { +class Host extends libLink.Link { // I don't like God classes, but the alternative of putting all this state // into global variables is not much better. - constructor(connector, slaveConfig, tlsCa, pluginInfos) { - super("slave", "controller", connector); + constructor(connector, hostConfig, tlsCa, pluginInfos) { + super("host", "controller", connector); libLink.attachAllMessages(this); this.pluginInfos = pluginInfos; @@ -98,7 +98,7 @@ class Slave extends libLink.Link { libPlugin.attachPluginMessages(this, { info: pluginInfo }); } - this.config = slaveConfig; + this.config = hostConfig; /** * Certificate authority used to validate TLS connections to the controller. @@ -173,7 +173,7 @@ class Slave extends libLink.Link { throw new Error(`Instance folder was unepectedly invalid: name ${err.message}`); } - let instancesDir = this.config.get("slave.instances_directory"); + let instancesDir = this.config.get("host.instances_directory"); for (let i = 0; i < 10; i++) { // Limit attempts in case this is somehow an infinite loop let candidateDir = path.join(instancesDir, await libFileOps.findUnusedName(instancesDir, name)); try { @@ -315,13 +315,13 @@ class Slave extends libLink.Link { instanceInfo.config.update(serialized_config, true, "controller"); } else { - let instanceConfig = new libConfig.InstanceConfig("slave"); + let instanceConfig = new libConfig.InstanceConfig("host"); await instanceConfig.load(serialized_config, "controller"); let instanceDir = await this._createNewInstanceDir(instanceConfig.get("instance.name")); logger.info(`Creating ${instanceDir}`); - await Instance.create(instanceDir, this.config.get("slave.factorio_directory")); + await Instance.create(instanceDir, this.config.get("host.factorio_directory")); instanceInfo = { path: instanceDir, config: instanceConfig, @@ -336,7 +336,7 @@ class Slave extends libLink.Link { // Somewhat hacky, but in the event of a lost session the status is // resent on assigment since the controller sends an assigment - // request for all the instances it knows should be on this slave. + // request for all the instances it knows should be on this host. let instanceConnection = this.instanceConnections.get(instance_id); libLink.messages.instanceStatusChanged.send(this, { instance_id, @@ -388,7 +388,7 @@ class Slave extends libLink.Link { * Initialize and connect an unloaded instance * * @param {number} instanceId - ID of instance to initialize. - * @returns {Promise} connection to instance. + * @returns {Promise} connection to instance. */ async _connectInstance(instanceId) { let instanceInfo = this.getRequestInstanceInfo(instanceId); @@ -399,7 +399,7 @@ class Slave extends libLink.Link { let [connectionClient, connectionServer] = libLink.VirtualConnector.makePair(); let instanceConnection = new InstanceConnection(connectionServer, this, instanceId); let instance = new Instance( - this, connectionClient, instanceInfo.path, this.config.get("slave.factorio_directory"), instanceInfo.config + this, connectionClient, instanceInfo.path, this.config.get("host.factorio_directory"), instanceInfo.config ); this.instanceConnections.set(instanceId, instanceConnection); @@ -422,8 +422,8 @@ class Slave extends libLink.Link { for await (let result of libPrometheus.defaultRegistry.collect()) { if (result.metric.name.startsWith("process_")) { results.push(libPrometheus.serializeResult(result, { - addLabels: { "slave_id": String(this.config.get("slave.id")) }, - metricName: result.metric.name.replace("process_", "clusterio_slave_"), + addLabels: { "host_id": String(this.config.get("host.id")) }, + metricName: result.metric.name.replace("process_", "clusterio_host_"), })); } else { @@ -601,7 +601,7 @@ class Slave extends libLink.Link { checkRequestSaveName(filename); let instanceInfo = this.getRequestInstanceInfo(instance_id); - let url = new URL(this.config.get("slave.controller_url")); + let url = new URL(this.config.get("host.controller_url")); url.pathname += `api/stream/${stream_id}`; let response = await phin({ url, method: "GET", @@ -656,7 +656,7 @@ class Slave extends libLink.Link { throw err; } - let url = new URL(this.config.get("slave.controller_url")); + let url = new URL(this.config.get("host.controller_url")); url.pathname += `api/stream/${stream_id}`; phin({ url, method: "PUT", @@ -706,10 +706,10 @@ class Slave extends libLink.Link { * Discover available instances * * Looks through the instances directory for instances and updates - * the slave and controller with the new list of instances. + * the host and controller with the new list of instances. */ async updateInstances() { - this.discoveredInstanceInfos = await discoverInstances(this.config.get("slave.instances_directory")); + this.discoveredInstanceInfos = await discoverInstances(this.config.get("host.instances_directory")); let list = []; for (let [instanceId, instanceInfo] of this.discoveredInstanceInfos) { let instanceConnection = this.instanceConnections.get(instanceId); @@ -773,7 +773,7 @@ class Slave extends libLink.Link { for (let instanceId of this.instanceConnections.keys()) { await this.stopInstance(instanceId); } - await this.connector.close(1000, "Slave Shutdown"); + await this.connector.close(1000, "Host Shutdown"); // Clear silly interval in pidfile library. pidusage.clear(); @@ -781,7 +781,7 @@ class Slave extends libLink.Link { setBlocking(true); logger.error(` +------------------------------------------------------------+ -| Unexpected error occured while shutting down slave, please | +| Unexpected error occured while shutting down host, please | | report it to https://github.com/clusterio/clusterio/issues | +------------------------------------------------------------+ ${err.stack}` @@ -801,7 +801,7 @@ ${err.stack}` } } -module.exports = Slave; +module.exports = Host; // For testing only module.exports._discoverInstances = discoverInstances; diff --git a/packages/slave/src/Instance.js b/packages/host/src/Instance.js similarity index 97% rename from packages/slave/src/Instance.js rename to packages/host/src/Instance.js index 726e4f1f..d416e46c 100644 --- a/packages/slave/src/Instance.js +++ b/packages/host/src/Instance.js @@ -98,13 +98,13 @@ const serverSettingsActions = { /** * Keeps track of the runtime parameters of an instance - * @alias module:slave/src/Instance + * @alias module:host/src/Instance */ class Instance extends libLink.Link { - constructor(slave, connector, dir, factorioDir, instanceConfig) { - super("instance", "slave", connector); + constructor(host, connector, dir, factorioDir, instanceConfig) { + super("instance", "host", connector); libLink.attachAllMessages(this); - this._slave = slave; + this._host = host; this._dir = dir; this.plugins = new Map(); @@ -461,10 +461,10 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); this._saveStats().catch(err => this.logger.error(`Error saving stats:\n${err.stack}`)); } - async _loadPlugin(pluginInfo, slave) { + async _loadPlugin(pluginInfo, host) { let pluginLoadStarted = Date.now(); let InstancePluginClass = await libPluginLoader.loadInstancePluginClass(pluginInfo); - let instancePlugin = new InstancePluginClass(pluginInfo, this, slave); + let instancePlugin = new InstancePluginClass(pluginInfo, this, host); this.plugins.set(pluginInfo.name, instancePlugin); await instancePlugin.init(); libPlugin.attachPluginMessages(this, instancePlugin); @@ -509,14 +509,14 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); for (let pluginInfo of pluginInfos) { if ( !pluginInfo.instanceEntrypoint - || !this._slave.serverPlugins.has(pluginInfo.name) + || !this._host.serverPlugins.has(pluginInfo.name) || !this.config.group(pluginInfo.name).get("load_plugin") ) { continue; } try { - await this._loadPlugin(pluginInfo, this._slave); + await this._loadPlugin(pluginInfo, this._host); } catch (err) { this.notifyExit(); await this.sendSaveListUpdate(); @@ -593,7 +593,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); * a vanilla mods folder. If the instance mods directory does't exist * then it will be created. * - * On Linux this creates symlinks to mods in the slave's mods folder, on + * On Linux this creates symlinks to mods in the host's mods folder, on * Windows hard links are used instead due to symlinks being privileged. */ async syncMods() { @@ -608,7 +608,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); // TODO validate factorioVersion - if (!this._slave.config.get("slave.mods_directory_is_shared")) { + if (!this._host.config.get("host.mods_directory_is_shared")) { throw new Error("Fetching mods is not implemented"); } @@ -629,7 +629,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); } // Add mods from mod the pack - const modsDir = this._slave.config.get("slave.mods_directory"); + const modsDir = this._host.config.get("host.mods_directory"); for (let mod of this.activeModPack.mods.values()) { const modFile = `${mod.name}_${mod.version}.zip`; const target = path.join(modsDir, modFile); @@ -668,7 +668,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); this.logger.verbose("Writing server-adminlist.json"); libFileOps.safeOutputFile( this.server.writePath("server-adminlist.json"), - JSON.stringify([...this._slave.adminlist], null, 4) + JSON.stringify([...this._host.adminlist], null, 4) ); } @@ -676,7 +676,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); this.logger.verbose("Writing server-banlist.json"); libFileOps.safeOutputFile( this.server.writePath("server-banlist.json"), - JSON.stringify([...this._slave.banlist].map( + JSON.stringify([...this._host.banlist].map( ([username, reason]) => ({ username, reason }) ), null, 4), ); @@ -686,7 +686,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); this.logger.verbose("Writing server-whitelist.json"); libFileOps.safeOutputFile( this.server.writePath("server-whitelist.json"), - JSON.stringify([...this._slave.whitelist], null, 4) + JSON.stringify([...this._host.whitelist], null, 4) ); } @@ -897,7 +897,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); if (this.config.get("factorio.sync_whitelist")) { await this.sendRcon("/whitelist clear"); - for (let player of this._slave.whitelist) { + for (let player of this._host.whitelist) { await this.sendRcon(`/whitelist ${player}`); } } @@ -1072,16 +1072,16 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); let zip = await libFactorio.exportData(this.server); let content = await zip.generateAsync({ type: "nodebuffer" }); - let url = new URL(this._slave.config.get("slave.controller_url")); + let url = new URL(this._host.config.get("host.controller_url")); url.pathname += "api/upload-export"; url.searchParams.set("mod_pack_id", this.activeModPack.id); let response = await phin({ url, method: "PUT", data: content, - core: { ca: this._slave.tlsCa }, + core: { ca: this._host.tlsCa }, headers: { "Content-Type": "application/zip", - "x-access-token": this._slave.config.get("slave.controller_token"), + "x-access-token": this._host.config.get("host.controller_token"), }, }); if (response.statusCode !== 200) { diff --git a/packages/slave/src/InstanceConnection.js b/packages/host/src/InstanceConnection.js similarity index 74% rename from packages/slave/src/InstanceConnection.js rename to packages/host/src/InstanceConnection.js index 41a6aa7f..b7a94eb3 100644 --- a/packages/slave/src/InstanceConnection.js +++ b/packages/host/src/InstanceConnection.js @@ -5,28 +5,28 @@ const libErrors = require("@clusterio/lib/errors"); class InstanceConnection extends libLink.Link { - constructor(connector, slave, instanceId) { - super("slave", "instance", connector); - this.slave = slave; + constructor(connector, host, instanceId) { + super("host", "instance", connector); + this.host = host; this.instanceId = instanceId; this.plugins = new Map(); this.status = "stopped"; libLink.attachAllMessages(this); - for (let pluginInfo of slave.pluginInfos) { + for (let pluginInfo of host.pluginInfos) { libPlugin.attachPluginMessages(this, { info: pluginInfo }); } } async forwardRequestToController(message, request) { - return await request.send(this.slave, message.data); + return await request.send(this.host, message.data); } async forwardRequestToInstance(message, request) { let instanceId = message.data.instance_id; - let instanceConnection = this.slave.instanceConnections.get(instanceId); + let instanceConnection = this.host.instanceConnections.get(instanceId); if (!instanceConnection) { - // Instance is probably on another slave + // Instance is probably on another host return await this.forwardRequestToController(message, request); } @@ -40,9 +40,9 @@ class InstanceConnection extends libLink.Link { async forwardEventToInstance(message, event) { let instanceId = message.data.instance_id; - let instanceConnection = this.slave.instanceConnections.get(instanceId); + let instanceConnection = this.host.instanceConnections.get(instanceId); if (!instanceConnection) { - // Instance is probably on another slave + // Instance is probably on another host await this.forwardEventToController(message, event); return; } @@ -52,15 +52,15 @@ class InstanceConnection extends libLink.Link { } async forwardEventToController(message, event) { - if (!this.slave.connector.hasSession) { + if (!this.host.connector.hasSession) { return; } - event.send(this.slave, message.data); + event.send(this.host, message.data); } async broadcastEventToInstance(message, event) { - for (let instanceConnection of this.slave.instanceConnections.values()) { + for (let instanceConnection of this.host.instanceConnections.values()) { // Do not broadcast back to the source if (instanceConnection === this) { continue; } if (event.plugin && !instanceConnection.plugins.has(event.plugin)) { continue; } @@ -76,7 +76,7 @@ class InstanceConnection extends libLink.Link { async instanceStatusChangedEventHandler(message, event) { this.status = message.data.status; if (this.status === "stopped") { - this.slave.instanceConnections.delete(this.instanceId); + this.host.instanceConnections.delete(this.instanceId); } this.forwardEventToController(message, event); } diff --git a/packages/lib/README.md b/packages/lib/README.md index 069ec951..f01338e8 100644 --- a/packages/lib/README.md +++ b/packages/lib/README.md @@ -1,5 +1,5 @@ # Common Library for Clusterio -This package contains functionality shared between controller, slave, ctl and/or plugins of Clusterio. +This package contains functionality shared between controller, host, ctl and/or plugins of Clusterio. See [the Clusterio repository](https://github.com/clusterio/clusterio) for more information on Clusterio. diff --git a/packages/lib/command.js b/packages/lib/command.js index f1ac5cd0..f66e70c7 100644 --- a/packages/lib/command.js +++ b/packages/lib/command.js @@ -135,35 +135,35 @@ class CommandTree { /** - * Resolve a string into a slave ID + * Resolve a string into a host ID * - * Resolves a string with either an slave name or an id into an integer with - * the slave ID. + * Resolves a string with either an host name or an id into an integer with + * the host ID. * - * @param {module:lib/link.Link} client - link to controller to query slave on. - * @param {string} slaveName - string with name or id of slave. - * @returns {Promise} slave ID. + * @param {module:lib/link.Link} client - link to controller to query host on. + * @param {string} hostName - string with name or id of host. + * @returns {Promise} host ID. * @static */ -async function resolveSlave(client, slaveName) { - let slaveId; - if (/^-?\d+$/.test(slaveName)) { - slaveId = parseInt(slaveName, 10); +async function resolveHost(client, hostName) { + let hostId; + if (/^-?\d+$/.test(hostName)) { + hostId = parseInt(hostName, 10); } else { - let response = await libLink.messages.listSlaves.send(client); - for (let slave of response.list) { - if (slave.name === slaveName) { - slaveId = slave.id; + let response = await libLink.messages.listHosts.send(client); + for (let host of response.list) { + if (host.name === hostName) { + hostId = host.id; break; } } - if (slaveId === undefined) { - throw new libErrors.CommandError(`No slave named ${slaveName}`); + if (hostId === undefined) { + throw new libErrors.CommandError(`No host named ${hostName}`); } } - return slaveId; + return hostId; } /** @@ -275,7 +275,7 @@ module.exports = { Command, CommandTree, - resolveSlave, + resolveHost, resolveInstance, resolveModPack, retrieveRole, diff --git a/packages/lib/config/definitions.js b/packages/lib/config/definitions.js index 70f30403..7eb683c5 100644 --- a/packages/lib/config/definitions.js +++ b/packages/lib/config/definitions.js @@ -10,7 +10,7 @@ const classes = require("./classes"); * @memberof module:lib/config */ class ControllerGroup extends classes.ConfigGroup { } -ControllerGroup.defaultAccess = ["controller", "slave", "control"]; +ControllerGroup.defaultAccess = ["controller", "host", "control"]; ControllerGroup.groupName = "controller"; ControllerGroup.define({ name: "name", @@ -110,7 +110,7 @@ ControllerGroup.define({ ControllerGroup.define({ name: "metrics_timeout", title: "Metrics Timeout", - description: "Timeout in seconds for metrics gathering from slaves.", + description: "Timeout in seconds for metrics gathering from hosts.", type: "number", initial_value: 8, }); @@ -148,95 +148,95 @@ ControllerConfig.registerGroup(ControllerGroup); /** - * Slave config group for {@link module:lib/config.SlaveConfig} + * Host config group for {@link module:lib/config.HostConfig} * @extends module:lib/config.ConfigGroup * @memberof module:lib/config */ -class SlaveGroup extends classes.ConfigGroup {} -SlaveGroup.defaultAccess = ["controller", "slave", "control"]; -SlaveGroup.groupName = "slave"; -SlaveGroup.define({ +class HostGroup extends classes.ConfigGroup {} +HostGroup.defaultAccess = ["controller", "host", "control"]; +HostGroup.groupName = "host"; +HostGroup.define({ name: "name", - description: "Name of the slave", + description: "Name of the host", type: "string", - initial_value: "New Slave", + initial_value: "New Host", }); -SlaveGroup.define({ +HostGroup.define({ name: "id", - description: "ID of the slave", + description: "ID of the host", type: "number", initial_value: () => Math.random() * 2**31 | 0, }); -SlaveGroup.define({ +HostGroup.define({ name: "factorio_directory", description: "Path to directory to look for factorio installs", type: "string", initial_value: "factorio", }); -SlaveGroup.define({ +HostGroup.define({ name: "mods_directory", title: "Mods Directory", description: "Path to directory where mods for instances are cached.", type: "string", initial_value: "mods", }); -SlaveGroup.define({ +HostGroup.define({ name: "mods_directory_is_shared", title: "Mods Directory is Shared", description: "True if the mods directory is shared with the controller.", type: "boolean", initial_value: true, }); -SlaveGroup.define({ +HostGroup.define({ name: "instances_directory", description: "Path to directory to store instances in.", restartRequired: true, type: "string", initial_value: "instances", }); -SlaveGroup.define({ +HostGroup.define({ name: "controller_url", description: "URL to connect to the controller at", restartRequired: true, type: "string", initial_value: "http://localhost:8080/", }); -SlaveGroup.define({ +HostGroup.define({ name: "controller_token", description: "Token to authenticate to controller with.", restartRequired: true, type: "string", initial_value: "enter token here", }); -SlaveGroup.define({ +HostGroup.define({ name: "tls_ca", description: "Path to Certificate Authority to validate TLS connection to controller against.", restartRequired: true, type: "string", optional: true, }); -SlaveGroup.define({ +HostGroup.define({ name: "public_address", - description: "Public facing address players should connect to in order to join instances on this slave", + description: "Public facing address players should connect to in order to join instances on this host", type: "string", initial_value: "localhost", }); -SlaveGroup.define({ +HostGroup.define({ name: "max_reconnect_delay", title: "Max Reconnect Delay", description: "Maximum delay to wait before attempting to reconnect WebSocket", type: "number", initial_value: 60, }); -SlaveGroup.finalize(); +HostGroup.finalize(); /** - * Slave Config class + * Host Config class * @extends module:lib/config.Config * @memberof module:lib/config */ -class SlaveConfig extends classes.Config { } -SlaveConfig.registerGroup(SlaveGroup); +class HostConfig extends classes.Config { } +HostConfig.registerGroup(HostGroup); /** @@ -245,7 +245,7 @@ SlaveConfig.registerGroup(SlaveGroup); * @memberof module:lib/config */ class InstanceGroup extends classes.ConfigGroup { } -InstanceGroup.defaultAccess = ["controller", "slave", "control"]; +InstanceGroup.defaultAccess = ["controller", "host", "control"]; InstanceGroup.groupName = "instance"; InstanceGroup.define({ name: "name", @@ -259,13 +259,13 @@ InstanceGroup.define({ initial_value: () => Math.random() * 2**31 | 0, }); InstanceGroup.define({ - name: "assigned_slave", + name: "assigned_host", type: "number", optional: true, }); InstanceGroup.define({ name: "auto_start", - description: "Automatically start this instance when the slave hosting it is started up", + description: "Automatically start this instance when the host hosting it is started up", type: "boolean", initial_value: false, }); @@ -277,7 +277,7 @@ InstanceGroup.finalize(); * @memberof module:lib/config */ class FactorioGroup extends classes.ConfigGroup { } -FactorioGroup.defaultAccess = ["controller", "slave", "control"]; +FactorioGroup.defaultAccess = ["controller", "host", "control"]; FactorioGroup.groupName = "factorio"; FactorioGroup.define({ name: "version", @@ -478,7 +478,7 @@ function registerPluginConfigGroups(pluginInfos) { } else { class ControllerConfigGroup extends classes.PluginConfigGroup { } - ControllerConfigGroup.defaultAccess = ["controller", "slave", "control"]; + ControllerConfigGroup.defaultAccess = ["controller", "host", "control"]; ControllerConfigGroup.groupName = pluginInfo.name; ControllerConfigGroup.finalize(); ControllerConfig.registerGroup(ControllerConfigGroup); @@ -491,7 +491,7 @@ function registerPluginConfigGroups(pluginInfos) { } else { class InstanceConfigGroup extends classes.PluginConfigGroup { } - InstanceConfigGroup.defaultAccess = ["controller", "slave", "control"]; + InstanceConfigGroup.defaultAccess = ["controller", "host", "control"]; InstanceConfigGroup.groupName = pluginInfo.name; InstanceConfigGroup.finalize(); InstanceConfig.registerGroup(InstanceConfigGroup); @@ -507,20 +507,20 @@ function registerPluginConfigGroups(pluginInfos) { */ function finalizeConfigs() { ControllerConfig.finalize(); - SlaveConfig.finalize(); + HostConfig.finalize(); InstanceConfig.finalize(); ControlConfig.finalize(); } module.exports = { ControllerGroup, - SlaveGroup, + HostGroup, InstanceGroup, FactorioGroup, ControlGroup, ControllerConfig, - SlaveConfig, + HostConfig, InstanceConfig, ControlConfig, diff --git a/packages/lib/factorio/export.js b/packages/lib/factorio/export.js index f30d33bf..b26be51c 100644 --- a/packages/lib/factorio/export.js +++ b/packages/lib/factorio/export.js @@ -34,8 +34,8 @@ async function generateExportMod(server) { clean: false, build: true, pack: true, - // XXX fix path when moving lib/factorio to slave - sourceDir: path.join(__dirname, "..", "..", "slave", "lua", "export"), + // XXX fix path when moving lib/factorio to host + sourceDir: path.join(__dirname, "..", "..", "host", "lua", "export"), outputDir: server.writePath("mods"), bumpPatch: false, factorioVersion: server.version.replace(/\.\d+$/, ""), diff --git a/packages/lib/link/messages.js b/packages/lib/link/messages.js index 0f421620..d4fbc7c5 100644 --- a/packages/lib/link/messages.js +++ b/packages/lib/link/messages.js @@ -278,7 +278,7 @@ class Request extends Message { let messages = {}; // Connection requests -let wsLinks = ["controller-control", "control-controller", "controller-slave", "slave-controller"]; +let wsLinks = ["controller-control", "control-controller", "controller-host", "host-controller"]; messages.prepareDisconnect = new Request({ type: "prepare_disconnect", links: wsLinks, @@ -287,7 +287,7 @@ messages.prepareDisconnect = new Request({ messages.prepareControllerDisconnect = new Request({ type: "prepare_controller_disconnect", - links: ["slave-instance"], + links: ["host-instance"], }); messages.ping = new Request({ @@ -335,7 +335,7 @@ messages.setControllerConfigProp = new Request({ }, }); -let slaveProperties = { +let hostProperties = { "agent": { type: "string" }, "version": { type: "string" }, "name": { type: "string" }, @@ -344,29 +344,29 @@ let slaveProperties = { "public_address": { type: ["null", "string"] }, }; -messages.listSlaves = new Request({ - type: "list_slaves", +messages.listHosts = new Request({ + type: "list_hosts", links: ["control-controller"], - permission: "core.slave.list", + permission: "core.host.list", responseProperties: { "list": { type: "array", items: { additionalProperties: false, required: ["agent", "version", "name", "id", "connected"], - properties: slaveProperties, + properties: hostProperties, }, }, }, }); -messages.setSlaveSubscriptions = new Request({ - type: "set_slave_subscriptions", +messages.setHostSubscriptions = new Request({ + type: "set_host_subscriptions", links: ["control-controller"], - permission: "core.slave.subscribe", + permission: "core.host.subscribe", requestProperties: { "all": { type: "boolean" }, - "slave_ids": { + "host_ids": { type: "array", items: { type: "integer" }, }, @@ -376,7 +376,7 @@ messages.setSlaveSubscriptions = new Request({ let instanceProperties = { "name": { type: "string" }, "id": { type: "integer" }, - "assigned_slave": { type: ["null", "integer"] }, + "assigned_host": { type: ["null", "integer"] }, "game_port": { type: ["null", "integer"] }, "status": { enum: [ "unknown", "unassigned", "stopped", "starting", "running", "stopping", @@ -403,7 +403,7 @@ messages.listInstances = new Request({ type: "array", items: { additionalProperties: false, - required: ["name", "id", "assigned_slave", "status"], + required: ["name", "id", "assigned_host", "status"], properties: instanceProperties, }, }, @@ -423,22 +423,22 @@ messages.setInstanceSubscriptions = new Request({ }, }); -messages.generateSlaveToken = new Request({ - type: "generate_slave_token", +messages.generateHostToken = new Request({ + type: "generate_host_token", links: ["control-controller"], - permission: "core.slave.generate_token", + permission: "core.host.generate_token", requestProperties: { - "slave_id": { type: ["integer", "null"] }, + "host_id": { type: ["integer", "null"] }, }, responseProperties: { "token": { type: "string" }, }, }); -messages.createSlaveConfig = new Request({ - type: "create_slave_config", +messages.createHostConfig = new Request({ + type: "create_host_config", links: ["control-controller"], - permission: "core.slave.create_config", + permission: "core.host.create_config", requestProperties: { "id": { type: ["integer", "null"] }, "name": { type: ["string", "null"] }, @@ -500,13 +500,13 @@ messages.assignInstanceCommand = new Request({ permission: "core.instance.assign", requestProperties: { "instance_id": { type: "integer" }, - "slave_id": { type: ["integer", "null"] }, + "host_id": { type: ["integer", "null"] }, }, }); messages.startInstance = new Request({ type: "start_instance", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.start", requestProperties: { "save": { type: ["string", "null"] }, @@ -533,7 +533,7 @@ let saveList = { messages.listSaves = new Request({ type: "list_saves", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.save.list", forwardTo: "instance", responseProperties: { @@ -543,7 +543,7 @@ messages.listSaves = new Request({ messages.createSave = new Request({ type: "create_save", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.save.create", forwardTo: "instance", requestProperties: { @@ -556,7 +556,7 @@ messages.createSave = new Request({ messages.renameSave = new Request({ type: "rename_save", - links: ["control-controller", "controller-slave"], + links: ["control-controller", "controller-host"], permission: "core.instance.save.rename", forwardTo: "instance", requestProperties: { @@ -567,7 +567,7 @@ messages.renameSave = new Request({ messages.copySave = new Request({ type: "copy_save", - links: ["control-controller", "controller-slave"], + links: ["control-controller", "controller-host"], permission: "core.instance.save.copy", forwardTo: "instance", requestProperties: { @@ -578,7 +578,7 @@ messages.copySave = new Request({ messages.deleteSave = new Request({ type: "delete_save", - links: ["control-controller", "controller-slave"], + links: ["control-controller", "controller-host"], permission: "core.instance.save.delete", forwardTo: "instance", requestProperties: { @@ -601,7 +601,7 @@ messages.downloadSave = new Request({ messages.transferSave = new Request({ type: "transfer_save", - links: ["control-controller", "controller-slave"], + links: ["control-controller", "controller-host"], permission: "core.instance.save.transfer", requestProperties: { "instance_id": { type: "integer" }, @@ -617,7 +617,7 @@ messages.transferSave = new Request({ messages.pullSave = new Request({ type: "pull_save", - links: ["controller-slave"], + links: ["controller-host"], requestProperties: { "instance_id": { type: "integer" }, "stream_id": { type: "string" }, @@ -630,7 +630,7 @@ messages.pullSave = new Request({ messages.pushSave = new Request({ type: "push_save", - links: ["controller-slave"], + links: ["controller-host"], requestProperties: { "instance_id": { type: "integer" }, "stream_id": { type: "string" }, @@ -653,7 +653,7 @@ messages.setSaveListSubscriptions = new Request({ messages.loadScenario = new Request({ type: "load_scenario", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.load_scenario", forwardTo: "instance", requestProperties: { @@ -666,42 +666,42 @@ messages.loadScenario = new Request({ messages.exportData = new Request({ type: "export_data", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.export_data", forwardTo: "instance", }); messages.extractPlayers = new Request({ type: "extract_players", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.extract_players", forwardTo: "instance", }); messages.stopInstance = new Request({ type: "stop_instance", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.stop", forwardTo: "instance", }); messages.killInstance = new Request({ type: "kill_instance", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.kill", forwardTo: "instance", }); messages.deleteInstance = new Request({ type: "delete_instance", - links: ["control-controller", "controller-slave"], + links: ["control-controller", "controller-host"], permission: "core.instance.delete", forwardTo: "instance", }); messages.sendRcon = new Request({ type: "send_rcon", - links: ["control-controller", "controller-slave", "slave-instance"], + links: ["control-controller", "controller-host", "host-instance"], permission: "core.instance.send_rcon", forwardTo: "instance", requestProperties: { @@ -714,7 +714,7 @@ messages.sendRcon = new Request({ messages.getModPack = new Request({ type: "get_mod_pack", - links: ["control-controller", "instance-slave", "slave-controller"], + links: ["control-controller", "instance-host", "host-controller"], permission: "core.mod_pack.get", forwardTo: "controller", requestProperties: { @@ -727,7 +727,7 @@ messages.getModPack = new Request({ messages.getDefaultModPack = new Request({ type: "get_default_mod_pack", - links: ["control-controller", "instance-slave", "slave-controller"], + links: ["control-controller", "instance-host", "host-controller"], permission: "core.mod_pack.get", forwardTo: "controller", responseProperties: { @@ -1107,7 +1107,7 @@ messages.setLogSubscriptions = new Request({ requestProperties: { "all": { type: "boolean" }, "controller": { type: "boolean" }, - "slave_ids": { + "host_ids": { type: "array", items: { type: "integer" }, }, @@ -1126,7 +1126,7 @@ messages.queryLog = new Request({ requestProperties: { "all": { type: "boolean" }, "controller": { type: "boolean" }, - "slave_ids": { + "host_ids": { type: "array", items: { type: "integer" }, }, @@ -1150,7 +1150,7 @@ messages.queryLog = new Request({ // Internal requests messages.updateInstances = new Request({ type: "update_instances", - links: ["slave-controller"], + links: ["host-controller"], requestProperties: { "instances": { type: "array", @@ -1171,7 +1171,7 @@ messages.updateInstances = new Request({ messages.assignInstance = new Request({ type: "assign_instance", - links: ["controller-slave"], + links: ["controller-host"], requestProperties: { "serialized_config": { type: "object" }, }, @@ -1180,13 +1180,13 @@ messages.assignInstance = new Request({ messages.unassignInstance = new Request({ type: "unassigne_instance", - links: ["controller-slave"], + links: ["controller-host"], forwardTo: "instance", }); messages.getMetrics = new Request({ type: "get_metrics", - links: ["controller-slave", "slave-instance"], + links: ["controller-host", "host-instance"], responseProperties: { "results": { type: "array" }, }, @@ -1221,8 +1221,8 @@ class Event extends Message { * Optional target to broadcast this event to. Only 'instance' is * currently supported. An event will only be broadcast towards * links that are downstream, so sending an event set to instance - * broadcast that's sent to a slave will only be broadcast to that - * slave's instances. + * broadcast that's sent to a host will only be broadcast to that + * host's instances. * @param {?Array} eventRequired - * List of properties required to be present in the event payload. * Defaults to all. @@ -1307,7 +1307,7 @@ class Event extends Message { if ( this.broadcastTo === "instance" && [ - "instance-slave", "slave-controller", "control-controller", "controller-slave", + "instance-host", "host-controller", "control-controller", "controller-host", ].includes(`${link.target}-${link.source}`) ) { if (!handler) { @@ -1387,7 +1387,7 @@ messages.accountUpdate = new Event({ messages.logMessage = new Event({ type: "log_message", - links: ["slave-controller", "controller-control"], + links: ["host-controller", "controller-control"], eventProperties: { "info": { type: "object", @@ -1400,16 +1400,16 @@ messages.logMessage = new Event({ }, }); -messages.slaveUpdate = new Event({ - type: "slave_update", +messages.hostUpdate = new Event({ + type: "host_update", links: ["controller-control"], - eventProperties: slaveProperties, + eventProperties: hostProperties, }); messages.instanceInitialized = new Event({ type: "instance_initialized", - links: ["instance-slave"], + links: ["instance-host"], eventProperties: { "instance_id": { type: "integer" }, "plugins": { @@ -1420,7 +1420,7 @@ messages.instanceInitialized = new Event({ }); messages.instanceStatusChanged = new Event({ type: "instance_status_changed", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], eventRequired: ["instance_id", "status"], eventProperties: { "instance_id": { type: "integer" }, @@ -1439,7 +1439,7 @@ messages.instanceUpdate = new Event({ messages.saveListUpdate = new Event({ type: "save_list_update", - links: ["instance-slave", "slave-controller", "controller-control"], + links: ["instance-host", "host-controller", "controller-control"], forwardTo: "controller", eventProperties: { "instance_id": { type: "integer" }, @@ -1472,7 +1472,7 @@ messages.userUpdate = new Event({ messages.controllerConnectionEvent = new Event({ type: "controller_connection_event", - links: ["slave-instance"], + links: ["host-instance"], eventProperties: { "event": { type: "string" }, }, @@ -1480,7 +1480,7 @@ messages.controllerConnectionEvent = new Event({ messages.syncUserLists = new Event({ type: "sync_user_lists", - links: ["controller-slave"], + links: ["controller-host"], eventProperties: { "adminlist": { type: "array", @@ -1503,7 +1503,7 @@ messages.syncUserLists = new Event({ messages.banlistUpdate = new Event({ type: "banlist_update", - links: ["controller-slave", "slave-instance"], + links: ["controller-host", "host-instance"], broadcastTo: "instance", eventProperties: { "name": { type: "string" }, @@ -1514,7 +1514,7 @@ messages.banlistUpdate = new Event({ messages.adminlistUpdate = new Event({ type: "adminlist_update", - links: ["controller-slave", "slave-instance"], + links: ["controller-host", "host-instance"], eventProperties: { "name": { type: "string" }, "admin": { type: "boolean" }, @@ -1524,7 +1524,7 @@ messages.adminlistUpdate = new Event({ messages.whitelistUpdate = new Event({ type: "whitelist_update", - links: ["controller-slave", "slave-instance"], + links: ["controller-host", "host-instance"], eventProperties: { "name": { type: "string" }, "whitelisted": { type: "boolean" }, @@ -1534,7 +1534,7 @@ messages.whitelistUpdate = new Event({ messages.playerEvent = new Event({ type: "player_event", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", eventRequired: ["instance_id", "type", "name"], eventProperties: { diff --git a/packages/lib/logging.js b/packages/lib/logging.js index 15e93efa..94135133 100644 --- a/packages/lib/logging.js +++ b/packages/lib/logging.js @@ -63,8 +63,8 @@ class WebConsoleFormat { transform(info, options) { let src = " "; - if (info.slave_id !== undefined) { - src += `s:${info.slave_name} - `; + if (info.host_id !== undefined) { + src += `s:${info.host_name} - `; } if (info.instance_id !== undefined) { src += `i:${info.instance_name}`; @@ -88,12 +88,12 @@ class WebConsoleFormat { * @property {string} [max_level] - * Maximum log level to include. Higher levels are more verbose. * @property {boolean} [all] - - * Include log entries from controller, all slaves and all instances. + * Include log entries from controller, all hosts and all instances. * @property {boolean} [controller] - * Include log entries from the controller. - * @property {Array} [slave_ids] - - * Include log entries for the given slaves and instances of those - * slaves by id. + * @property {Array} [host_ids] - + * Include log entries for the given hosts and instances of those + * hosts by id. * @property {Array} [instance_ids] - * Include log entries for the given instances by id. */ @@ -107,7 +107,7 @@ class WebConsoleFormat { * filter returning true for log entries that match it. * @static */ -function logFilter({ all, controller, slave_ids, instance_ids, max_level }) { +function logFilter({ all, controller, host_ids, instance_ids, max_level }) { return info => { // Note: reversed to filter out undefined levels if (max_level && !(levels[info.level] <= levels[max_level])) { @@ -117,14 +117,14 @@ function logFilter({ all, controller, slave_ids, instance_ids, max_level }) { if (all) { return true; } - if (controller && info.slave_id === undefined) { + if (controller && info.host_id === undefined) { return true; } if ( - slave_ids - && info.slave_id !== undefined + host_ids + && info.host_id !== undefined && info.instance_id === undefined - && slave_ids.includes(info.slave_id) + && host_ids.includes(info.host_id) ) { return true; } diff --git a/packages/lib/logging_utils.js b/packages/lib/logging_utils.js index 2417e13c..218abada 100644 --- a/packages/lib/logging_utils.js +++ b/packages/lib/logging_utils.js @@ -90,8 +90,8 @@ class TerminalFormat { if (info.instance_name) { src += `i:${info.instance_name} `; - } else if (info.slave_name) { - src += `s:${info.slave_name} `; + } else if (info.host_name) { + src += `s:${info.host_name} `; } if (info.plugin) { src += `${info.plugin}: `; @@ -158,7 +158,7 @@ class LogIndex { this.index.set(file, { levels: new Set(serializedEntry.levels), controller: serializedEntry.controller, - slave_ids: new Set(serializedEntry.slave_ids), + host_ids: new Set(serializedEntry.host_ids), instance_ids: new Set(serializedEntry.instance_ids), }); } @@ -174,7 +174,7 @@ class LogIndex { serialized.files[file] = { levels: [...entry.levels], controller: entry.controller, - slave_ids: [...entry.slave_ids], + host_ids: [...entry.host_ids], instance_ids: [...entry.instance_ids], }; } @@ -225,7 +225,7 @@ class LogIndex { let entry = { levels: new Set(), controller: false, - slave_ids: new Set(), + host_ids: new Set(), instance_ids: new Set(), }; for await (let line of lineStream) { @@ -240,10 +240,10 @@ class LogIndex { if (info.level) { entry.levels.add(info.level); } - if (info.slave_id === undefined) { + if (info.host_id === undefined) { entry.controller = true; } else if (info.instance_id === undefined) { - entry.slave_ids.add(info.slave_id); + entry.host_ids.add(info.host_id); } if (info.instance_id !== undefined) { entry.instance_ids.add(info.instance_id); @@ -279,7 +279,7 @@ class LogIndex { * @returns {boolean} * true if the file may contain entries included by the filter. */ - filterIncludesFile(file, { max_level, all, controller, instance_ids, slave_ids }) { + filterIncludesFile(file, { max_level, all, controller, instance_ids, host_ids }) { let entry = this.index.get(file); if (!entry) { return true; @@ -301,7 +301,7 @@ class LogIndex { if (controller && entry.controller) { return true; } - if (slave_ids && slave_ids.some(id => entry.slave_ids.has(id))) { + if (host_ids && host_ids.some(id => entry.host_ids.has(id))) { return true; } if (instance_ids && instance_ids.some(id => entry.instance_ids.has(id))) { @@ -321,12 +321,12 @@ class LogIndex { * @property {string} [max_level] - * Maximum log level to include. Higher levels are more verbose. * @property {boolean} [all] - - * Include log entries from controller, all slaves and all instances. + * Include log entries from controller, all hosts and all instances. * @property {boolean} [controller] - * Include log entries from the controller. - * @property {Array} [slave_ids] - - * Include log entries for the given slaves and instances of those - * slaves by id. + * @property {Array} [host_ids] - + * Include log entries for the given hosts and instances of those + * hosts by id. * @property {Array} [instance_ids] - * Include log entries for the given instances by id. */ diff --git a/packages/lib/plugin.js b/packages/lib/plugin.js index 0f0cf80b..364c0c92 100644 --- a/packages/lib/plugin.js +++ b/packages/lib/plugin.js @@ -19,7 +19,7 @@ const helpers = require("./helpers"); * Base class for instance plugins * * Instance plugins are subclasses of this class which get instantiated by - * the slave when it brings up an instance with the plugin enabled in the + * the host when it brings up an instance with the plugin enabled in the * config. To be discovered the class must be exported under the name * `InstancePlugin` in the module specified by the `instanceEntrypoint` in * the plugin's info.js file. @@ -31,7 +31,7 @@ const helpers = require("./helpers"); * @static */ class BaseInstancePlugin { - constructor(info, instance, slave) { + constructor(info, instance, host) { /** * The plugin's own info module */ @@ -39,19 +39,19 @@ class BaseInstancePlugin { /** * Instance the plugin started for - * @type {module:slave/src/Instance} + * @type {module:host/src/Instance} */ this.instance = instance; /** - * Slave running the instance + * Host running the instance * - * With the exepction of accessing the slave's config you should - * avoid ineracting with the slave object directly. + * With the exepction of accessing the host's config you should + * avoid ineracting with the host object directly. * - * @type {module:slave/src/Slave} + * @type {module:host/src/Host} */ - this.slave = slave; + this.host = host; /** * Logger for this plugin @@ -161,12 +161,12 @@ class BaseInstancePlugin { * * ##### drop * - * Invoked when a connection loss is detected between the slave and the + * Invoked when a connection loss is detected between the host and the * controller. Plugins should respond to this event by throtteling messages * it is sending to the controller to an absolute minimum. * * Messages sent over a dropped controller connection will get queued up in - * memory on the slave and sent all in one go when the connection is + * memory on the host and sent all in one go when the connection is * re-established again. * * ##### resume @@ -186,17 +186,17 @@ class BaseInstancePlugin { onControllerConnectionEvent(event) { } /** - * Called when the controller is preparing to disconnect from the slave + * Called when the controller is preparing to disconnect from the host * * Invoked when the controller has requested the disconnection from - * the slave. This typically happens when it is in the process of + * the host. This typically happens when it is in the process of * shutting down. * * Plugins must stop sending messages to the controller, or are forwarded * via the controller after the prepare disconnect has been handled. * - * @param {module:controller/src/SlaveConnection} connection - - * The connection to the slave preparing to disconnect. + * @param {module:controller/src/HostConnection} connection - + * The connection to the host preparing to disconnect. */ async onPrepareControllerDisconnect(connection) { } @@ -324,12 +324,12 @@ class BaseControllerPlugin { * Called when the status of an instance changes * * Invoked when the controller has changed the status of an instance - * or received notice from a slave that the status of an instance has + * or received notice from a host that the status of an instance has * changed. The possible statuses that can be notified about are: - * - `unassigned:`: Instance is no longer asssigned to a slave. - * - `unknown`: Slave assigned to instance is offline. + * - `unassigned:`: Instance is no longer asssigned to a host. + * - `unknown`: Host assigned to instance is offline. * - `stopped`: Instance is no longer running or was just assigned to a - * slave. + * host. * - `starting`: Instance is in the process of starting up. * - `running`: Instance startup completed and is now running. * - `stopping`: Instance is in the processing stopping. @@ -339,20 +339,20 @@ class BaseControllerPlugin { * - `deleted`: Instance was deleted. * * On controller startup all known instances gets the status `unknown` if - * they are assigned to a slave, when the slave then connects to the + * they are assigned to a host, when the host then connects to the * controller and informs of the current status of its instances this hook * is invoked for all those instances. You can detect this situation by - * checking if prev equals `unknown`. If the slave disconnects the + * checking if prev equals `unknown`. If the host disconnects the * instances will again get the `unknown` status. * * When instances are created on the controller they will notify of a status * change with prev set to null. While the status of new instances is * in most cases `unassigned` it's possible for the created instance to - * start with any state in some slave connection corner cases. + * start with any state in some host connection corner cases. * * Note that it's possible for status change notification to get lost in * the case of network outages if reconnect fails to re-establish the - * session between the controller and the slave. + * session between the controller and the host. * * @param {Object} instance - the instance that changed. * @param {?string} prev - the previous status of the instance. @@ -409,22 +409,22 @@ class BaseControllerPlugin { async onShutdown() { } /** - * Called when an event on a slave connection happens + * Called when an event on a host connection happens * * The event param may be one of connect, drop, resume and close and has * the following meaning: * * ##### connect * - * Invoked when a new connection to the slave has been established. + * Invoked when a new connection to the host has been established. * * ##### drop * * Invoked when a connection loss is detected between the controller and a - * slave. Plugins should respond to this event by throtteling messages - * it is sending to the given slave connection to an absolute minimum. + * host. Plugins should respond to this event by throtteling messages + * it is sending to the given host connection to an absolute minimum. * - * Messages sent over a dropped slave connection will get queued up in + * Messages sent over a dropped host connection will get queued up in * memory on the controller and sent all in one go when the connection is * re-established again. * @@ -435,13 +435,13 @@ class BaseControllerPlugin { * * ##### close * - * Invoked when the connection to the slave has been closed. + * Invoked when the connection to the host has been closed. * - * @param {module:controller/src/SlaveConnection} connection - + * @param {module:controller/src/HostConnection} connection - * The connection the event occured on. * @param {string} event - one of connect, drop, resume and close */ - onSlaveConnectionEvent(connection, event) { } + onHostConnectionEvent(connection, event) { } /** * Called when an avent on a control connection happens @@ -480,18 +480,18 @@ class BaseControllerPlugin { onControlConnectionEvent(connection, event) { } /** - * Called when a slave is preparing to disconnect from the controller + * Called when a host is preparing to disconnect from the controller * - * Invoked when a slave has requested the disconnection from the controller. + * Invoked when a host has requested the disconnection from the controller. * This typically happens when it is in the process of shutting down. * - * Plugins must stop sending messages to the slave in question after the + * Plugins must stop sending messages to the host in question after the * prepare disconnect has been handled. * - * @param {module:controller/src/SlaveConnection} connection - - * The connection to the slave preparing to disconnect. + * @param {module:controller/src/HostConnection} connection - + * The connection to the host preparing to disconnect. */ - async onPrepareSlaveDisconnect(connection) { } + async onPrepareHostDisconnect(connection) { } /** * Called when a mod pack is updated @@ -536,22 +536,22 @@ class BaseControllerPlugin { async onPlayerEvent(instance, event) { } /** - * Broadcast event to all connected slaves + * Broadcast event to all connected hosts * - * Sends the given event to all slaves connected to the controller. - * This does not include slaves that are in the process of closing the + * Sends the given event to all hosts connected to the controller. + * This does not include hosts that are in the process of closing the * connection, which typically happens when they are shutting down. * * @param {module:lib/link.Event} event - Event to send * @param {Object} data - Data ta pass with the event. */ - broadcastEventToSlaves(event, data={}) { - for (let slaveConnection of this.controller.wsServer.slaveConnections.values()) { + broadcastEventToHosts(event, data={}) { + for (let hostConnection of this.controller.wsServer.hostConnections.values()) { if ( - !slaveConnection.connector.closing - && (!event.plugin || slaveConnection.plugins.has(event.plugin)) + !hostConnection.connector.closing + && (!event.plugin || hostConnection.plugins.has(event.plugin)) ) { - event.send(slaveConnection, data); + event.send(hostConnection, data); } } } @@ -702,11 +702,11 @@ class BaseWebPlugin { * @type {object} * @property {React.ComponentType} ControllerPage - * Placed at the end of the controller page. - * @property {React.ComponentType} SlavesPage - - * Placed at the end of the slaves list page. - * @property {React.ComponentType} SlaveViewPage - - * Placed at the end of each slave page. Takes a `slave` param - * which is the slave the page is displayed for. + * @property {React.ComponentType} HostsPage - + * Placed at the end of the hosts list page. + * @property {React.ComponentType} HostViewPage - + * Placed at the end of each host page. Takes a `host` param + * which is the host the page is displayed for. * @property {React.ComponentType} InstancesPage - * Placed at the end of the instance list page. * @property {React.ComponentType} InstanceViewPage - diff --git a/packages/lib/schema.js b/packages/lib/schema.js index 17157876..572b7846 100644 --- a/packages/lib/schema.js +++ b/packages/lib/schema.js @@ -168,7 +168,7 @@ const clientHandshake = ajv.compile({ anyOf: [ { properties: { - "type": { const: "register_slave" }, + "type": { const: "register_host" }, "data": { additionalProperties: false, required: ["token", "agent", "version", "name", "id", "plugins"], diff --git a/packages/lib/shared_commands.js b/packages/lib/shared_commands.js index 3f2b95ad..d09ba5df 100644 --- a/packages/lib/shared_commands.js +++ b/packages/lib/shared_commands.js @@ -1,5 +1,5 @@ /** - * Implementation of commands shared between controller/slave/ctl. + * Implementation of commands shared between controller/host/ctl. * @module lib/shared_commands */ "use strict"; diff --git a/packages/lib/users.js b/packages/lib/users.js index a530f223..0d9f90d4 100644 --- a/packages/lib/users.js +++ b/packages/lib/users.js @@ -365,26 +365,26 @@ definePermission({ description: "Modify the controller config or entries of the controller config.", }); definePermission({ - name: "core.slave.list", - title: "List slaves", - description: "Get the full list of slaves in the cluster.", + name: "core.host.list", + title: "List hosts", + description: "Get the full list of hosts in the cluster.", grantByDefault: true, }); definePermission({ - name: "core.slave.subscribe", - title: "Subscribe to slave updates", - description: "Subscribe to be notified on updates on the details of slaves.", + name: "core.host.subscribe", + title: "Subscribe to host updates", + description: "Subscribe to be notified on updates on the details of hosts.", grantByDefault: true, }); definePermission({ - name: "core.slave.generate_token", - title: "Generate slave token", - description: "Generate tokens for slaves to connect to the cluster with.", + name: "core.host.generate_token", + title: "Generate host token", + description: "Generate tokens for hosts to connect to the cluster with.", }); definePermission({ - name: "core.slave.create_config", - title: "Create slave config", - description: "Create slave configs via the controller.", + name: "core.host.create_config", + title: "Create host config", + description: "Create host configs via the controller.", }); definePermission({ @@ -423,7 +423,7 @@ definePermission({ definePermission({ name: "core.instance.assign", title: "Assign instance", - description: "Assign or reassign instances to a slave.", + description: "Assign or reassign instances to a host.", }); definePermission({ name: "core.instance.save.list", diff --git a/packages/web_ui/src/components/AssignInstanceModal.jsx b/packages/web_ui/src/components/AssignInstanceModal.jsx index 8035a7eb..97f49576 100644 --- a/packages/web_ui/src/components/AssignInstanceModal.jsx +++ b/packages/web_ui/src/components/AssignInstanceModal.jsx @@ -5,14 +5,14 @@ import { libLink } from "@clusterio/lib"; import ControlContext from "./ControlContext"; import { notifyErrorHandler } from "../util/notify"; -import { useSlaveList } from "../model/slave"; +import { useHostList } from "../model/host"; const { Paragraph } = Typography; export default function AssignInstanceModal(props) { let [visible, setVisible] = useState(false); - let [slaveList] = useSlaveList(); + let [hostList] = useHostList(); let [applying, setApplying] = useState(false); let [form] = Form.useForm(); let control = useContext(ControlContext); @@ -22,20 +22,20 @@ export default function AssignInstanceModal(props) { } function handleAssign() { - let slaveId = form.getFieldValue("slave"); - if (slaveId === undefined) { + let hostId = form.getFieldValue("host"); + if (hostId === undefined) { setVisible(false); return; } - if (slaveId === "null") { - slaveId = null; + if (hostId === "null") { + hostId = null; } setApplying(true); libLink.messages.assignInstanceCommand.send(control, { instance_id: props.id, - slave_id: slaveId, + host_id: hostId, }).then(() => { setVisible(false); if (props.onFinish) { @@ -66,24 +66,24 @@ export default function AssignInstanceModal(props) { destroyOnClose > - Select a Slave to assign this instance to. Assignment - creates the necessary files on the slave to start up + Select a Host to assign this instance to. Assignment + creates the necessary files on the host to start up the instance. Note that reassigning an instance from - one slave to another will not move the server save over. + one host to another will not move the server save over. -
- + + diff --git a/packages/web_ui/src/components/SlaveViewPage.jsx b/packages/web_ui/src/components/HostViewPage.jsx similarity index 60% rename from packages/web_ui/src/components/SlaveViewPage.jsx rename to packages/web_ui/src/components/HostViewPage.jsx index 13e58a7f..23589ef0 100644 --- a/packages/web_ui/src/components/SlaveViewPage.jsx +++ b/packages/web_ui/src/components/HostViewPage.jsx @@ -6,61 +6,61 @@ import InstanceList from "./InstanceList"; import LogConsole from "./LogConsole"; import { useAccount } from "../model/account"; import { useInstanceList } from "../model/instance"; -import { useSlave } from "../model/slave"; +import { useHost } from "../model/host"; import PageLayout from "./PageLayout"; import PluginExtra from "./PluginExtra"; const { Title } = Typography; -export default function SlaveViewPage(props) { +export default function HostViewPage(props) { let params = useParams(); - let slaveId = Number(params.id); + let hostId = Number(params.id); let account = useAccount(); let [instanceList] = useInstanceList(); - let [slave] = useSlave(slaveId); + let [host] = useHost(hostId); - instanceList = instanceList.filter(instance => instance["assigned_slave"] === slaveId); + instanceList = instanceList.filter(instance => instance["assigned_host"] === hostId); - let nav = [{ name: "Slaves", path: "/slaves" }, { name: slave.name || slaveId }]; - if (slave.loading) { + let nav = [{ name: "Hosts", path: "/hosts" }, { name: host.name || hostId }]; + if (host.loading) { return ; } - if (slave.missing) { + if (host.missing) { return -

Slave with id {slaveId} was not found on the controller.

+

Host with id {hostId} was not found on the controller.

; } return - {slave["name"]} + {host["name"]} - - {slave["connected"] ? "Connected" : "Disconnected"} + + {host["connected"] ? "Connected" : "Disconnected"} - {slave["agent"]} - {slave["version"]} + {host["agent"]} + {host["version"]} {account.hasPermission("core.instance.list") && <> Instances - + } {account.hasPermission("core.log.follow") && <> Console - + } - + ; } diff --git a/packages/web_ui/src/components/SlavesPage.jsx b/packages/web_ui/src/components/HostsPage.jsx similarity index 74% rename from packages/web_ui/src/components/SlavesPage.jsx rename to packages/web_ui/src/components/HostsPage.jsx index ba2a6149..f941602a 100644 --- a/packages/web_ui/src/components/SlavesPage.jsx +++ b/packages/web_ui/src/components/HostsPage.jsx @@ -9,17 +9,17 @@ import { useAccount } from "../model/account"; import ControlContext from "./ControlContext"; import PageLayout from "./PageLayout"; import PluginExtra from "./PluginExtra"; -import { useSlaveList } from "../model/slave"; +import { useHostList } from "../model/host"; import notify, { notifyErrorHandler } from "../util/notify"; const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "base" }).compare; -function GenerateSlaveTokenButton(props) { +function GenerateHostTokenButton(props) { let control = useContext(ControlContext); let [visible, setVisible] = useState(false); let [token, setToken] = useState(null); - let [slaveId, setSlaveId] = useState(null); + let [hostId, setHostId] = useState(null); let [form] = Form.useForm(); let [pluginList, setPluginList] = useState([]); useEffect(() => { @@ -37,18 +37,18 @@ function GenerateSlaveTokenButton(props) { async function generateToken() { let id; let values = form.getFieldsValue(); - if (values.slaveId) { - id = Number.parseInt(values.slaveId, 10); + if (values.hostId) { + id = Number.parseInt(values.hostId, 10); if (Number.isNaN(id)) { - form.setFields([{ name: "slaveId", errors: ["Must be an integer"] }]); + form.setFields([{ name: "hostId", errors: ["Must be an integer"] }]); return; } - form.setFields([{ name: "slaveId", errors: [] }]); + form.setFields([{ name: "hostId", errors: [] }]); } - let result = await libLink.messages.generateSlaveToken.send(control, { slave_id: id || null }); + let result = await libLink.messages.generateHostToken.send(control, { host_id: id || null }); setToken(result.token); - setSlaveId(id); + setHostId(id); } // Generate a new random @@ -65,7 +65,7 @@ function GenerateSlaveTokenButton(props) { onClick={() => { setVisible(true); }} >Generate Token { @@ -76,7 +76,7 @@ function GenerateSlaveTokenButton(props) { width="700px" > - + { generateToken().catch(notifyErrorHandler("Error generating token")); }} /> @@ -84,7 +84,7 @@ function GenerateSlaveTokenButton(props) { {token !== null && <> - Slave auth token: + Host auth token:
- You can set the token on an existing slave with the following command: + You can set the token on an existing host with the following command:
-

npx clusterioslave config set slave.controller_token <token>

-

npx clusterioslave config set slave.id <slaveId>

+

npx clusteriohost config set host.controller_token <token>

+

npx clusteriohost config set host.id <hostId>

- Example slave setup commands: + Example host setup commands:

> mkdir clusterio

> cd clusterio

> npm init "@clusterio" -- --controller-token {token} - --mode "slave" + --mode "host" --download-headless --controller-url {document.location.origin}/ - --slave-name "Slave {slaveId || "?"}" + --host-name "Host {hostId || "?"}" --public-address localhost {pluginString.length ? "--plugins" : ""} {pluginString}

-

> ./run-slave

+

> ./run-host

} @@ -175,16 +175,16 @@ function CopyButton({ text, message }) { } -export default function SlavesPage() { +export default function HostsPage() { let account = useAccount(); let history = useHistory(); - let [slaveList] = useSlaveList(); + let [hostList] = useHostList(); - return + return } + title="Hosts" + extra={account.hasPermission("core.host.generate_token") && } /> - {slave["connected"] ? "Connected" : "Disconnected"} + {host["connected"] ? "Connected" : "Disconnected"} , sorter: (a, b) => a["connected"] - b["connected"], }, ]} - dataSource={slaveList} - rowKey={slave => slave["id"]} + dataSource={hostList} + rowKey={host => host["id"]} pagination={false} onRow={(record, rowIndex) => ({ onClick: event => { - history.push(`/slaves/${record.id}/view`); + history.push(`/hosts/${record.id}/view`); }, })} /> - + ; }; diff --git a/packages/web_ui/src/components/InstanceList.jsx b/packages/web_ui/src/components/InstanceList.jsx index cdd28ddd..4f39d4ad 100644 --- a/packages/web_ui/src/components/InstanceList.jsx +++ b/packages/web_ui/src/components/InstanceList.jsx @@ -4,7 +4,7 @@ import { message, Button, Space, Table } from "antd"; import CopyOutlined from "@ant-design/icons/CopyOutlined"; import { useAccount } from "../model/account"; -import { useSlaveList } from "../model/slave"; +import { useHostList } from "../model/host"; import InstanceStatusTag from "./InstanceStatusTag"; import StartStopInstanceButton from "./StartStopInstanceButton"; @@ -13,26 +13,26 @@ const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "ba export default function InstanceList(props) { let account = useAccount(); let history = useHistory(); - let [slaveList] = useSlaveList(); + let [hostList] = useHostList(); - function slaveName(slaveId) { - if (slaveId === null) { + function hostName(hostId) { + if (hostId === null) { return ""; } - let slave = slaveList.find(s => s.id === slaveId); - if (slave) { - return slave.name; + let host = hostList.find(s => s.id === hostId); + if (host) { + return host.name; } - return String(slaveId); + return String(hostId); } function instancePublicAddress(instance) { - let slave = slaveList.find(s => s.id === instance.assigned_slave); - if (slave && slave.public_address) { + let host = hostList.find(s => s.id === instance.assigned_host); + if (host && host.public_address) { if (instance.game_port) { - return `${slave.public_address}:${instance.game_port}`; + return `${host.public_address}:${instance.game_port}`; } - return slave.public_address; + return host.public_address; } return null; } @@ -45,10 +45,10 @@ export default function InstanceList(props) { sorter: (a, b) => strcmp(a["name"], b["name"]), }, { - title: "Assigned Slave", - key: "assigned_slave", - render: instance => slaveName(instance["assigned_slave"]), - sorter: (a, b) => strcmp(slaveName(a["assigned_slave"]), slaveName(b["assigned_slave"])), + title: "Assigned Host", + key: "assigned_host", + render: instance => hostName(instance["assigned_host"]), + sorter: (a, b) => strcmp(hostName(a["assigned_host"]), hostName(b["assigned_host"])), responsive: ["sm"], }, { @@ -69,7 +69,7 @@ export default function InstanceList(props) { /> : ""; }, - sorter: (a, b) => strcmp(slavePublicAddress(a["assigned_slave"]), slavePublicAddress(b["assigned_slave"])), + sorter: (a, b) => strcmp(hostPublicAddress(a["assigned_host"]), hostPublicAddress(b["assigned_host"])), responsive: ["lg"], }, { @@ -90,7 +90,7 @@ export default function InstanceList(props) { }] : []), ]; - if (props.hideAssignedSlave) { + if (props.hideAssignedHost) { columns.splice(1, 1); } diff --git a/packages/web_ui/src/components/InstanceViewPage.jsx b/packages/web_ui/src/components/InstanceViewPage.jsx index 78e7b677..98c970a2 100644 --- a/packages/web_ui/src/components/InstanceViewPage.jsx +++ b/packages/web_ui/src/components/InstanceViewPage.jsx @@ -19,7 +19,7 @@ import LoadScenarioModal from "./LoadScenarioModal"; import SavesList from "./SavesList"; import { notifyErrorHandler } from "../util/notify"; import { useInstance } from "../model/instance"; -import { useSlave } from "../model/slave"; +import { useHost } from "../model/host"; import InstanceStatusTag from "./InstanceStatusTag"; const { Title } = Typography; @@ -28,20 +28,20 @@ const { Title } = Typography; function InstanceDescription(props) { let account = useAccount(); - const { slave, instance } = props; - let assigned = instance["assigned_slave"] !== null; + const { host, instance } = props; + let assigned = instance["assigned_host"] !== null; return - + {!assigned ? Unassigned - : slave["name"] || instance["assigned_slave"] + : host["name"] || instance["assigned_host"] } {account.hasPermission("core.instance.assign") && - + { account.hasAllPermission("core.instance.save.list", "core.instance.save.list_subscribe") diff --git a/packages/web_ui/src/components/LogConsole.jsx b/packages/web_ui/src/components/LogConsole.jsx index fdb1278e..a7adffd2 100644 --- a/packages/web_ui/src/components/LogConsole.jsx +++ b/packages/web_ui/src/components/LogConsole.jsx @@ -60,7 +60,7 @@ export default function LogConsole(props) { let logFilter = { all: props.all || false, controller: props.controller || false, - slave_ids: props.slaves || [], + host_ids: props.hosts || [], instance_ids: props.instances || [], }; @@ -94,7 +94,7 @@ export default function LogConsole(props) { return () => { control.offLog(logFilter, logHandler); }; - }, [props.all, props.controller, (props.slaves || []).join(), (props.instances || []).join()]); + }, [props.all, props.controller, (props.hosts || []).join(), (props.instances || []).join()]); return <> diff --git a/packages/web_ui/src/components/SavesList.jsx b/packages/web_ui/src/components/SavesList.jsx index 686c567c..8f52afb2 100644 --- a/packages/web_ui/src/components/SavesList.jsx +++ b/packages/web_ui/src/components/SavesList.jsx @@ -186,7 +186,7 @@ export default function SavesList(props) { let [starting, setStarting] = useState(false); let [uploadingFiles, setUploadingFiles] = useState([]); - let slaveOffline = ["unassigned", "unknown"].includes(props.instance.status); + let hostOffline = ["unassigned", "unknown"].includes(props.instance.status); const saveTable =
Load save} {account.hasPermission("core.instance.save.rename") && } {account.hasPermission("core.instance.save.copy") && } {account.hasPermission("core.instance.save.download") && } {account.hasPermission("core.instance.save.transfer") && } {account.hasPermission("core.instance.save.delete") && - + } , }} @@ -309,7 +309,7 @@ export default function SavesList(props) { } let uploadProps = { - disabled: slaveOffline, + disabled: hostOffline, name: "file", accept: ".zip", headers: { @@ -326,7 +326,7 @@ export default function SavesList(props) { return
{account.hasPermission("core.instance.save.upload") && - + } {account.hasPermission("core.instance.save.create") && } } /> diff --git a/packages/web_ui/src/index.jsx b/packages/web_ui/src/index.jsx index f1fa8ffd..70bdc2e0 100644 --- a/packages/web_ui/src/index.jsx +++ b/packages/web_ui/src/index.jsx @@ -2,7 +2,7 @@ export { default as bootstrap } from "./bootstrap.jsx"; export { default as notify, notifyErrorHandler } from "./util/notify.jsx"; export * from "./model/instance.jsx"; -export * from "./model/slave.jsx"; +export * from "./model/host.jsx"; export * from "./model/locale.jsx"; export * from "./model/item_metadata.jsx"; export * from "./model/account.jsx"; diff --git a/packages/web_ui/src/model/host.jsx b/packages/web_ui/src/model/host.jsx new file mode 100644 index 00000000..763da37a --- /dev/null +++ b/packages/web_ui/src/model/host.jsx @@ -0,0 +1,77 @@ +import { useEffect, useContext, useState } from "react"; +import ControlContext from "../components/ControlContext"; + +import { libLink } from "@clusterio/lib"; + + +export function useHost(id) { + let control = useContext(ControlContext); + let [host, setHost] = useState({ loading: true }); + + function updateHost() { + // XXX optimize by requesting only the host in question + libLink.messages.listHosts.send(control).then(result => { + let match = result.list.find(i => i.id === id); + if (!match) { + setHost({ missing: true }); + } else { + setHost({ ...match, present: true }); + } + }); + } + + useEffect(() => { + if (!Number.isInteger(id)) { + setHost({ missing: true }); + return undefined; + } + updateHost(); + + function updateHandler(newHost) { + setHost({ ...newHost, present: true }); + } + + control.onHostUpdate(id, updateHandler); + return () => { + control.offHostUpdate(id, updateHandler); + }; + }, [id]); + + return [host, updateHost]; +} + +export function useHostList() { + let control = useContext(ControlContext); + let [hostList, setHostList] = useState([]); + + function updateHostList() { + libLink.messages.listHosts.send(control).then(result => { + setHostList(result.list); + }); + } + + useEffect(() => { + updateHostList(); + + function updateHandler(newHost) { + setHostList(oldList => { + let newList = oldList.concat(); + let index = newList.findIndex(s => s.id === newHost.id); + if (index !== -1) { + newList[index] = newHost; + } else { + newList.push(newHost); + } + return newList; + }); + } + + control.onHostUpdate(null, updateHandler); + return () => { + control.offHostUpdate(null, updateHandler); + }; + }, []); + + + return [hostList]; +} diff --git a/packages/web_ui/src/model/slave.jsx b/packages/web_ui/src/model/slave.jsx deleted file mode 100644 index 58a366fa..00000000 --- a/packages/web_ui/src/model/slave.jsx +++ /dev/null @@ -1,77 +0,0 @@ -import { useEffect, useContext, useState } from "react"; -import ControlContext from "../components/ControlContext"; - -import { libLink } from "@clusterio/lib"; - - -export function useSlave(id) { - let control = useContext(ControlContext); - let [slave, setSlave] = useState({ loading: true }); - - function updateSlave() { - // XXX optimize by requesting only the slave in question - libLink.messages.listSlaves.send(control).then(result => { - let match = result.list.find(i => i.id === id); - if (!match) { - setSlave({ missing: true }); - } else { - setSlave({ ...match, present: true }); - } - }); - } - - useEffect(() => { - if (!Number.isInteger(id)) { - setSlave({ missing: true }); - return undefined; - } - updateSlave(); - - function updateHandler(newSlave) { - setSlave({ ...newSlave, present: true }); - } - - control.onSlaveUpdate(id, updateHandler); - return () => { - control.offSlaveUpdate(id, updateHandler); - }; - }, [id]); - - return [slave, updateSlave]; -} - -export function useSlaveList() { - let control = useContext(ControlContext); - let [slaveList, setSlaveList] = useState([]); - - function updateSlaveList() { - libLink.messages.listSlaves.send(control).then(result => { - setSlaveList(result.list); - }); - } - - useEffect(() => { - updateSlaveList(); - - function updateHandler(newSlave) { - setSlaveList(oldList => { - let newList = oldList.concat(); - let index = newList.findIndex(s => s.id === newSlave.id); - if (index !== -1) { - newList[index] = newSlave; - } else { - newList.push(newSlave); - } - return newList; - }); - } - - control.onSlaveUpdate(null, updateHandler); - return () => { - control.offSlaveUpdate(null, updateHandler); - }; - }, []); - - - return [slaveList]; -} diff --git a/packages/web_ui/src/pages.jsx b/packages/web_ui/src/pages.jsx index b677c248..46eb9489 100644 --- a/packages/web_ui/src/pages.jsx +++ b/packages/web_ui/src/pages.jsx @@ -1,8 +1,8 @@ import React from "react"; import ControllerPage from "./components/ControllerPage"; -import SlavesPage from "./components/SlavesPage"; -import SlaveViewPage from "./components/SlaveViewPage"; +import HostsPage from "./components/HostsPage"; +import HostViewPage from "./components/HostViewPage"; import InstancesPage from "./components/InstancesPage"; import InstanceViewPage from "./components/InstanceViewPage"; import ModPackViewPage from "./components/ModPackViewPage"; @@ -22,15 +22,15 @@ export const pages = [ content: , }, { - path: "/slaves", - sidebarName: "Slaves", - permission: "core.slave.list", - content: , + path: "/hosts", + sidebarName: "Hosts", + permission: "core.host.list", + content: , }, { - path: "/slaves/:id/view", - sidebarPath: "/slaves", - content: , + path: "/hosts/:id/view", + sidebarPath: "/hosts", + content: , }, { path: "/instances", diff --git a/packages/web_ui/src/util/websocket.jsx b/packages/web_ui/src/util/websocket.jsx index f388c8e0..3d1df0cf 100644 --- a/packages/web_ui/src/util/websocket.jsx +++ b/packages/web_ui/src/util/websocket.jsx @@ -67,7 +67,7 @@ export class Control extends libLink.Link { this.accountRoles = null; this.accountUpdateHandlers = []; - this.slaveUpdateHandlers = new Map(); + this.hostUpdateHandlers = new Map(); this.instanceUpdateHandlers = new Map(); this.saveListUpdateHandlers = new Map(); this.modPackUpdateHandlers = new Map(); @@ -79,8 +79,8 @@ export class Control extends libLink.Link { this.accountName = data.account.name; this.accountRoles = data.account.roles; this.emitAccountUpdate(); - this.updateSlaveSubscriptions().catch(err => logger.error( - `Unexpected error updating slave subscriptions:\n${err.stack}` + this.updateHostSubscriptions().catch(err => logger.error( + `Unexpected error updating host subscriptions:\n${err.stack}` )); this.updateInstanceSubscriptions().catch(err => logger.error( `Unexpected error updating instance subscriptions:\n${err.stack}` @@ -143,60 +143,60 @@ export class Control extends libLink.Link { this.accountUpdateHandlers.splice(index, 1); } - async slaveUpdateEventHandler(message) { + async hostUpdateEventHandler(message) { let handlers = [].concat( - this.slaveUpdateHandlers.get(null) || [], - this.slaveUpdateHandlers.get(message.data.id) || [], + this.hostUpdateHandlers.get(null) || [], + this.hostUpdateHandlers.get(message.data.id) || [], ); for (let handler of handlers) { handler(message.data); } } - async onSlaveUpdate(id, handler) { + async onHostUpdate(id, handler) { if (id !== null && !Number.isInteger(id)) { - throw new Error("Invalid slave id"); + throw new Error("Invalid host id"); } - let handlers = this.slaveUpdateHandlers.get(id); + let handlers = this.hostUpdateHandlers.get(id); if (!handlers) { handlers = []; - this.slaveUpdateHandlers.set(id, handlers); + this.hostUpdateHandlers.set(id, handlers); } handlers.push(handler); if (handlers.length === 1) { - await this.updateSlaveSubscriptions(); + await this.updateHostSubscriptions(); } } - async offSlaveUpdate(id, handler) { - let handlers = this.slaveUpdateHandlers.get(id); + async offHostUpdate(id, handler) { + let handlers = this.hostUpdateHandlers.get(id); if (!handlers || !handlers.length) { - throw new Error(`No handlers for slave ${id} exists`); + throw new Error(`No handlers for host ${id} exists`); } let index = handlers.lastIndexOf(handler); if (index === -1) { - throw new Error(`Given handler is not registered for slave ${id}`); + throw new Error(`Given handler is not registered for host ${id}`); } handlers.splice(index, 1); if (!handlers.length) { - this.slaveUpdateHandlers.delete(id); - await this.updateSlaveSubscriptions(); + this.hostUpdateHandlers.delete(id); + await this.updateHostSubscriptions(); } } - async updateSlaveSubscriptions() { + async updateHostSubscriptions() { if (!this.connector.connected) { return; } - await libLink.messages.setSlaveSubscriptions.send(this, { - all: this.slaveUpdateHandlers.has(null), - slave_ids: [...this.slaveUpdateHandlers.keys()].filter(e => e !== null), + await libLink.messages.setHostSubscriptions.send(this, { + all: this.hostUpdateHandlers.has(null), + host_ids: [...this.hostUpdateHandlers.keys()].filter(e => e !== null), }); } @@ -536,16 +536,16 @@ export class Control extends libLink.Link { let combinedFilter = { all: false, controller: false, - slave_ids: [], + host_ids: [], instance_ids: [], }; for (let filter of this.logHandlers.keys()) { if (filter.all) { combinedFilter.all = true; } if (filter.controller) { combinedFilter.controller = true; } - for (let slaveId of filter.slave_ids || []) { - if (!combinedFilter.slave_ids.includes(slaveId)) { - combinedFilter.slave_ids.push(slaveId); + for (let hostId of filter.host_ids || []) { + if (!combinedFilter.host_ids.includes(hostId)) { + combinedFilter.host_ids.push(hostId); } } for (let instanceId of filter.instance_ids || []) { diff --git a/plugins/global_chat/README.md b/plugins/global_chat/README.md index 8b5e1882..c7341a1b 100644 --- a/plugins/global_chat/README.md +++ b/plugins/global_chat/README.md @@ -10,4 +10,4 @@ Run the following commands in the folder Clusterio is installed to: npm install @clusterio/plugin-global_chat npx clusteriocontroller plugin add @clusterio/plugin-global_chat -Substitute clusteriocontroller with clusterioslave or clusterioctl if this a dedicate slave or ctl installation respectively. +Substitute clusteriocontroller with clusteriohost or clusterioctl if this a dedicate host or ctl installation respectively. diff --git a/plugins/global_chat/info.js b/plugins/global_chat/info.js index b06816fa..0e2c0abd 100644 --- a/plugins/global_chat/info.js +++ b/plugins/global_chat/info.js @@ -11,7 +11,7 @@ module.exports = { messages: { chat: new libLink.Event({ type: "global_chat:chat", - links: ["instance-slave", "slave-controller", "controller-slave", "slave-instance", "control-controller"], + links: ["instance-host", "host-controller", "controller-host", "host-instance", "control-controller"], forwardTo: "controller", broadcastTo: "instance", eventProperties: { diff --git a/plugins/global_chat/instance.js b/plugins/global_chat/instance.js index cdf8ac71..3e7f8475 100644 --- a/plugins/global_chat/instance.js +++ b/plugins/global_chat/instance.js @@ -45,7 +45,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { async onOutput(output) { if (output.type === "action" && output.action === "CHAT") { - if (this.slave.connector.connected) { + if (this.host.connector.connected) { this.sendChat(output.message); } else { this.messageQueue.push(output.message); diff --git a/plugins/global_chat/test/plugin.js b/plugins/global_chat/test/plugin.js index f371d360..2be7b33c 100644 --- a/plugins/global_chat/test/plugin.js +++ b/plugins/global_chat/test/plugin.js @@ -24,7 +24,7 @@ describe("global_chat plugin", function() { let instancePlugin; before(async function() { - instancePlugin = new instance.InstancePlugin(info, new mock.MockInstance(), new mock.MockSlave()); + instancePlugin = new instance.InstancePlugin(info, new mock.MockInstance(), new mock.MockHost()); await instancePlugin.init(); }); diff --git a/plugins/inventory_sync/README.md b/plugins/inventory_sync/README.md index 9fa59bb1..c39a8283 100644 --- a/plugins/inventory_sync/README.md +++ b/plugins/inventory_sync/README.md @@ -15,7 +15,7 @@ Run the following commands in the folder Clusterio is installed to: npm install @clusterio/plugin-inventory_sync npx clusteriocontroller plugin add @clusterio/plugin-inventory_sync -Substitute clusteriocontroller with clusterioslave or clusterioctl if this a dedicated slave or ctl installation respectively. +Substitute clusteriocontroller with clusteriohost or clusterioctl if this a dedicated host or ctl installation respectively. ## Method of operation diff --git a/plugins/inventory_sync/info.js b/plugins/inventory_sync/info.js index bdc1bfc3..2c8e4711 100644 --- a/plugins/inventory_sync/info.js +++ b/plugins/inventory_sync/info.js @@ -2,7 +2,7 @@ const { libConfig, libLink, libUsers } = require("@clusterio/lib"); class ControllerConfigGroup extends libConfig.PluginConfigGroup { } -ControllerConfigGroup.defaultAccess = ["controller", "slave", "control"]; +ControllerConfigGroup.defaultAccess = ["controller", "host", "control"]; ControllerConfigGroup.groupName = "inventory_sync"; ControllerConfigGroup.define({ name: "autosave_interval", @@ -22,7 +22,7 @@ ControllerConfigGroup.define({ ControllerConfigGroup.finalize(); class InstanceConfigGroup extends libConfig.PluginConfigGroup { } -InstanceConfigGroup.defaultAccess = ["controller", "slave", "control"]; +InstanceConfigGroup.defaultAccess = ["controller", "host", "control"]; InstanceConfigGroup.groupName = "inventory_sync"; InstanceConfigGroup.define({ name: "rcon_chunk_size", @@ -57,7 +57,7 @@ module.exports = { messages: { acquire: new libLink.Request({ type: "inventory_sync:acquire", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", requestProperties: { "instance_id": { type: "integer" }, @@ -73,7 +73,7 @@ module.exports = { }), release: new libLink.Request({ type: "inventory_sync:release", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", requestProperties: { "instance_id": { type: "integer" }, @@ -82,7 +82,7 @@ module.exports = { }), upload: new libLink.Request({ type: "inventory_sync:upload", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", requestProperties: { "instance_id": { type: "integer" }, @@ -92,7 +92,7 @@ module.exports = { }), download: new libLink.Request({ type: "inventory_sync:download", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", requestProperties: { "instance_id": { type: "integer" }, diff --git a/plugins/inventory_sync/instance.js b/plugins/inventory_sync/instance.js index e35a0b94..67bc3169 100644 --- a/plugins/inventory_sync/instance.js +++ b/plugins/inventory_sync/instance.js @@ -41,7 +41,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { this.disconnecting = false; (async () => { for (let player_name of this.playersToRelease) { - if (!this.slave.connector.connected || this.disconnecting) { + if (!this.host.connector.connected || this.disconnecting) { return; } this.playersToRelease.delete(player); @@ -63,7 +63,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { message: "Controller is temporarily unavailable", }; - if (this.slave.connector.connected && !this.disconnecting) { + if (this.host.connector.connected && !this.disconnecting) { try { response = { player_name: request.player_name, @@ -85,7 +85,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { } async handleRelease(request) { - if (!this.slave.connector.connected) { + if (!this.host.connector.connected) { this.playersToRelease.set(request.player_name); } @@ -104,7 +104,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { } async handleUpload(player_data) { - if (!this.slave.connector.connected || this.disconnecting) { + if (!this.host.connector.connected || this.disconnecting) { return; } diff --git a/plugins/player_auth/README.md b/plugins/player_auth/README.md index 4d620613..c95e4866 100644 --- a/plugins/player_auth/README.md +++ b/plugins/player_auth/README.md @@ -12,7 +12,7 @@ Run the following commands in the folder Clusterio is installed to: npm install @clusterio/plugin-player_auth npx clusteriocontroller plugin add @clusterio/plugin-player_auth -Substitute clusteriocontroller with clusterioslave or clusterioctl if this a dedicate slave or ctl installation respectively. +Substitute clusteriocontroller with clusteriohost or clusterioctl if this a dedicate host or ctl installation respectively. ## Controller Configuration diff --git a/plugins/player_auth/info.js b/plugins/player_auth/info.js index 08667ebb..080e6703 100644 --- a/plugins/player_auth/info.js +++ b/plugins/player_auth/info.js @@ -3,7 +3,7 @@ let { libConfig, libLink } = require("@clusterio/lib"); class ControllerConfigGroup extends libConfig.PluginConfigGroup {} -ControllerConfigGroup.defaultAccess = ["controller", "slave", "control"]; +ControllerConfigGroup.defaultAccess = ["controller", "host", "control"]; ControllerConfigGroup.groupName = "player_auth"; ControllerConfigGroup.define({ name: "code_length", @@ -33,7 +33,7 @@ module.exports = { messages: { fetchPlayerCode: new libLink.Request({ type: "player_auth:fetch_player_code", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", requestProperties: { "player": { type: "string" }, @@ -45,7 +45,7 @@ module.exports = { }), setVerifyCode: new libLink.Request({ type: "player_auth:set_verify_code", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", requestProperties: { "player": { type: "string" }, diff --git a/plugins/player_auth/instance.js b/plugins/player_auth/instance.js index 470d086f..bc98aad8 100644 --- a/plugins/player_auth/instance.js +++ b/plugins/player_auth/instance.js @@ -18,7 +18,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { async handleEvent(event) { if (event.type === "open_dialog") { - if (!this.slave.connector.connected) { + if (!this.host.connector.connected) { await this.sendRcon(`/web-login error ${event.player} login is temporarily unavailable`); return; } diff --git a/plugins/player_auth/test/plugin.js b/plugins/player_auth/test/plugin.js index c01b084c..b3174674 100644 --- a/plugins/player_auth/test/plugin.js +++ b/plugins/player_auth/test/plugin.js @@ -363,10 +363,10 @@ describe("player_auth", function() { describe("open_dialog", async function() { it("should call /web-login error if not connected to controller", async function() { instancePlugin.instance.server.reset(); - instancePlugin.slave.connector.connected = false; + instancePlugin.host.connector.connected = false; await instancePlugin.handleEvent({ type: "open_dialog", player: "test" }); let command = instancePlugin.instance.server.rconCommands[0]; - instancePlugin.slave.connector.connected = true; + instancePlugin.host.connector.connected = true; assert.equal(command, "/web-login error test login is temporarily unavailable"); }); it("should call /web-login error after error from the controller", async function() { diff --git a/plugins/research_sync/README.md b/plugins/research_sync/README.md index bde2f7cc..46315762 100644 --- a/plugins/research_sync/README.md +++ b/plugins/research_sync/README.md @@ -10,4 +10,4 @@ Run the following commands in the folder Clusterio is installed to: npm install @clusterio/plugin-research_sync npx clusteriocontroller plugin add @clusterio/plugin-research_sync -Substitute clusteriocontroller with clusterioslave or clusterioctl if this a dedicate slave or ctl installation respectively. +Substitute clusteriocontroller with clusteriohost or clusterioctl if this a dedicate host or ctl installation respectively. diff --git a/plugins/research_sync/controller.js b/plugins/research_sync/controller.js index 2687634e..df489d67 100644 --- a/plugins/research_sync/controller.js +++ b/plugins/research_sync/controller.js @@ -59,7 +59,7 @@ class ControllerPlugin extends libPlugin.BaseControllerPlugin { this.lastProgressBroadcast = Date.now(); if (techs.length) { - this.broadcastEventToSlaves(this.info.messages.progress, { technologies: techs }); + this.broadcastEventToHosts(this.info.messages.progress, { technologies: techs }); } } @@ -97,7 +97,7 @@ class ControllerPlugin extends libPlugin.BaseControllerPlugin { tech.progress = null; this.progressToBroadcast.delete(name); - this.broadcastEventToSlaves(this.info.messages.finished, { name, level: tech.level }); + this.broadcastEventToHosts(this.info.messages.finished, { name, level: tech.level }); } } @@ -127,7 +127,7 @@ class ControllerPlugin extends libPlugin.BaseControllerPlugin { if (progress) { this.progressToBroadcast.add(name); } else if (researched || baseLevel(name) !== level) { - this.broadcastEventToSlaves(this.info.messages.finished, { name, level }); + this.broadcastEventToHosts(this.info.messages.finished, { name, level }); } } else { @@ -138,7 +138,7 @@ class ControllerPlugin extends libPlugin.BaseControllerPlugin { if (tech.level < level || researched) { // Send update if the unlocked level is greater if (level - !researched > tech.level - !tech.researched) { - this.broadcastEventToSlaves(this.info.messages.finished, { name, level: level - !researched }); + this.broadcastEventToHosts(this.info.messages.finished, { name, level: level - !researched }); } tech.level = level; tech.progress = progress; diff --git a/plugins/research_sync/info.js b/plugins/research_sync/info.js index 8320281e..43f3bec5 100644 --- a/plugins/research_sync/info.js +++ b/plugins/research_sync/info.js @@ -28,7 +28,7 @@ module.exports = { messages: { contribution: new libLink.Event({ type: "research_sync:contribution", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", eventProperties: { "name": { type: "string" }, @@ -38,7 +38,7 @@ module.exports = { }), progress: new libLink.Event({ type: "research_sync:progress", - links: ["controller-slave", "slave-instance"], + links: ["controller-host", "host-instance"], broadcastTo: "instance", eventProperties: { "technologies": { @@ -57,7 +57,7 @@ module.exports = { }), finished: new libLink.Event({ type: "research_sync:finished", - links: ["instance-slave", "slave-controller", "controller-slave", "slave-instance"], + links: ["instance-host", "host-controller", "controller-host", "host-instance"], forwardTo: "controller", broadcastTo: "instance", eventProperties: { @@ -67,7 +67,7 @@ module.exports = { }), syncTechnologies: new libLink.Request({ type: "research_sync:sync_technologies", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", requestProperties: { "technologies": technologies, diff --git a/plugins/statistics_exporter/README.md b/plugins/statistics_exporter/README.md index bfa20675..66ae1c8d 100644 --- a/plugins/statistics_exporter/README.md +++ b/plugins/statistics_exporter/README.md @@ -10,7 +10,7 @@ Run the following commands in the folder Clusterio is installed to: npm install @clusterio/plugin-statistics_exporter npx clusteriocontroller plugin add @clusterio/plugin-statistics_exporter -Substitute clusteriocontroller with clusterioslave or clusterioctl if this a dedicate slave or ctl installation respectively. +Substitute clusteriocontroller with clusteriohost or clusterioctl if this a dedicate host or ctl installation respectively. ## Instance Configuration diff --git a/plugins/statistics_exporter/info.js b/plugins/statistics_exporter/info.js index 42d61325..8b424049 100644 --- a/plugins/statistics_exporter/info.js +++ b/plugins/statistics_exporter/info.js @@ -2,7 +2,7 @@ const { libConfig } = require("@clusterio/lib"); class InstanceConfigGroup extends libConfig.PluginConfigGroup {} -InstanceConfigGroup.defaultAccess = ["controller", "slave", "control"]; +InstanceConfigGroup.defaultAccess = ["controller", "host", "control"]; InstanceConfigGroup.groupName = "statistics_exporter"; InstanceConfigGroup.define({ name: "command_timeout", diff --git a/plugins/subspace_storage/README.md b/plugins/subspace_storage/README.md index a3129723..6f1ed199 100644 --- a/plugins/subspace_storage/README.md +++ b/plugins/subspace_storage/README.md @@ -10,4 +10,4 @@ Run the following commands in the folder Clusterio is installed to: npm install @clusterio/plugin-subspace_storage npx clusteriocontroller plugin add @clusterio/plugin-subspace_storage -Substitute clusteriocontroller with clusterioslave or clusterioctl if this a dedicate slave or ctl installation respectively. +Substitute clusteriocontroller with clusteriohost or clusterioctl if this a dedicate host or ctl installation respectively. diff --git a/plugins/subspace_storage/controller.js b/plugins/subspace_storage/controller.js index f70c8b2a..5f19a9d6 100644 --- a/plugins/subspace_storage/controller.js +++ b/plugins/subspace_storage/controller.js @@ -107,7 +107,7 @@ class ControllerPlugin extends libPlugin.BaseControllerPlugin { } itemsToUpdate = [...itemsToUpdate.entries()]; - this.broadcastEventToSlaves(this.info.messages.updateStorage, { items: itemsToUpdate }); + this.broadcastEventToHosts(this.info.messages.updateStorage, { items: itemsToUpdate }); for (let link of this.subscribedControlLinks) { this.info.messages.updateStorage.send(link, { items: itemsToUpdate }); } @@ -142,7 +142,7 @@ class ControllerPlugin extends libPlugin.BaseControllerPlugin { let itemsRemoved = []; if (method === "simple") { // Give out as much items as possible until there are 0 left. This - // might lead to one slave getting all the items and the rest nothing. + // might lead to one host getting all the items and the rest nothing. for (let item of message.data.items) { let count = this.items.getItemCount(item[0]); let toRemove = Math.min(count, item[1]); diff --git a/plugins/subspace_storage/dole.js b/plugins/subspace_storage/dole.js index f8f64e32..a247e765 100644 --- a/plugins/subspace_storage/dole.js +++ b/plugins/subspace_storage/dole.js @@ -84,7 +84,7 @@ class NeuralDole { this.lastRequest[`${object.name}_${object.instanceID}_${object.instanceName}`] = object.count; // 0. Number of items to give in that dose // 1. New dole for item X - // 2. New carry for item X slave Y + // 2. New carry for item X instance Y this.dole[object.name] = magicData[1]; this.carry[`${object.name} ${object.instanceID}`] = magicData[2]; this.debt[`${object.name} ${object.instanceID}`] = magicData[3]; diff --git a/plugins/subspace_storage/dole_nn_base.js b/plugins/subspace_storage/dole_nn_base.js index af565c95..1818a76b 100644 --- a/plugins/subspace_storage/dole_nn_base.js +++ b/plugins/subspace_storage/dole_nn_base.js @@ -23,23 +23,23 @@ function sigmoid3(x) { return x; } -// DOSE - Doses items for item X slave Y -// Numreq - number of items that are requested for item X for slave Y +// DOSE - Doses items for item X instance Y +// Numreq - number of items that are requested for item X for instance Y // Instore - number of items for item X in controller gauge (currently) // store_last_tick - // Number of items for item X in controller gauge at time of last tick // dole - Current dole for item X -// carry - carry for item X slave Y -// prev_req - Numreq for previous request for item X slave Y +// carry - carry for item X instance Y +// prev_req - Numreq for previous request for item X instance Y // * doleinfo_last - // Object with 2 values for last "tick period": numreq - total number or -// requests for item, numslave - number of slaves requesting that item -// debt - debt for item X slave Y +// requests for item, numinstance - number of instances requesting that item +// debt - debt for item X instance Y // Returns: Array of 3 elements // 0.Number of items to give in that dose // 1.New dole for item X -// 2.New carry for item X slave Y +// 2.New carry for item X instance Y // 3.New debt function dose(numreq, instore, store_last_tick, dole, carry, prev_req, numreq_total_adj, debt) { numreq = Number(numreq); @@ -98,18 +98,18 @@ function dose(numreq, instore, store_last_tick, dole, carry, prev_req, numreq_to // TICK - // Updates values for item X, should be called once for each item for -// each round of all slaves requesting that item Instore - number of +// each round of all instances requesting that item Instore - number of // items for item X in controller gauge (currently) // dole - Current dole for item X // store_last_tick - // Number of items for item X in controller gauge at time of last tick (not this one) // * doleinfo_last - // Object with 2 values for last "tick period": numreq - total number or -// requests for item, numslave - number of slaves requesting that item +// requests for item, numinstance - number of instances requesting that item // // * doleinfo_new - // Object with 2 values for new "tick period": numreq - total number or -// requests for item, numslave - number of slaves requesting that item +// requests for item, numinstance - number of instances requesting that item // Returns: Array of 2 elements diff --git a/plugins/subspace_storage/info.js b/plugins/subspace_storage/info.js index b81b5365..d59c8bca 100644 --- a/plugins/subspace_storage/info.js +++ b/plugins/subspace_storage/info.js @@ -2,7 +2,7 @@ const { libConfig, libLink, libUsers } = require("@clusterio/lib"); class ControllerConfigGroup extends libConfig.PluginConfigGroup {} -ControllerConfigGroup.defaultAccess = ["controller", "slave", "control"]; +ControllerConfigGroup.defaultAccess = ["controller", "host", "control"]; ControllerConfigGroup.groupName = "subspace_storage"; ControllerConfigGroup.define({ name: "autosave_interval", @@ -29,12 +29,12 @@ ControllerConfigGroup.define({ ControllerConfigGroup.finalize(); class InstanceConfigGroup extends libConfig.PluginConfigGroup {} -InstanceConfigGroup.defaultAccess = ["controller", "slave", "control"]; +InstanceConfigGroup.defaultAccess = ["controller", "host", "control"]; InstanceConfigGroup.groupName = "subspace_storage"; InstanceConfigGroup.define({ name: "log_item_transfers", title: "Log Item Transfers", - description: "Spam slave console with item transfers done.", + description: "Spam host console with item transfers done.", type: "boolean", initial_value: false, }); @@ -78,7 +78,7 @@ module.exports = { // XXX this should be a request to be reliable place: new libLink.Event({ type: "subspace_storage:place", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", eventProperties: { "instance_id": { type: "integer" }, @@ -87,7 +87,7 @@ module.exports = { }), remove: new libLink.Request({ type: "subspace_storage:remove", - links: ["instance-slave", "slave-controller"], + links: ["instance-host", "host-controller"], forwardTo: "controller", requestProperties: { "instance_id": { type: "integer" }, @@ -99,7 +99,7 @@ module.exports = { }), getStorage: new libLink.Request({ type: "subspace_storage:get_storage", - links: ["instance-slave", "slave-controller", "control-controller"], + links: ["instance-host", "host-controller", "control-controller"], permission: "subspace_storage.storage.view", forwardTo: "controller", responseProperties: { @@ -108,7 +108,7 @@ module.exports = { }), updateStorage: new libLink.Event({ type: "subspace_storage:update_storage", - links: ["controller-slave", "slave-instance", "controller-control"], + links: ["controller-host", "host-instance", "controller-control"], broadcastTo: "instance", eventProperties: { "items": items, diff --git a/plugins/subspace_storage/instance.js b/plugins/subspace_storage/instance.js index 3ebc6c90..62f6d638 100644 --- a/plugins/subspace_storage/instance.js +++ b/plugins/subspace_storage/instance.js @@ -13,7 +13,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { this.provideItems(output).catch(err => this.unexpectedError(err)); }); this.instance.server.on("ipc-subspace_storage:orders", (orders) => { - if (this.instance.status !== "running" || !this.slave.connected) { + if (this.instance.status !== "running" || !this.host.connected) { return; } @@ -25,7 +25,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { async onStart() { this.pingId = setInterval(() => { - if (!this.slave.connected) { + if (!this.host.connected) { return; // Only ping if we are actually connected to the controller. } this.sendRcon( @@ -50,7 +50,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin { // provide items -------------------------------------------------------------- async provideItems(items) { - if (!this.slave.connector.hasSession) { + if (!this.host.connector.hasSession) { // For now the items are voided if the controller connection is // down, which is no different from the previous behaviour. if (this.instance.config.get("subspace_storage.log_item_transfers")) { diff --git a/test/controller/routes.js b/test/controller/routes.js index 63f42e54..bc7b90e7 100644 --- a/test/controller/routes.js +++ b/test/controller/routes.js @@ -307,7 +307,7 @@ describe("controller/src/routes", function() { }); assert.equal(response.statusCode, 500); assert.deepEqual( - JSON.parse(response.body), { errors: ["Timed out establishing stream to slave"], request_errors: [] } + JSON.parse(response.body), { errors: ["Timed out establishing stream to host"], request_errors: [] } ); }); diff --git a/test/file/log/test-2021-12-10.log b/test/file/log/test-2021-12-10.log index 41d157e1..2825c466 100644 --- a/test/file/log/test-2021-12-10.log +++ b/test/file/log/test-2021-12-10.log @@ -1,9 +1,9 @@ {"timestamp":"2021-12-10T10:00:00.000Z","level":"verbose","message":"Controller start"} {"timestamp":"2021-12-10T10:00:01.000Z","level":"verbose","message":"Loading"} {"timestamp":"2021-12-10T10:00:03.000Z","level":"info","message":"Ready"} -{"timestamp":"2021-12-10T10:00:10.000Z","slave_id":1,"level":"verbose","message":"Slave connected"} -{"timestamp":"2021-12-10T10:00:11.000Z","slave_id":1,"level":"verbose","message":"Found instance 10"} -{"timestamp":"2021-12-10T10:00:13.000Z","slave_id":1,"instance_id":10,"level":"server","message":"Starting up"} -{"timestamp":"2021-12-10T10:00:14.000Z","slave_id":1,"instance_id":10,"level":"server","message":"Loading map"} -{"timestamp":"2021-12-10T10:00:15.000Z","slave_id":1,"instance_id":10,"level":"server","message":"Game ready"} -{"timestamp":"2021-12-10T10:01:00.000Z","slave_id":1,"instance_id":10,"level":"error","message":"Unexpected crash"} +{"timestamp":"2021-12-10T10:00:10.000Z","host_id":1,"level":"verbose","message":"Host connected"} +{"timestamp":"2021-12-10T10:00:11.000Z","host_id":1,"level":"verbose","message":"Found instance 10"} +{"timestamp":"2021-12-10T10:00:13.000Z","host_id":1,"instance_id":10,"level":"server","message":"Starting up"} +{"timestamp":"2021-12-10T10:00:14.000Z","host_id":1,"instance_id":10,"level":"server","message":"Loading map"} +{"timestamp":"2021-12-10T10:00:15.000Z","host_id":1,"instance_id":10,"level":"server","message":"Game ready"} +{"timestamp":"2021-12-10T10:01:00.000Z","host_id":1,"instance_id":10,"level":"error","message":"Unexpected crash"} diff --git a/test/slave.js b/test/host.js similarity index 61% rename from test/slave.js rename to test/host.js index d8d34788..013d57d9 100644 --- a/test/slave.js +++ b/test/host.js @@ -3,9 +3,9 @@ const assert = require("assert").strict; const path = require("path"); const libConfig = require("@clusterio/lib/config"); -const Slave = require("@clusterio/slave/src/Slave"); +const Host = require("@clusterio/host/src/Host"); -describe("Slave testing", function() { +describe("Host testing", function() { before(function() { libConfig.InstanceConfig.finalize(); }); @@ -13,9 +13,9 @@ describe("Slave testing", function() { describe("discoverInstances()", function() { it("should discover test instance", async function() { let instancePath = path.join("test", "file", "instances"); - let instanceInfos = await Slave._discoverInstances(instancePath); + let instanceInfos = await Host._discoverInstances(instancePath); - let referenceConfig = new libConfig.InstanceConfig("slave"); + let referenceConfig = new libConfig.InstanceConfig("host"); await referenceConfig.init(); referenceConfig.set("instance.id", 1); referenceConfig.set("instance.name", "test"); @@ -29,11 +29,11 @@ describe("Slave testing", function() { }); }); - describe("class Slave", function() { + describe("class Host", function() { describe(".syncUserListsEventHandler()", function() { - let mockSlave; + let mockHost; beforeEach(function() { - mockSlave = { + mockHost = { adminlist: new Set(), whitelist: new Set(), banlist: new Map(), @@ -41,7 +41,7 @@ describe("Slave testing", function() { broadcastEventToInstance(message, event) { this.broadcasts.push(message["data"]); }, - syncUserListsEventHandler: Slave.prototype.syncUserListsEventHandler, + syncUserListsEventHandler: Host.prototype.syncUserListsEventHandler, syncLists(adminlist, banlist, whitelist) { return this.syncUserListsEventHandler({ "data": { "adminlist": adminlist, @@ -53,57 +53,57 @@ describe("Slave testing", function() { }); it("should broadcast new entries to adminlist", async function() { - await mockSlave.syncLists(["admin1"], [], []); - await mockSlave.syncLists(["admin1", "admin2"], [], []); + await mockHost.syncLists(["admin1"], [], []); + await mockHost.syncLists(["admin1", "admin2"], [], []); - assert.deepEqual(mockSlave.broadcasts, [ + assert.deepEqual(mockHost.broadcasts, [ { "name": "admin1", "admin": true }, { "name": "admin2", "admin": true }, ]); }); it("should broadcast removals from adminlist", async function() { - mockSlave.adminlist.add("admin1").add("admin2"); - await mockSlave.syncLists(["admin1"], [], []); - assert.deepEqual(mockSlave.broadcasts, [ + mockHost.adminlist.add("admin1").add("admin2"); + await mockHost.syncLists(["admin1"], [], []); + assert.deepEqual(mockHost.broadcasts, [ { "name": "admin2", "admin": false }, ]); }); it("should broadcast new entries to whitelist", async function() { - await mockSlave.syncLists([], [], ["player1"]); - await mockSlave.syncLists([], [], ["player1", "player2"]); + await mockHost.syncLists([], [], ["player1"]); + await mockHost.syncLists([], [], ["player1", "player2"]); - assert.deepEqual(mockSlave.broadcasts, [ + assert.deepEqual(mockHost.broadcasts, [ { "name": "player1", "whitelisted": true }, { "name": "player2", "whitelisted": true }, ]); }); it("should broadcast removals from whitelist", async function() { - mockSlave.whitelist.add("player1").add("player2"); - await mockSlave.syncLists([], [], ["player1"]); + mockHost.whitelist.add("player1").add("player2"); + await mockHost.syncLists([], [], ["player1"]); - assert.deepEqual(mockSlave.broadcasts, [ + assert.deepEqual(mockHost.broadcasts, [ { "name": "player2", "whitelisted": false }, ]); }); it("should broadcast new entries to banlist", async function() { - await mockSlave.syncLists([], [["badie1", "greifing"]], []); - await mockSlave.syncLists([], [["badie1", "greifing"], ["badie2", "annoying"]], []); + await mockHost.syncLists([], [["badie1", "greifing"]], []); + await mockHost.syncLists([], [["badie1", "greifing"], ["badie2", "annoying"]], []); - assert.deepEqual(mockSlave.broadcasts, [ + assert.deepEqual(mockHost.broadcasts, [ { "name": "badie1", "banned": true, "reason": "greifing" }, { "name": "badie2", "banned": true, "reason": "annoying" }, ]); }); it("should broadcast removals to banlist", async function() { - mockSlave.banlist.set("badie1", "greifing").set("badie2", "annoying"); - await mockSlave.syncLists([], [["badie1", "greifing"]], []); + mockHost.banlist.set("badie1", "greifing").set("badie2", "annoying"); + await mockHost.syncLists([], [["badie1", "greifing"]], []); - assert.deepEqual(mockSlave.broadcasts, [ + assert.deepEqual(mockHost.broadcasts, [ { "name": "badie2", "banned": false, "reason": "" }, ]); }); diff --git a/test/slave/Instance.js b/test/host/Instance.js similarity index 98% rename from test/slave/Instance.js rename to test/host/Instance.js index 1c3b5808..6b7b548f 100644 --- a/test/slave/Instance.js +++ b/test/host/Instance.js @@ -4,7 +4,7 @@ const path = require("path"); const libConfig = require("@clusterio/lib/config"); const { wait } = require("@clusterio/lib/helpers"); -const Instance = require("@clusterio/slave/src/Instance"); +const Instance = require("@clusterio/host/src/Instance"); const { MockConnector, MockServer } = require("../mock"); @@ -16,7 +16,7 @@ describe("class Instance", function() { let instance; let connector; beforeEach(async function() { - let instanceConfig = new libConfig.InstanceConfig("slave"); + let instanceConfig = new libConfig.InstanceConfig("host"); await instanceConfig.init(); instanceConfig.set("instance.name", "foo"); connector = new MockConnector(); diff --git a/test/integration/clusterio.js b/test/integration/clusterio.js index d5aa8008..bbcd662a 100644 --- a/test/integration/clusterio.js +++ b/test/integration/clusterio.js @@ -92,7 +92,7 @@ describe("Integration of Clusterio", function() { let result = await libLink.messages.queryLog.send(getControl(), { all: true, controller: false, - slave_ids: [], + host_ids: [], instance_ids: [], max_level: null, limit: 10, @@ -104,7 +104,7 @@ describe("Integration of Clusterio", function() { let first = await libLink.messages.queryLog.send(getControl(), { all: true, controller: false, - slave_ids: [], + host_ids: [], instance_ids: [], max_level: null, limit: 1, @@ -113,7 +113,7 @@ describe("Integration of Clusterio", function() { let last = await libLink.messages.queryLog.send(getControl(), { all: true, controller: false, - slave_ids: [], + host_ids: [], instance_ids: [], max_level: null, limit: 1, @@ -124,41 +124,41 @@ describe("Integration of Clusterio", function() { }); }); - describe("clusterioslave", function() { - describe("slaveUpdateEventHandler()", function() { - it("should trigger when a new slave is added", async function() { - // On windows there's currently no way to automate graceful shutdown of the slave + describe("clusteriohost", function() { + describe("hostUpdateEventHandler()", function() { + it("should trigger when a new host is added", async function() { + // On windows there's currently no way to automate graceful shutdown of the host // process as CTRL+C is some weird terminal thing and SIGINT isn't a thing. if (process.platform === "win32") { this.skip(); } slowTest(this); - getControl().slaveUpdates = []; - let config = "alt-slave-config.json"; + getControl().hostUpdates = []; + let config = "alt-host-config.json"; let configPath = path.join("temp", "test", config); await fs.remove(configPath); await fs.remove(path.join("temp", "test", "alt-instances")); - await execCtl(`slave create-config --id 5 --name alt-slave --generate-token --output ${config}`); + await execCtl(`host create-config --id 5 --name alt-host --generate-token --output ${config}`); await exec( - `node ../../packages/slave --config ${config} config set slave.tls_ca ../../test/file/tls/cert.pem` + `node ../../packages/host --config ${config} config set host.tls_ca ../../test/file/tls/cert.pem` ); await exec( - `node ../../packages/slave --config ${config} config set slave.instances_directory alt-instances` + `node ../../packages/host --config ${config} config set host.instances_directory alt-instances` ); - let slaveProcess; + let hostProcess; try { - slaveProcess = await spawn( - "alt-slave:", `node ../../packages/slave run --config ${config}`, /Started slave/ + hostProcess = await spawn( + "alt-host:", `node ../../packages/host run --config ${config}`, /Started host/ ); // Add instance to test the unknown status afterwards await execCtl("instance create alt-test --id 99"); await execCtl("instance assign alt-test 5"); } finally { - if (slaveProcess) { - slaveProcess.kill("SIGINT"); - await events.once(slaveProcess, "exit"); + if (hostProcess) { + hostProcess.kill("SIGINT"); + await events.once(hostProcess, "exit"); } } @@ -166,8 +166,8 @@ describe("Integration of Clusterio", function() { let sawConnected = false; let sawDisconnected = false; - for (let update of getControl().slaveUpdates) { - if (update.name !== "alt-slave") { + for (let update of getControl().hostUpdates) { + if (update.name !== "alt-host") { continue; } @@ -179,13 +179,13 @@ describe("Integration of Clusterio", function() { } } - assert(sawUpdate, "No slave update was sent"); - assert(sawConnected, "No slave update with status connected was sent"); - assert(sawDisconnected, "No slave update with status disconnected was sent"); + assert(sawUpdate, "No host update was sent"); + assert(sawConnected, "No host update with status connected was sent"); + assert(sawDisconnected, "No host update with status disconnected was sent"); - let result = await libLink.messages.listSlaves.send(getControl()); - let slaves = new Map(result.list.map(instance => [instance.id, instance])); - assert(slaves.has(5), "Slave list was not updated"); + let result = await libLink.messages.listHosts.send(getControl()); + let hosts = new Map(result.list.map(instance => [instance.id, instance])); + assert(hosts.has(5), "Host list was not updated"); }); }); }); @@ -233,17 +233,17 @@ describe("Integration of Clusterio", function() { }); }); - describe("slave list", function() { + describe("host list", function() { it("runs", async function() { - await execCtl("slave list"); + await execCtl("host list"); }); }); - describe("slave generate-token", function() { + describe("host generate-token", function() { it("runs", async function() { - await execCtl("slave generate-token --id 42"); + await execCtl("host generate-token --id 42"); }); it("runs without an id", async function() { - await execCtl("slave generate-token"); + await execCtl("host generate-token"); }); }); describe("instance list", function() { @@ -370,7 +370,7 @@ describe("Integration of Clusterio", function() { let { log } = await libLink.messages.queryLog.send(getControl(), { all: false, controller: false, - slave_ids: [], + host_ids: [], instance_ids: [44], max_level: null, limit: 10, @@ -683,24 +683,24 @@ describe("Integration of Clusterio", function() { ; describe(remote ? "remote" : "local", function() { if (remote) { - let slaveProcess; + let hostProcess; before(async function() { - // On windows there's currently no way to automate graceful shutdown of the slave + // On windows there's currently no way to automate graceful shutdown of the host // process as CTRL+C is some weird terminal thing and SIGINT isn't a thing. if (process.platform === "win32") { this.skip(); } slowTest(this); - // Reuse from the clusterioslave test - let config = "alt-slave-config.json"; - slaveProcess = await spawn( - "alt-slave:", `node ../../packages/slave run --config ${config}`, /Started slave/ + // Reuse from the clusteriohost test + let config = "alt-host-config.json"; + hostProcess = await spawn( + "alt-host:", `node ../../packages/host run --config ${config}`, /Started host/ ); }); after(async function() { - if (slaveProcess) { - slaveProcess.kill("SIGINT"); - await events.once(slaveProcess, "exit"); + if (hostProcess) { + hostProcess.kill("SIGINT"); + await events.once(hostProcess, "exit"); } }); } @@ -1036,14 +1036,14 @@ describe("Integration of Clusterio", function() { assert.deepEqual(newRole, { id: 5, name: "new", description: "A new role", permissions: [] }); }); it("should add permissions with --add-perms", async function() { - let args = "--name new --add-perms core.slave.list core.instance.list"; + let args = "--name new --add-perms core.host.list core.instance.list"; await execCtl(`role edit new ${args}`); let result = await libLink.messages.listRoles.send(getControl()); let newRole = result.list.find(role => role.name === "new"); - assert.deepEqual(newRole.permissions, ["core.slave.list", "core.instance.list"]); + assert.deepEqual(newRole.permissions, ["core.host.list", "core.instance.list"]); }); it("should remove permissions with --remove-perms", async function() { - let args = "--name new --remove-perms core.slave.list"; + let args = "--name new --remove-perms core.host.list"; await execCtl(`role edit new ${args}`); let result = await libLink.messages.listRoles.send(getControl()); let newRole = result.list.find(role => role.name === "new"); diff --git a/test/integration/index.js b/test/integration/index.js index 72465e06..10c3686a 100644 --- a/test/integration/index.js +++ b/test/integration/index.js @@ -26,7 +26,7 @@ class TestControl extends libLink.Link { constructor(connector) { super("control", "controller", connector); libLink.attachAllMessages(this); - this.slaveUpdates = []; + this.hostUpdates = []; this.instanceUpdates = []; this.saveListUpdates = []; this.modUpdates = []; @@ -34,9 +34,9 @@ class TestControl extends libLink.Link { this.userUpdates = []; this.connector.on("connect", () => { - libLink.messages.setSlaveSubscriptions.send( - this, { all: true, slave_ids: [] } - ).catch(err => logger.error(`Error setting slave subscriptions:\n${err.stack}`)); + libLink.messages.setHostSubscriptions.send( + this, { all: true, host_ids: [] } + ).catch(err => logger.error(`Error setting host subscriptions:\n${err.stack}`)); libLink.messages.setInstanceSubscriptions.send( this, { all: true, instance_ids: [] } ).catch(err => logger.error(`Error setting instance subscriptions:\n${err.stack}`)); @@ -61,8 +61,8 @@ class TestControl extends libLink.Link { async accountUpdateEventHandler() { } - async slaveUpdateEventHandler(message) { - this.slaveUpdates.push(message.data); + async hostUpdateEventHandler(message) { + this.hostUpdates.push(message.data); } async instanceUpdateEventHandler(message) { @@ -118,7 +118,7 @@ async function get(urlPath) { } let controllerProcess; -let slaveProcess; +let hostProcess; let control; let url = "https://localhost:4443/"; @@ -127,7 +127,7 @@ let instancesDir = path.join("temp", "test", "instances"); let databaseDir = path.join("temp", "test", "database"); let pluginListPath = path.join("temp", "test", "plugin-list.json"); let controllerConfigPath = path.join("temp", "test", "config-controller.json"); -let slaveConfigPath = path.join("temp", "test", "config-slave.json"); +let hostConfigPath = path.join("temp", "test", "config-host.json"); let controlConfigPath = path.join("temp", "test", "config-control.json"); async function exec(command, options = {}) { @@ -185,7 +185,7 @@ before(async function() { await fs.remove(pluginListPath); await fs.remove(controllerConfigPath); - await fs.remove(slaveConfigPath); + await fs.remove(hostConfigPath); await fs.remove(controlConfigPath); await fs.ensureDir(path.join("temp", "test")); @@ -210,11 +210,11 @@ before(async function() { controllerProcess = await spawn("controller:", "node ../../packages/controller run", /Started controller/); - await execCtl("slave create-config --id 4 --name slave --generate-token"); - await exec(`node ../../packages/slave config set slave.factorio_directory ${path.join("..", "..", "factorio")}`); - await exec("node ../../packages/slave config set slave.tls_ca ../../test/file/tls/cert.pem"); + await execCtl("host create-config --id 4 --name host --generate-token"); + await exec(`node ../../packages/host config set host.factorio_directory ${path.join("..", "..", "factorio")}`); + await exec("node ../../packages/host config set host.tls_ca ../../test/file/tls/cert.pem"); - slaveProcess = await spawn("slave:", "node ../../packages/slave run", /Started slave/); + hostProcess = await spawn("host:", "node ../../packages/host run", /Started host/); let tlsCa = await fs.readFile("test/file/tls/cert.pem"); let controlConnector = new TestControlConnector(url, 2, tlsCa); @@ -236,10 +236,10 @@ before(async function() { after(async function() { this.timeout(20000); - if (slaveProcess) { - console.log("Shutting down slave"); - slaveProcess.kill("SIGINT"); - await events.once(slaveProcess, "exit"); + if (hostProcess) { + console.log("Shutting down host"); + hostProcess.kill("SIGINT"); + await events.once(hostProcess, "exit"); } if (controllerProcess) { console.log("Shutting down controller"); @@ -253,7 +253,7 @@ after(async function() { // Ensure the test processes are stopped. process.on("exit", () => { - if (slaveProcess) { slaveProcess.kill(); } + if (hostProcess) { hostProcess.kill(); } if (controllerProcess) { controllerProcess.kill(); } }); @@ -274,6 +274,6 @@ module.exports = { instancesDir, databaseDir, controllerConfigPath, - slaveConfigPath, + hostConfigPath, controlConfigPath, }; diff --git a/test/lib/command.js b/test/lib/command.js index e2f94374..749085ad 100644 --- a/test/lib/command.js +++ b/test/lib/command.js @@ -11,12 +11,12 @@ describe("lib/command", function() { let testRole = { id: 28, name: "Test Role", description: "Test", permissions: [] }; let mockConnector = new mock.MockConnector(); mockConnector.on("send", function(message) { - if (message.type === "list_slaves_request") { + if (message.type === "list_hosts_request") { this.emit("message", { - seq: 1, type: "list_slaves_response", + seq: 1, type: "list_hosts_response", data: { seq: message.seq, - list: [{ agent: "test", version: "0.1", id: 11, name: "Test Slave", connected: false }], + list: [{ agent: "test", version: "0.1", id: 11, name: "Test Host", connected: false }], }, }); } else if (message.type === "list_instances_request") { @@ -24,7 +24,7 @@ describe("lib/command", function() { seq: 1, type: "list_instances_response", data: { seq: message.seq, - list: [{ id: 57, assigned_slave: 4, name: "Test Instance", status: "stopped" }], + list: [{ id: 57, assigned_host: 4, name: "Test Instance", status: "stopped" }], }, }); } else if (message.type === "list_roles_request") { @@ -39,21 +39,21 @@ describe("lib/command", function() { }); let testControl = new mock.MockControl(mockConnector); - libLink.messages.listSlaves.attach(testControl); + libLink.messages.listHosts.attach(testControl); libLink.messages.listInstances.attach(testControl); libLink.messages.listRoles.attach(testControl); - describe("resolveSlave", function() { + describe("resolveHost", function() { it("should pass an integer like string back", async function() { - assert.equal(await libCommand.resolveSlave(null, "123"), 123); + assert.equal(await libCommand.resolveHost(null, "123"), 123); }); - it("should resolve a slave name with the controller", async function() { - assert.equal(await libCommand.resolveSlave(testControl, "Test Slave"), 11); + it("should resolve a host name with the controller", async function() { + assert.equal(await libCommand.resolveHost(testControl, "Test Host"), 11); }); - it("should throw if slave is not found", async function() { + it("should throw if host is not found", async function() { await assert.rejects( - libCommand.resolveSlave(testControl, "invalid"), - new libErrors.CommandError("No slave named invalid") + libCommand.resolveHost(testControl, "invalid"), + new libErrors.CommandError("No host named invalid") ); }); }); diff --git a/test/lib/logging_utils.js b/test/lib/logging_utils.js index aacdf39f..d0ef0ac9 100644 --- a/test/lib/logging_utils.js +++ b/test/lib/logging_utils.js @@ -111,13 +111,13 @@ describe("lib/logging_utils.js", function() { it("should filter by controller", async function() { let log = await libLoggingUtils.queryLog(logDir, { controller: true }, index()); assert.deepEqual(log, allLines.filter( - info => info.slave_id === undefined && info.instance_id === undefined + info => info.host_id === undefined && info.instance_id === undefined )); }); - it("should filter by slave_ids", async function() { - let log = await libLoggingUtils.queryLog(logDir, { slave_ids: [1, 2] }, index()); + it("should filter by host_ids", async function() { + let log = await libLoggingUtils.queryLog(logDir, { host_ids: [1, 2] }, index()); assert.deepEqual(log, allLines.filter( - info => [1, 2].includes(info.slave_id) && info.instance_id === undefined + info => [1, 2].includes(info.host_id) && info.instance_id === undefined )); }); it("should filter by instance_ids", async function() { diff --git a/test/lib/plugin.js b/test/lib/plugin.js index 1103fac0..d38fdfce 100644 --- a/test/lib/plugin.js +++ b/test/lib/plugin.js @@ -66,8 +66,8 @@ describe("lib/plugin", function() { await controllerPlugin.onInstanceConfigFieldChanged({}, {}, "foo", null); await controllerPlugin.onMetrics(); await controllerPlugin.onShutdown(); - controllerPlugin.onSlaveConnectionEvent({}, "connect"); - await controllerPlugin.onPrepareSlaveDisconnect({}); + controllerPlugin.onHostConnectionEvent({}, "connect"); + await controllerPlugin.onPrepareHostDisconnect({}); }); }); diff --git a/test/mock.js b/test/mock.js index b10a9947..2f81f378 100644 --- a/test/mock.js +++ b/test/mock.js @@ -125,7 +125,7 @@ class MockServer extends events.EventEmitter { class MockInstance extends libLink.Link { constructor() { - super("instance", "slave", new MockConnector()); + super("instance", "host", new MockConnector()); this.logger = new MockLogger(); this.server = new MockServer(); this.name = "test"; @@ -150,9 +150,9 @@ class MockInstance extends libLink.Link { } } -class MockSlave extends libLink.Link { +class MockHost extends libLink.Link { constructor() { - super("slave", "controller", new MockConnector()); + super("host", "controller", new MockConnector()); } } @@ -193,7 +193,7 @@ class MockController { ["player", new libUsers.User({ name: "player", roles: [1] }, this.userManager.roles)], ]); this.instances = new Map(); - this.slaves = new Map(); + this.hosts = new Map(); } getControllerUrl() { @@ -228,8 +228,8 @@ async function createControllerPlugin(ControllerPluginClass, info) { async function createInstancePlugin(InstancePluginClass, info) { let instance = new MockInstance(); - let slave = new MockSlave(); - let plugin = new InstancePluginClass(info, instance, slave); + let host = new MockHost(); + let plugin = new InstancePluginClass(info, instance, host); libPlugin.attachPluginMessages(instance, plugin); await plugin.init(); return plugin; @@ -242,7 +242,7 @@ module.exports = { MockConnector, MockServer, MockInstance, - MockSlave, + MockHost, MockControl, MockController,