This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / spindle / startup_migrations.go
2.3 kB 80 lines
1package spindle 2 3import ( 4 "context" 5 "database/sql" 6 "fmt" 7 "log/slog" 8 9 "tangled.org/core/orm" 10 "tangled.org/core/spindle/db" 11 "tangled.org/core/spindle/secrets" 12) 13 14func runStartupMigrations(ctx context.Context, d *db.DB, vault secrets.Manager, logger *slog.Logger) error { 15 conn, err := d.DB.Conn(ctx) 16 if err != nil { 17 return fmt.Errorf("acquire spindle conn: %w", err) 18 } 19 defer conn.Close() 20 21 return orm.RunMigration(conn, logger, "copy-owner-rkey-secrets-to-repo-did", func(tx *sql.Tx) error { 22 return copyOwnerRkeySecretsToRepoDid(ctx, tx, vault, logger) 23 }) 24} 25 26type repoSecretPair struct { 27 oldID, newID secrets.RepoIdentifier 28} 29 30func loadRepoSecretPairs(ctx context.Context, tx *sql.Tx) ([]repoSecretPair, error) { 31 rows, err := tx.QueryContext(ctx, 32 `select owner, rkey, repo_did from repos 33 where repo_did is not null and repo_did <> ''`, 34 ) 35 if err != nil { 36 return nil, fmt.Errorf("select repos: %w", err) 37 } 38 defer rows.Close() 39 40 var collect func(acc []repoSecretPair) ([]repoSecretPair, error) 41 collect = func(acc []repoSecretPair) ([]repoSecretPair, error) { 42 if !rows.Next() { 43 return acc, rows.Err() 44 } 45 var owner, rkey, repoDid string 46 if err := rows.Scan(&owner, &rkey, &repoDid); err != nil { 47 return acc, fmt.Errorf("scan repos row: %w", err) 48 } 49 return collect(append(acc, repoSecretPair{ 50 oldID: secrets.RepoIdentifier(owner + "/" + rkey), 51 newID: secrets.RepoIdentifier(repoDid), 52 })) 53 } 54 return collect(nil) 55} 56 57func copyOwnerRkeySecretsToRepoDid(ctx context.Context, tx *sql.Tx, vault secrets.Manager, logger *slog.Logger) error { 58 pairs, err := loadRepoSecretPairs(ctx, tx) 59 if err != nil { 60 return err 61 } 62 63 var step func(remaining []repoSecretPair, totalCopied int) error 64 step = func(remaining []repoSecretPair, totalCopied int) error { 65 if len(remaining) == 0 { 66 logger.Info("secret copy migration complete", "rows", len(pairs), "copied", totalCopied) 67 return nil 68 } 69 p := remaining[0] 70 n, err := copyRepoSecrets(ctx, vault, p.oldID, p.newID) 71 if err != nil { 72 return fmt.Errorf("copy %s -> %s: %w", p.oldID, p.newID, err) 73 } 74 if n > 0 { 75 logger.Info("secrets copied", "old", p.oldID, "new", p.newID, "count", n) 76 } 77 return step(remaining[1:], totalCopied+n) 78 } 79 return step(pairs, 0) 80}