MCPcopy Index your code
hub / github.com/coder/coder / SeedAIProvidersFromEnv

Function SeedAIProvidersFromEnv

coderd/ai_providers_migrate.go:43–212  ·  view source on GitHub ↗

SeedAIProvidersFromEnv reconciles the deployment's environment- derived AI provider configuration with rows in the ai_providers table at server startup. Concurrent server starts are serialized via a Postgres advisory lock; rows that already exist with a matching canonical hash are left alone, missin

(
	ctx context.Context,
	db database.Store,
	cfg codersdk.AIBridgeConfig,
	logger slog.Logger,
)

Source from the content-addressed store, hash-verified

41//
42// Audit entries are recorded via the system actor for any inserts.
43func SeedAIProvidersFromEnv(
44 ctx context.Context,
45 db database.Store,
46 cfg codersdk.AIBridgeConfig,
47 logger slog.Logger,
48) error {
49 desired, err := providersFromEnv(ctx, cfg, logger)
50 if err != nil {
51 return xerrors.Errorf("compute providers from env: %w", err)
52 }
53 if len(desired) == 0 {
54 return nil
55 }
56
57 // Audit entries are attributed to the deployment rather than a user.
58 //nolint:gocritic // server startup, no user actor available
59 sysCtx := dbauthz.AsSystemRestricted(ctx)
60
61 // Collect inserted rows inside the transaction and emit audit
62 // entries only after the transaction commits. The auditor writes
63 // through the outer db handle, so emitting inside InTx would leave
64 // phantom audit rows if the transaction later rolls back.
65 var (
66 insertedProviders []database.AIProvider
67 insertedKeys []database.AIProviderKey
68 )
69
70 err = db.InTx(func(tx database.Store) error {
71 insertedProviders = insertedProviders[:0]
72 insertedKeys = insertedKeys[:0]
73
74 // Acquire the advisory lock. The lock is released when the
75 // transaction ends.
76 if err := tx.AcquireLock(sysCtx, database.LockIDAIProvidersEnvSeed); err != nil {
77 return xerrors.Errorf("acquire ai providers env seed lock: %w", err)
78 }
79
80 // Load every provider (including soft-deleted and disabled rows)
81 // once so we can decide insert vs. skip vs. drift per desired
82 // row without a query per name.
83 all, err := tx.GetAIProviders(sysCtx, database.GetAIProvidersParams{
84 IncludeDeleted: true,
85 IncludeDisabled: true,
86 })
87 if err != nil {
88 return xerrors.Errorf("load ai providers: %w", err)
89 }
90 // Prefer the live row when a soft-deleted row shares its name.
91 byName := make(map[string]database.AIProvider, len(all))
92 for _, row := range all {
93 if existing, ok := byName[row.Name]; ok && !existing.Deleted && row.Deleted {
94 continue
95 }
96 byName[row.Name] = row
97 }
98
99 for _, dp := range desired {
100 settings, err := encodeAIProviderSettings(codersdk.AIProviderSettings{Bedrock: dp.Bedrock})

Callers 3

buildFromEnvFunction · 0.92
ServerMethod · 0.92

Calls 15

canonicalMethod · 0.95
AsSystemRestrictedFunction · 0.92
AIProviderSettingsFunction · 0.92
NowFunction · 0.92
providersFromEnvFunction · 0.85
encodeAIProviderSettingsFunction · 0.85
computeProviderHashFunction · 0.85
InTxMethod · 0.65
AcquireLockMethod · 0.65
GetAIProvidersMethod · 0.65
InsertAIProviderMethod · 0.65

Tested by 2

buildFromEnvFunction · 0.74