ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/missionmatch / cmd/migrate-all-tenants/main.go

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/missionmatch / cmd/migrate-all-tenants/main.go
DateNot specified in source
RepositoryJanady13/missionmatch
Revision2178e7298d0e5d9af83afa12402fd587f0ba6ed8
Branchfeature/aioe-upgrade
Path or archive membercmd/migrate-all-tenants/main.go
Original SHA-2566342d6fc0912c24267237b52df2c406dee8d3efa872c56b305aaee8f6d82de32
Git blob SHA77ecd8cfcc1d5cdeb0c073c39d56ce44376d9e9b
Reading-copy SHA-2566342d6fc0912c24267237b52df2c406dee8d3efa872c56b305aaee8f6d82de32

Original source ↗

Every recorded occurrence

These 5 records contain identical original source bytes. Their paths and revisions remain part of the archive.

Original recordBranch or archiveRevision / identifierOriginal location
Janady13/missionmatch / cmd/migrate-all-tenants/main.gofeature/aioe-upgrade2178e7298d0e5d9af83afa12402fd587f0ba6ed8Open original
Janady13/missionmatch / cmd/migrate-all-tenants/main.goper-tenant-routing9bde0f9a74b89d01980fa658e5253acda7528d0cOpen original
Janady13/missionmatch / cmd/migrate-all-tenants/main.godeploy-and-opsbdacd9d0b4d5998d25fc74bf4007f4c3ec538c7aOpen original
Janady13/missionmatch / cmd/migrate-all-tenants/main.goper-tenant-routing9bde0f9a74b89d01980fa658e5253acda7528d0cOpen original
Janady13/missionmatch / cmd/migrate-all-tenants/main.gofeature/aioe-upgrade2178e7298d0e5d9af83afa12402fd587f0ba6ed8Open original

Recovered source transcript

// Command migrate-all-tenants applies the migration set to the control plane database AND to every active // tenant database in the database per tenant model. It reads the tenant directory in the control plane to // discover the tenant databases, then for each target applies BOTH the public schema migrations and the // segregated eeo migrations (two separate goose version tables), so a tenant database can never drift one // schema relative to the other. // // It is a migrator role operator tool (it needs BYPASSRLS to write the directory bookkeeping and to run // DDL). It is idempotent and resumable: goose records applied versions, so a re run is a no op on a // healthy database. The failure surface is hard: it records which database errored or is behind, keeps // going to the rest, and exits non zero if ANY database failed or is still behind head, so a partial fan // out can never report success. // // Two modes: // // migrate-all-tenants apply pending migrations to the control plane and every active tenant // migrate-all-tenants -check dry run: report each database's version and whether it is behind, NO writes // // It uses the per instance goose Provider (NOT the process global goose API, whose SetBaseFS and // SetTableName state would race and cross contaminate the public versus eeo table name across N databases // and under concurrency, the pressly/goose multi database guidance), and a Postgres session locker so two // operators (or a concurrent provision-tenant) cannot migrate the same database at once. package main import ( "context" "database/sql" "flag" "fmt" "io/fs" "log" "os" "sort" "sync" "time" "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" _ "github.com/jackc/pgx/v5/stdlib" goose "github.com/pressly/goose/v3" goosedb "github.com/pressly/goose/v3/database" gooselock "github.com/pressly/goose/v3/lock" "golang.org/x/sync/errgroup" dbembed "github.com/missionworkforce/missionmatch/db" "github.com/missionworkforce/missionmatch/internal/platform/database" "github.com/missionworkforce/missionmatch/internal/platform/directory" ) type target struct { name string // human label (control plane, or the tenant database name) dsn string // migrator DSN to this database org *uuid.UUID // nil for the control plane; set for a tenant (to record bookkeeping) } type result struct { name string pubVersion int64 eeoVersion int64 pending bool // dry run: any pending migration appliedPub int appliedEEO int err error } func main() { controlDSN := flag.String("control-dsn", os.Getenv("MM_MIGRATOR_DATABASE_URL"), "migrator DSN to the control plane database (defaults to MM_MIGRATOR_DATABASE_URL)") check := flag.Bool("check", false, "dry run: report each database's version and whether it is behind, make no changes") concurrency := flag.Int("concurrency", 1, "migrate up to N databases at once (distinct databases only)") flag.Parse() if *controlDSN == "" { log.Fatal("migrate-all-tenants: -control-dsn (or MM_MIGRATOR_DATABASE_URL) is required") } if *concurrency < 1 { *concurrency = 1 } ctx := context.Background() // The control plane pool: it must be the BYPASSRLS migrator so it can read the directory and run DDL. pool, err := pgxpool.New(ctx, *controlDSN) if err != nil { log.Fatalf("migrate-all-tenants: control plane pool: %v", err) } defer pool.Close() if err := database.AssertMigratorRole(ctx, pool); err != nil { log.Fatalf("migrate-all-tenants: %v", err) } dir := directory.New(pool) // Targets: the control plane first (the foundation), then every active tenant database. A tenant DSN // reuses the migrator credential and swaps only the database name (the migrator is a cluster role). targets := []target{{name: "control plane", dsn: *controlDSN, org: nil}} tenants, err := dir.List(ctx, directory.StatusActive) if err != nil { log.Fatalf("migrate-all-tenants: list tenants: %v", err) } for _, t := range tenants { org := t.OrganizationID targets = append(targets, target{name: t.DBName, dsn: swapDB(*controlDSN, t.DBName), org: &org}) } log.Printf("migrate-all-tenants: %d targets (control plane + %d active tenants), check=%v concurrency=%d", len(targets), len(tenants), *check, *concurrency) results := make([]result, len(targets)) var g errgroup.Group g.SetLimit(*concurrency) var mu sync.Mutex // guards the directory bookkeeping writes for i := range targets { i := i g.Go(func() error { r := migrateOne(ctx, targets[i], *check) results[i] = r // Record the applied version in the directory for a tenant that advanced (apply mode only). if !*check && r.err == nil && targets[i].org != nil { mu.Lock() if e := dir.SetMigrated(ctx, *targets[i].org, r.pubVersion); e != nil { log.Printf("migrate-all-tenants: WARNING could not record migration bookkeeping for %s: %v", targets[i].name, e) } mu.Unlock() } return nil // never abort the group on one database; the summary and exit code carry the verdict }) } _ = g.Wait() // Summary and a hard exit code. failed, behind := report(results, *check) if failed > 0 || (*check && behind > 0) { os.Exit(1) } } // migrateOne applies (or, in check mode, inspects) the two migration sets on one database using per // instance goose Providers and a session lock. func migrateOne(ctx context.Context, t target, check bool) result { r := result{name: t.name} sqlDB, err := sql.Open("pgx", t.dsn) if err != nil { r.err = fmt.Errorf("open: %w", err) return r } defer func() { _ = sqlDB.Close() }() sqlDB.SetMaxOpenConns(5) sqlDB.SetConnMaxLifetime(5 * time.Minute) locker, err := gooselock.NewPostgresSessionLocker() if err != nil { r.err = fmt.Errorf("locker: %w", err) return r } pubFS, err := fs.Sub(dbembed.Migrations, "migrations") if err != nil { r.err = err return r } pub, err := goose.NewProvider(goose.DialectPostgres, sqlDB, pubFS, goose.WithSessionLocker(locker)) if err != nil { r.err = fmt.Errorf("public provider: %w", err) return r } defer func() { _ = pub.Close() }() eeoStore, err := goosedb.NewStore(goosedb.DialectPostgres, "goose_db_version_eeo") if err != nil { r.err = fmt.Errorf("eeo store: %w", err) return r } eeoFS, err := fs.Sub(dbembed.EEOMigrations, "migrations_eeo") if err != nil { r.err = err return r } // Empty dialect because the table name is carried by the custom store. eeo, err := goose.NewProvider("", sqlDB, eeoFS, goose.WithStore(eeoStore), goose.WithSessionLocker(locker)) if err != nil { r.err = fmt.Errorf("eeo provider: %w", err) return r } defer func() { _ = eeo.Close() }() if check { pubPending, e1 := pub.HasPending(ctx) eeoPending, e2 := eeo.HasPending(ctx) if e1 != nil || e2 != nil { r.err = firstErr(e1, e2) return r } r.pending = pubPending || eeoPending r.pubVersion, _ = pub.GetDBVersion(ctx) r.eeoVersion, _ = eeo.GetDBVersion(ctx) return r } // Apply public then eeo, so the public foundation exists before the segregated eeo schema. rp, err := pub.Up(ctx) if err != nil { r.err = fmt.Errorf("public migrations: %w", err) return r } re, err := eeo.Up(ctx) if err != nil { r.err = fmt.Errorf("eeo migrations: %w", err) return r } r.appliedPub, r.appliedEEO = len(rp), len(re) r.pubVersion, _ = pub.GetDBVersion(ctx) r.eeoVersion, _ = eeo.GetDBVersion(ctx) return r } // report prints a per database table and returns how many failed and how many are behind. func report(results []result, check bool) (failed, behind int) { sorted := append([]result(nil), results...) sort.SliceStable(sorted, func(i, j int) bool { return sorted[i].name < sorted[j].name }) log.Printf("migrate-all-tenants: results") for _, r := range sorted { switch { case r.err != nil: failed++ log.Printf(" FAILED %-28s public=v%d eeo=v%d %v", r.name, r.pubVersion, r.eeoVersion, r.err) case check && r.pending: behind++ log.Printf(" BEHIND %-28s public=v%d eeo=v%d (has pending migrations)", r.name, r.pubVersion, r.eeoVersion) case check: log.Printf(" OK %-28s public=v%d eeo=v%d (at head)", r.name, r.pubVersion, r.eeoVersion) default: log.Printf(" APPLIED %-28s public=v%d (+%d) eeo=v%d (+%d)", r.name, r.pubVersion, r.appliedPub, r.eeoVersion, r.appliedEEO) } } if failed > 0 { log.Printf("migrate-all-tenants: %d database(s) FAILED", failed) } if check && behind > 0 { log.Printf("migrate-all-tenants: %d database(s) BEHIND head", behind) } if failed == 0 && behind == 0 { log.Printf("migrate-all-tenants: all databases OK") } return failed, behind } func firstErr(errs ...error) error { for _, e := range errs { if e != nil { return e } } return nil } // swapDB reuses a migrator DSN and swaps only the database name, so a tenant database is reached with the // same migrator credential (the migrator is a cluster role). Mirrors the helper in cmd/provision-tenant. func swapDB(dsn, name string) string { cfg, err := pgx.ParseConfig(dsn) if err != nil { return dsn } out := fmt.Sprintf("host=%s port=%d user=%s dbname=%s", cfg.Host, cfg.Port, cfg.User, name) if cfg.Password != "" { out += " password=" + cfg.Password } if cfg.TLSConfig == nil { out += " sslmode=disable" } return out }

Search equations, builds, manuscript text, and recovered sources.