Skip to content

feat(plugin): wire on_instance_spawn hook (CLI + daemon) - #60

Merged
ademboukabes merged 4 commits into
developfrom
feat/plugin-instance-spawn-hook
Oct 13, 2026
Merged

ademboukabes merged 4 commits into
developfrom
feat/plugin-instance-spawn-hook

Conversation

@ademboukabes

Copy link
Copy Markdown
Collaborator

Summary

Closes #40.

Wires the on_instance_spawn lifecycle hook into both spawn paths across the CLI and daemon:

  • CLI command: mctf instance spawn (cmd/instance.go)
  • HTTP instancer daemon: POST /spawn (internal/instancer/server.go + cmd/instancer.go)

What changed

  1. Protocol & Payload (internal/plugin/):

    • Defined HookOnInstanceSpawn = "on_instance_spawn".
    • Defined typed InstanceSpawnPayload struct containing: event, instance_id, challenge_slug, team_id, ports, flag, containers, and expires_at.
    • Extended TestHelperProcess in internal/plugin/plugin_test.go to handle on_instance_spawn.
    • Added unit test TestManager_InstanceSpawnHookDelivered verifying payload delivery and serialization over JSON-RPC.
  2. CLI Wiring (cmd/instance.go):

    • In instanceSpawnCmd, initialized one-shot plugin.Manager with plugin.Load(...) and deferred pm.Close().
    • Dispatched on_instance_spawn after instance creation and store persistence (instStore.Put(inst)).
    • Added instanceSpawnPayload helper to map instancer.Instance into plugin.InstanceSpawnPayload.
    • Added comprehensive unit tests in cmd/instance_plugin_test.go.
  3. HTTP Daemon Wiring (internal/instancer/server.go & cmd/instancer.go):

    • Added PluginManager *plugin.Manager to instancer.Options and attached persistent pm *plugin.Manager to instancer.Server.
    • Dispatched on_instance_spawn within s.spawn handler immediately following store persistence (s.store.Put(inst)).
    • Added Server.Close() to ensure graceful termination of plugin subprocesses on server shutdown.
    • Wired plugin loading and shutdown into daemon startup (cmd/instancer.go).
    • Maintained persistent plugin manager lifecycle (loaded once on daemon startup, reused across all requests, no per-request fork/exec penalty).
    • Added end-to-end integration test TestServer_Spawn_DispatchesPluginHook in internal/instancer/server_test.go.
  4. Crash Isolation:

    • Both CLI and daemon paths guarantee crash isolation: plugin failures, crashes, or timeouts are logged to stderr and dropped, never blocking or aborting instance creation.
  5. Documentation & Reference Plugin:

    • Updated docs/spec/plugins.md marking on_instance_spawn as shipped with JSON schema and field descriptions.
    • Updated examples/sample-event/plugins/logger.sh to subscribe to and log on_instance_spawn.
    • Updated docs/BACKLOG.md tracking.

Verification

  • golangci-lint run ./... & go vet ./... ✅ (0 issues)
  • go test -race ./... ✅ (100% tests pass, including plugin, CLI, and instancer daemon tests)
  • make build ✅
  • ./mctf -C examples/sample-event validate ✅
  • ./mctf -C examples/sample-event generate --check ✅

- Add HookOnInstanceSpawn constant in protocol.go.
- Define InstanceSpawnPayload struct matching instancer.Instance fields.
- Update TestHelperProcess and add TestManager_InstanceSpawnHookDelivered test.
- Dispatch on_instance_spawn after store.Put in instanceSpawnCmd.
- Add instanceSpawnPayload helper and unit tests in cmd/instance_plugin_test.go.
- Add PluginManager field to instancer.Options and Server.
- Dispatch on_instance_spawn after store.Put in Server.spawn handler.
- Add Server.Close method to terminate plugin subprocesses.
- Wire PluginManager loading and clean shutdown in cmd/instancer.go.
- Add TestServer_Spawn_DispatchesPluginHook integration test.
@ademboukabes
ademboukabes force-pushed the feat/plugin-instance-spawn-hook branch from f93b0dd to d6a1d47 Compare October 13, 2026 19:57
@ademboukabes
ademboukabes merged commit 0f97a73 into develop Oct 13, 2026
3 checks passed
@ademboukabes
ademboukabes deleted the feat/plugin-instance-spawn-hook branch October 13, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant