Skip to content

Commit 9c813a0

Browse files
committed
Dev 3.4.0
1 parent 475d8cb commit 9c813a0

87 files changed

Lines changed: 2156 additions & 409 deletions

File tree

Some content is hidden

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

_cmd.py

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -740,9 +740,12 @@ def __init__(self):
740740

741741
class ClusterMirrorCommand(ObdCommand):
742742

743-
def init(self, cmd, args):
743+
def init(self, cmd, args, need_deploy_name=True):
744744
super(ClusterMirrorCommand, self).init(cmd, args)
745-
self.parser.set_usage('%s <deploy name> [options]' % self.prev_cmd)
745+
usage = '%s <deploy name> [options]'
746+
if not need_deploy_name:
747+
usage = '%s [options]'
748+
self.parser.set_usage(usage % self.prev_cmd)
746749
return self
747750

748751
def get_obd_namespaces_data(self, obd):
@@ -837,6 +840,10 @@ def __init__(self):
837840
self.parser.allow_undefine = True
838841
self.parser.undefine_warn = False
839842

843+
def init(self, cmd, args, need_deploy_name=False):
844+
super(DemoCommand, self).init(cmd, args, need_deploy_name)
845+
return self
846+
840847
def _do_command(self, obd):
841848
setattr(self.opts, 'force', True)
842849
setattr(self.opts, 'clean', True)
@@ -849,6 +856,33 @@ def _do_command(self, obd):
849856
return res
850857

851858

859+
class PrefCommand(ClusterMirrorCommand):
860+
861+
def __init__(self):
862+
super(PrefCommand, self).__init__('pref', 'Quickly start')
863+
self.parser.add_option('-c', '--components', type='string', help="List the components. Multiple components are separated with commas. [oceanbase-ce,obproxy-ce,obagent,prometheus,grafana,ob-configserver]\nExample: \nstart oceanbase-ce: obd demo -c oceanbase-ce\n"
864+
+ "start -c oceanbase-ce V3.2.3: obd pref -c oceanbase-ce --oceanbase-ce.version=3.2.3\n"
865+
+ "start oceanbase-ce and obproxy-ce: obd pref -c oceanbase-ce,obproxy-ce", default='oceanbase-ce,obproxy-ce,obagent,prometheus,grafana')
866+
self.parser.allow_undefine = True
867+
self.parser.undefine_warn = False
868+
869+
def init(self, cmd, args, need_deploy_name=False):
870+
super(PrefCommand, self).init(cmd, args, need_deploy_name)
871+
return self
872+
873+
def _do_command(self, obd):
874+
setattr(self.opts, 'force', True)
875+
setattr(self.opts, 'clean', True)
876+
setattr(self.opts, 'force', True)
877+
setattr(self.opts, 'force_delete', True)
878+
setattr(self.opts, 'max', True)
879+
obd.set_options(self.opts)
880+
881+
res = obd.demo(name='pref')
882+
self.background_telemetry_task(obd, 'pref')
883+
return res
884+
885+
852886
class WebCommand(ObdCommand):
853887

854888
def __init__(self):
@@ -916,20 +950,25 @@ def __init__(self):
916950
self.parser.add_option('-C', '--clean', action='store_true', help="Clean the home path if the directory belong to you.", default=False)
917951
self.parser.add_option('-U', '--unuselibrepo', '--ulp', action='store_true', help="Disable OBD from installing the libs mirror automatically.")
918952
self.parser.add_option('-A', '--auto-create-tenant', '--act', action='store_true', help="Automatically create a tenant named `test` by using all the available resource of the cluster.")
953+
self.parser.add_option('-i', '--interactive', action='store_true', help="Interactive deployment cluster, including deployment and startup.")
919954
# self.parser.add_option('-F', '--fuzzymatch', action='store_true', help="enable fuzzy match when search package")
920955

921956
def _do_command(self, obd):
922-
if self.cmds:
923-
if getattr(self.opts, 'force', False) or getattr(self.opts, 'clean', False):
924-
setattr(self.opts, 'skip_cluster_status_check', True)
925-
obd.set_options(self.opts)
926-
res = obd.deploy_cluster(self.cmds[0])
927-
self.background_telemetry_task(obd)
928-
if res and COMMAND_ENV.get(const.INTERACTIVE_INSTALL, '0') == '0':
929-
obd.stdio.print(FormatText.success('Please execute ` obd cluster start %s ` to start' % self.cmds[0]))
930-
return res
957+
if getattr(self.opts, 'interactive'):
958+
name = self.cmds[0] if self.cmds else ''
959+
return obd.interactive_deploy(name)
931960
else:
932-
return self._show_help()
961+
if self.cmds:
962+
if getattr(self.opts, 'force', False) or getattr(self.opts, 'clean', False):
963+
setattr(self.opts, 'skip_cluster_status_check', True)
964+
obd.set_options(self.opts)
965+
res = obd.deploy_cluster(self.cmds[0])
966+
self.background_telemetry_task(obd)
967+
if res and COMMAND_ENV.get(const.INTERACTIVE_INSTALL, '0') == '0':
968+
obd.stdio.print(FormatText.success('Please execute ` obd cluster start %s ` to start' % self.cmds[0]))
969+
return res
970+
else:
971+
return self._show_help()
933972

934973

935974
class ClusterScaleoutCommand(ClusterMirrorCommand):
@@ -2803,6 +2842,7 @@ def __init__(self):
28032842
super(MainCommand, self).__init__('obd', '')
28042843
self.register_command(DevModeMajorCommand())
28052844
self.register_command(DemoCommand())
2845+
self.register_command(PrefCommand())
28062846
self.register_command(WebCommand())
28072847
self.register_command(MirrorMajorCommand())
28082848
self.register_command(ClusterMajorCommand())

_repository.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ def load_pkg(self, pkg, plugin):
424424
ParallerExtractor(pkg, need_extract_files, stdio=self.stdio).extract()
425425

426426
for link in links:
427+
directory = os.path.dirname(link)
428+
os.makedirs(directory, exist_ok=True)
427429
self.stdio and getattr(self.stdio, 'verbose', print)('link %s to %s' % (links[link], link))
428430
os.symlink(links[link], link)
429431
for n_dir in need_dirs:

_stdio.py

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import inspect2
2525
import six
2626
import logging
27+
import ast
2728
from copy import deepcopy
2829
from logging import handlers
2930

@@ -698,11 +699,16 @@ def read(self, msg='', blocked=False):
698699
self._print(MsgLevel.INFO, msg, end='')
699700
return self.get_input_stream().readline(not self.syncing and blocked)
700701

701-
def confirm(self, msg):
702+
def confirm(self, msg, default_option=''):
702703
if self.default_confirm:
703704
self.verbose("%s and then auto confirm yes" % msg)
704705
return True
705-
msg = '%s [y/n]: ' % msg
706+
if default_option is False:
707+
msg = '%s [y/n] [Default: n]: ' % msg
708+
elif default_option is True:
709+
msg = '%s [y/n] [Default: y]: ' % msg
710+
else:
711+
msg = '%s [y/n]: ' % msg
706712
self.print(msg, end='')
707713
if self.isatty() and not self.syncing:
708714
while True:
@@ -712,6 +718,10 @@ def confirm(self, msg):
712718
return True
713719
if ans == 'n':
714720
return False
721+
if default_option is True:
722+
return True
723+
if default_option is False:
724+
return False
715725
except Exception as e:
716726
if not e:
717727
return False
@@ -758,7 +768,7 @@ def _print(self, msg_lv, msg, *args, **kwargs):
758768
print_msg = pattern.sub(replacement, print_msg)
759769
kwargs['file'] and print(self._format(print_msg, *args), **kwargs)
760770
del kwargs['file']
761-
enaable_log and self.log(msg_lv, msg, *args, **kwargs)
771+
enaable_log and self.log(msg_lv, print_msg, *args, **kwargs)
762772

763773
def log(self, levelno, msg, *args, **kwargs):
764774
msg = self.log_masking(msg)
@@ -877,8 +887,11 @@ def contains_keys(msg):
877887
passkey_pattern = re.compile(passkey_regex)
878888
if passkey_pattern.search(msg):
879889
return passkey_pattern.sub(r'\1******', msg)
890+
891+
if "IDENTIFIED BY" in msg:
892+
return desensitize_sql_pwd(msg)
880893

881-
pwd_args_regex = r"(IDENTIFIED BY \S+.*args:\s*\[['\"]?|_password \S+.*args:\s*\[['\"]?)([^\s'\"']+)(['\"]*)"
894+
pwd_args_regex = r"(_password \S+.*args:\s*\[['\"]?)([^\s'\"']+)(['\"]*)"
882895
arg_pattern = re.compile(pwd_args_regex)
883896
if arg_pattern.search(msg):
884897
return arg_pattern.sub(r"\1******\3", msg)
@@ -932,7 +945,10 @@ def log_masking(self, msg):
932945
if passkey_pattern.search(msg):
933946
return passkey_pattern.sub(r'\1******', msg)
934947

935-
pwd_args_regex = r"(IDENTIFIED BY \S+.*args:\s*\[['\"]?|_password \S+.*args:\s*\[['\"]?)([^\s'\"']+)(['\"]*)"
948+
if "IDENTIFIED BY" in msg:
949+
return desensitize_sql_pwd(msg)
950+
951+
pwd_args_regex = r"(_password \S+.*args:\s*\[['\"]?)([^\s'\"']+)(['\"]*)"
936952
arg_pattern = re.compile(pwd_args_regex)
937953
if arg_pattern.search(msg):
938954
return arg_pattern.sub(r"\1******\3", msg)
@@ -1101,6 +1117,32 @@ def func_wrapper(*args, **kwargs):
11011117
return _type(func) if is_bond_method else func
11021118
return decorated
11031119

1120+
def desensitize_sql_pwd(sql_str):
1121+
if 'IDENTIFIED BY "' in sql_str:
1122+
pattern = r'(IDENTIFIED BY\s*)"[^"]*"'
1123+
replacement = r'\1"******"'
1124+
return re.sub(pattern, replacement, sql_str)
1125+
1126+
if 'IDENTIFIED BY %s' in sql_str:
1127+
args_match = re.search(r'args:\s*(\[.*\])', sql_str)
1128+
if not args_match:
1129+
return sql_str
1130+
1131+
try:
1132+
args_str = args_match.group(1)
1133+
args_list = ast.literal_eval(args_str)
1134+
identified_by_index = sql_str.index('IDENTIFIED BY %s')
1135+
prefix = sql_str[:identified_by_index]
1136+
placeholder_count = prefix.count('%s')
1137+
1138+
if placeholder_count < len(args_list):
1139+
args_list[placeholder_count] = '******'
1140+
new_args_str = str(args_list)
1141+
return sql_str.replace(args_str, new_args_str)
1142+
except (SyntaxError, ValueError):
1143+
pass
1144+
1145+
return sql_str
11041146

11051147
class SafeStdioMeta(type):
11061148

_tool.py

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
from _manager import Manager
2121
from _rpm import PackageInfo
22-
from _stdio import SafeStdio
22+
from _stdio import SafeStdio, FormatText
2323
from tool import YamlLoader, DirectoryUtil
2424
from const import COMP_OBCLIENT, COMP_OCEANBASE_DIAGNOSTIC_TOOL, COMP_OBDIAG, TOOL_TPCH, TOOL_TPCC, TOOL_SYSBENCH, COMP_JRE
2525

@@ -229,4 +229,61 @@ def is_tool_install(self, name):
229229
def check_if_avaliable_update(self, tool, package):
230230
if package.version > tool.config.version:
231231
return True
232-
return False
232+
return False
233+
234+
def ln_to_global(self, client, tool_path, tool_name, stdio):
235+
link_name = f'/usr/local/bin/{tool_name}'
236+
if client.config.username == 'root':
237+
cmd = f'ln -s {tool_path} {link_name}'
238+
else:
239+
cmd = f'sudo ln -s {tool_path} {link_name}'
240+
ret = client.execute_command(cmd, stdio=stdio)
241+
return ret
242+
243+
def unln_to_global(self, client, tool_name, stdio):
244+
link_name = f'/usr/local/bin/{tool_name}'
245+
if client.config.username == 'root':
246+
cmd = f'unlink {link_name}'
247+
else:
248+
cmd = f'sudo -s unlink {link_name}'
249+
return client.execute_command(cmd, stdio=stdio)
250+
251+
252+
def add_path_to_bash_profile(self, path, stdio):
253+
home_dir = os.getenv('HOME')
254+
bash_profile_path = os.path.join(home_dir, '.bash_profile')
255+
with open(bash_profile_path, 'r') as file:
256+
content = file.readlines()
257+
path_exists = any(
258+
f'PATH={x.strip()}'
259+
for x in content
260+
if 'PATH=' in x and path in x
261+
)
262+
if not path_exists:
263+
with open(bash_profile_path, 'a') as file:
264+
file.write(f'\nexport PATH="$PATH:{path}"\n')
265+
stdio.print(FormatText.info("Please source ~/.bash_profile to enable it"))
266+
267+
def remove_path_from_bash_profile(self, path):
268+
home_dir = os.getenv('HOME')
269+
bash_profile_path = os.path.join(home_dir, '.bash_profile')
270+
with open(bash_profile_path, 'r') as file:
271+
content = file.readlines()
272+
273+
new_content = []
274+
path_found = False
275+
for line in content:
276+
if line.startswith("export PATH="):
277+
line = line.strip()
278+
line_content = line.split('=', 1)[1].strip('"')
279+
paths = line_content.split(':')
280+
if path in paths:
281+
paths.remove(path)
282+
path_found = True
283+
new_line = f'export PATH="{":".join(paths)}"\n'
284+
new_content.append(new_line)
285+
else:
286+
new_content.append(line)
287+
if path_found:
288+
with open(bash_profile_path, 'w') as file:
289+
file.writelines(new_content)

_types.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ def _format(self):
237237
if not self._origin:
238238
self.value = '0M'
239239

240-
241240
class StringList(ConfigItemType):
242241

243242
def _format(self):

0 commit comments

Comments
 (0)