package deployer import ( "context" "fmt" "github.com/alexei/tinyforge/internal/workload/plugin" ) // DispatchPlugin routes a DeploymentIntent for w to the matching Source // plugin. This is the new unified deploy path; the legacy executeDeploy // remains in place until Phase 6 ports image-deploy logic into // source/image. While both exist, callers must pick: webhook/registry // triggers + image deploys still go through the legacy path, while // /api/hooks/generic + the unified webhook ingress go through here. func (d *Deployer) DispatchPlugin(ctx context.Context, w plugin.Workload, intent plugin.DeploymentIntent) error { src, err := plugin.GetSource(w.SourceKind) if err != nil { return fmt.Errorf("dispatch %s: %w", w.Name, err) } return src.Deploy(ctx, d.PluginDeps(), w, intent) } // DispatchTeardown routes a teardown call to the matching Source plugin. // Used when a workload is deleted. func (d *Deployer) DispatchTeardown(ctx context.Context, w plugin.Workload) error { src, err := plugin.GetSource(w.SourceKind) if err != nil { return fmt.Errorf("dispatch teardown %s: %w", w.Name, err) } return src.Teardown(ctx, d.PluginDeps(), w) } // DispatchReconcile routes a Reconcile call. Periodic reconciler iterates // every Workload and calls this; idle Sources should make it a cheap // no-op. func (d *Deployer) DispatchReconcile(ctx context.Context, w plugin.Workload) error { src, err := plugin.GetSource(w.SourceKind) if err != nil { return fmt.Errorf("dispatch reconcile %s: %w", w.Name, err) } return src.Reconcile(ctx, d.PluginDeps(), w) } // PluginDeps captures the Deployer's existing dependencies in the bundle // shape Sources expect. Reads d.dns under the RWMutex since proxy/DNS // can be hot-swapped at runtime when settings change. Exported so the // API layer can hand the same Deps to Trigger.Match — passing zero-Deps // to triggers would silently nil-panic the moment any Trigger touches // deps.Store / deps.Crypto for signature verification. func (d *Deployer) PluginDeps() plugin.Deps { d.dnsMu.RLock() dnsProvider := d.dns d.dnsMu.RUnlock() return plugin.Deps{ Store: d.store, Docker: d.docker, Proxy: d.proxy, DNS: dnsProvider, Health: d.health, Notifier: d.notifier, Events: d.eventBus, EncKey: d.encKey, } }