podman-desktop icon indicating copy to clipboard operation
podman-desktop copied to clipboard

feat(kind): add dynamic availability check for cluster creation

Open vzhukovs opened this issue 1 month ago • 9 comments

What does this PR do?

Adds dynamic availability checking for Kubernetes provider connection creation. The Kind extension now checks for running container providers and disables the "Create Kind Cluster" button when prerequisites are not met, showing a contextual error message to the user.

The implementation leverages provider status management and connection auditing. The Kind extension monitors container connection lifecycle events (onDidUpdateContainerConnection, onDidRegisterContainerConnection, onDidUnregisterContainerConnection) to dynamically update its provider status and warnings. The UI layer reacts to provider status changes, disabling creation buttons and performing real-time connection parameter audits to surface prerequisite errors before the user initiates creation.

Screenshot / video of UI

  • Disable Create new ... button if Podman machine is not running
  • Disable create new Kind cluster form, when Podman machine is stopped
  • Enable Create new ... button if Podman machine is running

What issues does this PR fix or reference?

fixes #14145

How to test this PR?

  1. Start Podman Desktop without any running container providers or stop the Podman machine
  2. Navigate to Kind section
  3. Verify "Create new ..." button is disabled with appropriate error message
  4. Start a container provider (e.g., Podman machine)
  5. Verify button becomes enabled
  • [x] Tests are covering the bug fix or the new feature

vzhukovs avatar Nov 06 '25 12:11 vzhukovs

📝 Walkthrough

Walkthrough

Derives Kind provider status from container connections, updates provider state on container lifecycle events, adds provider-availability checks to cluster creation audits, triggers re-audits when provider status changes, and disables "Create" when Kubernetes provider is not ready.

Changes

Cohort / File(s) Change Summary
Kind provider state & tests
extensions/kind/src/extension.ts,
extensions/kind/src/extension.spec.ts
Added updateKindProviderState() to compute provider status from getContainerConnections(); call it on activation and on container register/unregister/update events; extended tests and mocks (added updateStatus(), updateWarnings(), getContainerConnections()) and new "Container provider availability checks" suite.
Create-cluster validation
extensions/kind/src/create-cluster.ts,
extensions/kind/src/create-cluster.spec.ts
Added pre-checks in connectionAuditor to ensure provider connections exist and are running (Linux vs non-Linux messages); early returns on unavailability/non-running; memory check adjusted to emit info instead of error when <6GB; new parameterized tests for provider-not-installed and not-running cases.
Preferences re-audit flow & tests
packages/renderer/src/lib/preferences/PreferencesConnectionCreationOrEditRendering.svelte,
packages/renderer/src/lib/preferences/PreferencesConnectionCreationOrEditRendering.spec.ts
Introduced reactive effect to re-audit when provider status changes, with flags initialLoadComplete and providerInfosInitialized; added buildAuditData and updateAuditState; extensive tests validating re-audit triggers, skips, and outcomes.
Provider action button behavior & tests
packages/renderer/src/lib/preferences/ProviderActionButtons.svelte,
packages/renderer/src/lib/preferences/PreferencesResourcesRendering.spec.ts
Disable "Create New" for Kubernetes providers unless status is 'ready'; derive disabledReason from warnings/status; updated tooltip behavior; added tests covering Kubernetes disabled-state scenarios.
Docs formatting
MAINTAINERS.md
Reformatted Markdown table for alignment only; no behavioral changes.

Sequence Diagram(s)

sequenceDiagram
    participant Conn as Container Connection (provider backends)
    participant Ext as Kind Extension
    participant Prov as Provider API (UI state)
    participant Pref as Preferences Rendering
    participant Btn as Action Buttons

    Conn->>Ext: onDidRegisterContainerConnection / onDidUnregister / onDidUpdate
    activate Ext
    Ext->>Ext: updateKindProviderState() — call getContainerConnections()
    Ext->>Prov: updateStatus(status)
    Ext->>Prov: updateWarnings()
    deactivate Ext

    Prov->>Pref: provider.status changed (event)
    activate Pref
    Pref->>Pref: skip initialLoad if needed
    Pref->>Pref: buildAuditData() and call auditConnectionParameters()
    Pref->>Pref: updateAuditState(result)
    deactivate Pref

    Pref->>Btn: emit provider status + audit result
    activate Btn
    Btn->>Btn: derive isDisabled = kubernetesCreation && status !== 'ready'
    Btn->>Btn: set disabledReason / tooltip
    Btn-->>User: button enabled/disabled reflects provider availability
    deactivate Btn

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas to pay attention:
    • updateKindProviderState() correctness: status derivation, platform-specific warnings, and event subscription lifecycles (onDidRegister/Unregister/Update).
    • Mocks and tests in extensions/kind/src/extension.spec.ts: ensure new mock methods (updateStatus, updateWarnings, getContainerConnections) reflect runtime behavior and avoid flakiness.
    • connectionAuditor early-return logic in create-cluster.ts: message wording (Linux vs non-Linux), placement of memory check, and preservation of subsequent validations.
    • Reactive re-audit effect in PreferencesConnectionCreationOrEditRendering.svelte: guard conditions (initialLoadComplete, providerInfosInitialized, operation-in-progress) to prevent spurious audits or loops.
    • Button-disable logic in ProviderActionButtons.svelte: tooltip/disabledReason derivation and interaction with existing provider display/name logic.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(kind): add dynamic availability check for cluster creation' clearly and concisely summarizes the main change - adding availability checking for Kind cluster creation.
Description check ✅ Passed The description is directly related to the changeset, explaining dynamic availability checking, provider monitoring, and UI state management for the Kind cluster creation feature.
Linked Issues check ✅ Passed The PR directly addresses issue #14145 by disabling the 'Create Kind Cluster' button when prerequisites (running container providers) are not met, implementing dynamic status management and connection auditing.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing dynamic availability checking for Kind cluster creation, including test additions, provider state management, UI reactivity, and connection auditing logic.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07ac65c9ab5d22b77a4955e237f877129eb09670 and dd963dd50ce7117d00b064e1152bcef22c165929.

📒 Files selected for processing (1)
  • extensions/kind/src/extension.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • extensions/kind/src/extension.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: unit tests / ubuntu-24.04
  • GitHub Check: k8s sanity e2e tests
  • GitHub Check: unit tests / macos-15
  • GitHub Check: smoke e2e tests (production)
  • GitHub Check: Windows
  • GitHub Check: Linux
  • GitHub Check: unit tests / windows-2025
  • GitHub Check: smoke e2e tests (development)
  • GitHub Check: linter, formatters
  • GitHub Check: windows sanity check e2e tests
  • GitHub Check: macOS
  • GitHub Check: typecheck

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.

coderabbitai[bot] avatar Nov 06 '25 12:11 coderabbitai[bot]

Codecov Report

:x: Patch coverage is 98.36066% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...r/src/lib/preferences/ProviderActionButtons.svelte 83.33% 1 Missing :warning:

:loudspeaker: Thoughts on this report? Let us know!

codecov[bot] avatar Nov 06 '25 12:11 codecov[bot]

Looking at the packages/extension-api/src/extension-api.d.ts changes, I am thinking we should try to reuse existing check logic and interfaces that we have for provider install, let me explain

When you want to register an install logic for a given provider, you use the following method in the extension-api

https://github.com/podman-desktop/podman-desktop/blob/4093f43bad41ec3dbf932ee304e680cb22fa78c0/packages/extension-api/src/extension-api.d.ts#L696-L697

Similarly, when you want to register a KubernetesProviderConnectionFactory, you call

https://github.com/podman-desktop/podman-desktop/blob/4093f43bad41ec3dbf932ee304e680cb22fa78c0/packages/extension-api/src/extension-api.d.ts#L682-L685

Comparing those two functions arguments, we compare ProviderInstallation & KubernetesProviderConnectionFactory

Today (main branch) the KubernetesProviderConnectionFactory interface only have a create method

https://github.com/podman-desktop/podman-desktop/blob/4093f43bad41ec3dbf932ee304e680cb22fa78c0/packages/extension-api/src/extension-api.d.ts#L556-L559

Therefore, let's take a look at the ProviderInstallation

https://github.com/podman-desktop/podman-desktop/blob/4093f43bad41ec3dbf932ee304e680cb22fa78c0/packages/extension-api/src/extension-api.d.ts#L610-L614

It has an optional method called preflightChecks, which return an array of InstallCheck

https://github.com/podman-desktop/podman-desktop/blob/4093f43bad41ec3dbf932ee304e680cb22fa78c0/packages/extension-api/src/extension-api.d.ts#L604-L608

To maximise consistency, we should create an interface called Check and do something like

  export interface Check {
    title: string;
    execute(): Promise<CheckResult>;
    init?(): Promise<void>;
  }
  
  export type InstallCheck = Check;
  export type CreateCheck = Check;

We want to reuse the interface of the InstallCheck, but the naming would not match the Create logic we want for the kubernetes, so we might extract it into a Check interface, update the InstallCheck interface to be a type equalling the Check interface for backward compatibility and create a new CreateCheck to use in the preflightChecks of the KubernetesProviderConnectionFactory

At the end the KubernetesProviderConnectionFactory would look like

  export interface KubernetesProviderConnectionFactory extends ProviderConnectionFactory {
    preflightChecks?(): CreateCheck[];
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    create?(params: { [key: string]: any }, logger?: Logger, token?: CancellationToken): Promise<void>;
  }

Since this is a extension-api change, cc @benoitf

I choose CreateCheck but we could have FactoryCheck or something similar, but the idea would be to reuse existing interfaces and keep consistency

Yeah, took a closer look on your proposal and it make sense, but this require to rework the following PR. cc @benoitf are we okay with the proposal from @axel7083 ?

vzhukovs avatar Nov 07 '25 13:11 vzhukovs

As the factory returns a disposable, I'm wondering if the extension should monitor the number of container connection opened and if it reaches 0, it will un register the factory so that we cannot simply create such a resource then

jeffmaury avatar Nov 12 '25 16:11 jeffmaury

As the factory returns a disposable, I'm wondering if the extension should monitor the number of container connection opened and if it reaches 0, it will un register the factory so that we cannot simply create such a resource then

Pinging @benoitf for feedback

jeffmaury avatar Nov 13 '25 09:11 jeffmaury

The one mandatory think, that we need to take into account is that we need a reactivity on the UI and track/check that there are some modifications in state, whatever it will be a podman/kubernetes etc. If we do such checks (periodic) on the backend side, then these checks should be extremely light to execute.

vzhukovs avatar Nov 13 '25 10:11 vzhukovs

@benoitf I've updated the description of the current PR and it's ready to be reviewed again cc @jeffmaury @simonrey1 @axel7083

vzhukovs avatar Dec 03 '25 11:12 vzhukovs

@benoitf @simonrey1 Would you mind having another look at this?

jiridostal avatar Dec 15 '25 09:12 jiridostal

@benoitf @simonrey1 Would you mind having another look at this?

Yes thanks for the update.

I added an answer to the comment here: https://github.com/podman-desktop/podman-desktop/pull/14773#discussion_r2618681354

simonrey1 avatar Dec 15 '25 09:12 simonrey1

Also tested on Win11Pro: after I stopped may Podman machine, the Create new ... button was disabled. After I restarted it, it was enabled.

jeffmaury avatar Dec 22 '25 09:12 jeffmaury

As we are unregistering the factory when there are no container connection, is this required to check at the cluster creation ?

No, it's not required, but to be sure that there are no glitches after stopping connection, would be nice to perform force update

vzhukovs avatar Dec 22 '25 18:12 vzhukovs