rosotacom-dev 2.5.dev73__py3-none-any.whl → 2.5.dev74__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.
@@ -5614,22 +5614,40 @@ def _make_live_run_point(args: argparse.Namespace, session_name: str) -> RunPoin
5614
5614
  dist_installs = required_dist_installs(profile_obj)
5615
5615
  if dist_installs:
5616
5616
  # Custom delay-distribution tables must exist inside the
5617
- # shaping netns before netem references them by name.
5617
+ # shaping netns before netem references them by name, and
5618
+ # in the directory this image's `tc` was compiled to read
5619
+ # -- see tc_lib_dir_probe for why that is not a constant.
5620
+ from .network_profiles import tc_lib_dir_probe
5621
+
5618
5622
  for dist_container in (a_container, b_container):
5619
5623
  if not dist_container:
5620
5624
  continue
5625
+ probe = subprocess.run(
5626
+ ["docker", "exec", "-u", "root", dist_container, "sh", "-c", tc_lib_dir_probe()],
5627
+ capture_output=True,
5628
+ text=True,
5629
+ check=False,
5630
+ )
5631
+ tc_lib_dir = probe.stdout.strip()
5632
+ if probe.returncode != 0 or not tc_lib_dir.startswith("/"):
5633
+ raise RuntimeError(
5634
+ f"could not locate the tc library directory in {dist_container}: "
5635
+ f"{probe.stderr or probe.stdout}"
5636
+ )
5621
5637
  for table_name, file_path in dist_installs:
5622
- dist_target = f"/usr/lib/tc/{table_name}.dist"
5623
- for install_cmd in (
5624
- ["docker", "exec", "-u", "root", dist_container, "mkdir", "-p", "/usr/lib/tc"],
5638
+ dist_target = f"{tc_lib_dir}/{table_name}.dist"
5639
+ res = subprocess.run(
5625
5640
  ["docker", "cp", file_path, f"{dist_container}:{dist_target}"],
5626
- ):
5627
- res = subprocess.run(install_cmd, capture_output=True, text=True, check=False)
5628
- if res.returncode != 0:
5629
- raise RuntimeError(
5630
- f"failed to install netem distribution table {table_name!r} in "
5631
- f"{dist_container}: {' '.join(install_cmd)} -> {res.stderr or res.stdout}"
5632
- )
5641
+ capture_output=True,
5642
+ text=True,
5643
+ check=False,
5644
+ )
5645
+ if res.returncode != 0:
5646
+ raise RuntimeError(
5647
+ f"failed to install netem distribution table {table_name!r} in "
5648
+ f"{dist_container}: {file_path} -> {dist_target}: "
5649
+ f"{res.stderr or res.stdout}"
5650
+ )
5633
5651
  print(
5634
5652
  f" netem distribution {table_name!r} installed in {dist_container}: {dist_target}"
5635
5653
  )
@@ -440,9 +440,46 @@ def _resolve_distribution_files(profile: Profile, base: Path) -> Profile:
440
440
  return replace(profile, uplink=fix(profile.uplink), downlink=fix(profile.downlink))
441
441
 
442
442
 
443
+ #: Where `tc` looks for a delay-distribution table, in the order to try.
444
+ #: iproute2 compiles the directory in (``LIBDIR "/tc"``), so on a multiarch
445
+ #: Debian or Ubuntu build it is ``/usr/lib/<triplet>/tc`` and ``/usr/lib/tc``
446
+ #: does not exist at all. A table written to the latter is then invisible with
447
+ #: no error of its own: netem answers ``No distribution data for <name>`` and
448
+ #: the run dies at arming time, which is what every profile carrying a fitted
449
+ #: table did until this was found. The directory holding iproute2's own tables
450
+ #: is the one it reads, so that is the evidence to look for rather than a
451
+ #: guessed triplet.
452
+ TC_LIB_DIR_CANDIDATES = ("/usr/lib/*-linux-gnu*/tc", "/usr/lib/tc")
453
+
454
+ #: A table iproute2 ships, used as the marker for "this is the directory".
455
+ TC_LIB_DIR_MARKERS = ("normal.dist", "pareto.dist")
456
+
457
+
458
+ def tc_lib_dir_probe(root: str = "") -> str:
459
+ """A ``sh -c`` program that prints the directory ``tc`` reads tables from.
460
+
461
+ Three rungs, in order: a candidate that already holds one of iproute2's own
462
+ tables (proof, not inference); a candidate that merely exists; and finally
463
+ ``/usr/lib/tc``, created, for an image that has neither. `root` exists so
464
+ the rungs are testable without a container.
465
+ """
466
+ cands = " ".join(f"{root}{c}" for c in TC_LIB_DIR_CANDIDATES)
467
+ marker = " || ".join(f'[ -f "$d/{m}" ]' for m in TC_LIB_DIR_MARKERS)
468
+ fallback = f"{root}/usr/lib/tc"
469
+ return (
470
+ f"for d in {cands}; do "
471
+ f' if {marker}; then printf %s "$d"; exit 0; fi; '
472
+ f"done; "
473
+ f"for d in {cands}; do "
474
+ f' if [ -d "$d" ]; then printf %s "$d"; exit 0; fi; '
475
+ f"done; "
476
+ f"mkdir -p {fallback} && printf %s {fallback}"
477
+ )
478
+
479
+
443
480
  def required_dist_installs(profile: Profile) -> list[tuple[str, str]]:
444
481
  """``(table_name, file_path)`` pairs a runner must install as
445
- ``/usr/lib/tc/<table_name>.dist`` inside the shaping netns before arming.
482
+ ``<tc lib dir>/<table_name>.dist`` inside the shaping netns before arming.
446
483
 
447
484
  Builtin distributions need nothing; duplicates collapse; conflicting files
448
485
  for one name are an error (two segments must mean the same table).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev73
3
+ Version: 2.5.dev74
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -7,7 +7,7 @@ rosotacom/benchmark.py,sha256=3QoXJtWUGQPwvDWyQT_fOjx6K9G2pmvtnVurA21G2QY,76612
7
7
  rosotacom/benchmark_delta.py,sha256=qXzriBkbXOeJdlLKM4ziov1F-JfwlseYHE48S9hjFsQ,10005
8
8
  rosotacom/bundle_check.py,sha256=l_3BSuYk6juXQmsNU6jkxRbH8ayH2GkiW9ONKMQ1oJY,18270
9
9
  rosotacom/cli.py,sha256=WOl0PLl-tEu28ahHh9HIpu-hmNlD4WcH2b45HzoqMJg,438036
10
- rosotacom/cli_benchmark.py,sha256=yL5izp7_Y_ngGsx5R8yN2lSUe_Y5qxBYiMArDx4ms5I,355085
10
+ rosotacom/cli_benchmark.py,sha256=IhxiKMl3C7k7zXJAselrjTjcjKAsWGlc16Z_36AVuc0,356021
11
11
  rosotacom/deployment.py,sha256=XVhB8JjxhAsglSEEPtiVSeV6fCG0rgGmDRulh14oIYQ,7318
12
12
  rosotacom/ffmpeg_packet.py,sha256=zB1BHgY1kexr5sETVMkm4bkVnRytj9k2t0uOYiHUZ6M,4267
13
13
  rosotacom/forensics.py,sha256=fxpjuRq3pA1wCf2ERai4SlVnNhJBqZbDh6ETRKODNd0,53576
@@ -15,7 +15,7 @@ rosotacom/geomap.py,sha256=_85kWI-twzS3rf9KxamnFuhlw8Rp_fRk7n7xI-rUMFc,30292
15
15
  rosotacom/image_cache.py,sha256=71wC291j8rRMgF1D5pt2gTQdplmiIwnUDXk0BZoQNNQ,7185
16
16
  rosotacom/netem_dist.py,sha256=OWtc8asx-ow1wCxDoQuuJwJsFLl7F_lthLWsp-nlK-M,4642
17
17
  rosotacom/network_preflight.py,sha256=mQsjVnHP3CPDfHyLsOdobtymcYhcvJbmJRbXm9EgGDs,5532
18
- rosotacom/network_profiles.py,sha256=GAyVL794zQ3HnGlr1d6GoG5_qDaF5BsXwN9WRGF7kLE,31530
18
+ rosotacom/network_profiles.py,sha256=lUGAAXkJSIwpw7CWGoznKme7b6bC7b73lB56PxgMRAA,33258
19
19
  rosotacom/network_shaper.py,sha256=kjn9ZtiO1SMm8UHKIjmn92JBu_hE5TJF6vaNF1XKtNU,5463
20
20
  rosotacom/plots.py,sha256=YRGRxuGHSHDZmtL0sv1JS7cPVSL9VzjGYuvMxeHAj54,22674
21
21
  rosotacom/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -205,9 +205,9 @@ rosotacom/resources/ws/session/creation/generate_session_files.py,sha256=3Sx4xTS
205
205
  rosotacom/resources/ws/session/creation/run_session.py,sha256=G2hJhrmLp11gm3JZ6_C-zZcqu_reXlE_wmobB7BiCfU,16849
206
206
  rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py,sha256=Ub_5f-ttUUc-rAPrZmg_Op34s8Z4C91hTyEn8fgyt-E,2633
207
207
  rosotacom/resources/ws/session/creation/strip_ansi.py,sha256=vNjpemcq4xHr0VG4x0bZqvgwEBEfOgN-b4PzbrM5nfM,851
208
- rosotacom_dev-2.5.dev73.dist-info/licenses/LICENSE.txt,sha256=FDB3-fao3lqZ94wsJHKAH7U88kAnfvZhZC8Hm5rN__g,1459
209
- rosotacom_dev-2.5.dev73.dist-info/METADATA,sha256=Waeqm5ydlo3j0N--3kXVQXNF1QHPikSLYu3Y_dnQ9k0,58884
210
- rosotacom_dev-2.5.dev73.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
211
- rosotacom_dev-2.5.dev73.dist-info/entry_points.txt,sha256=im11ZWqBbgjQUBz2Ik2RNfMu54wlMwgiVpsBKeI7dCI,49
212
- rosotacom_dev-2.5.dev73.dist-info/top_level.txt,sha256=BZrtQcIVDWn_pQZR3Mlssqy5SaRXHjOa6B-1D9Fy4Ao,10
213
- rosotacom_dev-2.5.dev73.dist-info/RECORD,,
208
+ rosotacom_dev-2.5.dev74.dist-info/licenses/LICENSE.txt,sha256=FDB3-fao3lqZ94wsJHKAH7U88kAnfvZhZC8Hm5rN__g,1459
209
+ rosotacom_dev-2.5.dev74.dist-info/METADATA,sha256=nI3Vclf3YkUxefYLlVuE65wu80J6WBxdf_FStvBe-kw,58884
210
+ rosotacom_dev-2.5.dev74.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
211
+ rosotacom_dev-2.5.dev74.dist-info/entry_points.txt,sha256=im11ZWqBbgjQUBz2Ik2RNfMu54wlMwgiVpsBKeI7dCI,49
212
+ rosotacom_dev-2.5.dev74.dist-info/top_level.txt,sha256=BZrtQcIVDWn_pQZR3Mlssqy5SaRXHjOa6B-1D9Fy4Ao,10
213
+ rosotacom_dev-2.5.dev74.dist-info/RECORD,,