Skip to content

Requeue instead of awaiting change#309

Open
Jakob-Naucke wants to merge 4 commits into
trusted-execution-clusters:mainfrom
Jakob-Naucke:requeue
Open

Requeue instead of awaiting change#309
Jakob-Naucke wants to merge 4 commits into
trusted-execution-clusters:mainfrom
Jakob-Naucke:requeue

Conversation

@Jakob-Naucke

@Jakob-Naucke Jakob-Naucke commented Jul 10, 2026

Copy link
Copy Markdown
Member

As per kube-rs docs, await_change is unadvisable for cases where
eventual consistency is desired because reconcile events can be lost
occasionally. We saw this happen in tests where owned resources with
finalizers stayed behind after TEC deletion.

Instead, requeue after 1 minute (ongoing deletion cases) or 5
minutes (resources applied cases). This is shorter than kube-rs's
"sane default" of 60 minutes, but aligns better with testing, user
expectations, and is also what KubeVirt appears to be doing.

Also

  • update all timeouts that rely on such a change to a base of 6 minutes, to avoid timeout when an event is missed (seen many times on OpenShift CI, but @iroykaufman was able to reproduce in KinD too)
  • reconcile images on related jobs too so that even when the image is unavailable, their status is updated without relying on requeue

IMO this supersedes #302. complements #302. I had a number of successful runs with just this patchset on OpenShift CI, but #302 makes sense logically.

Summary by Sourcery

Switch controller reconciler actions from await_change to periodic requeue and adjust related timeouts to improve eventual consistency and test reliability.

Bug Fixes:

  • Prevent owned resources with finalizers from being left behind when reconcile events are missed by using requeue instead of await_change.
  • Reduce test flakiness caused by timeouts that expired before delayed reconcile-driven deletions completed.

Enhancements:

  • Reconcile ApprovedImage-related jobs so their status is updated even when images are unavailable.
  • Align controller requeue intervals with user expectations and external practices by using shorter, explicit delays.

Tests:

  • Increase deletion and condition wait timeouts in trusted execution cluster tests to accommodate delayed reconciliations.
  • Extend cleanup polling duration in test utilities to allow more time for resource teardown after cluster deletion.

so that status is updated in a timely manner

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
@openshift-ci

openshift-ci Bot commented Jul 10, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Jakob-Naucke

The full list of commands accepted by this bot can be found 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

@sourcery-ai

sourcery-ai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR replaces await_change-based controller behavior with explicit requeue delays and extends related test timeouts, while wiring the image controller to own Jobs so status/image reconciliations happen reliably even when events are missed.

Sequence diagram for controller requeue behavior instead of await_change

sequenceDiagram
    participant Controller
    participant image_add_reconcile
    participant handle_new_image

    Controller->>image_add_reconcile: reconcile ApprovedImage
    image_add_reconcile->>handle_new_image: handle_new_image(client, image)
    handle_new_image-->>image_add_reconcile: Ok(reason)
    image_add_reconcile-->>Controller: Action::requeue(Duration::from_secs(300)), reason

    alt image_remove_reconcile paths
        Controller->>image_remove_reconcile: reconcile ApprovedImage removal
        image_remove_reconcile-->>Controller: Action::requeue(Duration::from_secs(60))
    end

    alt keygen_reconcile cleanup
        Controller->>keygen_reconcile: Event::Cleanup(machine)
        keygen_reconcile->>trustee_unmount_secret: trustee::unmount_secret(kube_client, id)
        trustee_unmount_secret-->>keygen_reconcile: Ok(())
        keygen_reconcile-->>Controller: Action::requeue(Duration::from_secs(60))
    end

    alt keygen_reconcile apply
        Controller->>keygen_reconcile: Event::Apply(machine)
        keygen_reconcile->>trustee_mount_secret: trustee::mount_secret(kube_client, id)
        trustee_mount_secret-->>keygen_reconcile: Ok(())
        keygen_reconcile-->>Controller: Action::requeue(Duration::from_secs(300))
    end
Loading

File-Level Changes

Change Details Files
Replace await_change controller actions with explicit requeue durations to avoid lost reconcile events and better handle eventual consistency.
  • image_add_reconcile now requeues after 5 minutes on success and 1 minute on PCR computation failure instead of awaiting change
  • image_remove_reconcile uses 1-minute requeue actions both when TEC is absent/being deleted and after disallowing images, replacing await_change
  • keygen_reconcile maps successful mount_secret to a 5-minute requeue, and successful/short-circuit unmount_secret paths to a 1-minute requeue in place of await_change
operator/src/reference_values.rs
operator/src/register_server.rs
Extend test and cleanup timeouts to accommodate longer requeue intervals and missed events so resources have enough time to be deleted or reach expected states.
  • Increase deletion timeouts for ApprovedImage, Machine, and AttestationKey resources from 120s/60s to 360s in TEC-related tests
  • Increase the timeout for waiting for ApprovedImage PodPending state from 30s to 360s
  • Increase the TestContext cleanup poller timeout base from 60s to 360s
tests/trusted_execution_cluster.rs
test_utils/src/lib.rs
Have the RV image controller own Jobs with a specific label selector so Job events also trigger reconciles, ensuring related image state is updated even if image events are missed.
  • Instantiate a Jobs Api in launch_rv_image_controller and configure a watcher::Config with a label selector for PCR-command Jobs
  • Register Jobs as owned resources on the Controller with the configured watcher::Config so Job changes feed into image_reconcile
operator/src/reference_values.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The various requeue intervals (60s vs 300s) and scaled timeouts (360s) are currently hard-coded in multiple places; consider centralizing them into named constants to make the intended behavior clearer and easier to adjust.
  • For the new .owns(jobs, wc) watcher configuration, double-check that the label selector string construction ({JOB_LABEL_KEY}={PCR_COMMAND_NAME}) matches all existing job labels so that reconcile behavior for related jobs is consistent and predictable.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The various requeue intervals (60s vs 300s) and scaled timeouts (360s) are currently hard-coded in multiple places; consider centralizing them into named constants to make the intended behavior clearer and easier to adjust.
- For the new `.owns(jobs, wc)` watcher configuration, double-check that the label selector string construction (`{JOB_LABEL_KEY}={PCR_COMMAND_NAME}`) matches all existing job labels so that reconcile behavior for related jobs is consistent and predictable.

## Individual Comments

### Comment 1
<location path="operator/src/reference_values.rs" line_range="340-344" />
<code_context>

 pub async fn launch_rv_image_controller(client: Client) {
     let images: Api<ApprovedImage> = Api::default_namespaced(client.clone());
+    let jobs: Api<Job> = Api::default_namespaced(client.clone());
+    let wc = watcher::Config::default().labels(&format!("{JOB_LABEL_KEY}={PCR_COMMAND_NAME}"));
     tokio::spawn(
         Controller::new(images, Default::default())
+            .owns(jobs, wc)
             .run(image_reconcile, controller_error_policy, Arc::new(client))
             .for_each(controller_info),
</code_context>
<issue_to_address>
**question (bug_risk):** Clarify the implications of restricting owned Jobs via a label selector in the watcher config.

Using `watcher::Config::default().labels(&format!("{JOB_LABEL_KEY}={PCR_COMMAND_NAME}"))` with `.owns(jobs, wc)` limits ownership tracking to Jobs with exactly that label/value. Any relevant Jobs missing this label (or using a different value) will not be reconciled, while unrelated Jobs that reuse the label may be tracked incorrectly. Please either narrow the selector further (e.g., additional labels/owner refs) or confirm that all Jobs created for this controller reliably set this label.
</issue_to_address>

### Comment 2
<location path="tests/trusted_execution_cluster.rs" line_range="120" />
<code_context>
+        wait_for_resource_deleted(&machines, &machine_name, scaled_timeout(360)).await?;
+        wait_for_resource_deleted(&attestation_keys, &ak_name, scaled_timeout(360)).await?;
         let secrets_api: Api<Secret> = Api::namespaced(client.clone(), namespace);
         wait_for_resource_deleted(&secrets_api, &ak_name, scaled_timeout(120)).await?;

</code_context>
<issue_to_address>
**suggestion (testing):** Consider aligning Secret deletion timeout with the extended 360s timeouts for Machines and AttestationKeys

In the TEC cleanup and attestation key lifecycle tests, Machine and AttestationKey deletions were increased to 360s to tolerate missed reconcile events, but Secret deletion remains at 120s. If Secret deletion uses the same controller path, this shorter timeout can still cause intermittent flakes when reconciles are missed. Please consider increasing this to 360s (or centralizing these timeouts) for consistent test behavior.

Suggested implementation:

```rust
        wait_for_resource_deleted(&secrets_api, &ak_name, scaled_timeout(360)).await?;

```

If other tests in this file (or module) also use hard-coded deletion timeouts, consider:
1. Introducing a shared constant (e.g., `const DELETION_TIMEOUT_SECS: u64 = 360;`) and replacing the magic numbers with it.
2. Ensuring all resources that rely on the same controller path use the same timeout to avoid inconsistent behavior across tests.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +340 to +344
let jobs: Api<Job> = Api::default_namespaced(client.clone());
let wc = watcher::Config::default().labels(&format!("{JOB_LABEL_KEY}={PCR_COMMAND_NAME}"));
tokio::spawn(
Controller::new(images, Default::default())
.owns(jobs, wc)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

question (bug_risk): Clarify the implications of restricting owned Jobs via a label selector in the watcher config.

Using watcher::Config::default().labels(&format!("{JOB_LABEL_KEY}={PCR_COMMAND_NAME}")) with .owns(jobs, wc) limits ownership tracking to Jobs with exactly that label/value. Any relevant Jobs missing this label (or using a different value) will not be reconciled, while unrelated Jobs that reuse the label may be tracked incorrectly. Please either narrow the selector further (e.g., additional labels/owner refs) or confirm that all Jobs created for this controller reliably set this label.

wait_for_resource_deleted(&machines, &machine_name, scaled_timeout(360)).await?;
wait_for_resource_deleted(&attestation_keys, &ak_name, scaled_timeout(360)).await?;
let secrets_api: Api<Secret> = Api::namespaced(client.clone(), namespace);
wait_for_resource_deleted(&secrets_api, &ak_name, scaled_timeout(120)).await?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (testing): Consider aligning Secret deletion timeout with the extended 360s timeouts for Machines and AttestationKeys

In the TEC cleanup and attestation key lifecycle tests, Machine and AttestationKey deletions were increased to 360s to tolerate missed reconcile events, but Secret deletion remains at 120s. If Secret deletion uses the same controller path, this shorter timeout can still cause intermittent flakes when reconciles are missed. Please consider increasing this to 360s (or centralizing these timeouts) for consistent test behavior.

Suggested implementation:

        wait_for_resource_deleted(&secrets_api, &ak_name, scaled_timeout(360)).await?;

If other tests in this file (or module) also use hard-coded deletion timeouts, consider:

  1. Introducing a shared constant (e.g., const DELETION_TIMEOUT_SECS: u64 = 360;) and replacing the magic numbers with it.
  2. Ensuring all resources that rely on the same controller path use the same timeout to avoid inconsistent behavior across tests.

@iroykaufman

Copy link
Copy Markdown
Member

Looking good! Maybe it is also worth replace the await_change with requeue in the AK registration finalizer here

@iroykaufman

Copy link
Copy Markdown
Member

IMO this supersedes #302.

I think #302 is still necessary because the following scenario still holds:
ApproveImage created -> finalizer is patched -> Cluster removed -> finalizer called back with apply.
Adopt image is never called, and the ApproveImage will not be deleted. The race here is not a case of a missing trigger, which this PR tries to solve (AFAIU). Of course, we can continue this discussion on PR#302.

As per kube-rs docs, await_change is unadvisable for cases where
eventual consistency is desired because reconcile events can be lost
occasionally. We saw this happen in tests where owned resources with
finalizers stayed behind after TEC deletion.

Instead, requeue after 1 minute (ongoing deletion cases) or 5
minutes (resources applied cases). This is shorter than kube-rs's
"sane default" of 60 minutes, but aligns better with testing, user
expectations, and is also what KubeVirt appears to be doing.

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
requeue is 5 minutes, so wait 6 minutes for deletion if the event is
missed. Also applies to ApprovedImage status update.

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
in consistency with remainder codebase

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
if ak.spec.uuid.as_ref() == Some(&machine.spec.id) {
approve_ak(&ak, &machine, &ctx).await?;
return Ok(Action::await_change());
return Ok(Action::requeue(Duration::from_secs(300)));

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.

nit: should we define a macro for the default polling time to highlight when this should be the default behavior?

@alicefr

alicefr commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@Jakob-Naucke why do we set 5 mins instead of the suggested hour? Can you please give some example of missing events.

@alicefr

alicefr commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

My worry is that decreasing the polling time is just a mitigation for real bugs. I'd like to understand if it is the operator that just ignores the events or it is kubernetes that just drops those events

@Jakob-Naucke

Copy link
Copy Markdown
Member Author

why do we set 5 mins instead of the suggested hour?

This is a tradeoff between "overhead and log noise" and "how long it takes to reach consistency when events are lost". I went for a duration that also still makes sense for timeouts in testing. (Also considered changing the requeue duration for tests only, but that's a bit of a volkswagenism)

Can you please give some example of missing events.

So what's known to have happened is cases where (enhanced, see diff) operator logs suggest that the resource was deleted eventually, but error log suggests that it happened too late:

diff --git a/operator/src/reference_values.rs b/operator/src/reference_values.rs
index 4077d9b..c6faa15 100644
--- a/operator/src/reference_values.rs
+++ b/operator/src/reference_values.rs
@@ -324,2 +324,3 @@ async fn image_remove_reconcile(
     let name = image.metadata.name.as_ref().unwrap_or(&default);
+    info!("Cleanup for image {image:?}");
     if cluster.is_none() {
[INFO  operator::reference_values] Cleanup for image ApprovedImage { metadata: ObjectMeta { annotations: Some({"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"trusted-execution-clusters.io/v1alpha1\",\"kind\":\"ApprovedImage\",\"metadata\":{\"annotations\":{},\"name\":\"coreos\",\"namespace\":\"ci-79393-42ef8b13-test-c87cf399\"},\"spec\":{\"image\":\"quay.io/trusted-execution-clusters/fedora-coreos@sha256:6997f51fd27d1be1b5fc2e6cc3ebf16c17eb94d819b5d44ea8d6cf5f826ee773\"}}\n"}), creation_timestamp: Some(Time(2026-07-06T16:06:22Z)), deletion_grace_period_seconds: Some(0), deletion_timestamp: Some(Time(2026-07-06T16:36:07Z)), finalizers: Some(["finalizer.approved-image.trusted-execution-clusters.io"]), generate_name: None, generation: Some(2), labels: None, managed_fields: Some([ManagedFieldsEntry { api_version: Some("trusted-execution-clusters.io/v1alpha1"), fields_type: Some("FieldsV1"), fields_v1: Some(FieldsV1(Object {"f:metadata": Object {"f:annotations": Object {".": Object {}, "f:kubectl.kubernetes.io/last-applied-configuration": Object {}}}, "f:spec": Object {".": Object {}, "f:image": Object {}}})), manager: Some("kubectl-client-side-apply"), operation: Some("Update"), subresource: None, time: Some(Time(2026-07-06T16:06:22Z)) }, ManagedFieldsEntry { api_version: Some("trusted-execution-clusters.io/v1alpha1"), fields_type: Some("FieldsV1"), fields_v1: Some(FieldsV1(Object {"f:metadata": Object {"f:finalizers": Object {".": Object {}, "v:\"finalizer.approved-image.trusted-execution-clusters.io\"": Object {}}, "f:ownerReferences": Object {".": Object {}, "k:{\"uid\":\"09a280f6-1255-4234-a07e-b089169a9789\"}": Object {}}}})), manager: Some("unknown"), operation: Some("Update"), subresource: None, time: Some(Time(2026-07-06T16:06:23Z)) }, ManagedFieldsEntry { api_version: Some("trusted-execution-clusters.io/v1alpha1"), fields_type: Some("FieldsV1"), fields_v1: Some(FieldsV1(Object {"f:status": Object {".": Object {}, "f:conditions": Object {".": Object {}, "k:{\"type\":\"Committed\"}": Object {".": Object {}, "f:lastTransitionTime": Object {}, "f:message": Object {}, "f:observedGeneration": Object {}, "f:reason": Object {}, "f:status": Object {}, "f:type": Object {}}}}})), manager: Some("unknown"), operation: Some("Update"), subresource: Some("status"), time: Some(Time(2026-07-06T16:06:24Z)) }]), name: Some("coreos"), namespace: Some("ci-79393-42ef8b13-test-c87cf399"), owner_references: Some([OwnerReference { api_version: "trusted-execution-clusters.io/v1alpha1", block_owner_deletion: Some(true), controller: Some(true), kind: "TrustedExecutionCluster", name: "trusted-execution-cluster", uid: "09a280f6-1255-4234-a07e-b089169a9789" }]), resource_version: Some("47611"), self_link: None, uid: Some("a618f89e-8862-4eb2-bcb7-4f9bc1f92fed") }, spec: ApprovedImageSpec { image: "quay.io/trusted-execution-clusters/fedora-coreos@sha256:6997f51fd27d1be1b5fc2e6cc3ebf16c17eb94d819b5d44ea8d6cf5f826ee773" }, status: Some(ApprovedImageStatus { conditions: Some([Condition { last_transition_time: Time(2026-07-06T16:06:24Z), message: "", observed_generation: Some(1), reason: "ImageCommitted", status: "True", type_: "Committed" }]) }) }
[INFO  operator::reference_values] No TrustedExecutionCluster found, skipping disallow_image for coreos
INFO: test_vm_reboot_delete_machine: Deleting TrustedExecutionCluster: trusted-execution-cluster
INFO: test_vm_reboot_delete_machine: TrustedExecutionCluster trusted-execution-cluster has been deleted
Error: Resources were left behind after 180s, last error was: Resource still present: ApprovedImage { metadata: ObjectMeta { annotations: Some({"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"trusted-execution-clusters.io/v1alpha1\",\"kind\":\"ApprovedImage\",\"metadata\":{\"annotations\":{},\"name\":\"coreos\",\"namespace\":\"ci-79393-42ef8b13-test-c87cf399\"},\"spec\":{\"image\":\"quay.io/trusted-execution-clusters/fedora-coreos@sha256:6997f51fd27d1be1b5fc2e6cc3ebf16c17eb94d819b5d44ea8d6cf5f826ee773\"}}\n"}), creation_timestamp: Some(Time(2026-07-06T16:06:22Z)), deletion_grace_period_seconds: Some(0), deletion_timestamp: Some(Time(2026-07-06T16:36:07Z)), finalizers: Some(["finalizer.approved-image.trusted-execution-clusters.io"]), generate_name: None, generation: Some(2), labels: None, managed_fields: Some([ManagedFieldsEntry { api_version: Some("trusted-execution-clusters.io/v1alpha1"), fields_type: Some("FieldsV1"), fields_v1: Some(FieldsV1(Object {"f:metadata": Object {"f:annotations": Object {".": Object {}, "f:kubectl.kubernetes.io/last-applied-configuration": Object {}}}, "f:spec": Object {".": Object {}, "f:image": Object {}}})), manager: Some("kubectl-client-side-apply"), operation: Some("Update"), subresource: None, time: Some(Time(2026-07-06T16:06:22Z)) }, ManagedFieldsEntry { api_version: Some("trusted-execution-clusters.io/v1alpha1"), fields_type: Some("FieldsV1"), fields_v1: Some(FieldsV1(Object {"f:metadata": Object {"f:finalizers": Object {".": Object {}, "v:\"finalizer.approved-image.trusted-execution-clusters.io\"": Object {}}, "f:ownerReferences": Object {".": Object {}, "k:{\"uid\":\"09a280f6-1255-4234-a07e-b089169a9789\"}": Object {}}}})), manager: Some("unknown"), operation: Some("Update"), subresource: None, time: Some(Time(2026-07-06T16:06:23Z)) }, ManagedFieldsEntry { api_version: Some("trusted-execution-clusters.io/v1alpha1"), fields_type: Some("FieldsV1"), fields_v1: Some(FieldsV1(Object {"f:status": Object {".": Object {}, "f:conditions": Object {".": Object {}, "k:{\"type\":\"Committed\"}": Object {".": Object {}, "f:lastTransitionTime": Object {}, "f:message": Object {}, "f:observedGeneration": Object {}, "f:reason": Object {}, "f:status": Object {}, "f:type": Object {}}}}})), manager: Some("unknown"), operation: Some("Update"), subresource: Some("status"), time: Some(Time(2026-07-06T16:06:24Z)) }]), name: Some("coreos"), namespace: Some("ci-79393-42ef8b13-test-c87cf399"), owner_references: Some([OwnerReference { api_version: "trusted-execution-clusters.io/v1alpha1", block_owner_deletion: Some(true), controller: Some(true), kind: "TrustedExecutionCluster", name: "trusted-execution-cluster", uid: "09a280f6-1255-4234-a07e-b089169a9789" }]), resource_version: Some("47611"), self_link: None, uid: Some("a618f89e-8862-4eb2-bcb7-4f9bc1f92fed") }, spec: ApprovedImageSpec { image: "quay.io/trusted-execution-clusters/fedora-coreos@sha256:6997f51fd27d1be1b5fc2e6cc3ebf16c17eb94d819b5d44ea8d6cf5f826ee773" }, status: Some(ApprovedImageStatus { conditions: Some([Condition { last_transition_time: Time(2026-07-06T16:06:24Z), message: "", observed_generation: Some(1), reason: "ImageCommitted", status: "True", type_: "Committed" }]) }) }
test test_vm_reboot_delete_machine ... FAILED

but I understand your concern. I'm considering re-running without this patchset, but with timestamps (hello #227) for more definite proof of what's happening.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants