From ef86e000a2847c6bb6f28d8bdebabf17e1a16f35 Mon Sep 17 00:00:00 2001
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Date: Fri, 3 Mar 2023 23:30:12 +0100
Subject: [PATCH] info: rename box.info.cluster -> replicaset

It was named 'cluster', but really was just about the replicaset.
This is going to be even more confusing soon, because there will
be introduced an actual concept of cluster as multiple
replicasets.

The patch renames it to 'replicaset'. `box.info.cluster` now means
the whole cluster and is empty so far. Next patches will add here
the cluster name.

Part of #5029

@TarantoolBot document
Title: `box.info.cluster` is renamed to `box.info.replicaset`

Done since 3.0.0. The old behaviour can be reverted back via the
`compat` option `box_info_cluster_meaning`.

`box.info.cluster` key is still here, but now means a totally
different thing - the entire cluster with all its replicasets.

<h2>Compat documentation</h2>

`box.info.cluster` default meaning is the whole cluster with all
its replicasets. To get info about only the current replicaset
`box.info.replicaset` should be used.

In old versions (< 3.0.0) `box.info.cluster` meant the current
replicaset and `box.info.replicaset` didn't exist.

<h3>Old and new behaviour</h3>

New behaviour:
```
tarantool> box.info.cluster
---
- <some cluster keys>
...

tarantool> box.info.replicaset
---
- uuid: <replicaset uuid>
- <... other attributes of the replicaset>
...
```
Old behaviour:
```
tarantool> box.info.cluster
---
- uuid: <replicaset uuid>
- <... other attributes of the replicaset>
...

tarantool> box.info.replicaset (= nil on < 3.0.0)
---
- uuid: <replicaset uuid>
- <... other attributes of the replicaset>
...
```

<h3>Known compatibility issues</h3>

VShard versions < 0.1.24 do not support the new behaviour.

<h3>Detecting issues in you codebase</h3>

Look for all usages of `box.info.cluster`, `info.cluster`, and
even just `.cluster`, `['cluster']`, `["cluster"]`. For the new
behaviour to work all of them have to use 'replicaset' key.
---
 changelogs/unreleased/info-cluster-rename.md  |  6 +++
 src/box/lua/feedback_daemon.lua               |  2 +-
 src/box/lua/info.c                            | 24 +++++++++++-
 src/box/lua/load_cfg.lua                      |  2 +-
 src/lua/compat.lua                            | 13 +++++++
 .../gh-5632-6050-6259-gc-buf-reuse.test.lua   |  4 +-
 test/box-luatest/downgrade_test.lua           |  2 +-
 test/box-luatest/schema_sys_space_test.lua    |  4 +-
 test/box-luatest/upgrade_to_3_0_0_test.lua    |  2 +-
 test/box-tap/cfg.test.lua                     |  2 +-
 test/box/cfg.result                           |  2 +-
 test/box/cfg.test.lua                         |  2 +-
 test/box/info.result                          | 38 ++++++++++++++++++-
 test/box/info.test.lua                        | 16 +++++++-
 .../bootstrap_strategy_test.lua               |  4 +-
 15 files changed, 107 insertions(+), 16 deletions(-)
 create mode 100644 changelogs/unreleased/info-cluster-rename.md

diff --git a/changelogs/unreleased/info-cluster-rename.md b/changelogs/unreleased/info-cluster-rename.md
new file mode 100644
index 0000000000..377fe92dd3
--- /dev/null
+++ b/changelogs/unreleased/info-cluster-rename.md
@@ -0,0 +1,6 @@
+## bugfix/core
+
+* **[Breaking change]** The table `box.info.cluster` is renamed to
+  `box.info.replicaset`. The behaviour can be reverted using the `compat` option
+  `box_info_cluster_meaning`
+  (https://tarantool.io/compat/box_info_cluster_meaning) (gh-5029).
diff --git a/src/box/lua/feedback_daemon.lua b/src/box/lua/feedback_daemon.lua
index 14f2021d80..adfaadfb4e 100644
--- a/src/box/lua/feedback_daemon.lua
+++ b/src/box/lua/feedback_daemon.lua
@@ -114,7 +114,7 @@ local function fill_in_base_info(feedback)
     end
     feedback.tarantool_version = box.info.version
     feedback.server_id         = box.info.uuid
-    feedback.cluster_id        = box.info.cluster.uuid
+    feedback.cluster_id        = box.info.replicaset.uuid
     feedback.uptime            = box.info.uptime
 end
 
diff --git a/src/box/lua/info.c b/src/box/lua/info.c
index e04d06a02d..0db8f947a4 100644
--- a/src/box/lua/info.c
+++ b/src/box/lua/info.c
@@ -57,6 +57,16 @@
 #include "fiber.h"
 #include "sio.h"
 #include "tt_strerror.h"
+#include "tweaks.h"
+
+/**
+ * In 3.0.0 the meaning of box.info.cluster changed to something not related. In
+ * the major release it was allowed to make the new behaviour the default one,
+ * but since the change can be very breaking for some people, it still can be
+ * reverted.
+ */
+static bool box_info_cluster_new_meaning = true;
+TWEAK_BOOL(box_info_cluster_new_meaning);
 
 static inline void
 lbox_push_replication_error_message(struct lua_State *L, struct error *e,
@@ -369,8 +379,9 @@ lbox_info_pid(struct lua_State *L)
 	return 1;
 }
 
+/** box.info.replicaset. */
 static int
-lbox_info_cluster(struct lua_State *L)
+lbox_info_replicaset(struct lua_State *L)
 {
 	lua_createtable(L, 0, 2);
 	lua_pushliteral(L, "uuid");
@@ -379,6 +390,16 @@ lbox_info_cluster(struct lua_State *L)
 	return 1;
 }
 
+/** box.info.cluster. */
+static int
+lbox_info_cluster(struct lua_State *L)
+{
+	if (!box_info_cluster_new_meaning)
+		return lbox_info_replicaset(L);
+	lua_createtable(L, 0, 0);
+	return 1;
+}
+
 static int
 lbox_info_memory_call(struct lua_State *L)
 {
@@ -662,6 +683,7 @@ static const struct luaL_Reg lbox_info_dynamic_meta[] = {
 	{"ro_reason", lbox_info_ro_reason},
 	{"replication", lbox_info_replication},
 	{"replication_anon", lbox_info_replication_anon},
+	{"replicaset", lbox_info_replicaset},
 	{"status", lbox_info_status},
 	{"uptime", lbox_info_uptime},
 	{"pid", lbox_info_pid},
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index 4a0c0f6e83..f3a5e2f1ba 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -432,7 +432,7 @@ local function check_instance_uuid()
 end
 
 local function check_replicaset_uuid()
-    if box.cfg.replicaset_uuid ~= box.info.cluster.uuid then
+    if box.cfg.replicaset_uuid ~= box.info.replicaset.uuid then
         box.error(box.error.RELOAD_CFG, 'replicaset_uuid')
     end
 end
diff --git a/src/lua/compat.lua b/src/lua/compat.lua
index ef2d69d189..c690db39e7 100644
--- a/src/lua/compat.lua
+++ b/src/lua/compat.lua
@@ -51,6 +51,13 @@ initialization or new session creation.
 https://tarantool.io/compat/sql_seq_scan_default
 ]]
 
+local BOX_INFO_CLUSTER_MEANING_BRIEF = [[
+Whether box.info.cluster should show the current replicaset or the whole cluster
+with all its replicasets.
+
+https://tarantool.io/compat/box_info_cluster_meaning
+]]
+
 -- Returns an action callback that toggles a tweak.
 local function tweak_action(tweak_name, old_tweak_value, new_tweak_value)
     return function(is_new)
@@ -96,6 +103,12 @@ local options = {
         brief = SQL_SEQ_SCAN_DEFAULT_BRIEF,
         action = tweak_action('sql_seq_scan_default', true, false),
     },
+    box_info_cluster_meaning = {
+        default = 'new',
+        obsolete = nil,
+        brief = BOX_INFO_CLUSTER_MEANING_BRIEF,
+        action = tweak_action('box_info_cluster_new_meaning', false, true),
+    },
 }
 
 -- Array with option names in order of addition.
diff --git a/test/app-tap/gh-5632-6050-6259-gc-buf-reuse.test.lua b/test/app-tap/gh-5632-6050-6259-gc-buf-reuse.test.lua
index 84c2944e52..38db2cb0d3 100755
--- a/test/app-tap/gh-5632-6050-6259-gc-buf-reuse.test.lua
+++ b/test/app-tap/gh-5632-6050-6259-gc-buf-reuse.test.lua
@@ -200,9 +200,9 @@ local function test_info_uuid(test)
 
     local function uuid_to_str()
         local str1 = box.info.uuid
-        local str2 = box.info.cluster.uuid
+        local str2 = box.info.replicaset.uuid
         local str3 = box.info.uuid
-        local str4 = box.info.cluster.uuid
+        local str4 = box.info.replicaset.uuid
         if str1 ~= str3 or str2 ~= str4 then
             is_success = false
         end
diff --git a/test/box-luatest/downgrade_test.lua b/test/box-luatest/downgrade_test.lua
index 71b2f28590..340c7c1738 100644
--- a/test/box-luatest/downgrade_test.lua
+++ b/test/box-luatest/downgrade_test.lua
@@ -896,7 +896,7 @@ g.test_downgrade_replicaset_uuid_key = function(cg)
     cg.server:exec(function()
         local helper = require('test.box-luatest.downgrade_helper')
         local _schema = box.space._schema
-        local rs_uuid = box.info.cluster.uuid
+        local rs_uuid = box.info.replicaset.uuid
         local prev_version = helper.prev_version(helper.app_version('3.0.0'))
         t.assert_equals(box.schema.downgrade_issues(prev_version), {})
         t.assert_equals(_schema:get{'cluster'}, nil)
diff --git a/test/box-luatest/schema_sys_space_test.lua b/test/box-luatest/schema_sys_space_test.lua
index 52eaba8db3..fe5fcfac21 100644
--- a/test/box-luatest/schema_sys_space_test.lua
+++ b/test/box-luatest/schema_sys_space_test.lua
@@ -21,7 +21,7 @@ g.test_replicaset_uuid_update_ban = function(lg)
         t.assert_error_msg_contains(msg, _schema.replace, _schema,
                                     {'replicaset_uuid', tostring(uuid.NULL)})
         -- Fine to replace with the same value.
-        _schema:replace{'replicaset_uuid', box.info.cluster.uuid}
+        _schema:replace{'replicaset_uuid', box.info.replicaset.uuid}
     end)
 end
 
@@ -50,7 +50,7 @@ g.test_old_cluster_uuid_key = function(lg)
         local msg = "Can't reset replica set UUID"
         t.assert_error_msg_contains(msg, _schema.replace, _schema,
                                     {'cluster', uuid.str()})
-        _schema:replace{'cluster', box.info.cluster.uuid}
+        _schema:replace{'cluster', box.info.replicaset.uuid}
         _schema:delete{'cluster'}
     end)
 end
diff --git a/test/box-luatest/upgrade_to_3_0_0_test.lua b/test/box-luatest/upgrade_to_3_0_0_test.lua
index b338f1a9c2..a7f1999f2a 100644
--- a/test/box-luatest/upgrade_to_3_0_0_test.lua
+++ b/test/box-luatest/upgrade_to_3_0_0_test.lua
@@ -23,6 +23,6 @@ g.test_new_replicaset_uuid_key = function(cg)
         local _schema = box.space._schema
         t.assert_equals(_schema:get{'cluster'}, nil)
         t.assert_equals(_schema:get{'replicaset_uuid'}.value,
-                        box.info.cluster.uuid)
+                        box.info.replicaset.uuid)
     end)
 end
diff --git a/test/box-tap/cfg.test.lua b/test/box-tap/cfg.test.lua
index c6f511ec90..cd6706073d 100755
--- a/test/box-tap/cfg.test.lua
+++ b/test/box-tap/cfg.test.lua
@@ -444,7 +444,7 @@ test:is(run_script(code), 0, "check instance_uuid")
 code = [[
 replicaset_uuid = tostring(require('uuid').new())
 box.cfg{replicaset_uuid = replicaset_uuid}
-os.exit(replicaset_uuid == box.info.cluster.uuid and 0 or 1)
+os.exit(replicaset_uuid == box.info.replicaset.uuid and 0 or 1)
 ]]
 test:is(run_script(code), 0, "check replicaset_uuid")
 
diff --git a/test/box/cfg.result b/test/box/cfg.result
index fb3387a5e9..969371e90c 100644
--- a/test/box/cfg.result
+++ b/test/box/cfg.result
@@ -418,7 +418,7 @@ box.cfg{instance_uuid = '12345678-0123-5678-1234-abcdefabcdef'}
  | - error: Can't set option 'instance_uuid' dynamically
  | ...
 
-box.cfg{replicaset_uuid = box.info.cluster.uuid}
+box.cfg{replicaset_uuid = box.info.replicaset.uuid}
  | ---
  | ...
 box.cfg{replicaset_uuid = '12345678-0123-5678-1234-abcdefabcdef'}
diff --git a/test/box/cfg.test.lua b/test/box/cfg.test.lua
index 6342bb3df9..29f0e0a31d 100644
--- a/test/box/cfg.test.lua
+++ b/test/box/cfg.test.lua
@@ -50,7 +50,7 @@ box.cfg{replication_sync_timeout = replication_sync_timeout}
 box.cfg{instance_uuid = box.info.uuid}
 box.cfg{instance_uuid = '12345678-0123-5678-1234-abcdefabcdef'}
 
-box.cfg{replicaset_uuid = box.info.cluster.uuid}
+box.cfg{replicaset_uuid = box.info.replicaset.uuid}
 box.cfg{replicaset_uuid = '12345678-0123-5678-1234-abcdefabcdef'}
 
 box.cfg{memtx_memory = box.cfg.memtx_memory}
diff --git a/test/box/info.result b/test/box/info.result
index 17c365a601..73c8aa48d5 100644
--- a/test/box/info.result
+++ b/test/box/info.result
@@ -59,7 +59,7 @@ string.match(box.info.uptime, '^[1-9][0-9]*$') ~= nil
 ---
 - true
 ...
-box.info.cluster.uuid == box.space._schema:get{'replicaset_uuid'}[2]
+box.info.replicaset.uuid == box.space._schema:get{'replicaset_uuid'}[2]
 ---
 - true
 ...
@@ -83,6 +83,7 @@ t
   - memory
   - package
   - pid
+  - replicaset
   - replication
   - replication_anon
   - ro
@@ -234,3 +235,38 @@ ch:get() -- false
 ---
 - false
 ...
+--
+-- box.info.cluster compat. Before 3.0.0 it meant the current replicaset. Now it
+-- means the whole cluster.
+--
+compat = require('compat')
+---
+...
+info = compat.box_info_cluster_meaning
+---
+...
+assert(info.current == 'default')
+---
+- true
+...
+assert(info.default == 'new')
+---
+- true
+...
+rs_uuid = box.info.replicaset.uuid
+---
+...
+assert(box.info.cluster.uuid ~= rs_uuid)
+---
+- true
+...
+compat.box_info_cluster_meaning = 'old'
+---
+...
+assert(box.info.cluster.uuid == rs_uuid)
+---
+- true
+...
+compat.box_info_cluster_meaning = 'default'
+---
+...
diff --git a/test/box/info.test.lua b/test/box/info.test.lua
index 66935af10f..19056301bd 100644
--- a/test/box/info.test.lua
+++ b/test/box/info.test.lua
@@ -16,7 +16,7 @@ box.info.replication[1].id
 box.info.status
 string.len(box.info.uptime) > 0
 string.match(box.info.uptime, '^[1-9][0-9]*$') ~= nil
-box.info.cluster.uuid == box.space._schema:get{'replicaset_uuid'}[2]
+box.info.replicaset.uuid == box.space._schema:get{'replicaset_uuid'}[2]
 t = {}
 for k, _ in pairs(box.info()) do table.insert(t, k) end
 table.sort(t)
@@ -67,3 +67,17 @@ _ = fiber.create(function() box.ctl.wait_rw() ch:put(box.info.ro) end)
 fiber.sleep(0.001)
 box.cfg{read_only = false}
 ch:get() -- false
+
+--
+-- box.info.cluster compat. Before 3.0.0 it meant the current replicaset. Now it
+-- means the whole cluster.
+--
+compat = require('compat')
+info = compat.box_info_cluster_meaning
+assert(info.current == 'default')
+assert(info.default == 'new')
+rs_uuid = box.info.replicaset.uuid
+assert(box.info.cluster.uuid ~= rs_uuid)
+compat.box_info_cluster_meaning = 'old'
+assert(box.info.cluster.uuid == rs_uuid)
+compat.box_info_cluster_meaning = 'default'
diff --git a/test/replication-luatest/bootstrap_strategy_test.lua b/test/replication-luatest/bootstrap_strategy_test.lua
index 53d455c380..75a88ae663 100644
--- a/test/replication-luatest/bootstrap_strategy_test.lua
+++ b/test/replication-luatest/bootstrap_strategy_test.lua
@@ -388,7 +388,7 @@ g_config_success.test_correct_bootstrap_leader = function(cg)
     cg.replica_set_b:start{}
     cg.replica_set:start{}
     t.helpers.retrying({}, cg.server1.exec, cg.server1, function(uuid)
-        t.assert_equals(box.info.cluster.uuid, uuid,
+        t.assert_equals(box.info.replicaset.uuid, uuid,
                         'Server bootstrapped from correct leader')
     end, {uuidb})
 end
@@ -425,7 +425,7 @@ end)
 g_config_success.test_wait_only_for_leader = function(cg)
     cg.replica_set:start{}
     t.helpers.retrying({}, cg.server1.exec, cg.server1, function(uuid)
-        t.assert_equals(box.info.cluster.uuid, uuid,
+        t.assert_equals(box.info.replicaset.uuid, uuid,
                         'Server boots as soon as sees the leader')
     end, {uuidb})
 end
-- 
GitLab