ominfra 0.0.0.dev157__py3-none-any.whl → 0.0.0.dev159__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.
@@ -3,22 +3,24 @@
3
3
  ~deploy
4
4
  deploy.pid (flock)
5
5
  /app
6
- /<appspec> - shallow clone
6
+ /<appplaceholder> - shallow clone
7
7
  /conf
8
8
  /env
9
- <appspec>.env
9
+ <appplaceholder>.env
10
10
  /nginx
11
- <appspec>.conf
11
+ <appplaceholder>.conf
12
12
  /supervisor
13
- <appspec>.conf
13
+ <appplaceholder>.conf
14
14
  /venv
15
- /<appspec>
15
+ /<appplaceholder>
16
+
17
+ /tmp
16
18
 
17
19
  ?
18
20
  /logs
19
- /wrmsr--omlish--<spec>
21
+ /wrmsr--omlish--<placeholder>
20
22
 
21
- spec = <name>--<rev>--<when>
23
+ placeholder = <name>--<rev>--<when>
22
24
 
23
25
  ==
24
26
 
@@ -39,20 +41,23 @@ import dataclasses as dc
39
41
  import os.path
40
42
  import typing as ta
41
43
 
44
+ from omlish.lite.cached import cached_nullary
42
45
  from omlish.lite.check import check
43
46
 
47
+ from .types import DeployHome
48
+
44
49
 
45
50
  DeployPathKind = ta.Literal['dir', 'file'] # ta.TypeAlias
46
- DeployPathSpec = ta.Literal['app', 'tag'] # ta.TypeAlias
51
+ DeployPathPlaceholder = ta.Literal['app', 'tag'] # ta.TypeAlias
47
52
 
48
53
 
49
54
  ##
50
55
 
51
56
 
52
- DEPLOY_PATH_SPEC_PLACEHOLDER = '@'
53
- DEPLOY_PATH_SPEC_SEPARATORS = '-.'
57
+ DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER = '@'
58
+ DEPLOY_PATH_PLACEHOLDER_SEPARATORS = '-.'
54
59
 
55
- DEPLOY_PATH_SPECS: ta.FrozenSet[str] = frozenset([
60
+ DEPLOY_PATH_PLACEHOLDERS: ta.FrozenSet[str] = frozenset([
56
61
  'app',
57
62
  'tag', # <rev>-<dt>
58
63
  ])
@@ -70,7 +75,7 @@ class DeployPathPart(abc.ABC): # noqa
70
75
  raise NotImplementedError
71
76
 
72
77
  @abc.abstractmethod
73
- def render(self, specs: ta.Optional[ta.Mapping[DeployPathSpec, str]] = None) -> str:
78
+ def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
74
79
  raise NotImplementedError
75
80
 
76
81
 
@@ -84,9 +89,9 @@ class DirDeployPathPart(DeployPathPart, abc.ABC):
84
89
 
85
90
  @classmethod
86
91
  def parse(cls, s: str) -> 'DirDeployPathPart':
87
- if DEPLOY_PATH_SPEC_PLACEHOLDER in s:
88
- check.equal(s[0], DEPLOY_PATH_SPEC_PLACEHOLDER)
89
- return SpecDirDeployPathPart(s[1:])
92
+ if DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER in s:
93
+ check.equal(s[0], DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER)
94
+ return PlaceholderDirDeployPathPart(s[1:])
90
95
  else:
91
96
  return ConstDirDeployPathPart(s)
92
97
 
@@ -98,13 +103,13 @@ class FileDeployPathPart(DeployPathPart, abc.ABC):
98
103
 
99
104
  @classmethod
100
105
  def parse(cls, s: str) -> 'FileDeployPathPart':
101
- if DEPLOY_PATH_SPEC_PLACEHOLDER in s:
102
- check.equal(s[0], DEPLOY_PATH_SPEC_PLACEHOLDER)
103
- if not any(c in s for c in DEPLOY_PATH_SPEC_SEPARATORS):
104
- return SpecFileDeployPathPart(s[1:], '')
106
+ if DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER in s:
107
+ check.equal(s[0], DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER)
108
+ if not any(c in s for c in DEPLOY_PATH_PLACEHOLDER_SEPARATORS):
109
+ return PlaceholderFileDeployPathPart(s[1:], '')
105
110
  else:
106
- p = min(f for c in DEPLOY_PATH_SPEC_SEPARATORS if (f := s.find(c)) > 0)
107
- return SpecFileDeployPathPart(s[1:p], s[p:])
111
+ p = min(f for c in DEPLOY_PATH_PLACEHOLDER_SEPARATORS if (f := s.find(c)) > 0)
112
+ return PlaceholderFileDeployPathPart(s[1:p], s[p:])
108
113
  else:
109
114
  return ConstFileDeployPathPart(s)
110
115
 
@@ -119,9 +124,9 @@ class ConstDeployPathPart(DeployPathPart, abc.ABC):
119
124
  def __post_init__(self) -> None:
120
125
  check.non_empty_str(self.name)
121
126
  check.not_in('/', self.name)
122
- check.not_in(DEPLOY_PATH_SPEC_PLACEHOLDER, self.name)
127
+ check.not_in(DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER, self.name)
123
128
 
124
- def render(self, specs: ta.Optional[ta.Mapping[DeployPathSpec, str]] = None) -> str:
129
+ def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
125
130
  return self.name
126
131
 
127
132
 
@@ -137,40 +142,40 @@ class ConstFileDeployPathPart(ConstDeployPathPart, FileDeployPathPart):
137
142
 
138
143
 
139
144
  @dc.dataclass(frozen=True)
140
- class SpecDeployPathPart(DeployPathPart, abc.ABC):
141
- spec: str # DeployPathSpec
145
+ class PlaceholderDeployPathPart(DeployPathPart, abc.ABC):
146
+ placeholder: str # DeployPathPlaceholder
142
147
 
143
148
  def __post_init__(self) -> None:
144
- check.non_empty_str(self.spec)
145
- for c in [*DEPLOY_PATH_SPEC_SEPARATORS, DEPLOY_PATH_SPEC_PLACEHOLDER, '/']:
146
- check.not_in(c, self.spec)
147
- check.in_(self.spec, DEPLOY_PATH_SPECS)
148
-
149
- def _render_spec(self, specs: ta.Optional[ta.Mapping[DeployPathSpec, str]] = None) -> str:
150
- if specs is not None:
151
- return specs[self.spec] # type: ignore
149
+ check.non_empty_str(self.placeholder)
150
+ for c in [*DEPLOY_PATH_PLACEHOLDER_SEPARATORS, DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER, '/']:
151
+ check.not_in(c, self.placeholder)
152
+ check.in_(self.placeholder, DEPLOY_PATH_PLACEHOLDERS)
153
+
154
+ def _render_placeholder(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
155
+ if placeholders is not None:
156
+ return placeholders[self.placeholder] # type: ignore
152
157
  else:
153
- return DEPLOY_PATH_SPEC_PLACEHOLDER + self.spec
158
+ return DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER + self.placeholder
154
159
 
155
160
 
156
161
  @dc.dataclass(frozen=True)
157
- class SpecDirDeployPathPart(SpecDeployPathPart, DirDeployPathPart):
158
- def render(self, specs: ta.Optional[ta.Mapping[DeployPathSpec, str]] = None) -> str:
159
- return self._render_spec(specs)
162
+ class PlaceholderDirDeployPathPart(PlaceholderDeployPathPart, DirDeployPathPart):
163
+ def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
164
+ return self._render_placeholder(placeholders)
160
165
 
161
166
 
162
167
  @dc.dataclass(frozen=True)
163
- class SpecFileDeployPathPart(SpecDeployPathPart, FileDeployPathPart):
168
+ class PlaceholderFileDeployPathPart(PlaceholderDeployPathPart, FileDeployPathPart):
164
169
  suffix: str
165
170
 
166
171
  def __post_init__(self) -> None:
167
172
  super().__post_init__()
168
173
  if self.suffix:
169
- for c in [DEPLOY_PATH_SPEC_PLACEHOLDER, '/']:
174
+ for c in [DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER, '/']:
170
175
  check.not_in(c, self.suffix)
171
176
 
172
- def render(self, specs: ta.Optional[ta.Mapping[DeployPathSpec, str]] = None) -> str:
173
- return self._render_spec(specs) + self.suffix
177
+ def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
178
+ return self._render_placeholder(placeholders) + self.suffix
174
179
 
175
180
 
176
181
  ##
@@ -181,28 +186,30 @@ class DeployPath:
181
186
  parts: ta.Sequence[DeployPathPart]
182
187
 
183
188
  def __post_init__(self) -> None:
189
+ hash(self)
190
+
184
191
  check.not_empty(self.parts)
185
192
  for p in self.parts[:-1]:
186
193
  check.equal(p.kind, 'dir')
187
194
 
188
195
  pd = {}
189
196
  for i, p in enumerate(self.parts):
190
- if isinstance(p, SpecDeployPathPart):
191
- if p.spec in pd:
192
- raise DeployPathError('Duplicate specs in path', self)
193
- pd[p.spec] = i
197
+ if isinstance(p, PlaceholderDeployPathPart):
198
+ if p.placeholder in pd:
199
+ raise DeployPathError('Duplicate placeholders in path', self)
200
+ pd[p.placeholder] = i
194
201
 
195
202
  if 'tag' in pd:
196
203
  if 'app' not in pd or pd['app'] >= pd['tag']:
197
- raise DeployPathError('Tag spec in path without preceding app', self)
204
+ raise DeployPathError('Tag placeholder in path without preceding app', self)
198
205
 
199
206
  @property
200
207
  def kind(self) -> ta.Literal['file', 'dir']:
201
208
  return self.parts[-1].kind
202
209
 
203
- def render(self, specs: ta.Optional[ta.Mapping[DeployPathSpec, str]] = None) -> str:
210
+ def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
204
211
  return os.path.join( # noqa
205
- *[p.render(specs) for p in self.parts],
212
+ *[p.render(placeholders) for p in self.parts],
206
213
  *([''] if self.kind == 'dir' else []),
207
214
  )
208
215
 
@@ -215,10 +222,10 @@ class DeployPath:
215
222
  else:
216
223
  tail_parse = FileDeployPathPart.parse
217
224
  ps = check.non_empty_str(s).split('/')
218
- return cls([
225
+ return cls((
219
226
  *([DirDeployPathPart.parse(p) for p in ps[:-1]] if len(ps) > 1 else []),
220
227
  tail_parse(ps[-1]),
221
- ])
228
+ ))
222
229
 
223
230
 
224
231
  ##
@@ -226,5 +233,36 @@ class DeployPath:
226
233
 
227
234
  class DeployPathOwner(abc.ABC):
228
235
  @abc.abstractmethod
229
- def get_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
236
+ def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
230
237
  raise NotImplementedError
238
+
239
+
240
+ class SingleDirDeployPathOwner(DeployPathOwner, abc.ABC):
241
+ def __init__(
242
+ self,
243
+ *args: ta.Any,
244
+ owned_dir: str,
245
+ deploy_home: ta.Optional[DeployHome],
246
+ **kwargs: ta.Any,
247
+ ) -> None:
248
+ super().__init__(*args, **kwargs)
249
+
250
+ check.not_in('/', owned_dir)
251
+ self._owned_dir: str = check.non_empty_str(owned_dir)
252
+
253
+ self._deploy_home = deploy_home
254
+
255
+ self._owned_deploy_paths = frozenset([DeployPath.parse(self._owned_dir + '/')])
256
+
257
+ @cached_nullary
258
+ def _dir(self) -> str:
259
+ return os.path.join(check.non_empty_str(self._deploy_home), self._owned_dir)
260
+
261
+ @cached_nullary
262
+ def _make_dir(self) -> str:
263
+ if not os.path.isdir(d := self._dir()):
264
+ os.makedirs(d, exist_ok=True)
265
+ return d
266
+
267
+ def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
268
+ return self._owned_deploy_paths
@@ -0,0 +1,42 @@
1
+ # ruff: noqa: UP006 UP007
2
+ import dataclasses as dc
3
+ import hashlib
4
+ import typing as ta
5
+
6
+ from omlish.lite.cached import cached_nullary
7
+ from omlish.lite.check import check
8
+
9
+ from .types import DeployApp
10
+ from .types import DeployKey
11
+ from .types import DeployRev
12
+
13
+
14
+ ##
15
+
16
+
17
+ @dc.dataclass(frozen=True)
18
+ class DeployGitRepo:
19
+ host: ta.Optional[str] = None
20
+ username: ta.Optional[str] = None
21
+ path: ta.Optional[str] = None
22
+
23
+ def __post_init__(self) -> None:
24
+ check.not_in('..', check.non_empty_str(self.host))
25
+ check.not_in('.', check.non_empty_str(self.path))
26
+
27
+
28
+ ##
29
+
30
+
31
+ @dc.dataclass(frozen=True)
32
+ class DeploySpec:
33
+ app: DeployApp
34
+ repo: DeployGitRepo
35
+ rev: DeployRev
36
+
37
+ def __post_init__(self) -> None:
38
+ hash(self)
39
+
40
+ @cached_nullary
41
+ def key(self) -> DeployKey:
42
+ return DeployKey(hashlib.sha256(repr(self).encode('utf-8')).hexdigest()[:8])
@@ -0,0 +1,46 @@
1
+ # ruff: noqa: UP006 UP007
2
+ import typing as ta
3
+
4
+ from omlish.lite.cached import cached_nullary
5
+ from omlish.lite.check import check
6
+
7
+ from .atomics import DeployAtomicPathSwap
8
+ from .atomics import DeployAtomicPathSwapKind
9
+ from .atomics import DeployAtomicPathSwapping
10
+ from .atomics import TempDirDeployAtomicPathSwapping
11
+ from .paths import SingleDirDeployPathOwner
12
+ from .types import DeployHome
13
+
14
+
15
+ class DeployTmpManager(
16
+ SingleDirDeployPathOwner,
17
+ DeployAtomicPathSwapping,
18
+ ):
19
+ def __init__(
20
+ self,
21
+ *,
22
+ deploy_home: ta.Optional[DeployHome] = None,
23
+ ) -> None:
24
+ super().__init__(
25
+ owned_dir='tmp',
26
+ deploy_home=deploy_home,
27
+ )
28
+
29
+ @cached_nullary
30
+ def _swapping(self) -> DeployAtomicPathSwapping:
31
+ return TempDirDeployAtomicPathSwapping(
32
+ temp_dir=self._make_dir(),
33
+ root_dir=check.non_empty_str(self._deploy_home),
34
+ )
35
+
36
+ def begin_atomic_path_swap(
37
+ self,
38
+ kind: DeployAtomicPathSwapKind,
39
+ dst_path: str,
40
+ **kwargs: ta.Any,
41
+ ) -> DeployAtomicPathSwap:
42
+ return self._swapping().begin_atomic_path_swap(
43
+ kind,
44
+ dst_path,
45
+ **kwargs,
46
+ )
@@ -6,6 +6,7 @@ DeployHome = ta.NewType('DeployHome', str)
6
6
  DeployApp = ta.NewType('DeployApp', str)
7
7
  DeployTag = ta.NewType('DeployTag', str)
8
8
  DeployRev = ta.NewType('DeployRev', str)
9
+ DeployKey = ta.NewType('DeployKey', str)
9
10
 
10
11
 
11
12
  class DeployAppTag(ta.NamedTuple):
@@ -7,8 +7,11 @@ TODO:
7
7
  import os.path
8
8
  import typing as ta
9
9
 
10
- from omlish.lite.asyncio.subprocesses import asyncio_subprocesses
10
+ from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
11
+ from omlish.lite.cached import cached_nullary
12
+ from omlish.lite.check import check
11
13
 
14
+ from .atomics import DeployAtomicPathSwapping
12
15
  from .paths import DeployPath
13
16
  from .paths import DeployPathOwner
14
17
  from .types import DeployAppTag
@@ -19,14 +22,19 @@ class DeployVenvManager(DeployPathOwner):
19
22
  def __init__(
20
23
  self,
21
24
  *,
22
- deploy_home: DeployHome,
25
+ deploy_home: ta.Optional[DeployHome] = None,
26
+ atomics: DeployAtomicPathSwapping,
23
27
  ) -> None:
24
28
  super().__init__()
25
29
 
26
30
  self._deploy_home = deploy_home
27
- self._dir = os.path.join(deploy_home, 'venvs')
31
+ self._atomics = atomics
28
32
 
29
- def get_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
33
+ @cached_nullary
34
+ def _dir(self) -> str:
35
+ return os.path.join(check.non_empty_str(self._deploy_home), 'venvs')
36
+
37
+ def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
30
38
  return {
31
39
  DeployPath.parse('venvs/@app/@tag/'),
32
40
  }
@@ -40,6 +48,8 @@ class DeployVenvManager(DeployPathOwner):
40
48
  ) -> None:
41
49
  sys_exe = 'python3'
42
50
 
51
+ # !! NOTE: (most) venvs cannot be relocated, so an atomic swap can't be used. it's up to the path manager to
52
+ # garbage collect orphaned dirs.
43
53
  await asyncio_subprocesses.check_call(sys_exe, '-m', 'venv', venv_dir)
44
54
 
45
55
  #
@@ -61,6 +71,6 @@ class DeployVenvManager(DeployPathOwner):
61
71
 
62
72
  async def setup_app_venv(self, app_tag: DeployAppTag) -> None:
63
73
  await self.setup_venv(
64
- os.path.join(self._deploy_home, 'apps', app_tag.app, app_tag.tag),
65
- os.path.join(self._deploy_home, 'venvs', app_tag.app, app_tag.tag),
74
+ os.path.join(check.non_empty_str(self._deploy_home), 'apps', app_tag.app, app_tag.tag),
75
+ os.path.join(self._dir(), app_tag.app, app_tag.tag),
66
76
  )
@@ -7,10 +7,10 @@ import shlex
7
7
  import subprocess
8
8
  import typing as ta
9
9
 
10
- from omlish.lite.asyncio.subprocesses import asyncio_subprocesses
10
+ from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
11
11
  from omlish.lite.check import check
12
- from omlish.lite.subprocesses import SUBPROCESS_CHANNEL_OPTION_VALUES
13
- from omlish.lite.subprocesses import SubprocessChannelOption
12
+ from omlish.subprocesses import SUBPROCESS_CHANNEL_OPTION_VALUES
13
+ from omlish.subprocesses import SubprocessChannelOption
14
14
 
15
15
 
16
16
  ##
@@ -9,7 +9,7 @@ import json
9
9
  import os
10
10
  import typing as ta
11
11
 
12
- from omlish.lite.asyncio.subprocesses import asyncio_subprocesses
12
+ from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
13
13
  from omlish.lite.check import check
14
14
 
15
15
 
ominfra/pyremote.py CHANGED
@@ -162,7 +162,7 @@ def _pyremote_bootstrap_main(context_name: str) -> None:
162
162
  # Get pid
163
163
  pid = os.getpid()
164
164
 
165
- # Two copies of main src to be sent to parent
165
+ # Two copies of payload src to be sent to parent
166
166
  r0, w0 = os.pipe()
167
167
  r1, w1 = os.pipe()
168
168
 
@@ -201,17 +201,17 @@ def _pyremote_bootstrap_main(context_name: str) -> None:
201
201
  # Write pid
202
202
  os.write(1, struct.pack('<Q', pid))
203
203
 
204
- # Read main src from stdin
205
- main_z_len = struct.unpack('<I', os.read(0, 4))[0]
206
- if len(main_z := os.fdopen(0, 'rb').read(main_z_len)) != main_z_len:
204
+ # Read payload src from stdin
205
+ payload_z_len = struct.unpack('<I', os.read(0, 4))[0]
206
+ if len(payload_z := os.fdopen(0, 'rb').read(payload_z_len)) != payload_z_len:
207
207
  raise EOFError
208
- main_src = zlib.decompress(main_z)
208
+ payload_src = zlib.decompress(payload_z)
209
209
 
210
- # Write both copies of main src. Must write to w0 (parent stdin) before w1 (copy pipe) as pipe will likely fill
211
- # and block and need to be drained by pyremote_bootstrap_finalize running in parent.
210
+ # Write both copies of payload src. Must write to w0 (parent stdin) before w1 (copy pipe) as pipe will likely
211
+ # fill and block and need to be drained by pyremote_bootstrap_finalize running in parent.
212
212
  for w in [w0, w1]:
213
213
  fp = os.fdopen(w, 'wb', 0)
214
- fp.write(main_src)
214
+ fp.write(payload_src)
215
215
  fp.close()
216
216
 
217
217
  # Write second ack
@@ -275,7 +275,7 @@ class PyremotePayloadRuntime:
275
275
  input: ta.BinaryIO
276
276
  output: ta.BinaryIO
277
277
  context_name: str
278
- main_src: str
278
+ payload_src: str
279
279
  options: PyremoteBootstrapOptions
280
280
  env_info: PyremoteEnvInfo
281
281
 
@@ -283,9 +283,9 @@ class PyremotePayloadRuntime:
283
283
  def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
284
284
  # If src file var is not present we need to do initial finalization
285
285
  if _PYREMOTE_BOOTSTRAP_SRC_FILE_VAR not in os.environ:
286
- # Read second copy of main src
286
+ # Read second copy of payload src
287
287
  r1 = os.fdopen(_PYREMOTE_BOOTSTRAP_SRC_FD, 'rb', 0)
288
- main_src = r1.read().decode('utf-8')
288
+ payload_src = r1.read().decode('utf-8')
289
289
  r1.close()
290
290
 
291
291
  # Reap boostrap child. Must be done after reading second copy of source because source may be too big to fit in
@@ -303,7 +303,7 @@ def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
303
303
  # Write temp source file
304
304
  import tempfile
305
305
  tfd, tfn = tempfile.mkstemp('-pyremote.py')
306
- os.write(tfd, main_src.encode('utf-8'))
306
+ os.write(tfd, payload_src.encode('utf-8'))
307
307
  os.close(tfd)
308
308
 
309
309
  # Set vars
@@ -322,7 +322,7 @@ def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
322
322
 
323
323
  # Read temp source file
324
324
  with open(os.environ.pop(_PYREMOTE_BOOTSTRAP_SRC_FILE_VAR)) as sf:
325
- main_src = sf.read()
325
+ payload_src = sf.read()
326
326
 
327
327
  # Restore vars
328
328
  sys.executable = os.environ.pop(_PYREMOTE_BOOTSTRAP_ARGV0_VAR)
@@ -355,7 +355,7 @@ def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
355
355
  input=input,
356
356
  output=output,
357
357
  context_name=context_name,
358
- main_src=main_src,
358
+ payload_src=payload_src,
359
359
  options=options,
360
360
  env_info=env_info,
361
361
  )
@@ -367,31 +367,31 @@ def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
367
367
  class PyremoteBootstrapDriver:
368
368
  def __init__(
369
369
  self,
370
- main_src: ta.Union[str, ta.Sequence[str]],
370
+ payload_src: ta.Union[str, ta.Sequence[str]],
371
371
  options: PyremoteBootstrapOptions = PyremoteBootstrapOptions(),
372
372
  ) -> None:
373
373
  super().__init__()
374
374
 
375
- self._main_src = main_src
375
+ self._payload_src = payload_src
376
376
  self._options = options
377
377
 
378
- self._prepared_main_src = self._prepare_main_src(main_src, options)
379
- self._main_z = zlib.compress(self._prepared_main_src.encode('utf-8'))
378
+ self._prepared_payload_src = self._prepare_payload_src(payload_src, options)
379
+ self._payload_z = zlib.compress(self._prepared_payload_src.encode('utf-8'))
380
380
 
381
381
  self._options_json = json.dumps(dc.asdict(options), indent=None, separators=(',', ':')).encode('utf-8') # noqa
382
382
  #
383
383
 
384
384
  @classmethod
385
- def _prepare_main_src(
385
+ def _prepare_payload_src(
386
386
  cls,
387
- main_src: ta.Union[str, ta.Sequence[str]],
387
+ payload_src: ta.Union[str, ta.Sequence[str]],
388
388
  options: PyremoteBootstrapOptions,
389
389
  ) -> str:
390
390
  parts: ta.List[str]
391
- if isinstance(main_src, str):
392
- parts = [main_src]
391
+ if isinstance(payload_src, str):
392
+ parts = [payload_src]
393
393
  else:
394
- parts = list(main_src)
394
+ parts = list(payload_src)
395
395
 
396
396
  if (mn := options.main_name_override) is not None:
397
397
  parts.insert(0, f'__name__ = {mn!r}')
@@ -427,9 +427,9 @@ class PyremoteBootstrapDriver:
427
427
  d = yield from self._read(8)
428
428
  pid = struct.unpack('<Q', d)[0]
429
429
 
430
- # Write main src
431
- yield from self._write(struct.pack('<I', len(self._main_z)))
432
- yield from self._write(self._main_z)
430
+ # Write payload src
431
+ yield from self._write(struct.pack('<I', len(self._payload_z)))
432
+ yield from self._write(self._payload_z)
433
433
 
434
434
  # Read second ack (after writing src copies)
435
435
  yield from self._expect(_PYREMOTE_BOOTSTRAP_ACK1)