Skip to content

Support multicluster resource routing#568

Open
SoWieMarkus wants to merge 24 commits intomainfrom
multicluster-routing
Open

Support multicluster resource routing#568
SoWieMarkus wants to merge 24 commits intomainfrom
multicluster-routing

Conversation

@SoWieMarkus
Copy link
Collaborator

@SoWieMarkus SoWieMarkus commented Mar 11, 2026

Changes

  • Support for multiple remote clusters per gvk
  • Added ResourceRouter interface that can match a gvk to a cluster (for now only hypervisor crd by AZ)
  • Adjusted APIServerOverride config
  • List queries all clusters for the gvk and merges results
  • Get tries all clusters, returns first found (skips NotFound)
  • Create/Update/Delete/Patch: uses ResourceRouter to match the object to the correct cluster via labels
  • DeleteAllOf runs on all clusters for the gvk
  • Status/SubResource writes are routed via ResourceRouter like top-level writes
  • WatchesMulticluster sets up watches on all clusters serving the GVK
  • Every CRD now needs to be configured in which cluster can serve it (including the home cluster)

@SoWieMarkus SoWieMarkus marked this pull request as ready for review March 12, 2026 09:08
Copy link
Member

@PhilippMatthes PhilippMatthes left a comment

Choose a reason for hiding this comment

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

Love this progress! But let's revisit how we want to handle unknown resources.

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds multi-cluster routing primitives and a Hypervisor ResourceRouter; updates multicluster Client, builder, controllers to use WatchesMulticluster with explicit error handling; expands Helm home GVK lists; adds tests, docs, and scripts for three-cluster (home + two remotes) setups.

Changes

Cohort / File(s) Summary
Multicluster core & routing
pkg/multicluster/client.go, pkg/multicluster/builder.go, pkg/multicluster/routers.go
Introduce ResourceRouter interface and HypervisorResourceRouter; change Client to support per-GVK remote lists (map[GVK][]remoteCluster), homeGVKs, ResourceRouters, ClustersForGVK, clusterForWrite; update WatchesMulticluster to return (MulticlusterBuilder, error) and route operations across clusters.
Multicluster tests
pkg/multicluster/client_test.go, pkg/multicluster/builder_test.go, pkg/multicluster/routers_test.go
Add extensive tests and helpers (fake clusters/caches, testRouter, GVK constants) covering multi-cluster lookup, routing, indexing, and Hypervisor router behavior.
Controller wiring (many)
internal/.../*controller.go, internal/knowledge/..., internal/scheduling/...
Replace fluent BuildController(...).WatchesMulticluster(...) chains with an explicit builder (bldr) pattern and per-call error checks; convert many SetupWithManager implementations to use WatchesMulticluster with handler/predicate and propagate errors.
Helm values (home GVKs)
helm/bundles/.../values.yaml
Add cortex.conf.apiservers.home.gvks entries across bundles to declare supported CRDs and core kinds for the home apiserver.
Main wiring
cmd/main.go
Register Hypervisor GVK (kvm.cloud.sap/v1, Kind=Hypervisor) in multicluster.Client.ResourceRouters mapped to HypervisorResourceRouter.
Docs & manifests
docs/guides/multicluster/*
Add/rename kind manifests for additional remotes, add Hypervisor CR manifests per AZ, expand README and add run/cleanup scripts to document and automate three-cluster setup and certificate propagation.
Other small changes
internal/knowledge/datasources/plugins/*, internal/scheduling/.../deschedulings_*, Tiltfile
Migrate various controller setups to WatchesMulticluster with handlers and predicates; update imports; adjust CRD URL in Tiltfile.

Sequence Diagram

sequenceDiagram
    participant Caller as Client
    participant MCR as Multicluster.Client
    participant Router as ResourceRouter
    participant Home as HomeCluster
    participant RemoteA as RemoteClusterA
    participant RemoteB as RemoteClusterB

    Caller->>MCR: Request(op, GVK, obj?)
    MCR->>MCR: ClustersForGVK(GVK)
    alt write operation
        MCR->>Router: Match(obj, remote.labels)
        Router-->>MCR: match true/false
        alt matched remote
            MCR->>RemoteA: Execute write
            RemoteA-->>MCR: result
        else fallback
            MCR->>Home: Execute write (or single remote)
            Home-->>MCR: result
        end
    else read operation
        par Home read
            MCR->>Home: Read
            Home-->>MCR: home results
        and RemoteA read
            MCR->>RemoteA: Read
            RemoteA-->>MCR: remoteA results
        and RemoteB read
            MCR->>RemoteB: Read
            RemoteB-->>MCR: remoteB results
        end
        MCR->>MCR: Aggregate results
    end
    MCR-->>Caller: Return result/status
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

Possibly related PRs

Suggested reviewers

  • auhlig
  • juliusclausnitzer
  • umswmayj
  • mblos

Poem

🐰 I hop through zones and labels bright,

Routers nudge where writes alight,
Builders pause to check each err,
Home and remotes hum together,
A rabbit cheers: clusters take flight.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Support multicluster resource routing' accurately and concisely summarizes the main change: enabling resource routing across multiple clusters.
Description check ✅ Passed The pull request description clearly outlines the key changes including multicluster routing support, ResourceRouter interface, and how various operations handle multiple clusters.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch multicluster-routing
📝 Coding Plan
  • Generate coding plan for human review comments

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

Copy link

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/knowledge/kpis/controller.go (1)

484-488: ⚠️ Potential issue | 🟡 Minor

Fix copy-paste artifacts in comment and variable name.

The comment says "datasources" and the variable is named ds, but this predicate handles KPI objects, not Datasource objects.

📝 Proposed fix
 		&v1alpha1.KPI{},
 		builder.WithPredicates(predicate.NewPredicateFuncs(func(obj client.Object) bool {
-			// Only react to datasources matching the scheduling domain.
-			ds := obj.(*v1alpha1.KPI)
-			return ds.Spec.SchedulingDomain == c.Config.SchedulingDomain
+			// Only react to KPIs matching the scheduling domain.
+			kpi := obj.(*v1alpha1.KPI)
+			return kpi.Spec.SchedulingDomain == c.Config.SchedulingDomain
 		})),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/knowledge/kpis/controller.go` around lines 484 - 488, The predicate
created in builder.WithPredicates using predicate.NewPredicateFuncs refers to
"datasources" and uses variable name ds although it handles KPI objects; update
the inline comment to mention KPIs (e.g., "Only react to KPIs matching the
scheduling domain.") and rename the variable ds to a clearer name like kpi in
the predicate function (obj.(*v1alpha1.KPI)) so the comment and variable reflect
the actual type handled by the predicate.
🧹 Nitpick comments (4)
helm/bundles/cortex-nova/values.yaml (1)

83-103: Consider centralizing shared home.gvks entries to reduce drift across bundles.

This list is now duplicated across multiple bundle values.yaml files. A shared values fragment/template would reduce maintenance risk when GVKs evolve.

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

In `@helm/bundles/cortex-nova/values.yaml` around lines 83 - 103, The shared GVK
list under apiservers.home.gvks is duplicated across bundles; extract this array
into a single shared values fragment (e.g., a common values file or Helm library
chart) and update each bundle's values.yaml to reference/include that fragment
instead of duplicating entries; specifically, move the list currently under
apiservers.home.gvks (the cortex.cloud/*, kvm.cloud.sap/* and v1/Secret entries)
into the shared fragment and replace the duplicated block in each bundle with an
include/reference, ensuring keystoneSecretRef remains untouched.
pkg/multicluster/client.go (2)

181-200: Consider guarding against nil HomeCluster.

When homeGVKs[gvk] is true but HomeCluster is nil (e.g., uninitialized client), the method appends nil to the returned slice. Callers iterating and calling .GetClient() would panic.

♻️ Option: Add nil guard or validation
 	if isHome {
+		if c.HomeCluster == nil {
+			return nil, errors.New("HomeCluster is not initialized")
+		}
 		clusters = append(clusters, c.HomeCluster)
 	}

Alternatively, validate HomeCluster is set during InitFromConf to catch this earlier.

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

In `@pkg/multicluster/client.go` around lines 181 - 200, The ClustersForGVK method
can append a nil HomeCluster when homeGVKs[gvk] is true; update ClustersForGVK
to guard against a nil c.HomeCluster: after computing isHome, if isHome &&
c.HomeCluster == nil return an error (or at minimum do not append nil) so
callers don't receive nil cluster entries; locate and change the logic in
ClustersForGVK (references: ClustersForGVK, HomeCluster, homeGVKs,
remoteClusters, remoteClustersMu) to either validate HomeCluster during
InitFromConf or return an explicit error when a GVK is claimed as home but
HomeCluster is unset.

351-367: Note: Partial failure can leave clusters in inconsistent state.

DeleteAllOf stops on the first cluster error after potentially succeeding on previous clusters. This is a known limitation of distributed operations. Consider documenting this behavior or returning a multi-error aggregate if stricter consistency guarantees are needed in the future.

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

In `@pkg/multicluster/client.go` around lines 351 - 367, The current
Client.DeleteAllOf implementation exits on the first cluster error which can
leave other clusters already mutated; update DeleteAllOf (or add a documented
variant) to collect errors from each cl.GetClient().DeleteAllOf call instead of
returning immediately so callers can see all failures — iterate clusters from
Client.ClustersForGVK, accumulate per-cluster errors (e.g., into a slice and
return as an aggregated error via errors.Join or a multi-error type) and still
attempt DeleteAllOf on all clusters; alternatively add a clear comment on
Client.DeleteAllOf that it stops on first error if you prefer not to change
behavior.
pkg/multicluster/builder_test.go (1)

53-75: Test validates nil HomeCluster edge case rather than typical usage.

The test name suggests verifying that home GVKs return the home cluster, but HomeCluster is never set. This tests that ClustersForGVK returns a slice containing nil when homeGVKs is configured but HomeCluster is uninitialized.

In production, callers iterating over the result would panic calling .GetClient() on nil. Consider either:

  1. Adding a guard in ClustersForGVK to skip appending nil HomeCluster
  2. Renaming this test to clarify it tests the uninitialized edge case
  3. Adding a separate test with a mock HomeCluster to verify typical behavior
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/multicluster/builder_test.go` around lines 53 - 75, The test
TestClient_ClustersForGVK_HomeGVKReturnsHomeCluster currently asserts that a GVK
marked in Client.homeGVKs yields a nil HomeCluster because Client.HomeCluster is
uninitialized; update the implementation of Client.ClustersForGVK to guard
against appending a nil HomeCluster (check c.HomeCluster != nil before
appending) so callers won't receive nil entries, and then add a separate test
that sets Client.HomeCluster to a mock/non-nil remoteCluster to verify the
normal behavior; reference the Client struct fields homeGVKs, HomeCluster and
the method ClustersForGVK when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/multicluster/client_test.go`:
- Around line 1226-1253: The test TestClient_ConcurrentAddRemoteAndRead is flaky
because readers call ClustersForGVK(configMapGVK) before any cluster exists; to
stabilize it, ensure the Client starts with at least one entry for configMapGVK
by pre-populating c.remoteClusters[configMapGVK] = []remoteCluster{{}}
(protected by remoteClustersMu if needed) before spawning reader and writer
goroutines; reference Client, ClustersForGVK, remoteClusters, remoteClustersMu,
and configMapGVK when making this change.

In `@pkg/multicluster/routers.go`:
- Around line 21-25: The Match method in HypervisorResourceRouter uses a value
type assertion obj.(hv1.Hypervisor) which fails when Kubernetes passes a
pointer; update Match to accept pointer types (or both pointer and value) by
asserting obj.(*hv1.Hypervisor) or using a type switch to handle *hv1.Hypervisor
and hv1.Hypervisor, then use the dereferenced value (or the value case) for
subsequent logic so routing works for the client.Object pointer inputs.

---

Outside diff comments:
In `@internal/knowledge/kpis/controller.go`:
- Around line 484-488: The predicate created in builder.WithPredicates using
predicate.NewPredicateFuncs refers to "datasources" and uses variable name ds
although it handles KPI objects; update the inline comment to mention KPIs
(e.g., "Only react to KPIs matching the scheduling domain.") and rename the
variable ds to a clearer name like kpi in the predicate function
(obj.(*v1alpha1.KPI)) so the comment and variable reflect the actual type
handled by the predicate.

---

Nitpick comments:
In `@helm/bundles/cortex-nova/values.yaml`:
- Around line 83-103: The shared GVK list under apiservers.home.gvks is
duplicated across bundles; extract this array into a single shared values
fragment (e.g., a common values file or Helm library chart) and update each
bundle's values.yaml to reference/include that fragment instead of duplicating
entries; specifically, move the list currently under apiservers.home.gvks (the
cortex.cloud/*, kvm.cloud.sap/* and v1/Secret entries) into the shared fragment
and replace the duplicated block in each bundle with an include/reference,
ensuring keystoneSecretRef remains untouched.

In `@pkg/multicluster/builder_test.go`:
- Around line 53-75: The test
TestClient_ClustersForGVK_HomeGVKReturnsHomeCluster currently asserts that a GVK
marked in Client.homeGVKs yields a nil HomeCluster because Client.HomeCluster is
uninitialized; update the implementation of Client.ClustersForGVK to guard
against appending a nil HomeCluster (check c.HomeCluster != nil before
appending) so callers won't receive nil entries, and then add a separate test
that sets Client.HomeCluster to a mock/non-nil remoteCluster to verify the
normal behavior; reference the Client struct fields homeGVKs, HomeCluster and
the method ClustersForGVK when making the change.

In `@pkg/multicluster/client.go`:
- Around line 181-200: The ClustersForGVK method can append a nil HomeCluster
when homeGVKs[gvk] is true; update ClustersForGVK to guard against a nil
c.HomeCluster: after computing isHome, if isHome && c.HomeCluster == nil return
an error (or at minimum do not append nil) so callers don't receive nil cluster
entries; locate and change the logic in ClustersForGVK (references:
ClustersForGVK, HomeCluster, homeGVKs, remoteClusters, remoteClustersMu) to
either validate HomeCluster during InitFromConf or return an explicit error when
a GVK is claimed as home but HomeCluster is unset.
- Around line 351-367: The current Client.DeleteAllOf implementation exits on
the first cluster error which can leave other clusters already mutated; update
DeleteAllOf (or add a documented variant) to collect errors from each
cl.GetClient().DeleteAllOf call instead of returning immediately so callers can
see all failures — iterate clusters from Client.ClustersForGVK, accumulate
per-cluster errors (e.g., into a slice and return as an aggregated error via
errors.Join or a multi-error type) and still attempt DeleteAllOf on all
clusters; alternatively add a clear comment on Client.DeleteAllOf that it stops
on first error if you prefer not to change behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 424be9b7-5587-4274-960b-c65f38badd85

📥 Commits

Reviewing files that changed from the base of the PR and between 03031a8 and 0f75530.

📒 Files selected for processing (20)
  • cmd/main.go
  • helm/bundles/cortex-cinder/values.yaml
  • helm/bundles/cortex-ironcore/values.yaml
  • helm/bundles/cortex-manila/values.yaml
  • helm/bundles/cortex-nova/values.yaml
  • helm/bundles/cortex-pods/values.yaml
  • internal/knowledge/extractor/trigger.go
  • internal/knowledge/kpis/controller.go
  • internal/scheduling/cinder/filter_weigher_pipeline_controller.go
  • internal/scheduling/machines/filter_weigher_pipeline_controller.go
  • internal/scheduling/manila/filter_weigher_pipeline_controller.go
  • internal/scheduling/nova/detector_pipeline_controller.go
  • internal/scheduling/nova/filter_weigher_pipeline_controller.go
  • internal/scheduling/pods/filter_weigher_pipeline_controller.go
  • pkg/multicluster/builder.go
  • pkg/multicluster/builder_test.go
  • pkg/multicluster/client.go
  • pkg/multicluster/client_test.go
  • pkg/multicluster/routers.go
  • pkg/multicluster/routers_test.go

@PhilippMatthes PhilippMatthes self-requested a review March 16, 2026 13:59
Copy link
Member

@PhilippMatthes PhilippMatthes left a comment

Choose a reason for hiding this comment

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

Thanks so much for enduring the pain of fixing all the controllers. You implemented it really well, I just want us to test this really thoroughly before we merge it. See my one commend below.

@PhilippMatthes PhilippMatthes dismissed their stale review March 16, 2026 14:24

Markus has addressed my comments.

@PhilippMatthes
Copy link
Member

I'll support here by adjusting the multicluster guide so we can test this locally.

Copy link

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/guides/multicluster/readme.md`:
- Line 131: Replace the "TODO" at line 131 with a concrete, runnable
verification command that validates the aggregated Hypervisor listing from the
test cluster (kind-cortex-home); specifically instruct to run a cluster-aware
listing (e.g., via kubectl/context switch or the cortex CLI) that targets the
kind-cortex-home context and shows the Hypervisor resources, and include the
expected output pattern or success criteria so readers can confirm aggregation
worked for the Hypervisor objects.
- Around line 94-110: The Helm override mismaps remote AZ hosts and CA files:
change the entry with label az: cortex-remote-az-a to point to host
https://host.docker.internal:8444 and use the remote AZ-A CA
(root-ca-remote-az-a.pem) instead of the home CA, and change the entry with
label az: cortex-remote-az-b to point to host https://host.docker.internal:8445
and use root-ca-remote-az-b.pem; update the two host values and the caCert
heredoc commands accordingly so each label (az: cortex-remote-az-a / az:
cortex-remote-az-b) maps to the correct remote endpoint and CA file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 69f4956f-995b-43bc-993a-0e931ac498d9

📥 Commits

Reviewing files that changed from the base of the PR and between eb4b793 and a1763a5.

📒 Files selected for processing (5)
  • docs/guides/multicluster/cortex-remote-az-a.yaml
  • docs/guides/multicluster/cortex-remote-az-b.yaml
  • docs/guides/multicluster/hypervisors-az-a.yaml
  • docs/guides/multicluster/hypervisors-az-b.yaml
  • docs/guides/multicluster/readme.md

Copy link

@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: 4

🧹 Nitpick comments (1)
internal/knowledge/extractor/controller.go (1)

243-247: Misleading comment: refers to datasources but filters Knowledge resources.

The comment on line 244 says "Only react to datasources matching the operator" but the code filters Knowledge resources by SchedulingDomain. Consider updating the comment to accurately reflect what's being filtered.

📝 Suggested comment fix
 	bldr, err := bldr.WatchesMulticluster(
 		&v1alpha1.Knowledge{},
 		&handler.EnqueueRequestForObject{},
 		predicate.NewPredicateFuncs(func(obj client.Object) bool {
-			// Only react to datasources matching the operator.
+			// Only react to knowledge resources matching the scheduling domain.
 			ds := obj.(*v1alpha1.Knowledge)
 			return ds.Spec.SchedulingDomain == r.Conf.SchedulingDomain
 		}),
 	)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/knowledge/extractor/controller.go` around lines 243 - 247, Update
the misleading comment above the predicate.NewPredicateFuncs filter: it
currently says "Only react to datasources matching the operator" but the
predicate actually casts the client.Object to v1alpha1.Knowledge and checks
ds.Spec.SchedulingDomain == r.Conf.SchedulingDomain; change the comment to
accurately state that the controller only reacts to Knowledge resources whose
SchedulingDomain matches the operator's configured r.Conf.SchedulingDomain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/multicluster/client_test.go`:
- Around line 1226-1261: TestClient_ConcurrentAddRemoteAndRead pre-populates
c.remoteClusters with an empty remoteCluster whose cluster field is nil, which
can lead to nil-pointer panics; change the initial entry from {{}} to an actual
remoteCluster with a real cluster instance (e.g., remoteCluster{cluster:
newFakeCluster(scheme)}) so ClustersForGVK and downstream calls (like
cl.GetClient/GetCache) never receive nil; update the test's remoteClusters
initialization in the TestClient_ConcurrentAddRemoteAndRead setup to use
newFakeCluster(scheme).

In `@pkg/multicluster/client.go`:
- Around line 211-224: In clusterForWrite(), apply the configured home fallback
before evaluating remote routing: check c.homeGVKs[gvk] first and return
c.HomeCluster if true, regardless of whether c.remoteClusters[gvk] exists; only
when homeGVKs does not claim the GVK proceed to inspect remotes and
ResourceRouters (the existing remotes, router lookup via c.ResourceRouters[gvk],
and the single-remote fast path should remain but executed only when home
fallback is not configured).
- Around line 190-235: The error strings in clusterForWrite (and the earlier
similar return) start with capitalized identifiers ("GVK" and "ResourceRouter")
which violates the repo's error-string lint rule; update all fmt.Errorf messages
in this snippet (references: clusterForWrite, c.remoteClusters, c.homeGVKs, and
ResourceRouters) to begin with lowercase wording—e.g., change "GVK %s is not
configured..." -> "gvk %s is not configured...", "no ResourceRouter configured
for GVK %s..." -> "no resource router configured for gvk %s...", and
"ResourceRouter match error for GVK %s: %w" -> "resource router match error for
gvk %s: %w" so all error strings start lowercase and use lowercase identifiers
consistently.
- Around line 208-235: The read path (Get/List) currently loses cluster
provenance which allows a reconcile loop enqueued by WatchesMulticluster +
EnqueueRequestForObject to read from one cluster and then have clusterForWrite
choose a different cluster; modify Get and List to attach source cluster
identity to the returned object or to the reconciliation key (e.g., include
cluster name/ID in the NamespacedName or wrap the returned object with metadata
indicating sourceCluster) so that downstream reconcile requests and
clusterForWrite use that cluster provenance when deciding where to write; update
clusterForWrite error messages in the clusterForWrite function to use lowercase
descriptions ("gvk" and "resource router") in all returned fmt.Errorf strings to
follow Go conventions and keep references to the symbols clusterForWrite, Get,
List, WatchesMulticluster, and EnqueueRequestForObject when making these
changes.

---

Nitpick comments:
In `@internal/knowledge/extractor/controller.go`:
- Around line 243-247: Update the misleading comment above the
predicate.NewPredicateFuncs filter: it currently says "Only react to datasources
matching the operator" but the predicate actually casts the client.Object to
v1alpha1.Knowledge and checks ds.Spec.SchedulingDomain ==
r.Conf.SchedulingDomain; change the comment to accurately state that the
controller only reacts to Knowledge resources whose SchedulingDomain matches the
operator's configured r.Conf.SchedulingDomain.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ef54dc67-d2f7-44f6-ac89-62043ff929ab

📥 Commits

Reviewing files that changed from the base of the PR and between a1763a5 and 11b7dfc.

📒 Files selected for processing (26)
  • cmd/main.go
  • helm/bundles/cortex-cinder/values.yaml
  • helm/bundles/cortex-ironcore/values.yaml
  • helm/bundles/cortex-manila/values.yaml
  • helm/bundles/cortex-nova/values.yaml
  • helm/bundles/cortex-pods/values.yaml
  • internal/knowledge/datasources/plugins/openstack/controller.go
  • internal/knowledge/datasources/plugins/prometheus/controller.go
  • internal/knowledge/extractor/controller.go
  • internal/knowledge/kpis/controller.go
  • internal/scheduling/cinder/filter_weigher_pipeline_controller.go
  • internal/scheduling/explanation/controller.go
  • internal/scheduling/machines/filter_weigher_pipeline_controller.go
  • internal/scheduling/manila/filter_weigher_pipeline_controller.go
  • internal/scheduling/nova/deschedulings_cleanup.go
  • internal/scheduling/nova/deschedulings_executor.go
  • internal/scheduling/nova/detector_pipeline_controller.go
  • internal/scheduling/nova/filter_weigher_pipeline_controller.go
  • internal/scheduling/nova/hypervisor_overcommit_controller.go
  • internal/scheduling/pods/filter_weigher_pipeline_controller.go
  • internal/scheduling/reservations/controller/controller.go
  • pkg/multicluster/builder_test.go
  • pkg/multicluster/client.go
  • pkg/multicluster/client_test.go
  • pkg/multicluster/routers.go
  • pkg/multicluster/routers_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/scheduling/manila/filter_weigher_pipeline_controller.go
  • helm/bundles/cortex-cinder/values.yaml
  • internal/scheduling/pods/filter_weigher_pipeline_controller.go
  • helm/bundles/cortex-nova/values.yaml

Copy link

@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: 3

♻️ Duplicate comments (2)
docs/guides/multicluster/readme.md (2)

111-112: ⚠️ Potential issue | 🟠 Major

Fix the CA certificate for the az-a remote.

The caCert for cortex-remote-az-a incorrectly uses the home cluster's CA certificate (root-ca-home.pem). It should use the az-a remote cluster's CA certificate (root-ca-remote-az-a.pem) to properly authenticate against the cortex-remote-az-a API server.

,

Suggested fix
         caCert: |
-$(cat /tmp/root-ca-home.pem | sed 's/^/          /')
+$(cat /tmp/root-ca-remote-az-a.pem | sed 's/^/          /')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/guides/multicluster/readme.md` around lines 111 - 112, The caCert for
the cortex-remote-az-a remote is incorrectly sourcing root-ca-home.pem; update
the caCert entry that currently injects $(cat /tmp/root-ca-home.pem | sed 's/^/ 
/') to instead read from the az-a remote CA file (root-ca-remote-az-a.pem) so
the cortex-remote-az-a cluster uses its own CA; locate the caCert block for the
cortex-remote-az-a remote in the multicluster README and replace the referenced
PEM filename accordingly.

142-142: ⚠️ Potential issue | 🟡 Minor

Replace the TODO with a concrete verification command.

The guide should be end-to-end executable. Consider adding a verification command that lists Hypervisor resources from the home cluster to confirm multi-cluster aggregation works.

,

Example verification command
-TODO
+kubectl --context kind-cortex-home get hypervisors -A
+# Expected: Hypervisors from both az-a and az-b clusters should be listed
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/guides/multicluster/readme.md` at line 142, Replace the "TODO" with a
concrete, runnable verification step that lists Hypervisor resources from the
home cluster to prove multi-cluster aggregation works: add a specific command
that targets the home-cluster context (or kubeconfig) and lists Hypervisor
resources (e.g., cluster-wide or in the relevant namespace) and include a short
note about the expected successful output so readers can verify aggregation;
update the readme line containing "TODO" to this command and expected result,
referencing "Hypervisor" and "home cluster" so it's clear what to run and what
to observe.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/guides/multicluster/run.sh`:
- Around line 59-60: The caCert block for the cortex-remote-az-a remote
currently injects the home cluster CA by running cat /tmp/root-ca-home.pem;
update the caCert here to read the remote cluster's CA file instead (use
/tmp/root-ca-remote-az-a.pem) so the cortex-remote-az-a entry authenticates
against the az-a API server on 8444, preserving the existing sed indentation
pipeline (i.e., replace the reference to root-ca-home.pem with
root-ca-remote-az-a.pem in the caCert command).
- Line 38: Update the echo message to match the actual filenames used by the
script: replace the referenced names root-ca-az-a.pem and root-ca-az-b.pem in
the echo statement with root-ca-remote-az-a.pem and root-ca-remote-az-b.pem so
the printed message accurately reflects the files the script writes.
- Around line 11-12: Remove or complete the orphan echo statement that prints
"Installing hypervisor crd in home cluster": either delete that echo (to avoid a
misleading message) or move/replace it with the actual CRD installation
command(s) used later (the kubectl apply of the hypervisor CRD manifest),
ensuring the echo appears immediately before the real installation steps so the
log message matches the action.

---

Duplicate comments:
In `@docs/guides/multicluster/readme.md`:
- Around line 111-112: The caCert for the cortex-remote-az-a remote is
incorrectly sourcing root-ca-home.pem; update the caCert entry that currently
injects $(cat /tmp/root-ca-home.pem | sed 's/^/          /') to instead read
from the az-a remote CA file (root-ca-remote-az-a.pem) so the cortex-remote-az-a
cluster uses its own CA; locate the caCert block for the cortex-remote-az-a
remote in the multicluster README and replace the referenced PEM filename
accordingly.
- Line 142: Replace the "TODO" with a concrete, runnable verification step that
lists Hypervisor resources from the home cluster to prove multi-cluster
aggregation works: add a specific command that targets the home-cluster context
(or kubeconfig) and lists Hypervisor resources (e.g., cluster-wide or in the
relevant namespace) and include a short note about the expected successful
output so readers can verify aggregation; update the readme line containing
"TODO" to this command and expected result, referencing "Hypervisor" and "home
cluster" so it's clear what to run and what to observe.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9ca9d2c2-fd06-497a-a0fc-4706477f4659

📥 Commits

Reviewing files that changed from the base of the PR and between 11b7dfc and fd4aef5.

📒 Files selected for processing (4)
  • Tiltfile
  • docs/guides/multicluster/cleanup.sh
  • docs/guides/multicluster/readme.md
  • docs/guides/multicluster/run.sh

@PhilippMatthes
Copy link
Member

Markus and I discussed offline that we want to error out List and Get calls when there are ambiguous namespaced names across different clusters. Get should fail if multiple clusters report the demanded resource, and List should fail and report the duplicated items in the error message. We accept this as a limitation for now, and revisit later when our assumption is no longer valid. The assumption here is that all decisions, hypervisors, and reservations have unique names across all clusters.

@SoWieMarkus SoWieMarkus force-pushed the multicluster-routing branch from c3239d5 to 34fe33d Compare March 18, 2026 09:15
@github-actions
Copy link
Contributor

Test Coverage Report

Test Coverage 📊: 68.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/monitor.go:21:							NewMonitor				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/monitor.go:39:							Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/monitor.go:45:							Collect					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_api.go:37:			NewCinderAPI				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_api.go:45:			Init					81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_api.go:68:			GetAllStoragePools			73.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_sync.go:27:			Init					83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_sync.go:40:			Sync					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_sync.go:51:			SyncAllStoragePools			53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_types.go:46:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_types.go:49:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_types.go:52:			UnmarshalJSON				93.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_types.go:131:			MarshalJSON				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/controller.go:60:				Reconcile				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/controller.go:239:				SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_api.go:35:			NewIdentityAPI				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_api.go:39:			Init					80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_api.go:59:			GetAllDomains				66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_api.go:83:			GetAllProjects				72.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_sync.go:26:			Init					85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_sync.go:41:			Sync					83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_sync.go:54:			SyncDomains				53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_sync.go:74:			SyncProjects				53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_types.go:16:		TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_types.go:19:		Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_types.go:47:		TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_types.go:50:		Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_api.go:45:			NewLimesAPI				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_api.go:50:			Init					81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_api.go:74:			GetAllCommitments			90.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_api.go:124:			getCommitments				86.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_sync.go:28:			Init					83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_sync.go:41:			Sync					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_sync.go:52:			SyncCommitments				63.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_types.go:69:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_types.go:72:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_api.go:41:			NewManilaAPI				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_api.go:46:			Init					81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_api.go:69:			GetAllStoragePools			75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_sync.go:28:			Init					83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_sync.go:41:			Sync					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_sync.go:52:			SyncAllStoragePools			53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_types.go:47:			UnmarshalJSON				87.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_types.go:137:			MarshalJSON				72.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_types.go:234:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_types.go:237:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:54:				NewNovaAPI				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:59:				Init					81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:85:				GetAllServers				69.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:145:				GetDeletedServers			69.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:200:				GetAllHypervisors			69.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:254:				GetAllFlavors				68.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:291:				GetAllMigrations			69.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:344:				GetAllAggregates			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:29:				Init					90.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:53:				Sync					50.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:75:				SyncAllServers				57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:98:				SyncDeletedServers			64.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:128:			SyncAllHypervisors			57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:152:			SyncAllFlavors				57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:174:			SyncAllMigrations			57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:196:			SyncAllAggregates			57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:36:			UnmarshalJSON				77.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:59:			MarshalJSON				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:79:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:82:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:119:			UnmarshalJSON				77.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:142:			MarshalJSON				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:162:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:165:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:198:			UnmarshalJSON				80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:234:			MarshalJSON				85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:266:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:269:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:289:			UnmarshalJSON				54.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:312:			MarshalJSON				55.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:333:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:336:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:360:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:363:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:384:			TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:387:			Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:48:		NewPlacementAPI				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:53:		Init					81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:77:		GetAllResourceProviders			66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:105:		GetAllTraits				90.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:155:		getTraits				90.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:179:		GetAllInventoryUsages			71.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:229:		getInventoryUsages			77.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:28:		Init					62.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:46:		Sync					71.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:62:		SyncResourceProviders			53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:83:		SyncTraits				57.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:112:		SyncInventoryUsages			57.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:17:		TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:20:		Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:31:		TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:34:		Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:74:		TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:77:		Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/supported_syncers.go:22:			getSupportedSyncer			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/controller.go:51:				Reconcile				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/controller.go:201:				SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:32:					newTypedSyncer				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:100:					fetch					79.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:205:					getSyncWindowStart			81.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:245:					sync					68.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:295:					Sync					70.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/triggers.go:7:				TriggerMetricAliasSynced		0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/triggers.go:12:				TriggerMetricTypeSynced			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:42:					TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:43:					Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:44:					GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:45:					GetTimestamp				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:46:					GetValue				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:47:					With					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:90:					TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:91:					Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:92:					GetName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:93:					GetTimestamp				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:94:					GetValue				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:95:					With					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:145:				TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:146:				Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:147:				GetName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:148:				GetTimestamp				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:149:				GetValue				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:150:				With					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:170:				TableName				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:171:				Indexes					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:172:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:173:				GetTimestamp				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:174:				GetValue				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:175:				With					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:211:				TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:212:				Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:213:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:214:				GetTimestamp				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:215:				GetValue				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:216:				With					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:242:				TableName				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:243:				Indexes					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:244:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:245:				GetTimestamp				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:246:				GetValue				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:247:				With					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:282:				TableName				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:285:				Indexes					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:286:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:287:				GetTimestamp				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:288:				GetValue				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:289:				With					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:50:								FromSecretRef				6.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:131:								SelectTimed				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:140:								CreateTable				70.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:157:								AddTable				66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:168:								TableExists				58.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:197:								ReplaceAll				62.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:224:								BulkInsert				86.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/monitor.go:21:								newMonitor				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/monitor.go:63:								Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/monitor.go:73:								Collect					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/testing/containers/postgres.go:21:					GetPort					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/testing/containers/postgres.go:25:					Init					70.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/testing/containers/postgres.go:69:					Close					50.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/testing/env.go:24:							SetupDBEnv				59.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/controller.go:46:							Reconcile				54.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/controller.go:237:						SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:26:							NewMonitor				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:44:							Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:50:							Collect					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:69:							Init					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:78:							monitorFeatureExtractor			100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:97:							Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/base.go:28:						Init					87.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/base.go:45:						ExtractSQL				83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/base.go:58:						Extracted				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/flavor_groups.go:67:				Extract					77.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_az.go:31:					Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_capabilities.go:35:				Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_details.go:59:				Extract					87.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_pinned_projects.go:45:			Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_utilization.go:47:				Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/libvirt_domain_cpu_steal_pct.go:35:		Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vm_host_residency.go:53:				Extract					85.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vm_life_span.go:52:				extractHistogramBuckets			89.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vm_life_span.go:97:				Extract					88.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vrops_hostsystem_contention_long_term.go:39:	Extract					82.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vrops_hostsystem_contention_short_term.go:39:	Extract					82.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vrops_hostsystem_resolver.go:33:			Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vrops_project_noisiness.go:33:			Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/storage/storage_pool_cpu_usage.go:35:			Extract					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:42:							Reconcile				77.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:95:							findDependentKnowledge			96.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:142:							triggerKnowledgeReconciliation		100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:175:							enqueueKnowledgeReconciliation		81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:201:							getResourceType				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:213:							mapDatasourceToKnowledge		100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:234:							mapKnowledgeToKnowledge			100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:255:							SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:53:							Reconcile				42.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:107:							InitAllKPIs				83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:147:							getJointDB				27.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:185:							handleKPIChange				52.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:310:							handleDatasourceChange			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:335:							handleDatasourceCreated			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:345:							handleDatasourceUpdated			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:363:							handleDatasourceDeleted			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:375:							handleKnowledgeChange			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:400:							handleKnowledgeCreated			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:410:							handleKnowledgeUpdated			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:428:							handleKnowledgeDeleted			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:438:							SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/logger.go:21:								Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/logger.go:26:								Collect					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/logger.go:32:								Init					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/logger.go:37:								GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/base.go:24:							Init					80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/flavor_running_vms.go:32:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/flavor_running_vms.go:36:				Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/flavor_running_vms.go:54:				Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/flavor_running_vms.go:58:				Collect					71.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_contention.go:28:					GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_contention.go:32:					Init					80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_contention.go:49:					Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_contention.go:54:					Collect					82.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_running_vms.go:42:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_running_vms.go:46:				Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_running_vms.go:69:				Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_running_vms.go:73:				Collect					66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/project_noisiness.go:27:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/project_noisiness.go:31:				Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/project_noisiness.go:43:				Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/project_noisiness.go:47:				Collect					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:24:				getBuildingBlock			75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:42:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:46:				Init					87.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:138:				Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:146:				Collect					90.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:223:				exportCapacityMetricKVM			100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_vmware.go:29:			GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_vmware.go:33:			Init					80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_vmware.go:75:			Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_vmware.go:80:			Collect					67.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_vmware.go:153:			exportCapacityMetricVMware		92.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:30:					GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:34:					Init					85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:81:					Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:89:					convertLimesMemory			100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:106:					Collect					89.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:29:					GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:33:					Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:46:					Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:50:					Collect					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:57:					collectVMBuckets			71.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_migration_statistics.go:28:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_migration_statistics.go:32:				Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_migration_statistics.go:45:				Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_migration_statistics.go:49:				Collect					69.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/datasource_state.go:32:				GetName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/datasource_state.go:35:				Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/datasource_state.go:49:				Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/datasource_state.go:52:				Collect					92.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/decision_state.go:32:				GetName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/decision_state.go:35:				Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/decision_state.go:49:				Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/decision_state.go:52:				Collect					94.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/knowledge_state.go:32:				GetName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/knowledge_state.go:35:				Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/knowledge_state.go:49:				Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/knowledge_state.go:52:				Collect					85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/kpi_state.go:32:					GetName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/kpi_state.go:35:					Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/kpi_state.go:49:					Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/kpi_state.go:52:					Collect					92.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/pipeline_state.go:32:				GetName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/pipeline_state.go:35:				Init					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/pipeline_state.go:49:				Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/pipeline_state.go:52:				Collect					92.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/storage/storage_pool_cpu.go:28:				GetName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/storage/storage_pool_cpu.go:32:				Init					80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/storage/storage_pool_cpu.go:49:				Describe				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/storage/storage_pool_cpu.go:54:				Collect					82.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/math/histogram.go:7:							Histogram				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/decisions_cleanup.go:30:						DecisionsCleanup			76.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/e2e_checks.go:21:							RunChecks				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/e2e_checks.go:26:							checkCinderSchedulerReturnsValidHosts	0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:42:					NewAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:50:					Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:57:					canRunScheduler				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:80:					inferPipelineName			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:90:					CinderExternalScheduler			68.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:48:				PipelineType				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:53:				Reconcile				83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:73:				ProcessNewDecisionFromAPI		88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:112:				process					80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:142:				InitPipeline				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:155:				SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/pipeline_webhook.go:15:						NewPipelineWebhook			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/controller.go:47:						shouldReconcileDecision			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/controller.go:65:						Reconcile				81.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/controller.go:85:						reconcileHistory			80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/controller.go:147:						reconcileExplanation			64.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/controller.go:171:						StartupCallback				77.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/controller.go:194:						SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:28:						NewExplainer				75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:41:						Explain					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:46:						getResourceType				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:62:						calculateScoreGap			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:80:						fetchDecisionChain			92.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:120:						buildHostSegments			95.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:171:						detectLoop				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:183:						findWinner				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:212:						calculateScoresFromSteps		93.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:257:						calculateScoresWithoutStep		83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:271:						findCriticalSteps			78.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:315:						calculateStepImpacts			97.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:397:						buildContextData			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:419:						buildHistoryData			94.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:461:						buildWinnerData				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:496:						buildInputData				95.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:548:						buildCriticalStepsData			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:566:						buildDeletedHostsData			90.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:616:						buildChainData				86.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/explainer.go:655:						ExplainWithTemplates			87.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/templates.go:18:						NewTemplateManager			81.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/templates.go:59:						RenderExplanation			80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/explanation/templates.go:68:						formatTemplateDuration			90.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/activation.go:12:							NoEffect				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/activation.go:15:							Norm					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/activation.go:21:							Apply					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:22:							NewSchedulerMonitor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:32:							Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:36:							Collect					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:50:							Callback				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:56:							Respond					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector.go:53:							Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector.go:64:							Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector.go:75:							CheckKnowledges				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:26:						NewDetectorPipelineMonitor		100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:46:						SubPipeline				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:52:						Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:58:						Collect					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:76:						monitorDetector				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:99:						Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:107:						Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:112:						Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_pipeline.go:33:						Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_pipeline.go:63:						Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_pipeline.go:98:						Combine					97.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_step_opts.go:15:						Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter.go:31:								Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_monitor.go:23:							monitorFilter				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_monitor.go:36:							Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_monitor.go:41:							Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_monitor.go:46:							Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_validation.go:22:						Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_validation.go:28:						Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_validation.go:33:						validateFilter				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_validation.go:38:						Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:45:						InitNewFilterWeigherPipeline		86.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:138:					runFilters				73.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:166:					runWeighers				81.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:206:					normalizeInputWeights			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:215:					applyWeights				80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:251:					sortHostsByWeights			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:261:					Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:36:					NewPipelineMonitor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:90:					SubPipeline				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:97:					observePipelineResult			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:118:				Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:130:				Collect					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step.go:48:					Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step.go:63:					Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step.go:75:					IncludeAllHostsFromRequest		100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step.go:85:					PrepareStats				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step_monitor.go:42:				monitorStep				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step_monitor.go:65:				RunWrapped				48.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step_monitor.go:215:				impact					94.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step_opts.go:15:				Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:36:						InitAllPipelines			93.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:61:						handlePipelineChange			77.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:174:						HandlePipelineCreated			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:188:						HandlePipelineUpdated			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:201:						HandlePipelineDeleted			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:213:						handleKnowledgeChange			71.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:246:						HandleKnowledgeCreated			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:259:						HandleKnowledgeUpdated			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:281:						HandleKnowledgeDeleted			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:38:						ValidateCreate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:47:						ValidateUpdate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:56:						ValidateDelete				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:65:						validatePipeline			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:149:						SetupWebhookWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/scaling.go:7:								clamp					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/scaling.go:22:								MinMaxScale				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher.go:35:								Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher.go:40:								Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher.go:45:								CheckKnowledges				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_monitor.go:23:							monitorWeigher				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_monitor.go:36:							Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_monitor.go:41:							Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_monitor.go:46:							Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_validation.go:22:						Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_validation.go:28:						Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_validation.go:33:						validateWeigher				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_validation.go:38:						Run					81.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:52:				PipelineType				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:56:				Reconcile				83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:76:				ProcessNewMachine			89.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:133:			process					70.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:184:			InitPipeline				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:197:			handleMachine				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:237:			SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/pipeline_webhook.go:15:						NewPipelineWebhook			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/plugins/filters/filter_noop.go:21:				Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/plugins/filters/filter_noop.go:25:				Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/plugins/filters/filter_noop.go:34:				Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/plugins/filters/filter_noop.go:44:				init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/decisions_cleanup.go:32:						DecisionsCleanup			77.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/e2e_checks.go:34:							RunChecks				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/e2e_checks.go:39:							checkManilaSchedulerReturnsValidHosts	0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:42:					NewAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:50:					Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:57:					canRunScheduler				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:80:					inferPipelineName			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:90:					ManilaExternalScheduler			68.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:48:				PipelineType				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:53:				Reconcile				83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:73:				ProcessNewDecisionFromAPI		88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:112:				process					80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:142:				InitPipeline				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:155:				SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/pipeline_webhook.go:15:						NewPipelineWebhook			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/plugins/weighers/netapp_cpu_usage_balancing.go:35:			Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/plugins/weighers/netapp_cpu_usage_balancing.go:53:			Init					60.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/plugins/weighers/netapp_cpu_usage_balancing.go:64:			Run					88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/plugins/weighers/netapp_cpu_usage_balancing.go:110:			init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/candidate_gatherer.go:29:						MutateWithAllCandidates			94.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/decisions_cleanup.go:30:						DecisionsCleanup			79.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_cleanup.go:24:						Start					82.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_cleanup.go:63:						Reconcile				70.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_cleanup.go:95:						SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_executor.go:45:						Reconcile				68.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_executor.go:256:					SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_cycle_breaker.go:17:						Filter					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:42:					PipelineType				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:47:					InitPipeline				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:65:					CreateDeschedulingsPeriodically		0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:126:					Reconcile				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:131:					SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:61:							getHypervisors				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:104:							prepare					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:257:							randomRequest				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:330:							checkNovaSchedulerReturnsValidHosts	0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:360:							RunChecks				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:50:						NewAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:59:						Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:66:						canRunScheduler				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:89:						inferPipelineName			96.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:149:					limitHostsToRequest			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:171:					NovaExternalScheduler			68.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:51:				PipelineType				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:56:				Reconcile				91.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:76:				ProcessNewDecisionFromAPI		88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:115:				process					80.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:167:				InitPipeline				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:180:				SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:48:				Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:82:				Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:111:				Reconcile				93.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:178:				handleRemoteHypervisor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:207:				predicateRemoteHypervisor		100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:220:				SetupWithManager			23.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:57:							NewNovaClient				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:61:							Init					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:99:							Get					75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:108:							LiveMigrate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:119:							GetServerMigrations			74.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/pipeline_webhook.go:16:						NewPipelineWebhook			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/detectors/avoid_high_steal_pct.go:26:				Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/detectors/avoid_high_steal_pct.go:39:				Init					80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/detectors/avoid_high_steal_pct.go:49:				Run					86.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/detectors/avoid_high_steal_pct.go:85:				init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_allowed_projects.go:22:			Run					87.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_allowed_projects.go:54:			init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_capabilities.go:25:				hvToNovaCapabilities			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_capabilities.go:48:				Run					81.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_capabilities.go:119:				init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_correct_az.go:21:				Run					83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_correct_az.go:65:				init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_exclude_hosts.go:28:				Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_exclude_hosts.go:30:				Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_exclude_hosts.go:43:				init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_external_customer.go:23:			Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_external_customer.go:36:			Run					94.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_external_customer.go:86:			init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_accelerators.go:21:			Run					91.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_accelerators.go:55:			init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go:24:			Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go:44:			Run					76.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go:304:			init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_requested_traits.go:24:			Run					95.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_requested_traits.go:89:			init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_host_instructions.go:21:			Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_host_instructions.go:44:			init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_instance_group_affinity.go:19:			Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_instance_group_affinity.go:54:			init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_instance_group_anti_affinity.go:22:		Run					88.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_instance_group_anti_affinity.go:99:		init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_live_migratable.go:22:				checkHasSufficientFeatures		100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_live_migratable.go:51:				Run					94.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_live_migratable.go:112:			init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_requested_destination.go:30:			Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_requested_destination.go:43:			Run					98.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_requested_destination.go:135:			init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_status_conditions.go:23:			Run					93.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_status_conditions.go:88:			init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/vm_detection.go:17:						GetResource				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/vm_detection.go:18:						GetReason				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/vm_detection.go:19:						GetHost					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/vm_detection.go:20:						WithReason				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_binpack.go:29:					Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_binpack.go:72:					Run					90.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_binpack.go:141:					calcVMResources				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_binpack.go:154:					init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:26:			Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:30:			GetFailoverHostWeight			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:37:			GetDefaultHostWeight			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:54:			Run					93.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:116:			init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_instance_group_soft_affinity.go:29:		Run					94.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_instance_group_soft_affinity.go:85:		init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_prefer_smaller_hosts.go:29:			Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_prefer_smaller_hosts.go:60:			Run					92.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_prefer_smaller_hosts.go:157:			init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_anti_affinity_noisy_projects.go:29:		Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_anti_affinity_noisy_projects.go:44:		Init					80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_anti_affinity_noisy_projects.go:55:		Run					81.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_anti_affinity_noisy_projects.go:93:		init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_long_term_contended_hosts.go:35:	Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_long_term_contended_hosts.go:53:	Init					80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_long_term_contended_hosts.go:64:	Run					88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_long_term_contended_hosts.go:111:	init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_short_term_contended_hosts.go:35:	Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_short_term_contended_hosts.go:53:	Init					80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_short_term_contended_hosts.go:64:	Run					88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_short_term_contended_hosts.go:111:	init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:32:				Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:75:				Init					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:88:				Run					80.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:165:				calcHostCapacity			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:177:				calcHostAllocation			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:187:				calcVMResources				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:200:				init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:51:				PipelineType				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:55:				Reconcile				83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:75:				ProcessNewPod				89.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:132:				process					71.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:195:				InitPipeline				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:208:				handlePod				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:248:				SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/helpers/resources.go:12:						GetPodResourceRequests			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/helpers/resources.go:31:						AddResourcesInto			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/helpers/resources.go:41:						MaxResourcesInto			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/pipeline_webhook.go:15:						NewPipelineWebhook			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:22:				Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:26:				Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:30:				Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:43:				matchesNodeAffinity			88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:62:				matchesNodeSelectorTerm			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:71:				matchesNodeSelectorRequirement		90.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:124:				init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:21:				Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:25:				Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:29:				Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:42:				isNodeHealthy				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:70:				isNodeSchedulable			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:74:				init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:22:				Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:26:				Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:30:				Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:45:				hasCapacityForPod			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:60:				init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_noop.go:21:					Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_noop.go:25:					Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_noop.go:34:					Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_noop.go:44:					init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:21:					Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:25:					Validate				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:29:					Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:42:					canScheduleOnNode			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:53:					hasToleration				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:67:					init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/weighers/binpack.go:21:					Validate				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/weighers/binpack.go:34:					Run					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/weighers/binpack.go:48:					calculateBinpackScore			85.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/weighers/binpack.go:83:					init					50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api.go:22:					NewAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api.go:26:					NewAPIWithConfig			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api.go:33:					Init					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api_change_commitments.go:28:			sortedKeys				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api_change_commitments.go:45:			HandleChangeCommitments			76.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api_change_commitments.go:103:			processCommitmentChanges		79.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api_change_commitments.go:288:			watchReservationsUntilReady		63.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api_info.go:22:					HandleInfo				72.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api_info.go:58:					buildServiceInfo			22.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api_report_capacity.go:19:			HandleReportCapacity			78.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/capacity.go:24:					NewCapacityCalculator			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/capacity.go:29:					CalculateCapacity			91.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/capacity.go:60:					calculateAZCapacity			71.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/capacity.go:86:					getAvailabilityZones			55.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:46:					NewCommitmentsClient			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:50:					Init					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:109:					ListProjects				90.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:128:					ListCommitmentsByID			79.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:172:					listCommitments				90.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/config.go:17:					DefaultConfig				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/messages.go:135:					UnmarshalJSON				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/messages.go:158:					MarshalJSON				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_manager.go:25:			NewReservationManager			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_manager.go:46:			ApplyCommitmentState			89.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_manager.go:201:			syncReservationMetadata			93.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_manager.go:248:			newReservation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:23:					getFlavorGroupNameFromResource		100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:51:					FromCommitment				75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:95:					FromChangeCommitmentTargetState		93.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:148:					FromReservations			86.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:40:					NewSyncer				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:47:					Init					66.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:54:					getCommitmentStates			62.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:124:					SyncReservations			60.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/utils.go:13:					GetMaxSlotIndex				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/utils.go:30:					GetNextSlotIndex			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/utils.go:36:					extractCommitmentUUID			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/controller/controller.go:77:					Reconcile				53.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/controller/controller.go:348:					reconcileAllocations			17.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/controller/controller.go:427:					Init					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/controller/controller.go:441:					listServersByProjectID			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/controller/controller.go:471:					SetupWithManager			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/controller/monitor.go:32:					NewControllerMonitor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/controller/monitor.go:47:					Describe				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/controller/monitor.go:53:					Collect					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/flavor_groups.go:25:						Get					85.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/flavor_groups.go:46:						GetAllFlavorGroups			85.7%
total:																(statements)				68.5%

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.

2 participants