Skip to content

refactor(containers): one builder for the docker run hardening and resource flags - #249

Merged
napetrov merged 5 commits into
intel:mainfrom
napetrov:refactor/container-policy
Oct 28, 2026
Merged

napetrov merged 5 commits into
intel:mainfrom
napetrov:refactor/container-policy

Conversation

@napetrov

Copy link
Copy Markdown
Contributor

Summary

#229 P2-1: the docker run flags of the two container call sites are built by one policy module. Internal refactor; the argv does not change.

dokimi/dokimi/container_policy.py          (new)  ContainerPolicy: one helper per flag group
dokimi/dokimi/repos/container.py           DockerRunner.argv   -> flags.init/hardening/pids/network
dokimi/dokimi/metrics/example_runner.py    _run_docker         -> flags.network/resource/pids/read_only
dokimi/tests/test_container_argv_characterization.py (new)   pins both argv lists, flag order included

Two commits, in this order:

  • test(containers): characterize ...: the exact argv of both call sites, written against the code before the builder existed.
  • refactor(containers): one builder ...: both call sites splice the builder's groups in the order their argv has always had.

Not in this PR:

  • harnesses/docker_solver.py is not touched. A sibling PR adds its hardening flags (--cap-drop ALL, no-new-privileges, --pids-limit); adopting this builder there comes later.
  • metrics/example_runner.py has no --init, --cap-drop or no-new-privileges today. Adding them changes its argv, so it is a separate follow-up. The characterization test pins the absence and says so.
  • Other docker run/podman argv builders found by grep, candidates for later adoption: harnesses/docker_solver.py (run -d near line 356, the docker helper near 876) and harnesses/container_agent.py (network create, create, exec).

Refs #229 (P2-1).

Evidence

  • Before: the characterization tests written against the unchanged code (commit b76f1bc9, parent of the refactor) pass: 12 passed. They are characterization tests, so they pass by design; they pin the argv that already exists.
    After: the same file on the refactored code: 12 passed.
  • Mutation check: I broke the refactored code in five ways on a scratch copy (pids before init; --cap-drop all; network and resource order swapped; --read-only dropped; mb instead of m). Each one fails the characterization file (2 to 4 failures per break); the restored copy passes.
  • Full suite on the rebased head: pytest: 8989 passed, 4 skipped, exit 0.
  • make ci-local CI_LOCAL_ARGS='--offline --jobs static,typecheck': ruff, schema, registry drift, growth report, guidance self-scan, zizmor, bandit, mypy (250 files), deptry, schema_compat: all pass. Fragment for package changes fails, see Merge Danger.

Merge Danger

Door: two-way. The change is a refactor that the tests pin to the current argv; reverting restores the same argv.

Numbers: none change. No scores, no statistics, no report output.

Changelog: no fragment. This change has no user-visible effect, so the repo's rule (changelog.d/README.md) asks a maintainer for the skip-changelog label. The CI step Fragment for package changes fails until that label is added.

Blast radius: container runs. Every repo run / repo tasks check container (DockerRunner.argv) and every example run with --backend docker. The argv is byte-identical, which the characterization tests check for each mode (network none/bridge/host, the mounts, the user, the env, the resource flags). A regression in the builder would change how every repo container starts, so review the flag order in container_policy.py and the splices at the two call sites first.

New module: dokimi/container_policy.py is in the foundation layer; tests/test_import_architecture.py lists it and docs/architecture.md has the row.

🤖 Generated with Claude Code

Pin the exact argv that repos/container.py and metrics/example_runner.py
build today, flag order included, before a shared container policy
builder touches either. Test-only: these pass on the unchanged code.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…source flags

repos/container.py and metrics/example_runner.py each spelled their own
docker run flags. dokimi/container_policy.py now owns the spelling; each
call site splices the groups in its current order, so both argvs are
unchanged (pinned by test_container_argv_characterization.py).

harnesses/docker_solver.py is not touched here: its hardening and its
adoption of the builder come in their own changes.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The refactor keeps the argv byte-identical, and the characterization tests pin both call sites. One nit inline. I agree the change has no user-visible effect, so skip-changelog fits; the Fragment for package changes step stays red until a maintainer adds the label.

What I ran, on Linux at 0100bf1:

  • make ci-local: 25 passed, 3 failed, 7 skipped. 8,991 tests passed. Changed-line coverage 100%. Fragment for package changes fails for the missing label, as in GitHub CI. The other two failures are the gitleaks download (the proxy returned 504) and the scan that needs it, not this PR.
  • Base vs head comparison of the argv with the transport mocked: 324 DockerRunner.argv combinations (networks, names, users, workdirs, mounts, env) and 900 example-runner combinations (languages, cpus, memory, timeouts, images). The output is identical.
  • A mutation run: 53 mutants of the new code, 34 killed by the characterization file. The 19 survivors are equivalent mutants or the builder-level gap in the inline nit.

Checked, no issues

  • Layer: container_policy.py imports only dataclasses, so the foundation layer in test_import_architecture.py and docs/architecture.md is right.
  • Tests: the characterization file is offline, writes nothing outside the temp dir, and leaves the tree clean.
  • Scope claims: harnesses/docker_solver.py is untouched, and the other docker run builders the description names exist where it says.

Comment thread dokimi/dokimi/container_policy.py
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I pushed a commit per nit, up to 548d8c0, which fix the nit from my review:

  • 548d8c0: dokimi/tests/test_container_policy.py:1: new test file asserts the default policy yields no flags and each field alone yields exactly its flag, including cpus=0.0 and memory_mb=0.

make ci-local at 548d8c0: 25 passed, 3 failed, 7 skipped.

@napetrov napetrov added the skip-changelog No user-visible change: bypasses the changelog fragment check label Oct 28, 2026
@napetrov
napetrov merged commit 3a1f287 into intel:main Oct 28, 2026
23 of 24 checks passed
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.83%. Comparing base (bd8d453) to head (156ca92).
⚠️ Report is 2 commits behind head on main.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #249      +/-   ##
==========================================
+ Coverage   92.80%   92.83%   +0.02%     
==========================================
  Files         261      262       +1     
  Lines       32986    33016      +30     
  Branches     5508     5510       +2     
==========================================
+ Hits        30614    30649      +35     
+ Misses       1574     1571       -3     
+ Partials      798      796       -2     
Files with missing lines Coverage Δ
dokimi/dokimi/container_policy.py 100.00% <100.00%> (ø)
dokimi/dokimi/metrics/example_runner.py 95.31% <100.00%> (+1.66%) ⬆️
dokimi/dokimi/repos/container.py 84.92% <100.00%> (+1.04%) ⬆️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog No user-visible change: bypasses the changelog fragment check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants