From ddc68f2333456976146399e65ac851c825e95705 Mon Sep 17 00:00:00 2001 From: kerthcet Date: Fri, 4 Sep 2026 14:08:10 +0100 Subject: [PATCH 1/2] update the readme.md Signed-off-by: kerthcet --- README.md | 13 +++++++++++++ pkg/provider/catalog/catalog.go | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a1a0556..ce0c574 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,14 @@ per-cloud glue. The API follows a Karpenter-style split: Nebula architecture: the operator's webhook, virtual kubelet and placement controller drive NodePools and NodeClaims onto hyperscalers, NeoClouds, Kubernetes clusters and on-prem servers

+## Features + +- **Kubernetes-native experience.** Same Deployments or Jobs opt in with labels for integration, no new workload type, no per-cloud glue. +- **Multi-provider support.** Modal and AWS today, with more to come. +- **Policy-driven placement.** Flexible NodePool spec to pick providers by cost, availability, and region, with failover and network egress policy. +- **Cost tracking.** Out-of-the-box per-instance cost tracking. +- **Observability.** Rich metrics and logs for placement, provisioning, and instance lifecycle. + ## How it works 1. **Opt in.** You label a Pod to request an accelerator. @@ -64,6 +72,11 @@ spec: strategy: Ordered # try providers in listed order (or LowestPrice) failover: blocklistTTL: 10m # how long a failed placement is skipped + egress: # outbound policy; omitted = Open + mode: Allowlist # or Blocked to permit nothing + targets: # CIDRs, bare IPs and domains, wildcards allowed + - 10.0.0.0/8 + - "*.huggingface.co" ``` ## Opting a workload in diff --git a/pkg/provider/catalog/catalog.go b/pkg/provider/catalog/catalog.go index 9e709fa..9de75ff 100644 --- a/pkg/provider/catalog/catalog.go +++ b/pkg/provider/catalog/catalog.go @@ -192,8 +192,8 @@ func parseCSV(r io.Reader) ([]provider.Offering, error) { // ParseFloat takes "NaN" and "Inf" as valid floats. Refused at the boundary because a rate // is pinned onto the claim and integrated from there — the damage is downstream, in a // durable ledger and a counter that cannot be corrected, not in this row. - if math.IsNaN(price) || math.IsInf(price, 0) { - return nil, fmt.Errorf("row %d: price_per_hour %q is not a finite number", i, field(rec, colPrice)) + if math.IsNaN(price) || math.IsInf(price, 0) || price < 0 { + return nil, fmt.Errorf("row %d: price_per_hour %q must be a non-negative finite number", i, field(rec, colPrice)) } available, err := strconv.ParseBool(field(rec, colAvailable)) if err != nil { From e939d3547bff682c297a06730de9d5af4daa11f5 Mon Sep 17 00:00:00 2001 From: kerthcet Date: Fri, 4 Sep 2026 14:18:08 +0100 Subject: [PATCH 2/2] update Signed-off-by: kerthcet --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce0c574..6e23109 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ per-cloud glue. The API follows a Karpenter-style split: ## Features -- **Kubernetes-native experience.** Same Deployments or Jobs opt in with labels for integration, no new workload type, no per-cloud glue. +- **Kubernetes-native experience.** Existing Deployments and Jobs opt in via labels; no new workload type and no per-cloud glue. - **Multi-provider support.** Modal and AWS today, with more to come. - **Policy-driven placement.** Flexible NodePool spec to pick providers by cost, availability, and region, with failover and network egress policy. - **Cost tracking.** Out-of-the-box per-instance cost tracking.