Introduce a commercial license option alongside AGPL-3.0-only, require a CLA for contributors, and document the terms in COMMERCIAL.md and NOTICE. Add a script to stamp SPDX headers on Go files and apply it across the tree.
87 lines
3.6 KiB
Go
87 lines
3.6 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
|
|
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/db"
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/domains"
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/integration"
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/integrations"
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/systemtenant"
|
|
)
|
|
|
|
// ensureBootDataState performs the data-state work `start` does after
|
|
// migrations and before serving, and `seed-demo` does before seeding, so a
|
|
// database that was reset, migrated, and reseeded (test/reset-app-db.sh,
|
|
// the screen-capture utility's first step) holds exactly what a booted
|
|
// deployment holds:
|
|
//
|
|
// - every installed integration's provider record, after its key is
|
|
// checked against its manifest (integration-registration);
|
|
// - the System tenant (system-tenant);
|
|
// - expired pending domain claims swept (claim-expiry-and-carve-guards
|
|
// D1/D3): core registry work with no integration in it, run BEFORE the
|
|
// reconciliation below because a stranded pending external claim at a
|
|
// configured farm domain is exactly what makes EnsureOperatorRoot fail;
|
|
// logged, not fatal, since an unswept claim holds one name where an
|
|
// unensurable root leaves every hosted name unallocatable;
|
|
// - monthly RANGE partitions for core.webhook_events for the months ahead
|
|
// (webhook-partition-maintenance); logged, not fatal;
|
|
// - each integration's domains reconciliation (design D8): operator roots
|
|
// ensured from deployment configuration and placements backfilled for
|
|
// resources that predate the registry. Unconditional, not an
|
|
// integration's Startup hook, which runs only when Temporal is
|
|
// configured. Fatal: a registry that does not fit the deployment's own
|
|
// namespace configuration is a misconfiguration.
|
|
func ensureBootDataState(ctx context.Context, database *sql.DB, logger *slog.Logger, integs []integrations.Integration) error {
|
|
providerSources := make([]integration.ProviderSource, 0, len(integs))
|
|
for _, integ := range integs {
|
|
ps := integ.Provider()
|
|
if err := integration.AssertKeyMatch(integ.Key(), ps.ProviderManifest()); err != nil {
|
|
return fmt.Errorf("integration key mismatch: %w", err)
|
|
}
|
|
providerSources = append(providerSources, ps)
|
|
}
|
|
if err := integration.RegisterProviders(ctx, database, providerSources); err != nil {
|
|
return fmt.Errorf("register providers: %w", err)
|
|
}
|
|
|
|
if _, err := systemtenant.Ensure(ctx, database); err != nil {
|
|
return fmt.Errorf("ensure system tenant: %w", err)
|
|
}
|
|
|
|
if result, err := domains.NewRegistry(database).SweepExpiredClaims(ctx); err != nil {
|
|
logger.Error("domain claim expiry sweep failed",
|
|
slog.Int("candidates", result.Candidates),
|
|
slog.Int("expired", result.Expired),
|
|
slog.Int("failed", result.Failed),
|
|
slog.Any("error", err))
|
|
} else if result.Candidates > 0 {
|
|
logger.Info("domain claim expiry sweep completed",
|
|
slog.Int("candidates", result.Candidates),
|
|
slog.Int("expired", result.Expired))
|
|
}
|
|
|
|
if err := db.EnsureWebhookEventPartitions(ctx, database, time.Now(), db.DefaultWebhookPartitionMonthsAhead); err != nil {
|
|
logger.Warn("webhook_events partition ensure failed", slog.Any("error", err))
|
|
}
|
|
|
|
for _, integ := range integs {
|
|
dr, ok := integ.(domainsReconciler)
|
|
if !ok {
|
|
continue
|
|
}
|
|
if err := dr.ReconcileDomains(ctx, database, logger); err != nil {
|
|
return fmt.Errorf("reconcile domains registry for %s: %w", integ.Key(), err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|