fix(setup): CompleteAsNode idempotent — konvertiert Standalone zu Cluster-Node
Wenn setup bereits abgeschlossen war (z.B. zuvor als Standalone eingerichtet), wird der Node jetzt ohne Fehler auf is_cluster_node=true umgestellt statt mit "setup already completed" zu fehlschlagen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -168,6 +168,10 @@ func (s *Store) Complete(req Request) (*State, error) {
|
||||
// CompleteAsNode configures this node as a secondary cluster member.
|
||||
// No admin credentials are created; login becomes available after PG
|
||||
// replication brings users from the primary.
|
||||
//
|
||||
// Idempotent: if setup was already completed (e.g. the node was
|
||||
// previously configured as standalone), it is converted to cluster-node
|
||||
// mode. Calling again after a successful join is a no-op.
|
||||
func (s *Store) CompleteAsNode(req NodeRequest) (*State, error) {
|
||||
if !looksLikeFQDN(req.FQDN) {
|
||||
return nil, fmt.Errorf("fqdn %q does not look like a fully-qualified hostname", req.FQDN)
|
||||
@@ -179,16 +183,22 @@ func (s *Store) CompleteAsNode(req NodeRequest) (*State, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if prev.Completed {
|
||||
return nil, errors.New("setup already completed")
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
completedAt := &now
|
||||
if prev.CompletedAt != nil {
|
||||
completedAt = prev.CompletedAt
|
||||
}
|
||||
st := &State{
|
||||
FQDN: strings.TrimSpace(req.FQDN),
|
||||
ACMEEmail: strings.ToLower(strings.TrimSpace(req.ACMEEmail)),
|
||||
IsClusterNode: true,
|
||||
Completed: true,
|
||||
CompletedAt: &now,
|
||||
CompletedAt: completedAt,
|
||||
// Carry over non-auth fields from previous state.
|
||||
LicenseKey: prev.LicenseKey,
|
||||
IPv6Enabled: prev.IPv6Enabled,
|
||||
BackupRetentionKeep: prev.BackupRetentionKeep,
|
||||
AuditRetentionDays: prev.AuditRetentionDays,
|
||||
}
|
||||
if err := s.Save(st); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user