Skip to content

Commit 68d897d

Browse files
authored
V2.3.0 (#177)
* V2.3.0 * V2.3.0 * update docs
1 parent d84e56c commit 68d897d

File tree

129 files changed

+11550
-4042
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+11550
-4042
lines changed

_cmd.py

+103-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
from uuid import uuid1 as uuid, UUID
3030
from optparse import OptionParser, BadOptionError, Option, IndentedHelpFormatter
3131

32+
from colorama import Fore
33+
3234
from core import ObdHome
33-
from _stdio import IO
35+
from _stdio import IO, FormtatText
3436
from _lock import LockMode
3537
from tool import DirectoryUtil, FileUtil, NetUtil, COMMAND_ENV
3638
from _errno import DOC_LINK_MSG, LockError
@@ -780,6 +782,8 @@ def _do_command(self, obd):
780782
obd.set_options(self.opts)
781783
res = obd.deploy_cluster(self.cmds[0])
782784
self.background_telemetry_task(obd)
785+
if res:
786+
obd.stdio.print(FormtatText('Please execute ` obd cluster start %s ` to start' % self.cmds[0], Fore.GREEN))
783787
return res
784788
else:
785789
return self._show_help()
@@ -826,6 +830,7 @@ class ClusterDestroyCommand(ClusterMirrorCommand):
826830
def __init__(self):
827831
super(ClusterDestroyCommand, self).__init__('destroy', 'Destroy a deployed cluster.')
828832
self.parser.add_option('-f', '--force-kill', action='store_true', help="Force kill the running observer process in the working directory.")
833+
self.parser.add_option('--ignore-standby', '--igs', action='store_true', help="Force kill the observer while standby tenant in others cluster exists.")
829834

830835
def _do_command(self, obd):
831836
if self.cmds:
@@ -873,6 +878,7 @@ def __init__(self):
873878
super(ClusterRedeployCommand, self).__init__('redeploy', 'Redeploy a started cluster.')
874879
self.parser.add_option('-f', '--force-kill', action='store_true', help="Force kill the running observer process in the working directory.")
875880
self.parser.add_option('--confirm', action='store_true', help='Confirm to redeploy.')
881+
self.parser.add_option('--ignore-standby', '--igs', action='store_true', help="Force kill the observer while standby tenant in others cluster exists.")
876882

877883
def _do_command(self, obd):
878884
if self.cmds:
@@ -951,6 +957,7 @@ def __init__(self):
951957
self.parser.add_option('--disable', type='string', help="Hash list for disabled mirrors, separated with `,`.", default='')
952958
self.parser.add_option('-e', '--executer-path', type='string', help="Executer path.", default=os.path.join(ObdCommand.OBD_INSTALL_PATH, 'lib/executer'))
953959
self.parser.add_option('-t', '--script-query-timeout', type='string', help="The timeout(s) for executing sql in upgrade scripts. Supported since version 4.1.0", default='')
960+
self.parser.add_option('--ignore-standby', '--igs', action='store_true', help="Force upgrade, before upgrade standby tenant`s cluster.")
954961

955962
def _do_command(self, obd):
956963
if self.cmds:
@@ -996,11 +1003,100 @@ def _do_command(self, obd):
9961003
return self._show_help()
9971004

9981005

1006+
class ClusterTenantCreateStandByCommand(ClusterTenantCreateCommand):
1007+
1008+
def __init__(self):
1009+
super(ClusterTenantCreateStandByCommand, self).__init__()
1010+
self.name = 'create-standby'
1011+
self.summary = 'Create a standby tenant.'
1012+
self.parser.remove_option('-t')
1013+
self.parser.remove_option('--max-memory')
1014+
self.parser.remove_option('--min-memory')
1015+
self.parser.remove_option('--max-disk-size')
1016+
self.parser.remove_option('--max-session-num')
1017+
self.parser.remove_option('--mode')
1018+
self.parser.remove_option('--charset')
1019+
self.parser.remove_option('--collate')
1020+
self.parser.remove_option('--logonly-replica-num')
1021+
self.parser.remove_option('--tablegroup')
1022+
self.parser.remove_option('-s')
1023+
self.parser.add_option('-t', '-n', '--tenant-name', type='string', help="The standby tenant name. The default tenant name is consistent with the primary tenant name.", default='')
1024+
self.parser.add_option('--standbyro-password', type='string', help="standbyro user password.")
1025+
self.parser.add_option('-p', '--tenant-root-password', type='string', help="tenant root password,for crate standby user.")
1026+
1027+
1028+
def init(self, cmd, args):
1029+
super(ClusterTenantCreateStandByCommand, self).init(cmd, args)
1030+
self.parser.set_usage('%s <standby deploy name> <primary deploy name> <primary tenant name> [options]' % self.prev_cmd)
1031+
return self
1032+
1033+
def _do_command(self, obd):
1034+
if len(self.cmds) == 3:
1035+
return obd.create_standby_tenant(self.cmds[0], self.cmds[1], self.cmds[2])
1036+
else:
1037+
return self._show_help()
1038+
1039+
1040+
class ClusterTenantSwitchoverCommand(ClusterMirrorCommand):
1041+
1042+
def __init__(self):
1043+
super(ClusterTenantSwitchoverCommand, self).__init__('switchover', 'Switchover primary-standby tenant.')
1044+
self.parser.add_option('-p', '--tenant-root-password', type='string', help="tenant root password")
1045+
self.parser.add_option('--standbyro-password', type='string', help="standbyro user password.")
1046+
1047+
def init(self, cmd, args):
1048+
super(ClusterTenantSwitchoverCommand, self).init(cmd, args)
1049+
self.parser.set_usage('%s <standby deploy name> <standby tenant name> [options]' % self.prev_cmd)
1050+
return self
1051+
1052+
def _do_command(self, obd):
1053+
if len(self.cmds) == 2:
1054+
return obd.switchover_tenant(self.cmds[0], self.cmds[1])
1055+
else:
1056+
return self._show_help()
1057+
1058+
1059+
class ClusterTenantFailoverCommand(ClusterMirrorCommand):
1060+
def __init__(self):
1061+
super(ClusterTenantFailoverCommand, self).__init__('failover', 'failover standby tenant.')
1062+
self.parser.add_option('-p', '--tenant-root-password', type='string', help="tenant root password")
1063+
1064+
def init(self, cmd, args):
1065+
super(ClusterTenantFailoverCommand, self).init(cmd, args)
1066+
self.parser.set_usage('%s <standby deploy name> <standby tenant name> [options]' % self.prev_cmd)
1067+
return self
1068+
1069+
def _do_command(self, obd):
1070+
if len(self.cmds) == 2:
1071+
return obd.failover_decouple_tenant(self.cmds[0], self.cmds[1], 'failover')
1072+
else:
1073+
return self._show_help()
1074+
1075+
1076+
class ClusterTenantDecoupleCommand(ClusterMirrorCommand):
1077+
1078+
def __init__(self):
1079+
super(ClusterTenantDecoupleCommand, self).__init__('decouple', 'decouple standby tenant.')
1080+
self.parser.add_option('-p', '--tenant-root-password', type='string', help="tenant root password")
1081+
1082+
def init(self, cmd, args):
1083+
super(ClusterTenantDecoupleCommand, self).init(cmd, args)
1084+
self.parser.set_usage('%s <standby deploy name> <standby tenant name> [options]' % self.prev_cmd)
1085+
return self
1086+
1087+
def _do_command(self, obd):
1088+
if len(self.cmds) == 2:
1089+
return obd.failover_decouple_tenant(self.cmds[0], self.cmds[1], 'decouple')
1090+
else:
1091+
return self._show_help()
1092+
1093+
9991094
class ClusterTenantDropCommand(ClusterMirrorCommand):
10001095

10011096
def __init__(self):
10021097
super(ClusterTenantDropCommand, self).__init__('drop', 'Drop a tenant.')
10031098
self.parser.add_option('-t', '-n', '--tenant-name', type='string', help="Tenant name.")
1099+
self.parser.add_option('--ignore-standby', '--igs', action='store_true', help="Force drop tenant when it has standby tenant, the standby tenants will become unavailable.")
10041100

10051101
def _do_command(self, obd):
10061102
if self.cmds:
@@ -1013,6 +1109,8 @@ class ClusterTenantListCommand(ClusterMirrorCommand):
10131109

10141110
def __init__(self):
10151111
super(ClusterTenantListCommand, self).__init__('show', 'Show the list of tenant.')
1112+
self.parser.add_option('-t', '--tenant', type='string', help='Tenant name', default='')
1113+
self.parser.add_option('-g', '--graph', action='store_true', help='view standby by graph')
10161114

10171115
def _do_command(self, obd):
10181116
if self.cmds:
@@ -1028,6 +1126,10 @@ def __init__(self):
10281126
self.register_command(ClusterTenantCreateCommand())
10291127
self.register_command(ClusterTenantDropCommand())
10301128
self.register_command(ClusterTenantListCommand())
1129+
self.register_command(ClusterTenantCreateStandByCommand())
1130+
self.register_command(ClusterTenantSwitchoverCommand())
1131+
self.register_command(ClusterTenantFailoverCommand())
1132+
self.register_command(ClusterTenantDecoupleCommand())
10311133

10321134

10331135
class ClusterMajorCommand(MajorCommand):

_deploy.py

+99-25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020

2121
from __future__ import absolute_import, division, print_function
22+
from collections.abc import Iterable, Iterator
2223

2324
import os
2425
import re
@@ -111,48 +112,107 @@ class InnerConfigItem(str):
111112
pass
112113

113114

115+
class InnerConfigKey(object):
116+
117+
keyword_symbol = "$_"
118+
119+
@classmethod
120+
def is_keyword(cls, s):
121+
return s.startswith(cls.keyword_symbol)
122+
123+
@classmethod
124+
def to_keyword(cls, key):
125+
return "{}{}".format(cls.keyword_symbol, key)
126+
127+
@classmethod
128+
def keyword_to_str(cls, _keyword):
129+
return str(_keyword.replace(cls.keyword_symbol, '', 1))
130+
131+
132+
class ComponentInnerConfig(dict):
133+
134+
COMPONENT_GLOBAL_ATTRS = InnerConfigKey.to_keyword('component_global_attrs')
135+
136+
def __init__(self, component_name, config):
137+
super(ComponentInnerConfig, self).__init__()
138+
self.component_name = component_name
139+
c_config = {}
140+
for server in config:
141+
i_config = {}
142+
s_config = config[server]
143+
for key in s_config:
144+
i_config[InnerConfigItem(key)] = s_config[key]
145+
c_config[server] = i_config
146+
self.update(c_config)
147+
148+
def __iter__(self):
149+
keys = self.keys()
150+
servers = []
151+
for key in keys:
152+
if key != self.COMPONENT_GLOBAL_ATTRS:
153+
servers.append(key)
154+
return iter(servers)
155+
156+
def update_server_config(self, server, key, value):
157+
self._update_config(server, key, value)
158+
159+
def update_attr(self, key, value):
160+
self._update_config(self.COMPONENT_GLOBAL_ATTRS, key, value)
161+
162+
def del_server_config(self, server, key):
163+
self._del_config(server, key)
164+
165+
def del_attr(self, key):
166+
self._del_config(self.COMPONENT_GLOBAL_ATTRS, key)
167+
168+
def get_attr(self, key):
169+
return self._get_config(self.COMPONENT_GLOBAL_ATTRS, key)
170+
171+
def _update_config(self, item, key, value):
172+
if not self.__contains__(item):
173+
self[item] = {}
174+
if not InnerConfigKey.is_keyword(key):
175+
key = InnerConfigKey.to_keyword(key)
176+
self[item][key] = value
177+
178+
def _del_config(self, item, key):
179+
if not self.__contains__(item):
180+
return
181+
if not InnerConfigKey.is_keyword(key):
182+
key = InnerConfigKey.to_keyword(key)
183+
if key in self[item]:
184+
del self[item][key]
185+
186+
def _get_config(self, item, key):
187+
if not self.__contains__(item):
188+
return
189+
if not InnerConfigKey.is_keyword(key):
190+
key = InnerConfigKey.to_keyword(key)
191+
return self[item].get(key)
192+
114193
class InnerConfigKeywords(object):
115194

116195
DEPLOY_INSTALL_MODE = 'deploy_install_mode'
117196
DEPLOY_BASE_DIR = 'deploy_base_dir'
118197

119-
120198
class InnerConfig(object):
121199

122-
keyword_symbol = "$_"
123-
124200
def __init__(self, path, yaml_loader):
125201
self.path = path
126202
self.yaml_loader = yaml_loader
127203
self.config = {}
128204
self._load()
129205

130-
def is_keyword(self, s):
131-
return s.startswith(self.keyword_symbol)
132-
133-
def to_keyword(self, key):
134-
return "{}{}".format(self.keyword_symbol, key)
135-
136-
def keyword_to_str(self, _keyword):
137-
return str(_keyword.replace(self.keyword_symbol, '', 1))
138-
139206
def _load(self):
140207
self.config = {}
141208
try:
142209
with FileUtil.open(self.path, 'rb') as f:
143210
config = self.yaml_loader.load(f)
144211
for component_name in config:
145-
if self.is_keyword(component_name):
212+
if InnerConfigKey.is_keyword(component_name):
146213
self.config[InnerConfigItem(component_name)] = config[component_name]
147-
continue
148-
self.config[component_name] = {}
149-
c_config = config[component_name]
150-
for server in c_config:
151-
i_config = {}
152-
s_config = c_config[server]
153-
for key in s_config:
154-
i_config[InnerConfigItem(key)] = s_config[key]
155-
self.config[component_name][server] = i_config
214+
else:
215+
self.config[component_name] = ComponentInnerConfig(component_name, config[component_name])
156216
except:
157217
pass
158218

@@ -176,11 +236,11 @@ def get_server_config(self, component_name, server):
176236
return self.get_component_config(component_name).get(server, {})
177237

178238
def get_global_config(self, key, default=None):
179-
key = self.to_keyword(key)
239+
key = InnerConfigKey.to_keyword(key)
180240
return self.config.get(key, default)
181241

182242
def update_global_config(self, key, value):
183-
self.config[self.to_keyword(key)] = value
243+
self.config[InnerConfigKey.to_keyword(key)] = value
184244

185245
def update_component_config(self, component_name, config):
186246
self.config[component_name] = {}
@@ -192,6 +252,8 @@ def update_component_config(self, component_name, config):
192252
key = InnerConfigItem(key)
193253
c_config[key] = data[key]
194254
self.config[component_name][server] = c_config
255+
if ComponentInnerConfig.COMPONENT_GLOBAL_ATTRS in config:
256+
self.config[component_name][ComponentInnerConfig.COMPONENT_GLOBAL_ATTRS] = config[ComponentInnerConfig.COMPONENT_GLOBAL_ATTRS]
195257

196258

197259
class ConfigParser(object):
@@ -449,6 +511,10 @@ def set_base_dir(self, base_dir):
449511
self._include_config = None
450512
self._global_conf = None
451513

514+
@property
515+
def deploy_name(self):
516+
return self._deploy_config.name
517+
452518
@property
453519
def original_servers(self):
454520
return self._original_servers
@@ -465,7 +531,14 @@ def _clear_cache_server(self):
465531

466532
def get_inner_config(self):
467533
return self._inner_config
468-
534+
535+
def update_component_attr(self, key, value, save=True):
536+
self._inner_config.update_attr(key, value)
537+
return self._deploy_config.dump() if save else True
538+
539+
def get_component_attr(self, key):
540+
return self._inner_config.get_attr(key)
541+
469542
def is_cp_install_mode(self):
470543
return self._deploy_config.is_cp_install_mode()
471544

@@ -889,6 +962,7 @@ def __init__(self, yaml_path, yaml_loader=yaml, inner_config=None, config_parser
889962
self._inner_config = inner_config
890963
self.components = OrderedDict()
891964
self._src_data = None
965+
self.name = os.path.split(os.path.split(yaml_path)[0])[-1]
892966
self.yaml_path = yaml_path
893967
self.yaml_loader = yaml_loader
894968
self.config_parser_manager = config_parser_manager if config_parser_manager else DEFAULT_CONFIG_PARSER_MANAGER

0 commit comments

Comments
 (0)