cluster

package
v1.27.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2026 License: MIT Imports: 5 Imported by: 0

README

Cluster Management

This package provides interfaces and implementations for managing local Kubernetes clusters.

Design Philosophy

Following Caproni's Pluggable Backends principle, the cluster management is designed with:

  • Interface-based design: cluster.Manager defines the contract
  • Swappable implementations: Different drivers (Colima, k3d, minikube) can be used
  • Minimal surface area: Simple Start/Stop/Status operations

Interface

type Manager interface {
    Start(ctx context.Context, cfg config.ClusterConfig) error
    Stop(ctx context.Context) error
    Status(ctx context.Context) (*Status, error)
}

Usage

Creating a Cluster Manager

Drivers are automatically registered via their init() functions. Simply import the driver package and use the registry to create a manager:

import (
    "context"

    "gitlab.com/gitlab-org/caproni/internal/cluster"
    "gitlab.com/gitlab-org/caproni/internal/config"

    // Import auto driver to register auto, colima, and k3d
    _ "gitlab.com/gitlab-org/caproni/internal/cluster/auto"
)

// Create a manager using the registry ("auto" selects colima on macOS, k3d on Linux)
manager, err := cluster.NewManager("auto", "caproni-dev")
if err != nil {
    log.Fatalf("Failed to create manager: %v", err)
}

// With driver: auto, always provide both sections so the config works on any platform
cfg := config.ClusterConfig{
    Driver: "auto",
    Colima: &config.ColimaConfig{
        Memory: "10GiB",
        Cores:  4,
    },
    K3d: &config.K3dConfig{
        Agents:  0,
        Servers: 1,
    },
}

ctx := context.Background()
Listing Available Drivers
import "gitlab.com/gitlab-org/caproni/internal/cluster"

// Get all registered drivers
drivers := cluster.ListDrivers()
fmt.Printf("Available drivers: %v\n", drivers)
// Output: Available drivers: [colima k3d]
Starting a Cluster
// Start the cluster
if err := manager.Start(ctx, cfg); err != nil {
    log.Fatalf("Failed to start cluster: %v", err)
}

// Starting an already-running cluster with matching config is a no-op
// Starting with different config returns cluster.ErrConfigMismatch
Checking Cluster Status
status, err := manager.Status(ctx)
if err != nil {
    log.Fatalf("Failed to get status: %v", err)
}

fmt.Printf("State: %s\n", status.State)
fmt.Printf("Driver: %s\n", status.Driver)
fmt.Printf("Kubernetes Version: %s\n", status.KubernetesVersion)
Stopping a Cluster
if err := manager.Stop(ctx); err != nil {
    log.Fatalf("Failed to stop cluster: %v", err)
}

// Stopping an already-stopped cluster is a no-op

Available Drivers

Colima

The Colima driver (internal/cluster/colima) uses Colima as the backend for running Kubernetes clusters.

Requirements:

  • Colima must be installed and available in PATH
  • Supports macOS and Linux
  • Supports both arm64 and amd64 architectures

Features:

  • Profile-based isolation (multiple Colima instances)
  • Kubernetes-enabled clusters
  • Configuration verification (prevents starting with mismatched config)
k3d

The k3d driver (internal/cluster/k3d) uses k3d as the backend for running Kubernetes clusters.

Requirements:

  • k3d must be installed and available in PATH
  • Supports macOS, Linux, and Windows
  • Runs on any architecture supported by Docker

Features:

  • Lightweight Kubernetes clusters using k3s
  • Fast cluster creation and deletion
  • Profile-based isolation (multiple k3d clusters)

Error Handling

The package defines several sentinel errors:

  • cluster.ErrClusterNotRunning - Operation requires a running cluster
  • cluster.ErrClusterAlreadyRunning - Cluster is already running
  • cluster.ErrConfigMismatch - Running cluster config doesn't match requested config
  • cluster.ErrDriverNotFound - Specified driver is not available
  • cluster.ErrClusterNotReady - Cluster is running but not ready for workloads

Example:

err := manager.Start(ctx, cfg)
if errors.Is(err, cluster.ErrConfigMismatch) {
    log.Println("Cluster is running with different configuration")
    log.Println("Stop the cluster first or adjust your config")
}

Driver Registry

The cluster package uses a registry pattern for driver management. Drivers self-register in their init() functions, allowing new drivers to be added without modifying the core registry code.

How It Works
  1. Driver Package Init: Each driver package registers itself on import
  2. Factory Pattern: Drivers register a factory function that creates instances
  3. Auto-Detection: The auto driver package registers itself and selects colima on macOS or k3d on Linux
  4. Lookup via Registry: NewManager() looks up the driver in the registry
  5. Compile-Time Selection: Only imported driver packages are included in the binary
Benefits
  • Extensibility: Add new drivers without touching registry code
  • Modularity: Each driver is self-contained in its own package
  • Flexible Compilation: Control which drivers to include via imports
  • Thread-Safe: Registry uses mutex protection for concurrent access

Adding New Drivers

To add support for a new cluster driver:

  1. Create a new package under internal/cluster/<driver-name>/

  2. Implement the cluster.Manager interface:

    type Driver struct {
        // driver-specific fields
    }
    
    func (d *Driver) Start(ctx context.Context, cfg config.ClusterConfig) error
    func (d *Driver) Stop(ctx context.Context) error
    func (d *Driver) Status(ctx context.Context) (*cluster.Status, error)
    
  3. Register in init() function:

    func init() {
        cluster.RegisterDriver("driver-name", func(profileName string) cluster.Manager {
            return NewDriver(profileName)
        })
    }
    
  4. Add comprehensive tests

  5. Import in main package to enable the driver:

    import _ "path/to/your/driver"
    
Example: New Driver Layout
internal/cluster/
├── registry.go         # Driver registry
├── interface.go        # Manager interface definition
├── errors.go           # Common errors
├── auto/               # Auto-detection driver (selects colima or k3d by OS)
│   ├── driver.go
│   └── driver_test.go
├── colima/
│   ├── driver.go       # Colima implementation
│   └── driver_test.go
├── k3d/
│   ├── driver.go       # k3d implementation
│   └── driver_test.go
└── mock/               # Test-only mock driver
    ├── driver.go
    └── driver_test.go

k3d/driver.go:

package k3d

import (
    "context"
    "gitlab.com/gitlab-org/caproni/internal/cluster"
    "gitlab.com/gitlab-org/caproni/internal/config"
)

func init() {
    // Auto-register on import
    cluster.RegisterDriver("k3d", func(profileName string) cluster.Manager {
        return NewDriver(profileName)
    })
}

type Driver struct {
    profileName string
}

func NewDriver(profileName string) *Driver {
    return &Driver{profileName: profileName}
}

func (d *Driver) Start(ctx context.Context, cfg config.ClusterConfig) error {
    // Implementation
}

func (d *Driver) Stop(ctx context.Context) error {
    // Implementation
}

func (d *Driver) Status(ctx context.Context) (*cluster.Status, error) {
    // Implementation
}

Future Enhancements

Potential additions to the cluster management interface:

  • Restart(ctx context.Context) error - Restart the cluster
  • Version(ctx context.Context) (string, error) - Get Kubernetes version
  • Exec(ctx context.Context, cmd string) error - Execute command in cluster
  • Profile management (list, delete profiles)
  • Resource usage monitoring
  • Health checks and diagnostics

Documentation

Overview

Package cluster provides interfaces and implementations for managing local Kubernetes clusters.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrClusterNotRunning is returned when an operation requires a running cluster.
	ErrClusterNotRunning = errors.New("cluster is not running")

	// ErrClusterAlreadyRunning is returned when attempting to start an already running cluster.
	ErrClusterAlreadyRunning = errors.New("cluster is already running")

	// ErrConfigMismatch is returned when the running cluster configuration doesn't match the requested configuration.
	ErrConfigMismatch = errors.New("cluster configuration mismatch")

	// ErrDriverNotFound is returned when the specified cluster driver is not available.
	ErrDriverNotFound = errors.New("cluster driver not found")

	// ErrClusterNotReady is returned when the cluster is running but not ready for workloads.
	ErrClusterNotReady = errors.New("cluster is not ready")

	// ErrMissingDriverConfig is returned when driver-specific configuration is missing.
	ErrMissingDriverConfig = errors.New("driver configuration is missing")
)

Functions

func ListDrivers

func ListDrivers() []string

ListDrivers returns a list of all registered driver names.

func RegisterDriver

func RegisterDriver(name string, factory DriverFactory)

RegisterDriver registers a driver factory function with the given name. This is typically called from a driver package's init() function. Panics if a driver with the same name is already registered.

Types

type DriverFactory

type DriverFactory func(profileName string) Manager

DriverFactory is a function that creates a new cluster manager instance.

type Manager

type Manager interface {
	// Start starts the cluster with the given configuration.
	// If the cluster is already running with matching configuration, this is a no-op.
	// If the cluster is running with different configuration, it returns an error.
	Start(ctx context.Context, cfg types.ClusterConfig) error

	// Stop stops the running cluster gracefully.
	// If the cluster is not running, this is a no-op.
	Stop(ctx context.Context) error

	// Destroy completely removes the cluster and all its data.
	// This is a destructive operation that cannot be undone.
	// If the cluster is not found, this is a no-op.
	Destroy(ctx context.Context) error

	// Status returns the current status of the cluster.
	// Returns an error if unable to determine cluster state.
	Status(ctx context.Context) (*Status, error)
}

Manager defines the interface for managing local Kubernetes clusters. Implementations are responsible for starting, stopping, and monitoring cluster lifecycle using specific backend drivers (e.g., Colima, k3d, minikube).

func NewManager

func NewManager(driver string, profileName string) (Manager, error)

NewManager creates a new cluster manager for the specified driver. Returns ErrDriverNotFound if the driver is not registered.

type State

type State string

State represents the current state of a cluster.

const (
	// StateStopped indicates the cluster is not running.
	StateStopped State = "stopped"

	// StateStarting indicates the cluster is starting but not yet ready.
	StateStarting State = "starting"

	// StateNotReady indicates the cluster is running but not ready to accept workloads.
	StateNotReady State = "not-ready"

	// StateReady indicates the cluster is running and ready to accept workloads.
	StateReady State = "ready"
)

type Status

type Status struct {
	// State is the current state of the cluster.
	State State

	// Driver is the name of the cluster driver (e.g., "colima", "k3d").
	Driver string

	// KubernetesVersion is the version of Kubernetes running in the cluster.
	KubernetesVersion string

	// IPAddress is the IP address of the cluster (empty if unavailable).
	IPAddress string

	// KubeContext is the name of the kubeconfig context for this cluster.
	KubeContext string
}

Status represents the current state of a cluster.

Directories

Path Synopsis
Package auto provides an auto-detecting cluster driver that selects the appropriate driver based on the current operating system.
Package auto provides an auto-detecting cluster driver that selects the appropriate driver based on the current operating system.
Package colima provides a cluster.Manager implementation using Colima.
Package colima provides a cluster.Manager implementation using Colima.
Package k3d provides a cluster.Manager implementation using k3d.
Package k3d provides a cluster.Manager implementation using k3d.
Package mock provides a mock cluster driver implementation for testing.
Package mock provides a mock cluster driver implementation for testing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL