grizzly icon indicating copy to clipboard operation
grizzly copied to clipboard

Failed to manifest dashboard when modifying lib

Open wilfriedroset opened this issue 10 months ago • 7 comments

Grizzly Version

0.6.1

Expected Behavior

Dashboards manifestion works without error when any of the files in the watchList are modified.

Actual Behavior

Users might want to create reusable lib. As such they will start grizzly and watch several path. This is similar to what is documented here https://grafana.github.io/grizzly/server/, this is also what is done in [grafonnet examples(https://github.com/grafana/grafonnet/tree/main/examples/redMethod). Depending on what you are work on, user could edit either the dashboard itself or the underlying reusable lib. However when grizzly detect a change in the underlying lib the manifestion fails

➜  reproducer docker compose up
[+] Running 2/0
 ✔ Container grafana  Created                                                                                                                                                                            0.0s
 ✔ Container grizzly  Recreated                                                                                                                                                                          0.1s
Attaching to grafana, grizzly
grafana  | logger=plugins.registration t=2025-01-10T13:22:54.913338607Z level=error msg="Could not register plugin" pluginId=xychart error="plugin xychart is already registered"
grafana  | logger=plugins.initialization t=2025-01-10T13:22:54.913475793Z level=error msg="Could not initialize plugin" pluginId=xychart error="plugin xychart is already registered"
grizzly  | level=info msg="[watcher] Watching for changes"
grizzly  | Listening on http://localhost:8080/
grizzly  | level=error msg="[watcher] Error: parse error in '/mnt/dashboards/examples/redMethod/lib/redDashboard/main.libsonnet': RUNTIME ERROR: couldn't manifest function as JSON\n\tField \"addApplication\"\t\n\tDuring manifestation\t\n"
grizzly  | level=warning msg="[watcher] error: parse error in '/mnt/dashboards/examples/redMethod/lib/redDashboard/main.libsonnet': RUNTIME ERROR: couldn't manifest function as JSON\n\tField \"addApplication\"\t\n\tDuring manifestation\t\n"
grizzly  | level=error msg="[watcher] Error: parse error in '/mnt/dashboards/examples/redMethod/lib/redDashboard/main.libsonnet': RUNTIME ERROR: couldn't manifest function as JSON\n\tField \"addApplication\"\t\n\tDuring manifestation\t\n"
grizzly  | level=warning msg="[watcher] error: parse error in '/mnt/dashboards/examples/redMethod/lib/redDashboard/main.libsonnet': RUNTIME ERROR: couldn't manifest function as JSON\n\tField \"addApplication\"\t\n\tDuring manifestation\t\n"

In this case, user could workaround the error by restarting grizzly at each change but it is cumbersome and make the watch feature less useful.

Steps to Reproduce

  1. git clone https://github.com/grafana/grafonnet /tmp/grafonnet
  2. cd /tmp/grafonnet/examples/redMethod && jb init
  3. start the stack as described in the docker-compose below
  4. Open grizzly on localhost:8080 (or equivalent)
  5. Browse the dashboard
  6. Modify /tmp/grafonnet/examples/redMethod/lib/redDashboard/main.libsonnet
---
services:
  grafana:
    image: grafana/grafana:11.4.0
    container_name: grafana
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
      - GF_LOG_LEVEL=warning
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health"]
      interval: 5s
      retries: 5
      start_period: 1s
      timeout: 10s

  grizzly:
    image: grafana/grizzly:0.6.1
    container_name: grizzly
    volumes:
      # git clone https://github.com/grafana/grafonnet /tmp/grafonnet
      - /tmp/grafonnet:/mnt/dashboards
    ports:
      - 8080:8080
    command:
      - serve
      - -w
      - /mnt/dashboards/examples/redMethod/main.libsonnet
      - /mnt/dashboards/examples/redMethod
    environment:
      - GRAFANA_URL=http://grafana:3000
      - GRAFANA_USER=admin
      - GRAFANA_TOKEN=password
    depends_on:
      grafana:
        condition: service_healthy
        restart: true

wilfriedroset avatar Jan 10 '25 13:01 wilfriedroset

This is NOT a bug in Grizzly.

You are attempting to run the Grafonnet examples, particularly the redMethod one, but you are using the library main.libsonnet as the entry point. That library is designed to be used by other jsonnet code, not to be run directly. Instead, you should call the examples/redMethod/main.libsonnet file. This one should load everything correctly.

malcolmholmes avatar Jan 10 '25 16:01 malcolmholmes

I'm a bit confused as I specifically call grizzly with /mnt/dashboards/examples/redMethod/main.libsonnet which is different than /mnt/dashboards/examples/redMethod/lib/redDashboard/main.libsonnet (the underlying lib).

Is there something wrong in my reproducer?

wilfriedroset avatar Jan 10 '25 16:01 wilfriedroset

Can you execute examples/redMethod/main.libsonnet via Jsonnet?

malcolmholmes avatar Jan 10 '25 23:01 malcolmholmes

I could have been more explicit in the introduction. When I run serve -w examples/redMethod/main.libsonnet it works as expected and the dashboard is reloaded each time I modify examples/redMethod/main.libsonnet When I run serve -w examples/redMethod/main.libsonnet /mnt/dashboards/examples/redMethod it works as expected only when I modify examples/redMethod/main.libsonnet, when I modify anything under examples/redMethod/lib I have the error above.

If this is not a bug, what is the best way to structure your dashboards and lib while keeping the watch features that does not throw an error like couldn't manifest function as JSON

wilfriedroset avatar Jan 13 '25 15:01 wilfriedroset

I had a look at this and it seems the built-in jsonnet capabilities do not work well with the server functionality (or I'm doing something wrong and don't understand how to invoke the right CLI arguments).

IMO, it is probably much safer to use the -S or --script argument instead, it allows to rely on a jsonnet executable of your choosing:

PROJECT_ROOT=/tmp/grafonnet/examples/redMethod
GRR_SCRIPT="jsonnet -J $PROJECT_ROOT/vendor -J $PROJECT_ROOT/lib -J $PROJECT_ROOT $PROJECT_ROOT/main.libsonnet"

./grr serve -w -S $GRR_SCRIPT $PROJECT_ROOT

Duologic avatar Mar 03 '25 09:03 Duologic

Thank you for your feedback. It indeed avoid the error I've reported. From an end user point of view this is less user-friendly to write but the result with the recommended command is the one expected. What do you think about adding this example in the documentation, perhaps here: https://grafana.github.io/grizzly/server/ ?

wilfriedroset avatar Mar 03 '25 20:03 wilfriedroset

That's a good proposal, it'd be a first step towards deprecating 'native' jsonnet support from Grizzly

Duologic avatar Mar 04 '25 12:03 Duologic