Documentation
¶
Index ¶
- Constants
- Variables
- func IsLabRuntimeName(name string) bool
- func NormalizeExposeType(value string) (string, error)
- func Register(name string, init Initializer)
- func SanitizeName(name string) string
- func SanitizeNodeNames(nodeNames []string) (map[string]string, error)
- type ChangeAction
- type Config
- type DeployPlan
- type DeployRequest
- type DestroyRequest
- type Event
- type EventStreamRequest
- type ExecRequest
- type Initializer
- type InspectRequest
- type LabExistenceChecker
- type LabRuntime
- type LabState
- type ListRequest
- type Manifest
- type ManifestEmitter
- type NodeRequest
- type NodeState
- type ResourceChange
- type SaveRequest
- type SaveResult
- type SavedFile
- type TopologyPlanner
- type TopologyValidator
Constants ¶
const ( ClabernetesRuntimeName = "c9s" ExposeTypeClusterIP = "ClusterIP" ExposeTypeHeadless = "Headless" ExposeTypeLoadBalancer = "LoadBalancer" ExposeTypeNone = "None" )
Variables ¶
var LabRuntimes = map[string]Initializer{}
Functions ¶
func IsLabRuntimeName ¶
func NormalizeExposeType ¶
NormalizeExposeType validates a c9s expose type and returns its canonical CRD spelling.
func Register ¶
func Register(name string, init Initializer)
func SanitizeName ¶
SanitizeName maps a containerlab name onto the DNS-1035 label a lab runtime can name the objects it creates with: lower case, made up of a-z, 0-9 and '-', starting with a letter and at most 63 characters long. A large share of public labs name their nodes R1/PE_1 or capitalize the lab name, and Kubernetes cannot carry those names as they are -- renaming them beats making the user edit every reference in the topology.
The mapping is deterministic and idempotent: a name Kubernetes already accepts maps onto itself, so a sanitized name coming back from the runtime -- or typed by a user reading it off containerlab output -- resolves to the same object. The result is empty only for a name holding nothing a Kubernetes name can be built from.
func SanitizeNodeNames ¶
SanitizeNodeNames returns the sanitized name of every node name that needs one, keyed by the name the topology uses. Node names Kubernetes can carry as they are are absent from the result.
Two node names that differ only in something Kubernetes cannot carry (R1 and r1) would collapse onto one object, so that is reported as an error instead of silently merging the two nodes.
Types ¶
type ChangeAction ¶
type ChangeAction string
const ( ChangeCreate ChangeAction = "create" ChangeUpdate ChangeAction = "update" ChangeDelete ChangeAction = "delete" )
type DeployPlan ¶
type DeployPlan struct {
LabName string `json:"lab-name"`
Namespace string `json:"namespace"`
Changes []ResourceChange `json:"changes"`
}
DeployPlan describes the remote resources a lab runtime would change without mutating them.
type DeployRequest ¶
type DeployRequest struct {
Name string
Namespace string
Owner string
TopologyFile string
TopologyLabDir string
TopologyDefinition []byte
Wait bool
Timeout time.Duration
// MaxWorkers limits concurrent independent operations performed by the runtime.
MaxWorkers uint
// NoTopologyCR deploys without a controller-owned topology object: the runtime compiles the
// topology client-side and manages the individual lab resources directly.
NoTopologyCR bool
// ImagePullSecret names the same-namespace Docker-config Secret placed on device pods
// through Pod.spec.imagePullSecrets. Empty means the lab references no pull secret at
// all: public images and clusters whose runtime already holds credentials need none.
ImagePullSecret string
// ExposeType controls the Kubernetes Service type c9s creates for lab nodes. Empty uses the
// c9s CRD default.
ExposeType string
// NoPersistence deploys the lab on ephemeral node storage. By default every node's
// artifact volume is backed by a persistent claim so saved device configuration survives
// Pod replacement, matching the local-runtime lab directory contract; opting out trades
// that for not needing a dynamically provisionable storage class, and every Pod
// replacement then resets the node to its declared configuration.
NoPersistence bool
}
type DestroyRequest ¶
type EventStreamRequest ¶
type ExecRequest ¶
type Initializer ¶
type Initializer func(Config) (LabRuntime, error)
type InspectRequest ¶
type LabExistenceChecker ¶
type LabExistenceChecker interface {
LabExists(context.Context, InspectRequest) (bool, error)
}
LabExistenceChecker lets controller-driven runtimes report whether a lab has remote state. Core uses it to distinguish a fresh deployment from reconciliation without consulting the local container runtime.
type LabRuntime ¶
type LabRuntime interface {
Deploy(context.Context, DeployRequest) (*LabState, error)
Destroy(context.Context, DestroyRequest) error
Inspect(context.Context, InspectRequest) (*LabState, error)
List(context.Context, ListRequest) ([]*LabState, error)
Exec(context.Context, ExecRequest) (*clabexec.ExecResult, error)
Start(context.Context, NodeRequest) error
Stop(context.Context, NodeRequest) error
Restart(context.Context, NodeRequest) error
Save(context.Context, SaveRequest) (*SaveResult, error)
StreamEvents(context.Context, EventStreamRequest) (<-chan Event, <-chan error, error)
}
type ListRequest ¶
type Manifest ¶
type Manifest struct {
APIVersion string
Kind string
Namespace string
Name string
Object map[string]any
}
Manifest is one remote resource a lab runtime would create for a topology, ready to be serialized and applied by hand. Object is the complete resource including its type and metadata; the identity fields are duplicated for summaries and tests.
type ManifestEmitter ¶
type ManifestEmitter interface {
Manifests(context.Context, DeployRequest) ([]Manifest, error)
}
ManifestEmitter renders the exact resources a lab runtime would create for a topology, in apply order, without reading or changing remote state.
type NodeRequest ¶
type ResourceChange ¶
type ResourceChange struct {
Action ChangeAction `json:"action"`
Kind string `json:"kind"`
Namespace string `json:"namespace,omitempty"`
Name string `json:"name"`
}
type SaveRequest ¶
type SaveResult ¶
type SaveResult struct {
Files []SavedFile
}
type TopologyPlanner ¶
type TopologyPlanner interface {
Plan(context.Context, DeployRequest) (*DeployPlan, error)
}
TopologyPlanner compiles and diffs a desired topology without changing remote state.
type TopologyValidator ¶
type TopologyValidator interface {
Validate(context.Context, DeployRequest) error
}
TopologyValidator validates the runtime-specific topology subset without changing remote state.