grafana / grafana/composables

feat(grafana): auto-generate plugin-sync sidecar in register_plugin()

Open
#16 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Starlark
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Summary

Every plugin repo using `register_plugin()` with a named-volume `dist` spec currently has to manually define an identical plugin-sync sidecar service in its `cc-docker-compose.yaml`. This is ~20 lines of boilerplate YAML that gets copy-pasted across repos. `register_plugin()` could auto-generate this service, eliminating the duplication.

## Current Pattern (repeated in every plugin repo)

Each plugin repo defines an Alpine sidecar in its compose file:

```yaml
services:
slo-plugin-sync:
image: alpine:latest
volumes:
- slo-plugin-dist:/dist
- ./dist:/src:ro
command:
- sh
- -c
- |
echo "Waiting for plugin build (plugin.json)..."
while [ ! -f /src/plugin.json ]; do sleep 2; done
echo "Plugin found, syncing files..."
cp -r /src/* /dist/
echo "Plugin synced successfully"
touch /tmp/healthy
echo "Watching for changes..."
while true; do sleep 5; cp -r /src/* /dist/ 2>/dev/null || true; done
healthcheck:
test: ['CMD', 'test', '-f', '/tmp/healthy']
interval: 5s
timeout: 3s
retries: 30
start_period: 300s

volumes:
slo-plugin-dist:
```

And then registers the plugin referencing the volume:

```python
grafana.register_plugin([{
'name': 'grafana-slo-app',
'dist': 'slo-plugin-dist:/var/lib/grafana/plugins/grafana-slo-app',
'depends_on': ['slo-plugin-sync'],
}])
```

This exact pattern is already duplicated in at least `grafana/slo` and `grafana/service-model` (byte-for-byte identical logic, just different volume/service names).

## Proposed Enhancement

When `register_plugin()` sees a named-volume `dist` spec (i.e., `volume-name:/path`), it could auto-generate the sync sidecar service, the named volume, and the `depends_on` entry. The plugin repo would only need:

```python
grafana.register_plugin([{
'name': 'grafana-slo-app',
'dist': 'slo-plugin-dist:/var/lib/grafana/plugins/grafana-slo-app',
'sync_source': './dist', # host path to sync from
}])
```

`register_plugin()` would then emit compose overrides containing:
1. A `{name}-plugin-sync` service definition (the Alpine sidecar)
2. The named volume declaration
3. A `depends_on` with `condition: service_healthy` on Grafana
4. The existing volume mount + provisioning file logic

### Why the sidecar exists

Docker Compose doesn't allow populating a named volume from a host bind-mount at startup. The sidecar bridges `./dist` (bind-mount) to the named volume that Grafana mounts. It also provides a 5-second polling loop for hot-reload during development.

### Opt-out

Repos with custom sync needs could still define their own sidecar and omit `sync_source`, falling back to today's behavior.

## Benefits

- Eliminates copy-paste boilerplate across plugin repos
- Centralizes the sync logic so improvements (e.g., `inotifywait` instead of polling, better error handling) propagate to all consumers
- New plugin repos adopting compose_composer don't need to understand or copy the sidecar pattern
- Reduces the surface area for subtle bugs (e.g., missing healthcheck, wrong start_period)

## Context

- `grafana/slo` cc-compose.yaml: `slo-plugin-sync` service
- `grafana/service-model` cc-docker-compose.yaml: `servicemodel-plugin-sync` service
- Both are functionally identical

Contributor guide

Open the contributing guide

Research direction

Start at register_plugin() and compare its current compose override and provisioning behavior with the sidecars in grafana/slo cc-compose.yaml and grafana/service-model cc-docker-compose.yaml. Trace how named-volume dist specs and depends_on are emitted. Done means sync_source generates the sidecar, volume, health-gated dependency, and existing mounts while omitting it when sync_source is absent.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker-compose, grafana
Domain
devops, infrastructure
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.