ci: add OCE compliance test (DHCP VIVSO discovery + install) - #1126
ci: add OCE compliance test (DHCP VIVSO discovery + install)#1126bhouse-nexthop wants to merge 1 commit into
Conversation
52147f0 to
d463d29
Compare
Squashed content of PR opencomputeproject#1126, pulled in as a dependency. Signed-off-by: Brad House <bhouse@nexthop.ai>
Squashed content of PR opencomputeproject#1126, pulled in as a dependency. Signed-off-by: Brad House <bhouse@nexthop.ai>
Squashed content of PR opencomputeproject#1126, pulled in as a dependency. Signed-off-by: Brad House <bhouse@nexthop.ai>
d463d29 to
5f9e62c
Compare
|
Three of the notes below are about the code this PR #1126 On #1126 itself: the approach looks right, and it adds the gate the other I built the image and ran the #1114 harnesses against the On the eleven from #1114: nothing that has landed since has fixed any of Two attachments: ci-review-fixes.patch and the test suite described at the ############################################### On this PR (#1126) — the OCE job and harness############################################### These come first but are numbered 12-14: notes 1-11 keep the numbers they
################################################### From #1114 — still open, and two now cost more################################################### These eleven are grouped by how soon I'd act on them, not by severity. --- Worth a PR now: all small diffs, all compounding cost ---
--- Whenever convenient: low risk ---
###################### What was verified###################### Full build in your container, all four stages, no --privileged: All five artefacts ci-boot-test.sh relaxed PASS (31s) |
Add a CI job that runs ONIE's own OCE (ONIE Compliance Environment, contrib/oce/test-onie.py) compliance suite against the kvm_x86_64 image, headless under QEMU. The existing install-test job hands ONIE the installer URL directly (install_url= on the kernel command line), which bypasses discovery. This job exercises the real OCP discovery path instead: OCE stands up an isc-dhcp-server advertising the ONIE VIVSO vendor option (DHCP option 125) and an nginx HTTP server, and ONIE must DHCP, read the VIVSO installer URL from the lease, and fetch and install the image itself. The harness asserts each step from the serial console (DHCP lease, service discovery, the VIVSO URL fetch, and "NOS install successful"). OCE provides only the server side -- it does not drive or detect the DUT (its hands/pdu power-control modules are stubs) -- so the harness (emulation/ci-oce-test.sh) embeds ONIE on a disk, starts OCE's services, boots ONIE in OS-install mode, and watches the serial console. OCE requires L2 connectivity to the DUT (test-onie.py validates that the DUT address is in the host interface's subnet), so the VM runs on a tap interface rather than user-mode SLIRP. isc-dhcp-server is confined by AppArmor to system paths, so the generated dhcpd config and leases are placed under /etc/dhcp and /var/lib/dhcp rather than weakening the profile. This job is stacked on the python2-to-3 port because contrib/oce is python3 only after that change, and the GitHub runner is python3. Review hardening (@mshych, PR opencomputeproject#1126): - Cap the job with timeout-minutes. It is the longest job in the pipeline and the only one whose length depends on an input; at "full" scope the harness's own worst-case bound (a 240s embed plus 180s per test over 119 tests) exceeds GitHub's 6-hour job ceiling, where the platform kills the run without saying which test hung. The cap tracks the scope: 120 minutes for "default", 350 for "full". - Use one vCPU when /dev/kvm is unusable, matching ci-boot-test.sh. Every test is capped by PER_TEST_TIMEOUT and the sweep is fail-fast, so a guest slowed by pure emulation turns a working discovery method into a timeout. - Keep QEMU's stderr and hard-fail when QEMU exits immediately. Both launches discarded stderr, so a QEMU that never started left an empty serial log -- indistinguishable from "ONIE booted but never installed", and reported as that. Also pass the QEMU pid to wait_marker explicitly instead of reading $! inside it, which only happened to be right because QEMU is backgrounded after run_one's four service processes. Signed-off-by: Brad House <bhouse@nexthop.ai>
5f9e62c to
71803d0
Compare
|
Thanks — this is a thorough review, and the split you proposed is the right one. I went through all fourteen notes and re-verified each against the tree rather than taking them on trust; every one held up. All fourteen are applied, split exactly as you suggested:
I did not use your patch verbatim — I reimplemented each fix so the comments explain the reasoning in the surrounding style — but the substance is yours, and the On this PR (notes 12–14)12 — uncapped 13 — 14 — QEMU that never starts, and the implicit One addition beyond your patch: your patch puts the per-test stderr in On notes 1–11 (#1137)All confirmed. A few where I checked the specific claim:
Both PRs are pushed. CI on this one is sitting at |
Follow-up fixes to the CI added in 1a24708, found in review by @mshych on PR opencomputeproject#1126. Grouped here because they all fix already-merged code rather than anything that PR adds. Workflow: - The cross-toolchain cache key omitted inputs that change the toolchain. xtools.make derives XTOOLS_VERSION from ONIE_ARCH and LINUX_RELEASE, which live in machine/kvm_x86_64/machine.make and kernel-download.make -- neither of which was hashed. A kernel bump therefore kept HITTING the key while the build/x-tools/<XTOOLS_VERSION> directory name changed underneath it: the restored toolchain was the wrong one, "make xtools" rebuilt from scratch, and the save step (gated on a cache miss) skipped it, so every later run paid the same rebuild with no signal saying why. Hash those inputs, and add a guard that warns when a cache hit still had to build a toolchain -- the symptom of a key that is missing an input. - push: and pull_request: were both unfiltered, running the whole pipeline twice for every push to a branch with an open PR. The concurrency group cannot collapse them because the two events carry different refs. Add a small "gate" job that skips the push run when an open PR in the same repository already covers the commit. This is a query rather than the simpler branch filter on push: because a branch filter also removes CI from every topic branch in a fork, which is where this workflow does most of its pre-submit work. A fork's pull requests are opened against the upstream repository, so they raise no pull_request event in the fork, and workflow_dispatch is unavailable there unless the workflow is also on the fork's default branch -- a filtered branch would be left with no CI at all. The query has no such blind spot: in a fork it finds no pull request and the push run proceeds. - Drop --privileged from both docker run invocations. The Dockerfile ends with USER build, so the build is unprivileged and cannot use any capability --privileged grants; the image build uses fakeroot and mtools, not loop mounts. - Add a workflow-level "permissions: contents: read" and per-job timeout-minutes. Nothing here writes to the repository, and a wedged build would otherwise burn the 6-hour default. Dockerfile: - groupadd -g $GID failed when the host GID already exists in debian:11, which the low GID range is full of (30 dip, 50 staff, 100 users). A developer whose primary group lands there -- common with central/NFS accounts, and the norm on macOS -- could not build the image at all, while CI never saw it because the runner's GID happens to be free. Reuse the group when the GID is taken, and chown by numeric id since the "build" group then does not exist. - The /sbin:/usr/sbin PATH addition never took effect. It was appended to ~/.bashrc, but the workflow runs "bash -lc" and Debian's default .bashrc returns early for non-interactive shells. The root cause is a level deeper: /etc/profile *replaces* PATH for non-root users with one that omits both sbin dirs, so ENV alone would be undone under bash -l. Set both ENV and an /etc/profile.d snippet, which is sourced after /etc/profile. emulation/ci-boot-test.sh: - The "ONIE userspace" milestone matched strings GRUB itself echoes from grub-iso.cfg ("ONIE: Rescue Mode ...", "Version :"), so it duplicated the "GRUB reached" check and proved nothing about userspace. Assert "Info: BIOS mode:" from init-arch instead, which GRUB cannot produce. - secureboot mode never checked that Secure Boot was actually enforced: if the varstore failed to enrol the guest booted with SB off and the "must boot" assertion passed for the wrong reason. Assert the guest's own "Info: Secure Boot: Active." (read from the SecureBoot EFI variable by init-arch), and assert its absence in the relaxed run. - A failed virt-fw-vars was silently ignored: it was piped through "| sed | grep ... || true", which dropped its exit status twice over. Move enrolment into a helper that fails the run. - A QEMU that never started was indistinguishable from a firmware that refused the image -- both left an empty serial log -- so the negative control could score a broken harness as a successful rejection. Keep QEMU's stderr and hard-fail when it exits immediately. Also capture the OVMF debug console when the device is available, as a second evidence channel on debug OVMF builds. - The documented accel=kvm:tcg fallback did not work for secureboot at -smp 2: without KVM the boot dies in rcu_sched stalls and burns the whole timeout, where -smp 1 boots in ~31s. Use one vCPU when /dev/kvm is not usable. CI has /dev/kvm and is unaffected. Signed-off-by: Brad House <bhouse@nexthop.ai>
|
One follow-up on note 2, since I deviated from what you suggested — everything else is applied as proposed. I first implemented it exactly as you wrote it ( I noticed because pushing the branch with your filter applied produced zero runs on my fork, which is where I validate the stack before submitting anything here. So #1137 fixes the actual condition instead: a small Only Entirely happy to switch back to the plain branch filter if you prefer the simpler workflow file — it's your call on the cost/complexity tradeoff, and the only thing lost is fork-side pre-submit CI. |
What this adds
ci: add OCE compliance test (DHCP VIVSO discovery + install)— a new CI gate that runs ONIE's own OCE (ONIE Compliance Environment,contrib/oce) against the freshly builtkvm_x86_64image, exercising the real OCP discovery path end-to-end:oce-testjob chained afterinstall-test(build → boot-test → install-test → oce-test), so it runs against the same validated image.workflow_dispatchgains anoce_scopeinput:default(a fast representative subset, also what push/PR runs) orfull(the entire OCE installer+updater sweep).emulation/ci-oce-test.sh.