Skip to content

Add multiple LVM storage classes per host - #3

Merged
msdmazvoid merged 3 commits into
mainfrom
feature/storage-classes
Nov 6, 2026
Merged

msdmazvoid merged 3 commits into
mainfrom
feature/storage-classes

Conversation

@msdmazvoid

Copy link
Copy Markdown
Contributor

Summary

Adds first-class storage classes so one kouja agent can serve multiple LVM backends on the same physical host, for example NVMe, SSD, and HDD pools.

storage:
  classes:
    nvme: kouja-nvme
    ssd: kouja-ssd
    hdd: kouja-hdd
  • Adds storage.classes config mapping class names to LVM volume groups.
  • Includes class-referenced VGs in first-start registration via EffectiveVGs.
  • Adds storage_class to the agent CreateVolume request, Volume, and Capacity protobuf messages.
  • Returns the class on capacity and volume responses; raw VG names remain valid and act as their own class when no mapping exists.
  • Extends CSI StorageClass parameters with class (and storageClass alias). vg remains supported.
  • CSI host selection and GetCapacity now filter by storage class, so a PVC lands only on a host advertising that class.
  • Records the selected class in KoujaVolumePlacement.
  • Adds a class to volume context and documents the multi-backend setup.
  • Adds Ginkgo/Gomega tests for config mapping, agent resolution/capacity, CSI selection, capacity filtering, and placement.

Compatibility

Existing callers that pass only vg continue to work. If a class is not configured on the agent, it falls back to the raw VG name.

Test plan

  • go test -tags=unit ./...
  • go test -tags=integration ./test/integration/...
  • go test -tags=e2e ./test/e2e/...
  • go test -tags=csi_sanity ./test/csi/...
  • make coverage-check (80.8%)
  • go vet ./...
  • golangci-lint run
  • GitHub Actions CI

@msdmazvoid

Copy link
Copy Markdown
Contributor Author

QEMU end-to-end validation completed for this change:

  • Two Debian 13 QEMU/KVM VMs, host with loop-backed VGs kouja-nvme and kouja-hdd.
  • Host enabled classes only via storage.classes: nvme: kouja-nvme, hdd: kouja-hdd.
  • GET /v1/capacity returned both VGs with storageClass: nvme/hdd.
  • Direct API create with storageClass: hdd created the LV in kouja-hdd, returned storageClass: hdd, logged in over iSCSI with CHAP, and passed an 8 MiB write/read MD5 check.
  • Active-session delete returned SESSION_ACTIVE; after logout, delete succeeded and left no LV/target/backstore.
  • storageClass: nvme created in kouja-nvme; an explicit conflicting vg was rejected with InvalidArgument.
  • A real CSI controller selected the hdd class, created and published a volume, returned storage_class: hdd in the volume context, and completed the same 8 MiB write/read before unpublish/delete.

Recorded in docs/e2e.md.

@msdmazvoid

Copy link
Copy Markdown
Contributor Author

Added the client-facing storage-class discovery request:

  • gRPC: VolumeService.ListStorageClasses
  • HTTP: GET /v1/storage-classes
  • Returns class name, backing VG/UUID/state, total/free/allocatable bytes, extent size, maximum volume size, and observation time.
  • No admin role required; any authenticated caller/controller/node certificate can query it.
  • Verified over mTLS in QEMU with a caller certificate and two active classes.

@msdmazvoid
msdmazvoid merged commit 87d9cb7 into main Nov 6, 2026
2 checks passed
@msdmazvoid
msdmazvoid deleted the feature/storage-classes branch November 6, 2026 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant