Skip to content

Commit f58c5eb

Browse files
committed
ydbd_slice: add support for using raw config.yaml via --yaml-config and dynconfig.yaml via --yaml-dynconfig
- Add yaml_configurator instead of configurator - Add warning for old style cluster.yaml - Add dynconfig-generator for generating simple dynconfig.yaml - Add --save-raw-cfg option for saving raw config from old cluster.yaml
1 parent 60c4deb commit f58c5eb

File tree

7 files changed

+374
-31
lines changed

7 files changed

+374
-31
lines changed

ydb/tools/cfg/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,10 @@ def domains(self):
622622
)
623623
return domains
624624

625+
@domains.setter
626+
def domains(self, values):
627+
self.__cluster_description["domains"] = values
628+
625629
@property
626630
def domains_config(self):
627631
domains_config_dict = self.__cluster_description.get("domains_config", {})

ydb/tools/ydbd_slice/__init__.py

Lines changed: 149 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
from urllib3.exceptions import HTTPWarning
1414

1515
from ydb.tools.cfg.walle import NopHostsInformationProvider
16-
from ydb.tools.ydbd_slice import nodes, handlers, cluster_description
16+
from ydb.tools.ydbd_slice import nodes, handlers, cluster_description, yaml_configurator
1717
from ydb.tools.ydbd_slice.kube import handlers as kube_handlers, docker
1818

19-
warnings.filterwarnings("ignore", category=DeprecationWarning)
19+
# warnings.filterwarnings("ignore", category=DeprecationWarning)
2020
warnings.filterwarnings("ignore", category=HTTPWarning)
2121

2222

@@ -40,6 +40,9 @@
4040
\033[95msample-config\033[94m - get sample configuration for cluster:
4141
%(prog)s sample-config --cluster-type=block-4-2-8-nodes --output-file=cluster.yaml
4242
43+
\033[95mdynconfig-generator\033[94m - generate simple dynamic configuration for cluster:
44+
%(prog)s dynconfig-generator --yaml-config=config.yaml --output-file=dynconfig.yaml
45+
4346
\033[95minstall\033[94m - full install process from scratch:
4447
%(prog)s install cluster.yaml --arcadia
4548
@@ -254,9 +257,9 @@ def handler(signum, frame):
254257
raise Terminate(signum, frame)
255258

256259

257-
def safe_load_cluster_details(cluster_yaml, walle_provider):
260+
def safe_load_cluster_details(cluster_yaml, walle_provider, validator=None):
258261
try:
259-
cluster_details = cluster_description.ClusterDetails(cluster_yaml, walle_provider)
262+
cluster_details = cluster_description.ClusterDetails(cluster_yaml, walle_provider, validator=validator)
260263
except IOError as io_err:
261264
print('', file=sys.stderr)
262265
print("unable to open YAML params as a file, check args", file=sys.stderr)
@@ -310,8 +313,7 @@ def deduce_components_from_args(args, cluster_details):
310313
return result
311314

312315

313-
def deduce_nodes_from_args(args, walle_provider, ssh_user, ssh_key_path):
314-
cluster_hosts = safe_load_cluster_details(args.cluster, walle_provider).hosts_names
316+
def deduce_nodes_from_args(args, cluster_hosts, ssh_user, ssh_key_path):
315317
result = cluster_hosts
316318

317319
if args.nodes is not None:
@@ -547,6 +549,26 @@ def databases_config_path_args():
547549
return args
548550

549551

552+
def yaml_config_path_args():
553+
args = argparse.ArgumentParser(add_help=False)
554+
args.add_argument(
555+
"--yaml-config",
556+
metavar="YAML_CONFIG",
557+
default="",
558+
required=False,
559+
help="Path to file with config.yaml configuration",
560+
)
561+
args.add_argument(
562+
"--yaml-dynconfig",
563+
metavar="YAML_DYNCONFIG",
564+
default="",
565+
required=False,
566+
help="Path to file with dynconfig.yaml configuration",
567+
)
568+
569+
return args
570+
571+
550572
def cluster_type_args():
551573
args = argparse.ArgumentParser(add_help=False)
552574
available_erasure_types = [
@@ -628,38 +650,65 @@ def dispatch_run(func, args, walle_provider, need_confirmation=False):
628650

629651
logger.debug("run func '%s' with cmd args is '%s'", func.__name__, args)
630652

631-
cluster_details = safe_load_cluster_details(args.cluster, walle_provider)
632-
components = deduce_components_from_args(args, cluster_details)
633-
634-
nodes = deduce_nodes_from_args(args, walle_provider, args.ssh_user, args.ssh_key_path)
635-
636653
temp_dir = deduce_temp_dir_from_args(args)
654+
kikimr_bin, kikimr_compressed_bin = deduce_kikimr_bin_from_args(args)
637655
clear_tmp = not args.dry_run and args.temp_dir is None
638656

639-
kikimr_bin, kikimr_compressed_bin = deduce_kikimr_bin_from_args(args)
657+
if args.yaml_config and args.yaml_dynconfig:
658+
configurator = yaml_configurator.YamlConfigurator(
659+
args.cluster,
660+
temp_dir,
661+
kikimr_bin,
662+
kikimr_compressed_bin,
663+
args.yaml_config,
664+
args.yaml_dynconfig
665+
)
666+
cluster_details = configurator.cluster_description
667+
else:
668+
cluster_details = safe_load_cluster_details(args.cluster, walle_provider)
669+
configurator = cluster_description.Configurator(
670+
cluster_details,
671+
out_dir=temp_dir,
672+
kikimr_bin=kikimr_bin,
673+
kikimr_compressed_bin=kikimr_compressed_bin,
674+
walle_provider=walle_provider
675+
)
640676

641-
configurator = cluster_description.Configurator(
642-
cluster_details,
643-
out_dir=temp_dir,
644-
kikimr_bin=kikimr_bin,
645-
kikimr_compressed_bin=kikimr_compressed_bin,
646-
walle_provider=walle_provider
647-
)
677+
components = deduce_components_from_args(args, cluster_details)
648678

649679
v = vars(args)
650680
clear_logs = v.get('clear_logs')
651681
yav_version = v.get('yav_version')
682+
683+
nodes = deduce_nodes_from_args(args, configurator.hosts_names, args.ssh_user, args.ssh_key_path)
652684
slice = handlers.Slice(
653685
components,
654686
nodes,
655687
cluster_details,
656-
configurator,
688+
kikimr_bin,
689+
kikimr_compressed_bin,
657690
clear_logs,
658691
yav_version,
659692
walle_provider,
693+
configurator,
660694
)
661695
func(slice)
662696

697+
# used only for configurator and will be removed soon
698+
save_raw_cfg = v.get('save_raw_cfg')
699+
if save_raw_cfg and configurator:
700+
logger.debug("save raw cfg to '%s'", save_raw_cfg)
701+
for root, dirs, files in os.walk(temp_dir):
702+
for dir in dirs:
703+
os.makedirs(os.path.join(save_raw_cfg, dir), 0o755, exist_ok=True)
704+
705+
for file in files:
706+
src = os.path.join(root, file)
707+
dst = os.path.join(save_raw_cfg, os.path.relpath(src, temp_dir))
708+
with open(src, 'r') as src_f:
709+
with open(dst, 'w') as dst_f:
710+
dst_f.write(src_f.read())
711+
663712
if clear_tmp:
664713
logger.debug("remove temp dirs '%s'", temp_dir)
665714
# shutil.rmtree(temp_dir)
@@ -699,6 +748,7 @@ def _run(args):
699748
parents=[
700749
direct_nodes_args(),
701750
cluster_description_args(),
751+
yaml_config_path_args(),
702752
binaries_args(),
703753
component_args(),
704754
log_args(),
@@ -709,6 +759,13 @@ def _run(args):
709759
description="Full installation of the cluster from scratch. "
710760
"You can use --hosts to specify particular hosts. But it is tricky.",
711761
)
762+
mode.add_argument(
763+
"--save-raw-cfg",
764+
metavar="DIR",
765+
required=False,
766+
default="",
767+
help="Directory to save all static configuration files generated by configuration.create_static_cfg and configuration.create_dynamic_cfg",
768+
)
712769
mode.set_defaults(handler=_run)
713770

714771

@@ -722,6 +779,7 @@ def _run(args):
722779
parents=[
723780
direct_nodes_args(),
724781
cluster_description_args(),
782+
yaml_config_path_args(),
725783
binaries_args(),
726784
component_args(),
727785
log_args(),
@@ -759,7 +817,14 @@ def _run(args):
759817

760818
mode = modes.add_parser(
761819
"stop",
762-
parents=[direct_nodes_args(), cluster_description_args(), binaries_args(), component_args(), ssh_args()],
820+
parents=[
821+
direct_nodes_args(),
822+
cluster_description_args(),
823+
yaml_config_path_args(),
824+
binaries_args(),
825+
component_args(),
826+
ssh_args()
827+
],
763828
description="Stop ydbd static instances at the nodes. "
764829
"If option components specified, try to stop particular component. "
765830
"Use --hosts to specify particular hosts."
@@ -773,7 +838,14 @@ def _run(args):
773838

774839
mode = modes.add_parser(
775840
"start",
776-
parents=[direct_nodes_args(), cluster_description_args(), binaries_args(), component_args(), ssh_args()],
841+
parents=[
842+
direct_nodes_args(),
843+
cluster_description_args(),
844+
yaml_config_path_args(),
845+
binaries_args(),
846+
component_args(),
847+
ssh_args()
848+
],
777849
description="Start all ydbd instances at the nodes. "
778850
"If option components specified, try to start particular component. "
779851
"Otherwise only kikimr-multi-all will be started. "
@@ -791,6 +863,7 @@ def _run(args):
791863
parents=[
792864
direct_nodes_args(),
793865
cluster_description_args(),
866+
yaml_config_path_args(),
794867
binaries_args(),
795868
component_args(),
796869
ssh_args(),
@@ -812,6 +885,7 @@ def _run(args):
812885
parents=[
813886
direct_nodes_args(),
814887
cluster_description_args(),
888+
yaml_config_path_args(),
815889
binaries_args(),
816890
component_args(),
817891
ssh_args(),
@@ -861,6 +935,24 @@ def _run(args):
861935
mode.set_defaults(handler=_run)
862936

863937

938+
def add_dynconfig_generator(modes):
939+
def _run(args):
940+
if args.yaml_config:
941+
yaml_config = yaml_configurator.YamlConfig(args.yaml_config)
942+
943+
if args.output_file is not None and args.output_file:
944+
with open(args.output_file, "w") as output:
945+
output.write(yaml_config.dynamic_simple)
946+
947+
mode = modes.add_parser(
948+
"dynconfig-generator",
949+
parents=[yaml_config_path_args(), output_file()],
950+
description="Generate a minimalistic dynconfig.yaml for the provided config.yaml"
951+
)
952+
953+
mode.set_defaults(handler=_run)
954+
955+
864956
#
865957
# docker and kube scenarios
866958
def build_docker_image(build_args, docker_package, build_ydbd, image, force_rebuild):
@@ -1413,6 +1505,7 @@ def main(walle_provider=None):
14131505
add_format_mode(modes, walle_provider)
14141506
add_explain_mode(modes, walle_provider)
14151507
add_sample_config_mode(modes)
1508+
add_dynconfig_generator(modes)
14161509

14171510
add_docker_build_mode(modes)
14181511
add_docker_push_mode(modes)
@@ -1429,8 +1522,41 @@ def main(walle_provider=None):
14291522

14301523
args = parser.parse_args()
14311524
logging.root.setLevel(args.log_level.upper())
1432-
args.handler(args)
14331525

1526+
if not hasattr(args, 'handler'):
1527+
parser.print_help()
1528+
return
1529+
1530+
if not args.yaml_config:
1531+
warnings.warn(
1532+
'''
1533+
1534+
1535+
###### WARNING #######
1536+
1537+
Using cluster.yaml for cluster configuration is deprecated.
1538+
Only the 'domains' section should be filled with database and slot configurations.
1539+
The config.yaml and dynconfig.yaml should be passed as raw files through the --yaml-config and --yaml-dynconfig parameters.
1540+
1541+
ydbd_slice install cluster.yaml all --binary /path/to/ydbd --yaml-config /path/to/config.yaml --yaml-dynconfig /path/to/dynconfig.yaml
1542+
1543+
To save the resulting configuration files from an old cluster.yaml, use the --save-raw-cfg option.
1544+
1545+
ydbd_slice install cluster.yaml all --binary /path/to/ydbd --save-raw-cfg /path/to/save
1546+
1547+
The resulting configuration files will be saved in the /path/to/save directory. You can find config.yaml and dynconfig.yaml in the /path/to/save/kikimr-static directory.
1548+
1549+
To generate dynconfig.yaml from config.yaml, you can use the dynconfig-generator command.
1550+
1551+
ydbd_slice dynconfig-generator --yaml-config /path/to/config.yaml --output-file /path/to/dynconfig.yaml
1552+
1553+
###### WARNING #######
1554+
1555+
''',
1556+
DeprecationWarning
1557+
)
1558+
1559+
args.handler(args)
14341560
except KeyboardInterrupt:
14351561
sys.exit('\nStopped by KeyboardInterrupt.')
14361562
except Terminate:

ydb/tools/ydbd_slice/cluster_description.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ class ClusterDetails(ClusterDetailsProvider):
2727
SLOTS_PORTS_START = 31000
2828
PORTS_SHIFT = 10
2929

30-
def __init__(self, cluster_description_path, walle_provider):
30+
def __init__(self, cluster_description_path, walle_provider, validator=None):
3131
self.__template = None
3232
self.__details = None
3333
self.__databases = None
3434
self.__dynamic_slots = None
3535
self._cluster_description_file = cluster_description_path
3636
self._walle_provider = walle_provider
3737

38-
super(ClusterDetails, self).__init__(self.template, self._walle_provider, use_new_style_cfg=True)
38+
super(ClusterDetails, self).__init__(self.template, self._walle_provider, validator=validator, use_new_style_cfg=True)
3939

4040
@property
4141
def template(self):
@@ -132,6 +132,10 @@ def template(self):
132132
def detail(self):
133133
return self.__cluster_details
134134

135+
@property
136+
def hosts_names(self):
137+
return self.detail.hosts_names
138+
135139
@staticmethod
136140
def _generate_fake_keys():
137141
content = 'Keys {\n'
@@ -140,6 +144,7 @@ def _generate_fake_keys():
140144
content += ' Id: "fake-secret"\n'
141145
content += ' Version: 1\n'
142146
content += '}\n'
147+
143148
return content
144149

145150
@staticmethod

0 commit comments

Comments
 (0)