hector-cli 0.4.0__tar.gz → 0.5.0__tar.gz
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.
- {hector_cli-0.4.0 → hector_cli-0.5.0}/PKG-INFO +5 -1
- {hector_cli-0.4.0 → hector_cli-0.5.0}/README.md +4 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/core.py +1 -1
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/docker.py +20 -17
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/pipeline.py +1 -4
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector_cli.egg-info/PKG-INFO +5 -1
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_docker_argv.py +21 -4
- {hector_cli-0.4.0 → hector_cli-0.5.0}/LICENSE +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/__init__.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/__main__.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/commands/__init__.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/commands/base.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/commands/clean.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/commands/export.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/commands/init.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/commands/run.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/commands/test.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/commands/validate.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/connections.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/dependencies.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/generator.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/hubs.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/mappings.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/modules.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/peripherals.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/reporters.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/runners.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/scaffold.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector/validator.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector_cli.egg-info/SOURCES.txt +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector_cli.egg-info/dependency_links.txt +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector_cli.egg-info/entry_points.txt +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector_cli.egg-info/requires.txt +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/hector_cli.egg-info/top_level.txt +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/setup.cfg +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/setup.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_arguments.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_clean.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_cli_smoke.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_connections.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_core_paths.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_core_registry.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_core_text.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_generator.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_hubs.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_mappings.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_matrix.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_needs_renode_source.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_peripherals.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_pipeline_helpers.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_reporters.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_runners.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_scaffold.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_validator.py +0 -0
- {hector_cli-0.4.0 → hector_cli-0.5.0}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hector-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: YAML-driven Renode + Verilator simulation orchestrator for embedded hardware CI
|
|
5
5
|
Home-page: https://hector-ci.com
|
|
6
6
|
Author: Nemesis
|
|
@@ -482,6 +482,10 @@ hector run --renode-args '--console'
|
|
|
482
482
|
hector run --renode-args '--hide-log --config my.conf'
|
|
483
483
|
```
|
|
484
484
|
|
|
485
|
+
#### Container networking
|
|
486
|
+
|
|
487
|
+
Every container hector starts — the Renode emulation (`run`), robot tests, `shell` tests, `build:` steps and module builds — runs with `--net=host`. GDB servers (`--debug`), `tcp:` mappings and anything a step listens on are reachable from the host on the same port, and steps can reach host services on `localhost`. No port publishing is involved.
|
|
488
|
+
|
|
485
489
|
#### Running without Docker (`--no-docker`)
|
|
486
490
|
|
|
487
491
|
Call the locally installed `renode` and `renode-test` binaries directly instead of launching a Docker container. `build:` steps and `shell` tests also run on the host (their `image:` is ignored, with a warning), as do module builds.
|
|
@@ -452,6 +452,10 @@ hector run --renode-args '--console'
|
|
|
452
452
|
hector run --renode-args '--hide-log --config my.conf'
|
|
453
453
|
```
|
|
454
454
|
|
|
455
|
+
#### Container networking
|
|
456
|
+
|
|
457
|
+
Every container hector starts — the Renode emulation (`run`), robot tests, `shell` tests, `build:` steps and module builds — runs with `--net=host`. GDB servers (`--debug`), `tcp:` mappings and anything a step listens on are reachable from the host on the same port, and steps can reach host services on `localhost`. No port publishing is involved.
|
|
458
|
+
|
|
455
459
|
#### Running without Docker (`--no-docker`)
|
|
456
460
|
|
|
457
461
|
Call the locally installed `renode` and `renode-test` binaries directly instead of launching a Docker container. `build:` steps and `shell` tests also run on the host (their `image:` is ignored, with a warning), as do module builds.
|
|
@@ -67,7 +67,7 @@ class Registry:
|
|
|
67
67
|
# ==========================================================================
|
|
68
68
|
# CONSTANTS
|
|
69
69
|
# ==========================================================================
|
|
70
|
-
TOOL_VERSION = "0.
|
|
70
|
+
TOOL_VERSION = "0.5.0"
|
|
71
71
|
SUPPORTED_SCHEMA_VERSIONS = {"0.1"}
|
|
72
72
|
|
|
73
73
|
RENODE_REPO_URL = "https://github.com/renode/renode.git"
|
|
@@ -60,6 +60,13 @@ def _extra_mounts():
|
|
|
60
60
|
return args
|
|
61
61
|
|
|
62
62
|
|
|
63
|
+
# Every container shares the host's network stack: GDB servers, tcp: mappings and
|
|
64
|
+
# anything a build/test step listens on are reachable from the host as-is, and steps
|
|
65
|
+
# can reach host services (e.g. a local registry or a TCP-mapped UART) on localhost.
|
|
66
|
+
# No -p publishing is needed (Docker ignores it in this mode anyway).
|
|
67
|
+
_HOST_NETWORK = ["--net=host"]
|
|
68
|
+
|
|
69
|
+
|
|
63
70
|
def _runtime_flags(runtime):
|
|
64
71
|
"""Map aggregated RuntimeOptions (capabilities/devices/root, declared by mappings,
|
|
65
72
|
hubs, modules) to `docker run` flags.
|
|
@@ -89,7 +96,7 @@ def run_build(script, image):
|
|
|
89
96
|
subprocess.run(["bash", "-c", script], check=True)
|
|
90
97
|
return
|
|
91
98
|
subprocess.run(
|
|
92
|
-
["docker", "run", "--rm", "-u", "0:0",
|
|
99
|
+
["docker", "run", "--rm", *_HOST_NETWORK, "-u", "0:0",
|
|
93
100
|
*_workspace_mount(), *_extra_mounts(), image, "bash", "-c", script],
|
|
94
101
|
check=True,
|
|
95
102
|
)
|
|
@@ -128,8 +135,8 @@ def run_in_container(script, image, live=False):
|
|
|
128
135
|
if core.NO_DOCKER:
|
|
129
136
|
cmd = ["bash", "-c", f"set -ex\n{script}"]
|
|
130
137
|
else:
|
|
131
|
-
cmd = ["docker", "run", "--rm", *
|
|
132
|
-
*_user_flags(), image, "sh", "-c", f"set -ex\n{script}"]
|
|
138
|
+
cmd = ["docker", "run", "--rm", *_HOST_NETWORK, *_workspace_mount(),
|
|
139
|
+
*_extra_mounts(), *_user_flags(), image, "sh", "-c", f"set -ex\n{script}"]
|
|
133
140
|
if live:
|
|
134
141
|
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
|
135
142
|
stderr=subprocess.STDOUT, text=True)
|
|
@@ -145,7 +152,7 @@ def run_in_container(script, image, live=False):
|
|
|
145
152
|
return proc.stdout, proc.returncode == 0
|
|
146
153
|
|
|
147
154
|
|
|
148
|
-
def build_renode_argv(resc_filename, image,
|
|
155
|
+
def build_renode_argv(resc_filename, image, extra_args=None, runtime=None):
|
|
149
156
|
"""Build the exact argv that would run an emulation resc — the local `renode`
|
|
150
157
|
invocation under --no-docker, otherwise the full `docker run ... renode` command.
|
|
151
158
|
|
|
@@ -154,20 +161,18 @@ def build_renode_argv(resc_filename, image, ports=None, extra_args=None, runtime
|
|
|
154
161
|
runtime: aggregated RuntimeOptions whose docker flags (caps/devices/root) are added."""
|
|
155
162
|
if core.NO_DOCKER:
|
|
156
163
|
return ["renode", resc_filename] + (extra_args or [])
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
cmd += ["-p", f"{port}:{port}"]
|
|
161
|
-
cmd += [image, "renode", resc_filename] + (extra_args or [])
|
|
162
|
-
return cmd
|
|
164
|
+
return ["docker", "run", "-it", "--rm", *_xdisplay_args(), *_HOST_NETWORK,
|
|
165
|
+
*_workspace_mount(), *_extra_mounts(), *_user_flags(), *_runtime_flags(runtime),
|
|
166
|
+
image, "renode", resc_filename] + (extra_args or [])
|
|
163
167
|
|
|
164
168
|
|
|
165
|
-
def run_renode(resc_filename, image,
|
|
166
|
-
"""Run an emulation resc interactively.
|
|
169
|
+
def run_renode(resc_filename, image, extra_args=None, output_dir="results", runtime=None):
|
|
170
|
+
"""Run an emulation resc interactively. GDB ports (--debug) are reachable from the
|
|
171
|
+
host through the host network.
|
|
167
172
|
runtime: aggregated RuntimeOptions whose docker flags (caps/devices/root) are added."""
|
|
168
173
|
if not core.NO_DOCKER:
|
|
169
174
|
os.makedirs(os.path.join(os.getcwd(), output_dir), exist_ok=True)
|
|
170
|
-
subprocess.run(build_renode_argv(resc_filename, image,
|
|
175
|
+
subprocess.run(build_renode_argv(resc_filename, image, extra_args, runtime))
|
|
171
176
|
|
|
172
177
|
|
|
173
178
|
def run_renode_test(robot_file_host, image, results_dir_host,
|
|
@@ -177,8 +182,7 @@ def run_renode_test(robot_file_host, image, results_dir_host,
|
|
|
177
182
|
resc_host_path: passed as --variable RESC:<path> so .robot files can load
|
|
178
183
|
the generated emulation script via ${RESC}.
|
|
179
184
|
extra_args: optional list of additional flags forwarded verbatim to renode-test.
|
|
180
|
-
interactive: attach stdin/tty and
|
|
181
|
-
or when TCP ports need to be reachable from the host during the test).
|
|
185
|
+
interactive: attach stdin/tty and X display (useful with Pause Execution).
|
|
182
186
|
"""
|
|
183
187
|
os.makedirs(results_dir_host, exist_ok=True)
|
|
184
188
|
if core.NO_DOCKER:
|
|
@@ -190,9 +194,8 @@ def run_renode_test(robot_file_host, image, results_dir_host,
|
|
|
190
194
|
result = subprocess.run(cmd)
|
|
191
195
|
return result.returncode == 0
|
|
192
196
|
flags = ["-it"] if interactive else []
|
|
193
|
-
net = ["--net=host"] if interactive else []
|
|
194
197
|
display = _xdisplay_args() if interactive else []
|
|
195
|
-
cmd = ["docker", "run", "--rm", *flags, *
|
|
198
|
+
cmd = ["docker", "run", "--rm", *flags, *_HOST_NETWORK, *display,
|
|
196
199
|
*_workspace_mount(), *_extra_mounts(), *_user_flags(), *_runtime_flags(runtime),
|
|
197
200
|
image, "renode-test", to_container_path(robot_file_host),
|
|
198
201
|
"-r", to_container_path(results_dir_host)]
|
|
@@ -251,8 +251,7 @@ def snapshot_fastpath(args):
|
|
|
251
251
|
no_start=getattr(args, "no_start", False)))
|
|
252
252
|
print(f"[SNAP] {args.snapshot}"
|
|
253
253
|
+ (f" (+GDB: {debug_config})" if debug_config else ""))
|
|
254
|
-
run_renode(snap_resc, docker_image,
|
|
255
|
-
extra_args=shlex.split(args.renode_args or ""), output_dir=args.output)
|
|
254
|
+
run_renode(snap_resc, docker_image, extra_args=shlex.split(args.renode_args or ""), output_dir=args.output)
|
|
256
255
|
|
|
257
256
|
|
|
258
257
|
def _run_validate():
|
|
@@ -524,7 +523,6 @@ def action_simulate(state, cfg, result):
|
|
|
524
523
|
if not state.resc_filename:
|
|
525
524
|
raise ValueError("`hector run` needs at least one machine in 'machines:'.")
|
|
526
525
|
run_renode(_resolve_active_resc(state, cfg), cfg.docker_image,
|
|
527
|
-
ports=list(state.debug_config.values()) or None,
|
|
528
526
|
extra_args=cfg.renode_args, output_dir=cfg.output_dir,
|
|
529
527
|
runtime=state.runtime)
|
|
530
528
|
|
|
@@ -536,7 +534,6 @@ def action_export(state, cfg, result):
|
|
|
536
534
|
if not state.resc_filename:
|
|
537
535
|
raise ValueError("`hector export` needs at least one machine in 'machines:'.")
|
|
538
536
|
argv = build_renode_argv(_resolve_active_resc(state, cfg), cfg.docker_image,
|
|
539
|
-
ports=list(state.debug_config.values()) or None,
|
|
540
537
|
extra_args=cfg.renode_args, runtime=state.runtime)
|
|
541
538
|
line = shlex.join(argv)
|
|
542
539
|
print(line)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hector-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: YAML-driven Renode + Verilator simulation orchestrator for embedded hardware CI
|
|
5
5
|
Home-page: https://hector-ci.com
|
|
6
6
|
Author: Nemesis
|
|
@@ -482,6 +482,10 @@ hector run --renode-args '--console'
|
|
|
482
482
|
hector run --renode-args '--hide-log --config my.conf'
|
|
483
483
|
```
|
|
484
484
|
|
|
485
|
+
#### Container networking
|
|
486
|
+
|
|
487
|
+
Every container hector starts — the Renode emulation (`run`), robot tests, `shell` tests, `build:` steps and module builds — runs with `--net=host`. GDB servers (`--debug`), `tcp:` mappings and anything a step listens on are reachable from the host on the same port, and steps can reach host services on `localhost`. No port publishing is involved.
|
|
488
|
+
|
|
485
489
|
#### Running without Docker (`--no-docker`)
|
|
486
490
|
|
|
487
491
|
Call the locally installed `renode` and `renode-test` binaries directly instead of launching a Docker container. `build:` steps and `shell` tests also run on the host (their `image:` is ignored, with a warning), as do module builds.
|
|
@@ -37,10 +37,27 @@ def test_docker_argv_core_tokens():
|
|
|
37
37
|
assert argv[i + 1:i + 3] == ["renode", "job.resc"]
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
assert "-p
|
|
40
|
+
def test_docker_argv_does_not_publish_ports():
|
|
41
|
+
# Host networking exposes GDB ports directly; -p would be ignored by Docker.
|
|
42
|
+
argv = docker.build_renode_argv("j.resc", "img")
|
|
43
|
+
assert "-p" not in argv
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_every_container_uses_host_network(monkeypatch):
|
|
47
|
+
calls = []
|
|
48
|
+
|
|
49
|
+
class _Proc:
|
|
50
|
+
returncode, stdout = 0, ""
|
|
51
|
+
|
|
52
|
+
monkeypatch.setattr(docker.subprocess, "run",
|
|
53
|
+
lambda cmd, **kw: calls.append(cmd) or _Proc())
|
|
54
|
+
monkeypatch.setattr(docker.os, "makedirs", lambda *a, **kw: None)
|
|
55
|
+
docker.run_build("true", "img")
|
|
56
|
+
docker.run_in_container("true", "img")
|
|
57
|
+
docker.run_renode_test("t.robot", "img", "res")
|
|
58
|
+
docker.run_renode("j.resc", "img")
|
|
59
|
+
assert len(calls) == 4
|
|
60
|
+
assert all("--net=host" in cmd for cmd in calls)
|
|
44
61
|
|
|
45
62
|
|
|
46
63
|
def test_docker_argv_appends_extra_args_after_resc():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|