Skip to content

Commit 9a36471

Browse files
committed
fixed up doc clarification
1 parent 3cd548a commit 9a36471

1 file changed

Lines changed: 81 additions & 6 deletions

File tree

cloudManualExternal.md

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,37 @@ inst.InstanceTypeID = v1.MakeGenericInstanceTypeIDFromInstance(*inst) // LAST
398398
- "instance type not found" errors during provisioning
399399
- Instances appear "orphaned" (no associated instance type)
400400

401+
### Validating Your Instance Type IDs
402+
403+
The SDK provides validation functions to catch ID generation issues early. **Run these in your test suite:**
404+
405+
**1. `ValidateStableInstanceTypeIDs`** - Ensures your instance type IDs are stable and unique:
406+
```go
407+
// In your validation tests
408+
err := v1.ValidateStableInstanceTypeIDs(ctx, client, stableIDs)
409+
require.NoError(t, err, "ValidateStableInstanceTypeIDs should pass")
410+
```
411+
412+
This validates:
413+
- Each instance type ID is unique (no duplicates)
414+
- Your designated stable IDs exist in the current instance types
415+
- All instance types have required properties (base price, storage pricing)
416+
417+
**2. `ValidateCreateInstance`** - Validates that instance and instance type IDs match:
418+
```go
419+
// In your validation tests
420+
instance, err := v1.ValidateCreateInstance(ctx, client, attrs, selectedType)
421+
require.NoError(t, err, "ValidateCreateInstance should pass")
422+
```
423+
424+
This validates (among other things):
425+
- `instance.InstanceTypeID == selectedType.ID`**catches ID generation mismatches**
426+
- `instance.RefID` matches the provided RefID
427+
- Location and instance type fields are consistent
428+
429+
> **Why this matters:** If `MakeGenericInstanceTypeID()` and `MakeGenericInstanceTypeIDFromInstance()` produce different IDs for the same logical type, the control plane cannot correlate instances with their types. `ValidateCreateInstance` catches this.
430+
431+
See [`internal/validation/suite.go`](internal/validation/suite.go) for the full validation test suite you can use as a reference.
401432

402433
## 4. Location Model
403434

@@ -444,10 +475,6 @@ Availability is tracked **per instance type** using two fields on the `InstanceT
444475

445476
## 5. GPU Normalization
446477

447-
### Why GPU Normalization Matters
448-
449-
Users search for GPUs by model. They want "H100" not "NVIDIA H100 80GB HBM3 SXM5 Accelerator". Your provider implementation must normalize GPU data into the SDK's structured `GPU` type.
450-
451478
### The GPU Struct
452479

453480
The Cloud SDK represents GPUs with these fields:
@@ -610,7 +637,7 @@ Your implementation must:
610637
1. Accept this public key in your create instance API
611638
2. Install it in the VM's default user `~/.ssh/authorized_keys` before the instance becomes accessible
612639

613-
Brev generates a unique SSH key pair for each instance. The control plane retains the private key and uses it to connect after creation.
640+
Brev manages SSH keys per user. The public key provided in `CreateInstanceAttrs.PublicKey` belongs to the user, and the control plane retains the corresponding private key to connect after creation.
614641

615642
---
616643

@@ -713,7 +740,7 @@ return c.GetInstance(ctx, v1.CloudProviderInstanceID(resp.Data.InstanceIds[0]))
713740
- Return `nil` once the stop operation is initiated.
714741
- Instance should transition: `running``stopping``stopped`
715742

716-
**When to implement:** Only if your platform supports instances that can stop and perserve storae. Lambda Labs does not support this, but Nebius does.
743+
**When to implement:** Only if your platform supports instances that can stop and preserve storage. Lambda Labs does not support this, but Nebius does.
717744

718745
### Start Instance (Optional)
719746

@@ -728,6 +755,54 @@ return c.GetInstance(ctx, v1.CloudProviderInstanceID(resp.Data.InstanceIds[0]))
728755

729756
**Note:** If you implement `StopInstance`, you must also implement `StartInstance`.
730757

758+
### Stop/Start: Three Levels of Control
759+
760+
Stop/start support is controlled at three levels:
761+
762+
| Level | What to Set | Purpose |
763+
|-------|-------------|---------|
764+
| **Provider Capability** | `CapabilityStopStartInstance` in `GetCapabilities()` | Indicates your API supports stop/start operations |
765+
| **Instance Type** | `InstanceType.Stoppable = true/false` | Indicates whether this instance type can be stopped (e.g., spot instances typically cannot) |
766+
| **Instance** | `Instance.Stoppable = true/false` | Indicates whether this specific instance can be stopped |
767+
768+
**Example - Nebius (supports stop/start):**
769+
```go
770+
// In GetCapabilities()
771+
v1.CapabilityStopStartInstance, // API supports it
772+
773+
// In GetInstanceTypes() - instance type level
774+
instanceType := v1.InstanceType{
775+
Stoppable: true, // This type supports stop/start
776+
// ...
777+
}
778+
779+
// In GetInstance()/CreateInstance() - instance level
780+
instance := v1.Instance{
781+
Stoppable: true, // This instance can be stopped
782+
// ...
783+
}
784+
```
785+
786+
**Example - Lambda Labs (no stop/start support):**
787+
```go
788+
// In GetCapabilities()
789+
// CapabilityStopStartInstance NOT included
790+
791+
// In GetInstanceTypes()
792+
instanceType := v1.InstanceType{
793+
Stoppable: false, // Cannot be stopped
794+
// ...
795+
}
796+
797+
// In GetInstance()/CreateInstance()
798+
instance := v1.Instance{
799+
Stoppable: false, // Cannot be stopped
800+
// ...
801+
}
802+
```
803+
804+
The control plane checks all three levels before allowing a stop/start operation. If any level indicates `false`, the operation won't be attempted.
805+
731806

732807
### Get Instance (Required)
733808

0 commit comments

Comments
 (0)