ominfra 0.0.0.dev225__py3-none-any.whl → 0.0.0.dev227__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.
@@ -107,7 +107,7 @@ class JournalctlToAwsDriver(ExitStacked):
107
107
 
108
108
  def _ensure_locked(self) -> None:
109
109
  if (pf := self._pidfile()) is not None:
110
- pf.ensure_locked()
110
+ pf.acquire_lock()
111
111
 
112
112
  #
113
113
 
@@ -1953,6 +1953,7 @@ TODO:
1953
1953
  - 3) recheck current pid of flock holder == that pid
1954
1954
  - racy as to if it's a different actual process as initial check, just with same pid, but due to 'identity' / semantic
1955
1955
  meaning of the named pidfile the processes are considered equivalent
1956
+ - read_checked(), contextmanager
1956
1957
  """
1957
1958
 
1958
1959
 
@@ -1971,6 +1972,14 @@ class Pidfile:
1971
1972
  self._path = path
1972
1973
  self._inheritable = inheritable
1973
1974
 
1975
+ @property
1976
+ def path(self) -> str:
1977
+ return self._path
1978
+
1979
+ @property
1980
+ def inheritable(self) -> bool:
1981
+ return self._inheritable
1982
+
1974
1983
  def __repr__(self) -> str:
1975
1984
  return f'{self.__class__.__name__}({self._path!r})'
1976
1985
 
@@ -2014,6 +2023,7 @@ class Pidfile:
2014
2023
  state = self.__dict__.copy()
2015
2024
 
2016
2025
  if '_f' in state:
2026
+ # self._inheritable may be decoupled from actual file inheritability - for example when using the manager.
2017
2027
  if os.get_inheritable(fd := state.pop('_f').fileno()):
2018
2028
  state['__fd'] = fd
2019
2029
 
@@ -2038,7 +2048,7 @@ class Pidfile:
2038
2048
  del self._f
2039
2049
  return True
2040
2050
 
2041
- def try_lock(self) -> bool:
2051
+ def try_acquire_lock(self) -> bool:
2042
2052
  try:
2043
2053
  fcntl.flock(self._f, fcntl.LOCK_EX | fcntl.LOCK_NB)
2044
2054
  return True
@@ -2046,14 +2056,29 @@ class Pidfile:
2046
2056
  except OSError:
2047
2057
  return False
2048
2058
 
2049
- def ensure_locked(self) -> None:
2050
- if not self.try_lock():
2051
- raise RuntimeError('Could not get lock')
2059
+ #
2060
+
2061
+ class Error(Exception):
2062
+ pass
2063
+
2064
+ class LockedError(Error):
2065
+ pass
2066
+
2067
+ def acquire_lock(self) -> None:
2068
+ if not self.try_acquire_lock():
2069
+ raise self.LockedError
2070
+
2071
+ class NotLockedError(Error):
2072
+ pass
2073
+
2074
+ def ensure_cannot_lock(self) -> None:
2075
+ if self.try_acquire_lock():
2076
+ raise self.NotLockedError
2052
2077
 
2053
2078
  #
2054
2079
 
2055
2080
  def write(self, pid: ta.Optional[int] = None) -> None:
2056
- self.ensure_locked()
2081
+ self.acquire_lock()
2057
2082
 
2058
2083
  if pid is None:
2059
2084
  pid = os.getpid()
@@ -2064,21 +2089,26 @@ class Pidfile:
2064
2089
  self._f.flush()
2065
2090
 
2066
2091
  def clear(self) -> None:
2067
- self.ensure_locked()
2092
+ self.acquire_lock()
2068
2093
 
2069
2094
  self._f.seek(0)
2070
2095
  self._f.truncate()
2071
2096
 
2072
- def read(self) -> int:
2073
- if self.try_lock():
2074
- raise RuntimeError('Got lock')
2097
+ #
2098
+
2099
+ def read(self) -> ta.Optional[int]:
2100
+ self.ensure_cannot_lock()
2075
2101
 
2076
2102
  self._f.seek(0)
2077
- return int(self._f.read()) # FIXME: could be empty or hold old value, race w proc start
2103
+ buf = self._f.read()
2104
+ if not buf:
2105
+ return None
2106
+ return int(buf)
2078
2107
 
2079
2108
  def kill(self, sig: int = signal.SIGTERM) -> None:
2080
- pid = self.read()
2081
- os.kill(pid, sig) # FIXME: Still racy - pidfd_send_signal?
2109
+ if (pid := self.read()) is None:
2110
+ raise self.Error(f'Pidfile locked but empty')
2111
+ os.kill(pid, sig)
2082
2112
 
2083
2113
 
2084
2114
  ########################################
@@ -5034,7 +5064,7 @@ class JournalctlToAwsDriver(ExitStacked):
5034
5064
 
5035
5065
  def _ensure_locked(self) -> None:
5036
5066
  if (pf := self._pidfile()) is not None:
5037
- pf.ensure_locked()
5067
+ pf.acquire_lock()
5038
5068
 
5039
5069
  #
5040
5070
 
ominfra/scripts/manage.py CHANGED
@@ -77,9 +77,6 @@ VersionComparisonMethod = ta.Callable[[VersionCmpKey, VersionCmpKey], bool]
77
77
  # deploy/paths/types.py
78
78
  DeployPathKind = ta.Literal['dir', 'file'] # ta.TypeAlias
79
79
 
80
- # ../../omlish/asyncs/asyncio/timeouts.py
81
- AwaitableT = ta.TypeVar('AwaitableT', bound=ta.Awaitable)
82
-
83
80
  # ../../omlish/configs/types.py
84
81
  ConfigMap = ta.Mapping[str, ta.Any]
85
82
 
@@ -103,6 +100,9 @@ CheckOnRaiseFn = ta.Callable[[Exception], None] # ta.TypeAlias
103
100
  CheckExceptionFactory = ta.Callable[..., Exception] # ta.TypeAlias
104
101
  CheckArgsRenderer = ta.Callable[..., ta.Optional[str]] # ta.TypeAlias
105
102
 
103
+ # ../../omlish/lite/timeouts.py
104
+ TimeoutLike = ta.Union['Timeout', 'Timeout.Default', ta.Iterable['TimeoutLike'], float] # ta.TypeAlias
105
+
106
106
  # ../../omlish/lite/typing.py
107
107
  A0 = ta.TypeVar('A0')
108
108
  A1 = ta.TypeVar('A1')
@@ -120,6 +120,9 @@ CommandOutputT = ta.TypeVar('CommandOutputT', bound='Command.Output')
120
120
  # ../../omlish/argparse/cli.py
121
121
  ArgparseCmdFn = ta.Callable[[], ta.Optional[int]] # ta.TypeAlias
122
122
 
123
+ # ../../omlish/asyncs/asyncio/timeouts.py
124
+ AwaitableT = ta.TypeVar('AwaitableT', bound=ta.Awaitable)
125
+
123
126
  # ../../omlish/configs/formats.py
124
127
  ConfigDataT = ta.TypeVar('ConfigDataT', bound='ConfigData')
125
128
 
@@ -1204,19 +1207,6 @@ async def asyncio_open_stream_writer(
1204
1207
  )
1205
1208
 
1206
1209
 
1207
- ########################################
1208
- # ../../../omlish/asyncs/asyncio/timeouts.py
1209
-
1210
-
1211
- def asyncio_maybe_timeout(
1212
- fut: AwaitableT,
1213
- timeout: ta.Optional[float] = None,
1214
- ) -> AwaitableT:
1215
- if timeout is not None:
1216
- fut = asyncio.wait_for(fut, timeout) # type: ignore
1217
- return fut
1218
-
1219
-
1220
1210
  ########################################
1221
1211
  # ../../../omlish/configs/types.py
1222
1212
 
@@ -3067,6 +3057,205 @@ def format_num_bytes(num_bytes: int) -> str:
3067
3057
  return f'{num_bytes / 1024 ** (len(FORMAT_NUM_BYTES_SUFFIXES) - 1):.2f}{FORMAT_NUM_BYTES_SUFFIXES[-1]}'
3068
3058
 
3069
3059
 
3060
+ ########################################
3061
+ # ../../../omlish/lite/timeouts.py
3062
+ """
3063
+ TODO:
3064
+ - Event (/ Predicate)
3065
+ """
3066
+
3067
+
3068
+ ##
3069
+
3070
+
3071
+ class Timeout(abc.ABC):
3072
+ @property
3073
+ @abc.abstractmethod
3074
+ def can_expire(self) -> bool:
3075
+ """Indicates whether or not this timeout will ever expire."""
3076
+
3077
+ raise NotImplementedError
3078
+
3079
+ @abc.abstractmethod
3080
+ def expired(self) -> bool:
3081
+ """Return whether or not this timeout has expired."""
3082
+
3083
+ raise NotImplementedError
3084
+
3085
+ @abc.abstractmethod
3086
+ def remaining(self) -> float:
3087
+ """Returns the time (in seconds) remaining until the timeout expires. May be negative and/or infinite."""
3088
+
3089
+ raise NotImplementedError
3090
+
3091
+ @abc.abstractmethod
3092
+ def __call__(self) -> float:
3093
+ """Returns the time (in seconds) remaining until the timeout expires, or raises if the timeout has expired."""
3094
+
3095
+ raise NotImplementedError
3096
+
3097
+ @abc.abstractmethod
3098
+ def or_(self, o: ta.Any) -> ta.Any:
3099
+ """Evaluates time remaining via remaining() if this timeout can expire, otherwise returns `o`."""
3100
+
3101
+ raise NotImplementedError
3102
+
3103
+ #
3104
+
3105
+ @classmethod
3106
+ def _now(cls) -> float:
3107
+ return time.time()
3108
+
3109
+ #
3110
+
3111
+ class Default:
3112
+ def __new__(cls, *args, **kwargs): # noqa
3113
+ raise TypeError
3114
+
3115
+ class _NOT_SPECIFIED: # noqa
3116
+ def __new__(cls, *args, **kwargs): # noqa
3117
+ raise TypeError
3118
+
3119
+ @classmethod
3120
+ def of(
3121
+ cls,
3122
+ obj: ta.Optional[TimeoutLike],
3123
+ default: ta.Union[TimeoutLike, ta.Type[_NOT_SPECIFIED]] = _NOT_SPECIFIED,
3124
+ ) -> 'Timeout':
3125
+ if obj is None:
3126
+ return InfiniteTimeout()
3127
+
3128
+ elif isinstance(obj, Timeout):
3129
+ return obj
3130
+
3131
+ elif isinstance(obj, (float, int)):
3132
+ return DeadlineTimeout(cls._now() + obj)
3133
+
3134
+ elif isinstance(obj, ta.Iterable):
3135
+ return CompositeTimeout(*[Timeout.of(c) for c in obj])
3136
+
3137
+ elif obj is Timeout.Default:
3138
+ if default is Timeout._NOT_SPECIFIED or default is Timeout.Default:
3139
+ raise RuntimeError('Must specify a default timeout')
3140
+
3141
+ else:
3142
+ return Timeout.of(default) # type: ignore[arg-type]
3143
+
3144
+ else:
3145
+ raise TypeError(obj)
3146
+
3147
+ @classmethod
3148
+ def of_deadline(cls, deadline: float) -> 'DeadlineTimeout':
3149
+ return DeadlineTimeout(deadline)
3150
+
3151
+ @classmethod
3152
+ def of_predicate(cls, expired_fn: ta.Callable[[], bool]) -> 'PredicateTimeout':
3153
+ return PredicateTimeout(expired_fn)
3154
+
3155
+
3156
+ class DeadlineTimeout(Timeout):
3157
+ def __init__(
3158
+ self,
3159
+ deadline: float,
3160
+ exc: ta.Union[ta.Type[BaseException], BaseException] = TimeoutError,
3161
+ ) -> None:
3162
+ super().__init__()
3163
+
3164
+ self.deadline = deadline
3165
+ self.exc = exc
3166
+
3167
+ @property
3168
+ def can_expire(self) -> bool:
3169
+ return True
3170
+
3171
+ def expired(self) -> bool:
3172
+ return not (self.remaining() > 0)
3173
+
3174
+ def remaining(self) -> float:
3175
+ return self.deadline - self._now()
3176
+
3177
+ def __call__(self) -> float:
3178
+ if (rem := self.remaining()) > 0:
3179
+ return rem
3180
+ raise self.exc
3181
+
3182
+ def or_(self, o: ta.Any) -> ta.Any:
3183
+ return self()
3184
+
3185
+
3186
+ class InfiniteTimeout(Timeout):
3187
+ @property
3188
+ def can_expire(self) -> bool:
3189
+ return False
3190
+
3191
+ def expired(self) -> bool:
3192
+ return False
3193
+
3194
+ def remaining(self) -> float:
3195
+ return float('inf')
3196
+
3197
+ def __call__(self) -> float:
3198
+ return float('inf')
3199
+
3200
+ def or_(self, o: ta.Any) -> ta.Any:
3201
+ return o
3202
+
3203
+
3204
+ class CompositeTimeout(Timeout):
3205
+ def __init__(self, *children: Timeout) -> None:
3206
+ super().__init__()
3207
+
3208
+ self.children = children
3209
+
3210
+ @property
3211
+ def can_expire(self) -> bool:
3212
+ return any(c.can_expire for c in self.children)
3213
+
3214
+ def expired(self) -> bool:
3215
+ return any(c.expired() for c in self.children)
3216
+
3217
+ def remaining(self) -> float:
3218
+ return min(c.remaining() for c in self.children)
3219
+
3220
+ def __call__(self) -> float:
3221
+ return min(c() for c in self.children)
3222
+
3223
+ def or_(self, o: ta.Any) -> ta.Any:
3224
+ if self.can_expire:
3225
+ return self()
3226
+ return o
3227
+
3228
+
3229
+ class PredicateTimeout(Timeout):
3230
+ def __init__(
3231
+ self,
3232
+ expired_fn: ta.Callable[[], bool],
3233
+ exc: ta.Union[ta.Type[BaseException], BaseException] = TimeoutError,
3234
+ ) -> None:
3235
+ super().__init__()
3236
+
3237
+ self.expired_fn = expired_fn
3238
+ self.exc = exc
3239
+
3240
+ @property
3241
+ def can_expire(self) -> bool:
3242
+ return True
3243
+
3244
+ def expired(self) -> bool:
3245
+ return self.expired_fn()
3246
+
3247
+ def remaining(self) -> float:
3248
+ return float('inf')
3249
+
3250
+ def __call__(self) -> float:
3251
+ if not self.expired_fn():
3252
+ return float('inf')
3253
+ raise self.exc
3254
+
3255
+ def or_(self, o: ta.Any) -> ta.Any:
3256
+ return self()
3257
+
3258
+
3070
3259
  ########################################
3071
3260
  # ../../../omlish/lite/typing.py
3072
3261
 
@@ -5016,6 +5205,19 @@ class ArgparseCli:
5016
5205
  return fn()
5017
5206
 
5018
5207
 
5208
+ ########################################
5209
+ # ../../../omlish/asyncs/asyncio/timeouts.py
5210
+
5211
+
5212
+ def asyncio_maybe_timeout(
5213
+ fut: AwaitableT,
5214
+ timeout: ta.Optional[TimeoutLike] = None,
5215
+ ) -> AwaitableT:
5216
+ if timeout is not None:
5217
+ fut = asyncio.wait_for(fut, Timeout.of(timeout)()) # type: ignore
5218
+ return fut
5219
+
5220
+
5019
5221
  ########################################
5020
5222
  # ../../../omlish/configs/formats.py
5021
5223
  """
@@ -7323,17 +7525,43 @@ class SubprocessRunOutput(ta.Generic[T]):
7323
7525
  class SubprocessRun:
7324
7526
  cmd: ta.Sequence[str]
7325
7527
  input: ta.Any = None
7326
- timeout: ta.Optional[float] = None
7528
+ timeout: ta.Optional[TimeoutLike] = None
7327
7529
  check: bool = False
7328
7530
  capture_output: ta.Optional[bool] = None
7329
7531
  kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
7330
7532
 
7533
+ #
7534
+
7535
+ _FIELD_NAMES: ta.ClassVar[ta.FrozenSet[str]]
7536
+
7537
+ def replace(self, **kwargs: ta.Any) -> 'SubprocessRun':
7538
+ if not kwargs:
7539
+ return self
7540
+
7541
+ field_kws = {}
7542
+ extra_kws = {}
7543
+ for k, v in kwargs.items():
7544
+ if k in self._FIELD_NAMES:
7545
+ field_kws[k] = v
7546
+ else:
7547
+ extra_kws[k] = v
7548
+
7549
+ return dc.replace(self, **{
7550
+ **dict(kwargs={
7551
+ **(self.kwargs or {}),
7552
+ **extra_kws,
7553
+ }),
7554
+ **field_kws, # passing a kwarg named 'kwargs' intentionally clobbers
7555
+ })
7556
+
7557
+ #
7558
+
7331
7559
  @classmethod
7332
7560
  def of(
7333
7561
  cls,
7334
7562
  *cmd: str,
7335
7563
  input: ta.Any = None, # noqa
7336
- timeout: ta.Optional[float] = None,
7564
+ timeout: ta.Optional[TimeoutLike] = None,
7337
7565
  check: bool = False, # noqa
7338
7566
  capture_output: ta.Optional[bool] = None,
7339
7567
  **kwargs: ta.Any,
@@ -7354,20 +7582,25 @@ class SubprocessRun:
7354
7582
  def run(
7355
7583
  self,
7356
7584
  subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
7585
+ **kwargs: ta.Any,
7357
7586
  ) -> SubprocessRunOutput:
7358
7587
  if subprocesses is None:
7359
7588
  subprocesses = self._DEFAULT_SUBPROCESSES
7360
- return check.not_none(subprocesses).run_(self) # type: ignore[attr-defined]
7589
+ return check.not_none(subprocesses).run_(self.replace(**kwargs)) # type: ignore[attr-defined]
7361
7590
 
7362
7591
  _DEFAULT_ASYNC_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractAsyncSubprocesses
7363
7592
 
7364
7593
  async def async_run(
7365
7594
  self,
7366
7595
  async_subprocesses: ta.Optional[ta.Any] = None, # AbstractAsyncSubprocesses
7596
+ **kwargs: ta.Any,
7367
7597
  ) -> SubprocessRunOutput:
7368
7598
  if async_subprocesses is None:
7369
7599
  async_subprocesses = self._DEFAULT_ASYNC_SUBPROCESSES
7370
- return await check.not_none(async_subprocesses).run_(self) # type: ignore[attr-defined]
7600
+ return await check.not_none(async_subprocesses).run_(self.replace(**kwargs)) # type: ignore[attr-defined]
7601
+
7602
+
7603
+ SubprocessRun._FIELD_NAMES = frozenset(fld.name for fld in dc.fields(SubprocessRun)) # noqa
7371
7604
 
7372
7605
 
7373
7606
  ##
@@ -7384,11 +7617,19 @@ class SubprocessRunnable(abc.ABC, ta.Generic[T]):
7384
7617
 
7385
7618
  #
7386
7619
 
7387
- def run(self, subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractSubprocesses
7388
- return self.handle_run_output(self.make_run().run(subprocesses))
7620
+ def run(
7621
+ self,
7622
+ subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
7623
+ **kwargs: ta.Any,
7624
+ ) -> T:
7625
+ return self.handle_run_output(self.make_run().run(subprocesses, **kwargs))
7389
7626
 
7390
- async def async_run(self, async_subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractAsyncSubprocesses
7391
- return self.handle_run_output(await self.make_run().async_run(async_subprocesses))
7627
+ async def async_run(
7628
+ self,
7629
+ async_subprocesses: ta.Optional[ta.Any] = None, # AbstractAsyncSubprocesses
7630
+ **kwargs: ta.Any,
7631
+ ) -> T:
7632
+ return self.handle_run_output(await self.make_run().async_run(async_subprocesses, **kwargs))
7392
7633
 
7393
7634
 
7394
7635
  ########################################
@@ -9194,6 +9435,11 @@ class BaseSubprocesses(abc.ABC): # noqa
9194
9435
 
9195
9436
  #
9196
9437
 
9438
+ if 'timeout' in kwargs:
9439
+ kwargs['timeout'] = Timeout.of(kwargs['timeout']).or_(None)
9440
+
9441
+ #
9442
+
9197
9443
  return cmd, dict(
9198
9444
  env=env,
9199
9445
  shell=shell,
@@ -9828,7 +10074,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
9828
10074
  self,
9829
10075
  *cmd: str,
9830
10076
  input: ta.Any = None, # noqa
9831
- timeout: ta.Optional[float] = None,
10077
+ timeout: ta.Optional[TimeoutLike] = None,
9832
10078
  check: bool = False,
9833
10079
  capture_output: ta.Optional[bool] = None,
9834
10080
  **kwargs: ta.Any,
@@ -9905,6 +10151,11 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
9905
10151
 
9906
10152
  ########################################
9907
10153
  # ../../../omlish/subprocesses/sync.py
10154
+ """
10155
+ TODO:
10156
+ - popen
10157
+ - route check_calls through run_?
10158
+ """
9908
10159
 
9909
10160
 
9910
10161
  ##
@@ -9919,7 +10170,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
9919
10170
  self,
9920
10171
  *cmd: str,
9921
10172
  input: ta.Any = None, # noqa
9922
- timeout: ta.Optional[float] = None,
10173
+ timeout: ta.Optional[TimeoutLike] = None,
9923
10174
  check: bool = False,
9924
10175
  capture_output: ta.Optional[bool] = None,
9925
10176
  **kwargs: ta.Any,
@@ -10320,7 +10571,7 @@ class AsyncioProcessCommunicator:
10320
10571
  async def communicate(
10321
10572
  self,
10322
10573
  input: ta.Any = None, # noqa
10323
- timeout: ta.Optional[float] = None,
10574
+ timeout: ta.Optional[TimeoutLike] = None,
10324
10575
  ) -> Communication:
10325
10576
  return await asyncio_maybe_timeout(self._communicate(input), timeout)
10326
10577
 
@@ -10333,7 +10584,7 @@ class AsyncioSubprocesses(AbstractAsyncSubprocesses):
10333
10584
  self,
10334
10585
  proc: asyncio.subprocess.Process,
10335
10586
  input: ta.Any = None, # noqa
10336
- timeout: ta.Optional[float] = None,
10587
+ timeout: ta.Optional[TimeoutLike] = None,
10337
10588
  ) -> ta.Tuple[ta.Optional[bytes], ta.Optional[bytes]]:
10338
10589
  return await AsyncioProcessCommunicator(proc).communicate(input, timeout) # noqa
10339
10590
 
@@ -10344,7 +10595,7 @@ class AsyncioSubprocesses(AbstractAsyncSubprocesses):
10344
10595
  self,
10345
10596
  *cmd: str,
10346
10597
  shell: bool = False,
10347
- timeout: ta.Optional[float] = None,
10598
+ timeout: ta.Optional[TimeoutLike] = None,
10348
10599
  **kwargs: ta.Any,
10349
10600
  ) -> ta.AsyncGenerator[asyncio.subprocess.Process, None]:
10350
10601
  with self.prepare_and_wrap( *cmd, shell=shell, **kwargs) as (cmd, kwargs): # noqa
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ominfra
3
- Version: 0.0.0.dev225
3
+ Version: 0.0.0.dev227
4
4
  Summary: ominfra
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omdev==0.0.0.dev225
16
- Requires-Dist: omlish==0.0.0.dev225
15
+ Requires-Dist: omdev==0.0.0.dev227
16
+ Requires-Dist: omlish==0.0.0.dev227
17
17
  Provides-Extra: all
18
18
  Requires-Dist: paramiko~=3.5; extra == "all"
19
19
  Requires-Dist: asyncssh~=2.18; extra == "all"
@@ -20,7 +20,7 @@ ominfra/clouds/aws/instancetypes/cli.py,sha256=HcfOchROLGFsxmEIuXtXVywFJWjHOk4yv
20
20
  ominfra/clouds/aws/journald2aws/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
21
21
  ominfra/clouds/aws/journald2aws/__main__.py,sha256=d23loR_cKfTYZwYiqpt_CmKI7dd5WcYFgIYzqMep75E,68
22
22
  ominfra/clouds/aws/journald2aws/cursor.py,sha256=tQ7O6BHlEdaalbiI_Rqagj0aHfdtTQ_ZJwdOSRUjNvQ,1173
23
- ominfra/clouds/aws/journald2aws/driver.py,sha256=eXz32NbU_1rEB0tOnNg0KLIJ3tpRQcFKgA63lmpmZOc,6120
23
+ ominfra/clouds/aws/journald2aws/driver.py,sha256=bq9NQ8oNn3XRVuGoe7sZwtu4jXZ6r3eytSAJBYUtMko,6119
24
24
  ominfra/clouds/aws/journald2aws/main.py,sha256=sqs_IoLzadv0EJoWHnYdgg3bkDDSFshCvyRWByTm8Sg,2179
25
25
  ominfra/clouds/aws/journald2aws/poster.py,sha256=hz1XuctW8GtLmfjhRvCFY6py52D4BzXHYny5XKFpHSA,2833
26
26
  ominfra/clouds/aws/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -112,8 +112,8 @@ ominfra/manage/targets/connection.py,sha256=rVI1YJxFClcF-sdttqWyIz9_XjPI01GUdwxY
112
112
  ominfra/manage/targets/inject.py,sha256=P4597xWM-V3I_gCt2O71OLhYQkkXtuJvkYRsIbhhMcE,1561
113
113
  ominfra/manage/targets/targets.py,sha256=7GP6UAZyJFEhpkJN6UQdpr_WN3p7C76v-s445y-WB6U,1885
114
114
  ominfra/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
- ominfra/scripts/journald2aws.py,sha256=XZI8-2Z1kxCZz3qAS656HGwnYKtZx6tNiQI9xnWvdgY,164113
116
- ominfra/scripts/manage.py,sha256=ktyMVWd00ZCK3yEtaYT0CHJqP0tQvRXmt9XKO0V95RU,367611
115
+ ominfra/scripts/journald2aws.py,sha256=NUfhLpV9LFZeyQWNRkkCXYGMdPXyD2gj4F5PwDfxeDU,164683
116
+ ominfra/scripts/manage.py,sha256=zwqZl0SrFkGIuPNPLUxNXho8Ol6vV6XELLMnO0Ifrec,373794
117
117
  ominfra/scripts/supervisor.py,sha256=8vVoR8kq7Qh2z_NdOrDXXnNCu9N5TnOM2M5om4D-ZmA,296097
118
118
  ominfra/supervisor/LICENSE.txt,sha256=ZrHY15PVR98y26Yg6iQfa-SXnUaYTDhrUsPVcEO5OKM,1874
119
119
  ominfra/supervisor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
@@ -156,9 +156,9 @@ ominfra/tailscale/api.py,sha256=C5-t_b6jZXUWcy5k8bXm7CFnk73pSdrlMOgGDeGVrpw,1370
156
156
  ominfra/tailscale/cli.py,sha256=3FnJbgpLw6gInTfhERd1mDy9ijjMUGxkdYVo43Tnxx4,3555
157
157
  ominfra/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
158
  ominfra/tools/listresources.py,sha256=BxFoxtyF2aVEcW67ZD9QujoBkJBtvIxGmKqXvLwnEHo,6180
159
- ominfra-0.0.0.dev225.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
160
- ominfra-0.0.0.dev225.dist-info/METADATA,sha256=anqfSH5n5Dsr6-lbN9972BXw9Ep-dz86hI0NyjbKaoE,731
161
- ominfra-0.0.0.dev225.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
162
- ominfra-0.0.0.dev225.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
163
- ominfra-0.0.0.dev225.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
164
- ominfra-0.0.0.dev225.dist-info/RECORD,,
159
+ ominfra-0.0.0.dev227.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
160
+ ominfra-0.0.0.dev227.dist-info/METADATA,sha256=GdABnkToyX5q4QO7Wo3YgDsMb3PlCmDqRENlCE2TOTw,731
161
+ ominfra-0.0.0.dev227.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
162
+ ominfra-0.0.0.dev227.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
163
+ ominfra-0.0.0.dev227.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
164
+ ominfra-0.0.0.dev227.dist-info/RECORD,,