Przeglądaj źródła

add assigned_central_version column to controllers_ctl

Allow controllers to advertise which central version (cv1, cv2, or all)
they are assigned to handle via a new configurable field. The value is
persisted to the database on each heartbeat and validated at startup
against the DB CHECK constraint.
Grant Limberg 3 tygodni temu
rodzic
commit
2c57f85e25

+ 1 - 0
ext/central-controller-docker/migrations/0007_assigned_version.down.sql

@@ -0,0 +1 @@
+ALTER TABLE controllers_ctl DROP COLUMN IF EXISTS assigned_central_version;

+ 1 - 0
ext/central-controller-docker/migrations/0007_assigned_version.up.sql

@@ -0,0 +1 @@
+ALTER TABLE controllers_ctl ADD COLUMN IF NOT EXISTS assigned_central_version text DEFAULT 'all' NOT NULL CONSTRAINT controllers_ctl_assigned_central_version_check CHECK (assigned_central_version IN ('cv1', 'cv2', 'all'));

+ 6 - 4
nonfree/controller/CentralDB.cpp

@@ -63,6 +63,7 @@ CentralDB::CentralDB(
 	, _listenerMode(listenMode)
 	, _statusWriterMode(statusMode)
 	, _cc(cc)
+	, _assignedCentralVersion(cc->assignedCentralVersion)
 	, _pool()
 	, _myId(myId)
 	, _myAddress(myId.address())
@@ -1130,12 +1131,13 @@ void CentralDB::heartbeat()
 			try {
 				pqxx::work w { *c->c };
 				w.exec(
-					 "INSERT INTO controllers_ctl (id, hostname, last_heartbeat, public_identity, version) VALUES "
-					 "($1, $2, TO_TIMESTAMP($3::double precision/1000), $4, $5) "
+					 "INSERT INTO controllers_ctl (id, hostname, last_heartbeat, public_identity, version, assigned_central_version) VALUES "
+					 "($1, $2, TO_TIMESTAMP($3::double precision/1000), $4, $5, $6) "
 					 "ON CONFLICT (id) DO UPDATE SET hostname = EXCLUDED.hostname, last_heartbeat = "
 					 "EXCLUDED.last_heartbeat, "
-					 "public_identity = EXCLUDED.public_identity, version = EXCLUDED.version",
-					 pqxx::params { controllerId, hostname, ts, publicIdentity, versionStr })
+					 "public_identity = EXCLUDED.public_identity, version = EXCLUDED.version, "
+					 "assigned_central_version = EXCLUDED.assigned_central_version",
+					 pqxx::params { controllerId, hostname, ts, publicIdentity, versionStr, _assignedCentralVersion })
 					.no_rows();
 				w.commit();
 			}

+ 1 - 0
nonfree/controller/CentralDB.hpp

@@ -106,6 +106,7 @@ class CentralDB : public DB {
 	ListenerMode _listenerMode;
 	StatusWriterMode _statusWriterMode;
 	const ControllerConfig* _cc;
+	std::string _assignedCentralVersion;
 	std::shared_ptr<ConnectionPool<PostgresConnection> > _pool;
 
 	const Identity _myId;

+ 2 - 0
nonfree/controller/ControllerConfig.hpp

@@ -27,6 +27,7 @@ struct ControllerConfig {
 	bool ssoEnabled;
 	std::string listenMode;
 	std::string statusMode;
+	std::string assignedCentralVersion;
 	RedisConfig* redisConfig;
 	PubSubConfig* pubSubConfig;
 	BigTableConfig* bigTableConfig;
@@ -35,6 +36,7 @@ struct ControllerConfig {
 		: ssoEnabled(false)
 		, listenMode("")
 		, statusMode("")
+		, assignedCentralVersion("all")
 		, redisConfig(nullptr)
 		, pubSubConfig(nullptr)
 		, bigTableConfig(nullptr)

+ 11 - 0
service/OneService.cpp

@@ -1813,6 +1813,17 @@ class OneServiceImpl : public OneService {
 		if (cc.is_object()) {
 			_controllerConfig.listenMode = OSUtils::jsonString(cc["listenMode"], "pgsql");
 			_controllerConfig.statusMode = OSUtils::jsonString(cc["statusMode"], "pgsql");
+			// Valid values must match CHECK constraint in migration 0007_assigned_version
+			{
+				const std::string av = OSUtils::jsonString(cc["assignedCentralVersion"], "all");
+				if (av != "cv1" && av != "cv2" && av != "all") {
+					fprintf(
+						stderr,
+						"ERROR: assignedCentralVersion must be one of 'cv1', 'cv2', or 'all'" ZT_EOL_S);
+					exit(1);
+				}
+				_controllerConfig.assignedCentralVersion = av;
+			}
 
 			// redis settings
 			if (cc["redis"].is_object() && _rc == NULL) {