ominfra 0.0.0.dev120__py3-none-any.whl → 0.0.0.dev121__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 +4 -0
- ominfra/clouds/aws/journald2aws/driver.py +34 -13
- ominfra/clouds/aws/journald2aws/main.py +2 -5
- ominfra/configs.py +70 -0
- ominfra/deploy/_executor.py +1 -1
- ominfra/deploy/poly/_main.py +1 -1
- ominfra/pyremote/_runcommands.py +1 -1
- ominfra/scripts/journald2aws.py +994 -26
- ominfra/scripts/supervisor.py +1836 -138
- ominfra/supervisor/compat.py +13 -0
- ominfra/supervisor/configs.py +21 -0
- ominfra/supervisor/context.py +13 -2
- ominfra/supervisor/main.py +82 -11
- ominfra/supervisor/process.py +39 -4
- ominfra/supervisor/supervisor.py +23 -2
- ominfra/supervisor/types.py +5 -0
- ominfra/threadworkers.py +66 -9
- {ominfra-0.0.0.dev120.dist-info → ominfra-0.0.0.dev121.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev120.dist-info → ominfra-0.0.0.dev121.dist-info}/RECORD +23 -21
- {ominfra-0.0.0.dev120.dist-info → ominfra-0.0.0.dev121.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev120.dist-info → ominfra-0.0.0.dev121.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev120.dist-info → ominfra-0.0.0.dev121.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev120.dist-info → ominfra-0.0.0.dev121.dist-info}/top_level.txt +0 -0
| @@ -46,6 +46,7 @@ from omlish.lite.runtime import is_debugger_attached | |
| 46 46 |  | 
| 47 47 | 
             
            from ....journald.messages import JournalctlMessage  # noqa
         | 
| 48 48 | 
             
            from ....journald.tailer import JournalctlTailerWorker
         | 
| 49 | 
            +
            from ....threadworkers import ThreadWorkerGroup
         | 
| 49 50 | 
             
            from ..auth import AwsSigner
         | 
| 50 51 | 
             
            from ..logs import AwsLogMessageBuilder
         | 
| 51 52 | 
             
            from .cursor import JournalctlToAwsCursor
         | 
| @@ -63,6 +64,7 @@ class JournalctlToAwsDriver(ExitStacked): | |
| 63 64 | 
             
                    cursor_file: ta.Optional[str] = None
         | 
| 64 65 |  | 
| 65 66 | 
             
                    runtime_limit: ta.Optional[float] = None
         | 
| 67 | 
            +
                    heartbeat_age_limit: ta.Optional[float] = 60.
         | 
| 66 68 |  | 
| 67 69 | 
             
                    #
         | 
| 68 70 |  | 
| @@ -139,6 +141,12 @@ class JournalctlToAwsDriver(ExitStacked): | |
| 139 141 |  | 
| 140 142 | 
             
                #
         | 
| 141 143 |  | 
| 144 | 
            +
                @cached_nullary
         | 
| 145 | 
            +
                def _worker_group(self) -> ThreadWorkerGroup:
         | 
| 146 | 
            +
                    return ThreadWorkerGroup()
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                #
         | 
| 149 | 
            +
             | 
| 142 150 | 
             
                @cached_nullary
         | 
| 143 151 | 
             
                def _journalctl_message_queue(self):  # type: () -> queue.Queue[ta.Sequence[JournalctlMessage]]
         | 
| 144 152 | 
             
                    return queue.Queue()
         | 
| @@ -165,6 +173,8 @@ class JournalctlToAwsDriver(ExitStacked): | |
| 165 173 |  | 
| 166 174 | 
             
                        cmd=self._config.journalctl_cmd,
         | 
| 167 175 | 
             
                        shell_wrap=is_debugger_attached(),
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                        worker_groups=[self._worker_group()],
         | 
| 168 178 | 
             
                    )
         | 
| 169 179 |  | 
| 170 180 | 
             
                #
         | 
| @@ -178,26 +188,38 @@ class JournalctlToAwsDriver(ExitStacked): | |
| 178 188 |  | 
| 179 189 | 
             
                        ensure_locked=self._ensure_locked,
         | 
| 180 190 | 
             
                        dry_run=self._config.aws_dry_run,
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                        worker_groups=[self._worker_group()],
         | 
| 181 193 | 
             
                    )
         | 
| 182 194 |  | 
| 183 195 | 
             
                #
         | 
| 184 196 |  | 
| 185 | 
            -
                def  | 
| 186 | 
            -
                     | 
| 187 | 
            -
                     | 
| 197 | 
            +
                def _exit_contexts(self) -> None:
         | 
| 198 | 
            +
                    wg = self._worker_group()
         | 
| 199 | 
            +
                    wg.stop_all()
         | 
| 200 | 
            +
                    wg.join_all()
         | 
| 188 201 |  | 
| 189 | 
            -
             | 
| 202 | 
            +
                def run(self) -> None:
         | 
| 203 | 
            +
                    self._aws_poster_worker()
         | 
| 204 | 
            +
                    self._journalctl_tailer_worker()
         | 
| 190 205 |  | 
| 191 | 
            -
                     | 
| 192 | 
            -
             | 
| 206 | 
            +
                    wg = self._worker_group()
         | 
| 207 | 
            +
                    wg.start_all()
         | 
| 193 208 |  | 
| 194 209 | 
             
                    start = time.time()
         | 
| 195 210 |  | 
| 196 211 | 
             
                    while True:
         | 
| 197 | 
            -
                        for w in  | 
| 198 | 
            -
                             | 
| 199 | 
            -
             | 
| 200 | 
            -
             | 
| 212 | 
            +
                        for w in wg.get_dead():
         | 
| 213 | 
            +
                            log.critical('Worker died: %r', w)
         | 
| 214 | 
            +
                            break
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                        if (al := self._config.heartbeat_age_limit) is not None:
         | 
| 217 | 
            +
                            hbs = wg.check_heartbeats()
         | 
| 218 | 
            +
                            log.debug('Worker heartbeats: %r', hbs)
         | 
| 219 | 
            +
                            for w, age in hbs.items():
         | 
| 220 | 
            +
                                if age > al:
         | 
| 221 | 
            +
                                    log.critical('Worker heartbeat age limit exceeded: %r %f > %f', w, age, al)
         | 
| 222 | 
            +
                                    break
         | 
| 201 223 |  | 
| 202 224 | 
             
                        if (rl := self._config.runtime_limit) is not None and time.time() - start >= rl:
         | 
| 203 225 | 
             
                            log.warning('Runtime limit reached')
         | 
| @@ -205,6 +227,5 @@ class JournalctlToAwsDriver(ExitStacked): | |
| 205 227 |  | 
| 206 228 | 
             
                        time.sleep(1.)
         | 
| 207 229 |  | 
| 208 | 
            -
                     | 
| 209 | 
            -
             | 
| 210 | 
            -
                        w.join()
         | 
| 230 | 
            +
                    wg.stop_all()
         | 
| 231 | 
            +
                    wg.join_all()
         | 
| @@ -2,13 +2,12 @@ | |
| 2 2 | 
             
            # @omlish-amalg ../../../scripts/journald2aws.py
         | 
| 3 3 | 
             
            import argparse
         | 
| 4 4 | 
             
            import dataclasses as dc
         | 
| 5 | 
            -
            import json
         | 
| 6 5 | 
             
            import os.path
         | 
| 7 6 | 
             
            import sys
         | 
| 8 7 |  | 
| 9 8 | 
             
            from omlish.lite.logs import configure_standard_logging
         | 
| 10 | 
            -
            from omlish.lite.marshal import unmarshal_obj
         | 
| 11 9 |  | 
| 10 | 
            +
            from ....configs import read_config_file
         | 
| 12 11 | 
             
            from .driver import JournalctlToAwsDriver
         | 
| 13 12 |  | 
| 14 13 |  | 
| @@ -37,9 +36,7 @@ def _main() -> None: | |
| 37 36 |  | 
| 38 37 | 
             
                config: JournalctlToAwsDriver.Config
         | 
| 39 38 | 
             
                if args.config_file:
         | 
| 40 | 
            -
                     | 
| 41 | 
            -
                        config_dct = json.load(cf)
         | 
| 42 | 
            -
                    config = unmarshal_obj(config_dct, JournalctlToAwsDriver.Config)
         | 
| 39 | 
            +
                    config = read_config_file(os.path.expanduser(args.config_file), JournalctlToAwsDriver.Config)
         | 
| 43 40 | 
             
                else:
         | 
| 44 41 | 
             
                    config = JournalctlToAwsDriver.Config()
         | 
| 45 42 |  | 
    
        ominfra/configs.py
    ADDED
    
    | @@ -0,0 +1,70 @@ | |
| 1 | 
            +
            # ruff: noqa: UP006 UP007
         | 
| 2 | 
            +
            # @omlish-lite
         | 
| 3 | 
            +
            import json
         | 
| 4 | 
            +
            import typing as ta
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            from omdev.toml.parser import toml_loads
         | 
| 7 | 
            +
            from omlish.lite.check import check_isinstance
         | 
| 8 | 
            +
            from omlish.lite.check import check_not_isinstance
         | 
| 9 | 
            +
            from omlish.lite.marshal import unmarshal_obj
         | 
| 10 | 
            +
             | 
| 11 | 
            +
             | 
| 12 | 
            +
            T = ta.TypeVar('T')
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ConfigMapping = ta.Mapping[str, ta.Any]
         | 
| 15 | 
            +
             | 
| 16 | 
            +
             | 
| 17 | 
            +
            def read_config_file(
         | 
| 18 | 
            +
                    path: str,
         | 
| 19 | 
            +
                    cls: ta.Type[T],
         | 
| 20 | 
            +
                    *,
         | 
| 21 | 
            +
                    prepare: ta.Optional[ta.Callable[[ConfigMapping], ConfigMapping]] = None,
         | 
| 22 | 
            +
            ) -> T:
         | 
| 23 | 
            +
                with open(path) as cf:
         | 
| 24 | 
            +
                    if path.endswith('.toml'):
         | 
| 25 | 
            +
                        config_dct = toml_loads(cf.read())
         | 
| 26 | 
            +
                    else:
         | 
| 27 | 
            +
                        config_dct = json.loads(cf.read())
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                if prepare is not None:
         | 
| 30 | 
            +
                    config_dct = prepare(config_dct)  # type: ignore
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                return unmarshal_obj(config_dct, cls)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
             | 
| 35 | 
            +
            def build_config_named_children(
         | 
| 36 | 
            +
                    o: ta.Union[
         | 
| 37 | 
            +
                        ta.Sequence[ConfigMapping],
         | 
| 38 | 
            +
                        ta.Mapping[str, ConfigMapping],
         | 
| 39 | 
            +
                        None,
         | 
| 40 | 
            +
                    ],
         | 
| 41 | 
            +
                    *,
         | 
| 42 | 
            +
                    name_key: str = 'name',
         | 
| 43 | 
            +
            ) -> ta.Optional[ta.Sequence[ConfigMapping]]:
         | 
| 44 | 
            +
                if o is None:
         | 
| 45 | 
            +
                    return None
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                lst: ta.List[ConfigMapping] = []
         | 
| 48 | 
            +
                if isinstance(o, ta.Mapping):
         | 
| 49 | 
            +
                    for k, v in o.items():
         | 
| 50 | 
            +
                        check_isinstance(v, ta.Mapping)
         | 
| 51 | 
            +
                        if name_key in v:
         | 
| 52 | 
            +
                            n = v[name_key]
         | 
| 53 | 
            +
                            if k != n:
         | 
| 54 | 
            +
                                raise KeyError(f'Given names do not match: {n} != {k}')
         | 
| 55 | 
            +
                            lst.append(v)
         | 
| 56 | 
            +
                        else:
         | 
| 57 | 
            +
                            lst.append({name_key: k, **v})
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                else:
         | 
| 60 | 
            +
                    check_not_isinstance(o, str)
         | 
| 61 | 
            +
                    lst.extend(o)
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                seen = set()
         | 
| 64 | 
            +
                for d in lst:
         | 
| 65 | 
            +
                    n = d['name']
         | 
| 66 | 
            +
                    if n in d:
         | 
| 67 | 
            +
                        raise KeyError(f'Duplicate name: {n}')
         | 
| 68 | 
            +
                    seen.add(n)
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                return lst
         | 
    
        ominfra/deploy/_executor.py
    CHANGED
    
    
    
        ominfra/deploy/poly/_main.py
    CHANGED
    
    
    
        ominfra/pyremote/_runcommands.py
    CHANGED