Skip to content

Commit 82ca29a

Browse files
committed
refactor(longhorn): cleanup pass following Go best practices
- Drop dead BuildHelmValues exported wrapper. Tests in the same package use the unexported buildHelmValues directly; the public alias was added under a misleading 'for tests' comment with no external caller. - Skip ensureISCSI on the upgrade path. The iSCSI DaemonSet runs once per cluster on first install; re-running it on every helm upgrade burned a 3-minute readiness wait for nothing. Now Install consults the Helm release history first and only provisions iSCSI when the release is absent. - Fix Config struct doc. The previous comment claimed 'Enabled defaults to true so providers that ship a Longhorn block get the install for free' which contradicts IsEnabled() (nil Config = do not install). Reword to match the actual semantics. - Drop the conda-store reference from existing/hetzner config comments. Nebari no longer ships conda-store; jupyterhub shared-storage for group dirs is the relevant RWX use case.
1 parent eb4e5df commit 82ca29a

5 files changed

Lines changed: 24 additions & 24 deletions

File tree

pkg/provider/aws/config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,3 @@ func (c *Config) EFSStorageClassName() string {
9595
}
9696
return c.EFS.StorageClassName
9797
}
98-

pkg/provider/existing/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ type Config struct {
3030
// distributed/replicated block + RWX storage. The block is required to
3131
// opt-in (nil means "do not install"). Use this on bare-metal / hetzner-k3s
3232
// clusters that lack a managed RWX StorageClass — without it, charts that
33-
// need RWX (jupyterhub shared-storage, conda-store) have to fall back to
34-
// in-cluster NFS-on-RWO hacks.
33+
// need RWX (e.g. jupyterhub shared-storage for group dirs) fall back to
34+
// the in-cluster NFS-on-RWO workaround.
3535
Longhorn *longhorn.Config `yaml:"longhorn,omitempty"`
3636
}
3737

pkg/provider/hetzner/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ type Config struct {
3535

3636
// Longhorn opts the Hetzner provider into installing Longhorn distributed
3737
// block storage on the cluster after creation. Hetzner's hcloud-volumes
38-
// CSI is RWO-only; charts that need RWX (jupyterhub shared-storage,
39-
// conda-store, etc.) require Longhorn (or another RWX provider) to avoid
38+
// CSI is RWO-only; charts that need RWX (e.g. jupyterhub shared-storage
39+
// for group dirs) require Longhorn or another RWX provider to avoid
4040
// the in-cluster NFS-on-RWO workaround. Omit the block to skip the
4141
// install; explicit `enabled: false` also disables.
4242
Longhorn *longhorn.Config `yaml:"longhorn,omitempty"`

pkg/storage/longhorn/config.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ const (
2828

2929
// Config carries the user-tunable Longhorn settings shared across providers.
3030
//
31-
// All fields are optional — Enabled defaults to true so providers that ship a
32-
// Longhorn block in their config get the install for free, and ReplicaCount
33-
// defaults to 2 (sensible for small clusters; cloud production deploys can
34-
// raise it).
31+
// A nil *Config means "do not install" (see IsEnabled). When the user supplies
32+
// a non-nil Config, Enabled defaults to true so an empty block (`longhorn: {}`)
33+
// is the minimal opt-in. ReplicaCount defaults to 2 — appropriate for small
34+
// clusters; production deploys should raise it.
3535
type Config struct {
3636
Enabled *bool `yaml:"enabled,omitempty"`
3737
ReplicaCount int `yaml:"replica_count,omitempty"`

pkg/storage/longhorn/install.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ import (
1919
const installTimeout = 10 * time.Minute
2020

2121
// Install installs (or upgrades, if a release exists) Longhorn on the cluster
22-
// the kubeconfigBytes connect to. iSCSI prerequisites are deployed first as a
23-
// DaemonSet and waited on before the Helm install runs.
22+
// the kubeconfigBytes connect to.
2423
//
25-
// Install is idempotent: re-running it on a cluster with an existing
26-
// "longhorn" release in the longhorn-system namespace upgrades it in place
27-
// using the same Helm values.
24+
// On a fresh cluster, the iSCSI prerequisite DaemonSet is deployed and waited
25+
// on before the Helm install. On clusters with an existing release, the iSCSI
26+
// step is skipped (it was already provisioned on first install) and the Helm
27+
// release is upgraded in place.
28+
//
29+
// Install is idempotent: re-running on an installed cluster is a no-op modulo
30+
// any Config changes that would shift the rendered Helm values.
2831
func Install(ctx context.Context, kubeconfigBytes []byte, cfg *Config) error {
2932
tracer := otel.Tracer("nebari-infrastructure-core")
3033
ctx, span := tracer.Start(ctx, "longhorn.Install")
@@ -36,11 +39,6 @@ func Install(ctx context.Context, kubeconfigBytes []byte, cfg *Config) error {
3639
attribute.Bool("dedicated_nodes", cfg != nil && cfg.DedicatedNodes),
3740
)
3841

39-
if err := ensureISCSI(ctx, kubeconfigBytes); err != nil {
40-
span.RecordError(err)
41-
return fmt.Errorf("failed to install iSCSI prerequisites: %w", err)
42-
}
43-
4442
kubeconfigPath, cleanup, err := helm.WriteTempKubeconfig(kubeconfigBytes)
4543
if err != nil {
4644
span.RecordError(err)
@@ -62,12 +60,19 @@ func Install(ctx context.Context, kubeconfigBytes []byte, cfg *Config) error {
6260
histClient := action.NewHistory(actionConfig)
6361
histClient.Max = 1
6462
if _, err := histClient.Run(ReleaseName); err == nil {
63+
// Release exists — iSCSI was provisioned on initial install, so skip
64+
// the 3-minute DaemonSet readiness wait and go straight to upgrade.
6565
status.Send(ctx, status.NewUpdate(status.LevelInfo, "Longhorn already installed, upgrading").
6666
WithResource("longhorn").
6767
WithAction("upgrading"))
6868
return upgrade(ctx, actionConfig, cfg)
6969
}
7070

71+
if err := ensureISCSI(ctx, kubeconfigBytes); err != nil {
72+
span.RecordError(err)
73+
return fmt.Errorf("failed to install iSCSI prerequisites: %w", err)
74+
}
75+
7176
helmValues := buildHelmValues(cfg)
7277

7378
status.Send(ctx, status.NewUpdate(status.LevelProgress, "Installing Longhorn storage").
@@ -161,7 +166,7 @@ func loadChart(chartPathOptions action.ChartPathOptions) (*chart.Chart, error) {
161166
}
162167

163168
// buildHelmValues turns a Config into the values map passed to the Longhorn
164-
// Helm chart. Exported as helmValues() via BuildHelmValues for tests.
169+
// Helm chart.
165170
func buildHelmValues(cfg *Config) map[string]any {
166171
persistence := map[string]any{
167172
"defaultClass": true,
@@ -207,7 +212,3 @@ func buildHelmValues(cfg *Config) map[string]any {
207212

208213
return values
209214
}
210-
211-
// BuildHelmValues exposes buildHelmValues for cross-package tests that want
212-
// to assert the values map shape without actually running Helm.
213-
func BuildHelmValues(cfg *Config) map[string]any { return buildHelmValues(cfg) }

0 commit comments

Comments
 (0)