refactor: extract dereference/validate pipeline from reconcile_hive#707
Open
adwk67 wants to merge 17 commits into
Open
refactor: extract dereference/validate pipeline from reconcile_hive#707adwk67 wants to merge 17 commits into
adwk67 wants to merge 17 commits into
Conversation
Move external resource resolution (product image, S3 connection, metadata database, OPA config) into controller::dereference module with its own error enum. Extract config validation and merging into validate_cluster(), which produces a ValidatedHiveCluster proving all product-config validation succeeded before any Kubernetes resources are created. The validated struct owns the resolved product image and per-role/ per-rolegroup merged configs. Existing build functions are unchanged and receive their parameters from the validated structs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Member
Author
|
Jenkins: 🟢 (one failure on NS teardown) https://testing.stackable.tech/view/02%20Operator%20Tests%20(custom)/job/hive-operator-it-custom/52/ |
Rename FailedToResolveResourceConfig to FailedToResolveConfig and fix OPA error display string to match the convention used across all three dereference/validate extraction PRs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Image resolution is a pure computation, not an I/O dereference, so it belongs in validate_cluster alongside the other config validation. This aligns with the pattern used by the trino and airflow operators. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
siegfriedweber
requested changes
May 15, 2026
Co-authored-by: Siegfried Weber <mail@siegfriedweber.net>
…move derives where they do not exist on the upstream type
…pendency for subsequent steps
siegfriedweber
requested changes
May 19, 2026
Comment on lines
+53
to
+65
| /// Per-role configuration extracted during validation. | ||
| #[derive(Clone, Debug)] | ||
| pub struct ValidatedRoleConfig { | ||
| pub pdb: stackable_operator::commons::pdb::PdbConfig, | ||
| pub listener_class: String, | ||
| } | ||
|
|
||
| /// Per-rolegroup configuration: the merged CRD config plus the product-config properties. | ||
| #[derive(Clone, Debug)] | ||
| pub struct ValidatedRoleGroupConfig { | ||
| pub merged_config: MetaStoreConfig, | ||
| pub product_config_properties: HashMap<PropertyNameKind, BTreeMap<String, String>>, | ||
| } |
Member
There was a problem hiding this comment.
These validated structs could be moved to controller.rs next to ValidatedCluster. They belong together.
| metadata: | ||
| annotations: | ||
| listeners.stackable.tech/listener-name: hive-metastore | ||
| creationTimestamp: null |
Member
There was a problem hiding this comment.
The smoke tests fail:
case.go:401: failed in step 60-install-hive
case.go:403:
--- StatefulSet:test/hive-metastore-default
+++ StatefulSet:test/hive-metastore-default
@@ -7,8 +7,10 @@
app.kubernetes.io/managed-by: hive.stackable.tech_hivecluster
app.kubernetes.io/name: hive
app.kubernetes.io/role-group: default
+ app.kubernetes.io/version: 4.2.0-stackable0.0.0-dev
restarter.stackable.tech/enabled: "true"
stackable.tech/vendor: Stackable
+ managedFields: '[... elided field over 10 lines long ...]'
name: hive-metastore-default
namespace: test
ownerReferences:
@@ -16,9 +18,14 @@
controller: true
kind: HiveCluster
name: hive
+ uid: c7430cef-8300-4798-a3b0-8a18a5d46c14
spec:
+ persistentVolumeClaimRetentionPolicy:
+ whenDeleted: Retain
+ whenScaled: Retain
podManagementPolicy: Parallel
replicas: 1
+ revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/component: metastore
@@ -28,12 +35,16 @@
serviceName: hive-metastore-default-headless
template:
metadata:
+ annotations:
+ configmap.restarter.stackable.tech/hive-metastore-default: 77b8df79-2b13-41a9-942d-e49ea5232832/5052
+ secret.restarter.stackable.tech/hive-credentials: a1f650d3-3145-4617-88da-896d84f46a88/5044
labels:
app.kubernetes.io/component: metastore
app.kubernetes.io/instance: hive
app.kubernetes.io/managed-by: hive.stackable.tech_hivecluster
app.kubernetes.io/name: hive
app.kubernetes.io/role-group: default
+ app.kubernetes.io/version: 4.2.0-stackable0.0.0-dev
stackable.tech/vendor: Stackable
spec:
affinity:
@@ -130,6 +141,7 @@
value: group-value
- name: ROLE_VAR
value: role-value
+ image: oci.stackable.tech/sdp/hive:4.2.0-stackable0.0.0-dev
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
@@ -162,6 +174,8 @@
requests:
cpu: 250m
memory: 768Mi
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
volumeMounts:
- mountPath: /stackable/secrets/test-hive-s3-secret-class
name: test-hive-s3-secret-class-s3-credentials
@@ -181,6 +195,8 @@
enableServiceLinks: false
restartPolicy: Always
schedulerName: default-scheduler
+ securityContext:
+ fsGroup: 1000
serviceAccount: hive-serviceaccount
serviceAccountName: hive-serviceaccount
terminationGracePeriodSeconds: 300
@@ -204,6 +220,7 @@
volumeClaimTemplate:
metadata:
annotations:
+ secrets.stackable.tech/class: opa-tls-test
secrets.stackable.tech/provision-parts: public
spec:
accessModes:
@@ -228,13 +245,16 @@
defaultMode: 420
name: hive-metastore-default
name: log-config-mount
+ updateStrategy:
+ rollingUpdate:
+ partition: 0
+ type: RollingUpdate
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
listeners.stackable.tech/listener-name: hive-metastore
- creationTimestamp: null
labels:
app.kubernetes.io/component: metastore
app.kubernetes.io/instance: hive
@@ -252,7 +272,16 @@
storage: "1"
storageClassName: listeners.stackable.tech
volumeMode: Filesystem
+ status:
+ phase: Pending
status:
+ availableReplicas: 1
+ collisionCount: 0
+ currentReplicas: 1
+ currentRevision: hive-metastore-default-57c74d49fd
+ observedGeneration: 1
readyReplicas: 1
replicas: 1
-
+ updateRevision: hive-metastore-default-57c74d49fd
+ updatedReplicas: 1
+
case.go:403: resource StatefulSet:test/hive-metastore-default: .spec.volumeClaimTemplates.metadata.creationTimestamp: key is missing from map
logger.go:42: 14:10:59 | smoke_postgres-12.5.6_hive-4.2.0_opa-latest-1.12.3_openshift-false_s3-use-tls-false_opa-use-tls-true | skipping kubernetes event logging
=== NAME kuttl
harness.go:407: run tests finished
harness.go:515: cleaning up
harness.go:572: removing temp folder: ""
--- FAIL: kuttl (972.33s)
--- FAIL: kuttl/harness (0.00s)
--- FAIL: kuttl/harness/smoke_postgres-12.5.6_hive-4.2.0_opa-latest-1.12.3_openshift-false_s3-use-tls-false_opa-use-tls-true (972.32s)
Member
There was a problem hiding this comment.
The creationTimestamp is not set in my k3s cluster.
Client Version: v1.34.3
Kustomize Version: v5.7.1
Server Version: v1.34.5+k3s1
Can we remove it?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Clone,Debug,Eq,Hash,Ord,PartialEq,PartialOrdonHiveRoleso it can be used as aBTreeMapkey and in validated structscontroller::dereferencemodule with its own Snafu error enumvalidate_cluster(), producing aValidatedHiveClusterstruct that proves all validation succeeded before any Kubernetes resources are createdValidatedHiveClusterowns the resolved product image and per-role/per-rolegroup merged configs; existing build functions are unchanged and receive parameters from the validated structsReviewer notes
dereference()andvalidate_cluster()contain no new logic — they are pure extractions of code that was previously inline inreconcile_hive()ValidatedHiveClusterstruct intentionally has fewer fields than a full ownership model would (noname/namespace/uid/metadatavalidated types). This is a "construct but decompose" fail-fast gate: built early in reconcile to prove validation passes, then its fields feed the existing unchanged build functionscontroller/directory coexists withcontroller.rs— Rust treatscontroller.rsas the module root and looks for submodules incontroller/. Currently justdereference, withvalidateand further stages to follow in later PRsDereferencewrapper variant in the controller'sErrorenum replaces 3 individual error variants (ResolveProductImage,InvalidOpaConfig,InvalidMetadataDatabaseConnection) that moved into the new module's own error enum.ConfigureS3ConnectionandObjectHasNoNamespaceremain in the controller because they are still used by build functionsTest plan
🤖 Generated with Claude Code