Files
zeekay 6de27ba73b feat: nchain — composable blockchain node infrastructure operator
7 CRDs (nchain.hanzo.ai/v1alpha1):
  - NodeCluster: protocol-agnostic blockchain node cluster
  - Chain: blockchain/subnet/L2 definition
  - Indexer: blockchain data indexer
  - Explorer: block explorer UI+API
  - Bridge: cross-chain bridge
  - Gateway: RPC/API gateway with routing + rate limiting
  - Network: top-level composer (creates all child CRDs)

Protocol driver architecture:
  - LuxDriver: full luxd flag generation, snow consensus, staking keys,
    snapshot restore, chain tracking, startup scripting (487 lines)
  - EthereumDriver: reth command generation, standard EVM ports
  - GenericDriver: passthrough for any containerized node

Key design principles:
  - Composable: each CRD stands alone or composes via Network
  - Orthogonal: validators, indexers, explorers, bridges, gateways
    are independent concerns with independent CRDs
  - Complete: covers the full lifecycle from bootstrap to production
  - Protocol-agnostic: driver pattern isolates blockchain-specific logic
  - Do everything exactly once: one way to manage any blockchain

Replaces both HanzoNetwork (hanzo-operator) and LuxNetwork (lux-operator)
with a unified, deeper, protocol-agnostic alternative.

6,215 lines Go | go build + go vet clean
2026-03-03 06:43:22 -08:00

50 lines
1.2 KiB
Go

package status
import (
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/hanzoai/nchain/api/v1alpha1"
)
// SetCondition upserts a condition by type. If an existing condition of the
// same type is found and its status or reason differs, the condition is
// updated. Otherwise, a new condition is appended.
func SetCondition(
conditions *[]metav1.Condition,
condType string,
status metav1.ConditionStatus,
reason, message string,
) {
now := metav1.NewTime(time.Now())
for i, c := range *conditions {
if c.Type == condType {
if c.Status != status || c.Reason != reason {
(*conditions)[i].Status = status
(*conditions)[i].Reason = reason
(*conditions)[i].Message = message
(*conditions)[i].LastTransitionTime = now
}
return
}
}
*conditions = append(*conditions, metav1.Condition{
Type: condType,
Status: status,
Reason: reason,
Message: message,
LastTransitionTime: now,
})
}
// IsReady returns true when a "Ready" condition with status True exists.
func IsReady(conditions []metav1.Condition) bool {
for _, c := range conditions {
if c.Type == v1alpha1.ConditionTypeReady {
return c.Status == metav1.ConditionTrue
}
}
return false
}