Documentation
¶
Index ¶
- Constants
- func SaveServiceConfig(path string, cfg *ServiceConfig) error
- type DebugService
- func (d *DebugService) GetMetrics(ctx context.Context, state *lsvd_v1alpha.LsvdDebugGetMetrics) error
- func (d *DebugService) ListMounts(ctx context.Context, state *lsvd_v1alpha.LsvdDebugListMounts) error
- func (d *DebugService) ListVolumes(ctx context.Context, state *lsvd_v1alpha.LsvdDebugListVolumes) error
- type LSVDDisk
- type MountController
- func (c *MountController) Index() entity.Attr
- func (c *MountController) Init(ctx context.Context) error
- func (c *MountController) Reconcile(ctx context.Context, mount *storage_v1alpha.LsvdMount, meta *entity.Meta) error
- func (c *MountController) ReconcileWithEntities(ctx context.Context) error
- func (c *MountController) ReconcileWithSystem(ctx context.Context) error
- func (c *MountController) SetEAC(eac *entityserver_v1alpha.EntityAccessClient)
- func (c *MountController) Shutdown()
- type MountOps
- type MountState
- type Server
- type ServerOption
- type ServiceConfig
- type State
- func (s *State) DeleteMount(entityId string)
- func (s *State) DeleteVolume(entityId string)
- func (s *State) GetMount(entityId string) *MountState
- func (s *State) GetVolume(entityId string) *VolumeState
- func (s *State) GetVolumeByVolumeId(volumeId string) *VolumeState
- func (s *State) ListMounts() []*MountState
- func (s *State) ListVolumes() []*VolumeState
- func (s *State) Save() error
- func (s *State) SetMount(entityId string, mount *MountState)
- func (s *State) SetPath(dataPath string)
- func (s *State) SetVolume(entityId string, volume *VolumeState)
- type VolumeController
- func (c *VolumeController) Index() entity.Attr
- func (c *VolumeController) Init(ctx context.Context) error
- func (c *VolumeController) Reconcile(ctx context.Context, volume *storage_v1alpha.LsvdVolume, meta *entity.Meta) error
- func (c *VolumeController) ReconcileWithEntities(ctx context.Context) error
- func (c *VolumeController) ReconcileWithSystem(ctx context.Context) error
- func (c *VolumeController) SetEAC(eac *entityserver_v1alpha.EntityAccessClient)
- type VolumeOps
- type VolumeState
Constants ¶
const ServerVersion uint64 = 1
ServerVersion is a monotonically increasing version number for lsvd-server. IMPORTANT: This MUST be incremented whenever any changes are made to the lsvd-server code that require running instances to be upgraded. The main miren server will check this version and trigger a graceful restart if the running lsvd-server has an older version.
Variables ¶
This section is empty.
Functions ¶
func SaveServiceConfig ¶
func SaveServiceConfig(path string, cfg *ServiceConfig) error
SaveServiceConfig saves a service config to the given path.
Types ¶
type DebugService ¶
type DebugService struct {
// contains filtered or unexported fields
}
DebugService implements the LsvdDebug RPC interface
func NewDebugService ¶
func NewDebugService(server *Server) *DebugService
NewDebugService creates a new debug service
func (*DebugService) GetMetrics ¶
func (d *DebugService) GetMetrics(ctx context.Context, state *lsvd_v1alpha.LsvdDebugGetMetrics) error
GetMetrics returns reconciliation metrics
func (*DebugService) ListMounts ¶
func (d *DebugService) ListMounts(ctx context.Context, state *lsvd_v1alpha.LsvdDebugListMounts) error
ListMounts returns all mounts
func (*DebugService) ListVolumes ¶
func (d *DebugService) ListVolumes(ctx context.Context, state *lsvd_v1alpha.LsvdDebugListVolumes) error
ListVolumes returns all volumes
type LSVDDisk ¶
type LSVDDisk interface {
// Close closes the disk
Close(ctx context.Context) error
// Size returns the disk size in bytes
Size() int64
// HandleNBD handles NBD protocol on the given connection
HandleNBD(ctx context.Context, conn net.Conn, clientFile *os.File) error
}
LSVDDisk abstracts LSVD disk operations for NBD handling
type MountController ¶
type MountController struct {
// contains filtered or unexported fields
}
MountController watches lsvd_mount entities and manages NBD devices and mounts
func NewMountController ¶
func NewMountController(log *slog.Logger, dataPath, nodeId string, state *State, ops MountOps) *MountController
NewMountController creates a new mount controller. The controller is created without an EntityAccessClient so that local system reconciliation (ReconcileWithSystem) can run immediately at startup, even if the entity server is unavailable. Call SetEAC after establishing a connection to the entity server to enable entity-based reconciliation.
func (*MountController) Index ¶
func (c *MountController) Index() entity.Attr
Index returns the entity index attribute for watching mount entities on this node.
func (*MountController) Init ¶
func (c *MountController) Init(ctx context.Context) error
Init implements controller.ReconcileControllerI.
func (*MountController) Reconcile ¶
func (c *MountController) Reconcile(ctx context.Context, mount *storage_v1alpha.LsvdMount, meta *entity.Meta) error
Reconcile implements controller.ReconcileControllerI.
func (*MountController) ReconcileWithEntities ¶
func (c *MountController) ReconcileWithEntities(ctx context.Context) error
ReconcileWithEntities reconciles local state with entity server
func (*MountController) ReconcileWithSystem ¶
func (c *MountController) ReconcileWithSystem(ctx context.Context) error
ReconcileWithSystem reconciles mount state with the actual system
func (*MountController) SetEAC ¶
func (c *MountController) SetEAC(eac *entityserver_v1alpha.EntityAccessClient)
SetEAC sets the EntityAccessClient for entity server communication. This is separate from construction because the controller must be usable for local system reconciliation before the entity server connection is established — ensuring disks remain available even during entity server outages.
func (*MountController) Shutdown ¶
func (c *MountController) Shutdown()
Shutdown unmounts filesystems, disconnects NBD devices, and cleans up handlers.
type MountOps ¶
type MountOps interface {
// CreateDir creates a directory with the specified permissions
CreateDir(path string, perm os.FileMode) error
// RemoveFile removes a file
RemoveFile(path string) error
// NBDLoopback sets up an NBD loopback device
// Returns: index, conn, clientFile, cleanup function, error
NBDLoopback(ctx context.Context, sizeBytes uint64) (uint32, net.Conn, *os.File, func() error, error)
// NBDStatus checks the status of an NBD device
NBDStatus(idx uint32) error
// NBDDisconnect disconnects an NBD device
NBDDisconnect(idx uint32) error
// CreateDeviceNode creates a block device node
CreateDeviceNode(path string, nbdIndex uint32) error
// Mount mounts a device at the specified path
Mount(device, mountPath, filesystem string, readOnly bool) error
// Unmount unmounts a path
Unmount(path string) error
// IsMounted checks if a path is a mount point
IsMounted(path string) bool
// IsFormatted checks if a device has a filesystem
IsFormatted(device, filesystem string) (bool, error)
// FormatDevice formats a device with the specified filesystem
FormatDevice(ctx context.Context, device, filesystem string) error
// OpenLSVDDisk opens an LSVD disk for the given volume.
// If remoteOnly is true, the disk uses only remote cloud storage (no local).
// The leaseNonce is passed to the segment access for write operations.
OpenLSVDDisk(ctx context.Context, diskPath, volumeId string, remoteOnly bool, leaseNonce string) (LSVDDisk, error)
// AcquireVolumeLease acquires a lease from the cloud for exclusive access.
// Returns the lease nonce, or empty string if cloud auth is not configured.
AcquireVolumeLease(ctx context.Context, volumeId string, metadata map[string]any) (string, error)
// ReleaseVolumeLease releases a lease from the cloud.
// Does nothing if cloud auth is not configured or nonce is empty.
ReleaseVolumeLease(ctx context.Context, volumeId, nonce string) error
}
MountOps abstracts OS operations for mount management. This interface enables testing without requiring actual NBD, device, or mount operations.
func NewRealMountOps ¶
NewRealMountOps creates a MountOps that performs real OS operations. If authClient is non-nil, disks are opened with a ReplicaWriter that replicates writes to the remote cloud.
type MountState ¶
type MountState struct {
// EntityId is the ID of the lsvd_mount entity
EntityId string `json:"entity_id"`
// VolumeId is the ID of the lsvd_volume entity
VolumeId string `json:"volume_id"`
// NbdIndex is the NBD device index
NbdIndex uint32 `json:"nbd_index"`
// DevicePath is the path to the NBD device node
DevicePath string `json:"device_path"`
// MountPath is where the volume is mounted
MountPath string `json:"mount_path"`
// Mounted indicates if the volume is currently mounted
Mounted bool `json:"mounted"`
// ReadOnly indicates if the mount is read-only
ReadOnly bool `json:"read_only"`
// LeaseNonce is the volume lease nonce from remote Disk API
LeaseNonce string `json:"lease_nonce,omitempty"`
}
MountState represents the state of an LSVD mount
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server manages LSVD volumes and mounts by watching entities
type ServerOption ¶
type ServerOption func(*serverOptions)
ServerOption configures the server
func WithClientCredentials ¶
func WithClientCredentials(cert, key []byte) ServerOption
WithClientCredentials sets the client TLS credentials for connecting to entity server
func WithCloudAuth ¶
func WithCloudAuth(cloudURL, privateKey string) ServerOption
WithCloudAuth configures cloud authentication for disk replication
func WithSkipVerify ¶
func WithSkipVerify(skip bool) ServerOption
WithSkipVerify skips TLS verification when connecting to entity server
type ServiceConfig ¶
type ServiceConfig struct {
// ClientCert is the PEM-encoded client certificate
ClientCert []byte `json:"client_cert,omitempty"`
// ClientKey is the PEM-encoded client private key
ClientKey []byte `json:"client_key,omitempty"`
// CloudURL is the miren.cloud API URL for disk replication
CloudURL string `json:"cloud_url,omitempty"`
// PrivateKey is the PEM-encoded private key for cloud authentication
PrivateKey string `json:"private_key,omitempty"`
}
ServiceConfig holds credentials for connecting to the entity server. This is written by the main server process for lsvd-server to use.
func LoadServiceConfig ¶
func LoadServiceConfig(path string) (*ServiceConfig, error)
LoadServiceConfig loads a service config from the given path.
type State ¶
type State struct {
Volumes map[string]*VolumeState `json:"volumes"`
Mounts map[string]*MountState `json:"mounts"`
// contains filtered or unexported fields
}
State represents the persisted state of the LSVD server
func (*State) DeleteMount ¶
DeleteMount removes a mount state
func (*State) DeleteVolume ¶
DeleteVolume removes a volume state
func (*State) GetMount ¶
func (s *State) GetMount(entityId string) *MountState
GetMount returns a copy of a mount state by entity ID
func (*State) GetVolume ¶
func (s *State) GetVolume(entityId string) *VolumeState
GetVolume returns a copy of a volume state by entity ID
func (*State) GetVolumeByVolumeId ¶
func (s *State) GetVolumeByVolumeId(volumeId string) *VolumeState
GetVolumeByVolumeId returns a copy of a volume state by LSVD volume ID
func (*State) ListMounts ¶
func (s *State) ListMounts() []*MountState
ListMounts returns copies of all mount states
func (*State) ListVolumes ¶
func (s *State) ListVolumes() []*VolumeState
ListVolumes returns copies of all volume states
func (*State) SetMount ¶
func (s *State) SetMount(entityId string, mount *MountState)
SetMount sets a mount state
func (*State) SetVolume ¶
func (s *State) SetVolume(entityId string, volume *VolumeState)
SetVolume sets a volume state
type VolumeController ¶
type VolumeController struct {
// contains filtered or unexported fields
}
VolumeController watches lsvd_volume entities and manages LSVD volumes
func NewVolumeController ¶
func NewVolumeController(log *slog.Logger, dataPath, nodeId string, state *State, ops VolumeOps) *VolumeController
NewVolumeController creates a new volume controller. The controller is created without an EntityAccessClient so that local system reconciliation (ReconcileWithSystem) can run immediately at startup, even if the entity server is unavailable. Call SetEAC after establishing a connection to the entity server to enable entity-based reconciliation.
func (*VolumeController) Index ¶
func (c *VolumeController) Index() entity.Attr
Index returns the entity index attribute for watching volume entities on this node.
func (*VolumeController) Init ¶
func (c *VolumeController) Init(ctx context.Context) error
Init implements controller.ReconcileControllerI.
func (*VolumeController) Reconcile ¶
func (c *VolumeController) Reconcile(ctx context.Context, volume *storage_v1alpha.LsvdVolume, meta *entity.Meta) error
Reconcile implements controller.ReconcileControllerI.
func (*VolumeController) ReconcileWithEntities ¶
func (c *VolumeController) ReconcileWithEntities(ctx context.Context) error
ReconcileWithEntities reconciles local state with entity server
func (*VolumeController) ReconcileWithSystem ¶
func (c *VolumeController) ReconcileWithSystem(ctx context.Context) error
ReconcileWithSystem reconciles volume state with the actual system
func (*VolumeController) SetEAC ¶
func (c *VolumeController) SetEAC(eac *entityserver_v1alpha.EntityAccessClient)
SetEAC sets the EntityAccessClient for entity server communication. This is separate from construction because the controller must be usable for local system reconciliation before the entity server connection is established — ensuring disks remain available even during entity server outages.
type VolumeOps ¶
type VolumeOps interface {
// CreateVolumeDir creates the directory for a volume
CreateVolumeDir(path string) error
// RemoveVolumeDir removes a volume directory and all its contents
RemoveVolumeDir(path string) error
// VolumePathExists checks if a volume path exists
VolumePathExists(path string) bool
// InitLSVDVolume initializes an LSVD volume at the given path.
// Returns the actual volume ID used (which may differ from the input when
// cloud auth is configured and the server generates the ID).
// If remoteOnly is true, the volume is only initialized on the remote cloud
// (no local storage).
InitLSVDVolume(ctx context.Context, path, volumeId string, size units.Bytes, metadata map[string]any, remoteOnly bool) (string, error)
}
VolumeOps abstracts OS and LSVD operations for volume management. This interface enables testing without requiring actual filesystem or LSVD operations.
func NewRealVolumeOps ¶
func NewRealVolumeOps(log *slog.Logger, authClient *cloudauth.AuthClient, cloudURL string) VolumeOps
NewRealVolumeOps creates a VolumeOps that performs real OS operations. If authClient is non-nil, volumes are also initialized on the remote cloud.
type VolumeState ¶
type VolumeState struct {
// EntityId is the ID of the lsvd_volume entity
EntityId string `json:"entity_id"`
// VolumeId is the LSVD volume identifier
VolumeId string `json:"volume_id"`
// Name is the human-readable name (from parent disk)
Name string `json:"name,omitempty"`
// DiskPath is the path to the volume data directory
DiskPath string `json:"disk_path"`
// SizeBytes is the volume size
SizeBytes int64 `json:"size_bytes"`
// Filesystem type (ext4, xfs, btrfs)
Filesystem string `json:"filesystem"`
// RemoteOnly indicates if this uses only remote storage
RemoteOnly bool `json:"remote_only"`
}
VolumeState represents the state of an LSVD volume