Skip to content

Commit 8a8a65d

Browse files
committed
create: add config_storage template
Closes #1180 @TarantoolBot document Title: `tt create` support `config_storage` template. Configurable parameters: - Number of instances in replicaset - Interval of status checking
1 parent 32ed4d0 commit 8a8a65d

File tree

9 files changed

+208
-3
lines changed

9 files changed

+208
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
### Added
1111

12+
- `tt create`: add `config_storage` template
13+
1214
### Changed
1315

1416
### Fixed

cli/cmd/create.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ func NewCreateCmd() *cobra.Command {
4444
Built-in templates:
4545
cartridge: a simple Cartridge application.
4646
single_instance: Tarantool 3 application with a single instance configuration.
47-
vshard_cluster: Tarantool 3 vshard cluster application.`,
47+
vshard_cluster: Tarantool 3 vshard cluster application.
48+
config_storage: Tarantool 3 cluster configuration storage.`,
4849
Example: `
4950
# Create an application app1 from a template.
5051
@@ -62,7 +63,11 @@ Built-in templates:
6263
6364
# Create Tarantool 3 vshard cluster.
6465
65-
$ tt create vshard_cluster --name cluster_app`,
66+
$ tt create vshard_cluster --name cluster_app
67+
68+
# Create Tarantool 3 cluster configuration storage.
69+
70+
$ tt create config_storage --name tcs`,
6671
}
6772

6873
createCmd.Flags().StringVarP(&appName, "name", "n", "", "Application name")

cli/cmd/create_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func TestCreateValidArgsFunction(t *testing.T) {
4141
"cartridge",
4242
"vshard_cluster",
4343
"single_instance",
44+
"config_storage",
4445
"archive",
4546
"template2",
4647
tdir1Name,

cli/codegen/generate_code.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ func main() {
136136
if err != nil {
137137
log.Errorf("error while generating file modes: %s", err)
138138
}
139+
err = generateFileModeFile(
140+
"cli/create/builtin_templates/templates/config_storage",
141+
"cli/create/builtin_templates/static/config_storage_template_filemodes_gen.go",
142+
"ConfigStorage",
143+
)
144+
if err != nil {
145+
log.Errorf("error while generating file modes: %s", err)
146+
}
139147

140148
if err = generateLuaCodeVar(); err != nil {
141149
log.Errorf("error while generating lua code string variables: %s", err)

cli/create/builtin_templates/builtin_templates.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ var FileModes = map[string]map[string]int{
1414
"cartridge": static.CartridgeFileModes,
1515
"vshard_cluster": static.VshardClusterFileModes,
1616
"single_instance": static.SingleInstanceFileModes,
17+
"config_storage": static.ConfigStorageFileModes,
1718
}
1819

1920
// Names contains built-in template names.
20-
var Names = [...]string{"cartridge", "vshard_cluster", "single_instance"}
21+
var Names = [...]string{
22+
"cartridge",
23+
"vshard_cluster",
24+
"single_instance",
25+
"config_storage",
26+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
description: Config storage template
2+
follow-up-message: |
3+
What's next?
4+
Start '{{ .name }}' application:
5+
$ tt start {{ .name }}
6+
7+
Pay attention that default passwords were generated,
8+
you can change it in the config.yaml.
9+
10+
vars:
11+
- prompt: Storages replicas (odd, >=3)
12+
name: replicas_count
13+
default: '3'
14+
re: ^([3579]|[1-9]\d*[13579])$
15+
16+
- prompt: Status check interval
17+
name: status_check_interval
18+
default: '5'
19+
re: ^[1-9]\d*$
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
credentials:
2+
users:
3+
replicator:
4+
password: 'topsecret'
5+
roles: [replication]
6+
client:
7+
password: 'secret'
8+
privileges:
9+
- permissions: [execute]
10+
lua_call:
11+
- config.storage.get
12+
- config.storage.put
13+
- config.storage.delete
14+
- config.storage.keepalive
15+
- config.storage.txn
16+
- config.storage.info
17+
# Not necessary since tarantool 3.5.0, 3.4.1, 3.3.3, 3.2.2.
18+
- permissions: [read, write]
19+
spaces: [config_storage, config_storage_meta]
20+
21+
iproto:
22+
advertise:
23+
peer:
24+
login: replicator
25+
26+
replication:
27+
failover: election
28+
29+
database:
30+
use_mvcc_engine: true
31+
32+
groups:
33+
group-001:
34+
replicasets:
35+
{{- $status_check_interval := atoi .status_check_interval}}
36+
{{- $replicas := atoi .replicas_count}}
37+
{{- range replicasets "replicaset" 1 $replicas}}
38+
{{.Name}}:
39+
roles: [config.storage]
40+
roles_cfg:
41+
config.storage:
42+
status_check_interval: {{$status_check_interval}}
43+
instances:
44+
{{- range .InstNames}}
45+
{{.}}:
46+
iproto:
47+
listen:
48+
- uri: 127.0.0.1:{{port}}
49+
{{- end}}
50+
{{- end}}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
{{- $replicas := atoi .replicas_count}}
3+
{{- range replicasets "replicaset" 1 $replicas}}
4+
{{- range .InstNames}}
5+
{{.}}:
6+
{{- end}}
7+
{{- end}}

test/integration/create/test_create.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
run_command_and_get_output,
1616
wait_event,
1717
wait_file,
18+
wait_files,
1819
)
1920

2021
tt_config_text = """env:
@@ -1051,3 +1052,109 @@ def select_data_func():
10511052
# Assert here to be sure that instances are stopped.
10521053
assert can_insert, "can not insert data into the vshard cluster"
10531054
assert can_select, "can not select data from the vhsard cluster"
1055+
1056+
1057+
@pytest.mark.slow
1058+
@pytest.mark.skipif(
1059+
tarantool_major_version < 3,
1060+
reason="skip centralized config test for Tarantool < 3",
1061+
)
1062+
@pytest.mark.parametrize("num_replicas", [None, 3, 5])
1063+
def test_create_app_from_builtin_config_storage_template(tt_cmd, tmp_path, num_replicas):
1064+
with open(os.path.join(tmp_path, config_name), "w") as tnt_env_file:
1065+
tnt_env_file.write(tt_config_text.format(tmp_path))
1066+
1067+
create_cmd = [tt_cmd, "create", "config_storage", "--name", "app1"]
1068+
tt_process = subprocess.Popen(
1069+
create_cmd,
1070+
cwd=tmp_path,
1071+
stderr=subprocess.STDOUT,
1072+
stdout=subprocess.PIPE,
1073+
stdin=subprocess.PIPE,
1074+
text=True,
1075+
)
1076+
if num_replicas is None:
1077+
tt_process.stdin.writelines(["\n", "\n"])
1078+
else:
1079+
tt_process.stdin.writelines([f"{num_replicas}\n", "\n"])
1080+
tt_process.stdin.close()
1081+
tt_process.wait()
1082+
output = tt_process.stdout.read()
1083+
assert tt_process.returncode == 0
1084+
assert "Application 'app1' created successfully" in output
1085+
1086+
app_path = tmp_path / "app1"
1087+
assert os.path.exists(app_path / "config.yaml")
1088+
assert os.path.exists(app_path / "instances.yaml")
1089+
1090+
# Start app.
1091+
start_cmd = [tt_cmd, "start", "app1"]
1092+
instance_process = subprocess.Popen(
1093+
start_cmd,
1094+
cwd=tmp_path,
1095+
stderr=subprocess.STDOUT,
1096+
stdout=subprocess.PIPE,
1097+
text=True,
1098+
)
1099+
start_output = instance_process.stdout.readlines()
1100+
for line in start_output:
1101+
assert "Starting an instance" in line
1102+
if num_replicas is None:
1103+
num_replicas = 3
1104+
instances = [f"replicaset-001-{chr(ord('a')+i)}" for i in range(num_replicas)]
1105+
pid_files = [os.path.join(tmp_path, "app1", inst) for inst in instances]
1106+
assert wait_files(10, pid_files)
1107+
1108+
# Check status.
1109+
status_cmd = [tt_cmd, "status", "app1"]
1110+
status_rc, status_out = run_command_and_get_output(status_cmd, cwd=tmp_path)
1111+
assert status_rc == 0
1112+
status_info = extract_status(status_out)
1113+
for key in status_info.keys():
1114+
assert status_info[key]["STATUS"] == "RUNNING"
1115+
1116+
# def eval_cmd_func(inst, cmd):
1117+
# connect_process = subprocess.Popen(
1118+
# [tt_cmd, "connect", f"app1:{inst}", "-f-"],
1119+
# cwd=tmp_path,
1120+
# stdin=subprocess.PIPE,
1121+
# stderr=subprocess.STDOUT,
1122+
# stdout=subprocess.PIPE,
1123+
# text=True,
1124+
# )
1125+
# connect_process.stdin.write(cmd)
1126+
# connect_process.stdin.close()
1127+
# connect_process.wait()
1128+
# return connect_process.stdout.read()
1129+
1130+
# def insert_data_func():
1131+
# out = eval_cmd_func("router-001-a", "put_sample_data()")
1132+
# return out == "---\n...\n\n"
1133+
1134+
# def select_data_func():
1135+
# out = eval_cmd_func("router-001-a", "get(1)")
1136+
# return out.find("[1, 'Elizabeth', 12]") != -1
1137+
1138+
# # Check that data can be inserted and selected.
1139+
# can_insert = wait_event(60, insert_data_func)
1140+
# can_select = False
1141+
# if can_insert:
1142+
# can_select = wait_event(60, select_data_func)
1143+
1144+
# # Print instances log to find out the reason in case of an assert fall.
1145+
# for inst in instances:
1146+
# with open(os.path.join(tmp_path, "app1", inst, "tt.log")) as f:
1147+
# print(inst, f.read())
1148+
1149+
# # Stop the vhsard_cluster app.
1150+
# stop_cmd = [tt_cmd, "stop", "--yes", "app1"]
1151+
# stop_rc, stop_out = run_command_and_get_output(stop_cmd, cwd=tmp_path)
1152+
# assert stop_rc == 0
1153+
# for inst in instances:
1154+
# assert re.search(rf"The Instance app1:{inst} \(PID = \d+\) has been terminated.", stop_out)
1155+
1156+
# with open(app_path / "router-001-a" / "tt.log") as f:
1157+
# print("\n".join(f.readlines()))
1158+
# # Assert here to be sure that instances are stopped.
1159+
# assert can_insert, "can not insert data into the vshard cluster"
1160+
# assert can_select, "can not select data from the vhsard cluster"

0 commit comments

Comments
 (0)