Skip to content

CNF-19617, CNF-21768, CNF-21832, CNF-22018, OCPBUGS-59883, OCPBUGS-66407: Sync from upstream (07-Apr-2026)#691

Draft
nocturnalastro wants to merge 24 commits intoopenshift:mainfrom
nocturnalastro:upstream-sync-2026-04-07
Draft

CNF-19617, CNF-21768, CNF-21832, CNF-22018, OCPBUGS-59883, OCPBUGS-66407: Sync from upstream (07-Apr-2026)#691
nocturnalastro wants to merge 24 commits intoopenshift:mainfrom
nocturnalastro:upstream-sync-2026-04-07

Conversation

@nocturnalastro
Copy link
Copy Markdown
Contributor

@nocturnalastro nocturnalastro commented Apr 7, 2026

Upstream PRs included

  • #206 CNF-21768: Add TLS adherence support (CNF-21768)
  • #203 update OWNERS
  • #202 Upgrade to Go 1.25 and update dependencies
  • #201 Expose system-level and base board hardware details in NodePtpDevice Status (CNF-21832)
  • #200 Update Dockerfile builder image
  • #198 Update Dockerfile.krp to use Go version 1.25.7 for the builder stage
  • #197 CNF-19617: Add test coverage for clockClass verification when locking PTP source (CNF-19617,OCPBUGS-59883,OCPBUGS-66407)
  • #194 Set tls-profiles feature annotation to true in CSV
  • #192 Add must-gather collection to CI pipeline
  • #185 PTP CI: Add BC clock class recovery test for upstream link outage (CNF-22018)

Skipped PRs

  • #195 Configure AWS timeout to 2 hours for long jobs — all changed files are upstream-only (not present downstream)

jzding and others added 24 commits March 11, 2026 19:37
The operator now honors the cluster-wide TLS security profile from the
APIServer CR, so declare this capability via the OLM feature annotation.

Signed-off-by: Jack Ding <jackding@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Configure AWS timeout to 2 hours for long jobs
Set tls-profiles feature annotation to true in CSV
Update Dockerfile.krp to use Go version 1.25.7 for the builder stage
Move builder image to non-docker image so that we do not get hit with pull limits
This is needed for TLSAdherence support.

- Upgrade from Go 1.24 to Go 1.25.0
- Update openshift/api to v0.0.0-20260318185450-1f2fa3f09f4e
- Update openshift/library-go to v0.0.0-20260318142011-72bf34f474bc
- Update openshift/controller-runtime-common to v0.0.0-20260318085703-1812aed6dbd2
- Upgrade sigs.k8s.io/controller-runtime from v0.22.5 to v0.23.3
- Upgrade k8s.io dependencies from v0.34.3 to v0.35.2
- Update l2discovery-lib from v0.0.21 to v0.1.0
- Update l2discovery image in CI test
- Fix webhook registrations for controller-runtime v0.23 generic API

Signed-off-by: Jack Ding <jackding@gmail.com>
Upgrade to Go 1.25 and update dependencies
…-locked-after-degrading

PTP CI: Add BC clock class recovery test for upstream link outage
Add must-gather collection to CI pipeline
Signed-off-by: Jack Ding <jackding@gmail.com>
CNF-19617: Add test coverage for clockClass verification when locking PTP source
Expose system-level and base board hardware details in NodePtpDevice Status
Read the tlsAdherence policy from the APIServer CR and use
ShouldHonorClusterTLSProfile to conditionally apply the cluster
TLS profile. In Legacy mode (default), Go TLS defaults are used.
In Strict mode, the cluster-wide TLS profile is enforced on the
operator's webhook/metrics servers and on the daemon's
kube-rbac-proxy.

The SecurityProfileWatcher now also monitors adherence policy
changes and triggers a graceful restart when the policy changes.

Signed-off-by: Jack Ding <jackding@gmail.com>
Replace the separate TLSAdherencePolicy field on the reconciler
with a nil *TLSProfileSpec pointer pattern. When the pointer is
nil, legacy hardcoded ciphers are used. When non-nil, the cluster
TLS profile is applied. The adherence decision is made once in
main.go and expressed through the pointer value.

Signed-off-by: Jack Ding <jackding@gmail.com>
CNF-21768: Add TLS adherence support
@openshift-ci-robot openshift-ci-robot added jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Apr 7, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

openshift-ci-robot commented Apr 7, 2026

@nocturnalastro: This pull request references CNF-19617 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

This pull request references CNF-21768 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

This pull request references CNF-21832 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

This pull request references CNF-22018 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

This pull request references Jira Issue OCPBUGS-59883, which is invalid:

  • expected the bug to be open, but it isn't
  • expected the bug to target either version "4.22." or "openshift-4.22.", but it targets "4.18.z" instead
  • expected the bug to be in one of the following states: NEW, ASSIGNED, POST, but it is Closed (Done) instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

This pull request references Jira Issue OCPBUGS-66407, which is invalid:

  • expected the bug to be open, but it isn't
  • expected the bug to target either version "4.22." or "openshift-4.22.", but it targets "4.20.z" instead
  • expected the bug to be in one of the following states: NEW, ASSIGNED, POST, but it is Closed (Done) instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Upstream PRs included

  • #206 CNF-21768: Add TLS adherence support (CNF-21768)
  • #203 update OWNERS
  • #202 Upgrade to Go 1.25 and update dependencies
  • #201 Expose system-level and base board hardware details in NodePtpDevice Status (CNF-21832)
  • #200 Update Dockerfile builder image
  • #198 Update Dockerfile.krp to use Go version 1.25.7 for the builder stage
  • #197 CNF-19617: Add test coverage for clockClass verification when locking PTP source (CNF-19617,OCPBUGS-59883,OCPBUGS-66407)
  • #194 Set tls-profiles feature annotation to true in CSV
  • #192 Add must-gather collection to CI pipeline
  • #185 PTP CI: Add BC clock class recovery test for upstream link outage (CNF-22018)

Skipped PRs

  • #195 Configure AWS timeout to 2 hours for long jobs — all changed files are upstream-only (not present downstream)

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link
Copy Markdown
Contributor

openshift-ci-robot commented Apr 7, 2026

@nocturnalastro: This pull request references CNF-19617 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

This pull request references CNF-21768 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

This pull request references CNF-21832 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

This pull request references CNF-22018 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

This pull request references Jira Issue OCPBUGS-59883, which is invalid:

  • expected the bug to be open, but it isn't
  • expected the bug to target either version "4.22." or "openshift-4.22.", but it targets "4.18.z" instead
  • expected the bug to be in one of the following states: NEW, ASSIGNED, POST, but it is Closed (Done) instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

This pull request references Jira Issue OCPBUGS-66407, which is invalid:

  • expected the bug to be open, but it isn't
  • expected the bug to target either version "4.22." or "openshift-4.22.", but it targets "4.20.z" instead
  • expected the bug to be in one of the following states: NEW, ASSIGNED, POST, but it is Closed (Done) instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

Details

In response to this:

Upstream PRs included

  • #206 CNF-21768: Add TLS adherence support (CNF-21768)
  • #203 update OWNERS
  • #202 Upgrade to Go 1.25 and update dependencies
  • #201 Expose system-level and base board hardware details in NodePtpDevice Status (CNF-21832)
  • #200 Update Dockerfile builder image
  • #198 Update Dockerfile.krp to use Go version 1.25.7 for the builder stage
  • #197 CNF-19617: Add test coverage for clockClass verification when locking PTP source (CNF-19617,OCPBUGS-59883,OCPBUGS-66407)
  • #194 Set tls-profiles feature annotation to true in CSV
  • #192 Add must-gather collection to CI pipeline
  • #185 PTP CI: Add BC clock class recovery test for upstream link outage (CNF-22018)

Skipped PRs

  • #195 Configure AWS timeout to 2 hours for long jobs — all changed files are upstream-only (not present downstream)

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

Walkthrough

This PR upgrades the PTP operator to Go 1.25, extends the NodePtpDevice API with system and baseboard SMBIOS information fields, refactors webhook registration patterns, enhances TLS profile handling with adherence policy support, updates container base images, adds conformance tests for boundary clock behavior, and extends test infrastructure.

Changes

Cohort / File(s) Summary
Base Image Updates
Dockerfile, ptp-tools/Dockerfile.cep, ptp-tools/Dockerfile.krp, ptp-tools/Dockerfile.lptpd, ptp-tools/Dockerfile.ptpop
Updated Go builder base images from 1.24.x to 1.25.7 and Go 1.25.0 toolchain; added binutils-gold dependency to ptpop builder.
New Debug Container
ptp-tools/Dockerfile.debug
New Dockerfile building debug image from CentOS Stream 9 with tcpdump support.
API Type Extensions
api/v1/nodeptpdevice_types.go, api/v1/zz_generated.deepcopy.go
Added SystemInfo and BaseBoardInfo types for SMBIOS/DMI data; extended NodePtpDeviceStatus with these pointer fields and generated corresponding DeepCopy methods.
Webhook Registration Updates
api/v1/ptpconfig_webhook.go, api/v1/ptpoperatorconfig_webhook.go
Changed webhook builder from .For(r) pattern to NewWebhookManagedBy(mgr, r) and updated validator registration from .WithValidator() to .WithCustomValidator().
CRD Schema Updates
config/crd/bases/ptp.openshift.io_nodeptpdevices.yaml, bundle/manifests/ptp.openshift.io_nodeptpdevices.yaml, manifests/stable/ptp.openshift.io_nodeptpdevices.yaml
Extended NodePtpDevice status schema with baseBoardInfo and systemInfo object fields containing SMBIOS/DMI attributes.
ClusterServiceVersion Updates
bundle/manifests/ptp-operator.clusterserviceversion.yaml, config/manifests/bases/ptp-operator.clusterserviceversion.yaml, manifests/stable/ptp-operator.clusterserviceversion.yaml
Updated createdAt timestamps and enabled tls-profiles feature flag capability across operator manifests.
TLS Configuration & Control
controllers/ptpoperatorconfig_controller.go, main.go, bindata/linuxptp/ptp-daemon.yaml
Changed TLSProfileSpec to pointer field; introduced setTLSTemplateData helper with legacy cipher-suite fallback; updated main.go to fetch and honor TLSAdherencePolicy; added conditional TLS flags to kube-rbac-proxy arguments.
Monitoring Configuration
config/prometheus/monitor.yaml
Extended ServiceMonitor tlsConfig with client certificate and key file paths for mutual TLS.
TLS Test Infrastructure
controllers/tls_profile_test.go, controllers/tls_watcher_test.go
Refactored TLS rendering test setup with shared initialization; added legacy mode test coverage; introduced setTLSTemplateData unit tests validating profile conversion and nil-profile fallback behavior.
Must-Gather & Debug Support
must-gather/collection-scripts/gather, scripts/run-tests.sh, scripts/run-on-vm.sh
Added --debug-image flag support and extended tcpdump timeout handling in debug container; added --must-gather-image flag to test runner with automatic execution on failure; introduced trapping and conditional must-gather invocation.
Test Conformance & Helpers
test/conformance/serial/ptp.go, test/pkg/ptptesthelper/ptptesthelper.go, test/pkg/testconfig/testconfig.go
Added boundary clock gmCapable and clock-class recovery tests; introduced shared event-monitoring context and clock-class verification utilities; added port control helpers (TurnAllPortsDown, TurnOffAndWaitFaulty, TurnOnAndWaitSlave); updated L2 discovery image to v15.
Build Automation & Scripts
ptp-tools/Makefile, scripts/k8s-start.sh
Extended Makefile to generate debug build/push targets; added PriorityClass resource setup in cluster initialization script.
Dependencies & Ownership
go.mod, OWNERS
Upgraded Go module to 1.25.0; bumped Kubernetes/controller-runtime to v0.35.2/v0.23.3; updated OWNERS to replace aneeshkp with edcdavid and add sebsoto; removed reviewer list.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 7, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: nocturnalastro

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 7, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (4)
Dockerfile (1)

9-20: Consider adding a non-root USER for the runtime stage.

The runtime stage runs as root by default. If the ptp-operator doesn't require root privileges, adding a non-root user would improve security posture. However, this may require additional investigation and could be addressed in a follow-up.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 9 - 20, The Dockerfile's runtime stage runs as root;
add a non-root user and switch to it to improve security: create a user/group
(e.g., USER_ID/USER_NAME), chown the runtime artifacts copied into
/usr/local/bin/ptp-operator, /manifests and /bindata to that user, add a USER
instruction before ENTRYPOINT to drop root privileges, and ensure the existing
ENTRYPOINT ["/usr/local/bin/ptp-operator"] still works with the new user's
permissions (adjust file modes or capabilities if the operator needs specific
privileges).
ptp-tools/Dockerfile.ptpop (1)

1-2: Go version update and binutils-gold addition look correct.

The toolchain bump to Go 1.25.7 aligns with the PR objectives.

Consider adding --no-install-recommends to reduce image size and potential attack surface:

♻️ Optional improvement
-RUN apt-get update && apt-get install -y binutils-gold && rm -rf /var/lib/apt/lists/*
+RUN apt-get update && apt-get install -y --no-install-recommends binutils-gold && rm -rf /var/lib/apt/lists/*
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ptp-tools/Dockerfile.ptpop` around lines 1 - 2, Update the RUN line that
installs binutils-gold to use apt-get install --no-install-recommends to shrink
the image and reduce attack surface: locate the stage that starts with "FROM
docker.io/golang:1.25.7 AS builder" and modify the RUN command "apt-get update
&& apt-get install -y binutils-gold && rm -rf /var/lib/apt/lists/*" to include
"--no-install-recommends" in the apt-get install invocation so only required
packages are installed.
ptp-tools/Dockerfile.debug (1)

1-2: Consider adding a non-root user for defense-in-depth (optional for debug images).

The static analysis tool flags that this image runs as root. For a debug image that uses tcpdump (requiring CAP_NET_RAW), running as root is often necessary and acceptable. However, if you want to address this, you could add a non-root user and rely on capability grants at runtime instead.

Given this is explicitly a debug image with limited production exposure, the current implementation is reasonable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ptp-tools/Dockerfile.debug` around lines 1 - 2, The image currently runs as
root which the scanner flags; to address this add a non-root user and switch to
it in the Dockerfile while keeping tcpdump functionality by documenting or
relying on runtime capability grants (CAP_NET_RAW) or setcap on the tcpdump
binary. Update the Dockerfile to create a user (e.g., adduser or group/user
names), chown any needed directories, and use USER <nonroot> before final image
steps, and add a note that tcpdump requires CAP_NET_RAW so runtimes should grant
that capability or setcap on /usr/sbin/tcpdump.
api/v1/ptpoperatorconfig_webhook.go (1)

39-41: Migrate from deprecated WithCustomValidator to WithValidator.

The vendored controller-runtime v0.23 code marks WithCustomValidator as deprecated in favor of WithValidator. Update the webhook builder to use the non-deprecated API and modify ptpOperatorConfigValidator to implement admission.Validator[*PtpOperatorConfig] instead of admission.CustomValidator.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/v1/ptpoperatorconfig_webhook.go` around lines 39 - 41, Update the webhook
builder to replace the deprecated WithCustomValidator call with WithValidator
and change ptpOperatorConfigValidator to implement the new generic interface
admission.Validator[*PtpOperatorConfig] instead of admission.CustomValidator;
specifically, modify the call site using ctrl.NewWebhookManagedBy(mgr,
r).WithCustomValidator(&ptpOperatorConfigValidator{}).Complete() to use
.WithValidator(&ptpOperatorConfigValidator{}) and update the
ptpOperatorConfigValidator type signature and method receiver signatures to
match admission.Validator[*PtpOperatorConfig] (ValidateCreate, ValidateUpdate,
ValidateDelete signatures that accept *PtpOperatorConfig and return
admission.Response/Result types as required by the new interface).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/run-tests.sh`:
- Line 28: The script fails under "set -u" because DEBUG_IMAGE is referenced
without a default; initialize DEBUG_IMAGE (and any other optional flags
analogous to MUST_GATHER_IMAGE like the ones around the same block) to empty
strings at the top of the script so references in argument parsing and later
(e.g., the use on line where DEBUG_IMAGE is read) won't trigger an unbound
variable error; update the initial variable declarations to include
DEBUG_IMAGE="" to mirror MUST_GATHER_IMAGE="" (and ensure any other optional
variables used later are likewise initialized).

In `@test/conformance/serial/ptp.go`:
- Around line 3574-3615: The test is asserting on a shared PtpClockClassChange
topic and can pick up events from other BCs; update
setupBCClockClassEvents/verifyClockClassViaEvent to scope the event stream to
the BC under test: when subscribing (SubscribeToGMChangeEvents) or when calling
getGMEvents in verifyClockClassViaEvent, filter the returned events for the
node/config under test (e.g., check the event's source/namespace/node identifier
or include nodeName in the subscription call) so verifyMetric only uses
PtpClockClassChange events originating from that specific BC before asserting
the expectedClass.
- Around line 2055-2081: Compute the active slave-port set by filtering slaveIf
against the SKIP_INTERFACES map (skippedInterfacesStr -> skipInterfaces) before
taking the outage, register the cleanup immediately (call DeferCleanup to
TurnAllPortsUp right after building skipInterfaces and before invoking
portEngine.TurnAllPortsDown), and then build faultyRoles/slaveRoles sized to the
filtered active list (not the original slaveIf) and call metrics.CheckClockRole
with the filtered active port slice and corresponding roles so skipped ports are
excluded from the all-FAULTY assertion; keep using portEngine.TurnAllPortsDown
and TurnAllPortsUp and the existing metrics.CheckClockRole call but pass the
filtered slice instead of slaveIf.
- Around line 2019-2100: The test asserts clock-class degradation but never
enables gmCapable, so call ptptesthelper.EnableGMCapableInPlace(...) on the
clock-under-test PtpConfig before the initial checkClockClassState; if the test
is DualNIC (fullConfig.PtpModeDiscovered == DualNICBoundaryClock or
DualNICBoundaryClockHA) also call EnableGMCapableInPlace on
fullConfig.DiscoveredClockUnderTestSecondaryPtpConfig (same pattern as the
earlier patches at lines ~1082/1132) so ptp4l will report clock-class changes
when you reach the "Checking initial clock class is Locked (6)" check.

In `@test/pkg/ptptesthelper/ptptesthelper.go`:
- Around line 654-665: RestorePtp4lConf currently swallows errors and returns
immediately, which can leave the mutated ptp4l config active; change
RestorePtp4lConf to return an error, propagate and return any
client.Client.PtpConfigs(...).Update errors, and after a successful update poll
the PtpConfig via client.Client.PtpConfigs(pkg.PtpLinuxDaemonNamespace).Get
(checking ptpCfg.Spec.Profile[0].Ptp4lConf equals originalConf) with a
timeout/backoff until the old config is visible before returning nil; ensure
failures/timeouts return a descriptive error instead of only logging.

---

Nitpick comments:
In `@api/v1/ptpoperatorconfig_webhook.go`:
- Around line 39-41: Update the webhook builder to replace the deprecated
WithCustomValidator call with WithValidator and change
ptpOperatorConfigValidator to implement the new generic interface
admission.Validator[*PtpOperatorConfig] instead of admission.CustomValidator;
specifically, modify the call site using ctrl.NewWebhookManagedBy(mgr,
r).WithCustomValidator(&ptpOperatorConfigValidator{}).Complete() to use
.WithValidator(&ptpOperatorConfigValidator{}) and update the
ptpOperatorConfigValidator type signature and method receiver signatures to
match admission.Validator[*PtpOperatorConfig] (ValidateCreate, ValidateUpdate,
ValidateDelete signatures that accept *PtpOperatorConfig and return
admission.Response/Result types as required by the new interface).

In `@Dockerfile`:
- Around line 9-20: The Dockerfile's runtime stage runs as root; add a non-root
user and switch to it to improve security: create a user/group (e.g.,
USER_ID/USER_NAME), chown the runtime artifacts copied into
/usr/local/bin/ptp-operator, /manifests and /bindata to that user, add a USER
instruction before ENTRYPOINT to drop root privileges, and ensure the existing
ENTRYPOINT ["/usr/local/bin/ptp-operator"] still works with the new user's
permissions (adjust file modes or capabilities if the operator needs specific
privileges).

In `@ptp-tools/Dockerfile.debug`:
- Around line 1-2: The image currently runs as root which the scanner flags; to
address this add a non-root user and switch to it in the Dockerfile while
keeping tcpdump functionality by documenting or relying on runtime capability
grants (CAP_NET_RAW) or setcap on the tcpdump binary. Update the Dockerfile to
create a user (e.g., adduser or group/user names), chown any needed directories,
and use USER <nonroot> before final image steps, and add a note that tcpdump
requires CAP_NET_RAW so runtimes should grant that capability or setcap on
/usr/sbin/tcpdump.

In `@ptp-tools/Dockerfile.ptpop`:
- Around line 1-2: Update the RUN line that installs binutils-gold to use
apt-get install --no-install-recommends to shrink the image and reduce attack
surface: locate the stage that starts with "FROM docker.io/golang:1.25.7 AS
builder" and modify the RUN command "apt-get update && apt-get install -y
binutils-gold && rm -rf /var/lib/apt/lists/*" to include
"--no-install-recommends" in the apt-get install invocation so only required
packages are installed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b1852547-50b0-44e3-b7d0-c8a9bf027997

📥 Commits

Reviewing files that changed from the base of the PR and between 3c0739e and f0d4e74.

⛔ Files ignored due to path filters (268)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/gogo/protobuf/AUTHORS is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/CONTRIBUTORS is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/Makefile is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/clone.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/custom_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/decode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/deprecated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/discard.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/duration.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/duration_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/encode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/encode_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/equal.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/extensions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/extensions_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/lib.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/lib_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/message_set.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_reflect.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/properties.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/properties_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/skip_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_marshal.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_merge.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_unmarshal.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/text.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/text_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/text_parser.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/timestamp.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/wrappers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_cluster_version.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_ingress.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_insights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_network.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/register.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_backup.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_image_policy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_crio_credential_provider_config.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_image_policy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_insights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_pki.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha2/types_insights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha2/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/controller-runtime-common/pkg/tls/controller.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/controller-runtime-common/pkg/tls/tls.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/library-go/pkg/crypto/tls_adherence.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/encoding/text/decode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/filedesc/desc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/filedesc/editions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/impl/codec_map.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/impl/decode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/impl/validate.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/internal/version/version.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/proto/decode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1beta1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1beta1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admission/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1alpha1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1alpha1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1beta1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apidiscovery/v2/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apidiscovery/v2/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apidiscovery/v2/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apidiscovery/v2/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apidiscovery/v2beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apidiscovery/v2beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apidiscovery/v2beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apidiscovery/v2beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apiserverinternal/v1alpha1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apiserverinternal/v1alpha1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta2/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta2/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta2/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta2/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta2/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/apps/v1beta2/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1alpha1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1alpha1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1alpha1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1alpha1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authentication/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authorization/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authorization/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authorization/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authorization/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authorization/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authorization/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authorization/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/authorization/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2beta2/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2beta2/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2beta2/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/batch/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/register.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1alpha1/zz_generated.prerelease-lifecycle.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/register.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1alpha2/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1alpha2/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1alpha2/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1alpha2/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/coordination/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/toleration.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/core/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1beta1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1beta1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/discovery/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/events/v1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/events/v1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/events/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/events/v1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/events/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/events/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/events/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/events/v1beta1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/extensions/v1beta1/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/extensions/v1beta1/generated.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/extensions/v1beta1/generated.proto is excluded by !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/extensions/v1beta1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/k8s.io/api/extensions/v1beta1/types.go is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (32)
  • Dockerfile
  • OWNERS
  • api/v1/nodeptpdevice_types.go
  • api/v1/ptpconfig_webhook.go
  • api/v1/ptpoperatorconfig_webhook.go
  • api/v1/zz_generated.deepcopy.go
  • bindata/linuxptp/ptp-daemon.yaml
  • bundle/manifests/ptp-operator.clusterserviceversion.yaml
  • bundle/manifests/ptp.openshift.io_nodeptpdevices.yaml
  • config/crd/bases/ptp.openshift.io_nodeptpdevices.yaml
  • config/manifests/bases/ptp-operator.clusterserviceversion.yaml
  • config/prometheus/monitor.yaml
  • controllers/ptpoperatorconfig_controller.go
  • controllers/tls_profile_test.go
  • controllers/tls_watcher_test.go
  • go.mod
  • main.go
  • manifests/stable/ptp-operator.clusterserviceversion.yaml
  • manifests/stable/ptp.openshift.io_nodeptpdevices.yaml
  • must-gather/collection-scripts/gather
  • ptp-tools/Dockerfile.cep
  • ptp-tools/Dockerfile.debug
  • ptp-tools/Dockerfile.krp
  • ptp-tools/Dockerfile.lptpd
  • ptp-tools/Dockerfile.ptpop
  • ptp-tools/Makefile
  • scripts/k8s-start.sh
  • scripts/run-on-vm.sh
  • scripts/run-tests.sh
  • test/conformance/serial/ptp.go
  • test/pkg/ptptesthelper/ptptesthelper.go
  • test/pkg/testconfig/testconfig.go

TEST_MODES_RAW=""
PTP_LOG_LEVEL="info"
LINUXPTP_DAEMON_IMAGE=""
MUST_GATHER_IMAGE=""
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

DEBUG_IMAGE is used but may be unset, causing script failure.

DEBUG_IMAGE is referenced on line 127 but is only set when --debug-image is provided. Unlike MUST_GATHER_IMAGE which is initialized to "" on line 28, DEBUG_IMAGE has no default initialization. With set -u enabled, this will cause an "unbound variable" error if --must-gather-image is provided without --debug-image.

🔧 Proposed fix
 MUST_GATHER_IMAGE=""
+DEBUG_IMAGE=""

Also applies to: 40-43

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/run-tests.sh` at line 28, The script fails under "set -u" because
DEBUG_IMAGE is referenced without a default; initialize DEBUG_IMAGE (and any
other optional flags analogous to MUST_GATHER_IMAGE like the ones around the
same block) to empty strings at the top of the script so references in argument
parsing and later (e.g., the use on line where DEBUG_IMAGE is read) won't
trigger an unbound variable error; update the initial variable declarations to
include DEBUG_IMAGE="" to mirror MUST_GATHER_IMAGE="" (and ensure any other
optional variables used later are likewise initialized).

Comment on lines +2019 to +2100
It("BC clock class recovers to Locked after upstream link outage", func() {
if fullConfig.PtpModeDiscovered == testconfig.TelcoGrandMasterClock {
Skip("test not valid for WPC GM config")
}
if fullConfig.PtpModeDesired == testconfig.DualFollowerClock {
Skip("Test not valid for dual follower scenario")
}
if fullConfig.PtpModeDiscovered != testconfig.BoundaryClock &&
fullConfig.PtpModeDiscovered != testconfig.DualNICBoundaryClock &&
fullConfig.PtpModeDiscovered != testconfig.DualNICBoundaryClockHA {
Skip("test only valid for Boundary Clock configurations")
}

slaveIf := ptpv1.GetInterfaces((ptpv1.PtpConfig)(*fullConfig.DiscoveredClockUnderTestPtpConfig), ptpv1.Slave)
if fullConfig.PtpModeDiscovered == testconfig.DualNICBoundaryClock ||
fullConfig.PtpModeDiscovered == testconfig.DualNICBoundaryClockHA {
secondarySlaveIf := ptpv1.GetInterfaces((ptpv1.PtpConfig)(*fullConfig.DiscoveredClockUnderTestSecondaryPtpConfig), ptpv1.Slave)
logrus.Infof("Secondary BC slave interfaces are %+q", secondarySlaveIf)
slaveIf = append(slaveIf, secondarySlaveIf...)
}
Expect(slaveIf).ToNot(BeEmpty(), "no slave interfaces found in the clock-under-test PtpConfig(s)")
logrus.Infof("All slave interfaces are %+q", slaveIf)
slavePodNodeName := fullConfig.DiscoveredClockUnderTestPod.Spec.NodeName

portEngine.Initialize(fullConfig.DiscoveredClockUnderTestPod, slaveIf)
DeferCleanup(func() {
ptptesthelper.DeletePtpTestPrivilegedDaemonSet(
pkg.RecoveryNetworkOutageDaemonSetName,
pkg.RecoveryNetworkOutageDaemonSetNamespace,
)
})

By("Checking initial clock class is Locked (6)")
checkClockClassState(fullConfig, strconv.Itoa(int(fbprotocol.ClockClass6)))

By("Setting all slave interfaces down")
skippedInterfacesStr, isSet := os.LookupEnv("SKIP_INTERFACES")
if !isSet {
Skip("Mandatory to provide skipped interface to avoid making a node disconnected from the cluster")
}
skipInterfaces := make(map[string]bool)
for _, val := range strings.Split(skippedInterfacesStr, ",") {
skipInterfaces[val] = true
}
err := portEngine.TurnAllPortsDown(skipInterfaces)
Expect(err).To(BeNil())
DeferCleanup(func() {
portEngine.TurnAllPortsUp()
})

faultyRoles := make([]metrics.MetricRole, len(slaveIf))
for i := range faultyRoles {
faultyRoles[i] = metrics.MetricRoleFaulty
}
slaveRoles := make([]metrics.MetricRole, len(slaveIf))
for i := range slaveRoles {
slaveRoles[i] = metrics.MetricRoleSlave
}

By("Checking that all slave port roles are FAULTY after wait")
Eventually(func() error {
return metrics.CheckClockRole(faultyRoles, slaveIf, &slavePodNodeName)
}, 5*time.Minute, 10*time.Second).Should(BeNil())

By("Checking clock class has degraded away from Locked (6)")
Eventually(func() bool {
return !checkClockClassStateReturnBool(fullConfig, strconv.Itoa(int(fbprotocol.ClockClass6)))
}, 5*time.Minute, 10*time.Second).Should(BeTrue(),
"expected clock class to degrade from Locked (6) after upstream link loss")

By("Setting all slave interfaces up")
err = portEngine.TurnAllPortsUp()
Expect(err).To(BeNil())

By("Checking that all slave port roles are SLAVE after wait")
Eventually(func() error {
return metrics.CheckClockRole(slaveRoles, slaveIf, &slavePodNodeName)
}, 5*time.Minute, 10*time.Second).Should(BeNil())

By("Checking clock class recovers to Locked (6)")
waitForClockClass(fullConfig, strconv.Itoa(int(fbprotocol.ClockClass6)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'BC config defaults:\\n'
rg -n -C2 'gmCapable 0' test/pkg/testconfig/testconfig.go

printf '\nClock-class specs that patch gmCapable in place:\\n'
rg -n -C2 'EnableGMCapableInPlace|Verify clockClass when locking PTP source|BC clock class recovers to Locked after upstream link outage' test/conformance/serial/ptp.go

Repository: openshift/ptp-operator

Length of output: 2033


🏁 Script executed:

rg -n "checkClockClassState|checkClockClassStateReturnBool" test/conformance/serial/ptp.go -A3 -B1 | head -50

Repository: openshift/ptp-operator

Length of output: 2147


🏁 Script executed:

rg -n "gmCapable" test/conformance/serial/ptp.go | head -20

Repository: openshift/ptp-operator

Length of output: 1055


🏁 Script executed:

rg -n -A10 "func EnableGMCapableInPlace" test/pkg/

Repository: openshift/ptp-operator

Length of output: 1115


🏁 Script executed:

rg -n "BC clock class recovers to Locked after upstream link outage" test/conformance/serial/ptp.go -A80 | grep -i "gmCapable\|EnableGMCapableInPlace"

Repository: openshift/ptp-operator

Length of output: 48


Enable gmCapable=1 in this test before asserting clock-class degradation.

The BC configs created by CreatePtpConfigBC() default to gmCapable 0, which prevents ptp4l from reporting clock-class changes on sync loss (see comment at line 1077). The two preceding clock-class specs (lines 1082 and 1132) explicitly call ptptesthelper.EnableGMCapableInPlace() before asserting class changes. This spec asserts clock-class degradation at line 2085 without that patch, so the assertion targets behavior that the default config does not expose.

Add the EnableGMCapableInPlace() call before "Checking initial clock class is Locked (6)" at line 2051.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/conformance/serial/ptp.go` around lines 2019 - 2100, The test asserts
clock-class degradation but never enables gmCapable, so call
ptptesthelper.EnableGMCapableInPlace(...) on the clock-under-test PtpConfig
before the initial checkClockClassState; if the test is DualNIC
(fullConfig.PtpModeDiscovered == DualNICBoundaryClock or DualNICBoundaryClockHA)
also call EnableGMCapableInPlace on
fullConfig.DiscoveredClockUnderTestSecondaryPtpConfig (same pattern as the
earlier patches at lines ~1082/1132) so ptp4l will report clock-class changes
when you reach the "Checking initial clock class is Locked (6)" check.

Comment on lines +2055 to +2081
skippedInterfacesStr, isSet := os.LookupEnv("SKIP_INTERFACES")
if !isSet {
Skip("Mandatory to provide skipped interface to avoid making a node disconnected from the cluster")
}
skipInterfaces := make(map[string]bool)
for _, val := range strings.Split(skippedInterfacesStr, ",") {
skipInterfaces[val] = true
}
err := portEngine.TurnAllPortsDown(skipInterfaces)
Expect(err).To(BeNil())
DeferCleanup(func() {
portEngine.TurnAllPortsUp()
})

faultyRoles := make([]metrics.MetricRole, len(slaveIf))
for i := range faultyRoles {
faultyRoles[i] = metrics.MetricRoleFaulty
}
slaveRoles := make([]metrics.MetricRole, len(slaveIf))
for i := range slaveRoles {
slaveRoles[i] = metrics.MetricRoleSlave
}

By("Checking that all slave port roles are FAULTY after wait")
Eventually(func() error {
return metrics.CheckClockRole(faultyRoles, slaveIf, &slavePodNodeName)
}, 5*time.Minute, 10*time.Second).Should(BeNil())
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Compute the active-port set before the outage and install cleanup first.

Skipped slave ports are still included in the faultyRoles assertion, so a skipped PTP port can never satisfy the all-FAULTY check. Also, DeferCleanup is registered only after TurnAllPortsDown, so a partial failure can leave interfaces down for the rest of the suite.

Suggested adjustment
 				skipInterfaces := make(map[string]bool)
 				for _, val := range strings.Split(skippedInterfacesStr, ",") {
 					skipInterfaces[val] = true
 				}
+				activeSlaveIf := make([]string, 0, len(slaveIf))
+				for _, iface := range slaveIf {
+					if !skipInterfaces[iface] {
+						activeSlaveIf = append(activeSlaveIf, iface)
+					}
+				}
+				Expect(activeSlaveIf).ToNot(BeEmpty(), "all slave interfaces were skipped")
+
+				DeferCleanup(func() {
+					portEngine.TurnAllPortsUp()
+				})
 				err := portEngine.TurnAllPortsDown(skipInterfaces)
 				Expect(err).To(BeNil())
-				DeferCleanup(func() {
-					portEngine.TurnAllPortsUp()
-				})
 
-				faultyRoles := make([]metrics.MetricRole, len(slaveIf))
+				faultyRoles := make([]metrics.MetricRole, len(activeSlaveIf))
 				for i := range faultyRoles {
 					faultyRoles[i] = metrics.MetricRoleFaulty
 				}
@@
 				By("Checking that all slave port roles are FAULTY after wait")
 				Eventually(func() error {
-					return metrics.CheckClockRole(faultyRoles, slaveIf, &slavePodNodeName)
+					return metrics.CheckClockRole(faultyRoles, activeSlaveIf, &slavePodNodeName)
 				}, 5*time.Minute, 10*time.Second).Should(BeNil())
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/conformance/serial/ptp.go` around lines 2055 - 2081, Compute the active
slave-port set by filtering slaveIf against the SKIP_INTERFACES map
(skippedInterfacesStr -> skipInterfaces) before taking the outage, register the
cleanup immediately (call DeferCleanup to TurnAllPortsUp right after building
skipInterfaces and before invoking portEngine.TurnAllPortsDown), and then build
faultyRoles/slaveRoles sized to the filtered active list (not the original
slaveIf) and call metrics.CheckClockRole with the filtered active port slice and
corresponding roles so skipped ports are excluded from the all-FAULTY assertion;
keep using portEngine.TurnAllPortsDown and TurnAllPortsUp and the existing
metrics.CheckClockRole call but pass the filtered slice instead of slaveIf.

Comment on lines +3574 to +3615
func setupBCClockClassEvents(nodeName string) bcEventContext {
ctx := bcEventContext{}
if !event.Enable() {
return ctx
}
logrus.Info("Deploy consumer app for BC clock class event monitoring")
if createErr := event.CreateConsumerApp(nodeName); createErr != nil {
logrus.Warnf("PTP events not available: %s; skipping event checks", createErr)
return ctx
}
time.Sleep(10 * time.Second)
event.InitPubSub()
var eventCleanup func()
ctx.subs, eventCleanup = event.SubscribeToGMChangeEvents(100, true, 60*time.Second)
termMonitor, monErr := event.MonitorPodLogsRegex()
if monErr != nil {
logrus.Warnf("Could not start event monitoring: %s; skipping event checks", monErr)
} else {
ctx.available = true
}
DeferCleanup(func() {
if termMonitor != nil {
stopMonitor(termMonitor)
}
eventCleanup()
event.PubSub.Close()
if deleteErr := event.DeleteConsumerNamespace(); deleteErr != nil {
logrus.Debugf("Deleting consumer namespace failed: %s", deleteErr)
}
})
return ctx
}

// verifyClockClassViaEvent drains the clock-class event channel and asserts the
// expected value. No-op when events are not available.
func verifyClockClassViaEvent(evCtx bcEventContext, expectedClass int) {
if !evCtx.available {
return
}
events := getGMEvents(evCtx.subs.GNSS, evCtx.subs.CLOCKCLASS, evCtx.subs.LOCKSTATE, 10*time.Second)
verifyMetric(events[ptpEvent.PtpClockClassChange], float64(expectedClass))
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Filter the clock-class event stream to the BC under test before asserting.

This subscribes to the shared PtpClockClassChange topic with pushInitial=true, then verifyClockClassViaEvent() asserts on whichever clock-class event is buffered in the next 10s. In BC topologies that can be the initial snapshot or another config's transition, so the result is flaky unless the received event is scoped to the node/config under test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/conformance/serial/ptp.go` around lines 3574 - 3615, The test is
asserting on a shared PtpClockClassChange topic and can pick up events from
other BCs; update setupBCClockClassEvents/verifyClockClassViaEvent to scope the
event stream to the BC under test: when subscribing (SubscribeToGMChangeEvents)
or when calling getGMEvents in verifyClockClassViaEvent, filter the returned
events for the node/config under test (e.g., check the event's
source/namespace/node identifier or include nodeName in the subscription call)
so verifyMetric only uses PtpClockClassChange events originating from that
specific BC before asserting the expectedClass.

Comment on lines +654 to +665
func RestorePtp4lConf(configName, originalConf string) {
ptpCfg, err := client.Client.PtpConfigs(pkg.PtpLinuxDaemonNamespace).Get(
context.Background(), configName, metav1.GetOptions{})
if err != nil {
logrus.Errorf("Failed to get PtpConfig %s for restore: %s", configName, err)
return
}
ptpCfg.Spec.Profile[0].Ptp4lConf = &originalConf
if _, err := client.Client.PtpConfigs(pkg.PtpLinuxDaemonNamespace).Update(
context.Background(), ptpCfg, metav1.UpdateOptions{}); err != nil {
logrus.Errorf("Failed to restore PtpConfig %s: %s", configName, err)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don't let restore cleanup silently leak the modified ptp4l config.

The new BC clock-class specs mutate Ptp4lConf in place, but this helper only logs restore failures and returns immediately after the API update. A failed or slow restore can leave gmCapable=1 active for later serial specs. Return an error and wait until the old config is visible in the pod before cleanup completes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/pkg/ptptesthelper/ptptesthelper.go` around lines 654 - 665,
RestorePtp4lConf currently swallows errors and returns immediately, which can
leave the mutated ptp4l config active; change RestorePtp4lConf to return an
error, propagate and return any client.Client.PtpConfigs(...).Update errors, and
after a successful update poll the PtpConfig via
client.Client.PtpConfigs(pkg.PtpLinuxDaemonNamespace).Get (checking
ptpCfg.Spec.Profile[0].Ptp4lConf equals originalConf) with a timeout/backoff
until the old config is visible before returning nil; ensure failures/timeouts
return a descriptive error instead of only logging.

@nocturnalastro nocturnalastro marked this pull request as draft April 7, 2026 21:32
@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants