ominfra 0.0.0.dev193__py3-none-any.whl → 0.0.0.dev195__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ominfra/clouds/aws/journald2aws/main.py +5 -2
- ominfra/manage/deploy/conf/manager.py +2 -2
- ominfra/manage/main.py +3 -3
- ominfra/scripts/journald2aws.py +446 -95
- ominfra/scripts/manage.py +467 -168
- ominfra/scripts/supervisor.py +1055 -659
- ominfra/supervisor/configs.py +4 -3
- ominfra/supervisor/main.py +2 -2
- {ominfra-0.0.0.dev193.dist-info → ominfra-0.0.0.dev195.dist-info}/METADATA +4 -4
- {ominfra-0.0.0.dev193.dist-info → ominfra-0.0.0.dev195.dist-info}/RECORD +14 -15
- ominfra/configs.py +0 -102
- {ominfra-0.0.0.dev193.dist-info → ominfra-0.0.0.dev195.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev193.dist-info → ominfra-0.0.0.dev195.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev193.dist-info → ominfra-0.0.0.dev195.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev193.dist-info → ominfra-0.0.0.dev195.dist-info}/top_level.txt +0 -0
@@ -5,9 +5,9 @@ import dataclasses as dc
|
|
5
5
|
import os.path
|
6
6
|
import sys
|
7
7
|
|
8
|
+
from omlish.lite.configs import load_config_file_obj
|
8
9
|
from omlish.logs.standard import configure_standard_logging
|
9
10
|
|
10
|
-
from ....configs import read_config_file
|
11
11
|
from .driver import JournalctlToAwsDriver
|
12
12
|
|
13
13
|
|
@@ -36,7 +36,10 @@ def _main() -> None:
|
|
36
36
|
|
37
37
|
config: JournalctlToAwsDriver.Config
|
38
38
|
if args.config_file:
|
39
|
-
config =
|
39
|
+
config = load_config_file_obj(
|
40
|
+
os.path.expanduser(args.config_file),
|
41
|
+
JournalctlToAwsDriver.Config,
|
42
|
+
)
|
40
43
|
else:
|
41
44
|
config = JournalctlToAwsDriver.Config()
|
42
45
|
|
@@ -26,8 +26,8 @@ from omlish.lite.json import json_dumps_pretty
|
|
26
26
|
from omlish.lite.strings import strip_with_newline
|
27
27
|
from omlish.os.paths import is_path_in_dir
|
28
28
|
from omlish.os.paths import relative_symlink
|
29
|
-
from
|
30
|
-
from
|
29
|
+
from omlish.configs.nginx import NginxConfigItems
|
30
|
+
from omlish.configs.nginx import render_nginx_config_str
|
31
31
|
|
32
32
|
from omlish.formats.ini.sections import render_ini_sections
|
33
33
|
from ..paths.paths import DeployPath
|
ominfra/manage/main.py
CHANGED
@@ -17,12 +17,12 @@ from omlish.argparse.cli import argparse_arg
|
|
17
17
|
from omlish.argparse.cli import argparse_cmd
|
18
18
|
from omlish.lite.cached import cached_nullary
|
19
19
|
from omlish.lite.check import check
|
20
|
+
from omlish.lite.configs import load_config_file_obj
|
20
21
|
from omlish.lite.logs import log # noqa
|
21
22
|
from omlish.lite.marshal import ObjMarshalerManager
|
22
23
|
from omlish.lite.marshal import ObjMarshalOptions
|
23
24
|
from omlish.lite.pycharm import PycharmRemoteDebug
|
24
25
|
|
25
|
-
from ..configs import read_config_file
|
26
26
|
from .bootstrap import MainBootstrap
|
27
27
|
from .bootstrap_ import main_bootstrap
|
28
28
|
from .commands.base import Command
|
@@ -51,7 +51,7 @@ class MainCli(ArgparseCli):
|
|
51
51
|
if cf is None:
|
52
52
|
return ManageConfig()
|
53
53
|
else:
|
54
|
-
return
|
54
|
+
return load_config_file_obj(cf, ManageConfig)
|
55
55
|
|
56
56
|
#
|
57
57
|
|
@@ -122,7 +122,7 @@ class MainCli(ArgparseCli):
|
|
122
122
|
cmds.append(cmd)
|
123
123
|
|
124
124
|
for cf in self.args.command_file or []:
|
125
|
-
cmd =
|
125
|
+
cmd = load_config_file_obj(cf, Command, msh=msh)
|
126
126
|
cmds.append(cmd)
|
127
127
|
|
128
128
|
#
|
ominfra/scripts/journald2aws.py
CHANGED
@@ -9,6 +9,7 @@ import argparse
|
|
9
9
|
import base64
|
10
10
|
import collections
|
11
11
|
import collections.abc
|
12
|
+
import configparser
|
12
13
|
import contextlib
|
13
14
|
import dataclasses as dc
|
14
15
|
import datetime
|
@@ -52,6 +53,12 @@ if sys.version_info < (3, 8):
|
|
52
53
|
########################################
|
53
54
|
|
54
55
|
|
56
|
+
# ../../../../omlish/configs/types.py
|
57
|
+
ConfigMap = ta.Mapping[str, ta.Any]
|
58
|
+
|
59
|
+
# ../../../../omlish/formats/ini/sections.py
|
60
|
+
IniSectionSettingsMap = ta.Mapping[str, ta.Mapping[str, ta.Union[str, ta.Sequence[str]]]] # ta.TypeAlias
|
61
|
+
|
55
62
|
# ../../../../omlish/formats/toml/parser.py
|
56
63
|
TomlParseFloat = ta.Callable[[str], ta.Any]
|
57
64
|
TomlKey = ta.Tuple[str, ...]
|
@@ -69,12 +76,12 @@ CheckOnRaiseFn = ta.Callable[[Exception], None] # ta.TypeAlias
|
|
69
76
|
CheckExceptionFactory = ta.Callable[..., Exception] # ta.TypeAlias
|
70
77
|
CheckArgsRenderer = ta.Callable[..., ta.Optional[str]] # ta.TypeAlias
|
71
78
|
|
79
|
+
# ../../../../omlish/configs/formats.py
|
80
|
+
ConfigDataT = ta.TypeVar('ConfigDataT', bound='ConfigData')
|
81
|
+
|
72
82
|
# ../../../../omlish/lite/contextmanagers.py
|
73
83
|
ExitStackedT = ta.TypeVar('ExitStackedT', bound='ExitStacked')
|
74
84
|
|
75
|
-
# ../../../configs.py
|
76
|
-
ConfigMapping = ta.Mapping[str, ta.Any]
|
77
|
-
|
78
85
|
# ../../../threadworkers.py
|
79
86
|
ThreadWorkerT = ta.TypeVar('ThreadWorkerT', bound='ThreadWorker')
|
80
87
|
|
@@ -82,6 +89,54 @@ ThreadWorkerT = ta.TypeVar('ThreadWorkerT', bound='ThreadWorker')
|
|
82
89
|
SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull'] # ta.TypeAlias
|
83
90
|
|
84
91
|
|
92
|
+
########################################
|
93
|
+
# ../../../../../omlish/configs/types.py
|
94
|
+
|
95
|
+
|
96
|
+
#
|
97
|
+
|
98
|
+
|
99
|
+
########################################
|
100
|
+
# ../../../../../omlish/formats/ini/sections.py
|
101
|
+
|
102
|
+
|
103
|
+
##
|
104
|
+
|
105
|
+
|
106
|
+
def extract_ini_sections(cp: configparser.ConfigParser) -> IniSectionSettingsMap:
|
107
|
+
config_dct: ta.Dict[str, ta.Any] = {}
|
108
|
+
for sec in cp.sections():
|
109
|
+
cd = config_dct
|
110
|
+
for k in sec.split('.'):
|
111
|
+
cd = cd.setdefault(k, {})
|
112
|
+
cd.update(cp.items(sec))
|
113
|
+
return config_dct
|
114
|
+
|
115
|
+
|
116
|
+
##
|
117
|
+
|
118
|
+
|
119
|
+
def render_ini_sections(
|
120
|
+
settings_by_section: IniSectionSettingsMap,
|
121
|
+
) -> str:
|
122
|
+
out = io.StringIO()
|
123
|
+
|
124
|
+
for i, (section, settings) in enumerate(settings_by_section.items()):
|
125
|
+
if i:
|
126
|
+
out.write('\n')
|
127
|
+
|
128
|
+
out.write(f'[{section}]\n')
|
129
|
+
|
130
|
+
for k, v in settings.items():
|
131
|
+
if isinstance(v, str):
|
132
|
+
out.write(f'{k}={v}\n')
|
133
|
+
else:
|
134
|
+
for vv in v:
|
135
|
+
out.write(f'{k}={vv}\n')
|
136
|
+
|
137
|
+
return out.getvalue()
|
138
|
+
|
139
|
+
|
85
140
|
########################################
|
86
141
|
# ../../../../../omlish/formats/toml/parser.py
|
87
142
|
# SPDX-License-Identifier: MIT
|
@@ -900,6 +955,129 @@ def toml_make_safe_parse_float(parse_float: TomlParseFloat) -> TomlParseFloat:
|
|
900
955
|
return safe_parse_float
|
901
956
|
|
902
957
|
|
958
|
+
########################################
|
959
|
+
# ../../../../../omlish/formats/toml/writer.py
|
960
|
+
|
961
|
+
|
962
|
+
class TomlWriter:
|
963
|
+
@dc.dataclass(frozen=True)
|
964
|
+
class Literal:
|
965
|
+
s: str
|
966
|
+
|
967
|
+
def __init__(self, out: ta.TextIO) -> None:
|
968
|
+
super().__init__()
|
969
|
+
self._out = out
|
970
|
+
|
971
|
+
self._indent = 0
|
972
|
+
self._wrote_indent = False
|
973
|
+
|
974
|
+
#
|
975
|
+
|
976
|
+
def _w(self, s: str) -> None:
|
977
|
+
if not self._wrote_indent:
|
978
|
+
self._out.write(' ' * self._indent)
|
979
|
+
self._wrote_indent = True
|
980
|
+
self._out.write(s)
|
981
|
+
|
982
|
+
def _nl(self) -> None:
|
983
|
+
self._out.write('\n')
|
984
|
+
self._wrote_indent = False
|
985
|
+
|
986
|
+
def _needs_quote(self, s: str) -> bool:
|
987
|
+
return (
|
988
|
+
not s or
|
989
|
+
any(c in s for c in '\'"\n') or
|
990
|
+
s[0] not in string.ascii_letters
|
991
|
+
)
|
992
|
+
|
993
|
+
def _maybe_quote(self, s: str) -> str:
|
994
|
+
if self._needs_quote(s):
|
995
|
+
return repr(s)
|
996
|
+
else:
|
997
|
+
return s
|
998
|
+
|
999
|
+
#
|
1000
|
+
|
1001
|
+
def write_root(self, obj: ta.Mapping) -> None:
|
1002
|
+
for i, (k, v) in enumerate(obj.items()):
|
1003
|
+
if i:
|
1004
|
+
self._nl()
|
1005
|
+
self._w('[')
|
1006
|
+
self._w(self._maybe_quote(k))
|
1007
|
+
self._w(']')
|
1008
|
+
self._nl()
|
1009
|
+
self.write_table_contents(v)
|
1010
|
+
|
1011
|
+
def write_table_contents(self, obj: ta.Mapping) -> None:
|
1012
|
+
for k, v in obj.items():
|
1013
|
+
self.write_key(k)
|
1014
|
+
self._w(' = ')
|
1015
|
+
self.write_value(v)
|
1016
|
+
self._nl()
|
1017
|
+
|
1018
|
+
def write_array(self, obj: ta.Sequence) -> None:
|
1019
|
+
self._w('[')
|
1020
|
+
self._nl()
|
1021
|
+
self._indent += 1
|
1022
|
+
for e in obj:
|
1023
|
+
self.write_value(e)
|
1024
|
+
self._w(',')
|
1025
|
+
self._nl()
|
1026
|
+
self._indent -= 1
|
1027
|
+
self._w(']')
|
1028
|
+
|
1029
|
+
def write_inline_table(self, obj: ta.Mapping) -> None:
|
1030
|
+
self._w('{')
|
1031
|
+
for i, (k, v) in enumerate(obj.items()):
|
1032
|
+
if i:
|
1033
|
+
self._w(', ')
|
1034
|
+
self.write_key(k)
|
1035
|
+
self._w(' = ')
|
1036
|
+
self.write_value(v)
|
1037
|
+
self._w('}')
|
1038
|
+
|
1039
|
+
def write_inline_array(self, obj: ta.Sequence) -> None:
|
1040
|
+
self._w('[')
|
1041
|
+
for i, e in enumerate(obj):
|
1042
|
+
if i:
|
1043
|
+
self._w(', ')
|
1044
|
+
self.write_value(e)
|
1045
|
+
self._w(']')
|
1046
|
+
|
1047
|
+
def write_key(self, obj: ta.Any) -> None:
|
1048
|
+
if isinstance(obj, TomlWriter.Literal):
|
1049
|
+
self._w(obj.s)
|
1050
|
+
elif isinstance(obj, str):
|
1051
|
+
self._w(self._maybe_quote(obj.replace('_', '-')))
|
1052
|
+
elif isinstance(obj, int):
|
1053
|
+
self._w(repr(str(obj)))
|
1054
|
+
else:
|
1055
|
+
raise TypeError(obj)
|
1056
|
+
|
1057
|
+
def write_value(self, obj: ta.Any) -> None:
|
1058
|
+
if isinstance(obj, bool):
|
1059
|
+
self._w(str(obj).lower())
|
1060
|
+
elif isinstance(obj, (str, int, float)):
|
1061
|
+
self._w(repr(obj))
|
1062
|
+
elif isinstance(obj, ta.Mapping):
|
1063
|
+
self.write_inline_table(obj)
|
1064
|
+
elif isinstance(obj, ta.Sequence):
|
1065
|
+
if not obj:
|
1066
|
+
self.write_inline_array(obj)
|
1067
|
+
else:
|
1068
|
+
self.write_array(obj)
|
1069
|
+
else:
|
1070
|
+
raise TypeError(obj)
|
1071
|
+
|
1072
|
+
#
|
1073
|
+
|
1074
|
+
@classmethod
|
1075
|
+
def write_str(cls, obj: ta.Any) -> str:
|
1076
|
+
out = io.StringIO()
|
1077
|
+
cls(out).write_value(obj)
|
1078
|
+
return out.getvalue()
|
1079
|
+
|
1080
|
+
|
903
1081
|
########################################
|
904
1082
|
# ../../../../../omlish/lite/cached.py
|
905
1083
|
|
@@ -2217,6 +2395,235 @@ class JournalctlToAwsCursor:
|
|
2217
2395
|
os.rename(ncf, cf)
|
2218
2396
|
|
2219
2397
|
|
2398
|
+
########################################
|
2399
|
+
# ../../../../../omlish/configs/formats.py
|
2400
|
+
"""
|
2401
|
+
Notes:
|
2402
|
+
- necessarily string-oriented
|
2403
|
+
- single file, as this is intended to be amalg'd and thus all included anyway
|
2404
|
+
|
2405
|
+
TODO:
|
2406
|
+
- ConfigDataMapper? to_map -> ConfigMap?
|
2407
|
+
- nginx ?
|
2408
|
+
- raw ?
|
2409
|
+
"""
|
2410
|
+
|
2411
|
+
|
2412
|
+
##
|
2413
|
+
|
2414
|
+
|
2415
|
+
@dc.dataclass(frozen=True)
|
2416
|
+
class ConfigData(abc.ABC): # noqa
|
2417
|
+
@abc.abstractmethod
|
2418
|
+
def as_map(self) -> ConfigMap:
|
2419
|
+
raise NotImplementedError
|
2420
|
+
|
2421
|
+
|
2422
|
+
#
|
2423
|
+
|
2424
|
+
|
2425
|
+
class ConfigLoader(abc.ABC, ta.Generic[ConfigDataT]):
|
2426
|
+
@property
|
2427
|
+
def file_exts(self) -> ta.Sequence[str]:
|
2428
|
+
return ()
|
2429
|
+
|
2430
|
+
def match_file(self, n: str) -> bool:
|
2431
|
+
return '.' in n and n.split('.')[-1] in check.not_isinstance(self.file_exts, str)
|
2432
|
+
|
2433
|
+
#
|
2434
|
+
|
2435
|
+
def load_file(self, p: str) -> ConfigDataT:
|
2436
|
+
with open(p) as f:
|
2437
|
+
return self.load_str(f.read())
|
2438
|
+
|
2439
|
+
@abc.abstractmethod
|
2440
|
+
def load_str(self, s: str) -> ConfigDataT:
|
2441
|
+
raise NotImplementedError
|
2442
|
+
|
2443
|
+
|
2444
|
+
#
|
2445
|
+
|
2446
|
+
|
2447
|
+
class ConfigRenderer(abc.ABC, ta.Generic[ConfigDataT]):
|
2448
|
+
@property
|
2449
|
+
@abc.abstractmethod
|
2450
|
+
def data_cls(self) -> ta.Type[ConfigDataT]:
|
2451
|
+
raise NotImplementedError
|
2452
|
+
|
2453
|
+
def match_data(self, d: ConfigDataT) -> bool:
|
2454
|
+
return isinstance(d, self.data_cls)
|
2455
|
+
|
2456
|
+
#
|
2457
|
+
|
2458
|
+
@abc.abstractmethod
|
2459
|
+
def render(self, d: ConfigDataT) -> str:
|
2460
|
+
raise NotImplementedError
|
2461
|
+
|
2462
|
+
|
2463
|
+
##
|
2464
|
+
|
2465
|
+
|
2466
|
+
@dc.dataclass(frozen=True)
|
2467
|
+
class ObjConfigData(ConfigData, abc.ABC):
|
2468
|
+
obj: ta.Any
|
2469
|
+
|
2470
|
+
def as_map(self) -> ConfigMap:
|
2471
|
+
return check.isinstance(self.obj, collections.abc.Mapping)
|
2472
|
+
|
2473
|
+
|
2474
|
+
##
|
2475
|
+
|
2476
|
+
|
2477
|
+
@dc.dataclass(frozen=True)
|
2478
|
+
class JsonConfigData(ObjConfigData):
|
2479
|
+
pass
|
2480
|
+
|
2481
|
+
|
2482
|
+
class JsonConfigLoader(ConfigLoader[JsonConfigData]):
|
2483
|
+
file_exts = ('json',)
|
2484
|
+
|
2485
|
+
def load_str(self, s: str) -> JsonConfigData:
|
2486
|
+
return JsonConfigData(json.loads(s))
|
2487
|
+
|
2488
|
+
|
2489
|
+
class JsonConfigRenderer(ConfigRenderer[JsonConfigData]):
|
2490
|
+
data_cls = JsonConfigData
|
2491
|
+
|
2492
|
+
def render(self, d: JsonConfigData) -> str:
|
2493
|
+
return json_dumps_pretty(d.obj)
|
2494
|
+
|
2495
|
+
|
2496
|
+
##
|
2497
|
+
|
2498
|
+
|
2499
|
+
@dc.dataclass(frozen=True)
|
2500
|
+
class TomlConfigData(ObjConfigData):
|
2501
|
+
pass
|
2502
|
+
|
2503
|
+
|
2504
|
+
class TomlConfigLoader(ConfigLoader[TomlConfigData]):
|
2505
|
+
file_exts = ('toml',)
|
2506
|
+
|
2507
|
+
def load_str(self, s: str) -> TomlConfigData:
|
2508
|
+
return TomlConfigData(toml_loads(s))
|
2509
|
+
|
2510
|
+
|
2511
|
+
class TomlConfigRenderer(ConfigRenderer[TomlConfigData]):
|
2512
|
+
data_cls = TomlConfigData
|
2513
|
+
|
2514
|
+
def render(self, d: TomlConfigData) -> str:
|
2515
|
+
return TomlWriter.write_str(d.obj)
|
2516
|
+
|
2517
|
+
|
2518
|
+
##
|
2519
|
+
|
2520
|
+
|
2521
|
+
@dc.dataclass(frozen=True)
|
2522
|
+
class YamlConfigData(ObjConfigData):
|
2523
|
+
pass
|
2524
|
+
|
2525
|
+
|
2526
|
+
class YamlConfigLoader(ConfigLoader[YamlConfigData]):
|
2527
|
+
file_exts = ('yaml', 'yml')
|
2528
|
+
|
2529
|
+
def load_str(self, s: str) -> YamlConfigData:
|
2530
|
+
return YamlConfigData(__import__('yaml').safe_load(s))
|
2531
|
+
|
2532
|
+
|
2533
|
+
class YamlConfigRenderer(ConfigRenderer[YamlConfigData]):
|
2534
|
+
data_cls = YamlConfigData
|
2535
|
+
|
2536
|
+
def render(self, d: YamlConfigData) -> str:
|
2537
|
+
return __import__('yaml').safe_dump(d.obj)
|
2538
|
+
|
2539
|
+
|
2540
|
+
##
|
2541
|
+
|
2542
|
+
|
2543
|
+
@dc.dataclass(frozen=True)
|
2544
|
+
class IniConfigData(ConfigData):
|
2545
|
+
sections: IniSectionSettingsMap
|
2546
|
+
|
2547
|
+
def as_map(self) -> ConfigMap:
|
2548
|
+
return self.sections
|
2549
|
+
|
2550
|
+
|
2551
|
+
class IniConfigLoader(ConfigLoader[IniConfigData]):
|
2552
|
+
file_exts = ('ini',)
|
2553
|
+
|
2554
|
+
def load_str(self, s: str) -> IniConfigData:
|
2555
|
+
cp = configparser.ConfigParser()
|
2556
|
+
cp.read_string(s)
|
2557
|
+
return IniConfigData(extract_ini_sections(cp))
|
2558
|
+
|
2559
|
+
|
2560
|
+
class IniConfigRenderer(ConfigRenderer[IniConfigData]):
|
2561
|
+
data_cls = IniConfigData
|
2562
|
+
|
2563
|
+
def render(self, d: IniConfigData) -> str:
|
2564
|
+
return render_ini_sections(d.sections)
|
2565
|
+
|
2566
|
+
|
2567
|
+
##
|
2568
|
+
|
2569
|
+
|
2570
|
+
@dc.dataclass(frozen=True)
|
2571
|
+
class SwitchedConfigFileLoader:
|
2572
|
+
loaders: ta.Sequence[ConfigLoader]
|
2573
|
+
default: ta.Optional[ConfigLoader] = None
|
2574
|
+
|
2575
|
+
def load_file(self, p: str) -> ConfigData:
|
2576
|
+
n = os.path.basename(p)
|
2577
|
+
|
2578
|
+
for l in self.loaders:
|
2579
|
+
if l.match_file(n):
|
2580
|
+
return l.load_file(p)
|
2581
|
+
|
2582
|
+
if (d := self.default) is not None:
|
2583
|
+
return d.load_file(p)
|
2584
|
+
|
2585
|
+
raise NameError(n)
|
2586
|
+
|
2587
|
+
|
2588
|
+
DEFAULT_CONFIG_LOADERS: ta.Sequence[ConfigLoader] = [
|
2589
|
+
JsonConfigLoader(),
|
2590
|
+
TomlConfigLoader(),
|
2591
|
+
YamlConfigLoader(),
|
2592
|
+
IniConfigLoader(),
|
2593
|
+
]
|
2594
|
+
|
2595
|
+
DEFAULT_CONFIG_LOADER: ConfigLoader = JsonConfigLoader()
|
2596
|
+
|
2597
|
+
DEFAULT_CONFIG_FILE_LOADER = SwitchedConfigFileLoader(
|
2598
|
+
loaders=DEFAULT_CONFIG_LOADERS,
|
2599
|
+
default=DEFAULT_CONFIG_LOADER,
|
2600
|
+
)
|
2601
|
+
|
2602
|
+
|
2603
|
+
##
|
2604
|
+
|
2605
|
+
|
2606
|
+
@dc.dataclass(frozen=True)
|
2607
|
+
class SwitchedConfigRenderer:
|
2608
|
+
renderers: ta.Sequence[ConfigRenderer]
|
2609
|
+
|
2610
|
+
def render(self, d: ConfigData) -> str:
|
2611
|
+
for r in self.renderers:
|
2612
|
+
if r.match_data(d):
|
2613
|
+
return r.render(d)
|
2614
|
+
raise TypeError(d)
|
2615
|
+
|
2616
|
+
|
2617
|
+
DEFAULT_CONFIG_RENDERERS: ta.Sequence[ConfigRenderer] = [
|
2618
|
+
JsonConfigRenderer(),
|
2619
|
+
TomlConfigRenderer(),
|
2620
|
+
YamlConfigRenderer(),
|
2621
|
+
IniConfigRenderer(),
|
2622
|
+
]
|
2623
|
+
|
2624
|
+
DEFAULT_CONFIG_RENDERER = SwitchedConfigRenderer(DEFAULT_CONFIG_RENDERERS)
|
2625
|
+
|
2626
|
+
|
2220
2627
|
########################################
|
2221
2628
|
# ../../../../../omlish/io/buffers.py
|
2222
2629
|
|
@@ -3279,97 +3686,6 @@ class AwsLogMessageBuilder:
|
|
3279
3686
|
return [post]
|
3280
3687
|
|
3281
3688
|
|
3282
|
-
########################################
|
3283
|
-
# ../../../../configs.py
|
3284
|
-
|
3285
|
-
|
3286
|
-
##
|
3287
|
-
|
3288
|
-
|
3289
|
-
def parse_config_file(
|
3290
|
-
name: str,
|
3291
|
-
f: ta.TextIO,
|
3292
|
-
) -> ConfigMapping:
|
3293
|
-
if name.endswith('.toml'):
|
3294
|
-
return toml_loads(f.read())
|
3295
|
-
|
3296
|
-
elif any(name.endswith(e) for e in ('.yml', '.yaml')):
|
3297
|
-
yaml = __import__('yaml')
|
3298
|
-
return yaml.safe_load(f)
|
3299
|
-
|
3300
|
-
elif name.endswith('.ini'):
|
3301
|
-
import configparser
|
3302
|
-
cp = configparser.ConfigParser()
|
3303
|
-
cp.read_file(f)
|
3304
|
-
config_dct: ta.Dict[str, ta.Any] = {}
|
3305
|
-
for sec in cp.sections():
|
3306
|
-
cd = config_dct
|
3307
|
-
for k in sec.split('.'):
|
3308
|
-
cd = cd.setdefault(k, {})
|
3309
|
-
cd.update(cp.items(sec))
|
3310
|
-
return config_dct
|
3311
|
-
|
3312
|
-
else:
|
3313
|
-
return json.loads(f.read())
|
3314
|
-
|
3315
|
-
|
3316
|
-
def read_config_file(
|
3317
|
-
path: str,
|
3318
|
-
cls: ta.Type[T],
|
3319
|
-
*,
|
3320
|
-
prepare: ta.Optional[ta.Callable[[ConfigMapping], ConfigMapping]] = None,
|
3321
|
-
msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
|
3322
|
-
) -> T:
|
3323
|
-
with open(path) as cf:
|
3324
|
-
config_dct = parse_config_file(os.path.basename(path), cf)
|
3325
|
-
|
3326
|
-
if prepare is not None:
|
3327
|
-
config_dct = prepare(config_dct)
|
3328
|
-
|
3329
|
-
return msh.unmarshal_obj(config_dct, cls)
|
3330
|
-
|
3331
|
-
|
3332
|
-
##
|
3333
|
-
|
3334
|
-
|
3335
|
-
def build_config_named_children(
|
3336
|
-
o: ta.Union[
|
3337
|
-
ta.Sequence[ConfigMapping],
|
3338
|
-
ta.Mapping[str, ConfigMapping],
|
3339
|
-
None,
|
3340
|
-
],
|
3341
|
-
*,
|
3342
|
-
name_key: str = 'name',
|
3343
|
-
) -> ta.Optional[ta.Sequence[ConfigMapping]]:
|
3344
|
-
if o is None:
|
3345
|
-
return None
|
3346
|
-
|
3347
|
-
lst: ta.List[ConfigMapping] = []
|
3348
|
-
if isinstance(o, ta.Mapping):
|
3349
|
-
for k, v in o.items():
|
3350
|
-
check.isinstance(v, ta.Mapping)
|
3351
|
-
if name_key in v:
|
3352
|
-
n = v[name_key]
|
3353
|
-
if k != n:
|
3354
|
-
raise KeyError(f'Given names do not match: {n} != {k}')
|
3355
|
-
lst.append(v)
|
3356
|
-
else:
|
3357
|
-
lst.append({name_key: k, **v})
|
3358
|
-
|
3359
|
-
else:
|
3360
|
-
check.not_isinstance(o, str)
|
3361
|
-
lst.extend(o)
|
3362
|
-
|
3363
|
-
seen = set()
|
3364
|
-
for d in lst:
|
3365
|
-
n = d['name']
|
3366
|
-
if n in d:
|
3367
|
-
raise KeyError(f'Duplicate name: {n}')
|
3368
|
-
seen.add(n)
|
3369
|
-
|
3370
|
-
return lst
|
3371
|
-
|
3372
|
-
|
3373
3689
|
########################################
|
3374
3690
|
# ../../../../journald/messages.py
|
3375
3691
|
|
@@ -3629,6 +3945,38 @@ class ThreadWorkerGroup:
|
|
3629
3945
|
return dct
|
3630
3946
|
|
3631
3947
|
|
3948
|
+
########################################
|
3949
|
+
# ../../../../../omlish/lite/configs.py
|
3950
|
+
|
3951
|
+
|
3952
|
+
##
|
3953
|
+
|
3954
|
+
|
3955
|
+
def load_config_file_obj(
|
3956
|
+
f: str,
|
3957
|
+
cls: ta.Type[T],
|
3958
|
+
*,
|
3959
|
+
prepare: ta.Union[
|
3960
|
+
ta.Callable[[ConfigMap], ConfigMap],
|
3961
|
+
ta.Iterable[ta.Callable[[ConfigMap], ConfigMap]],
|
3962
|
+
] = (),
|
3963
|
+
msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
|
3964
|
+
) -> T:
|
3965
|
+
config_data = DEFAULT_CONFIG_FILE_LOADER.load_file(f)
|
3966
|
+
|
3967
|
+
config_dct = config_data.as_map()
|
3968
|
+
|
3969
|
+
if prepare is not None:
|
3970
|
+
if isinstance(prepare, ta.Iterable):
|
3971
|
+
pfs = list(prepare)
|
3972
|
+
else:
|
3973
|
+
pfs = [prepare]
|
3974
|
+
for pf in pfs:
|
3975
|
+
config_dct = pf(config_dct)
|
3976
|
+
|
3977
|
+
return msh.unmarshal_obj(config_dct, cls)
|
3978
|
+
|
3979
|
+
|
3632
3980
|
########################################
|
3633
3981
|
# ../../../../../omlish/logs/standard.py
|
3634
3982
|
"""
|
@@ -4909,7 +5257,10 @@ def _main() -> None:
|
|
4909
5257
|
|
4910
5258
|
config: JournalctlToAwsDriver.Config
|
4911
5259
|
if args.config_file:
|
4912
|
-
config =
|
5260
|
+
config = load_config_file_obj(
|
5261
|
+
os.path.expanduser(args.config_file),
|
5262
|
+
JournalctlToAwsDriver.Config,
|
5263
|
+
)
|
4913
5264
|
else:
|
4914
5265
|
config = JournalctlToAwsDriver.Config()
|
4915
5266
|
|