ominfra 0.0.0.dev90__py3-none-any.whl → 0.0.0.dev92__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -32,9 +32,10 @@ def compact_traceback() -> ta.Tuple[
32
32
  types.TracebackType,
33
33
  ]:
34
34
  t, v, tb = sys.exc_info()
35
- tbinfo = []
36
35
  if not tb:
37
36
  raise RuntimeError('No traceback')
37
+
38
+ tbinfo = []
38
39
  while tb:
39
40
  tbinfo.append((
40
41
  tb.tb_frame.f_code.co_filename,
@@ -72,6 +73,7 @@ def decode_wait_status(sts: int) -> ta.Tuple[int, str]:
72
73
  Return a tuple (exitstatus, message) where exitstatus is the exit status, or -1 if the process was killed by a
73
74
  signal; and message is a message telling what happened. It is the caller's responsibility to display the message.
74
75
  """
76
+
75
77
  if os.WIFEXITED(sts):
76
78
  es = os.WEXITSTATUS(sts) & 0xffff
77
79
  msg = f'exit status {es}'
@@ -171,6 +173,7 @@ def real_exit(code: int) -> None:
171
173
 
172
174
  def get_path() -> ta.Sequence[str]:
173
175
  """Return a list corresponding to $PATH, or a default."""
176
+
174
177
  path = ['/bin', '/usr/bin', '/usr/local/bin']
175
178
  if 'PATH' in os.environ:
176
179
  p = os.environ['PATH']
@@ -187,8 +190,9 @@ ANSI_ESCAPE_BEGIN = b'\x1b['
187
190
  ANSI_TERMINATORS = (b'H', b'f', b'A', b'B', b'C', b'D', b'R', b's', b'u', b'J', b'K', b'h', b'l', b'p', b'm')
188
191
 
189
192
 
190
- def strip_escapes(s):
193
+ def strip_escapes(s: bytes) -> bytes:
191
194
  """Remove all ANSI color escapes from the given string."""
195
+
192
196
  result = b''
193
197
  show = 1
194
198
  i = 0
@@ -12,6 +12,59 @@ from .datatypes import logging_level
12
12
  from .datatypes import octal_type
13
13
 
14
14
 
15
+ @dc.dataclass(frozen=True)
16
+ class ProcessConfig:
17
+ name: str
18
+ command: str
19
+
20
+ uid: ta.Optional[int] = None
21
+ directory: ta.Optional[str] = None
22
+ umask: ta.Optional[int] = None
23
+ priority: int = 999
24
+
25
+ autostart: bool = True
26
+ autorestart: str = 'unexpected'
27
+
28
+ startsecs: int = 1
29
+ startretries: int = 3
30
+
31
+ numprocs: int = 1
32
+ numprocs_start: int = 0
33
+
34
+ @dc.dataclass(frozen=True)
35
+ class Log:
36
+ file: ta.Optional[str] = None
37
+ capture_maxbytes: ta.Optional[int] = None
38
+ events_enabled: bool = False
39
+ syslog: bool = False
40
+ backups: ta.Optional[int] = None
41
+ maxbytes: ta.Optional[int] = None
42
+
43
+ stdout: Log = Log()
44
+ stderr: Log = Log()
45
+
46
+ stopsignal: int = signal.SIGTERM
47
+ stopwaitsecs: int = 10
48
+ stopasgroup: bool = False
49
+
50
+ killasgroup: bool = False
51
+
52
+ exitcodes: ta.Sequence[int] = (0,)
53
+
54
+ redirect_stderr: bool = False
55
+
56
+ environment: ta.Optional[ta.Mapping[str, str]] = None
57
+
58
+
59
+ @dc.dataclass(frozen=True)
60
+ class ProcessGroupConfig:
61
+ name: str
62
+
63
+ priority: int = 999
64
+
65
+ processes: ta.Optional[ta.Sequence[ProcessConfig]] = None
66
+
67
+
15
68
  @dc.dataclass(frozen=True)
16
69
  class ServerConfig:
17
70
  user: ta.Optional[str] = None
@@ -31,7 +84,7 @@ class ServerConfig:
31
84
  strip_ansi: bool = False
32
85
  silent: bool = False
33
86
 
34
- groups: ta.Optional[ta.Sequence['ProcessGroupConfig']] = None
87
+ groups: ta.Optional[ta.Sequence[ProcessGroupConfig]] = None
35
88
 
36
89
  @classmethod
37
90
  def new(
@@ -55,56 +108,3 @@ class ServerConfig:
55
108
  child_logdir=child_logdir if child_logdir else tempfile.gettempdir(),
56
109
  **kwargs,
57
110
  )
58
-
59
-
60
- @dc.dataclass(frozen=True)
61
- class ProcessGroupConfig:
62
- name: str
63
-
64
- priority: int = 999
65
-
66
- processes: ta.Optional[ta.Sequence['ProcessConfig']] = None
67
-
68
-
69
- @dc.dataclass(frozen=True)
70
- class ProcessConfig:
71
- name: str
72
- command: str
73
-
74
- uid: ta.Optional[int] = None
75
- directory: ta.Optional[str] = None
76
- umask: ta.Optional[int] = None
77
- priority: int = 999
78
-
79
- autostart: bool = True
80
- autorestart: str = 'unexpected'
81
-
82
- startsecs: int = 1
83
- startretries: int = 3
84
-
85
- numprocs: int = 1
86
- numprocs_start: int = 0
87
-
88
- @dc.dataclass(frozen=True)
89
- class Log:
90
- file: ta.Optional[str] = None
91
- capture_maxbytes: ta.Optional[int] = None
92
- events_enabled: bool = False
93
- syslog: bool = False
94
- backups: ta.Optional[int] = None
95
- maxbytes: ta.Optional[int] = None
96
-
97
- stdout: Log = Log()
98
- stderr: Log = Log()
99
-
100
- stopsignal: int = signal.SIGTERM
101
- stopwaitsecs: int = 10
102
- stopasgroup: bool = False
103
-
104
- killasgroup: bool = False
105
-
106
- exitcodes: ta.Iterable[int] = (0,)
107
-
108
- redirect_stderr: bool = False
109
-
110
- environment: ta.Optional[ta.Mapping[str, str]] = None
@@ -114,6 +114,7 @@ class ServerContext(AbstractServerContext):
114
114
  Set the uid of the supervisord process. Called during supervisord startup only. No return value. Exits the
115
115
  process via usage() if privileges could not be dropped.
116
116
  """
117
+
117
118
  if self.uid is None:
118
119
  if os.getuid() == 0:
119
120
  warnings.warn(
@@ -293,6 +294,7 @@ def drop_privileges(user: ta.Union[int, str, None]) -> ta.Optional[str]:
293
294
  and when spawning subprocesses. Returns None on success or a string error message if privileges could not be
294
295
  dropped.
295
296
  """
297
+
296
298
  if user is None:
297
299
  return 'No user specified to setuid to!'
298
300
 
@@ -151,15 +151,19 @@ SIGNUMS = [getattr(signal, k) for k in dir(signal) if k.startswith('SIG')]
151
151
  def signal_number(value: ta.Union[int, str]) -> int:
152
152
  try:
153
153
  num = int(value)
154
+
154
155
  except (ValueError, TypeError):
155
156
  name = value.strip().upper() # type: ignore
156
157
  if not name.startswith('SIG'):
157
158
  name = f'SIG{name}'
159
+
158
160
  num = getattr(signal, name, None) # type: ignore
159
161
  if num is None:
160
162
  raise ValueError(f'value {value!r} is not a valid signal name') # noqa
163
+
161
164
  if num not in SIGNUMS:
162
165
  raise ValueError(f'value {value!r} is not a valid signal number')
166
+
163
167
  return num
164
168
 
165
169
 
@@ -93,7 +93,9 @@ class OutputDispatcher(Dispatcher):
93
93
 
94
94
  `event_type` should be one of ProcessLogStdoutEvent or ProcessLogStderrEvent
95
95
  """
96
+
96
97
  super().__init__(process, event_type.channel, fd)
98
+
97
99
  self.event_type = event_type
98
100
 
99
101
  self.lc: ProcessConfig.Log = getattr(process.config, self._channel)
@@ -107,25 +109,30 @@ class OutputDispatcher(Dispatcher):
107
109
  self._output_buffer = b'' # data waiting to be logged
108
110
 
109
111
  # all code below is purely for minor speedups
112
+
110
113
  begin_token = self.event_type.BEGIN_TOKEN
111
114
  end_token = self.event_type.END_TOKEN
112
- self.begin_token_data = (begin_token, len(begin_token))
113
- self.end_token_data = (end_token, len(end_token))
114
- self.main_log_level = logging.DEBUG
115
+ self._begin_token_data = (begin_token, len(begin_token))
116
+ self._end_token_data = (end_token, len(end_token))
117
+
118
+ self._main_log_level = logging.DEBUG
119
+
120
+ self._log_to_main_log = process.context.config.loglevel <= self._main_log_level
121
+
115
122
  config = self._process.config
116
- self.log_to_main_log = process.context.config.loglevel <= self.main_log_level
117
- self.stdout_events_enabled = config.stdout.events_enabled
118
- self.stderr_events_enabled = config.stderr.events_enabled
123
+ self._stdout_events_enabled = config.stdout.events_enabled
124
+ self._stderr_events_enabled = config.stderr.events_enabled
119
125
 
120
- _child_log: ta.Optional[logging.Logger] # the current logger (normal_log or capture_log)
121
- _normal_log: ta.Optional[logging.Logger] # the "normal" (non-capture) logger
122
- _capture_log: ta.Optional[logging.Logger] # the logger used while we're in capture_mode
126
+ _child_log: ta.Optional[logging.Logger] = None # the current logger (normal_log or capture_log)
127
+ _normal_log: ta.Optional[logging.Logger] = None # the "normal" (non-capture) logger
128
+ _capture_log: ta.Optional[logging.Logger] = None # the logger used while we're in capture_mode
123
129
 
124
130
  def _init_normal_log(self) -> None:
125
131
  """
126
132
  Configure the "normal" (non-capture) log for this channel of this process. Sets self.normal_log if logging is
127
133
  enabled.
128
134
  """
135
+
129
136
  config = self._process.config # noqa
130
137
  channel = self._channel # noqa
131
138
 
@@ -146,7 +153,7 @@ class OutputDispatcher(Dispatcher):
146
153
  # maxbytes=maxbytes,
147
154
  # backups=backups,
148
155
  # )
149
- #
156
+
150
157
  # if to_syslog:
151
158
  # loggers.handle_syslog(
152
159
  # self.normal_log,
@@ -158,6 +165,7 @@ class OutputDispatcher(Dispatcher):
158
165
  Configure the capture log for this process. This log is used to temporarily capture output when special output
159
166
  is detected. Sets self.capture_log if capturing is enabled.
160
167
  """
168
+
161
169
  capture_maxbytes = self.lc.capture_maxbytes
162
170
  if capture_maxbytes:
163
171
  self._capture_log = logging.getLogger(__name__)
@@ -184,9 +192,11 @@ class OutputDispatcher(Dispatcher):
184
192
  if data:
185
193
  if self._process.context.config.strip_ansi:
186
194
  data = strip_escapes(data)
195
+
187
196
  if self._child_log:
188
197
  self._child_log.info(data)
189
- if self.log_to_main_log:
198
+
199
+ if self._log_to_main_log:
190
200
  if not isinstance(data, bytes):
191
201
  text = data
192
202
  else:
@@ -194,11 +204,13 @@ class OutputDispatcher(Dispatcher):
194
204
  text = data.decode('utf-8')
195
205
  except UnicodeDecodeError:
196
206
  text = f'Undecodable: {data!r}'
197
- log.log(self.main_log_level, '%r %s output:\n%s', self._process.config.name, self._channel, text) # noqa
207
+ log.log(self._main_log_level, '%r %s output:\n%s', self._process.config.name, self._channel, text) # noqa
208
+
198
209
  if self._channel == 'stdout':
199
- if self.stdout_events_enabled:
210
+ if self._stdout_events_enabled:
200
211
  notify_event(ProcessLogStdoutEvent(self._process, self._process.pid, data))
201
- elif self.stderr_events_enabled:
212
+
213
+ elif self._stderr_events_enabled:
202
214
  notify_event(ProcessLogStderrEvent(self._process, self._process.pid, data))
203
215
 
204
216
  def record_output(self):
@@ -210,9 +222,9 @@ class OutputDispatcher(Dispatcher):
210
222
  return
211
223
 
212
224
  if self._capture_mode:
213
- token, tokenlen = self.end_token_data
225
+ token, tokenlen = self._end_token_data
214
226
  else:
215
- token, tokenlen = self.begin_token_data
227
+ token, tokenlen = self._begin_token_data
216
228
 
217
229
  if len(self._output_buffer) <= tokenlen:
218
230
  return # not enough data
@@ -1,4 +1,5 @@
1
1
  # ruff: noqa: UP006 UP007
2
+ import abc
2
3
  import typing as ta
3
4
 
4
5
  from .compat import as_string
@@ -32,12 +33,11 @@ notify_event = EVENT_CALLBACKS.notify
32
33
  clear_events = EVENT_CALLBACKS.clear
33
34
 
34
35
 
35
- class Event:
36
+ class Event(abc.ABC): # noqa
36
37
  """Abstract event type """
37
38
 
38
39
 
39
- class ProcessLogEvent(Event):
40
- """Abstract"""
40
+ class ProcessLogEvent(Event, abc.ABC):
41
41
  channel: ta.Optional[str] = None
42
42
 
43
43
  def __init__(self, process, pid, data):
@@ -54,8 +54,8 @@ class ProcessLogEvent(Event):
54
54
  data = as_string(self.data)
55
55
  except UnicodeDecodeError:
56
56
  data = f'Undecodable: {self.data!r}'
57
- fmt = as_string('processname:%s groupname:%s pid:%s channel:%s\n%s')
58
- result = fmt % (
57
+
58
+ result = 'processname:%s groupname:%s pid:%s channel:%s\n%s' % ( # noqa
59
59
  as_string(self.process.config.name),
60
60
  as_string(groupname),
61
61
  self.pid,
@@ -73,8 +73,7 @@ class ProcessLogStderrEvent(ProcessLogEvent):
73
73
  channel = 'stderr'
74
74
 
75
75
 
76
- class ProcessCommunicationEvent(Event):
77
- """ Abstract """
76
+ class ProcessCommunicationEvent(Event, abc.ABC):
78
77
  # event mode tokens
79
78
  BEGIN_TOKEN = b'<!--XSUPERVISOR:BEGIN-->'
80
79
  END_TOKEN = b'<!--XSUPERVISOR:END-->'
@@ -1,18 +1,20 @@
1
1
  class ProcessError(Exception):
2
- """ Specialized exceptions used when attempting to start a process """
2
+ """Specialized exceptions used when attempting to start a process."""
3
3
 
4
4
 
5
5
  class BadCommandError(ProcessError):
6
- """ Indicates the command could not be parsed properly. """
6
+ """Indicates the command could not be parsed properly."""
7
7
 
8
8
 
9
9
  class NotExecutableError(ProcessError):
10
- """ Indicates that the filespec cannot be executed because its path
11
- resolves to a file which is not executable, or which is a directory. """
10
+ """
11
+ Indicates that the filespec cannot be executed because its path resolves to a file which is not executable, or which
12
+ is a directory.
13
+ """
12
14
 
13
15
 
14
16
  class NotFoundError(ProcessError):
15
- """ Indicates that the filespec cannot be executed because it could not be found """
17
+ """Indicates that the filespec cannot be executed because it could not be found."""
16
18
 
17
19
 
18
20
  class NoPermissionError(ProcessError):
@@ -143,6 +143,7 @@ class Subprocess(AbstractSubprocess):
143
143
  Internal: turn a program name into a file name, using $PATH, make sure it exists / is executable, raising a
144
144
  ProcessError if not
145
145
  """
146
+
146
147
  try:
147
148
  commandargs = shlex.split(self.config.command)
148
149
  except ValueError as e:
@@ -526,8 +527,12 @@ class Subprocess(AbstractSubprocess):
526
527
  os.kill(self.pid, sig)
527
528
  except OSError as exc:
528
529
  if exc.errno == errno.ESRCH:
529
- log.debug('unable to signal %s (pid %s), it probably just now exited '
530
- 'on its own: %s', processname, self.pid, str(exc))
530
+ log.debug(
531
+ 'unable to signal %s (pid %s), it probably just now exited on its own: %s',
532
+ processname,
533
+ self.pid,
534
+ str(exc),
535
+ )
531
536
  # we could change the state here but we intentionally do not. we will do it during normal SIGCHLD
532
537
  # processing.
533
538
  return None
@@ -543,6 +548,7 @@ class Subprocess(AbstractSubprocess):
543
548
 
544
549
  def finish(self, sts: int) -> None:
545
550
  """ The process was reaped and we need to report and manage its state """
551
+
546
552
  self.drain()
547
553
 
548
554
  es, msg = decode_wait_status(sts)
@@ -559,9 +565,11 @@ class Subprocess(AbstractSubprocess):
559
565
  else:
560
566
  too_quickly = False
561
567
  log.warning(
562
- "process '%s' (%s) laststart time is in the future, don't "
563
- "know how long process was running so assuming it did "
564
- "not exit too quickly", processname, self.pid)
568
+ "process '%s' (%s) laststart time is in the future, don't know how long process was running so "
569
+ "assuming it did not exit too quickly",
570
+ processname,
571
+ self.pid,
572
+ )
565
573
 
566
574
  exit_expected = es in self.config.exitcodes
567
575
 
@@ -658,7 +666,7 @@ class Subprocess(AbstractSubprocess):
658
666
  if self.config.autorestart is RestartUnconditionally:
659
667
  # EXITED -> STARTING
660
668
  self.spawn()
661
- elif self.exitstatus not in self.config.exitcodes: # type: ignore
669
+ elif self.exitstatus not in self.config.exitcodes:
662
670
  # EXITED -> STARTING
663
671
  self.spawn()
664
672
 
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # ruff: noqa: UP006 UP007
3
3
  # @omlish-amalg ../scripts/supervisor.py
4
+ import json
4
5
  import logging
5
6
  import signal
6
7
  import time
@@ -8,12 +9,12 @@ import typing as ta
8
9
 
9
10
  from omlish.lite.check import check_not_none
10
11
  from omlish.lite.logs import configure_standard_logging
12
+ from omlish.lite.marshal import unmarshal_obj
11
13
 
12
14
  from .compat import ExitNow
13
15
  from .compat import as_string
14
16
  from .compat import decode_wait_status
15
17
  from .compat import signame
16
- from .configs import ProcessConfig
17
18
  from .configs import ProcessGroupConfig
18
19
  from .configs import ServerConfig
19
20
  from .context import ServerContext
@@ -331,39 +332,24 @@ def timeslice(period, when):
331
332
 
332
333
 
333
334
  def main(args=None, test=False):
335
+ import argparse
336
+
337
+ parser = argparse.ArgumentParser()
338
+ parser.add_argument('config_file', metavar='config-file')
339
+ args = parser.parse_args()
340
+
334
341
  configure_standard_logging('INFO')
335
342
 
343
+ if not (cf := args.config_file):
344
+ raise RuntimeError('No config file specified')
345
+
336
346
  # if we hup, restart by making a new Supervisor()
337
347
  first = True
338
348
  while True:
339
- config = ServerConfig.new(
340
- nodaemon=True,
341
- groups=[
342
- ProcessGroupConfig(
343
- name='default',
344
- processes=[
345
- ProcessConfig(
346
- name='sleep',
347
- command='sleep 600',
348
- stdout=ProcessConfig.Log(
349
- file='/dev/fd/1',
350
- maxbytes=0,
351
- ),
352
- redirect_stderr=True,
353
- ),
354
- ProcessConfig(
355
- name='ls',
356
- command='ls -al',
357
- stdout=ProcessConfig.Log(
358
- file='/dev/fd/1',
359
- maxbytes=0,
360
- ),
361
- redirect_stderr=True,
362
- ),
363
- ],
364
- ),
365
- ],
366
- )
349
+ with open(cf) as f:
350
+ config_src = f.read()
351
+ config_dct = json.loads(config_src)
352
+ config: ServerConfig = unmarshal_obj(config_dct, ServerConfig)
367
353
 
368
354
  context = ServerContext(
369
355
  config,
@@ -1,4 +1,10 @@
1
1
  # ruff: noqa: UP007
2
+ # @omlish-lite
3
+ """
4
+ TODO:
5
+ - implement stop lol
6
+ - collective heartbeat monitoring - ThreadWorkerGroups
7
+ """
2
8
  import abc
3
9
  import threading
4
10
  import time
@@ -59,6 +65,3 @@ class ThreadWorker(abc.ABC):
59
65
 
60
66
  def stop(self) -> None:
61
67
  raise NotImplementedError
62
-
63
- def cleanup(self) -> None: # noqa
64
- pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ominfra
3
- Version: 0.0.0.dev90
3
+ Version: 0.0.0.dev92
4
4
  Summary: ominfra
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -10,10 +10,10 @@ Classifier: Development Status :: 2 - Pre-Alpha
10
10
  Classifier: Intended Audience :: Developers
11
11
  Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
- Requires-Python: ~=3.12
13
+ Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omdev ==0.0.0.dev90
16
- Requires-Dist: omlish ==0.0.0.dev90
15
+ Requires-Dist: omdev ==0.0.0.dev92
16
+ Requires-Dist: omlish ==0.0.0.dev92
17
17
  Provides-Extra: all
18
18
  Requires-Dist: paramiko ~=3.5 ; extra == 'all'
19
19
  Requires-Dist: asyncssh ~=2.18 ; extra == 'all'
@@ -3,21 +3,17 @@ ominfra/__about__.py,sha256=6i1AoruFYQCd-PyhhbDQDWY2d1tiQu9nkwWr-fXAqfY,705
3
3
  ominfra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  ominfra/cmds.py,sha256=E0AfnvEmnKntXWvmLW5L05_NeDpBET1VBXn7vV6EwBQ,2083
5
5
  ominfra/ssh.py,sha256=jQpc4WvkMckIfk4vILda8zFaeharRqc_6wxW50b0OjQ,5431
6
+ ominfra/threadworker.py,sha256=8rnWvgKjPIAdctS6wxiUiEIzm-mORRkWVD94YghVj0g,1413
6
7
  ominfra/clouds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
8
  ominfra/clouds/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
9
  ominfra/clouds/aws/__main__.py,sha256=HXMoxEl9KHhv6zOOPQxiJAftfR2SjBqeVTYw-og9aFw,163
9
10
  ominfra/clouds/aws/auth.py,sha256=p50hnm8SU4CWAkLX0C4XCTAm7yAAg-HqcP1YvL5cW94,6205
10
11
  ominfra/clouds/aws/cli.py,sha256=OJVVLIwSy1378drkgP1ke_JltbyzBmnrB_Lom6A83os,510
11
12
  ominfra/clouds/aws/dataclasses.py,sha256=rKhtJKJ0JhMssU9n9CABX_JaUiokIboEATJ9TZgZQ6A,3868
12
- ominfra/clouds/aws/logs.py,sha256=VIT1fQazuaVSOfIlIcA9IxGT0Bqb69dbqcnbaTMEvSE,5185
13
+ ominfra/clouds/aws/logs.py,sha256=7Cl9vjco6G-5wW06TmuzU9GZ-diFP8V26X2UZnfJD3U,5232
13
14
  ominfra/clouds/aws/metadata.py,sha256=XR1BuMdQheyeFjjA3MN8GCNWVAp5ahoPdbWXEmViutQ,2767
14
15
  ominfra/clouds/aws/journald2aws/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
15
- ominfra/clouds/aws/journald2aws/main.py,sha256=LIDVHMVl0FmQGYKxdR78bhM1s5GOyY1VYDUH96FvVvY,8510
16
- ominfra/clouds/aws/journald2aws/threadworker.py,sha256=JFOrfBmDxQKCwk13qJ8-Zs8fxueMpHu0qRTEssdI7J0,1359
17
- ominfra/clouds/aws/journald2aws/journald/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
18
- ominfra/clouds/aws/journald2aws/journald/genmessages.py,sha256=3lB3W_Xl4GLAutNu1KvihdtMvkkukYqrfsamcqOS204,1583
19
- ominfra/clouds/aws/journald2aws/journald/messages.py,sha256=YBU7mbMtqnuamQKM-fGoraJNlbfzf-c1g8bC0ATSnt4,1975
20
- ominfra/clouds/aws/journald2aws/journald/tailer.py,sha256=XldM5QCZovJkfcot5hByj9Jq-F8sAptx65IPmrMo8b4,3042
16
+ ominfra/clouds/aws/journald2aws/main.py,sha256=d7jSbcaxjGgpVpDCPl1kJCOZg3S7g2n0Lf7gI0ZL3j0,9126
21
17
  ominfra/deploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
18
  ominfra/deploy/_executor.py,sha256=zHn4zAz6Ch1i5R_EdKTfJv_4SE0QPNuQEk7O1ptB_7A,32834
23
19
  ominfra/deploy/configs.py,sha256=qi0kwT7G2NH7dXLOQic-u6R3yeadup_QtvrjwWIggbM,435
@@ -45,6 +41,10 @@ ominfra/deploy/poly/runtime.py,sha256=G66AI-a27Wi6QYpG3M0ryqI7c5MnJkXt-_j9Qi8UiU
45
41
  ominfra/deploy/poly/site.py,sha256=QJwDDJoVm2-kxi4bxIrp-mn4y2qDLuW3CAUax3W8gv8,239
46
42
  ominfra/deploy/poly/supervisor.py,sha256=zkl6VQBcAZaMAhyR9DbbbqULcgFCDZoe9S_vP-mMFQ8,2289
47
43
  ominfra/deploy/poly/venv.py,sha256=BoipDEa4NTeodjf3L57KJfq9eGKLagFNKwD8pS4yrzA,1552
44
+ ominfra/journald/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ ominfra/journald/genmessages.py,sha256=3lB3W_Xl4GLAutNu1KvihdtMvkkukYqrfsamcqOS204,1583
46
+ ominfra/journald/messages.py,sha256=2iMY4k63XGNcN3LPvBmmK55ftjupnNh8f_ijlW9mkhQ,2208
47
+ ominfra/journald/tailer.py,sha256=4CzBTQcAzlW9OQ--61fIdClZVgbMQQnYe2OD1d5P7e4,36780
48
48
  ominfra/manage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  ominfra/manage/manage.py,sha256=BttL8LFEknHZE_h2Pt5dAqbfUkv6qy43WI0raXBZ1a8,151
50
50
  ominfra/pyremote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -52,29 +52,29 @@ ominfra/pyremote/_runcommands.py,sha256=2UVHaUJjmWP8jMZE79j2Qk1E5IOyVV1qNSUbdr-z
52
52
  ominfra/pyremote/bootstrap.py,sha256=RvMO3YGaN1E4sgUi1JEtiPak8cjvqtc_vRCq1yqbeZg,3370
53
53
  ominfra/pyremote/runcommands.py,sha256=bviS0_TDIoZVAe4h-_iavbvJtVSFu8lnk7fQ5iasCWE,1571
54
54
  ominfra/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
- ominfra/scripts/journald2aws.py,sha256=i6IrOGXiRxX08EuYIiYHOElN-ulC_TSnh1Ac2WQy8Zg,56190
56
- ominfra/scripts/supervisor.py,sha256=EU989AXWM-QJF4BmvKSlxkkBvRR3n2rz6yeXhjzo100,106149
55
+ ominfra/scripts/journald2aws.py,sha256=AgOHKPujUo4SqTFoz_EiN-oJ-HwZJB-UNyCFJypsNus,91403
56
+ ominfra/scripts/supervisor.py,sha256=iWTZQIrzqNjlmuDH489AlfXGb0i_0sfoYIYP7h1LH-E,115374
57
57
  ominfra/supervisor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
58
58
  ominfra/supervisor/__main__.py,sha256=usW9jjq5JPe_2SL8H5PrjDdksO75MX85Ir0HFfb35eM,72
59
- ominfra/supervisor/compat.py,sha256=sqsvlCNF2iMFdrc0LuTfyCBxXSVACtQx2wCfeHwWvAQ,5044
60
- ominfra/supervisor/configs.py,sha256=FjgsFijC_ivqJkLua4ZV0UWjDxP3JeDua3aVy4_CnbM,2970
61
- ominfra/supervisor/context.py,sha256=xh03VN8e4hHj5udjtgUvYnqUticTzCCXdIA0Xp4Ba2c,15335
62
- ominfra/supervisor/datatypes.py,sha256=cq2p7wnLN0nvKT-jZxaBByqsnCIUz6pX9dPtm69h18Q,4428
63
- ominfra/supervisor/dispatchers.py,sha256=4AVtJagOEalRnxwCZjNr8LpkCkykzzg2ncMZiYsC4Bc,10367
64
- ominfra/supervisor/events.py,sha256=wT-gPfvv2HCAyQXMq3jiek17Jq6kAZb0U2hekzjf3ks,7743
65
- ominfra/supervisor/exceptions.py,sha256=jq8Md--zmAHri1BB2XeDPFcTur81IRwArOcZoP7-6W0,746
59
+ ominfra/supervisor/compat.py,sha256=Y1d_pk4eN18AbVYjDHAXMMnPwOKTFpc7JDb1uClYMsQ,5064
60
+ ominfra/supervisor/configs.py,sha256=KpibZJ-V-4UpoJM2fnjXOXJLvDbwRJzNLXLGESUljV4,2966
61
+ ominfra/supervisor/context.py,sha256=D2TCMX_P6M98_3JR2sgO97bsXEpP8EK_LTmYWgsUXqY,15337
62
+ ominfra/supervisor/datatypes.py,sha256=UnXO_UlCyJD9u0uvea1wvnk_UZCzxNMeFvPK83gv530,4432
63
+ ominfra/supervisor/dispatchers.py,sha256=FEZeHmrIyM6WWojJsp0wQcGacgAUpMrtHNfWVoC6vhs,10404
64
+ ominfra/supervisor/events.py,sha256=OGGCuf1RWobFPDecksHJO3I4GmzBPgFvPce4-DOaZ3s,7729
65
+ ominfra/supervisor/exceptions.py,sha256=Qbu211H3CLlSmi9LsSikOwrcL5HgJP9ugvcKWlGTAoI,750
66
66
  ominfra/supervisor/poller.py,sha256=RwVnjEl63-mNQUsJcVEEsFrwuh5aOKr9e-rrB2lWCgs,7726
67
- ominfra/supervisor/process.py,sha256=phucIv2a-LHXypY3kJ9fCsKEki9G9XdiJtXCVMgGcZI,31291
67
+ ominfra/supervisor/process.py,sha256=RlwlHjHy8CPPMqTn1ljk2uHX628SCGwVEDfvnN22KgA,31390
68
68
  ominfra/supervisor/states.py,sha256=JMxXYTZhJkMNQZ2tTV6wId7wrvnWgiZteskACprKskM,1374
69
- ominfra/supervisor/supervisor.py,sha256=GnG8SAhJ5UUay7cM3oBJYb4TmIUaQUdWWqnhANpalPw,13811
69
+ ominfra/supervisor/supervisor.py,sha256=eXmVKX-A3exX8yHmmJEhHVd-3VnjTtrfDCvV7EEb7o8,13238
70
70
  ominfra/supervisor/types.py,sha256=ec62QG0CDJc0XNxCnf3lXxhsxrr4CCScLPI-1SpQjlc,1141
71
71
  ominfra/tailscale/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
72
  ominfra/tailscale/cli.py,sha256=Ltg6RVFsMLLPjLzoGwM6sxjmwjEVEYHAdrqmCc4N1HM,3174
73
73
  ominfra/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
74
  ominfra/tools/listresources.py,sha256=L4t5rszm9ulcdWyr7n48_R9d5Etg4S2a4WQhlbHDtnQ,6106
75
- ominfra-0.0.0.dev90.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
76
- ominfra-0.0.0.dev90.dist-info/METADATA,sha256=TzmuouBJtC_YaPWaqdaGBHF3XcVqFA-KyI58mxAabCA,739
77
- ominfra-0.0.0.dev90.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
78
- ominfra-0.0.0.dev90.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
79
- ominfra-0.0.0.dev90.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
80
- ominfra-0.0.0.dev90.dist-info/RECORD,,
75
+ ominfra-0.0.0.dev92.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
76
+ ominfra-0.0.0.dev92.dist-info/METADATA,sha256=3EP4RSIaP8hFXGqSoduoMjsCVPwtA9nWUhGOxvKkpWU,739
77
+ ominfra-0.0.0.dev92.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
78
+ ominfra-0.0.0.dev92.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
79
+ ominfra-0.0.0.dev92.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
80
+ ominfra-0.0.0.dev92.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- # @omlish-lite