ominfra 0.0.0.dev188__py3-none-any.whl → 0.0.0.dev190__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,110 @@
1
+ # ruff: noqa: UP006 UP007
2
+ """
3
+ ~/.config/systemd/user/
4
+
5
+ verify - systemd-analyze
6
+
7
+ sudo loginctl enable-linger "$USER"
8
+
9
+ cat ~/.config/systemd/user/sleep-infinity.service
10
+ [Unit]
11
+ Description=User-specific service to run 'sleep infinity'
12
+ After=default.target
13
+
14
+ [Service]
15
+ ExecStart=/bin/sleep infinity
16
+ Restart=always
17
+ RestartSec=5
18
+
19
+ [Install]
20
+ WantedBy=default.target
21
+
22
+ systemctl --user daemon-reload
23
+
24
+ systemctl --user enable sleep-infinity.service
25
+ systemctl --user start sleep-infinity.service
26
+
27
+ systemctl --user status sleep-infinity.service
28
+ """
29
+ import os.path
30
+ import typing as ta
31
+
32
+ from omlish.lite.check import check
33
+ from omlish.os.paths import abs_real_path
34
+ from omlish.os.paths import is_path_in_dir
35
+
36
+ from .specs import DeploySystemdSpec
37
+ from .tmp import DeployHomeAtomics
38
+ from .types import DeployHome
39
+
40
+
41
+ class DeploySystemdManager:
42
+ def __init__(
43
+ self,
44
+ *,
45
+ atomics: DeployHomeAtomics,
46
+ ) -> None:
47
+ super().__init__()
48
+
49
+ self._atomics = atomics
50
+
51
+ def _scan_link_dir(
52
+ self,
53
+ d: str,
54
+ *,
55
+ strict: bool = False,
56
+ ) -> ta.Dict[str, str]:
57
+ o: ta.Dict[str, str] = {}
58
+ for f in os.listdir(d):
59
+ fp = os.path.join(d, f)
60
+ if strict:
61
+ check.state(os.path.islink(fp))
62
+ o[f] = abs_real_path(fp)
63
+ return o
64
+
65
+ async def sync_systemd(
66
+ self,
67
+ spec: ta.Optional[DeploySystemdSpec],
68
+ home: DeployHome,
69
+ conf_dir: str,
70
+ ) -> None:
71
+ check.non_empty_str(home)
72
+
73
+ if not spec:
74
+ return
75
+
76
+ if not (ud := spec.unit_dir):
77
+ return
78
+
79
+ ud = abs_real_path(os.path.expanduser(ud))
80
+
81
+ os.makedirs(ud, exist_ok=True)
82
+
83
+ uld = {
84
+ n: p
85
+ for n, p in self._scan_link_dir(ud).items()
86
+ if is_path_in_dir(home, p)
87
+ }
88
+
89
+ if os.path.exists(conf_dir):
90
+ cld = self._scan_link_dir(conf_dir, strict=True)
91
+ else:
92
+ cld = {}
93
+
94
+ for n in sorted(set(uld) | set(cld)):
95
+ ul = uld.get(n) # noqa
96
+ cl = cld.get(n)
97
+ if cl is None:
98
+ os.unlink(os.path.join(ud, n))
99
+ else:
100
+ with self._atomics(home).begin_atomic_path_swap( # noqa
101
+ 'file',
102
+ os.path.join(ud, n),
103
+ auto_commit=True,
104
+ skip_root_dir_check=True,
105
+ ) as dst_swap:
106
+ os.unlink(dst_swap.tmp_path)
107
+ os.symlink(
108
+ os.path.relpath(cl, os.path.dirname(dst_swap.dst_path)),
109
+ dst_swap.tmp_path,
110
+ )
@@ -12,14 +12,12 @@ from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
12
12
  from omlish.lite.check import check
13
13
 
14
14
  from .specs import DeployVenvSpec
15
- from .types import DeployHome
16
15
 
17
16
 
18
17
  class DeployVenvManager:
19
18
  async def setup_venv(
20
19
  self,
21
20
  spec: DeployVenvSpec,
22
- home: DeployHome,
23
21
  git_dir: str,
24
22
  venv_dir: str,
25
23
  ) -> None:
@@ -2344,10 +2344,15 @@ class DelimitingBuffer:
2344
2344
 
2345
2345
 
2346
2346
  class ReadableListBuffer:
2347
+ # FIXME: merge with PrependableGeneratorReader
2348
+
2347
2349
  def __init__(self) -> None:
2348
2350
  super().__init__()
2349
2351
  self._lst: list[bytes] = []
2350
2352
 
2353
+ def __len__(self) -> int:
2354
+ return sum(map(len, self._lst))
2355
+
2351
2356
  def feed(self, d: bytes) -> None:
2352
2357
  if d:
2353
2358
  self._lst.append(d)
@@ -2386,6 +2391,12 @@ class ReadableListBuffer:
2386
2391
 
2387
2392
  return None
2388
2393
 
2394
+ def read_exact(self, sz: int) -> bytes:
2395
+ d = self.read(sz)
2396
+ if d is None or len(d) != sz:
2397
+ raise EOFError(f'ReadableListBuffer got {"no" if d is None else len(d)}, expected {sz}')
2398
+ return d
2399
+
2389
2400
  def read_until(self, delim: bytes = b'\n') -> ta.Optional[bytes]:
2390
2401
  if not (lst := self._lst):
2391
2402
  return None